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/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/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/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/html/css/src/CCompiledStyle.cpp b/Common/3dParty/html/css/src/CCompiledStyle.cpp index 7de99f83d2a..76617ed6a1c 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(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_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() { @@ -68,9 +66,7 @@ namespace NSCSS 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 && @@ -100,16 +96,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 +110,8 @@ 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 dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE; + for (std::pair pPropertie : mStyle) { std::transform(pPropertie.first.begin(), pPropertie.first.end(), pPropertie.first.begin(), tolower); @@ -183,45 +169,48 @@ namespace NSCSS if (bIsThereBorder) break; - m_oMargin.AddValue(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetValues(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateAll(dFontSize); 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.SetRight(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateRight(dFontSize); break; } CASE(L"margin-bottom"): + CASE(L"bottommargin"): { if (bIsThereBorder) break; - m_oMargin.AddBottom(pPropertie.second, unLevel, bHardMode); + m_oMargin.SetBottom(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateBottom(dFontSize); 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.SetLeft(pPropertie.second, unLevel, bHardMode); m_oMargin.UpdateLeft(dFontSize); break; } @@ -229,35 +218,35 @@ namespace NSCSS CASE(L"padding"): CASE(L"mso-padding-alt"): { - m_oPadding.AddValue(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetValues(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateAll(dFontSize); break; } CASE(L"padding-top"): CASE(L"mso-padding-top-alt"): { - m_oPadding.AddTop(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetTop(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateTop(dFontSize); break; } CASE(L"padding-right"): CASE(L"mso-padding-right-alt"): { - m_oPadding.AddRight(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetRight(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateRight(dFontSize); break; } CASE(L"padding-bottom"): CASE(L"mso-padding-bottom-alt"): { - m_oPadding.AddBottom(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetBottom(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateBottom(dFontSize); break; } CASE(L"padding-left"): CASE(L"mso-padding-left-alt"): { - m_oPadding.AddLeft(pPropertie.second, unLevel, bHardMode); + m_oPadding.SetLeft(pPropertie.second, unLevel, bHardMode); m_oPadding.UpdateLeft(dFontSize); break; } @@ -305,6 +294,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 +387,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,6 +417,7 @@ namespace NSCSS break; } CASE(L"vertical-align"): + CASE(L"valign"): { m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode); break; @@ -501,6 +488,11 @@ namespace NSCSS return arParentsName; } + std::set CCompiledStyle::GetParentsNamesSet() const + { + return m_arParentsStyles; + } + void CCompiledStyle::SetID(const std::wstring& sId) { m_sId = sId; @@ -510,4 +502,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..7877945a6b3 100644 --- a/Common/3dParty/html/css/src/CCompiledStyle.h +++ b/Common/3dParty/html/css/src/CCompiledStyle.h @@ -22,9 +22,6 @@ namespace NSCSS unsigned short int m_nDpi; UnitMeasure m_UnitMeasure; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; - public: NSProperties::CFont m_oFont; NSProperties::CIndent m_oMargin; @@ -41,8 +38,6 @@ namespace NSCSS 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 +48,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..3ece3b199ff 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() @@ -24,6 +23,11 @@ namespace NSCSS return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure); } + bool CCssCalculator::CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors) + { + return m_pInternal->CalculatePageStyle(oPageData, arSelectors); + } + void CCssCalculator::AddStyles(const std::string &sStyle) { m_pInternal->AddStyles(sStyle); @@ -54,26 +58,6 @@ namespace NSCSS m_pInternal->SetBodyTree(oTree); } - void CCssCalculator::SetSizeSourceWindow(const CSizeWindow &oSizeWindow) - { - m_pInternal->SetSizeSourceWindow(oSizeWindow); - } - - void CCssCalculator::SetSizeDeviceWindow(const CSizeWindow &oSizeWindow) - { - m_pInternal->SetSizeDeviceWindow(oSizeWindow); - } - - CSizeWindow CCssCalculator::GetSizeSourceWindow() const - { - return m_pInternal->GetSizeSourceWindow(); - } - - CSizeWindow CCssCalculator::GetSizeDeviceWindow() const - { - return m_pInternal->GetSizeDeviceWindow(); - } - UnitMeasure CCssCalculator::GetUnitMeasure() const { return m_pInternal->GetUnitMeasure(); diff --git a/Common/3dParty/html/css/src/CCssCalculator.h b/Common/3dParty/html/css/src/CCssCalculator.h index fab353426b1..02bd6ed9575 100644 --- a/Common/3dParty/html/css/src/CCssCalculator.h +++ b/Common/3dParty/html/css/src/CCssCalculator.h @@ -22,6 +22,8 @@ namespace NSCSS 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; + 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); @@ -31,12 +33,6 @@ namespace NSCSS 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; diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp index c95a7243c76..e6a9160dd08 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.cpp +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.cpp @@ -16,8 +16,9 @@ #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) { @@ -52,13 +53,6 @@ namespace NSCSS m_mData.clear(); - #ifdef CSS_CALCULATOR_WITH_XHTML - for (std::map, CCompiledStyle*>::iterator iter = m_mUsedStyles.begin(); iter != m_mUsedStyles.end(); ++iter) - delete iter->second; - - m_mUsedStyles.clear(); - #endif - if (NULL != m_mStatictics) delete m_mStatictics; } @@ -86,6 +80,176 @@ namespace NSCSS } + #ifdef CSS_CALCULATOR_WITH_XHTML + std::map CCssCalculator_Private::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 CCssCalculator_Private::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::vector CCssCalculator_Private::CalculateAllNodes(const std::vector &arSelectors) + { + std::vector arNodes; + + for (std::vector::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode) + { + if (!oNode->m_wsName.empty()) + arNodes.push_back(oNode->m_wsName); + + 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" "); + + arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(), + [](std::wstring sRes, const std::wstring& sClass) + {return sRes += L'.' + sClass + L' ';})); + } + else + arNodes.push_back(L'.' + oNode->m_wsClass); + } + + if (!oNode->m_wsId.empty()) + arNodes.push_back(L'#' + oNode->m_wsId); + } + + return arNodes; + } + + 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; + + const std::vector arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend()); + const std::vector arTempKins = pElement->GetNextOfKin(wsName, arClasses); + + if (!arTempPrev.empty()) + arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end()); + + if (!arTempKins.empty()) + arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end()); + } + + std::vector CCssCalculator_Private::FindElements(std::vector &arNodes, std::vector &arNextNodes, bool bIsSettings) + { + std::vector arFindedElements; + + std::wstring wsName, wsId; + std::vector arClasses; + + if (arNodes.back()[0] == L'#') + { + wsId = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsId); + } + + if (arNodes.back()[0] == L'.') + { + arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" "); + arNextNodes.push_back(arNodes.back()); + arNodes.pop_back(); + } + + wsName = arNodes.back(); + arNodes.pop_back(); + arNextNodes.push_back(wsName); + + const std::map::const_iterator oFindName = m_mData.find(wsName); + std::map::const_iterator oFindId; + + if (!wsId.empty()) + { + oFindId = m_mData.find(wsId); + + if (oFindId != m_mData.end() && NULL != m_mStatictics) + { + std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, wsId}); + + if ((m_mStatictics->end() != oFindCountId) && + (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || + (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) + { + if (!oFindId->second->Empty()) + arFindedElements.push_back(oFindId->second); + } + + FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName); + } + } + + 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()) + arFindedElements.push_back(oFindClass->second); + + FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName); + } + } + } + } + + if (oFindName != m_mData.end()) + { + if (!bIsSettings) + { + if (!oFindName->second->Empty()) + arFindedElements.push_back(oFindName->second); + + FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses); + } + } + + if (arFindedElements.size() > 1) + { + std::sort(arFindedElements.rbegin(), arFindedElements.rend(), + [](CElement* oFirstElement, CElement* oSecondElement) + { + return oFirstElement->GetWeight() > oSecondElement->GetWeight(); + }); + } + + return arFindedElements; + } + #endif + + void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles) + { + m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)}); + } + inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet) { for (size_t i = 0; i < oStylesheet->imports.length; ++i) @@ -308,231 +472,11 @@ namespace NSCSS if (arSelectors.empty()) return CCompiledStyle(); - SetUnitMeasure(unitMeasure); - - 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)); + CCompiledStyle oStyle; - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - - return oStyle; - } - - CCompiledStyle *pStyle = new CCompiledStyle(); - - pStyle->SetDpi(m_nDpi); - pStyle->SetUnitMeasure(m_UnitMeasure); - - pStyle->SetSizeDeviceWindow(m_oDeviceWindow); - pStyle->SetSizeSourceWindow(m_oSourceWindow); - - 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); - - //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_wsClass.empty()) - { - if (oNode->m_wsClass.find(L' ') != std::wstring::npos) - { - std::vector arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); + GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure); - 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); - } - - std::vector arElements; - - 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 = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } - - sName = arWords.back(); - arWords.pop_back(); - arNextNodes.push_back(sName); - pStyle->AddParent(sName); - - const std::map::const_iterator oFindName = m_mData.find(sName); - std::map::const_iterator oFindId; - std::vector arFindElements; - - if (!sId.empty()) - { - oFindId = m_mData.find(sId); - - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); - - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - 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()) - { - 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()); - } - } - } - } - - if (oFindName != m_mData.end()) - { - if (!bIsSettings) - { - 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(), - [](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 (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); - } - - if (!bIsSettings) - { - 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; - } - - return *pStyle; + return oStyle; } bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) @@ -544,11 +488,11 @@ namespace NSCSS if (!bIsSettings) { - const std::map, CCompiledStyle*>::iterator oItem = m_mUsedStyles.find(arSelectors); + const std::map, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors); if (oItem != m_mUsedStyles.end()) { - oStyle = *oItem->second; + oStyle = oItem->second; return true; } } @@ -558,180 +502,35 @@ namespace NSCSS 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 false; } oStyle.SetDpi(m_nDpi); oStyle.SetUnitMeasure(m_UnitMeasure); - oStyle.SetSizeDeviceWindow(m_oDeviceWindow); - oStyle.SetSizeSourceWindow(m_oSourceWindow); - - 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_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); - } - - std::vector arElements; - + 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 (arWords.back()[0] == L'.') - { - arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); - arNextNodes.push_back(arWords.back()); - arWords.pop_back(); - } + if (!bInTable) + bInTable = IsTableElement(arSelectors[i].m_wsName); - 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; - - if (!sId.empty()) + if (bInTable) { - oFindId = m_mData.find(sId); - - if (oFindId != m_mData.end() && NULL != m_mStatictics) - { - std::map::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, sId}); - - if ((m_mStatictics->end() != oFindCountId) && - (((bIsSettings && oFindCountId->second < MaxNumberRepetitions) || - (!bIsSettings && oFindCountId->second >= MaxNumberRepetitions)))) - { - 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()) - { - 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_oBackground.Clear(); + oStyle.m_oBorder.Clear(); } - if (oFindName != m_mData.end()) - { - if (!bIsSettings) - { - if (!oFindName->second->Empty()) - arFindElements.push_back(oFindName->second); + CCompiledStyle oTempStyle; - const std::vector arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend()); - const std::vector arTempKins = oFindName->second->GetNextOfKin(sName, arClasses); + oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); - 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(), - [](CElement* oFirstElement, CElement* oSecondElement) - { - return oFirstElement->GetWeight() > oSecondElement->GetWeight(); - }); - } + for (const CElement* oElement : FindElements(arNodes, arPrevNodes, bIsSettings)) + oTempStyle.AddStyle(oElement->GetStyle(), i + 1); if (NULL != m_mStatictics) { @@ -741,31 +540,63 @@ namespace NSCSS { if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) || (!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions)) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); else if (!bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } - else if (bIsSettings) - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + else /*if (bIsSettings)*/ + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); } else - oStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); + oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true); - for (const CElement* oElement : arFindElements) - oStyle.AddStyle(oElement->GetStyle(), i + 1); + oStyle += oTempStyle; - oStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1); + // Скидываем некоторые внешние стили, которые внутри таблицы переопределяются + if (bInTable && i < arSelectors.size() - 1) + { + oStyle.m_oFont.GetLineHeight().Clear(); + oStyle.m_oPadding.Clear(); + oStyle.m_oMargin.Clear(); + } } - 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)); + + if (!bIsSettings && !oStyle.Empty()) + m_mUsedStyles[arSelectors] = oStyle; + + return true; + } + + bool CCssCalculator_Private::CalculatePageStyle(NSProperties::CPage &oPageData, const std::vector &arSelectors) + { + if (arSelectors.empty()) + return false; + + std::vector arNodes = CalculateAllNodes(arSelectors); + std::vector arNextNodes; + + for (size_t i = 0; i < arSelectors.size(); ++i) { - 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)); + if (!arSelectors[i].m_wsStyle.empty() && std::wstring::npos != arSelectors[i].m_wsStyle.find(L"page")) + { + 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); + } - CCompiledStyle *pTemp = new CCompiledStyle(oStyle); + for (const CElement* oElement : FindElements(arNodes, arNextNodes, false)) + { + std::map mRules = oElement->GetStyle(); + if (mRules.end() != mRules.find(L"page")) + SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true); + } - 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 @@ -784,6 +615,16 @@ namespace NSCSS if (wsStyle.empty()) return; + 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; + } + AddStyles(U_TO_UTF8(wsStyle)); } @@ -810,26 +651,6 @@ namespace NSCSS 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 - { - return m_oDeviceWindow; - } - void CCssCalculator_Private::SetUnitMeasure(const UnitMeasure& nType) { m_UnitMeasure = nType; @@ -863,9 +684,6 @@ namespace NSCSS m_mData.clear(); m_arFiles.clear(); - - m_oDeviceWindow.Clear(); - m_oSourceWindow.Clear(); } } inline static std::wstring StringifyValueList(const KatanaArray* oValues) @@ -968,4 +786,11 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue) return str; } +inline static 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; +} + diff --git a/Common/3dParty/html/css/src/CCssCalculator_Private.h b/Common/3dParty/html/css/src/CCssCalculator_Private.h index 7d0e0bfd47c..7bda5a79375 100644 --- a/Common/3dParty/html/css/src/CCssCalculator_Private.h +++ b/Common/3dParty/html/css/src/CCssCalculator_Private.h @@ -26,16 +26,31 @@ namespace NSCSS std::map m_mData; + typedef struct + { + std::vector m_wsNames; + std::map m_mData; + } TPageData; + + std::vector m_arPageDatas; + std::map *m_mStatictics; // Количество повторений свойств id и style у селекторов #ifdef CSS_CALCULATOR_WITH_XHTML - std::map, CCompiledStyle*> m_mUsedStyles; + std::map, CCompiledStyle> m_mUsedStyles; + + std::map GetPageData(const std::wstring& wsPageName); + void SetPageData(NSProperties::CPage& oPage, const std::map& mData, unsigned int unLevel, bool bHardMode = false); + + std::vector CalculateAllNodes(const std::vector& arSelectors); + + void FindPrevAndKindElements(const CElement* pElement, const std::vector& arNextNodes, std::vector& arFindedElements, const std::wstring& wsName, const std::vector& arClasses = {}); + std::vector FindElements(std::vector& arNodes, std::vector& arNextNodes, bool bIsSettings); #endif std::wstring m_sEncoding; - CSizeWindow m_oSourceWindow; - CSizeWindow m_oDeviceWindow; + void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles); void GetStylesheet(const KatanaStylesheet* oStylesheet); void GetRule(const KatanaRule* oRule); @@ -59,6 +74,8 @@ namespace NSCSS #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); + + bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector &arSelectors); #endif void AddStyles(const std::string& sStyle); @@ -69,12 +86,6 @@ namespace NSCSS 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; diff --git a/Common/3dParty/html/css/src/CElement.cpp b/Common/3dParty/html/css/src/CElement.cpp index 2d33e11a128..c6144ee26fe 100644 --- a/Common/3dParty/html/css/src/CElement.cpp +++ b/Common/3dParty/html/css/src/CElement.cpp @@ -173,26 +173,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 +205,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; } diff --git a/Common/3dParty/html/css/src/CElement.h b/Common/3dParty/html/css/src/CElement.h index 1669b07d90f..0cb32d7935f 100644 --- a/Common/3dParty/html/css/src/CElement.h +++ b/Common/3dParty/html/css/src/CElement.h @@ -39,7 +39,7 @@ 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; 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..56f1b28f790 100644 --- a/Common/3dParty/html/css/src/ConstValues.cpp +++ b/Common/3dParty/html/css/src/ConstValues.cpp @@ -2,34 +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; @@ -98,7 +70,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"}, diff --git a/Common/3dParty/html/css/src/ConstValues.h b/Common/3dParty/html/css/src/ConstValues.h index 145aa1caa71..4e7f8ab9fe5 100644 --- a/Common/3dParty/html/css/src/ConstValues.h +++ b/Common/3dParty/html/css/src/ConstValues.h @@ -16,21 +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 @@ -61,66 +46,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 237e83249ca..ae49a17baeb 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.cpp +++ b/Common/3dParty/html/css/src/StaticFunctions.cpp @@ -80,6 +80,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()) @@ -141,30 +187,17 @@ 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; diff --git a/Common/3dParty/html/css/src/StaticFunctions.h b/Common/3dParty/html/css/src/StaticFunctions.h index b4a13fa78ed..2bb29fe20e4 100644 --- a/Common/3dParty/html/css/src/StaticFunctions.h +++ b/Common/3dParty/html/css/src/StaticFunctions.h @@ -20,6 +20,7 @@ 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); diff --git a/Common/3dParty/html/css/src/StyleProperties.cpp b/Common/3dParty/html/css/src/StyleProperties.cpp index 732f05bfa46..513d4d604bc 100644 --- a/Common/3dParty/html/css/src/StyleProperties.cpp +++ b/Common/3dParty/html/css/src/StyleProperties.cpp @@ -25,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) @@ -63,7 +63,7 @@ namespace NSCSS 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)) { m_oValue = wsNewValue; m_unLevel = unLevel; @@ -109,6 +109,8 @@ namespace NSCSS void CString::Clear() { m_oValue.clear(); + m_unLevel = NULL; + m_bImportant = false; } int CString::ToInt() const @@ -149,10 +151,10 @@ 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; } } @@ -175,12 +177,15 @@ namespace NSCSS bool CDigit::Zero() const { - return (std::abs(0 - m_oValue) <= DBL_EPSILON); + return (std::abs(0. - m_oValue) <= DBL_EPSILON); } void CDigit::Clear() { - m_oValue = DBL_MAX; + m_oValue = DBL_MAX; + m_unLevel = NULL; + m_enUnitMeasure = None; + m_bImportant = false; } void CDigit::ConvertTo(UnitMeasure enUnitMeasure, double dPrevValue) @@ -191,7 +196,7 @@ namespace NSCSS int CDigit::ToInt() const { - if (DBL_MAX == m_oValue) + if (Empty()) return 0; return static_cast(m_oValue + 0.5); @@ -199,7 +204,7 @@ namespace NSCSS double CDigit::ToDouble() const { - if (DBL_MAX == m_oValue) + if (Empty()) return 0.; return m_oValue; @@ -249,7 +254,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 @@ -307,10 +324,19 @@ namespace NSCSS CDigit &CDigit::operator+=(const CDigit &oDigit) { - if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || DBL_MAX == oDigit.m_oValue) + if (m_unLevel > oDigit.m_unLevel || (m_bImportant && !oDigit.m_bImportant) || oDigit.Empty()) return *this; - m_oValue += oDigit.ToDouble(m_enUnitMeasure); + 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_unLevel = oDigit.m_unLevel; m_bImportant = oDigit.m_bImportant; @@ -349,7 +375,7 @@ namespace NSCSS bool CDigit::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode)) + if (wsValue.empty() || (CHECK_CONDITIONS && !bHardMode) || unLevel < m_unLevel) return false; std::wstring wsNewValue = wsValue; @@ -359,24 +385,37 @@ namespace NSCSS if (m_bImportant && !bImportant) return false; - double dNewValue; - UnitMeasure enNewUnitMeasure; + if (!CUnitMeasureConverter::GetValue(wsValue, m_oValue, m_enUnitMeasure)) + return false; + + 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 || bHardMode)) + 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; } @@ -566,9 +605,21 @@ namespace NSCSS return m_oValue.Empty(); } + bool CColor::None() const + { + return ColorNone == m_oValue.m_enType; + } + + bool CColor::Url() const + { + return ColorUrl == m_oValue.m_enType; + } + void CColor::Clear() { m_oValue.Clear(); + m_unLevel = NULL; + m_bImportant = false; } ColorType CColor::GetType() const @@ -581,10 +632,10 @@ namespace NSCSS if (m_oOpacity.Empty()) return 1.; - if (Percent == m_oOpacity.GetUnitMeasure()) + 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.; @@ -605,9 +656,9 @@ namespace NSCSS TRGB oRGB = ConvertHEXtoRGB(*pValue); return RGB_TO_INT(oRGB.uchRed, oRGB.uchGreen, oRGB.uchBlue); } + default: + return 0; } - - return 0; } double CColor::ToDouble() const @@ -625,6 +676,38 @@ namespace NSCSS } } + std::wstring CColor::EquateToColor(const std::vector> &arColors) const + { + if (arColors.empty()) + return L"none"; + + TRGB oCurrentColor; + + switch(m_oValue.m_enType) + { + case ColorRGB: oCurrentColor = *static_cast(m_oValue.m_pColor); break; + case ColorHEX: oCurrentColor = ConvertHEXtoRGB(*static_cast(m_oValue.m_pColor)); 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) @@ -786,6 +869,8 @@ namespace NSCSS break; } + default: + break; } return true; @@ -862,6 +947,8 @@ namespace NSCSS wsValue = L"rotate("; break; } + default: + break; } return wsValue; @@ -1055,7 +1142,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 @@ -1103,8 +1190,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; @@ -1173,7 +1260,7 @@ namespace NSCSS } // BACKGROUND - CBackground::CBackground() : m_bInBorder(false) + CBackground::CBackground() {} void CBackground::Equation(CBackground &oFirstBackground, CBackground &oSecondBackground) @@ -1199,19 +1286,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 @@ -1219,10 +1301,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; } @@ -1231,16 +1317,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 @@ -1268,6 +1350,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; @@ -1292,9 +1394,16 @@ namespace NSCSS // BORDER SIDE CBorderSide::CBorderSide() - : m_bBlock(false) + : m_bBlock(false) {} + 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); @@ -1306,11 +1415,16 @@ namespace NSCSS { if (wsValue.empty()) return false; - + if (L"none" == wsValue) + { + SetColor(L"#ffffff", unLevel, bHardMode); + SetStyle(L"solid", unLevel, bHardMode); + SetWidth(L"0",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)) @@ -1350,7 +1464,7 @@ namespace NSCSS { 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) @@ -1398,14 +1512,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; @@ -1420,9 +1544,28 @@ namespace NSCSS 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() + { + m_oLeft .Clear(); + m_oTop .Clear(); + m_oRight .Clear(); + m_oBottom.Clear(); + } void CBorder::Equation(CBorder &oFirstBorder, CBorder &oSecondBorder) { @@ -1434,34 +1577,55 @@ 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::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) @@ -1566,11 +1730,22 @@ 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; } + const CEnum &CBorder::GetCollapse() const + { + return m_enCollapse; + } + const CBorderSide& CBorder::GetLeftBorder() const { return m_oLeft; @@ -1593,10 +1768,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; } @@ -1609,6 +1789,18 @@ namespace NSCSS 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() {} @@ -1709,14 +1901,27 @@ namespace NSCSS { return m_oIndent == oText.m_oIndent && m_oAlign == oText.m_oAlign && -// m_oDecoration == oText.m_oDecoration && + m_oDecoration == oText.m_oDecoration && m_oColor == oText.m_oColor; } // 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) { @@ -1726,175 +1931,156 @@ 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::SetRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oTop, wsValue, unLevel, bHardMode); + return m_oRight.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oRight, wsValue, unLevel, bHardMode); + return m_oBottom.SetValue(wsValue, unLevel, bHardMode); } - bool CIndent::AddBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) + bool CIndent::SetLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { - return AddValue(m_oBottom, wsValue, unLevel, bHardMode); + return m_oLeft.SetValue(wsValue, unLevel, bHardMode); } - + void CIndent::UpdateAll(double dFontSize) { - UpdateLeft(dFontSize); - UpdateTop(dFontSize); - UpdateRight(dFontSize); + UpdateTop (dFontSize); + UpdateRight (dFontSize); UpdateBottom(dFontSize); + UpdateLeft (dFontSize); } - - void CIndent::UpdateLeft(double dFontSize) - { - if (NSCSS::Em == m_oLeft.GetUnitMeasure() || NSCSS::Rem == m_oLeft.GetUnitMeasure()) - m_oLeft.ConvertTo(NSCSS::Twips, dFontSize); - } - + void CIndent::UpdateTop(double dFontSize) { - if (NSCSS::Em == m_oTop.GetUnitMeasure() || NSCSS::Rem == m_oTop.GetUnitMeasure()) - m_oTop.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_oTop, dFontSize); } - + void CIndent::UpdateRight(double dFontSize) { - if (NSCSS::Em == m_oRight.GetUnitMeasure() || NSCSS::Rem == m_oRight.GetUnitMeasure()) - m_oRight.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_oRight, dFontSize); } - + void CIndent::UpdateBottom(double dFontSize) { - if (NSCSS::Em == m_oBottom.GetUnitMeasure() || NSCSS::Rem == m_oBottom.GetUnitMeasure()) - m_oBottom.ConvertTo(NSCSS::Twips, dFontSize); + UpdateSide(m_oBottom, dFontSize); } - const CDigit& CIndent::GetLeft() const + void CIndent::UpdateLeft(double dFontSize) { - return m_oLeft; + UpdateSide(m_oLeft, dFontSize); } - const CDigit& CIndent::GetTop() const + 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, double dFontSize) + { + if (oSide.Empty()) + return; - return true; + if (NSCSS::Em == oSide.GetUnitMeasure() || NSCSS::Rem == oSide.GetUnitMeasure()) + oSide.ConvertTo(NSCSS::Twips, dFontSize); } // FONT @@ -1960,6 +2146,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; @@ -1969,6 +2162,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() {} @@ -2048,16 +2248,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) @@ -2115,13 +2315,13 @@ 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) { - if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure()) - m_oSize.ConvertTo(NSCSS::Twips, dFontSize); + if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure()) + m_oSize.ConvertTo(NSCSS::Point, dFontSize); } void CFont::UpdateLineHeight(double dFontSize) @@ -2142,8 +2342,7 @@ namespace NSCSS void CFont::Clear() { - m_oSize = CDigit(24., 0); - + m_oSize .Clear(); m_oLineHeight.Clear(); m_oFamily .Clear(); m_oStretch .Clear(); @@ -2162,6 +2361,11 @@ namespace NSCSS return m_oLineHeight; } + CDigit &CFont::GetLineHeight() + { + return m_oLineHeight; + } + const CString &CFont::GetFamily() const { return m_oFamily; @@ -2195,7 +2399,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; @@ -2214,7 +2418,7 @@ 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() @@ -2273,7 +2477,16 @@ namespace NSCSS { Clear(); - m_pColor = new std::wstring(wsValue); + if (6 != wsValue.length() && 3 != wsValue.length()) + { + m_enType = ColorEmpty; + return; + } + + if (6 == wsValue.length()) + m_pColor = new std::wstring(wsValue); + else + m_pColor = new std::wstring({wsValue[0], wsValue[0], wsValue[1], wsValue[1], wsValue[2], wsValue[2]}); if (NULL == m_pColor) { @@ -2368,13 +2581,15 @@ namespace NSCSS RELEASEOBJECT(pValue); break; } + default: + break; } - + m_enType = ColorEmpty; } CEnum::CEnum() - : CValue(INT_MIN, 0, false){} + : CValue(INT_MAX, 0, false){} bool CEnum::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode) { @@ -2390,31 +2605,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) @@ -2440,13 +2658,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 179156bbc02..13ea54f67cf 100644 --- a/Common/3dParty/html/css/src/StyleProperties.h +++ b/Common/3dParty/html/css/src/StyleProperties.h @@ -54,6 +54,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; } @@ -81,8 +86,8 @@ namespace NSCSS 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; } @@ -124,13 +129,14 @@ 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 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 +150,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; @@ -220,6 +229,8 @@ namespace NSCSS 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; @@ -229,6 +240,7 @@ namespace NSCSS int ToInt() const override; double ToDouble() const override; std::wstring ToWString() const override; + std::wstring EquateToColor(const std::vector>& arColors) const; TRGB ToRGB() const; }; @@ -277,7 +289,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; @@ -370,19 +382,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 @@ -397,6 +408,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; @@ -412,6 +428,8 @@ namespace NSCSS public: CBorderSide(); + void Clear(); + static void Equation(CBorderSide &oFirstBorderSide, CBorderSide &oSecondBorderSide); bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); @@ -429,9 +447,12 @@ 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; + CBorderSide& operator =(const CBorderSide& oBorderSide); private: CDigit m_oWidth; CString m_oStyle; @@ -440,17 +461,26 @@ namespace NSCSS bool m_bBlock; }; + typedef enum + { + Collapse, + Separate + } BorderCollapse; + class CBorder { public: CBorder(); + void Clear(); + 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 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); @@ -480,8 +510,11 @@ namespace NSCSS 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; @@ -489,11 +522,15 @@ namespace NSCSS CBorder& operator+=(const CBorder& oBorder); 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 @@ -513,6 +550,7 @@ namespace NSCSS bool LineThrough() const; CTextDecorationLine &operator+=(const CTextDecorationLine& oTextDecoration); + bool operator==(const CTextDecorationLine& oTextDecorationLine) const; }; struct TTextDecoration @@ -522,6 +560,7 @@ namespace NSCSS CColor m_oColor; TTextDecoration& operator+=(const TTextDecoration& oTextDecoration); + bool operator==(const TTextDecoration& oTextDecoration) const; }; class CText @@ -561,33 +600,40 @@ 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); + 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 SetRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false); + + void UpdateAll (double dFontSize); + void UpdateTop (double dFontSize); + void UpdateRight (double dFontSize); void UpdateBottom(double dFontSize); + void UpdateLeft (double dFontSize); - 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, double dFontSize); CDigit m_oLeft; CDigit m_oTop; @@ -623,6 +669,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; @@ -642,8 +689,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..19bd8087b7d 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,314 @@ 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() && bInTable) + 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\" "; - 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\" "; - 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. + 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_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 (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 true; } 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..5f9db690586 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() && m_mBasicValues.find(CSSProperties::BasicProperties::B_BasedOn) == m_mBasicValues.end(); } 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,28 +200,8 @@ 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"); - } - 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"); + AddPropertiesInR(CSSProperties::RunnerProperties::R_B, L"bold"); } else if (sNameDefaultElement == L"div-c") { @@ -222,8 +210,6 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement) 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") { @@ -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..2e5ba1eaef2 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,40 @@ static void replace_all(std::string& s, const std::string& s1, const std::string } } +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 +111,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 +199,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 +327,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 +378,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 +402,7 @@ static std::string mhtTohtml(std::string& sFileContent) found = sFile.find(sName, tq); } } + return sFile; } @@ -587,7 +534,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 +565,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 +580,33 @@ 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 (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 +622,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/test/dst/az_Latn_AZ.txt b/Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt new file mode 100644 index 00000000000..5365bb7974d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/az_Latn_AZ.txt @@ -0,0 +1,213 @@ +A [Ü, Ha, Ağ, Ac, Ad, Da, Fa, Ah, Ka, Al, An, Na, Qa] +qocalmaq [almayacaq, almamaq] +Alderaan'ın [Federasiyanın] +hamısı +həmçinin +Və +cavab +dir +incəsənət +kimi +da +uzaq +körpə +zirzəmi [zəmində] +ol +olub +doğuldu [doğulduğu, doğurduğu] +bulvar [bunlar] +fasilə +nəsllər [nəsillər, nəsnələri, nəslə, nələrlə, səslər] +gəlin +lakin +al +ilə +Kaliforniya [Kanalizasiya] +Kalifornikasiya [Kommunikasiya] +bilər +kartlar +şans +Çin +çənə [dənə, çəkə, mənə, nənə, sənə, tənə, çənəyə] +klublar +Cobain [] +bürc [borc, gürcü] +nəzarət +qiymət +edə bilməzdim [bilməzdim] +yaratmaq +lənət +rəqs +saziş +sövdələşmələr [məsləhətləşmələr] +dağıdıcı +almazlar [almanlar, almaz lar, almaz-lar, almaları, marallar, mallara] +etməz +etməyərik [etmərik, etmədikləri] +arzu +xülyalar [yalanlar] +Şərq +kənar +kənarları [kənar ları, kənar-ları, kənarına, kənarında, kəlamları, aparılarkən] +məmnunluq +hamının +uzaq +peri [şeri, geri, meri, yeri] +solğun [dolğun] +üz +son +tap +ilk +üçün +-dan [-dam, -da, -an, -dana, -adan, -nda, -daş, -dən, -dağ, -can, -dad, -din, -lan, -don, -qan, adan, andan] +sərhəd +qız +qızın +yaxşı +gitara [artaraq] +əl +hardcore [hardadır] +var +yoxdur +o [od, ol, on, ot, ov, ox, ü, ı] +eşitmək +ürək +O'nun [Onun, Oyununu] +ona +gizli +yüksək +ona +onun +Hollivud [Holland] +Mən +Mənəm +əgər +içində +məlumat +içində +dir +bu +jack [janra] +sadəcə +kral +qohum +bilmək +qoyulmuş +qanun +yerləşdirilmək [yerləşdirilməsi, yerləşdirilmiş, yerləşdirilib, yerləşdirildiyini] +qurğuşun [quruluşunun] +aparmaq +yerləşdirilmə [yerləşdirilməsi, yerləşdirilmiş, yerləşdirilib, yerləşdirildiyini] +məkan +sevmək +şans +edilmiş +adam +çox +Evlənmək +maska [masa, marka] +o bilər [bilərlər, bilər] +bəlkə də [bəlkə] +mənası +mən +meditasiya [dissertasiya] +xatirə +ağılın +pul +mənim +heç vaxt [vaxtsa] +deyil +heç nə [heçə] +nömrələr [nömrələri, nömrə lər, nömrə-lər, nömrəli, nömrə] +of [od, əf, ol, on, ot, ov, ox, ofis] +of [od, əf, ol, on, ot, ov, ox, ofis] +üstündə +bir +yalnız +və ya [vəla] +nəticə +öz +Ödə [Də, Ədə, Adə, Edə, Idə, Öndə, Ölə, Önə] +Şəftəli [Həftəlik] +yerlər +oynayır +oynamaq +əhali +porno [sponsor] +tərifləmək [təriflər, təklifləri, təkliflərlə, təkliflərə] +ehtimal ki [ehtimal] +ehtimal +psixik [psixi, psixoloji] +kraliça [kralı] +qaldırmaq +qalan +hörmət +qalxmaq +yol +xam +müqəddəs +Xilas et [Xilası] +elmi +çığırmaq [çağırmaq, çıxarmaq] +satılır +şəkil +xəstələnmək [xəstələnməyi, dəstəklənməsi] +gümüşçü [gümüş] +dəri +əsgər +bir şey [şeydir] +Mahnı +mahnılar +qılınclar [qılınc lar, qılınc-lar, qılıncı] +büyü [böyüyü] +casuslar [ruslar] +ulduz +Stansiya +oğurlamaq [vurğulamaq] +daşlar +günəş +şübhəli +İsveç +qılınclar [qılınc lar, qılınc-lar, qılıncı] +yeniyetmə +test +dandan [andan, candan, qandan, yandan, danışanda, adından, yanından, canından] +bu ki [builki] +bu ki [builki] +bu +onların +bu +onlar +düşünmək +bu +onlar +gel-git [get-gedə] +üçün +deyilmişəm [deyilmiş əm, deyilmiş-əm, deyilmişdi, deyilmiş, deyilmi, deyiləm] +çox +cəhd et [cəhdlər] +başa düşdüm [] +qilin [ilin, bilin, dilin] +titrəmək [itirməmək, itirmək] +mübarizə aparır? [] +istəyirəm +müharibə +idi +dalğalar [qadağalar, dağlarda, adalar, dağlar] +geymək [getmək, getməmək] +silahlar +yaxşı +idarə olunan [olunanlardan] +Qərbi [Hərbi, Qəbri, Qərb, Qərbin, Qəbir, Qərbə, Qəlbi] +nə +arasında +qalib gəlmək [qaliblərin] +qalib gəlir [qalibləri] +ilə +qadın +dünya +səhv +siz +sizə +sənsən [səndən, sən sən, sən-sən, nədənsə, mənsə, sənə, səslənən] +sənin diff --git a/Common/3dParty/hunspell/test/dst/bg_BG.txt b/Common/3dParty/hunspell/test/dst/bg_BG.txt new file mode 100644 index 00000000000..57cc73c5c72 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/bg_BG.txt @@ -0,0 +1,212 @@ +A [А, Е, О, И, В, С, Я, У] +остаряване +Алдераан [Дерайлиран] +всичко +също +и +отговор +са +изкуство +като +в +далеч +бебе +мазе +бъда +било +роден +булевард +почивка +породи +невеста +но +купувам +от +Калифорния +Калифорникация [Калифорнийския, Калифорнийка, Калифорния] +може +карти +шанс +Китай +брадичка +клубове +Кобейн [Кобен] +съзвездие +контрол +цена +не можех [можехме] +създаване +проклятие +танц +сделка +сделки +унищожение +диаманти +не прави [неправи, неуправии, неправдиви] +не правим [непоправим] +мечта +мечти +Изток +ръб +ръбове +екстаз +всеки +далеч +приказка +избледнява +лица +краен +намирам +първи +за +от +предел +момиче +момичето +добре +китара +ръка +хардкор [хардуер] +има +няма +той +чуя +сърце +той е [той] +нейни +скрит +висок +него +негов +Холивуд +аз +аз съм [разсъмна] +ако +в +информация +вътре +е +това е [товарен] +вале +просто +крал +родственик +знам +определен +закон +поставям +водя +води +местоположение +обичам +късмет +направен +човек +много +Ожени се [Брожение] +маска +май +може би [можещи] +означава +аз +медитация +спомен +ума +пари +моя +никога +не +нищо +числа +от +изключен +на +един +само +или +изход +свой +Плати +праскова +места +играе +играя +население +порно [бурно, орно, порено, опорно, спорно, упорно, порна, парно, порне, поено, порни, потно, торно, морно, горно] +похвала +вероятно +вероятен +психичен +кралица +въздигам +останал +почит +възход +път +груб +светия +Спасявам +наука +крясък +продава +форма +по-болен +златар +кожа +войник +някаква +Песен +песни +пикове +заклинание +шпиони +звезда +стация [станция, стария, статия, стадия, атестация, стагнация] +крада +камъни +слънце +подозрителен +Швеция +мечове +тийнейджър [тинейджър, пейджър] +тест +отколкото +това +това е [товарен] +на +техни +тези +те с [тесте] +мисли +този +той +прилив +до +каза +също +опитайте +разбрано +еднорог [едно рог, еднороден] +вибрация +водене? [водене, неводен, воден] +искам +война +беше +вълни +носете +оръжия +Ами +бяха +Западна +какво +докато +победа +победи +със +жена +свят +грешка +ти +ти би [табиети] +ти си [тифуси] +вашият diff --git a/Common/3dParty/hunspell/test/dst/ca_ES.txt b/Common/3dParty/hunspell/test/dst/ca_ES.txt new file mode 100644 index 00000000000..be726d0d8a2 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ca_ES.txt @@ -0,0 +1,112 @@ +amor +llum +lluum [lluu, llum, lluus, lluïm, lluu m] +esperança +espirança [esperança, espirant, espinçadora, espinça, espira] +llibertat +força +forrça [forra, força, forçar] +pau +somni +llibre +mar +amistat +cançó +flor +cel +estrella +temps +camí +vent +muntanya +mumntanya [muntanya, muntanyà, muntant] +riu +soroll +silenci +viatge +foc +gel +paraula +vida +dia +nit +tarda +matí +lluna +sol +llac +marbre +ferro +sal +mel +sucre +peix +ocell +oceoll [ocell] +joc +ritme +melodia +pintura +pentura [puntera, entura, pintura, puntura, ventura, penetrant, apertura, parapent] +teatre +dansa +poema +història +llegenda +mitologia +festa +música +vi +cervesa +cervessa [cervesa, cer vessa, cer-vessa, cerves sa, cerves-sa, cervesera, cerveseria, cerveser, cessava] +formatge +pa +ciutat +poble +natura +camp +bosc +platja +sorra +sorrà +pedra +ànima +cos +ment +cor +somriure +somriàre [somriure, somrient] +abraçada +bes +parla +oida [oidà, oïda, ioda, odia, aido, oia, oda, oiada, oxida, aida, sida, onda, mida, dida, vida] +vista +tacte +gust +olfacte +color +forma +número +lletra +sistema +regla +escola +universitat +univversitat [universitat, universitari, universalitat, universalitzat, universalista] +mestre +estudiant +sabiduria [sabuderia] +lliçó +pregunta +resposta +risposta [resposta, disposta, ris posta, ris-posta, risp osta, risp-osta, trasposta, posteritat, riosta, polvorista] +dubte +certesa +veritat +mentida +promesa +secret +descoberta +descaberta [descoberta, desca berta, desca-berta, descabestrat, descartable, descabota, descarta] +aventura +destinació diff --git a/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt b/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt new file mode 100644 index 00000000000..87fc1cc63ba --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ca_ES_valencia.txt @@ -0,0 +1,212 @@ +A +envellir +Alderaan [Aldebaran, Aldebrand, Aldeana, Anedera] +tot +també +I +resposta +és +art +com +a +lluny +nadó +celler +ser +ha estat [hastat] +nat +bulevard +pausa +generacions +núvia +però +comprar +amb +Califòrnia +Californication [Californiana, Californita] +pot +cartes +oportunitat +Xina +mentó +clubs +Cobain [Cobai, Cobais, Cobrin, Cob ain, Cob-ain, Cobalamina] +signe del zodíac [signé del zodíac, signè del zodíac, sígne del zodíac, sïgne del zodíac, signE del zodíac, Signe del zodíac, sIgne del zodíac, sigNe del zodíac, siGne del zodíac] +control +preu +no podria [nodriria, podriria, nodria] +crear +maleït +ballar +acord +negocis +destructiu +diamants +no fer [noosfera] +no fem [nomenem] +desitjar +somnis +Est +vora +voreres +satisfacció +tots +llunyà +fada +pallid [pallis, palli, pallin, pali] +cara +final +trobar +primer +per +de +frontera +noia +la noia [la noïa, la Noia] +bé +guitarra +mà +hardcore [recordar] +hi ha [hifa] +no hi ha [nó hi ha, nò hi ha, nO hi ha, No hi ha] +ell +sentir +cor +ell és [estellés] +seva +secret +alt +ell +seu +Hollywood +jo +sóc +si +en +informació +interior +és +és +jack +només +rei +parent +saber +fixat +llei +col·locar +plom +portar +col·locació +lloc +estimar +oportunitat +fet +home +molts +casar-se +màscara +podria +potser +sentit +jo +meditació +memòria +ment +diners +meu +mai +no +res +números +de +fora +sobre +un +només +o +resultat +seu +pagar +préssec +llocs +jugar +joc +població +porno +elogiar +probablement +probable +psíquic +reina +elevar +restant +respecte +pujar +camí +cru +sant +salvar +ciència +crit +vendre’s [vendre's, vendre] +figura +malalt +joier +pell +soldat +alguna cosa [glucosamina] +cançó +cançons +cims +encanteri +espies +estrella +estació +robar +pedres +sol +sospitós +Suècia +espases +adolescent +prova +que +que +això +seu +aqueixos +ells +pensar +aqueix +ells +marees +per +no he estat [nó he estat, nò he estat, nO he estat, No he estat] +molt +intentar +entendre +fer +tremolar +lluitar +desitjar +guerra +va ser [vaser, serva] +ones +portar +armes +bé +administrat +Oest +què +entre +guanyar +guanya +amb +dona +món +equivocat +tu +vostè +tu ets [tubets] +teu diff --git a/Common/3dParty/hunspell/test/dst/cs_CZ.txt b/Common/3dParty/hunspell/test/dst/cs_CZ.txt new file mode 100644 index 00000000000..916cc8419c4 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/cs_CZ.txt @@ -0,0 +1,206 @@ +pomaliý [pomalý, pomaličku] +šťstný [šťastný] +smuutný [smutný, smutnu] +horcký [horký, horácký, horecký, horský, hornický, horňácký] +studiený [studený, studie] +záludnast [záludnost, záludný] +náhodillost [nahodilost, náhodnost] +úpěnlevý [úpěnlivý, úpletový] +rozspačitý [rozpačitý, rozpačitěný] +svéhllavý [svéhlavý, svéhlavička] +jablko +slunce +voda +dům +pták +káva +chleba +květina +kniha +pes +kočka +město +zelený +modrý +červený +bílý +černý +velký +malý +rychlý +pomalý +šťastný +smutný +horký +studený +nový +starý +hezký +ošklivý +dobrý +špatný +zdravý +nemocný +silný +slabý +chytrý +hloupý +pracovat +jíst +pít +spát +číst +psát +mluvit +smát se [smát] +plakat +zpívat +hrát +tančit +učit se [učitele] +nakupovat +vařit +telefonovat +dívat se [sedívat] +poslouchat +chodit +běžet +létat +plavat +psát +učit se [učitele] +dělat +mít +být +jít +přijít +odejít +dát +vzít +říct +vidět +slyšet +cítit +myslet +chtít +moct +muset +rád +nerad +ano +ne +prosím +děkuji +na shledanou [shledanou, dohledanou, shledávanou, ohledanou] +omlouvám se [omlouvání] +sbohem +ahoj +čau +hej +jo +fakt +super +blbost +paráda +no jo [nojo] +jasně +takže +vlastně +třeba +snad +leštěnka +pochmurný +živelný +ponaučení +záhada +pochybnost +nádhera +soucit +záludnost +náhodilost [nahodilost, náhodnost] +úpěnlivý +rozpačitý +svéhlavý +marnivost +blahodar [blaho dar, blaho-dar, lahoda] +rozčarování +odchylka +přelud +vytrvalost +neústupnost +lehkost +souznění +rozmarnost +roztržitost +úskočnost +rozkoš +marasmus +rozpolcenost +neúprosnost +ztřeštěnost +chmurnost +okouzlení +zářivost +vyrovnanost +neochvějnost +neúcta +bizarnost +rozmařilost +nepochopení +nevýslovný +pomíjivost +beznaděj +úzkost +odtažitost +rozerv [rozerve, rozervi, rozervu, rezerv, rozervat] +rozervanost +vyčerpanost +bezcitnost +záludnost +nezdolnost +rozkošátnost [rozkošnost, rozkošatěnost, rozkošnickost, rozkoktanost] +nezdolatelnost +rozmarnost +živelnost +bezútěšnost +záhadnost +neposkvrnitelnost [nepotiskovatelnost, nepopisovatelnost, nepřemostitelnost, nezvratitelnost] +rozkošnělost [rozkošatělost, rozkošnost, rozkošnickost, rozkošatěnost] +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +rozervanost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +bezbřehost diff --git a/Common/3dParty/hunspell/test/dst/da_DK.txt b/Common/3dParty/hunspell/test/dst/da_DK.txt new file mode 100644 index 00000000000..b7a362e12d2 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/da_DK.txt @@ -0,0 +1,129 @@ +Hej +Goddag +Tak +Ja +Nej +Måske +Mad +Vand +Hus +Bil +Tog +Cykel +Skole +Børn +Far +Mor +Søster +Bror +Hund +Kat +Fisk +Fugl +Træ +Blomst +Græs +Sol +Måne +Himmel +Regn +Sne +Sommer +Vinter +Forår +Efterår +Aften +Nat +Dag +Uge +Måned +År +Læse +Skrive +Tale +Lære [Lære, Læres, Lærer, Læren, Læreø, Læreå, læreå] +Arbejde +Sove +Vågne +Løbe +Gå +Sidde +Stå +Lytte +Se +Høre [Høre, Høres, Hører, Høreø, Høreå, høreå] +Spise +Drikke +Kød +Frugt +Grøntsager +Ost +Brød +Vand +Juice +Kaffe +Te +Mælk +Smør [Smør, Smøre, Smørs, Smør'] +Æg +Salt +Peber +Sukker +Bolle +Smørrebrød +Køkken +Stue +Soveværelse +Badeværelse +Toilet +Bord +Stol +Sofa +Lampe +Vindue +Dør +Gulv +Loft +Væg +Sofa +Pude +Tæppe +Badekar +Håndvask +Spejl +Håndklæde +Seng +Dyne +Dynee [Dynes, Dyner, Dyne, Dynen, Dynge, Dynees, Dynete, Dyneel, Dynele, Dyneed, Dyneeg, Dyneem, Dynefe, Dyneve] +Pude +Pudee [Pudene, Pudre, Puder, Pude, Pudes, Pudse, Puden, Pudet, Pudel] +Alarm +Alarmm [Alarm, Alarms] +Skrivebord +Stol +Hus +Hund +Kat +Katt [Kett, Katy, Katty, Kate, Kitt, Kata, Kato, Matt, Watt, Kat, Kast, Kats, Takt, Kart, Katte] +Bil +Skole +Skolee [Skolie, Skolede, Skoler, Skole, Skoles, Skolen, Skolet, Skolde] +Sol +Soll [Sol, Sole, Sols, Soli, Sola, Sall, Sold, Solo, Soul] +Vand +Vandd [Vanda, Vandy, Vandt, Vand, Vands, Vande, Vandr] +Mad +Madd [Mads, Maud, Mad, Made, Mand] +By +Barn +Barnn [Barni, Baran, Barny, Barn, Baren, Barns, Baron] +Tørklæde +Skæbne +Uafhængighed +Kærlighed +Kærligheed [Kærlighed, Ærlighed, Hæderlighed, Herlighed, Liderlighed] +overbelastning +Modstandsbevægelsen +Uafhængighedserklæringen +Forårssommertemperaturen +Stabiliseringsperioden diff --git a/Common/3dParty/hunspell/test/dst/de_AT.txt b/Common/3dParty/hunspell/test/dst/de_AT.txt new file mode 100644 index 00000000000..060081d0113 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_AT.txt @@ -0,0 +1,131 @@ +Ägyptologie +Ährenamt [Ährensamt, Ährenast, Ährenart, Ährenact, Ährenabt, Ährenakt, Ährenaxt, Ehrenamt, Ohrenamt, -ährenamt, Ährenartig] +Ängstlichkeit +Äquatoria +Abarbeiten +Abbild +Abbilden +Abbildungs [Abbildung, Abbildungs-, Bildungsnah, Unbildung] +Abbreviatur +Abbrüche +Abfassen +Abfertigen +Abfolge +Abfuhr +Ableugnen +Ablichten +Ablöse +Absätze +Abschnitts +Abwechseln +Abwehren +Aktiv +Britannia +Browserfenster +Budgetieren +Bugpartie +Bukarester +Burgundersoße +Butterkrem +Button +Cabriolet +Campanile +Canapé +Caprice +Celsius +Chamäleon +Charakteristik +Chronometer +Chronometrie +Cölln +Connectzustände +Cursorspur +Däne +Dachs +Dahindämmern +Darbringen +Daten +Datenbankserver +Desktopsystem +Detektivfilm +Dichtertum +Dinosaurier +Direktion +Diskantgambe +Diskothek +Druckereicode +Kapsel +Karausche +Katzen +Klinge +Klinke +Kohlrabi +Koinzidenz +Kolleg +Komplott +Meereis +Mehrphasigkeit +Memorieren +Messen +Methode +Metrowaggon +Meute +Migräne +Milieuforschung +Mindern +Mineralien +Mitternacht +Mobiliar +Mohrrübe +Mühelosigkeit +Normativität +Notifikation +Ökonomie +Orangeton +Osten +Subjekt +Subsidiarität +Subsumieren +Tagfalter +Speicher +Spielzeugsammlung +Zahler + +Сложные слова [] +Zurückgezogenheit +Äquipotentialfläche +Äußerungsbedeutung +Abfassungszeitraum +Abgeschlossenheits [Abgeschlossenheit, Abgeschlossenheits-, Unabgeschlossenheit, Aufgeschlossenheit, Abgeschlagenheit, Geschlossenheit] +Adjunktionsbeseitigung +Anknüpfungsgrundsätze +Chiffrierschlüssel +Knochenmarktransplantation +Bundeskaderathlet +Carbonsäurechlorid +Cardiazoltherapie +Chancenungleichheit +Charakterisierungsmöglichkeit +Chlorophyllkonzentration +Computerspielemarkt +Deindustrialisieren +Dekodierungsmöglichkeit +Kartoffelschälmesser +Kernspinresonanztomographie +Merkmalskombination +Nachbarschaftszentren +Opportunitätsprinzip +Tiefenstaffelung +Tourismusfachmann +Sequenzbetrachtung + +Слова с ошибками [] +Dechifrierprogramm [Dechiffrierprogramm, Liederprogramm] +Administratorkenwort [Administratorkennwort, Administratorkonto, Administratorrecht, Distriktadministrator, Distriktsadministrator] +Spigeln [Spiegeln] +Tätigkeite [Tätigkeit, Tätigkeiten, Untätigkeit, Nagetätigkeit, Mildtätigkeit, Regietätigkeit] +Draufgangertum [Draufgängertum, Draufgänger] +Abschnit [Abschnitt, Abschritt] +Komunikation [Kommunikation, Exkommunikation, Kommunikativ, Kommunikator, Komplikation] +Drackereicode [Druckereicode, Dreidecker] +Bumeln [Baumeln, Bummeln, Blumen, Brummeln, Bummel] diff --git a/Common/3dParty/hunspell/test/dst/de_CH.txt b/Common/3dParty/hunspell/test/dst/de_CH.txt new file mode 100644 index 00000000000..196e03636bf --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_CH.txt @@ -0,0 +1,116 @@ +Alpinist +Alteration +Alternative +Alumne +Amateurfilmer +Ambulanz +Amtmänner +Analogie +Analytik +Ananas +Angabe +Ankünfte +Dynastie +Ebenbürtigkeit +Echtheitszertifikat +Editionspläne +Editor +Ehrenamtlichkeit +Eigentümerschaft +Einbau +Eindringling +Eingabequittungsbetrieb +Einhüllen +Einkommen +Einloggen +Einschließen [Einschliessen, Einschliefen] +Einsortier [Einsortier-, Einsorter, Eintortier, Einportier, Einvortier, Einsortiere, Einsortiert, Unsortierter, Unsortiert, Einzusortieren, Sortieren] +Elaboration +Elementar +Entertainer +Entkuppeln +Entschädigungs [Entschädigung, Entschädigungs-, Entschädigungslos, Entschädigens, Entschädigen] +Enumerator +Erbringen +Erdichten +Erfahrenheit +Erhalt +Erleichtern +Ersparnis +Erstatten +Erzählliteratur +Helikopter +Helpdesk +Herunterladen +Hindeuten +Hinterlassenschaft +Hiob +Landesprache [Landessprache, Landesrache, Landsprache, Ladesprache, -landesprache] +flexibilität [Flexibilität, -flexibilität, flexibilisiert] +floristisch +flugbillet [Flugbillet, -flugbillet, flugbereit] +heroben +herrichten +herstellen +herübereilen +herunterzubücken +hie +hieraus +hilfe [Hilfe, hilf, hilfe-, -hilfe, helfe, hilft, hälfe] +himbeere [Himbeere, -himbeere, himbeer-, himbeerrot] +justiz [Justiz, justiz-, -justiz, justiziell] +kältebeständig +kärtchen [Kärtchen, -kärtchen, Gärtchen, Bärtchen, kärglichen] +känguru [Känguru, -känguru] +kaktusgewächs [Kaktusgewächs, -kaktusgewächs, ausgewechselt] +kalligrafie [Kalligrafie, -kalligrafie, kalligrafiere, kalligrafische, kalligrafisch] +kamel [Kamel, kamel-, -kamel, kamen, rammel] +kampagnendirektor [Kampagnendirektor, -kampagnendirektor, kampagnenartig] +kapazitär +kapitalist [Kapitalist, -kapitalist, kapital ist, kapital-ist, kapitalistisch, kapitalisierst, kapitalisiert, kapitalstark] +karamell [Karamell, karamell-, -karamell, lamellar] +kardieren +karpfen [Karpfen, -karpfen, krampfen] +katalogdaten [Katalogdaten, -katalogdaten, katalogartigen] +lyzeum [Lyzeum, -lyzeum] +mahagonirot +makkaroni [Makkaroni, -makkaroni, marokkanisch] +malerausbildung [Malerausbildung, -malerausbildung, ausbildungsreif] +management [Management, -management, managen, gemanagt, angemahnt] +mangel +maniküre +manneskraft [Manneskraft, -manneskraft, maskenhaft] +mansarde [Mansarde, -mansarde, ansparende] +mark [Mark, -mark, merk, park, Sark, Park, Bark, markig] +marketingpraktiker [Marketingpraktiker, -marketingpraktiker, marketingorientiert, marketingwirksamer] +maschinell +massage [Massage, massage-, -massage, massige, Passage, Gassage, passagere] +massengutschifffahrt [Massengutschifffahrt, -massengutschifffahrt, maschinenschriftlich] +materie [Materie, -materie, materiell, materiefrei, maturiere, mattier] +medaille [Medaille, -medaille, medaillenlos] +medizinalshampoo [Medizinalshampoo, -medizinalshampoo, sozialmedizinisch] +meeresfrüchte [Meeresfrüchte, -meeresfrüchte, Heeresfrüchte, meeresfeuchte, meeresfeucht, früchtereiche, früchtereich] +quotient [Quotient, -quotient, quotiert, quotieren, quotiere, quotisieren] +salonwagen [Salonwagen, -salonwagen, lossagen] +satzeinleitend +trilateral +tristesse [Tristesse, -tristesse, tristeste, trist esse, trist-esse, triste, rissfeste, stresse, rissfest] +tropen [Tropen, tropfen, tropen-, -tropen, trogen, tropenfest] +vereisen +verfahren +verfügungs [verfügungs-, verfügen] +verhindern +verkäufer [Verkäufer, -verkäufer, verkämpfe, verkaufe, verkupfer] + +Слова с ошибками [] +Anbindungsystem [Anbindungssystem] +Anglistikdocent [Anglistikdozent, Anglistikstudent, Linguistikdozent] +Ecco [Echo, Codec] +Economclass [Economyclass, Economyklasse] +Einverstandnis [Einverständnis, Einverstandanis, Einverstandnils, Einverstandeis, Einverstandnil, Einverstanden, Seinsverständnis, Koranverständnis, Unverständnis] +Electrik [Elektrik, Electrabel] +Historique [Historisiere, Historie] +herüberzurucken [herüberzugucken, herüberzurücken, herüberzulocken, herüberzustrecken, herüberzublicken, herüberzuschicken] +kartofel [kartoniere] +salade [malade, lade] +sanddornbere [versandbereite] diff --git a/Common/3dParty/hunspell/test/dst/de_DE.txt b/Common/3dParty/hunspell/test/dst/de_DE.txt new file mode 100644 index 00000000000..36cde4a624e --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/de_DE.txt @@ -0,0 +1,211 @@ +Hallo +Guten Morgen [Morgenläuten, Morgenröten] +Danke +Bitte +Ja +Nein +Entschuldigung +Tschüss +Liebe +Freund +Familie +Glück +Gesundheit +Schule +Arbeit +Essen +Trinken +Wasser +Brot +Käse +Fleisch +Gemüse +Obst +Kaffee +Tee +Milch +Zucker +Salz +Pfeffer +Haus +Wohnung +Bett +Stuhl +Tisch +Sofa +Fernseher +Telefon +Computer +Buch +Zeitung +Schreiben +Lesen +Hören +Sehen +Fühlen +Laufen +Springen +Schwimmen +Tanzen +Singen +Lachen +Weinen +Freude +Trauer +Angst +Mut +Liebe +Hass +Freundschaft +Beziehung +Familie +Eltern +Kinder +Geschwister +Großeltern +Onkel +Tante +Cousin +Cousine +Ehemann +Ehefrau +Verlobung +Hochzeit +Scheidung +Geburt +Tod +Krankheit +Arzt +Krankenhaus +Medikament +Apotheke +Gesundheit +Wohlbefinden +Fitness +Diät +Schlaf +Ruhe +Entspannung +Sport +Fußball +Tennis +Schwimmen +Laufen +Radfahren +Wandern +Reisen +Urlaub +Strand +Sonne +Meer +Komplementär +Perspektive +Konsens +Integrität +Konsequenz +Authentizität +Korrelation +Charakteristik +Akzeptanz +Flexibilität +Assoziation +Dekomposition +Komplexität +Positivismus +Universalität +Stabilität +Individualität +Konsistenz +Konformität +Dezentralisierung +Kollaboration +Partizipation +Präzision +Transformation +Konkurrenz +Paradoxie +Redundanz +Regeneration +Integration +Isolation +Asymmetrie +Aggregation +Disziplin +Resilienz +Relevanz +Konfusion +Komplikation +Koordination +Harmonie +Ineffizienz +Konstruktion +Konversion +Kollusion +Gerontologie +Differenzierung +Dimensionalität +Inferenz +Fluktuation +Kontraktion +Rezession +Inflation +Dekontamination +Exzellenz +Innovation +Isomorphie +Konnotation +Insuffizienz +Konversion +Kompensation +Koalition +Inkongruenz +Inkontinenz +Kontrahent +Konfiskation +Konjunktur +Aggression +Konfrontation +Kompatibilität +Prognose +Akzeleration +Konstruktion +Diversifikation +Prävention +Sanktion +Indikation +Reduktion +Konkurrenz +Konfiguration +Konnotation +Rezession +Transformation +Interaktion +Kooperation +Innovation +Kollision +Proklamation +Konnotation +Konfrontation +Disposition +Konkordanz +Deklamation +Kollaboration +Isolation +Inflation +Diversifikation +Konnotation +Kompensation +Diffusion +Dekadenz +Konserve +Deklomotion [Deklamation, Deklination, Deletionsklon] +Kolaboration [Kollaboration, Kollaborativ, Elaboration, Korporation, Inkorporation] +Isollation [Isolation, Installation, Kollation, Solmisation, Spallation] +Infllation [Inflation, Inflationär, Inflammation, Inflationiere, Installation] +Divirsifikation [Diversifikation, Ossifikation, Kodifikation, Ratifikation] +Konotation [Konnotation, Korotation, Kinotation, Kontotation, Ökonotation, Konnotativ, Annotation, Notation, Konfrontation] +Kompenssation [Kompensation] +Difusion [Diffusion, Gasdiffusion, Infusion, Diskussion, Fusion] +Dekadens [Dekaden, Dekadenz, Dekadent, Dekade, Dekans, Dekagons, Dekkans] +Kanzerve [Verwanze] + diff --git a/Common/3dParty/hunspell/test/dst/el_GR.txt b/Common/3dParty/hunspell/test/dst/el_GR.txt new file mode 100644 index 00000000000..cc8cf011f27 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/el_GR.txt @@ -0,0 +1,123 @@ +Αβαντάζ +Αβασταγά +Αβγάτισες +αβέβαιο +αβέλτερο +αβέλτεροι +αβίαστους +άβλαβοι +αβοκάντο +αβράδιαστης +άβραστη +αβράχυντου +άβρεχτα +αβρή +αβρότης +άβυσσον +αγαθόν +αγαθούς +αγάλακτο +αγγούρι +αγελαδινού +αγέρα +αγεωμέτρητων +αγίνωτοι +άγκυρες +αγορεύσεις +αγόρευσή +αγορίνα +Αγοριού +Αγροληψία +Αρμόνια +βγαίνοντας +βεβαιώσεων +διάθεση +διαίρεση +Διαιρέσου +Διαιτολογίου +διαψεύσουν +διδασκάλισσας +ενασκήσεις +ενασχόληση +ενασχόλησή +ενδείξεις +ενδεχόμενον +ενδιαμέσου +Επιστήθιες +Επιστημο [Επιστημοσύνη] +Επιστολές +Επιστολή +εύπορους +ευρέα +ευρημάτων +ευρύτητά +ευσταθών +εύστροφα +ευσυνειδησία +εύτακτε +ευτελείς +ευτελίζουν +ιδρυτικό +ιεροψάλτες +Ιζόλα +Ιθαγένειάς +ικανότατος +ιλαρότης +κεφαλής +κεφαλιάτικες +κεφαλωτές +κήπε +κήπευση +Κήρυξής +Λεξικογραφιών +Λεξιλογικός +λεοντή +λεοντής +ολιγοχρόνιου +ολικέ +ολικές +ολική +πελαγώνω +πελατών +πελάων +προστατεύει +προστασίας +σούρουπου +σουρούπωμα +σούρτης +Σούρωνα +Σπαγέτα +Σφάλμα +Σφάλματά +σφικτά +σφικτέ +σφοδρότητας +σφοδρού +σφραγίσω +σχεδιάζουμε +σχεδιάζουν +σχηματίσου +σχηματίσουμε +σχολιάζεσαι +Σχολιάζεστε +Ενδιαφέροντα + +Слова с ошибками [] +Αβασiλευτου [Αβασίλευτου, Αβασίλευτο, Αβόλευτου] +αγαπούσαv [αγαπούσα, αγαπούσαν, αγαπούσε] +βeβαιωμένοι [βεβαιωμένοι, βεβαιωμένο] +εvασxόλησης [ενασχόλησης] +επιoτολικέ [επιστολικέ, επιστολικό] +ιδιωτικοποιήσειc [ιδιωτικοποιήσει, ιδιωτικοποιήσεις, ιδιωτικοποιήσετε, ιδιωτικοποιήσεως, ιδιωτικοποιήσεων, ιδιωτικοποιήστε] +λεπταίσθnτη [λεπταίσθητη, λεπταίσθητα, λεπταίσθητε, λεπταίσθητο] +πρoστιμάρισμα [προστιμάρισμα, στιμάρισμα] +σφάλμαtα [σφάλματα, σφάλμα] +προστάτεuε [προστάτευε, προστάτεψε, προστάτευσε, προστάτες, προστάτευα, προστάτευσα] +κεxριμπαριού [κεχριμπαριού, κεχριμπαρένιο] +διαισθnτικότητες [διαισθητικότητες, διαισθητικότητας, διαισθητικότητα, διαισθητικότης, αισθητικότητες] +αγκιστpώσουv [αγκιστρώσουν] +αγαθoεργiας [αγαθοεργίας] +αβεβαιoτητά [αβεβαιότητά, βεβαιότητά] +αγέρεc [αγέρες] +διδαxθούμε [διδαχθούμε, διδαχτούμε] +εuσταθειώv [ευσταθειών] diff --git a/Common/3dParty/hunspell/test/dst/en_AU.txt b/Common/3dParty/hunspell/test/dst/en_AU.txt new file mode 100644 index 00000000000..55691a415f1 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_AU.txt @@ -0,0 +1,116 @@ +Acknowledge +acrophobia +adventurousness +aeronautics +algal +Alligator +allegation +alphabetise +Analogy +appropriable +assembly +attempt +Average +barbecue +bathtub +begun +belongingness +Better +binary +blackberry +boatswain +bow-tie +brambly +bright-eyed +bubble +Calender +cancellous +cantankerousness +carefree +categorized [categorised, categorise, categorisation, category, decorticated, cauterised, avant-grist] +cellular +chaos +cheerfulise +childlike +circumstance +close-mouthed +Cocoa +coherent +co-located +Colours +controversial +cottage +creditworthiness +cut-down +dedicated +deep-freeze +Definitive +Designs +digital +distensible +dollar +dyslexia +Egyptian +effectively +etiquette +excess +exotica +fairly +feedback +features +figure's +fjord +forty-seven +government +haematomata +helpless +homologous +implant +Indemnify +inexpert +interior +localises +loquaciousness +maelstrom +mechanizable +melodious +mezzo-soprano +mozzie +municipalisation +mystifier +Neoclassicism +newsletter +non-professional +officiation +orientalisation +palaeoanthropography +parrot +pickpocket +pioneer +cryptanalytic +simplifying +sommelier +spicy +steward +subcontinental +swimwear +Technical +trajectory +wholesomeness +Advantageously +interindustry +red-eye +sub-group + +Слова с ошибками [] +Acredited [Credited, A credited, Accredited, Accredit, Accreted, Creditable, Discredit, Acridity, Aegritude] +agressive [aggressive, regressive, digressive, progressive, transgressive, aggressor, expressive] +appreciativiness [appreciativeness, appreciatively, appreciative, appreciation, apprehensiveness, operativeness, provocativeness] +aritmetical [arithmetical, arithmetica, arithmetic, hermetical, antithetical, paramedical, grammatical] +biosyntesized [biosynthesized, nonsynthesised, synthesised, amniocenteses, amniocentesis] +lisense [license, senilise, linenise, sensualise, sensise, licence, licensable] +paranoa [paranoia, paranoid, paranormal, paragon, panorama, Paringa, parental] +fotoelectronic [photoelectronic] +semi transparent [semitransparent, transparentise, non-transparent, transparency, semi-permanent, transpiration, superintendence] +synonymus [synonyms, synonymous, synonym's, synonym us, synonym-us, synonym, anonymous, synchronous, synoecious, anonymise, unanimous] +wordprocessing [word-processing] diff --git a/Common/3dParty/hunspell/test/dst/en_CA.txt b/Common/3dParty/hunspell/test/dst/en_CA.txt new file mode 100644 index 00000000000..a23012fcfa4 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_CA.txt @@ -0,0 +1,125 @@ +admire +admittance +aggrandizement +Airmen +Albatross +amateur +angling +apparatus +Architecture +assessment +attempt's +awakening +backgrounder +Balance's +barometric +bashfulness +beautiful +belletristic +blatancy +bonbon +border +Bottom +bountifulness +breakpoints +bulkiness +businesslike +can't +cash +castle +Casual +cauliflower +celebrity +childish +chokecherry +choreographically +chronological +classification +clearheaded +coalesce +Coexistence +collaborative +coloured's +concentration +draconian +drainpipe +demonstrativeness +dependence +dependency +dream +duplication +epidemiological +equitable +Essence +Exemption +exonerate +fainthearted +falsification +ferromagnetic +flammable +fraternization +French +frontier +gadget +galleria +Gallery +gateaux +geocache +ginger +glace +glacier +globalization +hockey +holiday +housemate +intensifier +joystick +Language +leaseholder +non-breakable +northerly +o'clock +oeuvre +openhandedness +oscillation +outface +outlaw +overladen +package +palazzo +panama +Paragraphs +Parliament +particular +pasteurization +pathogen +perception +phenomena +philanthropically +physical +populations +repugnance +request +resplendence +retroactive +rigidity +schedule's +School +scintillation +sensibility +settlement +taxiway +bereft + +Слова с ошибками [] +acomplishment [accomplishment, accomplish, compliment] +anihilate [annihilate, annihilator, annihilation] +caprise [caprice, cap rise, cap-rise, apprise] +chambre [chamber, chambray] +etnographically [ethnographically, pornographically, photographically, typographically, topographically] +horsmanship [horsemanship, sportsmanship, swordsmanship, marksmanship, showmanship] +innundation [inundation, foundation, annunciation, insinuation, intimidation] +lemongras [lemongrass, lemonades] +omelete [omelette, telemeter] +retorical [rhetorical, oratorical, categorical, theoretical, reportorial] +shepishness [sheepishness, snappishness, waspishness, impishness, foppishness] diff --git a/Common/3dParty/hunspell/test/dst/en_GB.txt b/Common/3dParty/hunspell/test/dst/en_GB.txt new file mode 100644 index 00000000000..3b8b7a1426f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_GB.txt @@ -0,0 +1,122 @@ +Abbreviation +Acceptability +acquirable +Addressee +afterthought +airworthiness +all-powerful +amateurishness +amorphousness +anthology +Auspiciousness +Bibliographer +Bilberry +birthday +bodyguard +broadleaved +brontosaurus +bumptiousness +Cabaret +Californian +calumny +cancellation +cantonal +capitalize +careful +carry-on +casino +clown +co-ordinate +cockleshell +decennial +deckchair +decryption +deep-freeze +Democracy +financial +fish-plate +Flamenco +housing +Hybrid +hydroelectricity +iceboat +ichthyology +idiomatic +ill-humoured +imperatrix +individuality +interocular +intrasectoral +ironwoods +Jolliness +Jurisprudent +knowledgable +kopeks +labour-intensive +laboratory +lake +language +larynx +latching +leakiness +License +licensed +licensee +life-threatening +linguistics +long-lived +machinable +mainsheet +Major +malleability +man-hour +Mango +ninety-five +nobody +non-blocking +non-judicial +nonconforming +north-Western +nutritiousness +quasi-synchronous +question +racoon [raccoon, racoon's, contra] +radish +Railway +Rarity +saucer +Save +Saying +supplely +tallish +target +Taxi +teach-in +technician +ultramodern +umbrae +uncertainness +unconstitutionality +washing +wasn't +waxen +weather +well-formed +what's-his-name +whereupon +Wi-Fi +Wikipedia + +Слова с ошибками [] +Abstractnes [Abstractness, Abstractedness, Abstracter, Abstraction, Abstracted] +advantageusness [advantageousness, advantageous] +arhythmical [rhythmical, arrhythmical, a rhythmical, arrhythmic, arrhythmia] +autosuggestibility [auto-suggestibility] +kaptor [captor] +coldshouldering [cold-shouldering] +humaneneses [humaneness, humanenesses, humannesses, humanness, humanises, humblenesses] +imaginativness [imaginativeness, imaginative, imaginableness, imitativeness] +knight-erantry [knight-errantry, straight-eight] +magasine [magazine, magnesia, imagine] +night-wachman [night-watchman, nightmarish] +qualifidly [qualifiedly, qualified, squalidly] diff --git a/Common/3dParty/hunspell/test/dst/en_US.txt b/Common/3dParty/hunspell/test/dst/en_US.txt new file mode 100644 index 00000000000..a1cd136a72b --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_US.txt @@ -0,0 +1,218 @@ +apple +banana +cat +dog +egg +fish +gold +house +ice +juice +kite +lion +mouse +night +orange +pencil +queen +rabbit +sun +tea +umbrella +vase +watch +xylophone +yellow +zebra +arrow +book +cake +car +day +elephant +flower +hat +island +jelly +king +lamp +moon +nose +owl +pink +quilt +radio +sunflower +tree +unicorn +violin +water +xylophone +yellow +zoo +apple juice [applesauce] +blue +calculator +desk +elephant +fire +goat +hat +ice cream [creamer] +jacket +key +lemon +map +notebook +owl +pear +quilt +rose +soccer +table +umbrella +vegetable +whale +xylophone +yellow +zebra +apple pie [pineapple] +beach +computer +drum +elephant +goat cheese [headcheese] +hat +ice skate [cheapskate] +juice box [jukebox] +kite festival [quite festival] +lemonade +mountain +notebook paper [] +orange juice [orangeade] +pizza +queen bee [quin bee, queen bi, keen bee, ween bee] +rainbow +snow +turtle +umbrella hat [umbrella] +valley +Aberration +Absolution +Acquiesce +Adumbrate +Aesthete +Altruistic +Ambivalent +Anomalous +Antediluvian +Antipathy +Aphorism +Apocryphal +Apostasy +Apparition +Arduous +Assiduous +Audacious +Austere +Autonomy +Avaricious +Axiomatic +Baleful +Bellicose +Belligerent +Bereft +Bilious +Bombastic +Cacophony +Capricious +Cartography +Castigate +Clandestine +Coalesce +Cogent +Cognizant +Colloquy +Concomitant +Confabulate +Congenial +Conundrum +Copious +Corpulent +Coven +Credulous +Culpable +Dearth +Debilitate +Deleterious +Denigrate +Despondent +Diatribe +Dilapidated +Disparage +Dissemble +Dissonance +Duplicity +Ebullient +Egregious +Ephemeral +Equanimity +Esoteric +Euphemism +Evanescent +Exacerbate +Exhort +Expatriate +Extol +Facetious +Fatuous +Feckless +Felicitous +Feral +Fervent +Fetter +Flummox +Fractious +Garrulous +Hegemony +Iconoclast +Idiosyncrasy +Ignominious +Impecunious +Ineffable +Inexorable +Inscrutable +Insidious +Intrepid +Intransigent +Invective +Irascible +Juxtapose +Kowtow +Languid +Lassitude +Lurid +Malinger +Maudlin +Mawkish +Mendacious +Metaphysical +Antransigent [Intransigent, Intransigence, Transient, Intransitive, Transcendent] +Inwective [Infective, Invective, Ineffective, Instinctive, Inactive] +Iracible [Irascible, Acquirable] +Juxtopose [Juxtapose, Juxtaposition] +Kovtow [Kowtow, Kowloon] +Langued [Languid, Languished] +Lasitude [Lassitude, Latitude] +Larid [Arid, L arid, La rid, La-rid, Laird, Lard, Laid, Lurid] +Mallinger [Malinger, Salinger, Lingering, Lingerer, Germinal] +Haudlin [Maudlin, Handling] +Mavkish [Mawkish, Mavis] +Mendocious [Mendacious, Mendocino] +Mitaphysical [Metaphysical, Physicality, Physical] +timeline [time line, time-line, timberline] +rollout [roll out, roll-out, rollover] +workshopped [work shopped, work-shopped, works hopped, works-hopped, workshop] +deliverables [deliverable, deliverable s, deliverers, deliberative, desirable] + + diff --git a/Common/3dParty/hunspell/test/dst/en_ZA.txt b/Common/3dParty/hunspell/test/dst/en_ZA.txt new file mode 100644 index 00000000000..89bb91d321f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/en_ZA.txt @@ -0,0 +1,114 @@ +Acceptably +Achievement +administrate +all-day +amount +average +bilayer +blasé +boutique +breezy +byers +cabdriver +carefree +categorised +Chameleon +cheerful +chronology +cliché +cooling-off +courage +crudités +decorates +dooryard +débâcle +electromotive +equalled +Exotica +fellow-traveller +forests +full-timer +graded +habitué +haven't +hide-and-seek +home-building +interaxial +kingdom +largeness +long-distance +Majority +manoeuvre +Matrix +metier +mightn't +multidisciplinary +night-time +officio +old-style +organize +overaggressive +packing +parenthesis +pince-nez +Plaint +play-act +policy-making +Preheat +prohibit +puzzle +queue +quite +re-enact +reason +ready-made +renewal +resize +rooihout +scampi +schoolteacher +sea-green +shop-boy +sidebar +skyscraper +soundless +spelling +stakeout +synchronizing +take-off +Thereof +Trademark +transportable +treatment +tweeness +under-age +unmake +Variate +Visitant +volume +webmaster +well-prepared +window +yesteryear +first-aid +Hydrant +inconstant +network +northernmost +nowhere +souvenir +telecommunicate + +Слова с ошибками [] +afordable [fordable, affordable, a fordable, formidable, recordable, foreseeable, adorable, avoidable, avoidably] +anthropologie [anthropology, anthropologies] +bagage [baggage, bag age, bag-age, Babbage, garbage, bagged, bagel, bakgat, ribcage] +comparatif [comparative, comparator, compatriot, comparable, comparability, comparably] +flammeble [flammable, flamelike, lamentable, blameless, flamed, flammability, flamboyance] +indivizible [indivisible, individualize, indiscernible, divisible, invincible, indefeasible, inadvisability] +jetlag [jet-lag] +lettrebox [letterbox, treble, storybook, legislature] +panoramma [panorama, Panorama, panoramic, paranormal, Panamanian, pentagram, paramagnet] +posessor [possessor, possess, assessor, processor, professor, poses, posses] +selfdoubt [self-doubt] +abandonner [abandoner, abandon, bandoleer, Ndondondwane, Bannerman, abundance, abundant] diff --git a/Common/3dParty/hunspell/test/dst/es_ES.txt b/Common/3dParty/hunspell/test/dst/es_ES.txt new file mode 100644 index 00000000000..c68b9446d3a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/es_ES.txt @@ -0,0 +1,208 @@ +nosotros +vosotros +ellos +ellas +aquí +allí +ahora +antes +después +siempre +nunca +también +solamente +verdad +mentira +bien +mal +grande +pequeño +rápido +lento +nuevo +viejo +bueno +malo +feliz +triste +bonito +feo +caliente +frío +dulce +amargo +fuerte +débil +cerca +lejos +fácil +difícil +cierto +falso +caro +barato +limpio +sucio +fuerte +débil +alto +bajo +claro +oscuro +abierto +cerrado +joven +viejo +corto +largo +alegre +tranquilo +nervioso +amable +grosero +conocido +desconocido +cortés +rudo +agradable +desagradable +sabroso +insípido +difícil +fácil +cansado +descansado +moderno +antiguo +último +primero +posible +imposible +rápido +lento +sencillo +complicado +propio +ajeno +abierto +cerrado +amable +desagradable +seguro +inseguro +correcto +incorrecto +dulce +amargo +Anacoreta +Sobrentender +Embriaguez +Inquebrantable +Empedernido +Derramamiento +Despotricar +Escafandra +Aletargamiento +Estancamiento +Descarado +Exégesis [Génesis] +Contrariedad +Espeluznante +Conspiración +Impedimenta +Deglutir +Engreído +Enmascarado +Exterminio +Embelesar +Permutación [Permutan] +Desesperanza +Impenetrable +Enarbolamiento [Enarbola miento, Enarbola-miento, Enrollamiento, Arrollamiento, Encarcelamiento, Eslabonamiento] +Errabundo +Deslinde +Inefable +Soliviantar +Embriaguez +Perdurable +Opulencia +Trémulo +Desembolso +Empedernido +Anquilosar +Enigmático +Inquebrantable +Contrincante +Desmesurado +Vanagloriar +Exasperar +Desvanecer +Perpetuidad +Desbaratar +Ineficaz +Zozobra +Elucubración +Ineludible +Desgarramiento +Atestiguar +Encascarar [Encascara, Encascaran, Encascaras, Enmascarar, Encascar, Encascar ar, Encascar-ar, Encascabelar, Encascotar, Enmascaran, Enmascara] +Desembozar +Irreverente +Soslayar +Despiadado +Embaucar +Moflete +Endilgar +Desfalco +Embelesamiento +Desestimar +Enajenación +Desavenencia +Inexorable +Atolladero +Egrégoro [Negror] +Desafiar +Afable +Enervar +Belicoso +Enervar +Descacharrante +Entramado +Inigualable +Perplejidad +Descabellado +Diligencia +Enaltecimiento +Desvergonzado +Arrebato +Empatía [Empata, Empate] +Endiosar +Peripecia +Desidia +Subversión +Desfachatado +Desfalco +Desvirtuar +Errático +Desahuciar +Envilecimiento +Empecinado +Estolidez +Despropósito +Engatusar +Culminante +Sobrentender +Enseñorear +Desacato +segguro [seguro, seg guro, seg-guro, seguiros, segur] +insseguro [inseguro, insegura] +correcto +incarrecto [incorrecto, insurrecto] +dalce [salce, dale, alce, dance, calce, dalle, dulce, d alce, cendal, cebadal, celda] +amergo [amero, mergo, amargo, amelgo, a mergo, amorgone] +Anasoreta [Anacoreta, Masoreta, Trasfretana, Asotanas, Asotanara] +Sobrententter [Sobrestante, Soberanamente, Sobriamente, Soberbiamente] +Embreagues [Embregues, Embragues, Embriagues, Embriaguemos, Embragares, Embrague, Embriague] +Inquebranttable [Inquebrantable, Quebrantable, Infranqueable, Intransitable] +Empidernedo [Empedernido, Empedernecer, Empedernir] + diff --git a/Common/3dParty/hunspell/test/dst/eu_ES.txt b/Common/3dParty/hunspell/test/dst/eu_ES.txt new file mode 100644 index 00000000000..a0335c41c03 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/eu_ES.txt @@ -0,0 +1,132 @@ +Abantza +ñabar +abasto +abegikortasun +aberaskeria +aberetzar +abezedario +abialdi +Abiatzaile +abizari +Aboli +abonatu +absenta +absolutibo +accelerando +adabegitsu +adberbio +adiaka +adierazle +adierazkizun +adikuntza +adin +adinaro +adineratu +adin-txikitasun +administratzaile +adoleszentzia +adopzio +adostu +aerolabangailu +Aeroplano +afalordu +agente +agertezin +agiantza +agoran +arradatze +arrakasta +Batata +baterakuntza +baterakor +Bateri +batuar +baud-abiadura +batzuenganako +batzuengandik +batzuengan +batzuengatik +batzuen +baxera +berezi +berezikeria +beritzete +beroa +Beroate +beroatza +berorri +berrabiatu +berra +berresgarri +berripaper +chap +dabilzkidake +dabilzkie +dagitza +dagokik +dagozkieke +erdiondu +galdera +galtzada +garaitiar +garantia +Garaztaketa +garbitasun +gastronomiko +Gaurgero +gaurgoitik +legizkie +legokizue +legozkidake +lehenbizi +nindoakio +publikotasun +publizitate +subsidiario +substantibo +sugestio +superbalorazio +taidun +taldeburu +Talent +Teknografia +xantxa +xerbitor +xerokopia +zabaldura +Zabalkor +Zabaltza +zabilzkieken +zabilzkio +zaharkote +zeneritzeketen +zenerra +zenezagu +zengozkigute +zeniharduke +zenioke +zenioketez +zeniraute +zenizkien +zenizkiguke +Zintut +Zintuzkedan +isiltasun + +Слова с ошибками [] +abriсot [abrikot, abrigo] +absenzia [absentzia] +addikzio [adikzio, dikzio, adukzio, adizio] +administraziozerbizu [administrazio-zerbitzu, administrazio-zuzenbide, administraziopean] +bat-bates [bat-batez] +bermagari [bermagarri, bermagailuari, bermagailuri, armagaberi, bermaguneari] +cataluniar [kataluniar, catalunyar, kataluniera] +dakarza [dakartza, dakarna, dakarzu] +erdemin [erremin, erdimin, iminerdi] +garatienetarikoa [garatuenetarikoa, ugarienetarikoa, gogoratuenetarikoa, argienetarikoa, aberatsenetarikoa] +ishil [isil, istil] +nindezaguane [nindezaguena, nindezaguan, nindezaguanez, nindezaguanek, nindezaguanen, nindezaguanei, nindezaguana, nindezagunan, nindezagutean, nindezagutenan, nindezaguzue] +nintzainaken [nintzainanek, nintzainake, nintzainakeen, nintzainanen, nintzaiakeenen, nintzaiakeen, nintzakenanen, nintzaiekenan] +summa [suma, susma, sumoa] +technologiko [teknologikoko, teknologiko, terminologiko, etnologikoko] +charmant [charmat, xarmant] diff --git a/Common/3dParty/hunspell/test/dst/fr_FR.txt b/Common/3dParty/hunspell/test/dst/fr_FR.txt new file mode 100644 index 00000000000..9b4428ca524 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/fr_FR.txt @@ -0,0 +1,211 @@ +Bonjour +Merci +Oui +Non +S'il +Excusez-moi +Pardon +Bien +Mal +Grosse +Petit +Beau +Moche +Fort +Faible +Chaud +Froid +Vite +Lent +Haut +Bas +Loin +Près +Heureux +Triste +Facile +Difficile +Simple +Compliqué +Bon +Mauvais +Nouveau +Vieux +Jeune +Âgé +Bienvenue +Amitié +Amour +Famille +Travail +Maison +Voiture +Manger +Boire +Courir +Marcher +Nager +Chanter +Dormir +Jouer +Parler +Écouter +Regarder +Lire +Écrire +Acheter +Vendre +Aller +Venir +Faire +Dire +Voir +Savoir +Apprendre +Aimer +Détester +Partir +Rester +Arriver +Revenir +Partager +Aider +Aimer +Ouvrir +Fermer +Manger +Boire +Avoir +Être +Pouvoir +Vouloir +Devoir +Parler +Écouter +Rire +Pleurer +Danse +Étudier +Travailler +Voyager +Vivre +Connaître +Reconnaître +Voyager +Exister +Choisir +Donner +Recevoir +Aimer +Oser +Phénoménologie +Électroencéphalographie +Parallélépipède +Anticonstitutionnellement +Transsubstantiation +Éclectisme +Anachronisme +Catéchuménat +Démagogie +Fructueux +Ineffable +Hypothèque +Propriété +Procrastination +Complaisance +Réminiscence +Éthique +Équinoxe +Exponentiel +Hétérogénéité +Imbroglio +Incorrigible +Maelström +Métaphysique +Protagoniste +Subliminal +Verrouillage +Volumétrique +Énigmatique +Époustouflant +Immatériel +Infini +Polyglotte +Recrudescence +Prophylactique +Symbiotique +Vestibulaire +Épistémologie +Faramineux +Géopolitique +Hypnotique +Inamovible +Intemporel +Labyrinthe +Pacifiste +Quémandeur +Soporifique +Ubuesque +Volumineux +Effervescence +Électrophorèse +Paradoxe +Prorata +Quadrupède +Sarcophage +Trigonométrie +Vaccinologie [Carcinologie, Actinologie, Vaccinogène, Accidentologie] +Xenophobe [Xénophobe, Technophobe] +Zéphyr +Génétique +Labyrintique [Labyrinthique] +Mégalo +Nostalgie +Omniprésent +Pangramme +Périlleux +Quinquennat +Rémunération +Scolopendre +Tautologique +Utopiste +Vexatoire +Wolof +Xanthine +Yacht +Zanzibar +Axiomatique +Chronométrer +Dilettante +Énervement +Facétieux +Générique +Harmonique +Illusoire +Juridique +Kabbaliste +Longetivité [Longévité] +Médiane +Néologisme +Oxygène +Patronymique +Quotidien +Rétorique [Rétorque, Rhétorique, Rotorique, Ré torique, Ré-torique, Météorique, Torique, Théorétique, Théorique] +Sémantique +Tautologie +Utopique +Vaccinologie [Carcinologie, Actinologie, Vaccinogène, Accidentologie] +Xénophobie +Yachting +Zoroastrisme +Voager [Viager, Voyager, Ouvrager] +Exisster [Exister] +Chaiser [Chaires, Chaise, Chaisier, Chaises, Chasser, Chaise r, Chamoiser, Tchadiser] +Doner [Toner, Zoner, Donner, Drone, Doser, Doter, Dorer, Douer, Doler, Doper, Dîner] +Resevoir [Redevoir, Recevoir, Revoir, Reversoir, Ivoire, Voire] +Aimmer [Aimer] +Osero [Oser, Osera, Oser o, Rosser, Roeser, Rose] +Phénoménollogie [Phénoménologie] +Électraencéphallographie [] +Parallélépepède [Parallélépipède] + diff --git a/Common/3dParty/hunspell/test/dst/gl_ES.txt b/Common/3dParty/hunspell/test/dst/gl_ES.txt new file mode 100644 index 00000000000..74cc6886333 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/gl_ES.txt @@ -0,0 +1,120 @@ +ola +tipo +Si +non +nonnr [nono] +comida +comidaa [comídaa, comidas, comida, comidan] +auga +augaa [áugaa, augas, auga, augaba, augada, augala, augara, augar] +casa +coche +cochee [coches, coche, chochee, cachee, checo] +un tren [oin tren] +bicicleta +escola +escolaa [escóraa, escoala, escolas, escola, escálaa, escolla, escolma, escolar, escolta] +niños +pai +paii [paio, pai, pii, aii, pali, pais] +nai +naii [nai, nii, aii, naif, nais, nazi] +irmá +irmán +cachorro +gato +gatoo [gato, atoo, gateo, gatos] +peixe +peixee [peidee, peixes, peixe, peitee] +aves +avess [aveas, avesa, aves, avesas, avesos, vesas, aveso, aveces, escave] +árbore +flor +herba +o sol [ou sol] +lúa +o ceo [ou ceo, o ceou] +chuvia +neve +vexa +inverno +primavera +outono +noite +noite +día +unha semana [semanalmente] +mes +ano +para ler [parable] +escribir +fala +ensinar +traballo +durmir +durmir +correr +vai +senta +estado +para escoitar [parasitario] +vexa +escoita +hai +beber +carne +furtas +verduras +queixo +pan +auga +zume +café +té +leite +aceite +ovo +sal +impacienta +azucre +un bocadillo [oin bocadillo] +cociña +sala de estar [sala dei estar] +dormitorio +baño +batela +sofá +lámpada +fiestra +a porta [aporta, portara, portador, porta] +piso +teito +parede +sofá +alfombra +baño +afundir +espello +toalla +cama +manta +almofada +reloxo de alarma [riloxo de alarma, ríloxo de alarma, reiloxo de alarma, reloxo dei alarma, relouxo de alarma, reloxou de alarma, relollo de alarma] +escritorio +cadeira +marabilloso +adverbio +obviamente +Dominante +residenciais +convidado +perigo +cuestión +deporte +mina +cordeiro +cabeza +tratar +avogado +intelixente +guapo diff --git a/Common/3dParty/hunspell/test/dst/hr_HR.txt b/Common/3dParty/hunspell/test/dst/hr_HR.txt new file mode 100644 index 00000000000..6ce3b0a0715 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/hr_HR.txt @@ -0,0 +1,215 @@ +boliestan [bolestan, obijestan] +jyak [jak] +slaby [slabu, slab, slaba, slabe, slabi, slabo] +pameetan [pametan, pametna, napamet] +gllup [glup] +bezuspješhno [bezuspješno, bezuspješnih, bezuspješan, bezuspješna] +besimeni [besi meni, besi-meni, bezimeni, besanim] +bezuzban [bezuman, bezuba] +blagastanje [blagostanje, blaga stanje, blaga-stanje, blagostanja, blistanje, oblaganje] +bljeskovica [bljeskovima, bljeskovi, bljeskova, bljeskalica, bljeskavi] +jabuka +sunce +voda +kuća +ptica +kava +kruh +cvijet +knjiga +pas +mačka +grad +zelen +plav +crven +bijel +crn +velik +malen +brz +spor +sretan +tužan +vruć +hladan +nov +star +lijep +ružan +dobar +loš +zdrav +bolestan +jak +slab +pametan +glup +raditi +jesti +piti +spavati +čitati +pisati +govoriti +smijati se [smijati] +plakati +pjevati +igrati +plesati +učiti se [učiti] +kupovati +kuhati +telefonirati +gledati +slušati +hodati +trčati +letjeti +plivati +čitati +pisati +raditi +imati +biti +ići +doći +otići +dati +uzeti +reći +vidjeti +čuti +osjetiti +misliti +htjeti +moći +morati +rado +nerado +da +ne +molim +hvala +doviđenja +oprosti +zbogom +zdravo +čau [ča, ču, čađu, čaju, čamu, času, čađ, čaj, čak, čar, čas, ča u] +ej +da +baš +super +glupost +fantastično +jasno +tako +zapravo +možda +lako +teško +prozračnost +usplahirenost +neoblomivost [neslomivom] +prezir +proigranost [prostranost, programiranosti, razigranosti, pristranost] +uznemirenost +besprijekornost +besprizornost [besprizornom, besprizornoj, besprijekornost, besprizorni] +nepredvidivost +beznadnost +promašenost [promašenosti, promašen, osiromašenom, raspršenost] +protivljenje +neizreciv +bezizlaznost +neuspjelost [neuspjeloj, neuspješnost, neuspjelog, neuspjelom] +zbunjenost +neodlučnost +protivština +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +bezduhovitost [bez duhovitost, bez-duhovitost, duhovitostu, duhovitosti, duhovitosta, duhovitost] +ravnodušnost +prolaznost +neobaveznost [neobaveznosti, neobaveznom, neobaveznoj, neobavezna, neobavezni] +bezbrižnost +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +promašenost [promašenosti, promašen, osiromašenom, raspršenost] +neprepoznatljivost [neprepoznatljivosti, ne prepoznatljivost, ne-prepoznatljivost, prepoznatljivosti, prepoznatljivost, neprepoznatljiva, neraspoznatljivosti] +neukrotivost [neukrotivog, neukrotiv, neučtivost, neotuđivosti] +bezobzirnost +nevinost +nestalnost +nepostojanost +bezizlaznost +nepovratnost [nepovratnoj, nepovratnom, nepovratna, nepovratnima] +prolaznost +neodgovornost +bezbrižnost +nevolja +nezadovoljstvo +prolaznost +bezuspješno +bezimeni +bezuzdan [bez uzdan, bez-uzdan, bezdan, bezdušan, beznadan] +blagostanje +bljeskavica [bljeskalica, bljeskavima, bljeska vica, bljeska-vica, bljeskavi, bljeskalici, bljeskava, bljeskalicu] +boren [borne, obrne, bore, oboren, borbena] +carovnija [otrovnija, darovnica] +crpeža [crteža] +dostojanstvo +duhovitost +egzaltacija +gorkoća [gorkoga, gorkošću] +histerija +idila +ironija +izdaja +janjetina +kajanje +kavana +krhotina +ljepljivost +lukavstvo +magnutizam [zategnutima, zamahnutima, izdignutima, vagnutima] +melankolija +misticizam +naivnost +nelagoda +neraspoloženje +obmana +okrutnost +opojenost [opojnost, obojenost, opojenoj, popunjenost, podvojenost, opčinjenost] +prezir +propast +ravnodušnost +sjenka +skitnica +spletka +stid +sudbina +susret +sudbina +šapat +tišina +trepet +utopija +uzaludnost +veličanstvo +zaborav +zanesenost +zanos +zavjera +zbunjenost +zluradost [zluradosti, zlu radost, zlu-radost, zlurad] +zloslutnost [zloslutnoj, zloslutnom, zloslutnu, zloslutna] +žargon +žártva [žrtva] +šaptanje +čarobnost +dileme +hodočasće [hodočaste, hodočašće] +lebdjeti +iznimka +preobilje [preobilne, preoblikuje] +probuditi se [probuditi] +surov diff --git a/Common/3dParty/hunspell/test/dst/hu_HU.txt b/Common/3dParty/hunspell/test/dst/hu_HU.txt new file mode 100644 index 00000000000..c925ed03d03 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/hu_HU.txt @@ -0,0 +1,114 @@ +Szorzótábla +Réges-régen +normálméret +nemeslelkűség +mindegyik +milliós +Mikroflóra +Mezőgazdaságigép +meséskönyv +mennyiség +Memória +kártya +kuráre +Kurzor +jégkorong +jellemesség +Javak +irányzás +iromány +Inkluzíve +hűtőedény +hőmérséklet +hír +hétszázas +hátrány +háromszáz +Hintó +generátor +gavallérság +explozíva +eső +esdeklés +epilógus +Energia +Előélet +előterjesztés +előnézet +elvonás +elszigetelés +ellátmány +Elevátor +egynémelykor +egyenlőség +eddzenek +dzsungel +ananász +akvárium +Szépül +Sztorizik +szobroz +szimbolizál +szemlélődik +sugdolózik +majmol +Macskáz +Létesít +Lokalizálódik +litografál +levelesedik +lepet +közömbösít +kételkedik +kivirágoz +kerekez +kedvez +járkál +jegyzőkönyvez +iskolázik +individualizál +csendesít +borsoz +billentet +bajmolódik +anyagozik +alkonyodik +Aktualizál +színes +szemelt +lassú +hatékony +hasznos +gyúlékony +gyári +abszurd +örökjog +öregkor +ömlő +Zászlaj [Zászlajú, Zászlaja, Zászlai, Zászlóalj] +Zseblámpa +regényirodalom +realitás +raktárhelyiség +pötty +pótlék +pótdíj +pályafutás +Promóció +Processzus +poloska +pernye +pediáter +parancsnoklás + +Слова с ошибками [] +sponzorálás [szponzorálás, szponzorál, zongorálás] +mihamarábiak [mihamarábbiak, mihamarabbiak, mihamarábbi, hamarábbiak, mihamarább] +idohatár [időhatár] +hypnotizmus [hipnotizmus, nepotizmus] +departement [département] +légiesul [légiesül, légiósul] +kutagat [kutatgat, kutazgat, kutasat, kutakat, kutadat, kutamat, kútagát, kútágat, kútágát, kutat] +költségtakkarékos [költségtakarékos, költségtakarékkos, költséghatékony] +redukzió [redukció, redukáló] +pilanatfelvétel [pillanatfelvétel, pialantfelvétel, adatfelvétel] diff --git a/Common/3dParty/hunspell/test/dst/id_ID.txt b/Common/3dParty/hunspell/test/dst/id_ID.txt new file mode 100644 index 00000000000..2d95d3b7404 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/id_ID.txt @@ -0,0 +1,121 @@ +acang-acang +Adiksi +Adventisius +Advokat +afirmatif +agroindustry [agroindustri, nonindustri] +agrisilvikultur +akhir-akhir +akomodatif +aksi +aljabar +anggul +anotasi +antusiasme +apoteker +bahagia +bakat +bangkang +Bankir +Barikade +bebaru +belar +beleid +bencana +bentangur +beritawan +besuk +bilingualisme +Cecak +Celempong +cencawan +cengkar +ceremai +cermin +cudang +Dampal +dampan +dansa +datung +debitur +defensi +defisit +demper +dendang +Derivasi +Desember +deskripsi +diskotek +diskusi +distansi +dragon +dramatisasi +Eksamen +Eksistensi +eksperimen +ekstensifikasi +ekuitas +elektron +gelut +Geofisikawan +Gerbang +gerempang +influenza +Informasi +Inisiator +insekta +institusional +instruksional +jelajah +Kamrad +Kapilaritas +kapster +kardiovaskular +karismatik +keranjingan +komunal +Limitatif +Linguistik +lintang +masabodoh [masa bodoh, masa-bodoh, mastodon] +matematikus +medisinal +Melankolia +Memorabilia +nasional +nasionisme +Panen +pangkek +peranti +perian +persekusi +perunjung +regenerasi +reglementer +robotika +runjang +Sabtu +Simbang +simpati +tebing +topi +Unggal +unsuri +urbanisasi +variabel +wahana +warganegara [warga negara, warga-negara, negarawan, antarnegara, mancanegara, waranggana] + +Слова с ошибками [] +Abonement [Abonemen, Bombardemen] +Abcente [Absente, Centet] +ambivalan [ambivalen, ambilan, ambalan] +bakteriostatic [bakteriostatik, bakteriolisis] +cekaw [cekat, cekak, cekau, cekam, cekal, cekah, kacek] +darmavisata [darmawisata, darmatirta, mandataris] +declarasi [deklarasi, deflagrasi] +duplex [dupleks] +ecozona [ekozona, eco zona, eco-zona] +gempur-mengempur [gempur-menggempur, gempul-gempul] +jejengok [jejengkok, jengkeng] +transitive [transitif, transvetisme, transit, transisi] diff --git a/Common/3dParty/hunspell/test/dst/it_IT.txt b/Common/3dParty/hunspell/test/dst/it_IT.txt new file mode 100644 index 00000000000..5b9d3363bd9 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/it_IT.txt @@ -0,0 +1,200 @@ +Ciao +Ciaoo [Ciao, Ciano, Ciao o, Ciocia] +Buongiorno +Buonasera +Buonassera [Buonasera, Buon assera, Buon-assera, Buonalbergo] +Grazie +Prego +Arrivederci +Buonanotte +Scusa +Per favore [Favorevole] +Amore +Amico +Famiglia +Casa +Città +Strada +Montagna +Montaga [Montagna, Montata, Montana, Montala, Montava, Montaggi, Montaguto, Montano, Montato] +Mare +Sole +Luna +Stelle +Giorno +Notte +Colazione +Clazione [Colazione, Coazione, Cl azione, Cl-azione, Clonazione, Collazione, Clorazione, Chelazione] +Pranzo +Cena +Acqua +Vino +Caffè +Pane +Formaggio +Pasta +Pizza +Gelato +Dolce +Salato +Frutta +Verdura +Carne +Pesce +Pollo +Uovo +Sale +Pepe +Olio +Burro +Zucchero +Latte +Yogurt +Insalata +Zuppa +Bistecca +Prosciutto +Parmigiano +Biscotti +Cioccolato +Spagggrhetti [Spaghetti, Spaghetteria] +Spaghetti +Lasagne +Risotto +Gnocchi +Penne +Ravioli +Cannelloni +Pesto +Caprese +Limoncello +Espresso +Cappuccino +Tiramisù +Panna cotta [Panbiscotto] +Cannoli +Panettone +Brioche +Focaccia +Foacdccia [Focaccia] +Crostini +Arancini +Antipasto +Primo piatto [Rimpiattato, Primariato, Rimpiatto, Rimpatriato] +Secondo piatto [Attosecondo] +Contorno +Pane tostato [Tostapane] +Marmellata +Accoglienza +Affascinante +Aggressività +Alleviare +Appassionato +Armonioso +Autonomia +Autovfnomia [Autonomia, Autotomia] +Barbarie +Beneficiare +Bizzarro +Burocrazia +Cambiamento +Capriccioso +Cautela +Commemorare +Comportamento +Conseguenza +Controverso +Coraggioso +Debolezza +Decisivo +Delizioso +Desiderare +Destrezza +Determinato +Determin [Determina, Determini, Determino, Determinò, Termine] +Difficoltà +Disponibilità +Divertimento +Eccentrico +Efficienza +Elettrizzante +Emergere +Empatia +Energia +Equilibrio +Esperienza +Fantastico +Fenomenale +Generosità +Gratitudine +Immaginazione +Impressionante +Impressiante [Impressi ante, Impressi-ante, Impressionante, Impressionate, Imprestante, Impressioniste] +Indipendenza +Ingenuità +Innovazione +Intelligenza +Intensità +Intrigante +Ispirazione +Instabilità +Irresistibile +Leggenda +Libertà +Luminoso +Magistrale +Malinconia +Meraviglioso +Metamorfosi +Miracolo +Misterioso +Nostalgia +Opportunità +Originalità +Passione +Pericoloso +Prestigioso +Prodigioso +Prospettiva +Raffinato +Rafinato [Raffinato, Rapinato, Affinato, Trainato, Raffrenato, Raffilato] +Ricchezza +Rispettoso +Sensibilità +Sorprendente +Spontaneità +Spontaneita [Spontaneità, Spontaneista] +Stravagante +Suggestivo +Surreale +Tenerezza +Trasformazione +Unicità +Vibrante +Vittoria +Volontà +Amicizia +Avventura +Bellezza +Calma +Danza +Eleganza +Felicità +Gioia +Incanto +Magia +Natura +Odore +Passatempo +Quotidiano +Relax +Serenità +Tesoro +Umorismo +Vacanza +Zelo +Avventuriero +Speranza +Risate +Armonia +Incanto diff --git a/Common/3dParty/hunspell/test/dst/kk_KZ.txt b/Common/3dParty/hunspell/test/dst/kk_KZ.txt new file mode 100644 index 00000000000..3547d29f053 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/kk_KZ.txt @@ -0,0 +1,209 @@ +сөз +адам +қала +тау +ауа +су +аспан +жер +бала +ата +ана +тамақ +кітап +ұстаз +оқу +тұтыну +тыныш +тұз +ауру +денсаулық +топ +маусым +төс +көз +жүрек +сарғыш +көп +аз +ертең +түн +түс +жас +қара +ақ +көк +қызыл +шай +салт +ыстық +суық +қазақ +жеті +он +жүз +мың +бір +екі +үш +төрт +бес +алты +жеті +сегіз +тоғыз +он +бақша +бұлақ +қиыр +досым +ақша +патша +таң +кеш +тауар +күн +апат +риза +ауырсыну +орман +жаңбыр +бауыр +жел +тұман +үй +бұлақ +көше +айнала +шайыр +тағам +сусын +топ +бас +әрекет +тіл +кеме +сиыр +қой +ешкі +шөп +ит +тұқым +қарындаш +апа +ана +әке +дала +тарлау +дәуір +таңдай +жыл +басқарушылар +басқарушшылар [басқарушылар, басқарушы, басқармасылар, басқаруғалар, бақылаушыларлар] +жауапкер +ерекшеліктерімендерге +тұмылдырықтатқыздан +білімділігінге +білімдарды +алалықсыздар +айырмашылықтарын +тұрақтандырып +сылтауратқандарыңызды +қолдар +байланысқадан +жетілдірілген +зарарсыздандырады +ескеріп +ескеріпп [ескеріп, ескеріпі, ескеріле] +міндеттемелеріндерге +кезеңдердің +себепсіздік +біреудейлер +беделілерің +кездестіріңіз +шектердің +көңіл +көңл [көң, көл, көңіл, көңі] +мол +алайда +мәселе +мәселеу [мәселе, мәселең, мәселен, мәселес, мәпелеу, мәуелеу, мәселем, мә селеу, селеу] +сендің +келер +келерр [келер, керлер, келері, кереле, еркеле, кермеле, келекеле] +кәне +көпір +күндіз +сана +белгілер +дайын +ез +қайшы +саф +рең +шақ +үміткер +бақыт +бақытт [бақыт, бақытта, бақытты, бақырт, бақыты] +республика +консервациялау +мемлекеттік +тағатсыздан +адамда +бәрі +бең +беңр [бең, бер] +жасағанда +жасағоанда [жасағанда, жасалғанда, жасасқанда, жасаманда, жасақанда] +жабайылық +заманда +көшірдік +мерейі +Мерейій [Мерейі, Мерейің, Мерейім, Мерейлі, Мерей, Мейір] +мөлшерсіздікк [мөлшерсіздік, өлшемсіздік, мөлшерсіз, өлшеусіздік] +мөлшерсіздік +пенді +тылда +мәртебесімен +аппаратпен +тегінді +кездеме +ересектік +көңілсіздік +тәуекелсіздік +қанағатсыздық +ғаділетсіздік +сайдақы +басым +тәжікеден +тұрғын +қонақ +қауіпсіздік +қадірсіздік +білгішсінбейсіңдер +талқандас +кешікті +қоздырғышы +бас +емдейсіңдер +құқылы +тақылет +әдемі +көткеншектейсіңдер +әжет +қайтар +белсену +түсінбеймін +жағымсыздық +сыздар +мәртебесі +тұрғыны +мезгіл +әлбетте +барысын +оқылған +безге +жаса +аламаңдайсыңдар +кереметті +епетейсіздік diff --git a/Common/3dParty/hunspell/test/dst/ko_KR.txt b/Common/3dParty/hunspell/test/dst/ko_KR.txt new file mode 100644 index 00000000000..5d30797f0cc --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ko_KR.txt @@ -0,0 +1,157 @@ +안녕하세요 +감사합니다 +사랑해요 +미안합니다 +음식 +친구 +가방 +집 +학교 +컴퓨터 +물 +밥 +책 +산 +바다 +날씨 +일 +노래 +치킨 +반찬 +꽃 +숙제 +가족 +아이 +게임 +영화 +생일 +시간 +동물 +여행 +차 +쇼핑 +추천 +대화 +전화 +사진 +운동 +잠 +병원 +음료수 +능력 +주말 +전자기기 +고양이 +강아지 +바나나 +가을 +겨울 +봄 +여름 +옷 +신발 +지하철 +택시 +버스 +비행기 +샴푸 +브러시 +삼계탕 +국수 +불고기 +된장 +김치 +먹다 +마시다 +보다 +듣다 +놀다 +하다 +가다 +오다 +서다 +늦다 +일어나다 +자다 +빨갛다 +파랗다 +노랗다 +녹색 +보라색 +맛있다 +시원하다 +덥다 +추운 +기분 +슬프다 +즐겁다 +정신이 +바쁘다 +참새 +나비 +병아리 +돌 +물고기 +향신료 +시장 +기차 +공원 +해변 +지갑 +병원 +대학 +교통 +공항 +천재 +연구 +일본 +중국 +사업 +지식 +성격 +자금 +기술 +정부 +전략 +협력 +혁신 +경제 +철학 +신체 +영감 +현상 +역사 +태양 +설명 +사회 +환경 +자연 +현실 +존경 +정확 +장애 +낙관 +발전 +절망 +일상 +소멸 +도전 +반복 +포기 +파괴 +혁혹 [현혹, 혈족] +소외 [쇠오, 소아, 시외, 소오, 소에, 소의, 소와, 소요, 소유, 소위, 소야, 소되, 소뇌, 소 외, 소외감] +식민지 +혐오 +출산 +행복 +불평 +판매 +위험 +안녕하ㅎ요 [안녕하다] +감사합ㅅ다 [감사하다, 감사하여가다, 감사해가다] +사랑ㄱ해요 [사랑해요, 사랑해내요] +미안ㅎ합니다 [미안합니다, 미안한체합니다, 미안할만합니다, 미안해갑니다, 미안하여갑니다] +친ㅔ구 [친구] +가ㅎ방 [가방, 감방] + diff --git a/Common/3dParty/hunspell/test/dst/lb_LU.txt b/Common/3dParty/hunspell/test/dst/lb_LU.txt new file mode 100644 index 00000000000..37c698dbc9c --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lb_LU.txt @@ -0,0 +1,118 @@ +Aarbecht +Aarbechtszäitorganisatioun +Aartgenoss +Abenteuer +abrëll [Abrëll, brëll] +absence [Absence] +Abusives +Abzebillercher +Acquéreur +Adjointeë +Affischéiertes +Airbussen +Alldeegleches +Angschtzoustä +Basketballspiller +Baufirme +bauren [Bauren, bauen, brauen] +bekanntes +Beleg +Berodung +Bewältegung +Datentransfer +Dateschutz +Decisives +Donneschden +Drangsaléiertes +Dränk +Giischtgen +Grondlag +grondreegel [Grondreegel, grondleeënd] +Géies +Handelsdag +hausaufgab [Hausaufgab, ausbaufäheg] +hierschtdag [Hierschtdag, hierarchescht] +Häerzi +Industriell +Infrastrukturelles +Interessi +Internetfore +Intervall +Kamell +Kantoner +Karamell +Klenges +Nopeschhaus +Motors +Muer +Muerenter +Musek +Nettoverméige +niess [miess, Niess, iess, giess, Siess, Fiess] +Protektioun +Prouf +Provisioun +Prozessor +Präis +Präsens +Sanitäres +Schauspiller +Schema +Taxatioun +Telefonsgespréich +termingrë [Termingrë, verminnte] +terrass [Terrass, zerrass] +Textdatei +Textsprooch +Titulaire +Titel +erausféieren +erausjoe +gëeicht +onglécklecherweis +unzesammelen +unzespille +Approvisionnement + +Сложные слова [] +Aktiegesellschaft +Aktivitéitsdéclaratioun +Alarmstëmmung +Allgemengverständleches +Bankenoperatioun +Bensinsreserven +Besteierungsofkommes +Diskriminéierungsmoossnam +Dokumentatiounsaarbecht +Haaptrecommandatioun +Héchstgeschwindegkeet +Héichproblematesches +Hëllefsdéngscht +Integratiounsméisseges +Iwwersetzungsprogramm +Kapitaliséierungsdimensioun +Museksinstrument +Publicitéitsmarché +Transportproblem + +Слова с ошибками [] +Abonnnement [Abonnement, Joresabonnement, Abonnenti, Abonnent, Agebonnent] +Accomodéiertes [Accommodéiertes, Accommodéiert, Accordéiertes, Accommodéiers] +Agrarcenter [Agrarzenter, Agrozenter] +Begrennung [Begrënnung, Begrenzung, Benennung, Verbrennung, Begrenzen, Trennung] +Berodunszentren [Berodungszentren, Berodungszentre, Berodungszentr, Berodungszenter] +Deeluung [Deelung, Andeelung, Opdeelung, Verdeelung, Zelldeelung] +Dialogue [Dialoge, Dialog] +Dictaten [Diktaten, Dichten] +Inspektor +Iwereileges [Iwwereileges, Iwwereilegtes, Iwwereileg, Iwwerfälleges] +Pedagogik +Televisionschaîn [Televisiounschaîn, Televisiounsgeschäft] +Bechäftegungsméiglechkeet [Beschäftegungsméiglechkeet] +Gläicheetspolitik [Gläichheetspolitik, Sécherheetspolitik, Gesondheetspolitik, Geschäftspolitik, Dechetspolitik] +Musekheichschoul [Musekhéichschoul, Museksschoul] +Satelliten [Satellitten, Satellitte, Satellit] +Addressbichelchen [Adressbichelchen, Reklammbichelchen] +Aarbechtsfield [Aarbechtsfeld, Aarbechtsgefier, Aarbechtsblieder, Aarbechtsatelier, Aarbechtsalldag] + + diff --git a/Common/3dParty/hunspell/test/dst/lt_LT.txt b/Common/3dParty/hunspell/test/dst/lt_LT.txt new file mode 100644 index 00000000000..09068f6d859 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lt_LT.txt @@ -0,0 +1,127 @@ +Abstraktus +šachmatai +žadintoja +agurkas +Aikštė +Akinukai +akmuo +šakoti +aktualinti +aktorius +šalinis +šaltinis +bernystė +beskuo +būgnelis +Bilietas +bilingvizmas +daržavietė +Darbadienis +Darbas +darbuotoja +dargi +daržinė +daugintoja +Daugiaveiksmis +delnė +įdelnis +detalizuoti +šerdelė +erdvėti +šeriškas +šeštadienis +etiketas +Evoliucija +fabrikantė +Fantastika +Fenomenas +fikusas +gaudinėti +gausėja +gūbrinti +geležis +geležtė +gelsvis +geranoris +Gertys +gerviukas +giesmininkė +Gikas +Goža +griaustinis +grįžinys +gėrioja +griozdas +grizijo +gryčia +grožėja +grįžti +grupė +gąstauti +Jaukas +jodinėjo +jodyti +keturnagis +Kiaušina +Kiaurymė +kiausta +kietakaktis +ūkiškas +kilimėlis +kilometrinis +ūkininkaitė +ūkinis +krykti +lapuotis +laukas +laupti +laužtė +Maudulys +Maumedis +mažutėlis +mazgotuvė +mechanikė +medeinė +medikamentinis +meduolinis +Nūdien +nebrendėlė +Negu +neiginys +parudenys +pasakotojas +pasausė +pasieninis +paskyriui +paslapčiom +Pasodas +Pat +Pataikūniškas +patarška +patentinis +proskyna +protekiniais +provizoriškas +rėkčioti +rūmas +rodyklinis +Romanistas +Skylmatis +Skyriklis +skolininkas +skraidžioja +skruzdėda +skėtrus + +Слова с ошибками [] +Abbreviatūra [Abreviatūra, Klaviatūra] +alpinismas [alpinsimas, alpinimas, alpinistas, alpinizmas, alpinistinis, alpinistini, alpinamas, alpinariumas] +amortizacia [amortizacija, amortizacini, amortizavo, amortizuoti] +daugiamžis [daugiaamžis, daugiaamži, daugiamatis, daugiametis, daugiažiedis] +deziderativinis [dezideratyvinis, dezideratyvini, prezidentinis, rezidentinis] +generazija [generacija, energija] +keturiasdešimtūkstantas [keturiasdešimttūkstantas, keturiasdešimttūkstanta, aštuoniasdešimttūkstantas, šešiasdešimttūkstantas, aštuoniasdešimttūkstanta] +krivuluoja [krivuliuoja, kreivuliuoja, kultivuoja] +Šnaukstai [Šnaukštai, Niaukstai, Šniauktai, Šniaukštai, Auksintai] +pazintinis [pažintinis, parazitinis, pantinis, patentinis, panteistinis] +progresa [progresai, progresas, progreso, progrese, progresu, progresą, progresų, progresavo, progresija] diff --git a/Common/3dParty/hunspell/test/dst/lv_LV.txt b/Common/3dParty/hunspell/test/dst/lv_LV.txt new file mode 100644 index 00000000000..6cd9ccc2a0d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/lv_LV.txt @@ -0,0 +1,205 @@ +Sveiks +Sveikks [Sveiks, Sveikas, Sveikās, Sveikts, Sveikus, Sveikos, Sveikt, Saveiks, Ieveiks, Veiks] +Labrīt +Lbrīt [Larīt, Lorīt, Labrīt] +Paldies +Paldiess [Paldies, Paliess, Palaidies] +Lūdzu +Luzu [Lizu, Ludzu, Auzu, Zuzu, Guzu, Lauzu, Lupu, Lubu, Lugu, Lūzu, Luču] +Atvainojiet +Atvainvfojiet [Atvaimanājiet] +Prieks +Perieks [Peries, Prieks, Persiks] +Draugs +Dravfugs [Draugs] +Ģimene +Gimene [Ķimene, Ģimene] +Māja +Maja [Maija, Paja, Raja, Laja, Maža, Maka, Mija, Mana, Masa, Māja, Mata, Maša, Maza, Mala] +Pilsēta +Pilseta [Pilsēta, Pil seta, Pil-seta, Piebilsta] +Ceļš +Ceļšs [Ceļš, Ceļošs, Ceļas, Ceļus, Ceļos] +Kalns +Jūra +Sauls [Auls, Kauls, Rauls, Pauls, Salus, Sauks, Sals, Saules, Sakuls, Saulēs, Saguls, Sulas, Salsu, Sauli, Sauss] +Mēness +Zvaigznes +Diena +Nakts +Brokastis +Pusdienas +Vakariņas +Vīns +Kafija +Maize +Siers +Makaroni +Pica +Saldējums +Deserts +Sāļš +Augļi +Dārzeņi +Gaļa +Zivis +Vistas +Ola +Sāls +Pipari +Eļļa +Sviests +Cukurs +Piens +Jogurts +Salāti +Zupa +Salds +Šokolāde +Spageti +Rīsi +Kakao +Biezpiens +Kūka +Tēja +Karalis +Zelts +Ezis +Tulpe +Lācis +Kaķis +Suns +Putns +Vārna +Zaķis +Pele +Ābols +Aita +Zirgs +Lauva +Pūķis +Lasis +Vilks +Vējš +Uguns +Ūdens +Zeme +Debesis +Saule +Rūpniecība +Aizkustinošs +Izdzīvošana +Nepieciešamība +Atbildība +Lieliski +Apmierināts +Neparasts +Izglītība +Sarežģīts +Atsevišķs +Pamatots +Organizācija +Sadarbība +Efektīvs +Daudzveidīgs +Novērtēt +Pārsteidzošs +Inovatīvs +Vērtība +Aizraujošs +Nopietns +Komunikācija +Māksla +Dzīvība +Ekskluzīvs +Tehnoloģijas +Rezultāts +Atbalsts +Nodrošinātība +Pārbaudīt +Radošs +Sociāls +Izteiksmīgs +Brīvība +Pieredze +Ietekme +Pārmaiņas +Drosmīgs +Racionāls +Empātija +Izpratne +Risinājums +Iespējas +Atklāts +Vadošais +Eksperimentāls +Neatkarība +Tīrība +Samierināšanās +Motivācija +Harmonija +Dinamisks +Iedvesma +Izglītojošs +Komplicēts +Pieejamība +Sadarbība +Tūlītējs +Saprotams +Neizsakāms +Lieliskums +Inovācijas +Aizrautība +Pārdomas +Sapratne +Rezultatīvs +Iespējams +Pārbaude +Sociālais +Izteiksme +Brīvība +Pieredzējis +Ietekmīgs +Pārmaiņu +Racionāla +Izpratni +Risinājumi +Iespējams +Atklāta +Vadošā +Eksperimentāla +Neatkarība +Tīra +Motivējošs +Harmonisks +Dinamika +Iedvesmojošs +Spēks +Mīlestība +Pasaule +Daba +Skaistums +Miers +Sapnis +Prieks +Rītausma +Brīnums +Izcils +Saikne +Dzirksts +Pārmaiņas +Atbalsts +Izcilība +Satriecošs +Dzīvīgums +Pārveidošana +Uzdrīkstēšanās +Uzticamība +Ieguldījums +Vērtība +Līdzsvars +Saskaņa +Izsmalcinātība +Pateicība +Atzinība +Pārsteigums diff --git a/Common/3dParty/hunspell/test/dst/mn_MN.txt b/Common/3dParty/hunspell/test/dst/mn_MN.txt new file mode 100644 index 00000000000..b590811bfcd --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/mn_MN.txt @@ -0,0 +1,103 @@ +Баатар +Багаа +Базар +Барра +Бат-Очир +Баттуул +Батхэсэн +Баярмаа +Билгэх +Бор +Бөөнцагаан +Бүрэнхайрхан +Бямбагар +Бэх +Гарам +Гантиг +Гурвантэс +Гүр +Гэрэлтуяа +Давст +Дангаа +Дансран +Дарь-Эх +Дөргөн +Дундбүрд +Дэмүүл +Дэлгэрцэцэг +Жавзан +Жарантай +Заглул +Зүүнхөвөө +Кир +Корона +Лүн +Лха +Лхаваан +Майхан +Манлай +Мөндөөхөө +Мөнхөт +Мөрөн +Мөнххаан +Мөст +Мэгэд +Мухар +Найдалмаа +Найтингейл +Налайх +Нарантуул +Намтай +Насантогтох +Номин +Нямсамбуу +Нэүдэй +Орог +Очир +Өнөржаргал +Өөдөс +Өргөн +Паган +Пас +Пүрэвдорж +Пүрэвхүү +Сайнаа +Сайхандулаан +Сундуй +Сэлх +Сүүж +Сээр +Тайван +Тарав +Тогтуун +Төрболд +Төхөм +Төмөр +Түргэн +Түшиг +Түгтөмөр +Түшиг +Удвал +Улиастай +Улаандэл +гүедэцгээчих +дэвхэрлүүлсхийчих +дэвхэлцгээчих +дэвшигдүүлгэчих +дэвшилцчих +дэвээ +дэггүйчүүд +наламгардуулалц +налбаруулзна + +Слова с ошибками [] +Батарчулуун [Баатарчулуун, Батар чулуун, Батарч улуун] +Баруунхарааа [Баруунхарааг, Баруунхараа, Баруунхараагаа, Баруунхараад] +Даважаргал [Даваажаргал] +Дөрволжин [Дөрвөлжин] +Мягмараран [Мягмараар, Мягмарнаран] +Оюунтулхуур [Унтуурхуул] +оторчилсхилгэ [оторчилсхийлгэ, оторчилсхийчих, оторчилсхий, отогчилсхийлгэ, хорчилсхийлгэ] +Асрамжлулгацгаачих [Асрамжлуулгацгаачих] +гүентүүлгэцгэээ [гүентүүлгэцгээе, гүентүүлгэцгээ, гүентүүлгэцгээгээ, гүентүүлгэцгээж, гүентүүлгэцгээн, гүентүүлгэцгээнэ, гүентүүлгэцгээв, гүентүүлгэцгээг, гүентүүлгэцгээх, гүентүүлгэцгээм] +наладаадуулга [налдаадуулга, наадалдуулгаа, наадалдуулга, налдаадуулцгаа, наадамдуулгаа] diff --git a/Common/3dParty/hunspell/test/dst/nb_NO.txt b/Common/3dParty/hunspell/test/dst/nb_NO.txt new file mode 100644 index 00000000000..37cb4b46e62 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nb_NO.txt @@ -0,0 +1,113 @@ +Bahamasøyene +Festarrangement +Festarrangemang [Festarrangement, Festarrangør, Fellesarrangement, Storarrangementa] +Festival +festligheta +festnummer +forhandlernett +forgylle +fotballstyre +Fotgå +fotoamatørene +Fotogalleri +fotokopiere +generalkostnadene +generaltabbe +generøs +Generell +genmodifisertst +handlingsresymeet +hardhet +Harmfull +hastighetsregulering +havbanke +havforskningsundersøkelsene +informasjonsutveksling +Infrarødest +kaffeautomat +kaldslig +kalenderåra +kjekk +kjendisstoffa +kjærlighetslyrikk +kjøkken +Kontantautomat +kontantlån +kontrahere +kontraheringsplikt +Låskasse +læregutt +læreprosess +Museums +museumssamling +musikkorps +myggstikka +myndighetsaldere +omløpstider +omregn +områdeplan +omriss +omsetningsgjeld +omsjaltning +omsetningsvolumer +omslutning +omslyngning +omsonst +omstendeligheta +Omstart +Omstreifende +Omsyn +omtåketheta +oppdagelse +oppbygning +oppebære +oppfølgingsapparat +oppgjørsbank +oppgjørsblankett +opphøringene +partisipere +randverdi +rapportskriver +rasjonalisering +Rate +selsak +selskapsinntekt +selskapsoverskudd +selvbetjeningene +snabbingene +Snadderene +Sytti +søkekriterium +søkemulighetene +søkeargumenter +søkingen +søkne +sølvlaga +sørlandsk +søtningene +tabellrad +Tabellkolonne +Takhalm +taksene +takseringssystema +tal +trolsk +trosinnholdene +utfoldelsesmuligheta +Utformingsmetode +Utgift +vekstfaktor +vekstforhold + +Слова с ошибками [] +Arbeidstagerorganisasion [Arbeidstagerorganisasjon, Arbeidstakerorganisasjon, Arbeidsgiverorganisasjon, Sosialarbeiderorganisasjon, Arbeiderorganisasjon] +festsprel [festsprell, festsprek, festsprelt, festspell, feltprest, fengselsprest] +forhandlingsdirektor [forhandlingsdirektør, forhandlingssekretær, forhandlingstekniskere, forhandlingstaktiskere, forhandlingskontor] +handlingforløpa [handlingsforløpa, handling forløpa, handling-forløpa, handlingsforløp, lønnsforhandlinga, lønnsforhandling, forhandlingspart] +kjempeflinktt [kjempeflinkt, kjempeflinkest, kjempeflink, kjempeflott, kjempefint] +lanetilbud [lånetilbud, langetilbud, landetilbud, linetilbud, laketilbud, langtilbud, lagetilbud, landtilbud, danetilbud, lunetilbud, vanetilbud, fanetilbud, banetilbud, hanetilbud, kantinetilbud] +omraming [omramming, omringing, omringning, ramming, omring] +omsvøpssfull [omsvøpsfull, omsvøpslaus] +raportmateriale [rapportmateriale, kartmaterialer, kartmateriale, programmateriale, skrapmateriale] +serstilt [særstilt, ser stilt, ser-stilt, seerstilt, tverrstilt, storstilt, lederstil, stiliser] +taksamst [takksamst, takksamt, takksam, samletakst, samstav] diff --git a/Common/3dParty/hunspell/test/dst/nl_NL.txt b/Common/3dParty/hunspell/test/dst/nl_NL.txt new file mode 100644 index 00000000000..ce7cdbafcca --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nl_NL.txt @@ -0,0 +1,115 @@ +Advertentie +Advocate +affirmatie +afgevaardigd +afneemster +allerbekendst +alternatieveling +annulering +anticycloon +Backtrackroute [Jacktrackroute, Backtrackrouten, Baktrackroute, Backtrackroute-, Backtrack-route, Back-trackroute, Backtrackroutes] +Bearbeiden +becijfer +bediening +bedrag +beduiden +beïnvloeding +benadeling +bepaaldelijk +Catalogiseer +Catering +cellulair +classificator +collaboreren +collectiviteit +comfortabel +complimenteus +contractant +correctionaliseren +daaraanvolgend +dagelijks +deelgenoot +degelijkheid +demarqueren +Denotative [Denotatie, Denominatieve] +deposant +dergelijken +detail +deugen +diakritisch +Directioneel +dusgenaamd +eendrachtigheid +Eenzaamheid +eersteklascoupé +Eigenschap +felicitatietelegram +centerkanaal [centerkabaal, enterkanaal, centerkanaal-, center-kanaal, callcenter] +Chargeer +filiaal +klare +Klassikaal +kleinhandel +evolutie +exemplaar +exequiën +familiaal +fauteuil +luister +magistratelijk +perelaar +Permitteren +Perseveratie +persoonlijk +pictogram +pixel +sloten +sluimer +sneltoets +Soldij +Solliciteren +zegepraal +zelfbeeld +zevendaags +aangeslotene +meermaals +expedieert +jaargetijden +kaderleden +Kapitelen + +Сложные слова [] +avontuurlijkheid +bedrijfsmaatschappelijk +begrotingstechnisch +belangstellingssfeer +concurrentievoordeel +conferentieganger +democratisch-liberaal +discontoverhoging +doctoraatsverhandeling +dubbeldeksbus +economisch-financieel +energiezuinig +erkentelijkheid +evenwichtigheid +klimaatsverandering +koffiezetmachine +koopmansgebruik +maatschapsovereenkomst +personeelsconsulent +sociaalwetenschappelijk +zelfverzekerdheid +fondsenwervende + +Слова с ошибками [] +afficher [affiche, afficheer, affiche-, affiches] +algorithme [algoritme, algoritmiek] +beeindiging [beëindiging] +client [cliënt] +consnteren [consenteren, contesteren, constateren, consulteren, confronteren] +deactivieren [deactiveren, deactiveerde, reactiveren, deactiveert, geactiveerden] +deblockering [deblokkering] +electrisch [elektrisch] +certificat [certificaat, certificatie, certificeert, certificeer, certificeren] +sovereiniteit [soevereiniteit, suzereiniteit, sereniteit, universiteit] diff --git a/Common/3dParty/hunspell/test/dst/nn_NO.txt b/Common/3dParty/hunspell/test/dst/nn_NO.txt new file mode 100644 index 00000000000..90d328d8e3a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/nn_NO.txt @@ -0,0 +1,116 @@ +Ankeret +Anleggsbedrift +Annandag +annonseavis +annuell +ansats +ansvarsmedviten +Antibiotikai +apal +apoteki +apparattavlor +appetitt +Aprikos +arbeidsdokument +arbeidsmarknad +barndom +bastematte +bautingi +Bedriftsleiar +befolkningi +begynnarkurs +Beheld +belastningi +beredskapsnivå +beredskapsperiode +berglandskapi +berrfrost +beskjedi +beskrivingi +betalingsoppdrag +betalingsplikt +bevismateriale +bildeband +bildebruki +bildespråki +bildeteksti +bilingval +billettlukone +binær +bione +bjørkegreini +bjørnebæri +blenge +blokkeringi +blomsterbordi +blyerts +bogen +bokstavrekningi +bokstavteikni +Borddisk +effektevaluering +elgkalv +Elone +emballer +faktainformasjon +familiebedrifti +familieterapeut +fastbuande +Februar +feili +fisketom +hengelåsi +istandsetjingi +Item +jaguar +jamlig +janen +jarnbanestasjon +kjende +kjentfolki +kjæleri +kjøledisk +kjørety +midli +Mideftnar +midtstrek +multiplikasjonstabell +museumsdirektør +onsdag +operasjon +operasjonskode +opinionsskapingi +opningi +Personalkonsulent +Personligdom +persontryggleik +petroleumspris +redningsaksjon +reduksjon +refusnik +seinst +sekretær +seljande +sendeferd +Standpunkt +støyisolering +støytvis +terminoppgåve +tidløysone +tidsfølgjone +Tilbakebetalingstid +uprofesjonell +upåklageleg + +Слова с ошибками [] +Anlegsarbeid [Anleggsarbeid, Tvangsarbeid, Grunnlagsarbeid, Føregangsarbeid, Bergingsarbeid] +anonse [annonse, nonsens, anse] +ansversproblematikk [ansvarsproblematikk, vurderingsproblematikk, ventelisteproblematikk, valdsproblematikk, drivhusproblematikk] +barneforteling [barneforteljing, barnefordeling, barneforsking, barnefarforelegg, barnebefolkning, barnebortføring] +besoksliste [besøksliste, sortsliste] +bilophoggingi [bilopphoggingi, bilopphogging, opphogging] +effektivitetskontrol [effektivitetskontroll, effektivitetsforskjell, effektivitetsproblem, effektivitetsnøytral, effektivitetsforbetring] +fakturaerklering [fakturaerklæring, faktureringsliste, overfakturering] +miljøbyrad [miljøbyråd, miljøby rad, miljøby-rad, miljøbragd] +selskapskat [selskap skat, selskap-skat, selskaps kat, selskaps-kat, selskapsskatt, selskapskapital, selskapsrett, selskapstype] +cement [sement, dement, centime, cent] diff --git a/Common/3dParty/hunspell/test/dst/oc_FR.txt b/Common/3dParty/hunspell/test/dst/oc_FR.txt new file mode 100644 index 00000000000..26c580cdf5f --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/oc_FR.txt @@ -0,0 +1,108 @@ +Ajustaira +alaguiar +alausièr +alberguèri +alcaloïdic +alègrament +alenament +algorisme +Alimentacion +allergologia +alpèstra +amaisament +amorteirar +analista +analogic +atucament +Audicion +auquièr +auscultacion +auscultar +ausèri +autenticament +brilhant +brumós +Burgada +cabelièira +cadeçar +Caducèu +çaicontra +calcièrs +Calmar +camarilha +cambièra +canalhariá +casse +cedar +cendrós +cèrca +cèrtes +cestòdes +chantièr +chartrós +Chassís +dimensionar +diptèrs +dirèctament +discrecionària +discriminar +Distraire +dòler +Enòrme +enqueriái +espicifòrme +esquelèt +Esquèrra +estetic +innocéncia +innocentàs +Maniquèu +mantelejar +Nauchièr +natièr +oxigèn +pacanariá +pagés +pagesiá +Primièirament +requereguèri +requisitòria +saumelèri +S'autodeterminar +sautarèl +scientament +scientologia +secador +secretèri +sècta +sectorial +s'efarcimar +s'endeven +s'engarrar +sentimental +s'entrepausar +shampó +sextant +sòli +Solidament +soquèla [soquèla, roquèla] +subrejornada +suedés +utilitària +Utilizaire +vacàs +vaisselèri +valiái +validament + +Слова с ошибками [] +albatros [albatròs] +amistanza [amistança, amistat, animista] +brunonièr [brunhonièr, prunhonièr] +carpentier [carpentièr] +centrifugation [centrifugacion, centrifugadoira, centrifugador, centrifugar, centrifuga] +estelhad [estelhas, estelha, estelhada, estelhar, estelhan, estelhat, estelham, estrelhada, estervelhada, estenalhada, estendalha] +primaria [primariá, primària, primarai, primaris, primari, primariam, primacia, primarga] +s'embractar [s'embracetar, s'embraceta, s'embodracar, s'embarrassar, embracetar] +sosembrançament [sosembrancament, embraçament, asombrament] +vascularisacion [vascularizacion, secularizacion, cardiovascular] diff --git a/Common/3dParty/hunspell/test/dst/pl_PL.txt b/Common/3dParty/hunspell/test/dst/pl_PL.txt new file mode 100644 index 00000000000..3cb6dba99fe --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pl_PL.txt @@ -0,0 +1,225 @@ +dom +pies +kot +auto +drzewo +książka +szkoła +przyjaciel +mama +tata +dziecko +jabłko +czekolada +kawa +herbata +telefon +telewizor +komputer +muzyka +sport +zdrowie +piękno +praca +miłość +szczęście +czas +pieniądze +język +kraj +miasto +zima +lato +jesień +wiosna +morze +góry +jezioro +rzeka +park +zwierzę +ptak +ryba +drewno +złoto +srebro +metal +szkło +buty +sukienka +spodnie +koszula +czapka +płaszcz +ręka +noga +oko +ucho +nos +usta +ząb +głowa +serce +mózg +król +królowa +książę +księżniczka +chłopak +dziewczyna +mężczyzna +kobieta +staruszek +staruszka +lekarz +pielęgniarka +nauczyciel +uczennica +student +studentka +kucharz +kelner +wojna +pokój +mapa +flaga +śmiech +płacz +sen +marzenie +praca +nauka +sztuka +teatr +kino +muzeum +kaplica +kościół +zamek +most +droga + +Сложные слова на польском языке [] + +1. konstantynopolitańczykowianeczka [nicejsko-konstantynopolitańskiego] +2. niezadogłębienieńskujący [] +3. antykontraatakujący [finansująco-kontraktujący] +4. supersamoobsługiwalnymi [kancelaryjno-archiwalnymi] +5. rozpierduchlanoculka [nieporozpierdzielanie] +6. nieodezwawiałobyś [nieodprzedmiotawiany] +7. przystawieniowy [przedstawieniowy, nieprzystawienie, niepoprzystawianie, nieprzystawianie] +8. nieprzeżyciowakościami [nieprzewartościowywaniami, nieprzewartościowaniami] +9. nieprzekazywających [nieprzekrzywiających, nieprzejednywających, nieprzywdziewających, nieprzepoczwarzających] +10. przeciwzakwaszeniowych [zatokowo-przedsionkowych] +11. nieszczęściodrapańskiego [ogrodniczo-pszczelarskiego] +12. społeczno-wychowawczyniami [socjalizacyjno-wychowawczymi] +13. seledynowo-fioletowymi [mięśniowo-szkieletowymi] +14. przeciwdeszczową [przeciwdeszczową, przeciwdeszczowy] +15. mikroelektroniczno-kwalitacyjną [reumatologiczno-rehabilitacyjną] +16. nieokreślonościowo-losowo-obiektywnie [] +17. zagubieniecioburakowatej [] +18. antyneuroleptyzanckim [] +19. nieupubliczniającymi [nieuwieloznaczniającymi] +20. splądrowałbyś [wyeksplorowałbyś] +21. konserwowano-spożywczymi [konserwiarsko-zamrażalniczymi] +22. ożelośćiowo-miłosnej [] +23. nieprzyzwoitolicjią [nieprzypieczętowującą] +24. nieodporowościę [nieodpoliturowanie] +25. rzeszołkofiołkowatymi [] +26. niezakapiactwuja [niezakatrupiająca] +27. nieoszczędniewczelnianków [oszczędnościowo-rozliczeniowa] +28. przekształconowaczkołępów [] +29. rozwińczywianiu [nieporozwiązywaniu] +30. nieprzeskakiwalnościami [nieprzewartościowywaniami] +31. modernizująco-rewolucyjnego [reumatologiczno-rehabilitacyjnego] +32. nadzwyczajnieuzdolnionymi [] +33. przemocno-wsparciański [warciańsko-odrzańskiemu] +34. przepyszno-peltzerowskiego [faszystowsko-hitlerowskiego] +35. kwestionowano-wzmocnieniami [] +36. nieodczynieństwującą [nieodrzeczywistniającą] +37. niezasłużonowypasionego [] +38. likwidującego/zarządzającego [odchudzająco-oczyszczającego] +39. szeszcześtoplutowanych [nieprzeinstrumentowanych] +40. niewpadkowościowi [wielonarodowościowi] +41. antynazizhownemu [niebizantynizowanemu] +42. nieuchronnieprzekroczeniowym [oszczędnościowo-rozliczeniowym] +43. niezatrawialnieprzyjemnego [] +44. kardiopulmonologiczno-angiologów [endokrynologiczno-ginekologicznemu] +45. gorączkowointensywnościowego [wydolnościowo-sprawnościowego] +46. antykonstytucyjnorozpadowego [konstytucyjno-monarchicznego] +47. nieobawiamysię/źródleni [] +48. prerewolucyjnolphillipsowi [] +49. szóstkaniewygranych [niewykrystalizowywanych] +50. nieupadkokogeneracyjnymi [korekcyjno-kompensacyjnymi] +51. społeczno-humanitarnarządzaniami [] +52. nieodziewowiędzy [nieumiędzynarodowienie] +53. przemocnochamować [] +54. społecznosensacyjnosądowym [kompensacyjno-wyrównawczymi] +55. przerażającorzymskiego [kobylińsko-borzymskiego] +56. nieprzemontowanych/zamuzowych [] +57. referendumkonstytucyjno-reformujące [] +58. niezniesłowiałszymi [niezesłowiańszczonymi] +59. niebohaterystycznymi [charakterystyczniejszymi] +60. produktodenarodowomenopauzalem [] +61. odrywającopierdolca [niedopierdzielająca] +62. niegotowożywione [żywieniowo-noclegowi] +63. niepostronnynarodzonemu [kilkudziesięciostronicowemu] +64. przedniaautochtonicznym [urbanistyczno-architektonicznym] +65. nadciągniono-wchodzących [] +66. promocjostworczym [czteromocarstwowym] +67. niezapowiadającychkoalicji [] +68. bezgłupinczłapie [] +69. wyomjaził [] +70. wagotonizacyjno-radiofonizowanego [] +71. gospodarczo-zasadotwórczej [organizacyjno-gospodarczej] +72. skrupulatno-rzeźniczobardziej [] +73. samokiedy-konstytucyjnej [konstytucyjno-monarchicznej] +74. niedomętnością [nieumiejętnością] +75. nieoszustamiwykorzystana [] +76. przeprowadzonoświeckie [nieprzeprojektowywanie] +77. nieuniknionaobowiązkowo-plastycznej [] +78. poduszkowo-nicościowych [porządkowo-czystościowych] +79. niepowodzeńbutmizeryjewego [] +80. skojarzeniowocolorowymi [wypoczynkowo-szkoleniowymi] +81. przytułkamiwciągarkowych [] +82. wchodziłoprzeciwniepowszechny [] +83. karaublicznociągana [publiczno-prywatnego] +84. przedpolitycznilubelskim [hemolityczno-mocznicowemu] +85. niezapowiedziano-date-expanded [] +86. licznościłodziennej [termiczno-wilgotnościowej] +87. niezawinieniomatołek [] +88. pakujączwobilardowego [] +89. rewersdopisek [] +90. przeprosinoworadosną [nieprzeprojektowywaną] +91. nieakceptacyjnoprospekcyjnymi [adaptacyjno-rehabilitacyjnymi] +92. jedniżużytym [nienadużytymi] +93. ainikopciksemilitechnikowany [] +94. motszynopiszącym [niewspółtowarzyszącym] +95. nieprzerejestrowanasezonowanie [] +96. słupotartackimoblikiem [] +97. nieodbieraniemniedostępności [] +98. dorozwinięcówkobiet [] +99. szybopojabytesłowickiego [] +100. przystępnoracjmujacych [] + +Слова с ошибками [] + +jedniiżużytym [nienadużytymi] + +wiomjaził [jaziowy] + +niezzniesłoowiałszymi [niezesłowiańszczonymi, niezesłowiańszczanymi, niezesłowiańszczającymi, najniesłowniejszymi] + +superrsammoobsługiwalnymi [muzealno-archiwalnymi] + +przemoocnochamować [przeprogramować] + +staruszzka [staruszka, staruszeczka, staruszek, staroruska, starszaka] + +tiatr [tiar, titr, tatr, teatr, wiatr, otiatra, otiatria, tristia] + +woina [wpina, wona, wina, wozina, dwoina, wolina, wonna, wcina, toina, wodna, doina, wolna, wojna, wgina, woźna] + +teleffon [telefon, telef fon, telef-fon, telefoto] + +zołoto [złoto, gołoto, hołoto, Gołoto, Hołoto, zołotnik] diff --git a/Common/3dParty/hunspell/test/dst/pt_BR.txt b/Common/3dParty/hunspell/test/dst/pt_BR.txt new file mode 100644 index 00000000000..1f66fc5565d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pt_BR.txt @@ -0,0 +1,108 @@ +que +eu +não +de +você +para +ele +se +é +um +sim +por +isso +em +uma +uuma [u uma, uma, usma, suma, numa, ruma, duma, puma, fuma, juma] +está +como +com +bem +na +me +mas +do +era +quando +então +tudo +tydo [tudo, tido, todo] +aqui +disse +estava +esâtava [estava, tavares] +lá +fazer +vai +sobre +vamos +homem +hollmem [homem-gol] +bom +ok [o k, o, k, oó, os, oi, oc, ou, om, oh] +agora +coisa +coissa [coisca, coiça, coisas, coisa, cossa, comissa, cisosa, cissoa, cossai] +quero +foi +meu +seu +só +eles +as +posso +pocso [posso, poco, poso, psoco, poiso, pouso, pocho] +estou +mais +mim +certo +dizer +dizdizerr [dizer] +os +no +sei +ela +vocês +sua +todos +sabe +minha +alguma +algyyma [amalgama] +casa +muito +oh +quallquer [qualquer, alquerque, malquerer, alqueria, alquermes] +qualquer +da +estamos +até +onde +onede [enode, onde, monede, neode, onere, olede, nedendo] +ao +tenho +nós +tem +tinha +tiinha [tinão ha, tiazinha, toinha, tinha, tirinha, tidinha, tipinha, tianha, tainha] +quê +ir +ou +pode +quer +vou +seus +dia +estão +nos +cabeça +quem +anos +depois +sou +vez +vá +fez +irmão +câmera +câmeara [cameara, cameará, câmera, câmara, acâmera, comeara] diff --git a/Common/3dParty/hunspell/test/dst/pt_PT.txt b/Common/3dParty/hunspell/test/dst/pt_PT.txt new file mode 100644 index 00000000000..9477e3d006d --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/pt_PT.txt @@ -0,0 +1,135 @@ +pan [pana, pane, pano, pen, par, pai, pau, paz, San, Van, Dan, pança] +manteiga +menteiga [manteiga, antigamente] +queijo +salchichón [salsicha] +saуlchichón [] +óleo +pimenta +pimmenta [pimenta, pigmenta, pimenteira, pavimenta, implementa, impiamente] +sal +baga +mel +geléia [geleia] +cogumelo +cebola +cóbola [cebola] +banana +cenoura +pêra [pera, para, pira, pura] +beterraba +frutas +melão +melancia +bolo +chocolate +carne +batatas +salada +salóda [salda, salada, salsada] +tomate +pepino +pipino [pepino, pi pino, pi-pino, pipi no, pipi-no, filipino, pino] +col [cola, cole, colo, coa, cal, coe, cor, rol, sol, coo, com] +mingau [mingua, mingai, minga, mingar, mingas, mingou, mingam] +sopa +sanduíche +refrigerante +refrigarante [refrigerante, refrigerar, intrigante] +água +café +chá +leite +suco +scuco [suco, cuco, cucos] +maçã +uvas +laranja +abacaxi +adacaxi [abacaxi, cacada] +damasco +demasco [damasco, demarco, remasco, de masco, de-masco, descasco] +açucar [açúcar, açucara, açucare, açucaro, açudar] +arroz +macarrão +res [rés, ser, ares, reis, ires, ores, dres, rei, ris, ses, rãs, rês] +porco +frango +costeleta +cãsteleta [costeleta, chapeleta] +limão +ervilha +pão +peixe +caramelo +sorvete +nogueira +ovo +pêssego +xícara +xíícara [xícara, caraíba] +vidro +prato +colher +garfo +faca +pires +garrafa +guardanapo +café da manhã [ssafé da manhã] +almoço +jantar +avião +carro +bonde +ônibus [ónibus] +trem +bicicleta +janeiro +fevereiro +fevíreiro [fevereiro, ferreiro] +março +abril +maio +junho +julho +agosto +setembro +setembra [setembro, seteara] +outubro +novembro +dezembro +desembro [desmembro, dezembro, deslumbro, setembro, desdobro] +caneta +livro +xadrez +telefone +relógio +pente +televisão +ferro +sabão +rádio +bolsa +cartão +mala +presente +câmera [câmara, comera] +computador +camputador [computador, captador] +filme +flor +vaso +quadro +lenço +bola +balão +brinquedo +brinqueedo [brinquedo, branqueado] +conta +sobre +papel +pepel [papel, repele, pele] +jornal +letra +bilhete diff --git a/Common/3dParty/hunspell/test/dst/ro_RO.txt b/Common/3dParty/hunspell/test/dst/ro_RO.txt new file mode 100644 index 00000000000..b1bd8929057 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ro_RO.txt @@ -0,0 +1,210 @@ +casă +copil +carte +masă +școală +lumină +apă +munte +soare +lună +pâine +fruct +floare +stradă +mașină +aer +timp +zi +noapte +nor +vânt +ochi +gură +nas +mână +picior +inimă +sânge +cap +ureche +voce +melodie +culoare +formă +linie +cerc +dreptunghi +cercetare +știință +limbă +frază +literă +cifră +număr +sunet +zgomot +telefon +internet +computer +program +ecran +tastatură +mouse +joc +sport +muzică +artă +film +televizor +radio +planetă +stea +univers +galaxie +atom +moleculă +substanță +energie +lumină +căldură +frig +aparat +instrument +mașinărie +unelte +hrană +băutură +haine +pantofi +păr +piele +ochelari +ceas +bijuterie +pământ +apă +aer +foc +metal +lemn +piatră +hârtie +cerneală +pix +carte +cadru +tablou +sculptură +model +formă +anticonstituționalitate [anti constituționalitate, anti-constituționalitate, anticonstituționali tate, anticonstituționali-tate, anticonstituționale, neconstituționalitate, anticonstituțională, constituționalitate] +dezvoltare +inexpugnabil +nefast +concomitent +antiseptic +recalcitrant +perseverență +extravagant +inexorabil +colosal +plauzibil +efervescent +perspicacitate +superfluu [superfluă, superfulger] +subversiv +incoruptibil +inefabil +hiperbolic +indefectibil [indestructibil, indefinibil] +peremptoriu +ambivalent +paradoxal +heterogen [eterogen, heterogonie] +indiferent +periferic +subliminal +ultraviolet +indeferent [indiferent, interferent, deferent, inaderent, independent] +conglomerație +circumstanțial +contraproducător [contra producător, contra-producător, contraproductivă, contraproductiv, neproducător] +conglomerat +insurmontabil +intransigent +insidios +inerent +consternant +ambiguitate +inerție +inconsolabil +oniric +remarcabil +repudiat +subiectiv +periculos +infatigabil +abnegare +exuberant +facet [face, falet, facem] +represiune +implacabil +indiferent +infatigabil +insolit +intempestiv +incandescent +letargic +magistral +magnanim [magnaliu] +nefast +oblivial [bolivian] +oportun +periculos +plutitor +propice +reprobabil +risipitor +robust +salutar +simetric +solicitant +stringent +sufocant +superficial +tranzitoriu +tributar +trivial +umilitor +unic +vehement +vernal +vicios +victorios +vindicativ +virtuos +vizibil +volatil +vorace +vulnerabil +xenofob +xerofil +yonder [pondere] +yang +yodel [model] +zonal +zodiac +zoon [ozon, zono, zoom, zoo, zon, zobon, zovon, zvon, zoo n] +zoomorf +zurbagiu +Caaă [Casă, Cară, Cată, Cală, Cană, Cauă, Camă, Capă, Cadă, Cață, Cază, Cavă, Cașă] +Soaare [Soare, Sotare, Solare, Sonare, Somare, Soțioare] +Cartr [Carte, Cart, Carter, Carta, Carto, Cartu, Cartă] +Appă [Papă, Apă, Arpă, Aptă] +Coopil [Copil, Copilo, Copiilor] +Frumoss [Frumos, Frumos s, Frumoasă] +Feriсire [Fericire, Rereferire, Ferire] +Prietenn [Prieten, Prieteni, Prietena, Prietene, Prieteno, Prietenu, Prietenă, Prieten n, Prietinie, Prietin, Pretenție] +Muziică [Muzică, Muzic, Muică] +Exeplu [Exemplu] diff --git a/Common/3dParty/hunspell/test/dst/ru_RU.txt b/Common/3dParty/hunspell/test/dst/ru_RU.txt new file mode 100644 index 00000000000..938369e89b8 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/ru_RU.txt @@ -0,0 +1,197 @@ +должен +доллжен [должен, доложен] +наш +думаю +думмаю [думаю] +свою +сам +всем +ни +нас +пока +этом +этой +ваша +всеми +возьми +моей +сама +вся +день +само +всей +бывает +себе +пойду +куда +ими +твоей +всю +своего +твой +пусть +ним +про +точно +иметь +которые +тогда +сюда +наше +самой +взять +наверное +домой +совсем +те +тобой +наверно +что-то +будто +твои +пути +дома +такие +тех +такое +его +самой +вашей +наверное +мои +например +типа +значит +люблю +минут +пор +случае +искусство +лучше +того +такому +ждать +видеть +мною +ждал +имя +важно +чего-то +самому +обычно +представляет +мечтать +стало +помните +взять +моих +самим +своим +вообще +самими +здесь +обратно +сразу +таким +ежели +наоборот +куда +таков +мечтает +значит +покажи +такими +кстати +почти +всякий +научит +вдоль +тогдашний +толком +занимает +Аквапланирование +Барокамера +Библиографирование +Биосинтез +Взаимодействующий +Вибраторный +Виртуальность +Вооруженность +Господствующий +Десантно-штурмовой +Диагностировать +Дипломатический +Дисгармония +Дискриминационный +Достопримечательный +Жизнеустройство +Интернациональный +Инфицированный +Кальцинировать +Ключичный +Коннотация +Лиловатый +Люминесцентный +Метрополитен +Многоплановый +Модернизировать +Наивысший +Наименее +Неопределенный +Нераскрытый +Неоднократный +Неохотно +Непостижимый +Неусыпный +Обезьяноподобный +Обзавестись +Оптический +Оптимизировать +Осуществиться +Очистительный +Парафинировать +Переключатель +Пограничный +Подготовительный +Подрядчик +Полиморфный +Почитать +Преисполниться +Преподаватель +Преследователь +Прирожденный +Проектирование +Профанация +Разграничительный +Распоряжающийся +Реконструктивный +Революционный +Рентгенологический +Рискованный +Роскошествовать +Самоунижение +Сверхъестественный +Светочувствительный +Семантика +Сингулярность +Совершенствовать +Соединительный +Сосуществование +Спорообразующий +Стационарный +Столовая +Сторицей +Сцепной +Трансформирующий +Триумвират +Укротитель +Универсальный +Федеративный +Хронометраж +Целостность +Криумвират [Триумвират] +Укратитель [Укротитель] +Универссальный [Универсальный] +Фидиративный [] +Хранометраж [Хронометраж] +Целосность [Целостность] diff --git a/Common/3dParty/hunspell/test/dst/sk_SK.txt b/Common/3dParty/hunspell/test/dst/sk_SK.txt new file mode 100644 index 00000000000..d8167476c95 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sk_SK.txt @@ -0,0 +1,205 @@ +hiša [šiša, Riša, Miša, hi ša, hi-ša] +pes +mačka +avto [atto, asto, auto, zavito] +drevo +knjiga [kvadriga] +šola [šila, šoka, šla, švola, škola, šosa, vola, šora, rola, kola, mola, dola, šopa, pola, hola] +prijatelj [prijatej, prijate, prijatie] +mama +oče [očne, otče, toče, očke, koče, moče, očeš, oči, one, ose, oke, oje, obe, očí, očú] +otrok +jabolko [jablko] +čokolada [čokoláda] +kava +čaj +telefon [telefón, telefot] +televizija [televízia] +računalnik [račianski] +glasba [glasnosť] +šport +zdravje [zdravej, zdravie, zdravte, zdravme, zdrav je, zdrav-je] +lepota [pelota, slepota, lopota, lehota, klepotať, epoleta, poleptať] +delo +ljubezen [lezeniu] +sreča [srnča, skeča, smeča] +čas +denar [denár, nedar] +jezik [veziko] +država [držiava, držala, dŕžava, dĺžava] +mesto +zima +poletje [polejte, poleje, poletuje, polje] +jesen [jeseň, jesne, nesej, jeden, jesene, jeseni, jesení] +pomlad [omlad, poklad, p omlad, pomlka] +morje [morke, more, moje, morte, morme, mor je, mor-je, morčej] +gore [hore, gofre, nore, kore, more, zore, bore, šore, Nore, Tore, Lore, Zore, gágore] +jezero [jazero, je zero, je-zero, zero] +reka [areka, rieka, rekta, repka, rezka, raka, roka, rekt, seka, reva, veka, deka, repa, reku, ruka] +park +žival [žuval, živa, živel, živil, rival, ži val, ži-val, živ al, živ-al, živa l, žičieval] +ptica [pica, pätica, psica, štica] +riba [rabi, roba, ria, iba, raba, ribi, ryba, rúba, róba, Tiba, r iba, babri] +les +zlato +srebro [rebro, s rebro, striebro] +kovina [okovina, krovina, ovinka, konina, novina, korina, rovina, kozina, košina, kofina, rakovina, kávovina] +steklo [šteklo, seklo, stekalo, stieklo, stenklo, streklo, stoklo, steblo, stĺklo] +čevlji [nevlhči] +obleka +hlače [hláče, tlače, hlase, hlave, hlade, plače] +srajca [rajca, krajca, s rajca] +kapa +plašč [plaš, plač, plaší, plaš č] +roka +noga [noha, nota, nosa, nova, nora, loga, koga, doga, joga, noža, noša, noxa, Toga, neogab] +oko +uho [ujo, ho, tuho, uhor, uhol, uhlo, ucho, uhoľ, uňho, hou, oho, uto, uhm, cho, uhú] +nos +ustnice [ustrice, kapustnice] +zob +glava [hlava, Ilava, Slava] +srce [drce, srnce, srdce, srne, srde, síce, súce] +možgani [moganie] +kralj [kraj, kraal] +kraljica [kraslica] +princ +princesa +fant +dekle [deke, dele, pekle, de kle, de-kle, debakle] +moški [košmi, kamoši] +ženska [ženská, ženiska, žensky, ženskí, ženský, ženskú, ženské] +starec +starka [starká, straka, statka, starla, stara, ostarka, staríka, starca, starkí, starký, starkú, starké] +zdravnik [zdrav nik, zdrav-nik, zdravenia] +medicinska sestra [medicínska sestra] +učitelj [učitelík] +učenka [učeníka, učenia, učenca, utečenka] +študent +študentka +kuhar [kurare] +natakar [katakana, katarakta, katarakt] +vojna +mir [mri, mor, mi, mira, mire, mier, emir, miri, miru, mar, air, mer, min, sir, mil] +zemljevid [zemediel] +zastava [zástava, zastáva, zastav, zastavia, zastaval, zastavaj, zastavať, zostava, zastala, zastaví] +smeh [sneh, smej, sme, steh, smer, smel, smeč, smeť, sme h] +jok [koj, kok, joj, jol, ojok, jak, jot, tok, sok, vok, rok, lok, mok, dok, job] +spanje [spanie] +sanje [sane, saje, sanuje, banje] +delo +učenje [učenej, učene, učenie] +umetnost [etnosti] +gledališče [nepojedali] +kino +muzej [mušej, muzeálnej] +kapela +cerkev +grad [grád, gard, hrad, graf, rad, grand, gram, gray, úrad, Arad] +most +cesta + +Сложные слова [] + +1. Neparlamentarna [parlamentarizmus] +2. Samozadosten [rozradostene] +3. Nepristranski [protistranícki] +4. Pretirano [pretrénovanosti] +5. Nepredušno [nepriedušnosť] +6. Nesreča [] +7. Razpršeno [zhoršenou] +8. Nesprejemljiv [nesprejazdňujeme] +9. Prekomeren [rekompenzovať] +10. Prostovoljstvo [sprostredkovateľstvo] +11. Izolirati [] +12. Trmast [] +13. Brezpogojno [] +14. Neodvisnost [neodôvodnenosti] +15. Skupnost [ústupnosti] +16. Neizvedljiv [] +17. Nelegitimen [nelegitimizuje] +18. Nevzdržen [] +19. Preobremenjenost [] +20. Ogrevalni sistem [] +21. Preoblikovati [aplikovateľnosti] +22. Nezaslišano [nezasluhujúci] +23. Neugoden [] +24. Prezasedenost [prezamestnanosť] +25. Nesreča [] +26. Neupravičeno [nenapraviteľnosť] +27. Mednaroden [mŕtvonarodeným] +28. Kompatibilnost [najkompatibilnejšom] +29. Neuspeh [neusporte] +30. Neobvladljiv [] +31. Neskončen [neskončenej] +32. Neprimeren [neprimeranie] +33. Amortizacija [amortizovaných] +34. Koncentracija [dekoncentrácia] +35. Cirkulacija [recirkulácia] +36. Obremenitev [odbremenenie] +37. Gromozanski [] +38. Simbol [] +39. Vinjeta [] +40. Digitalizacija [digitalizovaný] +41. Funkcionalnost [funkcionalistické] +42. Rentabilnost [nerentabilnosti] +43. Ekshibicionizem [exhibicionizmus] +44. Frustracija [frustrujúci] +45. Neprilagodljiv [] +46. Severnoameriški [] +47. Ekskluzivnost [] +48. Preverjanje [preverovanej] +49. Celoživljenjsko [] +50. Privlačnost [neprivlastňovala] +51. Periferija [periferický] +52. Sokrivda [dokrivkať] +53. Kompromis [kompromisník] +54. Strpnost [ostrovtipnosť] +55. Racionalizacija [zracionalizovania] +56. Birokracija [gerontokracia] +57. Odraslost [odrastenými] +58. Stabilnost [nestabilnosti] +59. Nepredvidljivost [najnepredstaviteľnejšou] +60. Razkošje [] +61. Smrtnost [úmrtnostným] +62. Obveščenost [presvedčenosti] +63. Produktivnost [neproduktívnosti] +64. Neugodje [] +65. Zapletenost [zakrpatenosti] +66. Hegemonija [] +67. Umetnost [menostatikum] +68. Tranzicija [tranzitivita] +69. Individualnost [individualisticky] +70. Kontaminacija [kontaminantmi] +71. Inkubacija [] +72. Prikrito [prikrátko] +73. Etnični [Letničie] +74. Sovražnost [samovražednosť] +75. Atraktivnost [abstraktnosti] +76. Nestrpnost [nepriestupnosti] +77. Divergenca [divergencia] +78. Digitalna pismenost [] +79. Stabilizacija [autostabilizácia] +80. Raznolikost [] + +Слова с ошибками [] + + Kontamenacija [Kontaminácia] + + Grommozanski [Grobianski] + + Neobvladlliv [Neobkradli] + + Neparlametarna [Neparlamentný, Parlamentárnej, Parlamentne] + + Nevrzdržen [Združene, Zdražene] + + voina [vonia, vina, vojna, voľna, voština] + + muzei [muzeálni] + + ryba + + serebro [se rebro, se-rebro, rebro] + + televiziia [televízia] diff --git a/Common/3dParty/hunspell/test/dst/sl_SI.txt b/Common/3dParty/hunspell/test/dst/sl_SI.txt new file mode 100644 index 00000000000..6bd93841419 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sl_SI.txt @@ -0,0 +1,210 @@ +Hiša +Sonce +Miza +Stol +Ptica +Trava +Drevo +Noč +Luna +Morje +Gora +Cvet +Riba +Rdeča +Modra +Zelena +Rumena +Bela +Črna +Kamen +Pes +Mačka +Roka +Noga +Glava +Oči +Uho +Nos +Usta +Jabolko +Hruška +Sliva +Jagoda +Malina +Lubenica +Kruh +Mleko +Sir +Mesnica +Sadje +Zelenjava +Voda +Zrak +Ogenj +Sneg +Dež +Oblak +Veter +Zima +Poletje +Jesen +Pomlad +Zajec +Lisica +Volk +Medved +Lev +Tigrica +Slon +Konj +Krava +Ovca +Piščanec +Jajce +Mleko +Kava +Čaj +Sok +Vino +Pivo +Hrana +Pecivo +Testo +Marmelada +Kruh +Sir +Olje +Sol +Poper +Sladkor +Kava +Čaj +Vino +Pivo +Šola +Učitelj +Učenec +Knjiga +Pisarna +Računalnik +Telefon +Glasba +Slika +Film +Gledališče +Mesto +Vas +Trg +Cesta +Reka +Avtomatizacija +Razvoj +Komunikacija +Kompjuter [Juterškov] +Programiranje +Elektronski +Inženiring +Elektrifikacija +Kombinacija +Sistem +Informacija +Univerza +Biblioteka +Univerzitetni +Laboratorij +Raziskava +Razvojna +Inovacija +Intelektualni +Integriteta +Izobraževanje +Izvajanje +Preverjanje +Tehnologija +Implementacija +Program +Sodelovanje +Proizvodnja +Industrija +Organizacija +Administracija +Proaktivnost [Retroaktivnost, Produktivnosti, Produktivnost, Provokativnost] +Kreativnost +Projektni +Razumevanje +Kvaliteta +Upravljanje +Ocenjevanje +Statistika +Kompetentnost +Konsolidacija +Realizacija +Kapaciteta +Distribucija +Kompatibilnost +Konceptualizacija [Konceptualizem] +Povezava +Posodobitev +Fleksibilnost +Ekonomija +Organiziranje +Konkurenca +Stabilnost +Ekologija +Osebnost +Zavzetost +Entuziazem [Entuziast] +Motivacija +Avtorizacija +Kreacija +Akumulacija +Monotonija +Diferenciacija +Transformacija +Koncentracija +Inovativnost +Aktivnost +Vzpostavljanje +Reorganizacija +Kategorizacija +Partikularnost +Homogenost +Izjemenost [Izjemnost, Izjemen ost, Izjemen-ost, Zmenjenosti, Izrojenost, Izmišljenost, Izrinjenost] +Generalizacija +Hierarhija +Koordinacija +Inspiracija +Evaluacija +Ustvarjalnost +Oblikovanje +Kompatibilnost +Konkretizacija +Proaktivnost [Retroaktivnost, Produktivnosti, Produktivnost, Provokativnost] +Identifikacija +Kapaciteta +Intervencija +Konsolidacija +Realizacija +Eksplozivnost +Abstrakcija +Individualnost +Integracija +Segmentacija [Sedimentacija, Sedimentacij, Argumentacija, Alimentacija] +Asimilacija +Artikulacija [Artikuliranja, Artikulirala, Cirkulacija, Kalkulacija] +Kolaboracija +Asociacija +Stabilizacija +Kooperacija +Transformacija +Hšza [Hrza] +Kmojnikacija [Komunikacija] +Progrramiranjee [Programiranje, Reprogramiranj, Programiranega, Programiranj] +Elektornkski [Elektorski, Elektorkin, Elektronski, Elektorki] +Inženeirrng [Inženiring] +Izzobraževanjee [Izobraževanje, Izobraževanj, Izobraževanega, Izobraževane] +Infomracija [Informacija, Informacij, Rafinacijam] +Razvoojnaa [Razvojen] +Proizvdonja [Proizvodnja, Proizvajanja, Proizvajanj, Proizvaja] +Akitvnostt [Aktivnost] diff --git a/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt b/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt new file mode 100644 index 00000000000..ef1ecd7824b --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sr_Cyrl_RS.txt @@ -0,0 +1,227 @@ +кућа +пас +мачка +аутомобил +дрво +књига +школа +пријатељ +мама +тата +дете +јабука +чоколада +кафа +чај +телефон +телевизија +рачунар +музика +спорт +здравље +лепота +посао +љубав +срећа +време +новац +језик +земља +град +зима +лето +јесен +пролеће +море +планине +језеро +река +парк +животиња +птица +риба +дрво +злато +сребро +метал +стакло +ципеле +одећа +панталоне +кошуља +капа +капут +рука +нога +око +уво +нос +усне +зуб +глава +срце +мозак +краљ +краљица +принц +принцеза +дечак +девојчица +мушкарац +жена +старац +старица +доктор +медицинска сестра [војномедицинска] +наставник +ученик +студент +студенткиња +кувар +конобар +рат +мир +мапа +застава +смех +плач +сан +сањарење +посао +учење +уметност +позориште +биоскоп +музеј +црква +дворац +мост +улица +пут + +Сложные слова [Словенства] + +Конечно! Вот сто сложных слов на сербском языке на кириллице: [] + +1. Контраст [контрастира, контраста, контрастно, контрастна] +2. Компликација [компликацијама, компликација, компликације] +3. Конструкција [реконструкција, конструкцијама, конструкција, конструкцију] +4. Диспропорција [пропорцијалном] +5. Корелација [корелацијама, корелација] +6. Колаборација [колаборација] +7. Консервативан [конзервативан] +8. Диференцијација [диференцијације, диференцијацијом, диференцијална, диференцијални] +9. Експерименталан [експерименталним, експериментална, експериментални, експерименталне] +10. Инвалидитет [инвалидитет] +11. Легитиман [нелегитиман] +12. Оптимизација [аклиматизација] +13. Компетентан [некомпетентан, компетентан] +14. Документација [документација, документацијом, документацију, документације] +15. Персистентан [асистенткиња] +16. Апроксимација [апроксимације] +17. Екстраваганција [екстравагантност] +18. Катастрафалан [катастрофалан] +19. Резервација [резервација] +20. Прогресиван [прогресиван] +21. Идентификација [идентификација, идентификације] +22. Генерација [регенерација, генерација] +23. Криминалистички [криминалистички, криминалистичка, криминалистичке] +24. Дестабилизација [индустријализација] +25. Корумпиран [корумпирана, корумпиран] +26. Конфронтација [контаминација] +27. Експлозиван [експлозиван] +28. Функционалан [функционалности] +29. Релевантан [релевантан] +30. Квалификација [квалификацијама, дисквалификација, квалификација] +31. Акредитација [рехабилитација] +32. Петиција [петицијама] +33. Каустичан [аутистичан] +34. Периодичан [периодичан] +35. Контроверзан [контроверзна] +36. Гигантски [гигантских] +37. Принципијалан [беспринципијелан] +38. Управоливост [расположивости] +39. Имунизација [имунизација] +40. Магнетичан [магнетично] +41. Оперативан [оперативан] +42. Десант [десантне] +43. Хиерархија [хијерархија] +44. Феминистички [феминистичког] +45. Сегментација [сегментацијом] +46. Колоритан [колорисан] +47. Деградација [деградација] +48. Диверзификација [диверсификацију] +49. Казуистички [карикатуристички] +50. Реципрочан [реципрочан] +51. Манипулативан [манипулативна] +52. Екстензиван [екстензивна] +53. Колективни [колективни] +54. Каузалитет [локалитету] +55. Синхронизација [синхронизација] +56. Кампања [кампањама] +57. Товарни [товарника] +58. Хируршки [хируршких] +59. Шампионат [шампионати] +60. Геостационаран [револуционарност] +61. Опустошан [опустошености] +62. Клема [] +63. Стационарни [стационарна] +64. Секуларни [секуларних] +65. Исегментација [сегментацијом] +66. Дебелина [дебелића] +67. Прецизан [непрецизан] +68. Рафиниран [рафинирани] +69. Психолошки [психолошких, психолошки] +70. Турбулентан [корпулентан] +71. Интегритет [интегритет] +72. Идеолошки [идеолошких] +73. Манифестација [манифестација] +74. Имплицитан [имплицитан] +75. Хомогеност [хомогеност] +76. Изолација [хидроизолација] +77. Хетерогеност [] +78. Спекулативан [спекулативна] +79. Вагу [превагу] +80. Математички [математичким, математички] +81. Гематолошки [стоматолошки] +82. Психијатријски [психијатријске] +83. Блокада [блокадама] +84. Заплена [заплетена] +85. Монопол [монополом] +86. Дисидент [дисидентски] +87. Екстрадиција [екстрадиција] +88. Ревизија [ревизијама] +89. Ваидан [] +90. Колонизација [колонизација] +91. Мотивација [мотивација] +92. Просек [просектор] +93. Ресурс [ресурсу] +94. Хуманизам [хуманизам] +95. Дравски [Подравских] +96. Коалиција [коалиција] +97. Картеля [картелима] +98. Резолуција [резолуција] +99. Менталитет [менталитет] +100. Епидемиологија [дијалектологија] + +С ошибками [] + + Колонизакаија [Колонизација, Колонизацији, Колонијализам, Колонијализма] + + Епидемиогија [Епидемија, Епидемијом, Демагогија] + + Казуистикаки [Казуистика, Казуистике, Статистика] + + Хуманкзам [Хуманизам, Хуманизма] + + Манитулативан [Манипулативна, Ултимативан, Ултимативни] + + сањваење [сањање] + + утење [хтење, утање, стење, умење, утеше, утече, учење, утехе, утеже, уђење, утезање] + + автомобил [аутомобил, обилатом] + + мекицинска сестра [војномедицинска] + + стукло [стукли, тукло, стукла, стакло, стекло, свукло] diff --git a/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt b/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt new file mode 100644 index 00000000000..8996675c198 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sr_Latn_RS.txt @@ -0,0 +1,173 @@ +ananas +anarhistički +antidepresiv [depresivan, depresivna, represivan, depresivne] +Anđeo +avion +banana +banka +belina +bespomoćnost +bibliotekar +bibliaoteikar [bibliotekarka, bibliotekar, biblioteka] +brod +citat +crkva +cvet +cveće +demokratija +demackratija [demokratija, demokratizacija, demokratiji, demokratije] +demokratizacija +Dobrota +dom +Dragi +ekran +eksperimentalni +eksplozija +epidemiologija [epistemologija, ideologija] +farmakologija +filantropija +flaša +frizura +fudbal [fudbal, fudbala, fudbalu] +garaža +generalitet +geografski +globalizam +gnezdo +grad +građanstvo +grlo +hamburger +Harmonija +himalaji [Himalaji, malajski] +hiperbola +hipotermija [hidroterapija] +hleb +Hrabrost +hrana [hrana] +Hvala +igra +igračka +individualnost +infrastruktura +internet +inmternet [internet, interne] +jabuka +jahač +jastuk +jednakost +jubilej +jurisprudencija +kafa +krevet +kriminalisticki [kriminalistički, kriminalistika, kriminalistička, kriminalistiku, kriminalističke] +kriminalistika +kuća +kvantitativni +lampa +latiaratura [mlatarati, rasturati, maturirala, landarati] +Lepota +lingvistika +literatura +ljubav +Ljubavi +ljubavnica +Ljubazan +Ljubim +lubenica +majica +majka +mašina +mikroorganizama +mikroskopija [mikroskop ija, mikroskop-ija, mikroskopi ja, mikroskopi-ja, mikroskopi, mikroskopska, mikroskopa, mikroskopski] +Milost +Mir +Mirno +nacionalizam +nedopustiv +neurologija +novčanik +noć +nož +oktobar +okultizam +optimističan [optimistička, optimistički, optimističke, optimističku] +optimističnost [optimistički, optimističke, optimistička, optimističku] +ormar +Osoba +oči +pas +peškir +planina [planina, planinar, planinac, planinčina, planini, planinčini, planin] +poniženje +Porodica +Prijatelj +psihologija +psihoterapija +Radost +računar +reka +rekonvalescencija +reumatologija [dermatologija, hematologija, stomatologija] +revolucija +sendvič +Slatko +Sloboda +Slobodan +Snaga +socijalizacija [socijalizam, specijalizacija, specijalizacijom, socijalizma] +socijalizam +Spreman +Sreća +Srećan +Srećno +sunce +superiornost +Svetlost +tata +tehnologija +telefon +telekomunikacije +top +tradicionalni +ulica +univerzalnost +univerzitet +univirzdalnost [univerzalnost] +Usmena +Znanje +usta +Vedar +vegetarijanstvo +velikodušnost +voda +voz +Zabava +zavisnost +Zdravlje +zemlja +Zima +zjmlja [zemlja] +zločinački +zoološki +Zvezda +ćilim +čarapa +čarobnjak +časopis +čizme +đak +đevrek +đumbir +šešir +šišmiš +škola +šljiva +šuma +žaba +ženskara +žirafa +život +životinjski +žurka + diff --git a/Common/3dParty/hunspell/test/dst/sv_SE.txt b/Common/3dParty/hunspell/test/dst/sv_SE.txt new file mode 100644 index 00000000000..408fca774df --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/sv_SE.txt @@ -0,0 +1,210 @@ +Hus +Sol +Mjölk +Vatten +Fisk +Stol +Grön +Blomma +Träd +Katt +Hund +Bok +Cykel +Kaffe +Frukt +Kött +Fönster +Dörr +Säng +Lampa +Bord +Hår +Ögon +Hand +Fötter +Näsa +Mun +Öra +Huvud +Arm +Ben +Kläder +Hatt +Skor +Väska +Papper +Penna +Skrivbord +Telefon +Radio +Musik +Film +Teater +Konst +Sport +Spel +Resa +Bil +Tåg +Buss +Flygplan +Båt +Stad +Land +Hav +Sjö +Flod +Berg +Dal +Park +Skog +Sjukhus +Apotek +Skola +Universitet +Affär +Restaurang +Café +Hotell +Turist +Vän +Familj +Mamma +Pappa +Bror +Syster +Barn +Morfar +Mormor +Vänster +Höger +Framåt +Bakåt +Upp +Ner +Snäll +Osnäll [Snäll, Osäll] +Glad +Ledsen +Trött +Stark +Svag +Tyst +Bullrig +Ren +Smutsig +Vacker +Ful +Liten +Stor +Komplexitet +Oproportionerlig +Ovillkorlig +Efterklokhet +Komplicerad +Desorientering +Konstellation +Otillgänglighet +Irreversibel +Förlåtelse +Overksamhet +Indifferent +Hierarki +Kombinatorik [Kombinatorisk, Kombination] +Inkompatibilitet +Absorption +Konsekvens +Verklighetsfrånvänd +Retrospektiv +Förändringsbarhet [Förändringsbarnet, Förhandlingsbart, Förhandlingsbar] +Ambivalens +Besvikenhet [Besviken, Besviket] +Ineffektivitet +Intrikat +Dilemma +Hesitation +Absurditet +Kompromisslös +Konsolidering +Föresats +Tillfredsställelse +Delegering +Rekommendation +Detaljrikedom +Oanvändbar +Stagnation +Nostalgi +Hemlighetsfull +Avsaknad +Perseverans [Perseverera, Reverseras, Reversera] +Existentialism +Repetitivitet [Repetitivt, Receptivitet, Repetitiv, Representativitet] +Intolerans +Anonymitet +Obetydlig +Paradox +Förvirring +Juxtaposition +Reflektion +Självständighet +Kollision +Kreativitet +Djupgående +Abstraktion +Eufori +Autentisk +Insinuation +Omöjlig +Pessimism +Inkonsekvens +Revisionism +Sensationell +Obeveklig +Subjektivitet +Universalitet +Entropi +Omvälvande +Infiltration +Konservativ +Atypisk +Provokation +Konfrontation +Anarki +Konkurrenskraft +Defensivitet [Defensivt, Sensitivitet, Defensiv, Densitet] +Nihilism +Konklusion +Apori [Apor, Apors, Porig] +Korrespondens +Prioritering +Exponentiell +Fragmentering +Aversion +Harmoni +Vanmakt +Signifikans +Katalysator +Förlust +Enhällighet +Ambition +Tendens +Alienation +Artificiell +Uppfyllelse +Psykosomatisk +Virtuos +Egensinnig +Anpassning +Hållbarhet +Konstitution +Kompleksitet [Komplexitet, Komplementet] +Oproporsjonerlig [Oproportionerlig, Proportionerlig] +Uvilkorlig [Villkorlig] +Etterklokhed [Efterklok] +Komplisert [Komplicerat] +Desorientering +Konstelasjon [Konstellation] +Utilgjengelighet [Tillgänglighet] +Irreversibel +Forlatelse [Förlåtelse] diff --git a/Common/3dParty/hunspell/test/dst/tr_TR.txt b/Common/3dParty/hunspell/test/dst/tr_TR.txt new file mode 100644 index 00000000000..0ea601fe67a --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/tr_TR.txt @@ -0,0 +1,205 @@ +Akşam +Almak +Altın +Anahtar +Anlamak +Araba +Atmak +Ayakkabı +Açmak +Ağaç +Bahçe +Bakır +Bakkal +Bakmak +Balık +Beyaz +Bilgisayar +Bilmek +Binmek +Bulmak +Ceket +Cevaplamak +Deniz +Dinlemek +Doktor +Duyurulmamış +Düzenleştirme +Düşmek +Düşünmek +Ekmek +Elbise +Eldiven +Elma +Erkek +Etek +Etmek +Ev +Eşarp +Gelgit +Geliştiricilikle +Geliştirilebilir +Geliştirme +Gerçekleştirme +Gezmek +Geçmek +Gitar +Gitmek +Giymek +Gri +Gömlek +Görülebilirlik +Görünümlü +Görünüşlü +Gözlük +Gümüş +Günaydın +Hareketlendi +Hareketlilik +Hava +Hayalperest +Hüzün +Kahve +Kahverengi +Kalabalıklar +Kalem +Kalkmak +Kalmak +Kapatmak +Kararlılık +Kararlılıkla +Kararsızlık +Kararsızlıkla +Karpuz +Kedi +Kemer +Kemdkcer [Kemerler] +Kırmızı +Kitap +Kız +Kızgınmak [Kızgın] +Koklamak +Koalye [Kolye, Kavalye] +Kolye +Konservatuvar +Konuşmak +Korkmak +Koymak +Koşmak +Kravat +Kullanılabilir +Kullanılmış +Kullanılmışlık +Kullanışlılık +Kurumsallaşma +Köpek +Küpe +Kütüphane +Mavi +Mazbut +Melankoli +Merdiven +Merhaba +Merhabalar +Meurhaba [Merhaba, Murabaha] +Meydan +Meyhane +Meyve +Mor +Muhafazakar +Muhteşem +Mukadderatlarınızdanmışçasına [] +Muvaffak +Muzaffer +Muzafferiyet +Muzip +Mükemmeldik +Münasebet +Münzevi +Müsrif +Mütevazi +Müteessir +Mütercim +Mütereddit +Mütevazı +Müzmin +Okul +Okumak +Otobüs +Otoriterlik +Oynamak +Pantolon +Pasta +Pembe +Pembei [Pembe, Pembeyi, Pembeli, Pembeci, Pembe i, Pembesi, Pemben] +Plaj +Platin +Saat +Sandalye +Sarı +Satmak +Sevinmek +Sevmek +Sıcak +Sıradaymışız +Siyah +Sormak +Soymak +Soğuk +Su +Sükûnet [Sükunet, Sünnet] +Sürrealist +Süt +Tabak +Tadına bakmak [Alınamamaktadır] +Tatlı +Tavuk +Telefoncu +Televizyon +Temizlemek +Teşekkürler +Türkuaz +Tuirkuazu [Türkuaz] +Turuncu +Tutmak +Ulaştırılabilir +Uygulanabilir +Uyumak +Uçak +Yapmak +Yatak +Yazmak +Yemek +Yeşil +Yıkanmak +Yıldız +Yol +Yöneltilmezken +Yüzme +Yüzük +Zenginleştirmek +Çalışamamıştı +Çalışmak +Çalışmamıştır +Çanta +Çay +Çıkarmak +Çiçek +Çorap +Özelleştirilmiş +Özelleştirme +Özgürleştirme +Üzülmek +İnmek +İsteksizlik +İsteksizlikle +İstikrarlı +İstikrarlılık +İstisnai +İslamiyetle +İzlemek +İçmek +İşbirliği +İşitmek +Şapka +Şemsiye diff --git a/Common/3dParty/hunspell/test/dst/uk_UA.txt b/Common/3dParty/hunspell/test/dst/uk_UA.txt new file mode 100644 index 00000000000..be4941540b1 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uk_UA.txt @@ -0,0 +1,210 @@ +абдукція +абіогенез +амбівалентнасть [амбівалентність, амбівалентний, бівалентність, біоеквівалентність, внівалентність] +амбівалентність +анахранізм [анахронізм, брахманізм, анархізм, нанізм] +анахронізм +антропогенез +антропологія +антропоморфізм +апатія +археологія +архетип +аскетизм +астрономія +афект +бачити +бігти +білий +біллий [білий, збілілий] +біологія +бувай +будинок +будь ласка [будь ласку] +бути +важко +велиикий [великий, великоокий] +великий +веселка +взяти +вибачте +відчувати +вода +волюнтаризм +втаємниченість +вчитися +гарний +гарячий +гегемонія +географія +герменевтика +герменевтика +гештальт [штатгальтер] +говорити +гойдалка +готувати +грати +дати +дедукція +деконструктивізм [де конструктивізм, де-конструктивізм, конструктивізм, неконструктивно] +деконструкція +демаркація +детермінізм +дзвіночок +дивитися +дисгарммонія [дисгармонія, дисгармоніям, дисгармонійний, фісгармонія] +дисгармонія +дисфункція +дисфункця [дисфункція, дистинкція] +дихотомія +до побачення [побачення] +добрий +доктрина +думати +дурний +дурня +дякую +евфемізм +езотерика +ей +екзистенціалізм +екзистенціалізм +екзистенцілізм [екзистенціалізм, екзистенціаліст, екзистенція] +екзистенція +економіка +емерджентність +ентелехія +епістемологія +ефемерність +ефемерність +занепадництво +звісно +здоровий +зелений +йти +ілюзорність +ілюзорність +імплікація +інвектива +індукція +інтроспекціїя [інтроспекції, інтроспекція, інтроспекції я, ретроспекція] +їсти +історія +каблучка +кава +казус +калюжа +катарсис +каченя +каштани +квітка +кішка +класно +книга +когнітивістика [когнітивність, когнітивна] +комаха +консенсус +космогенез [номогенез, екогенез] +купувати +легко +лінгвістика +літати +маленький +марнослів'я +математика +мати +метаморфоза +метелик +метелиця +містифікація +місто +могти +можливо +мусити +насправді +не радий [нерадий, незрадний] +незворушність +ні +нігілізм +новий +нонсенс +ностальгія +павучок +парадокс +пес +писати +пити +піти +плавати +плакати +повільний +поганий +політологія +постмодернізм +потворний +працювати +привіт +прийти +психоаналіз +птах +радий +ремінісценція +рефлексія +робити +розбурхання [розбухання, розбурханий, розпухання, бурхання] +розумний +сильний +сингулярність +синестезія [кінестезія, анестезія] +синій +синішй [синій, синішай, синішати] +синкретизм +сказати +скатертина +слабкий +слухати +сміятися +сніг +соліпсизм +соломинка +сонечко +сонце +соціологія +спати +співати +справді +старий +структуралізм +сумний +так +так +танцювати +телефонувати +тож +трансцендентність +фантастично +фаталізм +фемінізм +феномен +феноменологія +фізика +філософія +фрактал +хворий +хімія +хліб +хліб +ходити +холодний +хотіти +чао [чадо, чан, чат, чар, час, чад, дао, чаш, чай, чаї, чаю] +червонй [червоний, червоній, червоно, червона, червоні, червону, червоне, червоню, червонявий] +червоний +черевики +читати +чорнй [чорний, чорній, чорно, чорна, чорни, чорні, чорну, чорне, чорню] +чорний +чути +швидкий +щасливий +яблуко diff --git a/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt b/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt new file mode 100644 index 00000000000..7aee3099656 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uz_Cyrl_UZ.txt @@ -0,0 +1,262 @@ +Mарт [Арт, Ғарт, Қарт, Карт, Шарт, Фарт, Варт, Парт, Сарт, Март] +Ёз +Ём +Ёхуд +Август +Адвакат [Адвокат, Адэкват] +Адреси +айтган-лирангиз +айқин +амалга +анча +Апрел +арзонроқ +аҳамият [аҳамият, аҳамияти, ҳамият, ҳамжамият] +аҳднома +бажарилади +бажарилди +баланд +ихтисослан +банкрот +баҳона +Баҳор +бераман +берасизми +беринг +бериш +бешинчи +биз +Бизга +Бизнинг +билан [билан, биланг, билани] +Бирор +Бозорнинг +бор +бошқа +Бу +Бугун +будингиз +бунга +бундай +Бухгалтерлик +бўлади +бўладими +бўлиши +бўлмаган +бўлса +бўш +бўшайди +бўшатасиз +вазифасига +вазият +вариант +вақт +газетадаги +газетадан +даромад +Декабрь +Душанба +Эрталаб +Етказиб +Жисмоний +Жуда +Жума +зарур +зиёфат +Ижара +ижарага +икки +Илтимос +Индинга +информатизациялари +Иситгич +иши +ишлатсак +Ишхона +Июль +Июнь +Йўқ +йил +йилдан +кам +Шинамгина +кампанияси +келдим +келишимдан +келмоқчи +келсам +келтириш +керак +керакдир +керакми +кета-ди [кетади, кетарди, кета-чи, кета-кета, дискета] +кеч +Кеча +кечага +Кечаси +Кечир +Кечирдинг +кирла +кирадими +кондиционер +коррупциядир +кран +Куз +Кун +куни +кўрмоқчи +кўчиб +лойиҳа +Май +маълумоти +маълумотларни +Маъмурият +маъруза +Мен +музлатгич +мумкин +муфмкин [мумкин] +мутахассис +мушовир +муҳим +нарса +нархи +Нархини +нақд +ўшанақасини +неча +Номардлик +Ноябри +интернетдаги +ойнаси +ойнинг +Октябри +олдин +олдиндан +олмаймиз +олмоқчи +орқали +шоти +шорти [шоти, орти, ортиш, шотир, корти, форти, шарти, порти, сорти, ширти, торти, борти, шомурти] +Оқшом +пайдо +Панжшанба +пулини +Раҳмат +резюме +реклама +Салом +Сармоядор +Сентябрь +Сешанба +Сиз +сизга +сизда +Сизнинг +синган +сифатида +совуқ +софвуқ [совуқ] +Солиқларни +Статистик +сўм +тажрибали +тайёргарлик +тайёрладик +тайёрладингизми +таклиф +талафот +талафоти +таъминловчилардан +танишинг +таржимон +тарржимон [таржимон, тарраксимон] +тахминан +ташкил +Телефонни +технология +Безантирани +тозалан +тозалигига [тозалигига, газтозалагич] +Тонгда +топширишимиз +топшириқ +турли +турмоқчи +тутсак +Тушлик +ўладиганингиз +тўлай +тўлаймиз +тилдиришинг +тўлиқ +уйингиз +уйни +уч +учун +ўқидим +фақат +Феврал +хабар +Хайрли кун [Хайрли кўн] +Мотамхонаси +хонлик +Чек +Чоршанба +Шанба +шарт-номани +шартини +шартлар +шартлари +шартни +шартнома +шахс +шовқин +Шом +Шу +эди +Эртага +Эртадан сўнг [Эртасиганг] +Эшитишимга +эълон +эълонингиз +эълонингизни +эътироф +Юклаш +Якшанба +Январи +Ярим кеча [Яримкеча, Яримчиликча] +яхши +қабул +қаерда +Қанақа +қаноатманда +қанча +қачон +қизиқарлидир +қиламиз +қилганим [қилганим, қилганими, қилгандайин] +қилдим +қилинг +қилинди +қилишди +қиммат +қиммати +Қимматидан +қирқ +Қиш +қувонарлими +қўнғироқ +Қўшимча +ҳайвонини +ҳам +ҳамза +Ҳар +ҳафтага +ҳақиқатан +ҳисоблаб +Ҳозир +ҳужжатни +Ўтган кун [Ўтган кўн] + + diff --git a/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt b/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt new file mode 100644 index 00000000000..0b2717d0ce6 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/uz_Latn_UZ.txt @@ -0,0 +1,200 @@ +Salom +Sallom [Slalom, Salom, Musallo, Alloma, Salo] +Rahmat +Rhmat [Rahmat, Marhamat] +Iltimos +Iltimo [Iltimos, Tilsimot, Timol] +Kattalar +Kattalarvf [Kattalashtir] +Yaxshi +Yashi [Ayshi, Tashi, Yash, Yasashi, Yarashish, Yalashish, Yaxshi] +Kelajak +Keljajak [Kelajak] +Oilaviy +Oilaaviy [Oilaviy, Hosilaviy] +Qarindosh +Qarinndosh [Qarindosh, Qayindoshlar, Oqarinish] +Shahar +Shaha [Shah, Shalha] +Dengiz +Dengizzz [Dengiz] +Quyosh +Quyyosh [Quyosh, Quysh] +Yulduz +Oyim +Kechqurun +Tushun +Suvchi +Sharob +Choyxona +Nonushta +Tushlik +Muzqaymoq +Desert +Tuzluq +Mevalar +Sabzavot +Baliq +Tuxumli +Sabza +Sariq +Salatlar +Shirinlik +Shokolad +Rishta +Kakao +Pishloq +Tort +Qaymoq +Sutli +Qatiq +Salomatlik +Temir +Zahar +Oqimli +Shamol +Olov +Yer +Osmon +Shanba +Dushanba +Seshanba +Chorshanba +Payshanba +Juma +Yakshanba +Oltin +Tong +Bomdod +Asr +Shom +Kun +Oqsoqol +Shoshqaloq +Kulgili +Muxlislilar +Tavsiflash +Tuzilishga +Mustaqillik +Tushuntirish +Boshqarish +Mashhurlik +Tarkibiy +Tahlil +Ishchi +Xalqaro +Tarjima +Mustahkamlik +Chaqaloq +Istiqbol +Tasvir +Taklif +Tasavvur +Jiddiy +Majburiyat +Asosiy +Tahdid +Tushunmovchilik +Ishonch +Maqomi +Ijodkor +Tadbirkor +Hayotiy +Mashhur +Bemorlik +Tadbir +Jismoniy +Madaniyat +Xavfsizlik +Sifatli +Suvli +Sotuvchi +Chetel +Tashqi +Sotuv +Tarbiyalanish +Murabbo +Sariqcha +Qovun +Shaharlik +Muhimlik +Tarbiyachilik +Xatolik +Balandlik +Yuzaki +Kuyov +Qiziquvchan +Orzular +Mashq +Qalampir +Muammo +Sadoqatli +Yovuzlik +Fikr-mulohaza +Boylik +Tushuncha +Zanjir +Eslatma +Tabassum +Ishonuvchi +Chidamlilik +Ilova +Birodarlik +Oqilona +Ijodiyot +Tayanch +Hurmat +Baxtli +Tajriba +Samimiylik +Shifokor +Ishrat +Baho +Namoyish +Qiyinchilik +Bolalar +Ishonchli +Taqdir +Shovqinli +Xalqaro +Baxt +Fursat +Hurmatli +Qulaylik +Zamonaviy +Sadoqat +Sabr +Nikoh +Jasorat +Barkamollik +Dunyoqarash +Omadli +Foydali +Yorqin +Mehribonlik +Fazilatli +Kutubxona +Istiqomatli +Fido +Bahor +Shafqatsizlik +Tafakkur +Fazilat +Qochish +Laziz +Uzoq +Ilhom +Omad +Hurmatli +Tandir +Sherzod +Bahoriy +Dilshod +Baxtli +Shonli +Nurli +Shafqatsizlik +Oqqush +Boylik +Toza +Sabrli diff --git a/Common/3dParty/hunspell/test/dst/vi_VN.txt b/Common/3dParty/hunspell/test/dst/vi_VN.txt new file mode 100644 index 00000000000..bcc3ab31505 --- /dev/null +++ b/Common/3dParty/hunspell/test/dst/vi_VN.txt @@ -0,0 +1,128 @@ +Bánh +Bang +bênh +bướng +bậy +Chanh +chum +chuyện +chép +Chùng +chắp +chệnh +chới +chữ +công +cạc +cột +cứu +Doanh +duyên +dùng +dể +dọng +gia +giày +giêng +Giảng +giềng +hon +Hoẳn +Hài +hôm +hước +hấu +hớt +hữu +Khiển +Khoào +khuya +khuyến +khách +khén +khẩn +khắp +khựng +kẻo +lang +liền +Loàng +Luỗng +lình +lương +lấp +lệnh +lịnh +lốn +lời +lựng +Muộn +Mãnh +mại +mạn +mổ +mởn +nghiễm +nghều +Ngoáy +Nguyên +ngóp +người +ngỏ +ngớp +ngụa +ngửng +nhiếp +nhu +nhà +nhân +Nhóm +nhưỡng +nhắm +nhổn +nhứt +ninh +noi +nãy +nạn +nốt +ong +pao +phiên +phiêu +Phên +Phương tiện [] +phẩm chất [] +phố đi bộ [phố đì bộ, phố đĩ bộ] +quan trọng [quàn trọng, quản trọng, quán trọng, quăn trọng, quằn trọng, quắn trọng, quặn trọng, quân trọng, quần trọng, quẩn trọng, quẫn trọng, quấn trọng, quận trọng] +quyền lợi [quyền] +quán cà phê [qùán cà phê, qủán cà phê, qũán cà phê, qúán cà phê, qụán cà phê, qưán cà phê, qừán cà phê, qửán cà phê, qữán cà phê, qứán cà phê, qựán cà phê] +quảng cáo [quảng] +Quốc +Quốc tế [Quốc] +riêng biệt [triêng] +rưỡi +Rải +Rẻng +rộng rãi [rộng] +siễn +sum +Sõng +Sưu +sưu tập [] +sử dụng [sử đụng] +Thiệt thòi [] +Thuộc về [Thuộc] +thuộc tính [] + +Слова с ошибками [] +thiệte [thiệt, thiệt e, thiện] +quốq tế [] +nguên [nguyên, nguồn] +khoao [khoào, khoai, khoa, khao, khoeo, khoèo, khoan] +chenh [chênh, chềnh, chểnh, chễnh, chếnh, chệnh, cheng, chen, chanh, chành, chảnh, chánh, chạnh, chinh, chình] +chhùng [chùng, chùn, hùng] +man +doah [doa, doanh, doan, doa h] +khien [khiên, khiền, khiển, khiến, khin, khen] +ngoay diff --git a/Common/3dParty/hunspell/test/main.cpp b/Common/3dParty/hunspell/test/main.cpp new file mode 100644 index 00000000000..6d9406c53e6 --- /dev/null +++ b/Common/3dParty/hunspell/test/main.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/3dParty/hunspell/hunspell/src/hunspell/hunspell.h" +#include "../../../../DesktopEditor/common/StringExt.h" +#include "../../../../DesktopEditor/common/Directory.h" + +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; +} + +int main(int argc, char *argv[]) +{ + std::wstring sSrcDir = NSFile::GetProcessDirectory() + L"/../src"; + std::wstring sDstDir = NSFile::GetProcessDirectory() + L"/../dst"; + std::wstring sDictionariesDir = NSFile::GetProcessDirectory() + L"/../../../../../../dictionaries"; + 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"; + + 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); + } + + return 0; +} diff --git a/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt b/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt new file mode 100644 index 00000000000..4d97adce042 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/az_Latn_AZ.txt @@ -0,0 +1,213 @@ +A +qocalmaq +Alderaan'ın +hamısı +həmçinin +Və +cavab +dir +incəsənət +kimi +da +uzaq +körpə +zirzəmi +ol +olub +doğuldu +bulvar +fasilə +nəsllər +gəlin +lakin +al +ilə +Kaliforniya +Kalifornikasiya +bilər +kartlar +şans +Çin +çənə +klublar +Cobain +bürc +nəzarət +qiymət +edə bilməzdim +yaratmaq +lənət +rəqs +saziş +sövdələşmələr +dağıdıcı +almazlar +etməz +etməyərik +arzu +xülyalar +Şərq +kənar +kənarları +məmnunluq +hamının +uzaq +peri +solğun +üz +son +tap +ilk +üçün +-dan +sərhəd +qız +qızın +yaxşı +gitara +əl +hardcore +var +yoxdur +o +eşitmək +ürək +O'nun +ona +gizli +yüksək +ona +onun +Hollivud +Mən +Mənəm +əgər +içində +məlumat +içində +dir +bu +jack +sadəcə +kral +qohum +bilmək +qoyulmuş +qanun +yerləşdirilmək +qurğuşun +aparmaq +yerləşdirilmə +məkan +sevmək +şans +edilmiş +adam +çox +Evlənmək +maska +o bilər +bəlkə də +mənası +mən +meditasiya +xatirə +ağılın +pul +mənim +heç vaxt +deyil +heç nə +nömrələr +of +of +üstündə +bir +yalnız +və ya +nəticə +öz +Ödə +Şəftəli +yerlər +oynayır +oynamaq +əhali +porno +tərifləmək +ehtimal ki +ehtimal +psixik +kraliça +qaldırmaq +qalan +hörmət +qalxmaq +yol +xam +müqəddəs +Xilas et +elmi +çığırmaq +satılır +şəkil +xəstələnmək +gümüşçü +dəri +əsgər +bir şey +Mahnı +mahnılar +qılınclar +büyü +casuslar +ulduz +Stansiya +oğurlamaq +daşlar +günəş +şübhəli +İsveç +qılınclar +yeniyetmə +test +dandan +bu ki +bu ki +bu +onların +bu +onlar +düşünmək +bu +onlar +gel-git +üçün +deyilmişəm +çox +cəhd et +başa düşdüm +qilin +titrəmək +mübarizə aparır? +istəyirəm +müharibə +idi +dalğalar +geymək +silahlar +yaxşı +idarə olunan +Qərbi +nə +arasında +qalib gəlmək +qalib gəlir +ilə +qadın +dünya +səhv +siz +sizə +sənsən +sənin diff --git a/Common/3dParty/hunspell/test/src/bg_BG.txt b/Common/3dParty/hunspell/test/src/bg_BG.txt new file mode 100644 index 00000000000..a09b554067d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/bg_BG.txt @@ -0,0 +1,212 @@ +A +остаряване +Алдераан +всичко +също +и +отговор +са +изкуство +като +в +далеч +бебе +мазе +бъда +било +роден +булевард +почивка +породи +невеста +но +купувам +от +Калифорния +Калифорникация +може +карти +шанс +Китай +брадичка +клубове +Кобейн +съзвездие +контрол +цена +не можех +създаване +проклятие +танц +сделка +сделки +унищожение +диаманти +не прави +не правим +мечта +мечти +Изток +ръб +ръбове +екстаз +всеки +далеч +приказка +избледнява +лица +краен +намирам +първи +за +от +предел +момиче +момичето +добре +китара +ръка +хардкор +има +няма +той +чуя +сърце +той е +нейни +скрит +висок +него +негов +Холивуд +аз +аз съм +ако +в +информация +вътре +е +това е +вале +просто +крал +родственик +знам +определен +закон +поставям +водя +води +местоположение +обичам +късмет +направен +човек +много +Ожени се +маска +май +може би +означава +аз +медитация +спомен +ума +пари +моя +никога +не +нищо +числа +от +изключен +на +един +само +или +изход +свой +Плати +праскова +места +играе +играя +население +порно +похвала +вероятно +вероятен +психичен +кралица +въздигам +останал +почит +възход +път +груб +светия +Спасявам +наука +крясък +продава +форма +по-болен +златар +кожа +войник +някаква +Песен +песни +пикове +заклинание +шпиони +звезда +стация +крада +камъни +слънце +подозрителен +Швеция +мечове +тийнейджър +тест +отколкото +това +това е +на +техни +тези +те с +мисли +този +той +прилив +до +каза +също +опитайте +разбрано +еднорог +вибрация +водене? +искам +война +беше +вълни +носете +оръжия +Ами +бяха +Западна +какво +докато +победа +победи +със +жена +свят +грешка +ти +ти би +ти си +вашият diff --git a/Common/3dParty/hunspell/test/src/ca_ES.txt b/Common/3dParty/hunspell/test/src/ca_ES.txt new file mode 100644 index 00000000000..3fd8739062a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ca_ES.txt @@ -0,0 +1,112 @@ +amor +llum +lluum +esperança +espirança +llibertat +força +forrça +pau +somni +llibre +mar +amistat +cançó +flor +cel +estrella +temps +camí +vent +muntanya +mumntanya +riu +soroll +silenci +viatge +foc +gel +paraula +vida +dia +nit +tarda +matí +lluna +sol +llac +marbre +ferro +sal +mel +sucre +peix +ocell +oceoll +joc +ritme +melodia +pintura +pentura +teatre +dansa +poema +història +llegenda +mitologia +festa +música +vi +cervesa +cervessa +formatge +pa +ciutat +poble +natura +camp +bosc +platja +sorra +sorrà +pedra +ànima +cos +ment +cor +somriure +somriàre +abraçada +bes +parla +oida +vista +tacte +gust +olfacte +color +forma +número +lletra +sistema +regla +escola +universitat +univversitat +mestre +estudiant +sabiduria +lliçó +pregunta +resposta +risposta +dubte +certesa +veritat +mentida +promesa +secret +descoberta +descaberta +aventura +destinació \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt b/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt new file mode 100644 index 00000000000..8b31af1a394 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ca_ES_valencia.txt @@ -0,0 +1,212 @@ +A +envellir +Alderaan +tot +també +I +resposta +és +art +com +a +lluny +nadó +celler +ser +ha estat +nat +bulevard +pausa +generacions +núvia +però +comprar +amb +Califòrnia +Californication +pot +cartes +oportunitat +Xina +mentó +clubs +Cobain +signe del zodíac +control +preu +no podria +crear +maleït +ballar +acord +negocis +destructiu +diamants +no fer +no fem +desitjar +somnis +Est +vora +voreres +satisfacció +tots +llunyà +fada +pallid +cara +final +trobar +primer +per +de +frontera +noia +la noia +bé +guitarra +mà +hardcore +hi ha +no hi ha +ell +sentir +cor +ell és +seva +secret +alt +ell +seu +Hollywood +jo +sóc +si +en +informació +interior +és +és +jack +només +rei +parent +saber +fixat +llei +col·locar +plom +portar +col·locació +lloc +estimar +oportunitat +fet +home +molts +casar-se +màscara +podria +potser +sentit +jo +meditació +memòria +ment +diners +meu +mai +no +res +números +de +fora +sobre +un +només +o +resultat +seu +pagar +préssec +llocs +jugar +joc +població +porno +elogiar +probablement +probable +psíquic +reina +elevar +restant +respecte +pujar +camí +cru +sant +salvar +ciència +crit +vendre’s +figura +malalt +joier +pell +soldat +alguna cosa +cançó +cançons +cims +encanteri +espies +estrella +estació +robar +pedres +sol +sospitós +Suècia +espases +adolescent +prova +que +que +això +seu +aqueixos +ells +pensar +aqueix +ells +marees +per +no he estat +molt +intentar +entendre +fer +tremolar +lluitar +desitjar +guerra +va ser +ones +portar +armes +bé +administrat +Oest +què +entre +guanyar +guanya +amb +dona +món +equivocat +tu +vostè +tu ets +teu diff --git a/Common/3dParty/hunspell/test/src/cs_CZ.txt b/Common/3dParty/hunspell/test/src/cs_CZ.txt new file mode 100644 index 00000000000..a76fe6803e8 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/cs_CZ.txt @@ -0,0 +1,206 @@ +pomaliý +šťstný +smuutný +horcký +studiený +záludnast +náhodillost +úpěnlevý +rozspačitý +svéhllavý +jablko +slunce +voda +dům +pták +káva +chleba +květina +kniha +pes +kočka +město +zelený +modrý +červený +bílý +černý +velký +malý +rychlý +pomalý +šťastný +smutný +horký +studený +nový +starý +hezký +ošklivý +dobrý +špatný +zdravý +nemocný +silný +slabý +chytrý +hloupý +pracovat +jíst +pít +spát +číst +psát +mluvit +smát se +plakat +zpívat +hrát +tančit +učit se +nakupovat +vařit +telefonovat +dívat se +poslouchat +chodit +běžet +létat +plavat +psát +učit se +dělat +mít +být +jít +přijít +odejít +dát +vzít +říct +vidět +slyšet +cítit +myslet +chtít +moct +muset +rád +nerad +ano +ne +prosím +děkuji +na shledanou +omlouvám se +sbohem +ahoj +čau +hej +jo +fakt +super +blbost +paráda +no jo +jasně +takže +vlastně +třeba +snad +leštěnka +pochmurný +živelný +ponaučení +záhada +pochybnost +nádhera +soucit +záludnost +náhodilost +úpěnlivý +rozpačitý +svéhlavý +marnivost +blahodar +rozčarování +odchylka +přelud +vytrvalost +neústupnost +lehkost +souznění +rozmarnost +roztržitost +úskočnost +rozkoš +marasmus +rozpolcenost +neúprosnost +ztřeštěnost +chmurnost +okouzlení +zářivost +vyrovnanost +neochvějnost +neúcta +bizarnost +rozmařilost +nepochopení +nevýslovný +pomíjivost +beznaděj +úzkost +odtažitost +rozerv +rozervanost +vyčerpanost +bezcitnost +záludnost +nezdolnost +rozkošátnost +nezdolatelnost +rozmarnost +živelnost +bezútěšnost +záhadnost +neposkvrnitelnost +rozkošnělost +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +rozervanost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +ztracenost +bezbřehost +opojení +bezradnost +neuchopitelnost +pošetilost +opojení +rozervanost +marnost +bezstarostnost +nevinnost +náladovost +vyrovnanost +bezbřehost \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/da_DK.txt b/Common/3dParty/hunspell/test/src/da_DK.txt new file mode 100644 index 00000000000..1581a616601 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/da_DK.txt @@ -0,0 +1,129 @@ +Hej +Goddag +Tak +Ja +Nej +Måske +Mad +Vand +Hus +Bil +Tog +Cykel +Skole +Børn +Far +Mor +Søster +Bror +Hund +Kat +Fisk +Fugl +Træ +Blomst +Græs +Sol +Måne +Himmel +Regn +Sne +Sommer +Vinter +Forår +Efterår +Aften +Nat +Dag +Uge +Måned +År +Læse +Skrive +Tale +Lære +Arbejde +Sove +Vågne +Løbe +Gå +Sidde +Stå +Lytte +Se +Høre +Spise +Drikke +Kød +Frugt +Grøntsager +Ost +Brød +Vand +Juice +Kaffe +Te +Mælk +Smør +Æg +Salt +Peber +Sukker +Bolle +Smørrebrød +Køkken +Stue +Soveværelse +Badeværelse +Toilet +Bord +Stol +Sofa +Lampe +Vindue +Dør +Gulv +Loft +Væg +Sofa +Pude +Tæppe +Badekar +Håndvask +Spejl +Håndklæde +Seng +Dyne +Dynee +Pude +Pudee +Alarm +Alarmm +Skrivebord +Stol +Hus +Hund +Kat +Katt +Bil +Skole +Skolee +Sol +Soll +Vand +Vandd +Mad +Madd +By +Barn +Barnn +Tørklæde +Skæbne +Uafhængighed +Kærlighed +Kærligheed +overbelastning +Modstandsbevægelsen +Uafhængighedserklæringen +Forårssommertemperaturen +Stabiliseringsperioden diff --git a/Common/3dParty/hunspell/test/src/de_AT.txt b/Common/3dParty/hunspell/test/src/de_AT.txt new file mode 100644 index 00000000000..fccb06c4319 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_AT.txt @@ -0,0 +1,131 @@ +Ägyptologie +Ährenamt +Ängstlichkeit +Äquatoria +Abarbeiten +Abbild +Abbilden +Abbildungs +Abbreviatur +Abbrüche +Abfassen +Abfertigen +Abfolge +Abfuhr +Ableugnen +Ablichten +Ablöse +Absätze +Abschnitts +Abwechseln +Abwehren +Aktiv +Britannia +Browserfenster +Budgetieren +Bugpartie +Bukarester +Burgundersoße +Butterkrem +Button +Cabriolet +Campanile +Canapé +Caprice +Celsius +Chamäleon +Charakteristik +Chronometer +Chronometrie +Cölln +Connectzustände +Cursorspur +Däne +Dachs +Dahindämmern +Darbringen +Daten +Datenbankserver +Desktopsystem +Detektivfilm +Dichtertum +Dinosaurier +Direktion +Diskantgambe +Diskothek +Druckereicode +Kapsel +Karausche +Katzen +Klinge +Klinke +Kohlrabi +Koinzidenz +Kolleg +Komplott +Meereis +Mehrphasigkeit +Memorieren +Messen +Methode +Metrowaggon +Meute +Migräne +Milieuforschung +Mindern +Mineralien +Mitternacht +Mobiliar +Mohrrübe +Mühelosigkeit +Normativität +Notifikation +Ökonomie +Orangeton +Osten +Subjekt +Subsidiarität +Subsumieren +Tagfalter +Speicher +Spielzeugsammlung +Zahler + +Сложные слова +Zurückgezogenheit +Äquipotentialfläche +Äußerungsbedeutung +Abfassungszeitraum +Abgeschlossenheits +Adjunktionsbeseitigung +Anknüpfungsgrundsätze +Chiffrierschlüssel +Knochenmarktransplantation +Bundeskaderathlet +Carbonsäurechlorid +Cardiazoltherapie +Chancenungleichheit +Charakterisierungsmöglichkeit +Chlorophyllkonzentration +Computerspielemarkt +Deindustrialisieren +Dekodierungsmöglichkeit +Kartoffelschälmesser +Kernspinresonanztomographie +Merkmalskombination +Nachbarschaftszentren +Opportunitätsprinzip +Tiefenstaffelung +Tourismusfachmann +Sequenzbetrachtung + +Слова с ошибками +Dechifrierprogramm +Administratorkenwort +Spigeln +Tätigkeite +Draufgangertum +Abschnit +Komunikation +Drackereicode +Bumeln \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/de_CH.txt b/Common/3dParty/hunspell/test/src/de_CH.txt new file mode 100644 index 00000000000..12c46630805 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_CH.txt @@ -0,0 +1,116 @@ +Alpinist +Alteration +Alternative +Alumne +Amateurfilmer +Ambulanz +Amtmänner +Analogie +Analytik +Ananas +Angabe +Ankünfte +Dynastie +Ebenbürtigkeit +Echtheitszertifikat +Editionspläne +Editor +Ehrenamtlichkeit +Eigentümerschaft +Einbau +Eindringling +Eingabequittungsbetrieb +Einhüllen +Einkommen +Einloggen +Einschließen +Einsortier +Elaboration +Elementar +Entertainer +Entkuppeln +Entschädigungs +Enumerator +Erbringen +Erdichten +Erfahrenheit +Erhalt +Erleichtern +Ersparnis +Erstatten +Erzählliteratur +Helikopter +Helpdesk +Herunterladen +Hindeuten +Hinterlassenschaft +Hiob +Landesprache +flexibilität +floristisch +flugbillet +heroben +herrichten +herstellen +herübereilen +herunterzubücken +hie +hieraus +hilfe +himbeere +justiz +kältebeständig +kärtchen +känguru +kaktusgewächs +kalligrafie +kamel +kampagnendirektor +kapazitär +kapitalist +karamell +kardieren +karpfen +katalogdaten +lyzeum +mahagonirot +makkaroni +malerausbildung +management +mangel +maniküre +manneskraft +mansarde +mark +marketingpraktiker +maschinell +massage +massengutschifffahrt +materie +medaille +medizinalshampoo +meeresfrüchte +quotient +salonwagen +satzeinleitend +trilateral +tristesse +tropen +vereisen +verfahren +verfügungs +verhindern +verkäufer + +Слова с ошибками +Anbindungsystem +Anglistikdocent +Ecco +Economclass +Einverstandnis +Electrik +Historique +herüberzurucken +kartofel +salade +sanddornbere \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/de_DE.txt b/Common/3dParty/hunspell/test/src/de_DE.txt new file mode 100644 index 00000000000..3ab503f810a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/de_DE.txt @@ -0,0 +1,211 @@ +Hallo +Guten Morgen +Danke +Bitte +Ja +Nein +Entschuldigung +Tschüss +Liebe +Freund +Familie +Glück +Gesundheit +Schule +Arbeit +Essen +Trinken +Wasser +Brot +Käse +Fleisch +Gemüse +Obst +Kaffee +Tee +Milch +Zucker +Salz +Pfeffer +Haus +Wohnung +Bett +Stuhl +Tisch +Sofa +Fernseher +Telefon +Computer +Buch +Zeitung +Schreiben +Lesen +Hören +Sehen +Fühlen +Laufen +Springen +Schwimmen +Tanzen +Singen +Lachen +Weinen +Freude +Trauer +Angst +Mut +Liebe +Hass +Freundschaft +Beziehung +Familie +Eltern +Kinder +Geschwister +Großeltern +Onkel +Tante +Cousin +Cousine +Ehemann +Ehefrau +Verlobung +Hochzeit +Scheidung +Geburt +Tod +Krankheit +Arzt +Krankenhaus +Medikament +Apotheke +Gesundheit +Wohlbefinden +Fitness +Diät +Schlaf +Ruhe +Entspannung +Sport +Fußball +Tennis +Schwimmen +Laufen +Radfahren +Wandern +Reisen +Urlaub +Strand +Sonne +Meer +Komplementär +Perspektive +Konsens +Integrität +Konsequenz +Authentizität +Korrelation +Charakteristik +Akzeptanz +Flexibilität +Assoziation +Dekomposition +Komplexität +Positivismus +Universalität +Stabilität +Individualität +Konsistenz +Konformität +Dezentralisierung +Kollaboration +Partizipation +Präzision +Transformation +Konkurrenz +Paradoxie +Redundanz +Regeneration +Integration +Isolation +Asymmetrie +Aggregation +Disziplin +Resilienz +Relevanz +Konfusion +Komplikation +Koordination +Harmonie +Ineffizienz +Konstruktion +Konversion +Kollusion +Gerontologie +Differenzierung +Dimensionalität +Inferenz +Fluktuation +Kontraktion +Rezession +Inflation +Dekontamination +Exzellenz +Innovation +Isomorphie +Konnotation +Insuffizienz +Konversion +Kompensation +Koalition +Inkongruenz +Inkontinenz +Kontrahent +Konfiskation +Konjunktur +Aggression +Konfrontation +Kompatibilität +Prognose +Akzeleration +Konstruktion +Diversifikation +Prävention +Sanktion +Indikation +Reduktion +Konkurrenz +Konfiguration +Konnotation +Rezession +Transformation +Interaktion +Kooperation +Innovation +Kollision +Proklamation +Konnotation +Konfrontation +Disposition +Konkordanz +Deklamation +Kollaboration +Isolation +Inflation +Diversifikation +Konnotation +Kompensation +Diffusion +Dekadenz +Konserve +Deklomotion +Kolaboration +Isollation +Infllation +Divirsifikation +Konotation +Kompenssation +Difusion +Dekadens +Kanzerve + diff --git a/Common/3dParty/hunspell/test/src/el_GR.txt b/Common/3dParty/hunspell/test/src/el_GR.txt new file mode 100644 index 00000000000..badd16854fe --- /dev/null +++ b/Common/3dParty/hunspell/test/src/el_GR.txt @@ -0,0 +1,123 @@ +Αβαντάζ +Αβασταγά +Αβγάτισες +αβέβαιο +αβέλτερο +αβέλτεροι +αβίαστους +άβλαβοι +αβοκάντο +αβράδιαστης +άβραστη +αβράχυντου +άβρεχτα +αβρή +αβρότης +άβυσσον +αγαθόν +αγαθούς +αγάλακτο +αγγούρι +αγελαδινού +αγέρα +αγεωμέτρητων +αγίνωτοι +άγκυρες +αγορεύσεις +αγόρευσή +αγορίνα +Αγοριού +Αγροληψία +Αρμόνια +βγαίνοντας +βεβαιώσεων +διάθεση +διαίρεση +Διαιρέσου +Διαιτολογίου +διαψεύσουν +διδασκάλισσας +ενασκήσεις +ενασχόληση +ενασχόλησή +ενδείξεις +ενδεχόμενον +ενδιαμέσου +Επιστήθιες +Επιστημο +Επιστολές +Επιστολή +εύπορους +ευρέα +ευρημάτων +ευρύτητά +ευσταθών +εύστροφα +ευσυνειδησία +εύτακτε +ευτελείς +ευτελίζουν +ιδρυτικό +ιεροψάλτες +Ιζόλα +Ιθαγένειάς +ικανότατος +ιλαρότης +κεφαλής +κεφαλιάτικες +κεφαλωτές +κήπε +κήπευση +Κήρυξής +Λεξικογραφιών +Λεξιλογικός +λεοντή +λεοντής +ολιγοχρόνιου +ολικέ +ολικές +ολική +πελαγώνω +πελατών +πελάων +προστατεύει +προστασίας +σούρουπου +σουρούπωμα +σούρτης +Σούρωνα +Σπαγέτα +Σφάλμα +Σφάλματά +σφικτά +σφικτέ +σφοδρότητας +σφοδρού +σφραγίσω +σχεδιάζουμε +σχεδιάζουν +σχηματίσου +σχηματίσουμε +σχολιάζεσαι +Σχολιάζεστε +Ενδιαφέροντα + +Слова с ошибками +Αβασiλευτου +αγαπούσαv +βeβαιωμένοι +εvασxόλησης +επιoτολικέ +ιδιωτικοποιήσειc +λεπταίσθnτη +πρoστιμάρισμα +σφάλμαtα +προστάτεuε +κεxριμπαριού +διαισθnτικότητες +αγκιστpώσουv +αγαθoεργiας +αβεβαιoτητά +αγέρεc +διδαxθούμε +εuσταθειώv \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_AU.txt b/Common/3dParty/hunspell/test/src/en_AU.txt new file mode 100644 index 00000000000..f9404bce0d3 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_AU.txt @@ -0,0 +1,116 @@ +Acknowledge +acrophobia +adventurousness +aeronautics +algal +Alligator +allegation +alphabetise +Analogy +appropriable +assembly +attempt +Average +barbecue +bathtub +begun +belongingness +Better +binary +blackberry +boatswain +bow-tie +brambly +bright-eyed +bubble +Calender +cancellous +cantankerousness +carefree +categorized +cellular +chaos +cheerfulise +childlike +circumstance +close-mouthed +Cocoa +coherent +co-located +Colours +controversial +cottage +creditworthiness +cut-down +dedicated +deep-freeze +Definitive +Designs +digital +distensible +dollar +dyslexia +Egyptian +effectively +etiquette +excess +exotica +fairly +feedback +features +figure's +fjord +forty-seven +government +haematomata +helpless +homologous +implant +Indemnify +inexpert +interior +localises +loquaciousness +maelstrom +mechanizable +melodious +mezzo-soprano +mozzie +municipalisation +mystifier +Neoclassicism +newsletter +non-professional +officiation +orientalisation +palaeoanthropography +parrot +pickpocket +pioneer +cryptanalytic +simplifying +sommelier +spicy +steward +subcontinental +swimwear +Technical +trajectory +wholesomeness +Advantageously +interindustry +red-eye +sub-group + +Слова с ошибками +Acredited +agressive +appreciativiness +aritmetical +biosyntesized +lisense +paranoa +fotoelectronic +semi transparent +synonymus +wordprocessing \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_CA.txt b/Common/3dParty/hunspell/test/src/en_CA.txt new file mode 100644 index 00000000000..f3bf6608a78 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_CA.txt @@ -0,0 +1,125 @@ +admire +admittance +aggrandizement +Airmen +Albatross +amateur +angling +apparatus +Architecture +assessment +attempt's +awakening +backgrounder +Balance's +barometric +bashfulness +beautiful +belletristic +blatancy +bonbon +border +Bottom +bountifulness +breakpoints +bulkiness +businesslike +can't +cash +castle +Casual +cauliflower +celebrity +childish +chokecherry +choreographically +chronological +classification +clearheaded +coalesce +Coexistence +collaborative +coloured's +concentration +draconian +drainpipe +demonstrativeness +dependence +dependency +dream +duplication +epidemiological +equitable +Essence +Exemption +exonerate +fainthearted +falsification +ferromagnetic +flammable +fraternization +French +frontier +gadget +galleria +Gallery +gateaux +geocache +ginger +glace +glacier +globalization +hockey +holiday +housemate +intensifier +joystick +Language +leaseholder +non-breakable +northerly +o'clock +oeuvre +openhandedness +oscillation +outface +outlaw +overladen +package +palazzo +panama +Paragraphs +Parliament +particular +pasteurization +pathogen +perception +phenomena +philanthropically +physical +populations +repugnance +request +resplendence +retroactive +rigidity +schedule's +School +scintillation +sensibility +settlement +taxiway +bereft + +Слова с ошибками +acomplishment +anihilate +caprise +chambre +etnographically +horsmanship +innundation +lemongras +omelete +retorical +shepishness \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_GB.txt b/Common/3dParty/hunspell/test/src/en_GB.txt new file mode 100644 index 00000000000..f50273dd01d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_GB.txt @@ -0,0 +1,122 @@ +Abbreviation +Acceptability +acquirable +Addressee +afterthought +airworthiness +all-powerful +amateurishness +amorphousness +anthology +Auspiciousness +Bibliographer +Bilberry +birthday +bodyguard +broadleaved +brontosaurus +bumptiousness +Cabaret +Californian +calumny +cancellation +cantonal +capitalize +careful +carry-on +casino +clown +co-ordinate +cockleshell +decennial +deckchair +decryption +deep-freeze +Democracy +financial +fish-plate +Flamenco +housing +Hybrid +hydroelectricity +iceboat +ichthyology +idiomatic +ill-humoured +imperatrix +individuality +interocular +intrasectoral +ironwoods +Jolliness +Jurisprudent +knowledgable +kopeks +labour-intensive +laboratory +lake +language +larynx +latching +leakiness +License +licensed +licensee +life-threatening +linguistics +long-lived +machinable +mainsheet +Major +malleability +man-hour +Mango +ninety-five +nobody +non-blocking +non-judicial +nonconforming +north-Western +nutritiousness +quasi-synchronous +question +racoon +radish +Railway +Rarity +saucer +Save +Saying +supplely +tallish +target +Taxi +teach-in +technician +ultramodern +umbrae +uncertainness +unconstitutionality +washing +wasn't +waxen +weather +well-formed +what's-his-name +whereupon +Wi-Fi +Wikipedia + +Слова с ошибками +Abstractnes +advantageusness +arhythmical +autosuggestibility +kaptor +coldshouldering +humaneneses +imaginativness +knight-erantry +magasine +night-wachman +qualifidly \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/en_US.txt b/Common/3dParty/hunspell/test/src/en_US.txt new file mode 100644 index 00000000000..f910ca76ce8 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_US.txt @@ -0,0 +1,216 @@ +apple +banana +cat +dog +egg +fish +gold +house +ice +juice +kite +lion +mouse +night +orange +pencil +queen +rabbit +sun +tea +umbrella +vase +watch +xylophone +yellow +zebra +arrow +book +cake +car +day +elephant +flower +hat +island +jelly +king +lamp +moon +nose +owl +pink +quilt +radio +sunflower +tree +unicorn +violin +water +xylophone +yellow +zoo +apple juice +blue +calculator +desk +elephant +fire +goat +hat +ice cream +jacket +key +lemon +map +notebook +owl +pear +quilt +rose +soccer +table +umbrella +vegetable +whale +xylophone +yellow +zebra +apple pie +beach +computer +drum +elephant +goat cheese +hat +ice skate +juice box +kite festival +lemonade +mountain +notebook paper +orange juice +pizza +queen bee +rainbow +snow +turtle +umbrella hat +valley +Aberration +Absolution +Acquiesce +Adumbrate +Aesthete +Altruistic +Ambivalent +Anomalous +Antediluvian +Antipathy +Aphorism +Apocryphal +Apostasy +Apparition +Arduous +Assiduous +Audacious +Austere +Autonomy +Avaricious +Axiomatic +Baleful +Bellicose +Belligerent +Bereft +Bilious +Bombastic +Cacophony +Capricious +Cartography +Castigate +Clandestine +Coalesce +Cogent +Cognizant +Colloquy +Concomitant +Confabulate +Congenial +Conundrum +Copious +Corpulent +Coven +Credulous +Culpable +Dearth +Debilitate +Deleterious +Denigrate +Despondent +Diatribe +Dilapidated +Disparage +Dissemble +Dissonance +Duplicity +Ebullient +Egregious +Ephemeral +Equanimity +Esoteric +Euphemism +Evanescent +Exacerbate +Exhort +Expatriate +Extol +Facetious +Fatuous +Feckless +Felicitous +Feral +Fervent +Fetter +Flummox +Fractious +Garrulous +Hegemony +Iconoclast +Idiosyncrasy +Ignominious +Impecunious +Ineffable +Inexorable +Inscrutable +Insidious +Intrepid +Intransigent +Invective +Irascible +Juxtapose +Kowtow +Languid +Lassitude +Lurid +Malinger +Maudlin +Mawkish +Mendacious +Metaphysical +Antransigent +Inwective +Iracible +Juxtopose +Kovtow +Langued +Lasitude +Larid +Mallinger +Haudlin +Mavkish +Mendocious +Mitaphysical +timeline +rollout +workshopped +deliverables diff --git a/Common/3dParty/hunspell/test/src/en_ZA.txt b/Common/3dParty/hunspell/test/src/en_ZA.txt new file mode 100644 index 00000000000..f509809717c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/en_ZA.txt @@ -0,0 +1,114 @@ +Acceptably +Achievement +administrate +all-day +amount +average +bilayer +blasé +boutique +breezy +byers +cabdriver +carefree +categorised +Chameleon +cheerful +chronology +cliché +cooling-off +courage +crudités +decorates +dooryard +débâcle +electromotive +equalled +Exotica +fellow-traveller +forests +full-timer +graded +habitué +haven't +hide-and-seek +home-building +interaxial +kingdom +largeness +long-distance +Majority +manoeuvre +Matrix +metier +mightn't +multidisciplinary +night-time +officio +old-style +organize +overaggressive +packing +parenthesis +pince-nez +Plaint +play-act +policy-making +Preheat +prohibit +puzzle +queue +quite +re-enact +reason +ready-made +renewal +resize +rooihout +scampi +schoolteacher +sea-green +shop-boy +sidebar +skyscraper +soundless +spelling +stakeout +synchronizing +take-off +Thereof +Trademark +transportable +treatment +tweeness +under-age +unmake +Variate +Visitant +volume +webmaster +well-prepared +window +yesteryear +first-aid +Hydrant +inconstant +network +northernmost +nowhere +souvenir +telecommunicate + +Слова с ошибками +afordable +anthropologie +bagage +comparatif +flammeble +indivizible +jetlag +lettrebox +panoramma +posessor +selfdoubt +abandonner \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/es_ES.txt b/Common/3dParty/hunspell/test/src/es_ES.txt new file mode 100644 index 00000000000..05520c2d2f1 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/es_ES.txt @@ -0,0 +1,208 @@ +nosotros +vosotros +ellos +ellas +aquí +allí +ahora +antes +después +siempre +nunca +también +solamente +verdad +mentira +bien +mal +grande +pequeño +rápido +lento +nuevo +viejo +bueno +malo +feliz +triste +bonito +feo +caliente +frío +dulce +amargo +fuerte +débil +cerca +lejos +fácil +difícil +cierto +falso +caro +barato +limpio +sucio +fuerte +débil +alto +bajo +claro +oscuro +abierto +cerrado +joven +viejo +corto +largo +alegre +tranquilo +nervioso +amable +grosero +conocido +desconocido +cortés +rudo +agradable +desagradable +sabroso +insípido +difícil +fácil +cansado +descansado +moderno +antiguo +último +primero +posible +imposible +rápido +lento +sencillo +complicado +propio +ajeno +abierto +cerrado +amable +desagradable +seguro +inseguro +correcto +incorrecto +dulce +amargo +Anacoreta +Sobrentender +Embriaguez +Inquebrantable +Empedernido +Derramamiento +Despotricar +Escafandra +Aletargamiento +Estancamiento +Descarado +Exégesis +Contrariedad +Espeluznante +Conspiración +Impedimenta +Deglutir +Engreído +Enmascarado +Exterminio +Embelesar +Permutación +Desesperanza +Impenetrable +Enarbolamiento +Errabundo +Deslinde +Inefable +Soliviantar +Embriaguez +Perdurable +Opulencia +Trémulo +Desembolso +Empedernido +Anquilosar +Enigmático +Inquebrantable +Contrincante +Desmesurado +Vanagloriar +Exasperar +Desvanecer +Perpetuidad +Desbaratar +Ineficaz +Zozobra +Elucubración +Ineludible +Desgarramiento +Atestiguar +Encascarar +Desembozar +Irreverente +Soslayar +Despiadado +Embaucar +Moflete +Endilgar +Desfalco +Embelesamiento +Desestimar +Enajenación +Desavenencia +Inexorable +Atolladero +Egrégoro +Desafiar +Afable +Enervar +Belicoso +Enervar +Descacharrante +Entramado +Inigualable +Perplejidad +Descabellado +Diligencia +Enaltecimiento +Desvergonzado +Arrebato +Empatía +Endiosar +Peripecia +Desidia +Subversión +Desfachatado +Desfalco +Desvirtuar +Errático +Desahuciar +Envilecimiento +Empecinado +Estolidez +Despropósito +Engatusar +Culminante +Sobrentender +Enseñorear +Desacato +segguro +insseguro +correcto +incarrecto +dalce +amergo +Anasoreta +Sobrententter +Embreagues +Inquebranttable +Empidernedo + diff --git a/Common/3dParty/hunspell/test/src/eu_ES.txt b/Common/3dParty/hunspell/test/src/eu_ES.txt new file mode 100644 index 00000000000..9cbd124e59f --- /dev/null +++ b/Common/3dParty/hunspell/test/src/eu_ES.txt @@ -0,0 +1,132 @@ +Abantza +ñabar +abasto +abegikortasun +aberaskeria +aberetzar +abezedario +abialdi +Abiatzaile +abizari +Aboli +abonatu +absenta +absolutibo +accelerando +adabegitsu +adberbio +adiaka +adierazle +adierazkizun +adikuntza +adin +adinaro +adineratu +adin-txikitasun +administratzaile +adoleszentzia +adopzio +adostu +aerolabangailu +Aeroplano +afalordu +agente +agertezin +agiantza +agoran +arradatze +arrakasta +Batata +baterakuntza +baterakor +Bateri +batuar +baud-abiadura +batzuenganako +batzuengandik +batzuengan +batzuengatik +batzuen +baxera +berezi +berezikeria +beritzete +beroa +Beroate +beroatza +berorri +berrabiatu +berra +berresgarri +berripaper +chap +dabilzkidake +dabilzkie +dagitza +dagokik +dagozkieke +erdiondu +galdera +galtzada +garaitiar +garantia +Garaztaketa +garbitasun +gastronomiko +Gaurgero +gaurgoitik +legizkie +legokizue +legozkidake +lehenbizi +nindoakio +publikotasun +publizitate +subsidiario +substantibo +sugestio +superbalorazio +taidun +taldeburu +Talent +Teknografia +xantxa +xerbitor +xerokopia +zabaldura +Zabalkor +Zabaltza +zabilzkieken +zabilzkio +zaharkote +zeneritzeketen +zenerra +zenezagu +zengozkigute +zeniharduke +zenioke +zenioketez +zeniraute +zenizkien +zenizkiguke +Zintut +Zintuzkedan +isiltasun + +Слова с ошибками +abriсot +absenzia +addikzio +administraziozerbizu +bat-bates +bermagari +cataluniar +dakarza +erdemin +garatienetarikoa +ishil +nindezaguane +nintzainaken +summa +technologiko +charmant \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/fr_FR.txt b/Common/3dParty/hunspell/test/src/fr_FR.txt new file mode 100644 index 00000000000..5ab592e094c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/fr_FR.txt @@ -0,0 +1,211 @@ +Bonjour +Merci +Oui +Non +S'il +Excusez-moi +Pardon +Bien +Mal +Grosse +Petit +Beau +Moche +Fort +Faible +Chaud +Froid +Vite +Lent +Haut +Bas +Loin +Près +Heureux +Triste +Facile +Difficile +Simple +Compliqué +Bon +Mauvais +Nouveau +Vieux +Jeune +Âgé +Bienvenue +Amitié +Amour +Famille +Travail +Maison +Voiture +Manger +Boire +Courir +Marcher +Nager +Chanter +Dormir +Jouer +Parler +Écouter +Regarder +Lire +Écrire +Acheter +Vendre +Aller +Venir +Faire +Dire +Voir +Savoir +Apprendre +Aimer +Détester +Partir +Rester +Arriver +Revenir +Partager +Aider +Aimer +Ouvrir +Fermer +Manger +Boire +Avoir +Être +Pouvoir +Vouloir +Devoir +Parler +Écouter +Rire +Pleurer +Danse +Étudier +Travailler +Voyager +Vivre +Connaître +Reconnaître +Voyager +Exister +Choisir +Donner +Recevoir +Aimer +Oser +Phénoménologie +Électroencéphalographie +Parallélépipède +Anticonstitutionnellement +Transsubstantiation +Éclectisme +Anachronisme +Catéchuménat +Démagogie +Fructueux +Ineffable +Hypothèque +Propriété +Procrastination +Complaisance +Réminiscence +Éthique +Équinoxe +Exponentiel +Hétérogénéité +Imbroglio +Incorrigible +Maelström +Métaphysique +Protagoniste +Subliminal +Verrouillage +Volumétrique +Énigmatique +Époustouflant +Immatériel +Infini +Polyglotte +Recrudescence +Prophylactique +Symbiotique +Vestibulaire +Épistémologie +Faramineux +Géopolitique +Hypnotique +Inamovible +Intemporel +Labyrinthe +Pacifiste +Quémandeur +Soporifique +Ubuesque +Volumineux +Effervescence +Électrophorèse +Paradoxe +Prorata +Quadrupède +Sarcophage +Trigonométrie +Vaccinologie +Xenophobe +Zéphyr +Génétique +Labyrintique +Mégalo +Nostalgie +Omniprésent +Pangramme +Périlleux +Quinquennat +Rémunération +Scolopendre +Tautologique +Utopiste +Vexatoire +Wolof +Xanthine +Yacht +Zanzibar +Axiomatique +Chronométrer +Dilettante +Énervement +Facétieux +Générique +Harmonique +Illusoire +Juridique +Kabbaliste +Longetivité +Médiane +Néologisme +Oxygène +Patronymique +Quotidien +Rétorique +Sémantique +Tautologie +Utopique +Vaccinologie +Xénophobie +Yachting +Zoroastrisme +Voager +Exisster +Chaiser +Doner +Resevoir +Aimmer +Osero +Phénoménollogie +Électraencéphallographie +Parallélépepède + diff --git a/Common/3dParty/hunspell/test/src/gl_ES.txt b/Common/3dParty/hunspell/test/src/gl_ES.txt new file mode 100644 index 00000000000..1fa4436b773 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/gl_ES.txt @@ -0,0 +1,120 @@ +ola +tipo +Si +non +nonnr +comida +comidaa +auga +augaa +casa +coche +cochee +un tren +bicicleta +escola +escolaa +niños +pai +paii +nai +naii +irmá +irmán +cachorro +gato +gatoo +peixe +peixee +aves +avess +árbore +flor +herba +o sol +lúa +o ceo +chuvia +neve +vexa +inverno +primavera +outono +noite +noite +día +unha semana +mes +ano +para ler +escribir +fala +ensinar +traballo +durmir +durmir +correr +vai +senta +estado +para escoitar +vexa +escoita +hai +beber +carne +furtas +verduras +queixo +pan +auga +zume +café +té +leite +aceite +ovo +sal +impacienta +azucre +un bocadillo +cociña +sala de estar +dormitorio +baño +batela +sofá +lámpada +fiestra +a porta +piso +teito +parede +sofá +alfombra +baño +afundir +espello +toalla +cama +manta +almofada +reloxo de alarma +escritorio +cadeira +marabilloso +adverbio +obviamente +Dominante +residenciais +convidado +perigo +cuestión +deporte +mina +cordeiro +cabeza +tratar +avogado +intelixente +guapo diff --git a/Common/3dParty/hunspell/test/src/hr_HR.txt b/Common/3dParty/hunspell/test/src/hr_HR.txt new file mode 100644 index 00000000000..6fbcfb98f7c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/hr_HR.txt @@ -0,0 +1,215 @@ +boliestan +jyak +slaby +pameetan +gllup +bezuspješhno +besimeni +bezuzban +blagastanje +bljeskovica +jabuka +sunce +voda +kuća +ptica +kava +kruh +cvijet +knjiga +pas +mačka +grad +zelen +plav +crven +bijel +crn +velik +malen +brz +spor +sretan +tužan +vruć +hladan +nov +star +lijep +ružan +dobar +loš +zdrav +bolestan +jak +slab +pametan +glup +raditi +jesti +piti +spavati +čitati +pisati +govoriti +smijati se +plakati +pjevati +igrati +plesati +učiti se +kupovati +kuhati +telefonirati +gledati +slušati +hodati +trčati +letjeti +plivati +čitati +pisati +raditi +imati +biti +ići +doći +otići +dati +uzeti +reći +vidjeti +čuti +osjetiti +misliti +htjeti +moći +morati +rado +nerado +da +ne +molim +hvala +doviđenja +oprosti +zbogom +zdravo +čau +ej +da +baš +super +glupost +fantastično +jasno +tako +zapravo +možda +lako +teško +prozračnost +usplahirenost +neoblomivost +prezir +proigranost +uznemirenost +besprijekornost +besprizornost +nepredvidivost +beznadnost +promašenost +protivljenje +neizreciv +bezizlaznost +neuspjelost +zbunjenost +neodlučnost +protivština +nepovratnost +bezduhovitost +ravnodušnost +prolaznost +neobaveznost +bezbrižnost +nepovratnost +promašenost +neprepoznatljivost +neukrotivost +bezobzirnost +nevinost +nestalnost +nepostojanost +bezizlaznost +nepovratnost +prolaznost +neodgovornost +bezbrižnost +nevolja +nezadovoljstvo +prolaznost +bezuspješno +bezimeni +bezuzdan +blagostanje +bljeskavica +boren +carovnija +crpeža +dostojanstvo +duhovitost +egzaltacija +gorkoća +histerija +idila +ironija +izdaja +janjetina +kajanje +kavana +krhotina +ljepljivost +lukavstvo +magnutizam +melankolija +misticizam +naivnost +nelagoda +neraspoloženje +obmana +okrutnost +opojenost +prezir +propast +ravnodušnost +sjenka +skitnica +spletka +stid +sudbina +susret +sudbina +šapat +tišina +trepet +utopija +uzaludnost +veličanstvo +zaborav +zanesenost +zanos +zavjera +zbunjenost +zluradost +zloslutnost +žargon +žártva +šaptanje +čarobnost +dileme +hodočasće +lebdjeti +iznimka +preobilje +probuditi se +surov \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/hu_HU.txt b/Common/3dParty/hunspell/test/src/hu_HU.txt new file mode 100644 index 00000000000..aae52a65b73 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/hu_HU.txt @@ -0,0 +1,114 @@ +Szorzótábla +Réges-régen +normálméret +nemeslelkűség +mindegyik +milliós +Mikroflóra +Mezőgazdaságigép +meséskönyv +mennyiség +Memória +kártya +kuráre +Kurzor +jégkorong +jellemesség +Javak +irányzás +iromány +Inkluzíve +hűtőedény +hőmérséklet +hír +hétszázas +hátrány +háromszáz +Hintó +generátor +gavallérság +explozíva +eső +esdeklés +epilógus +Energia +Előélet +előterjesztés +előnézet +elvonás +elszigetelés +ellátmány +Elevátor +egynémelykor +egyenlőség +eddzenek +dzsungel +ananász +akvárium +Szépül +Sztorizik +szobroz +szimbolizál +szemlélődik +sugdolózik +majmol +Macskáz +Létesít +Lokalizálódik +litografál +levelesedik +lepet +közömbösít +kételkedik +kivirágoz +kerekez +kedvez +járkál +jegyzőkönyvez +iskolázik +individualizál +csendesít +borsoz +billentet +bajmolódik +anyagozik +alkonyodik +Aktualizál +színes +szemelt +lassú +hatékony +hasznos +gyúlékony +gyári +abszurd +örökjog +öregkor +ömlő +Zászlaj +Zseblámpa +regényirodalom +realitás +raktárhelyiség +pötty +pótlék +pótdíj +pályafutás +Promóció +Processzus +poloska +pernye +pediáter +parancsnoklás + +Слова с ошибками +sponzorálás +mihamarábiak +idohatár +hypnotizmus +departement +légiesul +kutagat +költségtakkarékos +redukzió +pilanatfelvétel \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/id_ID.txt b/Common/3dParty/hunspell/test/src/id_ID.txt new file mode 100644 index 00000000000..dff2ed986ef --- /dev/null +++ b/Common/3dParty/hunspell/test/src/id_ID.txt @@ -0,0 +1,121 @@ +acang-acang +Adiksi +Adventisius +Advokat +afirmatif +agroindustry +agrisilvikultur +akhir-akhir +akomodatif +aksi +aljabar +anggul +anotasi +antusiasme +apoteker +bahagia +bakat +bangkang +Bankir +Barikade +bebaru +belar +beleid +bencana +bentangur +beritawan +besuk +bilingualisme +Cecak +Celempong +cencawan +cengkar +ceremai +cermin +cudang +Dampal +dampan +dansa +datung +debitur +defensi +defisit +demper +dendang +Derivasi +Desember +deskripsi +diskotek +diskusi +distansi +dragon +dramatisasi +Eksamen +Eksistensi +eksperimen +ekstensifikasi +ekuitas +elektron +gelut +Geofisikawan +Gerbang +gerempang +influenza +Informasi +Inisiator +insekta +institusional +instruksional +jelajah +Kamrad +Kapilaritas +kapster +kardiovaskular +karismatik +keranjingan +komunal +Limitatif +Linguistik +lintang +masabodoh +matematikus +medisinal +Melankolia +Memorabilia +nasional +nasionisme +Panen +pangkek +peranti +perian +persekusi +perunjung +regenerasi +reglementer +robotika +runjang +Sabtu +Simbang +simpati +tebing +topi +Unggal +unsuri +urbanisasi +variabel +wahana +warganegara + +Слова с ошибками +Abonement +Abcente +ambivalan +bakteriostatic +cekaw +darmavisata +declarasi +duplex +ecozona +gempur-mengempur +jejengok +transitive \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/it_IT.txt b/Common/3dParty/hunspell/test/src/it_IT.txt new file mode 100644 index 00000000000..02852a870c7 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/it_IT.txt @@ -0,0 +1,200 @@ +Ciao +Ciaoo +Buongiorno +Buonasera +Buonassera +Grazie +Prego +Arrivederci +Buonanotte +Scusa +Per favore +Amore +Amico +Famiglia +Casa +Città +Strada +Montagna +Montaga +Mare +Sole +Luna +Stelle +Giorno +Notte +Colazione +Clazione +Pranzo +Cena +Acqua +Vino +Caffè +Pane +Formaggio +Pasta +Pizza +Gelato +Dolce +Salato +Frutta +Verdura +Carne +Pesce +Pollo +Uovo +Sale +Pepe +Olio +Burro +Zucchero +Latte +Yogurt +Insalata +Zuppa +Bistecca +Prosciutto +Parmigiano +Biscotti +Cioccolato +Spagggrhetti +Spaghetti +Lasagne +Risotto +Gnocchi +Penne +Ravioli +Cannelloni +Pesto +Caprese +Limoncello +Espresso +Cappuccino +Tiramisù +Panna cotta +Cannoli +Panettone +Brioche +Focaccia +Foacdccia +Crostini +Arancini +Antipasto +Primo piatto +Secondo piatto +Contorno +Pane tostato +Marmellata +Accoglienza +Affascinante +Aggressività +Alleviare +Appassionato +Armonioso +Autonomia +Autovfnomia +Barbarie +Beneficiare +Bizzarro +Burocrazia +Cambiamento +Capriccioso +Cautela +Commemorare +Comportamento +Conseguenza +Controverso +Coraggioso +Debolezza +Decisivo +Delizioso +Desiderare +Destrezza +Determinato +Determin +Difficoltà +Disponibilità +Divertimento +Eccentrico +Efficienza +Elettrizzante +Emergere +Empatia +Energia +Equilibrio +Esperienza +Fantastico +Fenomenale +Generosità +Gratitudine +Immaginazione +Impressionante +Impressiante +Indipendenza +Ingenuità +Innovazione +Intelligenza +Intensità +Intrigante +Ispirazione +Instabilità +Irresistibile +Leggenda +Libertà +Luminoso +Magistrale +Malinconia +Meraviglioso +Metamorfosi +Miracolo +Misterioso +Nostalgia +Opportunità +Originalità +Passione +Pericoloso +Prestigioso +Prodigioso +Prospettiva +Raffinato +Rafinato +Ricchezza +Rispettoso +Sensibilità +Sorprendente +Spontaneità +Spontaneita +Stravagante +Suggestivo +Surreale +Tenerezza +Trasformazione +Unicità +Vibrante +Vittoria +Volontà +Amicizia +Avventura +Bellezza +Calma +Danza +Eleganza +Felicità +Gioia +Incanto +Magia +Natura +Odore +Passatempo +Quotidiano +Relax +Serenità +Tesoro +Umorismo +Vacanza +Zelo +Avventuriero +Speranza +Risate +Armonia +Incanto diff --git a/Common/3dParty/hunspell/test/src/kk_KZ.txt b/Common/3dParty/hunspell/test/src/kk_KZ.txt new file mode 100644 index 00000000000..69010faa9b5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/kk_KZ.txt @@ -0,0 +1,209 @@ +сөз +адам +қала +тау +ауа +су +аспан +жер +бала +ата +ана +тамақ +кітап +ұстаз +оқу +тұтыну +тыныш +тұз +ауру +денсаулық +топ +маусым +төс +көз +жүрек +сарғыш +көп +аз +ертең +түн +түс +жас +қара +ақ +көк +қызыл +шай +салт +ыстық +суық +қазақ +жеті +он +жүз +мың +бір +екі +үш +төрт +бес +алты +жеті +сегіз +тоғыз +он +бақша +бұлақ +қиыр +досым +ақша +патша +таң +кеш +тауар +күн +апат +риза +ауырсыну +орман +жаңбыр +бауыр +жел +тұман +үй +бұлақ +көше +айнала +шайыр +тағам +сусын +топ +бас +әрекет +тіл +кеме +сиыр +қой +ешкі +шөп +ит +тұқым +қарындаш +апа +ана +әке +дала +тарлау +дәуір +таңдай +жыл +басқарушылар +басқарушшылар +жауапкер +ерекшеліктерімендерге +тұмылдырықтатқыздан +білімділігінге +білімдарды +алалықсыздар +айырмашылықтарын +тұрақтандырып +сылтауратқандарыңызды +қолдар +байланысқадан +жетілдірілген +зарарсыздандырады +ескеріп +ескеріпп +міндеттемелеріндерге +кезеңдердің +себепсіздік +біреудейлер +беделілерің +кездестіріңіз +шектердің +көңіл +көңл +мол +алайда +мәселе +мәселеу +сендің +келер +келерр +кәне +көпір +күндіз +сана +белгілер +дайын +ез +қайшы +саф +рең +шақ +үміткер +бақыт +бақытт +республика +консервациялау +мемлекеттік +тағатсыздан +адамда +бәрі +бең +беңр +жасағанда +жасағоанда +жабайылық +заманда +көшірдік +мерейі +Мерейій +мөлшерсіздікк +мөлшерсіздік +пенді +тылда +мәртебесімен +аппаратпен +тегінді +кездеме +ересектік +көңілсіздік +тәуекелсіздік +қанағатсыздық +ғаділетсіздік +сайдақы +басым +тәжікеден +тұрғын +қонақ +қауіпсіздік +қадірсіздік +білгішсінбейсіңдер +талқандас +кешікті +қоздырғышы +бас +емдейсіңдер +құқылы +тақылет +әдемі +көткеншектейсіңдер +әжет +қайтар +белсену +түсінбеймін +жағымсыздық +сыздар +мәртебесі +тұрғыны +мезгіл +әлбетте +барысын +оқылған +безге +жаса +аламаңдайсыңдар +кереметті +епетейсіздік diff --git a/Common/3dParty/hunspell/test/src/ko_KR.txt b/Common/3dParty/hunspell/test/src/ko_KR.txt new file mode 100644 index 00000000000..3ef2abd2ce5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ko_KR.txt @@ -0,0 +1,157 @@ +안녕하세요 +감사합니다 +사랑해요 +미안합니다 +음식 +친구 +가방 +집 +학교 +컴퓨터 +물 +밥 +책 +산 +바다 +날씨 +일 +노래 +치킨 +반찬 +꽃 +숙제 +가족 +아이 +게임 +영화 +생일 +시간 +동물 +여행 +차 +쇼핑 +추천 +대화 +전화 +사진 +운동 +잠 +병원 +음료수 +능력 +주말 +전자기기 +고양이 +강아지 +바나나 +가을 +겨울 +봄 +여름 +옷 +신발 +지하철 +택시 +버스 +비행기 +샴푸 +브러시 +삼계탕 +국수 +불고기 +된장 +김치 +먹다 +마시다 +보다 +듣다 +놀다 +하다 +가다 +오다 +서다 +늦다 +일어나다 +자다 +빨갛다 +파랗다 +노랗다 +녹색 +보라색 +맛있다 +시원하다 +덥다 +추운 +기분 +슬프다 +즐겁다 +정신이 +바쁘다 +참새 +나비 +병아리 +돌 +물고기 +향신료 +시장 +기차 +공원 +해변 +지갑 +병원 +대학 +교통 +공항 +천재 +연구 +일본 +중국 +사업 +지식 +성격 +자금 +기술 +정부 +전략 +협력 +혁신 +경제 +철학 +신체 +영감 +현상 +역사 +태양 +설명 +사회 +환경 +자연 +현실 +존경 +정확 +장애 +낙관 +발전 +절망 +일상 +소멸 +도전 +반복 +포기 +파괴 +혁혹 +소외 +식민지 +혐오 +출산 +행복 +불평 +판매 +위험 +안녕하ㅎ요 +감사합ㅅ다 +사랑ㄱ해요 +미안ㅎ합니다 +친ㅔ구 +가ㅎ방 + diff --git a/Common/3dParty/hunspell/test/src/lb_LU.txt b/Common/3dParty/hunspell/test/src/lb_LU.txt new file mode 100644 index 00000000000..e7dd0e3d594 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lb_LU.txt @@ -0,0 +1,118 @@ +Aarbecht +Aarbechtszäitorganisatioun +Aartgenoss +Abenteuer +abrëll +absence +Abusives +Abzebillercher +Acquéreur +Adjointeë +Affischéiertes +Airbussen +Alldeegleches +Angschtzoustä +Basketballspiller +Baufirme +bauren +bekanntes +Beleg +Berodung +Bewältegung +Datentransfer +Dateschutz +Decisives +Donneschden +Drangsaléiertes +Dränk +Giischtgen +Grondlag +grondreegel +Géies +Handelsdag +hausaufgab +hierschtdag +Häerzi +Industriell +Infrastrukturelles +Interessi +Internetfore +Intervall +Kamell +Kantoner +Karamell +Klenges +Nopeschhaus +Motors +Muer +Muerenter +Musek +Nettoverméige +niess +Protektioun +Prouf +Provisioun +Prozessor +Präis +Präsens +Sanitäres +Schauspiller +Schema +Taxatioun +Telefonsgespréich +termingrë +terrass +Textdatei +Textsprooch +Titulaire +Titel +erausféieren +erausjoe +gëeicht +onglécklecherweis +unzesammelen +unzespille +Approvisionnement + +Сложные слова +Aktiegesellschaft +Aktivitéitsdéclaratioun +Alarmstëmmung +Allgemengverständleches +Bankenoperatioun +Bensinsreserven +Besteierungsofkommes +Diskriminéierungsmoossnam +Dokumentatiounsaarbecht +Haaptrecommandatioun +Héchstgeschwindegkeet +Héichproblematesches +Hëllefsdéngscht +Integratiounsméisseges +Iwwersetzungsprogramm +Kapitaliséierungsdimensioun +Museksinstrument +Publicitéitsmarché +Transportproblem + +Слова с ошибками +Abonnnement +Accomodéiertes +Agrarcenter +Begrennung +Berodunszentren +Deeluung +Dialogue +Dictaten +Inspektor +Iwereileges +Pedagogik +Televisionschaîn +Bechäftegungsméiglechkeet +Gläicheetspolitik +Musekheichschoul +Satelliten +Addressbichelchen +Aarbechtsfield + + diff --git a/Common/3dParty/hunspell/test/src/lt_LT.txt b/Common/3dParty/hunspell/test/src/lt_LT.txt new file mode 100644 index 00000000000..1f04ae6ce1d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lt_LT.txt @@ -0,0 +1,127 @@ +Abstraktus +šachmatai +žadintoja +agurkas +Aikštė +Akinukai +akmuo +šakoti +aktualinti +aktorius +šalinis +šaltinis +bernystė +beskuo +būgnelis +Bilietas +bilingvizmas +daržavietė +Darbadienis +Darbas +darbuotoja +dargi +daržinė +daugintoja +Daugiaveiksmis +delnė +įdelnis +detalizuoti +šerdelė +erdvėti +šeriškas +šeštadienis +etiketas +Evoliucija +fabrikantė +Fantastika +Fenomenas +fikusas +gaudinėti +gausėja +gūbrinti +geležis +geležtė +gelsvis +geranoris +Gertys +gerviukas +giesmininkė +Gikas +Goža +griaustinis +grįžinys +gėrioja +griozdas +grizijo +gryčia +grožėja +grįžti +grupė +gąstauti +Jaukas +jodinėjo +jodyti +keturnagis +Kiaušina +Kiaurymė +kiausta +kietakaktis +ūkiškas +kilimėlis +kilometrinis +ūkininkaitė +ūkinis +krykti +lapuotis +laukas +laupti +laužtė +Maudulys +Maumedis +mažutėlis +mazgotuvė +mechanikė +medeinė +medikamentinis +meduolinis +Nūdien +nebrendėlė +Negu +neiginys +parudenys +pasakotojas +pasausė +pasieninis +paskyriui +paslapčiom +Pasodas +Pat +Pataikūniškas +patarška +patentinis +proskyna +protekiniais +provizoriškas +rėkčioti +rūmas +rodyklinis +Romanistas +Skylmatis +Skyriklis +skolininkas +skraidžioja +skruzdėda +skėtrus + +Слова с ошибками +Abbreviatūra +alpinismas +amortizacia +daugiamžis +deziderativinis +generazija +keturiasdešimtūkstantas +krivuluoja +Šnaukstai +pazintinis +progresa \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/lv_LV.txt b/Common/3dParty/hunspell/test/src/lv_LV.txt new file mode 100644 index 00000000000..51984047594 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/lv_LV.txt @@ -0,0 +1,205 @@ +Sveiks +Sveikks +Labrīt +Lbrīt +Paldies +Paldiess +Lūdzu +Luzu +Atvainojiet +Atvainvfojiet +Prieks +Perieks +Draugs +Dravfugs +Ģimene +Gimene +Māja +Maja +Pilsēta +Pilseta +Ceļš +Ceļšs +Kalns +Jūra +Sauls +Mēness +Zvaigznes +Diena +Nakts +Brokastis +Pusdienas +Vakariņas +Vīns +Kafija +Maize +Siers +Makaroni +Pica +Saldējums +Deserts +Sāļš +Augļi +Dārzeņi +Gaļa +Zivis +Vistas +Ola +Sāls +Pipari +Eļļa +Sviests +Cukurs +Piens +Jogurts +Salāti +Zupa +Salds +Šokolāde +Spageti +Rīsi +Kakao +Biezpiens +Kūka +Tēja +Karalis +Zelts +Ezis +Tulpe +Lācis +Kaķis +Suns +Putns +Vārna +Zaķis +Pele +Ābols +Aita +Zirgs +Lauva +Pūķis +Lasis +Vilks +Vējš +Uguns +Ūdens +Zeme +Debesis +Saule +Rūpniecība +Aizkustinošs +Izdzīvošana +Nepieciešamība +Atbildība +Lieliski +Apmierināts +Neparasts +Izglītība +Sarežģīts +Atsevišķs +Pamatots +Organizācija +Sadarbība +Efektīvs +Daudzveidīgs +Novērtēt +Pārsteidzošs +Inovatīvs +Vērtība +Aizraujošs +Nopietns +Komunikācija +Māksla +Dzīvība +Ekskluzīvs +Tehnoloģijas +Rezultāts +Atbalsts +Nodrošinātība +Pārbaudīt +Radošs +Sociāls +Izteiksmīgs +Brīvība +Pieredze +Ietekme +Pārmaiņas +Drosmīgs +Racionāls +Empātija +Izpratne +Risinājums +Iespējas +Atklāts +Vadošais +Eksperimentāls +Neatkarība +Tīrība +Samierināšanās +Motivācija +Harmonija +Dinamisks +Iedvesma +Izglītojošs +Komplicēts +Pieejamība +Sadarbība +Tūlītējs +Saprotams +Neizsakāms +Lieliskums +Inovācijas +Aizrautība +Pārdomas +Sapratne +Rezultatīvs +Iespējams +Pārbaude +Sociālais +Izteiksme +Brīvība +Pieredzējis +Ietekmīgs +Pārmaiņu +Racionāla +Izpratni +Risinājumi +Iespējams +Atklāta +Vadošā +Eksperimentāla +Neatkarība +Tīra +Motivējošs +Harmonisks +Dinamika +Iedvesmojošs +Spēks +Mīlestība +Pasaule +Daba +Skaistums +Miers +Sapnis +Prieks +Rītausma +Brīnums +Izcils +Saikne +Dzirksts +Pārmaiņas +Atbalsts +Izcilība +Satriecošs +Dzīvīgums +Pārveidošana +Uzdrīkstēšanās +Uzticamība +Ieguldījums +Vērtība +Līdzsvars +Saskaņa +Izsmalcinātība +Pateicība +Atzinība +Pārsteigums diff --git a/Common/3dParty/hunspell/test/src/mn_MN.txt b/Common/3dParty/hunspell/test/src/mn_MN.txt new file mode 100644 index 00000000000..ac86b087ab0 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/mn_MN.txt @@ -0,0 +1,103 @@ +Баатар +Багаа +Базар +Барра +Бат-Очир +Баттуул +Батхэсэн +Баярмаа +Билгэх +Бор +Бөөнцагаан +Бүрэнхайрхан +Бямбагар +Бэх +Гарам +Гантиг +Гурвантэс +Гүр +Гэрэлтуяа +Давст +Дангаа +Дансран +Дарь-Эх +Дөргөн +Дундбүрд +Дэмүүл +Дэлгэрцэцэг +Жавзан +Жарантай +Заглул +Зүүнхөвөө +Кир +Корона +Лүн +Лха +Лхаваан +Майхан +Манлай +Мөндөөхөө +Мөнхөт +Мөрөн +Мөнххаан +Мөст +Мэгэд +Мухар +Найдалмаа +Найтингейл +Налайх +Нарантуул +Намтай +Насантогтох +Номин +Нямсамбуу +Нэүдэй +Орог +Очир +Өнөржаргал +Өөдөс +Өргөн +Паган +Пас +Пүрэвдорж +Пүрэвхүү +Сайнаа +Сайхандулаан +Сундуй +Сэлх +Сүүж +Сээр +Тайван +Тарав +Тогтуун +Төрболд +Төхөм +Төмөр +Түргэн +Түшиг +Түгтөмөр +Түшиг +Удвал +Улиастай +Улаандэл +гүедэцгээчих +дэвхэрлүүлсхийчих +дэвхэлцгээчих +дэвшигдүүлгэчих +дэвшилцчих +дэвээ +дэггүйчүүд +наламгардуулалц +налбаруулзна + +Слова с ошибками +Батарчулуун +Баруунхарааа +Даважаргал +Дөрволжин +Мягмараран +Оюунтулхуур +оторчилсхилгэ +Асрамжлулгацгаачих +гүентүүлгэцгэээ +наладаадуулга \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nb_NO.txt b/Common/3dParty/hunspell/test/src/nb_NO.txt new file mode 100644 index 00000000000..7218490a618 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nb_NO.txt @@ -0,0 +1,113 @@ +Bahamasøyene +Festarrangement +Festarrangemang +Festival +festligheta +festnummer +forhandlernett +forgylle +fotballstyre +Fotgå +fotoamatørene +Fotogalleri +fotokopiere +generalkostnadene +generaltabbe +generøs +Generell +genmodifisertst +handlingsresymeet +hardhet +Harmfull +hastighetsregulering +havbanke +havforskningsundersøkelsene +informasjonsutveksling +Infrarødest +kaffeautomat +kaldslig +kalenderåra +kjekk +kjendisstoffa +kjærlighetslyrikk +kjøkken +Kontantautomat +kontantlån +kontrahere +kontraheringsplikt +Låskasse +læregutt +læreprosess +Museums +museumssamling +musikkorps +myggstikka +myndighetsaldere +omløpstider +omregn +områdeplan +omriss +omsetningsgjeld +omsjaltning +omsetningsvolumer +omslutning +omslyngning +omsonst +omstendeligheta +Omstart +Omstreifende +Omsyn +omtåketheta +oppdagelse +oppbygning +oppebære +oppfølgingsapparat +oppgjørsbank +oppgjørsblankett +opphøringene +partisipere +randverdi +rapportskriver +rasjonalisering +Rate +selsak +selskapsinntekt +selskapsoverskudd +selvbetjeningene +snabbingene +Snadderene +Sytti +søkekriterium +søkemulighetene +søkeargumenter +søkingen +søkne +sølvlaga +sørlandsk +søtningene +tabellrad +Tabellkolonne +Takhalm +taksene +takseringssystema +tal +trolsk +trosinnholdene +utfoldelsesmuligheta +Utformingsmetode +Utgift +vekstfaktor +vekstforhold + +Слова с ошибками +Arbeidstagerorganisasion +festsprel +forhandlingsdirektor +handlingforløpa +kjempeflinktt +lanetilbud +omraming +omsvøpssfull +raportmateriale +serstilt +taksamst \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nl_NL.txt b/Common/3dParty/hunspell/test/src/nl_NL.txt new file mode 100644 index 00000000000..3efaf4df406 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nl_NL.txt @@ -0,0 +1,115 @@ +Advertentie +Advocate +affirmatie +afgevaardigd +afneemster +allerbekendst +alternatieveling +annulering +anticycloon +Backtrackroute +Bearbeiden +becijfer +bediening +bedrag +beduiden +beïnvloeding +benadeling +bepaaldelijk +Catalogiseer +Catering +cellulair +classificator +collaboreren +collectiviteit +comfortabel +complimenteus +contractant +correctionaliseren +daaraanvolgend +dagelijks +deelgenoot +degelijkheid +demarqueren +Denotative +deposant +dergelijken +detail +deugen +diakritisch +Directioneel +dusgenaamd +eendrachtigheid +Eenzaamheid +eersteklascoupé +Eigenschap +felicitatietelegram +centerkanaal +Chargeer +filiaal +klare +Klassikaal +kleinhandel +evolutie +exemplaar +exequiën +familiaal +fauteuil +luister +magistratelijk +perelaar +Permitteren +Perseveratie +persoonlijk +pictogram +pixel +sloten +sluimer +sneltoets +Soldij +Solliciteren +zegepraal +zelfbeeld +zevendaags +aangeslotene +meermaals +expedieert +jaargetijden +kaderleden +Kapitelen + +Сложные слова +avontuurlijkheid +bedrijfsmaatschappelijk +begrotingstechnisch +belangstellingssfeer +concurrentievoordeel +conferentieganger +democratisch-liberaal +discontoverhoging +doctoraatsverhandeling +dubbeldeksbus +economisch-financieel +energiezuinig +erkentelijkheid +evenwichtigheid +klimaatsverandering +koffiezetmachine +koopmansgebruik +maatschapsovereenkomst +personeelsconsulent +sociaalwetenschappelijk +zelfverzekerdheid +fondsenwervende + +Слова с ошибками +afficher +algorithme +beeindiging +client +consnteren +deactivieren +deblockering +electrisch +certificat +sovereiniteit \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/nn_NO.txt b/Common/3dParty/hunspell/test/src/nn_NO.txt new file mode 100644 index 00000000000..6c0c1b48bc9 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/nn_NO.txt @@ -0,0 +1,116 @@ +Ankeret +Anleggsbedrift +Annandag +annonseavis +annuell +ansats +ansvarsmedviten +Antibiotikai +apal +apoteki +apparattavlor +appetitt +Aprikos +arbeidsdokument +arbeidsmarknad +barndom +bastematte +bautingi +Bedriftsleiar +befolkningi +begynnarkurs +Beheld +belastningi +beredskapsnivå +beredskapsperiode +berglandskapi +berrfrost +beskjedi +beskrivingi +betalingsoppdrag +betalingsplikt +bevismateriale +bildeband +bildebruki +bildespråki +bildeteksti +bilingval +billettlukone +binær +bione +bjørkegreini +bjørnebæri +blenge +blokkeringi +blomsterbordi +blyerts +bogen +bokstavrekningi +bokstavteikni +Borddisk +effektevaluering +elgkalv +Elone +emballer +faktainformasjon +familiebedrifti +familieterapeut +fastbuande +Februar +feili +fisketom +hengelåsi +istandsetjingi +Item +jaguar +jamlig +janen +jarnbanestasjon +kjende +kjentfolki +kjæleri +kjøledisk +kjørety +midli +Mideftnar +midtstrek +multiplikasjonstabell +museumsdirektør +onsdag +operasjon +operasjonskode +opinionsskapingi +opningi +Personalkonsulent +Personligdom +persontryggleik +petroleumspris +redningsaksjon +reduksjon +refusnik +seinst +sekretær +seljande +sendeferd +Standpunkt +støyisolering +støytvis +terminoppgåve +tidløysone +tidsfølgjone +Tilbakebetalingstid +uprofesjonell +upåklageleg + +Слова с ошибками +Anlegsarbeid +anonse +ansversproblematikk +barneforteling +besoksliste +bilophoggingi +effektivitetskontrol +fakturaerklering +miljøbyrad +selskapskat +cement \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/oc_FR.txt b/Common/3dParty/hunspell/test/src/oc_FR.txt new file mode 100644 index 00000000000..23c82dafd0d --- /dev/null +++ b/Common/3dParty/hunspell/test/src/oc_FR.txt @@ -0,0 +1,108 @@ +Ajustaira +alaguiar +alausièr +alberguèri +alcaloïdic +alègrament +alenament +algorisme +Alimentacion +allergologia +alpèstra +amaisament +amorteirar +analista +analogic +atucament +Audicion +auquièr +auscultacion +auscultar +ausèri +autenticament +brilhant +brumós +Burgada +cabelièira +cadeçar +Caducèu +çaicontra +calcièrs +Calmar +camarilha +cambièra +canalhariá +casse +cedar +cendrós +cèrca +cèrtes +cestòdes +chantièr +chartrós +Chassís +dimensionar +diptèrs +dirèctament +discrecionària +discriminar +Distraire +dòler +Enòrme +enqueriái +espicifòrme +esquelèt +Esquèrra +estetic +innocéncia +innocentàs +Maniquèu +mantelejar +Nauchièr +natièr +oxigèn +pacanariá +pagés +pagesiá +Primièirament +requereguèri +requisitòria +saumelèri +S'autodeterminar +sautarèl +scientament +scientologia +secador +secretèri +sècta +sectorial +s'efarcimar +s'endeven +s'engarrar +sentimental +s'entrepausar +shampó +sextant +sòli +Solidament +soquèla +subrejornada +suedés +utilitària +Utilizaire +vacàs +vaisselèri +valiái +validament + +Слова с ошибками +albatros +amistanza +brunonièr +carpentier +centrifugation +estelhad +primaria +s'embractar +sosembrançament +vascularisacion \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pl_PL.txt b/Common/3dParty/hunspell/test/src/pl_PL.txt new file mode 100644 index 00000000000..81c4afafce5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pl_PL.txt @@ -0,0 +1,225 @@ +dom +pies +kot +auto +drzewo +książka +szkoła +przyjaciel +mama +tata +dziecko +jabłko +czekolada +kawa +herbata +telefon +telewizor +komputer +muzyka +sport +zdrowie +piękno +praca +miłość +szczęście +czas +pieniądze +język +kraj +miasto +zima +lato +jesień +wiosna +morze +góry +jezioro +rzeka +park +zwierzę +ptak +ryba +drewno +złoto +srebro +metal +szkło +buty +sukienka +spodnie +koszula +czapka +płaszcz +ręka +noga +oko +ucho +nos +usta +ząb +głowa +serce +mózg +król +królowa +książę +księżniczka +chłopak +dziewczyna +mężczyzna +kobieta +staruszek +staruszka +lekarz +pielęgniarka +nauczyciel +uczennica +student +studentka +kucharz +kelner +wojna +pokój +mapa +flaga +śmiech +płacz +sen +marzenie +praca +nauka +sztuka +teatr +kino +muzeum +kaplica +kościół +zamek +most +droga + +Сложные слова на польском языке + +1. konstantynopolitańczykowianeczka +2. niezadogłębienieńskujący +3. antykontraatakujący +4. supersamoobsługiwalnymi +5. rozpierduchlanoculka +6. nieodezwawiałobyś +7. przystawieniowy +8. nieprzeżyciowakościami +9. nieprzekazywających +10. przeciwzakwaszeniowych +11. nieszczęściodrapańskiego +12. społeczno-wychowawczyniami +13. seledynowo-fioletowymi +14. przeciwdeszczową +15. mikroelektroniczno-kwalitacyjną +16. nieokreślonościowo-losowo-obiektywnie +17. zagubieniecioburakowatej +18. antyneuroleptyzanckim +19. nieupubliczniającymi +20. splądrowałbyś +21. konserwowano-spożywczymi +22. ożelośćiowo-miłosnej +23. nieprzyzwoitolicjią +24. nieodporowościę +25. rzeszołkofiołkowatymi +26. niezakapiactwuja +27. nieoszczędniewczelnianków +28. przekształconowaczkołępów +29. rozwińczywianiu +30. nieprzeskakiwalnościami +31. modernizująco-rewolucyjnego +32. nadzwyczajnieuzdolnionymi +33. przemocno-wsparciański +34. przepyszno-peltzerowskiego +35. kwestionowano-wzmocnieniami +36. nieodczynieństwującą +37. niezasłużonowypasionego +38. likwidującego/zarządzającego +39. szeszcześtoplutowanych +40. niewpadkowościowi +41. antynazizhownemu +42. nieuchronnieprzekroczeniowym +43. niezatrawialnieprzyjemnego +44. kardiopulmonologiczno-angiologów +45. gorączkowointensywnościowego +46. antykonstytucyjnorozpadowego +47. nieobawiamysię/źródleni +48. prerewolucyjnolphillipsowi +49. szóstkaniewygranych +50. nieupadkokogeneracyjnymi +51. społeczno-humanitarnarządzaniami +52. nieodziewowiędzy +53. przemocnochamować +54. społecznosensacyjnosądowym +55. przerażającorzymskiego +56. nieprzemontowanych/zamuzowych +57. referendumkonstytucyjno-reformujące +58. niezniesłowiałszymi +59. niebohaterystycznymi +60. produktodenarodowomenopauzalem +61. odrywającopierdolca +62. niegotowożywione +63. niepostronnynarodzonemu +64. przedniaautochtonicznym +65. nadciągniono-wchodzących +66. promocjostworczym +67. niezapowiadającychkoalicji +68. bezgłupinczłapie +69. wyomjaził +70. wagotonizacyjno-radiofonizowanego +71. gospodarczo-zasadotwórczej +72. skrupulatno-rzeźniczobardziej +73. samokiedy-konstytucyjnej +74. niedomętnością +75. nieoszustamiwykorzystana +76. przeprowadzonoświeckie +77. nieuniknionaobowiązkowo-plastycznej +78. poduszkowo-nicościowych +79. niepowodzeńbutmizeryjewego +80. skojarzeniowocolorowymi +81. przytułkamiwciągarkowych +82. wchodziłoprzeciwniepowszechny +83. karaublicznociągana +84. przedpolitycznilubelskim +85. niezapowiedziano-date-expanded +86. licznościłodziennej +87. niezawinieniomatołek +88. pakujączwobilardowego +89. rewersdopisek +90. przeprosinoworadosną +91. nieakceptacyjnoprospekcyjnymi +92. jedniżużytym +93. ainikopciksemilitechnikowany +94. motszynopiszącym +95. nieprzerejestrowanasezonowanie +96. słupotartackimoblikiem +97. nieodbieraniemniedostępności +98. dorozwinięcówkobiet +99. szybopojabytesłowickiego +100. przystępnoracjmujacych + +Слова с ошибками + +jedniiżużytym + +wiomjaził + +niezzniesłoowiałszymi + +superrsammoobsługiwalnymi + +przemoocnochamować + +staruszzka + +tiatr + +woina + +teleffon + +zołoto \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pt_BR.txt b/Common/3dParty/hunspell/test/src/pt_BR.txt new file mode 100644 index 00000000000..6f39dbef644 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pt_BR.txt @@ -0,0 +1,108 @@ +que +eu +não +de +você +para +ele +se +é +um +sim +por +isso +em +uma +uuma +está +como +com +bem +na +me +mas +do +era +quando +então +tudo +tydo +aqui +disse +estava +esâtava +lá +fazer +vai +sobre +vamos +homem +hollmem +bom +ok +agora +coisa +coissa +quero +foi +meu +seu +só +eles +as +posso +pocso +estou +mais +mim +certo +dizer +dizdizerr +os +no +sei +ela +vocês +sua +todos +sabe +minha +alguma +algyyma +casa +muito +oh +quallquer +qualquer +da +estamos +até +onde +onede +ao +tenho +nós +tem +tinha +tiinha +quê +ir +ou +pode +quer +vou +seus +dia +estão +nos +cabeça +quem +anos +depois +sou +vez +vá +fez +irmão +câmera +câmeara \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/pt_PT.txt b/Common/3dParty/hunspell/test/src/pt_PT.txt new file mode 100644 index 00000000000..ed038092d09 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/pt_PT.txt @@ -0,0 +1,135 @@ +pan +manteiga +menteiga +queijo +salchichón +saуlchichón +óleo +pimenta +pimmenta +sal +baga +mel +geléia +cogumelo +cebola +cóbola +banana +cenoura +pêra +beterraba +frutas +melão +melancia +bolo +chocolate +carne +batatas +salada +salóda +tomate +pepino +pipino +col +mingau +sopa +sanduíche +refrigerante +refrigarante +água +café +chá +leite +suco +scuco +maçã +uvas +laranja +abacaxi +adacaxi +damasco +demasco +açucar +arroz +macarrão +res +porco +frango +costeleta +cãsteleta +limão +ervilha +pão +peixe +caramelo +sorvete +nogueira +ovo +pêssego +xícara +xíícara +vidro +prato +colher +garfo +faca +pires +garrafa +guardanapo +café da manhã +almoço +jantar +avião +carro +bonde +ônibus +trem +bicicleta +janeiro +fevereiro +fevíreiro +março +abril +maio +junho +julho +agosto +setembro +setembra +outubro +novembro +dezembro +desembro +caneta +livro +xadrez +telefone +relógio +pente +televisão +ferro +sabão +rádio +bolsa +cartão +mala +presente +câmera +computador +camputador +filme +flor +vaso +quadro +lenço +bola +balão +brinquedo +brinqueedo +conta +sobre +papel +pepel +jornal +letra +bilhete \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/ro_RO.txt b/Common/3dParty/hunspell/test/src/ro_RO.txt new file mode 100644 index 00000000000..2cd141c9418 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ro_RO.txt @@ -0,0 +1,210 @@ +casă +copil +carte +masă +școală +lumină +apă +munte +soare +lună +pâine +fruct +floare +stradă +mașină +aer +timp +zi +noapte +nor +vânt +ochi +gură +nas +mână +picior +inimă +sânge +cap +ureche +voce +melodie +culoare +formă +linie +cerc +dreptunghi +cercetare +știință +limbă +frază +literă +cifră +număr +sunet +zgomot +telefon +internet +computer +program +ecran +tastatură +mouse +joc +sport +muzică +artă +film +televizor +radio +planetă +stea +univers +galaxie +atom +moleculă +substanță +energie +lumină +căldură +frig +aparat +instrument +mașinărie +unelte +hrană +băutură +haine +pantofi +păr +piele +ochelari +ceas +bijuterie +pământ +apă +aer +foc +metal +lemn +piatră +hârtie +cerneală +pix +carte +cadru +tablou +sculptură +model +formă +anticonstituționalitate +dezvoltare +inexpugnabil +nefast +concomitent +antiseptic +recalcitrant +perseverență +extravagant +inexorabil +colosal +plauzibil +efervescent +perspicacitate +superfluu +subversiv +incoruptibil +inefabil +hiperbolic +indefectibil +peremptoriu +ambivalent +paradoxal +heterogen +indiferent +periferic +subliminal +ultraviolet +indeferent +conglomerație +circumstanțial +contraproducător +conglomerat +insurmontabil +intransigent +insidios +inerent +consternant +ambiguitate +inerție +inconsolabil +oniric +remarcabil +repudiat +subiectiv +periculos +infatigabil +abnegare +exuberant +facet +represiune +implacabil +indiferent +infatigabil +insolit +intempestiv +incandescent +letargic +magistral +magnanim +nefast +oblivial +oportun +periculos +plutitor +propice +reprobabil +risipitor +robust +salutar +simetric +solicitant +stringent +sufocant +superficial +tranzitoriu +tributar +trivial +umilitor +unic +vehement +vernal +vicios +victorios +vindicativ +virtuos +vizibil +volatil +vorace +vulnerabil +xenofob +xerofil +yonder +yang +yodel +zonal +zodiac +zoon +zoomorf +zurbagiu +Caaă +Soaare +Cartr +Appă +Coopil +Frumoss +Feriсire +Prietenn +Muziică +Exeplu diff --git a/Common/3dParty/hunspell/test/src/ru_RU.txt b/Common/3dParty/hunspell/test/src/ru_RU.txt new file mode 100644 index 00000000000..28d99377fcf --- /dev/null +++ b/Common/3dParty/hunspell/test/src/ru_RU.txt @@ -0,0 +1,197 @@ +должен +доллжен +наш +думаю +думмаю +свою +сам +всем +ни +нас +пока +этом +этой +ваша +всеми +возьми +моей +сама +вся +день +само +всей +бывает +себе +пойду +куда +ими +твоей +всю +своего +твой +пусть +ним +про +точно +иметь +которые +тогда +сюда +наше +самой +взять +наверное +домой +совсем +те +тобой +наверно +что-то +будто +твои +пути +дома +такие +тех +такое +его +самой +вашей +наверное +мои +например +типа +значит +люблю +минут +пор +случае +искусство +лучше +того +такому +ждать +видеть +мною +ждал +имя +важно +чего-то +самому +обычно +представляет +мечтать +стало +помните +взять +моих +самим +своим +вообще +самими +здесь +обратно +сразу +таким +ежели +наоборот +куда +таков +мечтает +значит +покажи +такими +кстати +почти +всякий +научит +вдоль +тогдашний +толком +занимает +Аквапланирование +Барокамера +Библиографирование +Биосинтез +Взаимодействующий +Вибраторный +Виртуальность +Вооруженность +Господствующий +Десантно-штурмовой +Диагностировать +Дипломатический +Дисгармония +Дискриминационный +Достопримечательный +Жизнеустройство +Интернациональный +Инфицированный +Кальцинировать +Ключичный +Коннотация +Лиловатый +Люминесцентный +Метрополитен +Многоплановый +Модернизировать +Наивысший +Наименее +Неопределенный +Нераскрытый +Неоднократный +Неохотно +Непостижимый +Неусыпный +Обезьяноподобный +Обзавестись +Оптический +Оптимизировать +Осуществиться +Очистительный +Парафинировать +Переключатель +Пограничный +Подготовительный +Подрядчик +Полиморфный +Почитать +Преисполниться +Преподаватель +Преследователь +Прирожденный +Проектирование +Профанация +Разграничительный +Распоряжающийся +Реконструктивный +Революционный +Рентгенологический +Рискованный +Роскошествовать +Самоунижение +Сверхъестественный +Светочувствительный +Семантика +Сингулярность +Совершенствовать +Соединительный +Сосуществование +Спорообразующий +Стационарный +Столовая +Сторицей +Сцепной +Трансформирующий +Триумвират +Укротитель +Универсальный +Федеративный +Хронометраж +Целостность +Криумвират +Укратитель +Универссальный +Фидиративный +Хранометраж +Целосность diff --git a/Common/3dParty/hunspell/test/src/sk_SK.txt b/Common/3dParty/hunspell/test/src/sk_SK.txt new file mode 100644 index 00000000000..1bc44a6dda5 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sk_SK.txt @@ -0,0 +1,205 @@ +hiša +pes +mačka +avto +drevo +knjiga +šola +prijatelj +mama +oče +otrok +jabolko +čokolada +kava +čaj +telefon +televizija +računalnik +glasba +šport +zdravje +lepota +delo +ljubezen +sreča +čas +denar +jezik +država +mesto +zima +poletje +jesen +pomlad +morje +gore +jezero +reka +park +žival +ptica +riba +les +zlato +srebro +kovina +steklo +čevlji +obleka +hlače +srajca +kapa +plašč +roka +noga +oko +uho +nos +ustnice +zob +glava +srce +možgani +kralj +kraljica +princ +princesa +fant +dekle +moški +ženska +starec +starka +zdravnik +medicinska sestra +učitelj +učenka +študent +študentka +kuhar +natakar +vojna +mir +zemljevid +zastava +smeh +jok +spanje +sanje +delo +učenje +umetnost +gledališče +kino +muzej +kapela +cerkev +grad +most +cesta + +Сложные слова + +1. Neparlamentarna +2. Samozadosten +3. Nepristranski +4. Pretirano +5. Nepredušno +6. Nesreča +7. Razpršeno +8. Nesprejemljiv +9. Prekomeren +10. Prostovoljstvo +11. Izolirati +12. Trmast +13. Brezpogojno +14. Neodvisnost +15. Skupnost +16. Neizvedljiv +17. Nelegitimen +18. Nevzdržen +19. Preobremenjenost +20. Ogrevalni sistem +21. Preoblikovati +22. Nezaslišano +23. Neugoden +24. Prezasedenost +25. Nesreča +26. Neupravičeno +27. Mednaroden +28. Kompatibilnost +29. Neuspeh +30. Neobvladljiv +31. Neskončen +32. Neprimeren +33. Amortizacija +34. Koncentracija +35. Cirkulacija +36. Obremenitev +37. Gromozanski +38. Simbol +39. Vinjeta +40. Digitalizacija +41. Funkcionalnost +42. Rentabilnost +43. Ekshibicionizem +44. Frustracija +45. Neprilagodljiv +46. Severnoameriški +47. Ekskluzivnost +48. Preverjanje +49. Celoživljenjsko +50. Privlačnost +51. Periferija +52. Sokrivda +53. Kompromis +54. Strpnost +55. Racionalizacija +56. Birokracija +57. Odraslost +58. Stabilnost +59. Nepredvidljivost +60. Razkošje +61. Smrtnost +62. Obveščenost +63. Produktivnost +64. Neugodje +65. Zapletenost +66. Hegemonija +67. Umetnost +68. Tranzicija +69. Individualnost +70. Kontaminacija +71. Inkubacija +72. Prikrito +73. Etnični +74. Sovražnost +75. Atraktivnost +76. Nestrpnost +77. Divergenca +78. Digitalna pismenost +79. Stabilizacija +80. Raznolikost + +Слова с ошибками + + Kontamenacija + + Grommozanski + + Neobvladlliv + + Neparlametarna + + Nevrzdržen + + voina + + muzei + + ryba + + serebro + + televiziia \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sl_SI.txt b/Common/3dParty/hunspell/test/src/sl_SI.txt new file mode 100644 index 00000000000..3a2674932d2 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sl_SI.txt @@ -0,0 +1,210 @@ +Hiša +Sonce +Miza +Stol +Ptica +Trava +Drevo +Noč +Luna +Morje +Gora +Cvet +Riba +Rdeča +Modra +Zelena +Rumena +Bela +Črna +Kamen +Pes +Mačka +Roka +Noga +Glava +Oči +Uho +Nos +Usta +Jabolko +Hruška +Sliva +Jagoda +Malina +Lubenica +Kruh +Mleko +Sir +Mesnica +Sadje +Zelenjava +Voda +Zrak +Ogenj +Sneg +Dež +Oblak +Veter +Zima +Poletje +Jesen +Pomlad +Zajec +Lisica +Volk +Medved +Lev +Tigrica +Slon +Konj +Krava +Ovca +Piščanec +Jajce +Mleko +Kava +Čaj +Sok +Vino +Pivo +Hrana +Pecivo +Testo +Marmelada +Kruh +Sir +Olje +Sol +Poper +Sladkor +Kava +Čaj +Vino +Pivo +Šola +Učitelj +Učenec +Knjiga +Pisarna +Računalnik +Telefon +Glasba +Slika +Film +Gledališče +Mesto +Vas +Trg +Cesta +Reka +Avtomatizacija +Razvoj +Komunikacija +Kompjuter +Programiranje +Elektronski +Inženiring +Elektrifikacija +Kombinacija +Sistem +Informacija +Univerza +Biblioteka +Univerzitetni +Laboratorij +Raziskava +Razvojna +Inovacija +Intelektualni +Integriteta +Izobraževanje +Izvajanje +Preverjanje +Tehnologija +Implementacija +Program +Sodelovanje +Proizvodnja +Industrija +Organizacija +Administracija +Proaktivnost +Kreativnost +Projektni +Razumevanje +Kvaliteta +Upravljanje +Ocenjevanje +Statistika +Kompetentnost +Konsolidacija +Realizacija +Kapaciteta +Distribucija +Kompatibilnost +Konceptualizacija +Povezava +Posodobitev +Fleksibilnost +Ekonomija +Organiziranje +Konkurenca +Stabilnost +Ekologija +Osebnost +Zavzetost +Entuziazem +Motivacija +Avtorizacija +Kreacija +Akumulacija +Monotonija +Diferenciacija +Transformacija +Koncentracija +Inovativnost +Aktivnost +Vzpostavljanje +Reorganizacija +Kategorizacija +Partikularnost +Homogenost +Izjemenost +Generalizacija +Hierarhija +Koordinacija +Inspiracija +Evaluacija +Ustvarjalnost +Oblikovanje +Kompatibilnost +Konkretizacija +Proaktivnost +Identifikacija +Kapaciteta +Intervencija +Konsolidacija +Realizacija +Eksplozivnost +Abstrakcija +Individualnost +Integracija +Segmentacija +Asimilacija +Artikulacija +Kolaboracija +Asociacija +Stabilizacija +Kooperacija +Transformacija +Hšza +Kmojnikacija +Progrramiranjee +Elektornkski +Inženeirrng +Izzobraževanjee +Infomracija +Razvoojnaa +Proizvdonja +Akitvnostt \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt b/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt new file mode 100644 index 00000000000..9002894db69 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sr_Cyrl_RS.txt @@ -0,0 +1,227 @@ +кућа +пас +мачка +аутомобил +дрво +књига +школа +пријатељ +мама +тата +дете +јабука +чоколада +кафа +чај +телефон +телевизија +рачунар +музика +спорт +здравље +лепота +посао +љубав +срећа +време +новац +језик +земља +град +зима +лето +јесен +пролеће +море +планине +језеро +река +парк +животиња +птица +риба +дрво +злато +сребро +метал +стакло +ципеле +одећа +панталоне +кошуља +капа +капут +рука +нога +око +уво +нос +усне +зуб +глава +срце +мозак +краљ +краљица +принц +принцеза +дечак +девојчица +мушкарац +жена +старац +старица +доктор +медицинска сестра +наставник +ученик +студент +студенткиња +кувар +конобар +рат +мир +мапа +застава +смех +плач +сан +сањарење +посао +учење +уметност +позориште +биоскоп +музеј +црква +дворац +мост +улица +пут + +Сложные слова + +Конечно! Вот сто сложных слов на сербском языке на кириллице: + +1. Контраст +2. Компликација +3. Конструкција +4. Диспропорција +5. Корелација +6. Колаборација +7. Консервативан +8. Диференцијација +9. Експерименталан +10. Инвалидитет +11. Легитиман +12. Оптимизација +13. Компетентан +14. Документација +15. Персистентан +16. Апроксимација +17. Екстраваганција +18. Катастрафалан +19. Резервација +20. Прогресиван +21. Идентификација +22. Генерација +23. Криминалистички +24. Дестабилизација +25. Корумпиран +26. Конфронтација +27. Експлозиван +28. Функционалан +29. Релевантан +30. Квалификација +31. Акредитација +32. Петиција +33. Каустичан +34. Периодичан +35. Контроверзан +36. Гигантски +37. Принципијалан +38. Управоливост +39. Имунизација +40. Магнетичан +41. Оперативан +42. Десант +43. Хиерархија +44. Феминистички +45. Сегментација +46. Колоритан +47. Деградација +48. Диверзификација +49. Казуистички +50. Реципрочан +51. Манипулативан +52. Екстензиван +53. Колективни +54. Каузалитет +55. Синхронизација +56. Кампања +57. Товарни +58. Хируршки +59. Шампионат +60. Геостационаран +61. Опустошан +62. Клема +63. Стационарни +64. Секуларни +65. Исегментација +66. Дебелина +67. Прецизан +68. Рафиниран +69. Психолошки +70. Турбулентан +71. Интегритет +72. Идеолошки +73. Манифестација +74. Имплицитан +75. Хомогеност +76. Изолација +77. Хетерогеност +78. Спекулативан +79. Вагу +80. Математички +81. Гематолошки +82. Психијатријски +83. Блокада +84. Заплена +85. Монопол +86. Дисидент +87. Екстрадиција +88. Ревизија +89. Ваидан +90. Колонизација +91. Мотивација +92. Просек +93. Ресурс +94. Хуманизам +95. Дравски +96. Коалиција +97. Картеля +98. Резолуција +99. Менталитет +100. Епидемиологија + +С ошибками + + Колонизакаија + + Епидемиогија + + Казуистикаки + + Хуманкзам + + Манитулативан + + сањваење + + утење + + автомобил + + мекицинска сестра + + стукло \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt b/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt new file mode 100644 index 00000000000..48cd99d072a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sr_Latn_RS.txt @@ -0,0 +1,173 @@ +ananas +anarhistički +antidepresiv +Anđeo +avion +banana +banka +belina +bespomoćnost +bibliotekar +bibliaoteikar +brod +citat +crkva +cvet +cveće +demokratija +demackratija +demokratizacija +Dobrota +dom +Dragi +ekran +eksperimentalni +eksplozija +epidemiologija +farmakologija +filantropija +flaša +frizura +fudbal +garaža +generalitet +geografski +globalizam +gnezdo +grad +građanstvo +grlo +hamburger +Harmonija +himalaji +hiperbola +hipotermija +hleb +Hrabrost +hrana +Hvala +igra +igračka +individualnost +infrastruktura +internet +inmternet +jabuka +jahač +jastuk +jednakost +jubilej +jurisprudencija +kafa +krevet +kriminalisticki +kriminalistika +kuća +kvantitativni +lampa +latiaratura +Lepota +lingvistika +literatura +ljubav +Ljubavi +ljubavnica +Ljubazan +Ljubim +lubenica +majica +majka +mašina +mikroorganizama +mikroskopija +Milost +Mir +Mirno +nacionalizam +nedopustiv +neurologija +novčanik +noć +nož +oktobar +okultizam +optimističan +optimističnost +ormar +Osoba +oči +pas +peškir +planina +poniženje +Porodica +Prijatelj +psihologija +psihoterapija +Radost +računar +reka +rekonvalescencija +reumatologija +revolucija +sendvič +Slatko +Sloboda +Slobodan +Snaga +socijalizacija +socijalizam +Spreman +Sreća +Srećan +Srećno +sunce +superiornost +Svetlost +tata +tehnologija +telefon +telekomunikacije +top +tradicionalni +ulica +univerzalnost +univerzitet +univirzdalnost +Usmena +Znanje +usta +Vedar +vegetarijanstvo +velikodušnost +voda +voz +Zabava +zavisnost +Zdravlje +zemlja +Zima +zjmlja +zločinački +zoološki +Zvezda +ćilim +čarapa +čarobnjak +časopis +čizme +đak +đevrek +đumbir +šešir +šišmiš +škola +šljiva +šuma +žaba +ženskara +žirafa +život +životinjski +žurka + diff --git a/Common/3dParty/hunspell/test/src/sv_SE.txt b/Common/3dParty/hunspell/test/src/sv_SE.txt new file mode 100644 index 00000000000..99b61d15766 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/sv_SE.txt @@ -0,0 +1,210 @@ +Hus +Sol +Mjölk +Vatten +Fisk +Stol +Grön +Blomma +Träd +Katt +Hund +Bok +Cykel +Kaffe +Frukt +Kött +Fönster +Dörr +Säng +Lampa +Bord +Hår +Ögon +Hand +Fötter +Näsa +Mun +Öra +Huvud +Arm +Ben +Kläder +Hatt +Skor +Väska +Papper +Penna +Skrivbord +Telefon +Radio +Musik +Film +Teater +Konst +Sport +Spel +Resa +Bil +Tåg +Buss +Flygplan +Båt +Stad +Land +Hav +Sjö +Flod +Berg +Dal +Park +Skog +Sjukhus +Apotek +Skola +Universitet +Affär +Restaurang +Café +Hotell +Turist +Vän +Familj +Mamma +Pappa +Bror +Syster +Barn +Morfar +Mormor +Vänster +Höger +Framåt +Bakåt +Upp +Ner +Snäll +Osnäll +Glad +Ledsen +Trött +Stark +Svag +Tyst +Bullrig +Ren +Smutsig +Vacker +Ful +Liten +Stor +Komplexitet +Oproportionerlig +Ovillkorlig +Efterklokhet +Komplicerad +Desorientering +Konstellation +Otillgänglighet +Irreversibel +Förlåtelse +Overksamhet +Indifferent +Hierarki +Kombinatorik +Inkompatibilitet +Absorption +Konsekvens +Verklighetsfrånvänd +Retrospektiv +Förändringsbarhet +Ambivalens +Besvikenhet +Ineffektivitet +Intrikat +Dilemma +Hesitation +Absurditet +Kompromisslös +Konsolidering +Föresats +Tillfredsställelse +Delegering +Rekommendation +Detaljrikedom +Oanvändbar +Stagnation +Nostalgi +Hemlighetsfull +Avsaknad +Perseverans +Existentialism +Repetitivitet +Intolerans +Anonymitet +Obetydlig +Paradox +Förvirring +Juxtaposition +Reflektion +Självständighet +Kollision +Kreativitet +Djupgående +Abstraktion +Eufori +Autentisk +Insinuation +Omöjlig +Pessimism +Inkonsekvens +Revisionism +Sensationell +Obeveklig +Subjektivitet +Universalitet +Entropi +Omvälvande +Infiltration +Konservativ +Atypisk +Provokation +Konfrontation +Anarki +Konkurrenskraft +Defensivitet +Nihilism +Konklusion +Apori +Korrespondens +Prioritering +Exponentiell +Fragmentering +Aversion +Harmoni +Vanmakt +Signifikans +Katalysator +Förlust +Enhällighet +Ambition +Tendens +Alienation +Artificiell +Uppfyllelse +Psykosomatisk +Virtuos +Egensinnig +Anpassning +Hållbarhet +Konstitution +Kompleksitet +Oproporsjonerlig +Uvilkorlig +Etterklokhed +Komplisert +Desorientering +Konstelasjon +Utilgjengelighet +Irreversibel +Forlatelse diff --git a/Common/3dParty/hunspell/test/src/tr_TR.txt b/Common/3dParty/hunspell/test/src/tr_TR.txt new file mode 100644 index 00000000000..9ad60f3664a --- /dev/null +++ b/Common/3dParty/hunspell/test/src/tr_TR.txt @@ -0,0 +1,205 @@ +Akşam +Almak +Altın +Anahtar +Anlamak +Araba +Atmak +Ayakkabı +Açmak +Ağaç +Bahçe +Bakır +Bakkal +Bakmak +Balık +Beyaz +Bilgisayar +Bilmek +Binmek +Bulmak +Ceket +Cevaplamak +Deniz +Dinlemek +Doktor +Duyurulmamış +Düzenleştirme +Düşmek +Düşünmek +Ekmek +Elbise +Eldiven +Elma +Erkek +Etek +Etmek +Ev +Eşarp +Gelgit +Geliştiricilikle +Geliştirilebilir +Geliştirme +Gerçekleştirme +Gezmek +Geçmek +Gitar +Gitmek +Giymek +Gri +Gömlek +Görülebilirlik +Görünümlü +Görünüşlü +Gözlük +Gümüş +Günaydın +Hareketlendi +Hareketlilik +Hava +Hayalperest +Hüzün +Kahve +Kahverengi +Kalabalıklar +Kalem +Kalkmak +Kalmak +Kapatmak +Kararlılık +Kararlılıkla +Kararsızlık +Kararsızlıkla +Karpuz +Kedi +Kemer +Kemdkcer +Kırmızı +Kitap +Kız +Kızgınmak +Koklamak +Koalye +Kolye +Konservatuvar +Konuşmak +Korkmak +Koymak +Koşmak +Kravat +Kullanılabilir +Kullanılmış +Kullanılmışlık +Kullanışlılık +Kurumsallaşma +Köpek +Küpe +Kütüphane +Mavi +Mazbut +Melankoli +Merdiven +Merhaba +Merhabalar +Meurhaba +Meydan +Meyhane +Meyve +Mor +Muhafazakar +Muhteşem +Mukadderatlarınızdanmışçasına +Muvaffak +Muzaffer +Muzafferiyet +Muzip +Mükemmeldik +Münasebet +Münzevi +Müsrif +Mütevazi +Müteessir +Mütercim +Mütereddit +Mütevazı +Müzmin +Okul +Okumak +Otobüs +Otoriterlik +Oynamak +Pantolon +Pasta +Pembe +Pembei +Plaj +Platin +Saat +Sandalye +Sarı +Satmak +Sevinmek +Sevmek +Sıcak +Sıradaymışız +Siyah +Sormak +Soymak +Soğuk +Su +Sükûnet +Sürrealist +Süt +Tabak +Tadına bakmak +Tatlı +Tavuk +Telefoncu +Televizyon +Temizlemek +Teşekkürler +Türkuaz +Tuirkuazu +Turuncu +Tutmak +Ulaştırılabilir +Uygulanabilir +Uyumak +Uçak +Yapmak +Yatak +Yazmak +Yemek +Yeşil +Yıkanmak +Yıldız +Yol +Yöneltilmezken +Yüzme +Yüzük +Zenginleştirmek +Çalışamamıştı +Çalışmak +Çalışmamıştır +Çanta +Çay +Çıkarmak +Çiçek +Çorap +Özelleştirilmiş +Özelleştirme +Özgürleştirme +Üzülmek +İnmek +İsteksizlik +İsteksizlikle +İstikrarlı +İstikrarlılık +İstisnai +İslamiyetle +İzlemek +İçmek +İşbirliği +İşitmek +Şapka +Şemsiye diff --git a/Common/3dParty/hunspell/test/src/uk_UA.txt b/Common/3dParty/hunspell/test/src/uk_UA.txt new file mode 100644 index 00000000000..b139dedfbd8 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uk_UA.txt @@ -0,0 +1,210 @@ +абдукція +абіогенез +амбівалентнасть +амбівалентність +анахранізм +анахронізм +антропогенез +антропологія +антропоморфізм +апатія +археологія +архетип +аскетизм +астрономія +афект +бачити +бігти +білий +біллий +біологія +бувай +будинок +будь ласка +бути +важко +велиикий +великий +веселка +взяти +вибачте +відчувати +вода +волюнтаризм +втаємниченість +вчитися +гарний +гарячий +гегемонія +географія +герменевтика +герменевтика +гештальт +говорити +гойдалка +готувати +грати +дати +дедукція +деконструктивізм +деконструкція +демаркація +детермінізм +дзвіночок +дивитися +дисгарммонія +дисгармонія +дисфункція +дисфункця +дихотомія +до побачення +добрий +доктрина +думати +дурний +дурня +дякую +евфемізм +езотерика +ей +екзистенціалізм +екзистенціалізм +екзистенцілізм +екзистенція +економіка +емерджентність +ентелехія +епістемологія +ефемерність +ефемерність +занепадництво +звісно +здоровий +зелений +йти +ілюзорність +ілюзорність +імплікація +інвектива +індукція +інтроспекціїя +їсти +історія +каблучка +кава +казус +калюжа +катарсис +каченя +каштани +квітка +кішка +класно +книга +когнітивістика +комаха +консенсус +космогенез +купувати +легко +лінгвістика +літати +маленький +марнослів'я +математика +мати +метаморфоза +метелик +метелиця +містифікація +місто +могти +можливо +мусити +насправді +не радий +незворушність +ні +нігілізм +новий +нонсенс +ностальгія +павучок +парадокс +пес +писати +пити +піти +плавати +плакати +повільний +поганий +політологія +постмодернізм +потворний +працювати +привіт +прийти +психоаналіз +птах +радий +ремінісценція +рефлексія +робити +розбурхання +розумний +сильний +сингулярність +синестезія +синій +синішй +синкретизм +сказати +скатертина +слабкий +слухати +сміятися +сніг +соліпсизм +соломинка +сонечко +сонце +соціологія +спати +співати +справді +старий +структуралізм +сумний +так +так +танцювати +телефонувати +тож +трансцендентність +фантастично +фаталізм +фемінізм +феномен +феноменологія +фізика +філософія +фрактал +хворий +хімія +хліб +хліб +ходити +холодний +хотіти +чао +червонй +червоний +черевики +читати +чорнй +чорний +чути +швидкий +щасливий +яблуко diff --git a/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt b/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt new file mode 100644 index 00000000000..b92bea172f4 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uz_Cyrl_UZ.txt @@ -0,0 +1,262 @@ +Mарт +Ёз +Ём +Ёхуд +Август +Адвакат +Адреси +айтган-лирангиз +айқин +амалга +анча +Апрел +арзонроқ +аҳамият +аҳднома +бажарилади +бажарилди +баланд +ихтисослан +банкрот +баҳона +Баҳор +бераман +берасизми +беринг +бериш +бешинчи +биз +Бизга +Бизнинг +билан +Бирор +Бозорнинг +бор +бошқа +Бу +Бугун +будингиз +бунга +бундай +Бухгалтерлик +бўлади +бўладими +бўлиши +бўлмаган +бўлса +бўш +бўшайди +бўшатасиз +вазифасига +вазият +вариант +вақт +газетадаги +газетадан +даромад +Декабрь +Душанба +Эрталаб +Етказиб +Жисмоний +Жуда +Жума +зарур +зиёфат +Ижара +ижарага +икки +Илтимос +Индинга +информатизациялари +Иситгич +иши +ишлатсак +Ишхона +Июль +Июнь +Йўқ +йил +йилдан +кам +Шинамгина +кампанияси +келдим +келишимдан +келмоқчи +келсам +келтириш +керак +керакдир +керакми +кета-ди +кеч +Кеча +кечага +Кечаси +Кечир +Кечирдинг +кирла +кирадими +кондиционер +коррупциядир +кран +Куз +Кун +куни +кўрмоқчи +кўчиб +лойиҳа +Май +маълумоти +маълумотларни +Маъмурият +маъруза +Мен +музлатгич +мумкин +муфмкин +мутахассис +мушовир +муҳим +нарса +нархи +Нархини +нақд +ўшанақасини +неча +Номардлик +Ноябри +интернетдаги +ойнаси +ойнинг +Октябри +олдин +олдиндан +олмаймиз +олмоқчи +орқали +шоти +шорти +Оқшом +пайдо +Панжшанба +пулини +Раҳмат +резюме +реклама +Салом +Сармоядор +Сентябрь +Сешанба +Сиз +сизга +сизда +Сизнинг +синган +сифатида +совуқ +софвуқ +Солиқларни +Статистик +сўм +тажрибали +тайёргарлик +тайёрладик +тайёрладингизми +таклиф +талафот +талафоти +таъминловчилардан +танишинг +таржимон +тарржимон +тахминан +ташкил +Телефонни +технология +Безантирани +тозалан +тозалигига +Тонгда +топширишимиз +топшириқ +турли +турмоқчи +тутсак +Тушлик +ўладиганингиз +тўлай +тўлаймиз +тилдиришинг +тўлиқ +уйингиз +уйни +уч +учун +ўқидим +фақат +Феврал +хабар +Хайрли кун +Мотамхонаси +хонлик +Чек +Чоршанба +Шанба +шарт-номани +шартини +шартлар +шартлари +шартни +шартнома +шахс +шовқин +Шом +Шу +эди +Эртага +Эртадан сўнг +Эшитишимга +эълон +эълонингиз +эълонингизни +эътироф +Юклаш +Якшанба +Январи +Ярим кеча +яхши +қабул +қаерда +Қанақа +қаноатманда +қанча +қачон +қизиқарлидир +қиламиз +қилганим +қилдим +қилинг +қилинди +қилишди +қиммат +қиммати +Қимматидан +қирқ +Қиш +қувонарлими +қўнғироқ +Қўшимча +ҳайвонини +ҳам +ҳамза +Ҳар +ҳафтага +ҳақиқатан +ҳисоблаб +Ҳозир +ҳужжатни +Ўтган кун + + diff --git a/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt b/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt new file mode 100644 index 00000000000..ee6a1d93567 --- /dev/null +++ b/Common/3dParty/hunspell/test/src/uz_Latn_UZ.txt @@ -0,0 +1,200 @@ +Salom +Sallom +Rahmat +Rhmat +Iltimos +Iltimo +Kattalar +Kattalarvf +Yaxshi +Yashi +Kelajak +Keljajak +Oilaviy +Oilaaviy +Qarindosh +Qarinndosh +Shahar +Shaha +Dengiz +Dengizzz +Quyosh +Quyyosh +Yulduz +Oyim +Kechqurun +Tushun +Suvchi +Sharob +Choyxona +Nonushta +Tushlik +Muzqaymoq +Desert +Tuzluq +Mevalar +Sabzavot +Baliq +Tuxumli +Sabza +Sariq +Salatlar +Shirinlik +Shokolad +Rishta +Kakao +Pishloq +Tort +Qaymoq +Sutli +Qatiq +Salomatlik +Temir +Zahar +Oqimli +Shamol +Olov +Yer +Osmon +Shanba +Dushanba +Seshanba +Chorshanba +Payshanba +Juma +Yakshanba +Oltin +Tong +Bomdod +Asr +Shom +Kun +Oqsoqol +Shoshqaloq +Kulgili +Muxlislilar +Tavsiflash +Tuzilishga +Mustaqillik +Tushuntirish +Boshqarish +Mashhurlik +Tarkibiy +Tahlil +Ishchi +Xalqaro +Tarjima +Mustahkamlik +Chaqaloq +Istiqbol +Tasvir +Taklif +Tasavvur +Jiddiy +Majburiyat +Asosiy +Tahdid +Tushunmovchilik +Ishonch +Maqomi +Ijodkor +Tadbirkor +Hayotiy +Mashhur +Bemorlik +Tadbir +Jismoniy +Madaniyat +Xavfsizlik +Sifatli +Suvli +Sotuvchi +Chetel +Tashqi +Sotuv +Tarbiyalanish +Murabbo +Sariqcha +Qovun +Shaharlik +Muhimlik +Tarbiyachilik +Xatolik +Balandlik +Yuzaki +Kuyov +Qiziquvchan +Orzular +Mashq +Qalampir +Muammo +Sadoqatli +Yovuzlik +Fikr-mulohaza +Boylik +Tushuncha +Zanjir +Eslatma +Tabassum +Ishonuvchi +Chidamlilik +Ilova +Birodarlik +Oqilona +Ijodiyot +Tayanch +Hurmat +Baxtli +Tajriba +Samimiylik +Shifokor +Ishrat +Baho +Namoyish +Qiyinchilik +Bolalar +Ishonchli +Taqdir +Shovqinli +Xalqaro +Baxt +Fursat +Hurmatli +Qulaylik +Zamonaviy +Sadoqat +Sabr +Nikoh +Jasorat +Barkamollik +Dunyoqarash +Omadli +Foydali +Yorqin +Mehribonlik +Fazilatli +Kutubxona +Istiqomatli +Fido +Bahor +Shafqatsizlik +Tafakkur +Fazilat +Qochish +Laziz +Uzoq +Ilhom +Omad +Hurmatli +Tandir +Sherzod +Bahoriy +Dilshod +Baxtli +Shonli +Nurli +Shafqatsizlik +Oqqush +Boylik +Toza +Sabrli diff --git a/Common/3dParty/hunspell/test/src/vi_VN.txt b/Common/3dParty/hunspell/test/src/vi_VN.txt new file mode 100644 index 00000000000..2982e9eb45c --- /dev/null +++ b/Common/3dParty/hunspell/test/src/vi_VN.txt @@ -0,0 +1,128 @@ +Bánh +Bang +bênh +bướng +bậy +Chanh +chum +chuyện +chép +Chùng +chắp +chệnh +chới +chữ +công +cạc +cột +cứu +Doanh +duyên +dùng +dể +dọng +gia +giày +giêng +Giảng +giềng +hon +Hoẳn +Hài +hôm +hước +hấu +hớt +hữu +Khiển +Khoào +khuya +khuyến +khách +khén +khẩn +khắp +khựng +kẻo +lang +liền +Loàng +Luỗng +lình +lương +lấp +lệnh +lịnh +lốn +lời +lựng +Muộn +Mãnh +mại +mạn +mổ +mởn +nghiễm +nghều +Ngoáy +Nguyên +ngóp +người +ngỏ +ngớp +ngụa +ngửng +nhiếp +nhu +nhà +nhân +Nhóm +nhưỡng +nhắm +nhổn +nhứt +ninh +noi +nãy +nạn +nốt +ong +pao +phiên +phiêu +Phên +Phương tiện +phẩm chất +phố đi bộ +quan trọng +quyền lợi +quán cà phê +quảng cáo +Quốc +Quốc tế +riêng biệt +rưỡi +Rải +Rẻng +rộng rãi +siễn +sum +Sõng +Sưu +sưu tập +sử dụng +Thiệt thòi +Thuộc về +thuộc tính + +Слова с ошибками +thiệte +quốq tế +nguên +khoao +chenh +chhùng +man +doah +khien +ngoay \ No newline at end of file diff --git a/Common/3dParty/hunspell/test/test.pro b/Common/3dParty/hunspell/test/test.pro new file mode 100644 index 00000000000..2dee3f69709 --- /dev/null +++ b/Common/3dParty/hunspell/test/test.pro @@ -0,0 +1,29 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-07-21T18:28:42 +# +#------------------------------------------------- + +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle + +DEFINES += KERNEL_USE_DYNAMIC_LIBRARY + +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(UnicodeConverter kernel hunspell) + +core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32 +core_linux:LIBS += -lz + +SOURCES += main.cpp + +DESTDIR = $$PWD/build 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/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/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/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/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index bfaba2dbdcc..8fce91db664 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -236,6 +236,15 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt char *pFirst = strstr((char *)pBuffer, "%PDF-"); + 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 "); @@ -299,7 +308,7 @@ 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 @@ -317,27 +326,33 @@ bool COfficeFileFormatChecker::isOleObjectFile(POLE::Storage *storage) 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 @@ -841,7 +856,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; @@ -849,9 +864,7 @@ 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; if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) @@ -900,12 +913,12 @@ 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"; - const char *vsdxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"; - const char *vssxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml"; - const char *vstxFormatLine = "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml"; - const char *vsdmFormatLine = "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml"; - const char *vssmFormatLine = "application/vnd.ms-powerpoint.slideshow.macroEnabled.main+xml"; - const char *vstmFormatLine = "application/vnd.ms-powerpoint.template.macroEnabled.main+xml"; + 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 strContentTypes((char*)pBuffer, nBufferSize); @@ -1084,6 +1097,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"; @@ -1110,31 +1124,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; } @@ -1671,7 +1692,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/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index 243abd1d896..2221abef9a7 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -71,6 +71,7 @@ #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_SPREADSHEET 0x0100 #define AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX AVS_OFFICESTUDIO_FILE_SPREADSHEET + 0x0001 @@ -126,6 +127,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 diff --git a/Common/base.pri b/Common/base.pri index 59a3bb0e2ae..6cf2958beb3 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}" @@ -299,6 +304,12 @@ core_ios { CONFIG(iphonesimulator, iphoneos|iphonesimulator): { message("iphonesimulator") CORE_BUILDS_PLATFORM_PREFIX = ios_simulator + + QMAKE_CFLAGS += -fembed-bitcode + QMAKE_CXXFLAGS += -fembed-bitcode + QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CFLAGS += -fobjc-arc + QMAKE_CXXFLAGS += -fobjc-arc } else { QMAKE_IOS_DEPLOYMENT_TARGET = 11.0 @@ -306,6 +317,7 @@ core_ios { QMAKE_CFLAGS += -fembed-bitcode QMAKE_CXXFLAGS += -fembed-bitcode QMAKE_LFLAGS += -fembed-bitcode + QMAKE_CFLAGS += -fobjc-arc QMAKE_CXXFLAGS += -fobjc-arc bundle_xcframeworks { @@ -366,6 +378,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 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 66442dbb01f..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; @@ -586,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 87db1ec14cd..8303dc21653 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 @@ -1690,38 +1698,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..b8ce97b3f8a 100644 --- a/DesktopEditor/common/File.h +++ b/DesktopEditor/common/File.h @@ -194,7 +194,18 @@ namespace NSFile 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/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/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/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index 0d20fb73b03..0f564810409 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -357,6 +357,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); diff --git a/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp b/DesktopEditor/doctrenderer/docbuilder.net/src/docbuilder.net.cpp index 436a3e3eb3c..f5022fbde76 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 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..978b306176c --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -0,0 +1,596 @@ +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_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_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] + _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, 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 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))) + + 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): + return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal))) + + @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..24bb38523fc --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.cpp @@ -0,0 +1,395 @@ +#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_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_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) +{ + return new CDocBuilderContext(self->GetContext()); +} + +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..64b94140b3d --- /dev/null +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder_functions.h @@ -0,0 +1,134 @@ +#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_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_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); + +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 a3e4192a941..ea742b5ac9b 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -1440,7 +1440,11 @@ 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); diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index f4cb3affb09..c0b3a5190a5 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -110,6 +110,8 @@ namespace NSDoctRenderer 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; } } @@ -619,7 +621,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) 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/js_internal/jsc/jsc_base.mm b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm index 3bde66eefd1..d0fefa6b6ba 100644 --- a/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm +++ b/DesktopEditor/doctrenderer/js_internal/jsc/jsc_base.mm @@ -219,6 +219,13 @@ bool IsOldVersion() { 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()) diff --git a/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h b/DesktopEditor/doctrenderer/js_internal/v8/v8_base.h index 01c6d1bc37d..a6b5e332c37 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; @@ -483,7 +497,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(); @@ -514,7 +528,7 @@ namespace NSJSBase LOGGER_LAP_NAME(name) - JSSmart<CJSValue> _ret = _return; + JSSmart<CJSValue> _ret = _return; return _ret; } @@ -804,10 +818,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; } diff --git a/DesktopEditor/doctrenderer/json/json.cpp b/DesktopEditor/doctrenderer/json/json.cpp index 4639bab11a8..88b4825f608 100644 --- a/DesktopEditor/doctrenderer/json/json.cpp +++ b/DesktopEditor/doctrenderer/json/json.cpp @@ -66,16 +66,13 @@ namespace NSJSON static_cast<CPrimitive*>(m_internal->m_value.get())->isDouble()); } - bool IValue::IsStringA() const + bool IValue::IsString() const { - return (m_internal->m_type == CTypedValue::vtPrimitive && - static_cast<CPrimitive*>(m_internal->m_value.get())->isStringA()); - } + if (m_internal->m_type != CTypedValue::vtPrimitive) + return false; - bool IValue::IsStringW() const - { - return (m_internal->m_type == CTypedValue::vtPrimitive && - static_cast<CPrimitive*>(m_internal->m_value.get())->isStringW()); + CPrimitive* pPrimitive = static_cast<CPrimitive*>(m_internal->m_value.get()); + return (pPrimitive->isStringA() || pPrimitive->isStringW()); } bool IValue::IsArray() const diff --git a/DesktopEditor/doctrenderer/json/json.h b/DesktopEditor/doctrenderer/json/json.h index e2de0b4e433..efd9ac6ae6f 100644 --- a/DesktopEditor/doctrenderer/json/json.h +++ b/DesktopEditor/doctrenderer/json/json.h @@ -6,6 +6,7 @@ #include <string> #include <vector> +#ifndef JSON_DECL #ifdef JSBASE_NO_USE_DYNAMIC_LIBRARY #define JSON_DECL #else @@ -16,6 +17,7 @@ #define JSON_DECL Q_DECL_IMPORT #endif #endif +#endif // uncomment to enable exceptions throwing //#define JSON_DEBUG @@ -73,11 +75,7 @@ namespace NSJSON /** * Returns true if the value is a string. */ - bool IsStringA() const; - /** - * Returns true if the value is a wstring. - */ - bool IsStringW() const; + bool IsString() const; /** * Returns true if the value is an array. */ diff --git a/DesktopEditor/doctrenderer/json/json_values.cpp b/DesktopEditor/doctrenderer/json/json_values.cpp index 8b157056220..3b745cbbb8e 100644 --- a/DesktopEditor/doctrenderer/json/json_values.cpp +++ b/DesktopEditor/doctrenderer/json/json_values.cpp @@ -1,5 +1,8 @@ #include "json_values.h" +// for string <=> wstring conversion +#include "../../common/File.h" + namespace NSJSON { IBaseValue::IBaseValue() @@ -62,7 +65,7 @@ namespace NSJSON bool CPrimitive::isDouble() const { - return m_type == ptDouble; + return m_type == ptDouble || m_type == ptInteger; } bool CPrimitive::isStringA() const @@ -113,6 +116,12 @@ namespace NSJSON { 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 @@ -123,6 +132,12 @@ namespace NSJSON { 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 diff --git a/DesktopEditor/doctrenderer/json/serialization.h b/DesktopEditor/doctrenderer/json/serialization.h index 844d6256339..07a75a38681 100644 --- a/DesktopEditor/doctrenderer/json/serialization.h +++ b/DesktopEditor/doctrenderer/json/serialization.h @@ -29,13 +29,9 @@ namespace NSJSON { ret = NSJSBase::CJSContext::createDouble((double)value); } - else if (value.IsStringA()) + else if (value.IsString()) { - ret = NSJSBase::CJSContext::createString((std::string)value); - } - else if (value.IsStringW()) - { - ret = NSJSBase::CJSContext::createString((std::wstring)value); + ret = NSJSBase::CJSContext::createString(value.ToStringA()); } // arrays else if (value.IsArray()) @@ -72,6 +68,8 @@ namespace NSJSON static CValue fromJS(JSSmart<NSJSBase::CJSValue> jsValue) { + if (!jsValue.is_init()) + return CValue::CreateUndefined(); if (jsValue->isUndefined()) return CValue::CreateUndefined(); if (jsValue->isNull()) diff --git a/DesktopEditor/doctrenderer/test/json/main.cpp b/DesktopEditor/doctrenderer/test/json/main.cpp index e527566b624..be3ada49085 100644 --- a/DesktopEditor/doctrenderer/test/json/main.cpp +++ b/DesktopEditor/doctrenderer/test/json/main.cpp @@ -180,32 +180,18 @@ class CJSONTest : public testing::Test return false; } } - else if (value.IsStringA()) - { - if (makeExpects) - 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; - } else { if (makeExpects) { - EXPECT_TRUE(value.IsStringW()); + EXPECT_TRUE(value.IsString()); EXPECT_TRUE(jsValue->isString()); } if (!jsValue->isString()) return false; - std::wstring val = value.ToStringW(); - std::wstring jsVal = jsValue->toStringW(); + std::string val = value.ToStringA(); + std::string jsVal = jsValue->toStringA(); if (makeExpects) EXPECT_EQ(val, jsVal); if (val != jsVal) @@ -261,7 +247,8 @@ TEST_F(CJSONTest, bool_) TEST_F(CJSONTest, int_) { CValue val = 42; - EXPECT_FALSE(val.IsDouble()); + EXPECT_TRUE(val.IsDouble()); + EXPECT_TRUE(val.IsInt()); JSSmart<CJSValue> jsVal = CJSContext::createInt(42); EXPECT_TRUE(compare(val, jsVal)); val = 100; @@ -564,26 +551,24 @@ TEST_F(CJSONTest, wrong_usage) EXPECT_THROW((bool)val, std::bad_cast); EXPECT_THROW((int)val, std::bad_cast); EXPECT_THROW((double)val, std::bad_cast); - EXPECT_THROW((std::wstring)val, std::bad_cast); #else EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::wstring)val, L""); #endif + EXPECT_EQ((std::wstring)val, L"test"); - val = L"тест"; + 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); - EXPECT_THROW((std::string)val, std::bad_cast); #else EXPECT_EQ((bool)val, false); EXPECT_EQ((int)val, 0); EXPECT_EQ((double)val, 0.0); - EXPECT_EQ((std::string)val, ""); #endif + EXPECT_EQ((std::string)val, "test"); val = CValue::CreateObject(); #ifdef JSON_DEBUG diff --git a/DesktopEditor/fontengine/ApplicationFonts.cpp b/DesktopEditor/fontengine/ApplicationFonts.cpp index d851460c9e0..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; + pPanose = (BYTE *)pOs2->panose; - INT bBold = (pFace->style_flags & FT_STYLE_FLAG_BOLD ? 1 : 0); - INT bItalic = (pFace->style_flags & FT_STYLE_FLAG_ITALIC) ? 1 : 0; + ulRange1 = pOs2->ulUnicodeRange1; + ulRange2 = pOs2->ulUnicodeRange2; + ulRange3 = pOs2->ulUnicodeRange3; + ulRange4 = pOs2->ulUnicodeRange4; + ulCodeRange1 = pOs2->ulCodePageRange1; + ulCodeRange2 = pOs2->ulCodePageRange2; - const char* pPostName = FT_Get_Postscript_Name(pFace); - std::string sPostscriptName = ""; - if (NULL != pPostName) - sPostscriptName = FT_Get_Postscript_Name(pFace); + usWeight = pOs2->usWeightClass; + usWidth = pOs2->usWidthClass; - INT bFixedWidth = FT_IS_FIXED_WIDTH( pFace ); + sFamilyClass = pOs2->sFamilyClass; - TT_OS2 *pOs2 = (TT_OS2 *)FT_Get_Sfnt_Table( pFace, ft_sfnt_os2 ); + usType = pOs2->fsType; - 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; - - 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()) + { + FT_Stream stream = pTTFace->name_table.stream; + FT_Memory memory = pFace->memory; + FT_Error error = 0; - if (!sEncoding.empty()) + if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || + FT_STREAM_SEEK( rec->stringOffset ) || + FT_STREAM_READ( rec->string, rec->stringLength ) ) { - FT_Stream stream = pTTFace->name_table.stream; - FT_Memory memory = pFace->memory; - FT_Error error = 0; + 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()); - 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 + if (std::wstring::npos == sNameW.find(wsFamilyName) && std::wstring::npos == wsFamilyName.find(sNameW)) { - 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); diff --git a/DesktopEditor/fontengine/ApplicationFonts.h b/DesktopEditor/fontengine/ApplicationFonts.h index ead47dac86a..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); diff --git a/DesktopEditor/fontengine/MemoryStream.h b/DesktopEditor/fontengine/MemoryStream.h index 753620c7ad0..4abebc12907 100644 --- a/DesktopEditor/fontengine/MemoryStream.h +++ b/DesktopEditor/fontengine/MemoryStream.h @@ -45,7 +45,9 @@ #include <stdlib.h> #endif +#ifndef _ARM_ALIGN_ #define _ARM_ALIGN_ +#endif static void LOGGING(const std::string& strFile, const std::wstring& strMessage) { 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/libfont.json b/DesktopEditor/fontengine/js/libfont.json index d720f09f4c4..3d4028e04b4 100644 --- a/DesktopEditor/fontengine/js/libfont.json +++ b/DesktopEditor/fontengine/js/libfont.json @@ -110,7 +110,9 @@ "_getcwd=getcwd", "NO_CONSOLE_IO", "BUILD_ZLIB_AS_SOURCES", - "IMAGE_CHECKER_DISABLE_XML" + "IMAGE_CHECKER_DISABLE_XML", + + "BUILDING_WASM_MODULE" ], "compile_files_array": [ { diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 19ba697d178..ab0abf482fc 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -624,12 +624,18 @@ namespace Aggplus 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) + double dWidth = pPen->Size; + if (!m_bIntegerGrid && m_bIs0PenWidthAs1px) { - if (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; } @@ -762,6 +768,7 @@ namespace Aggplus } } + double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant())); if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize) dWidth = dWidthMinSize; diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index d1ad0fc7265..b989524cc23 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(); diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index feb28daab37..d4493f997e2 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -113,6 +113,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; @@ -147,6 +148,10 @@ class IAdvancedCommand Annotaion = 4, DeleteAnnot = 5, WidgetsInfo = 6, + ShapeStart = 7, + ShapeEnd = 8, + PageClear = 9, + PageRotate = 10, Undefined = 255 }; @@ -164,13 +169,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: // тип рендерера----------------------------------------------------------------------------- @@ -261,6 +266,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); } @@ -295,6 +301,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) @@ -327,7 +339,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; @@ -352,29 +373,50 @@ 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) { return S_FALSE; } - virtual HRESULT AdvancedCommand(IAdvancedCommand* command) { 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) { return S_FALSE; } + virtual HRESULT put_LayerOpacity(double dValue) + { + UNUSED_VARIABLE(dValue); + return S_FALSE; + } }; #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/Matrix.cpp b/DesktopEditor/graphics/Matrix.cpp index c8e1043d8d8..ae15b65e111 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) 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 b12fc408a85..d5258ab8e05 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.cpp +++ b/DesktopEditor/graphics/MetafileToRenderer.cpp @@ -925,6 +925,10 @@ namespace NSOnlineOfficeBinToPdf case ctAnnotField: case ctAnnotFieldDelete: case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: + case ctPageClear: + case ctPageRotate: { IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Undefined; switch (eCommand) @@ -933,6 +937,10 @@ namespace NSOnlineOfficeBinToPdf 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; default: break; } @@ -1252,6 +1260,10 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: case ctAnnotField: case ctAnnotFieldDelete: + case ctWidgetsInfo: + case ctShapeStart: + case ctShapeEnd: + case ctPageRotate: default: { BYTE* cur = oReader.GetCurrentBuffer(); diff --git a/DesktopEditor/graphics/MetafileToRenderer.h b/DesktopEditor/graphics/MetafileToRenderer.h index 57f64880f9c..12e91e57e24 100644 --- a/DesktopEditor/graphics/MetafileToRenderer.h +++ b/DesktopEditor/graphics/MetafileToRenderer.h @@ -183,6 +183,8 @@ namespace NSOnlineOfficeBinToPdf ctAnnotField = 164, ctAnnotFieldDelete = 165, ctWidgetsInfo = 166, + ctShapeStart = 167, + ctShapeEnd = 168, ctPageWidth = 200, ctPageHeight = 201, @@ -190,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 d40d1029892..1b66a6b9f5d 100644 --- a/DesktopEditor/graphics/MetafileToRendererReader.cpp +++ b/DesktopEditor/graphics/MetafileToRendererReader.cpp @@ -58,6 +58,10 @@ namespace NSOnlineOfficeBinToPdf case ctFormField: return Read_Command<CFormFieldInfo> (this, pCorrector); case ctAnnotFieldDelete: return Read_Command<CAnnotFieldDelete>(this, pCorrector); case ctWidgetsInfo: return Read_Command<CWidgetsInfo> (this, pCorrector); + case ctShapeStart: return Read_Command<CShapeStart> (this, pCorrector); + case ctShapeEnd: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); + case ctPageClear: return new CEmptyComand(IAdvancedCommand::AdvancedCommandType::PageClear); + case ctPageRotate: return Read_Command<CPageRotate> (this, pCorrector); default: break; } 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/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 4cec1d4d7a8..fd8fe60ff5f 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -34,9 +34,21 @@ #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; @@ -82,12 +94,11 @@ CAnnotFieldInfo::~CAnnotFieldInfo() void CAnnotFieldInfo::SetType(int nType) { + m_nType = nType; switch (nType) { case 0: { - m_nType = 15; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -97,8 +108,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 2: { - m_nType = 13; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -108,8 +117,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 3: { - m_nType = 9; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -120,8 +127,6 @@ void CAnnotFieldInfo::SetType(int nType) case 4: case 5: { - m_nType = 11; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -132,8 +137,6 @@ void CAnnotFieldInfo::SetType(int nType) case 6: case 7: { - m_nType = 12; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -146,8 +149,6 @@ void CAnnotFieldInfo::SetType(int nType) case 10: case 11: { - m_nType = 10; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -157,8 +158,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 13: { - m_nType = 14; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -168,8 +167,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 14: { - m_nType = 8; - RELEASEOBJECT(m_pMarkupPr); m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr(); @@ -179,8 +176,6 @@ void CAnnotFieldInfo::SetType(int nType) } case 15: { - m_nType = 24; - RELEASEOBJECT(m_pPopupPr); m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr(); break; @@ -194,20 +189,14 @@ 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::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; @@ -220,207 +209,88 @@ void CAnnotFieldInfo::GetBorder(BYTE& nType, double& dWidth, std::vector<double> dWidth = m_oBorder.dWidth; 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; } +const std::wstring& CAnnotFieldInfo::GetNM() { return m_wsNM; } +const std::wstring& CAnnotFieldInfo::GetLM() { return m_wsLM; } +const std::wstring& CAnnotFieldInfo::GetContents() { return m_wsContents; } +const std::vector<double>& 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); -} - -CAnnotFieldInfo::CWidgetAnnotPr::CWidgetAnnotPr(BYTE nType) -{ - m_pButtonPr = NULL; - m_pTextPr = NULL; - m_pChoicePr = NULL; - m_pSignaturePr = NULL; - - m_nType = nType; - switch (nType) - { - case 26: - { - // Unknown widget - break; - } - case 27: - case 28: - case 29: - { - RELEASEOBJECT(m_pButtonPr); - m_pButtonPr = new CWidgetAnnotPr::CButtonWidgetPr(); - break; - } - case 30: - { - RELEASEOBJECT(m_pTextPr); - m_pTextPr = new CWidgetAnnotPr::CTextWidgetPr(); - break; - } - case 31: - case 32: - { - RELEASEOBJECT(m_pChoicePr); - m_pChoicePr = new CWidgetAnnotPr::CChoiceWidgetPr(); - break; - } - case 33: - { - RELEASEOBJECT(m_pSignaturePr); - m_pSignaturePr = new CWidgetAnnotPr::CSignatureWidgetPr(); - break; - } - } -} -CAnnotFieldInfo::CWidgetAnnotPr::~CWidgetAnnotPr() -{ - RELEASEOBJECT(m_pButtonPr); - RELEASEOBJECT(m_pTextPr); - RELEASEOBJECT(m_pChoicePr); - RELEASEOBJECT(m_pSignaturePr); - - for (int i = 0; i < m_arrAction.size(); ++i) - RELEASEOBJECT(m_arrAction[i]); + return (m_nType == 13); } -CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPdf::CBufferReader* pReader) -{ - CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pRes = new CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget(); - - pRes->nActionType = pReader->ReadByte(); - switch (pRes->nActionType) - { - case 14: // JavaScript - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 1: // GoTo - { - pRes->nInt1 = pReader->ReadInt(); - pRes->nKind = pReader->ReadByte(); - switch (pRes->nKind) - { - case 0: - case 2: - case 3: - case 6: - case 7: - { - pRes->nFlags = pReader->ReadByte(); - if (pRes->nFlags & (1 << 0)) - pRes->dD[0] = pReader->ReadDouble(); - if (pRes->nFlags & (1 << 1)) - pRes->dD[1] = pReader->ReadDouble(); - if (pRes->nFlags & (1 << 2)) - pRes->dD[2] = pReader->ReadDouble(); - break; - } - case 4: - { - pRes->dD[0] = pReader->ReadDouble(); - pRes->dD[1] = pReader->ReadDouble(); - pRes->dD[2] = pReader->ReadDouble(); - pRes->dD[3] = pReader->ReadDouble(); - break; - } - case 1: - case 5: - default: - { - break; - } - } - break; - } - case 10: // Named - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 6: // URI - { - pRes->wsStr1 = pReader->ReadString(); - break; - } - case 9: // Hide - { - pRes->nKind = pReader->ReadByte(); - int n = pReader->ReadInt(); - for (int i = 0; i < n; ++i) - pRes->arrStr.push_back(pReader->ReadString()); - break; - } - case 12: // ResetForm - { - pRes->nInt1 = pReader->ReadInt(); - int n = pReader->ReadInt(); - for (int i = 0; i < n; ++i) - pRes->arrStr.push_back(pReader->ReadString()); - break; - } - } - - if (pReader->ReadByte()) - pRes->pNext = ReadAction(pReader); - - return pRes; -} +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::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; } bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { @@ -497,9 +367,23 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta else if (IsWidget()) m_pWidgetPr->Read(pReader, nType); - return IsValid(); + 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::CFontData*>& CAnnotFieldInfo::CMarkupAnnotPr::GetRC() { return m_arrRC; } void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_nFlag = nFlags; @@ -510,7 +394,26 @@ void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader if (nFlags & (1 << 2)) m_dCA = pReader->ReadDouble(); if (nFlags & (1 << 3)) - m_wsRC = pReader->ReadString(); + { + 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)) @@ -520,6 +423,12 @@ void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader 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); @@ -530,6 +439,8 @@ void CAnnotFieldInfo::CTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* if (nFlags & (1 << 18)) m_nState = pReader->ReadByte(); } + +const std::vector< std::vector<double> >& CAnnotFieldInfo::CInkAnnotPr::GetInkList() { return m_arrInkList; } void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader) { int n = pReader->ReadInt(); @@ -543,6 +454,17 @@ void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* p 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<double>& CAnnotFieldInfo::CLineAnnotPr::GetIC() { return m_arrIC; } void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { m_dL[0] = pReader->ReadDouble(); @@ -578,6 +500,9 @@ void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* m_dCO[1] = pReader->ReadDouble(); } } + +BYTE CAnnotFieldInfo::CTextMarkupAnnotPr::GetSubtype() const { return m_nSubtype; } +const std::vector<double>& CAnnotFieldInfo::CTextMarkupAnnotPr::GetQuadPoints() { return m_arrQuadPoints; } void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) { m_nSubtype = nType; @@ -585,6 +510,10 @@ void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRe 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<double>& CAnnotFieldInfo::CSquareCircleAnnotPr::GetIC() { return m_arrIC; } void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) { m_nSubtype = nType; @@ -602,6 +531,12 @@ void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBuffer 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<double>& CAnnotFieldInfo::CPolygonLineAnnotPr::GetIC() { return m_arrIC; } +const std::vector<double>& CAnnotFieldInfo::CPolygonLineAnnotPr::GetVertices() { return m_arrVertices; } void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags) { int n = pReader->ReadInt(); @@ -623,9 +558,24 @@ void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferR 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<double>& CAnnotFieldInfo::CFreeTextAnnotPr::GetCL() { return m_arrCL; } +const std::vector<double>& CAnnotFieldInfo::CFreeTextAnnotPr::GetIC() { return m_arrIC; } +BYTE* CAnnotFieldInfo::CFreeTextAnnotPr::GetRender(LONG& nLen) +{ + nLen = m_nRenderLen; + return m_pRender; +} 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(); @@ -645,7 +595,22 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead 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()); + } + if (nFlags & (1 << 22)) + { + m_nRenderLen = pReader->ReadInt() - 4; + m_pRender = pReader->GetCurrentBuffer(); + pReader->Skip(m_nRenderLen); + } } + +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)) @@ -658,6 +623,10 @@ void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* if (nFlags & (1 << 16)) m_nSy = pReader->ReadByte(); } + +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(); @@ -665,6 +634,171 @@ void CAnnotFieldInfo::CPopupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* 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<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetTC() { return m_arrTC; } +const std::vector<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetBC() { return m_arrBC; } +const std::vector<double>& CAnnotFieldInfo::CWidgetAnnotPr::GetBG() { return m_arrBG; } +const std::vector<CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget*>& 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; + m_pTextPr = NULL; + m_pChoicePr = NULL; + m_pSignaturePr = NULL; + + m_nType = nType; + switch (nType) + { + case 26: + { + // Unknown widget + break; + } + case 27: + case 28: + case 29: + { + RELEASEOBJECT(m_pButtonPr); + m_pButtonPr = new CWidgetAnnotPr::CButtonWidgetPr(); + break; + } + case 30: + { + RELEASEOBJECT(m_pTextPr); + m_pTextPr = new CWidgetAnnotPr::CTextWidgetPr(); + break; + } + case 31: + case 32: + { + RELEASEOBJECT(m_pChoicePr); + m_pChoicePr = new CWidgetAnnotPr::CChoiceWidgetPr(); + break; + } + case 33: + { + RELEASEOBJECT(m_pSignaturePr); + m_pSignaturePr = new CWidgetAnnotPr::CSignatureWidgetPr(); + break; + } + } +} +CAnnotFieldInfo::CWidgetAnnotPr::~CWidgetAnnotPr() +{ + RELEASEOBJECT(m_pButtonPr); + RELEASEOBJECT(m_pTextPr); + RELEASEOBJECT(m_pChoicePr); + RELEASEOBJECT(m_pSignaturePr); + + for (int i = 0; i < m_arrAction.size(); ++i) + 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(); + + pRes->nActionType = pReader->ReadByte(); + switch (pRes->nActionType) + { + case 14: // JavaScript + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 1: // GoTo + { + pRes->nInt1 = pReader->ReadInt(); + pRes->nKind = pReader->ReadByte(); + switch (pRes->nKind) + { + case 0: + case 2: + case 3: + case 6: + case 7: + { + pRes->nFlags = pReader->ReadByte(); + if (pRes->nFlags & (1 << 0)) + pRes->dD[0] = pReader->ReadDouble(); + if (pRes->nFlags & (1 << 1)) + pRes->dD[1] = pReader->ReadDouble(); + if (pRes->nFlags & (1 << 2)) + pRes->dD[2] = pReader->ReadDouble(); + break; + } + case 4: + { + pRes->dD[0] = pReader->ReadDouble(); + pRes->dD[1] = pReader->ReadDouble(); + pRes->dD[2] = pReader->ReadDouble(); + pRes->dD[3] = pReader->ReadDouble(); + break; + } + case 1: + case 5: + default: + { + break; + } + } + break; + } + case 10: // Named + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 6: // URI + { + pRes->wsStr1 = pReader->ReadString(); + break; + } + case 9: // Hide + { + pRes->nKind = pReader->ReadByte(); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + pRes->arrStr.push_back(pReader->ReadString()); + break; + } + case 12: // ResetForm + { + pRes->nInt1 = pReader->ReadInt(); + int n = pReader->ReadInt(); + for (int i = 0; i < n; ++i) + pRes->arrStr.push_back(pReader->ReadString()); + break; + } + } + + if (pReader->ReadByte()) + pRes->pNext = ReadAction(pReader); + + return pRes; +} void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType) { m_wsFN = pReader->ReadString(); @@ -733,6 +867,21 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader 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) @@ -777,6 +926,11 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr::Read(NSOnlineOfficeBinToP m_wsAP_N_Yes = pReader->ReadString(); } } + +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; } void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag) { if (nFlags & (1 << 9)) @@ -788,6 +942,13 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf if (nFlags & (1 << 12)) m_wsAPV = pReader->ReadString(); } + +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<int>& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetI() { return m_arrI; } +const std::vector<std::wstring>& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetArrV() { return m_arrV; } +const std::vector< std::pair<std::wstring, std::wstring> >& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetOpt() { return m_arrOpt; } void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags) { if (nFlags & (1 << 9)) @@ -821,6 +982,8 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToP } 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(); @@ -833,6 +996,9 @@ CWidgetsInfo::~CWidgetsInfo() for (int i = 0; i < m_arrParents.size(); ++i) RELEASEOBJECT(m_arrParents[i]); } +const std::vector<int>& CWidgetsInfo::GetCO() { return m_arrCO; } +const std::vector<std::wstring>& CWidgetsInfo::GetButtonImg() { return m_arrButtonImg; } +const std::vector<CWidgetsInfo::CParent*>& CWidgetsInfo::GetParents() { return m_arrParents; } bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector) { int n = pReader->ReadInt(); diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 2d403218925..2f1e86fe943 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -36,41 +36,29 @@ #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: - 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; } - int GetI() const { return m_nI; } - int GetRI() const { return m_nRI; } - int GetIX() const { return m_nIX; } - void GetA(double& dA1, double& dA2) const { dA1 = m_dA1; dA2 = m_dA2; } - const std::wstring& GetV() const { return m_wsV; } - 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); @@ -91,13 +79,13 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsAP_N_Yes; }; - class CTextWidgetPr + class GRAPHICS_DECL CTextWidgetPr { public: - int GetMaxLen() const { return m_nMaxLen; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetRV() const { return m_wsRV; } - const std::wstring& GetAPV() const { return m_wsAPV; } + int GetMaxLen() const; + const std::wstring& GetV(); + const std::wstring& GetRV(); + const std::wstring& GetAPV(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag); @@ -108,15 +96,15 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsAPV; }; - class CChoiceWidgetPr + class GRAPHICS_DECL CChoiceWidgetPr { public: - int GetTI() const { return m_nTI; } - const std::wstring& GetV() const { return m_wsV; } - const std::wstring& GetAPV() const { return m_wsAPV; } - const std::vector<int>& GetI() const { return m_arrI; } - const std::vector<std::wstring>& GetArrV() const { return m_arrV; } - const std::vector< std::pair<std::wstring, std::wstring> >& GetOpt() const { return m_arrOpt; } + int GetTI() const; + const std::wstring& GetV(); + const std::wstring& GetAPV(); + const std::vector<int>& GetI(); + const std::vector<std::wstring>& GetArrV(); + const std::vector< std::pair<std::wstring, std::wstring> >& GetOpt(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -129,57 +117,56 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector< std::pair<std::wstring, std::wstring> > m_arrOpt; }; - 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<std::wstring> arrStr; CActionWidget* pNext; }; - public: CWidgetAnnotPr(BYTE nType); ~CWidgetAnnotPr(); - 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; } - int GetFontStyle() const { return m_nFontStyle; } - double GetFontSize() const { return m_dFS; } - double GetFontSizeAP() const { return m_dFSAP; } - 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::wstring& GetFontName() const { return m_wsFN; } - const std::wstring& GetFontKey() const { return m_wsFK; } - const std::vector<double>& GetTC() const { return m_arrTC; } - const std::vector<double>& GetBC() const { return m_arrBC; } - const std::vector<double>& GetBG() const { return m_arrBG; } - const std::vector<CActionWidget*> GetActions() const { return m_arrAction; } - - 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<double>& GetTC(); + const std::vector<double>& GetBC(); + const std::vector<double>& GetBG(); + const std::vector<CActionWidget*>& GetActions(); + + CButtonWidgetPr* GetButtonWidgetPr(); + CTextWidgetPr* GetTextWidgetPr(); + CChoiceWidgetPr* GetChoiceWidgetPr(); + CSignatureWidgetPr* GetSignatureWidgetPr(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); @@ -211,18 +198,32 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand CSignatureWidgetPr* m_pSignaturePr; }; - class CMarkupAnnotPr + class GRAPHICS_DECL CMarkupAnnotPr { public: - 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<CFontData*>& GetRC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -236,17 +237,18 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::wstring m_wsRC; std::wstring m_wsCD; std::wstring m_wsSubj; + std::vector<CFontData*> m_arrRC; }; - class CTextAnnotPr + class GRAPHICS_DECL CTextAnnotPr { public: - CTextAnnotPr() : m_bOpen(false), m_nName(2), m_nState(7), m_nStateModel(2) {} + CTextAnnotPr(); - bool IsOpen() const { return m_bOpen; } - BYTE GetName() const { return m_nName; } - BYTE GetState() const { return m_nState; } - BYTE GetStateModel() const { return m_nStateModel; } + bool IsOpen() const; + BYTE GetName() const; + BYTE GetState() const; + BYTE GetStateModel() const; void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -257,10 +259,10 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nStateModel; }; - class CInkAnnotPr + class GRAPHICS_DECL CInkAnnotPr { public: - const std::vector< std::vector<double> >& GetInkList() const { return m_arrInkList; } + const std::vector< std::vector<double> >& GetInkList(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); @@ -268,19 +270,19 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector< std::vector<double> > m_arrInkList; }; - class CLineAnnotPr + class GRAPHICS_DECL CLineAnnotPr { public: - 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<double>& 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<double>& GetIC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -291,17 +293,17 @@ 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<double> m_arrIC; }; - class CTextMarkupAnnotPr + class GRAPHICS_DECL CTextMarkupAnnotPr { public: - BYTE GetSubtype() const { return m_nSubtype; } - const std::vector<double>& GetQuadPoints() const { return m_arrQuadPoints; } + BYTE GetSubtype() const; + const std::vector<double>& GetQuadPoints(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType); @@ -310,46 +312,46 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand std::vector<double> m_arrQuadPoints; }; - class CSquareCircleAnnotPr + class GRAPHICS_DECL CSquareCircleAnnotPr { public: - 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<double>& GetIC() const { return m_arrIC; } + BYTE GetSubtype() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); + const std::vector<double>& GetIC(); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags); private: BYTE m_nSubtype; - double m_dRD[4]; + double m_dRD[4]{}; std::vector<double> m_arrIC; }; - class CPolygonLineAnnotPr + class GRAPHICS_DECL CPolygonLineAnnotPr { public: - 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<double>& GetIC() const { return m_arrIC; } - const std::vector<double>& GetVertices() const { return m_arrVertices; } + BYTE GetIT() const; + BYTE GetSubtype() const; + void GetLE(BYTE& nLE1, BYTE& nLE2); + const std::vector<double>& GetIC(); + const std::vector<double>& 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<double> m_arrIC; std::vector<double> m_arrVertices; }; - class CPopupAnnotPr + class GRAPHICS_DECL CPopupAnnotPr { public: - bool IsOpen() const { return m_bOpen; } - int GetFlag() const { return m_nFlag; } - int GetParentID() const { return m_nParentID; } + bool IsOpen() const; + int GetFlag() const; + int GetParentID() const; void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader); @@ -359,15 +361,18 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand int m_nParentID; }; - class CFreeTextAnnotPr + class GRAPHICS_DECL CFreeTextAnnotPr { public: - 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<double>& 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<double>& GetCL(); + const std::vector<double>& GetIC(); + BYTE* GetRender(LONG& nLen); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -375,16 +380,20 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand BYTE m_nQ; BYTE m_nIT; BYTE m_nLE; + int m_nRotate; std::wstring m_wsDS; double m_dRD[4]{}; std::vector<double> m_arrCL; + std::vector<double> m_arrIC; + LONG m_nRenderLen; + BYTE* m_pRender; }; - class CCaretAnnotPr + class GRAPHICS_DECL CCaretAnnotPr { public: - 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]; } + BYTE GetSy() const; + void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4); void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags); @@ -393,32 +402,22 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand double m_dRD[4]{}; }; -private: - struct CBorder - { - BYTE nType; - double dWidth; - std::vector<double> arrDash; - }; - -public: CAnnotFieldInfo(); virtual ~CAnnotFieldInfo(); void SetType(int nType); - bool IsValid() const; - - void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2) const; - void GetBorder(BYTE& nType, double& dWidth, std::vector<double>& arrDash); - 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<double>& GetC() const { return m_arrC; } + + void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2); + void GetBorder(BYTE& nType, double& dWidth, std::vector<double>& arrDash); + int GetFlag() const; + int GetID() const; + int GetAnnotFlag() const; + int GetPage() const; + void GetBE(BYTE& nS, double& dI); + const std::wstring& GetNM(); + const std::wstring& GetLM(); + const std::wstring& GetContents(); + const std::vector<double>& GetC(); bool IsWidget() const; bool IsButtonWidget() const; @@ -436,21 +435,28 @@ class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand 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; } + CMarkupAnnotPr* GetMarkupAnnotPr(); + CTextAnnotPr* GetTextAnnotPr(); + CInkAnnotPr* GetInkAnnotPr(); + CLineAnnotPr* GetLineAnnotPr(); + CTextMarkupAnnotPr* GetTextMarkupAnnotPr(); + CSquareCircleAnnotPr* GetSquareCircleAnnotPr(); + CPolygonLineAnnotPr* GetPolygonLineAnnotPr(); + CPopupAnnotPr* GetPopupAnnotPr(); + CFreeTextAnnotPr* GetFreeTextAnnotPr(); + CCaretAnnotPr* GetCaretAnnotPr(); + CWidgetAnnotPr* GetWidgetAnnotPr(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); private: + struct CBorder + { + BYTE nType; + double dWidth; + std::vector<double> arrDash; + }; + int m_nType; double m_dX1; double m_dY1; @@ -484,9 +490,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); @@ -512,9 +518,9 @@ class GRAPHICS_DECL CWidgetsInfo : public IAdvancedCommand CWidgetsInfo(); virtual ~CWidgetsInfo(); - const std::vector<int>& GetCO() const { return m_arrCO; } - const std::vector<std::wstring>& GetButtonImg() const { return m_arrButtonImg; } - const std::vector<CParent*>& GetParents() const { return m_arrParents; } + const std::vector<int>& GetCO(); + const std::vector<std::wstring>& GetButtonImg(); + const std::vector<CParent*>& GetParents(); bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector); diff --git a/DesktopEditor/graphics/commands/DocInfo.cpp b/DesktopEditor/graphics/commands/DocInfo.cpp index 723f50c37b1..f098bf6b01d 100644 --- a/DesktopEditor/graphics/commands/DocInfo.cpp +++ b/DesktopEditor/graphics/commands/DocInfo.cpp @@ -128,3 +128,39 @@ 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; +} + diff --git a/DesktopEditor/graphics/commands/DocInfo.h b/DesktopEditor/graphics/commands/DocInfo.h index a9df8a230fc..c691a86ecb4 100644 --- a/DesktopEditor/graphics/commands/DocInfo.h +++ b/DesktopEditor/graphics/commands/DocInfo.h @@ -132,4 +132,43 @@ 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; +}; + + #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 1a06368fac0..d41a82ee79c 100644 --- a/DesktopEditor/graphics/pro/Fonts.h +++ b/DesktopEditor/graphics/pro/Fonts.h @@ -766,6 +766,7 @@ namespace NSFonts virtual std::vector<NSFonts::CFontInfo*>* 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 diff --git a/DesktopEditor/graphics/pro/Image.h b/DesktopEditor/graphics/pro/Image.h index 9bb1f8d7764..afce354eb11 100644 --- a/DesktopEditor/graphics/pro/Image.h +++ b/DesktopEditor/graphics/pro/Image.h @@ -121,6 +121,7 @@ namespace MetaFile IMetaFile(NSFonts::IApplicationFonts *pAppFonts) {} virtual ~IMetaFile() {} + virtual void SetImageSize(int nWidth, int nHeight) = 0; virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0; virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0; virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0; diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index efdba26d0b0..1a5e6af8113 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -44,11 +44,25 @@ "_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", - "../../../../Common/3dParty/openssl/openssl/include" + "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", @@ -66,7 +80,8 @@ "_tcsnicmp=strncmp", "_lseek=lseek", "_getcwd=getcwd", "NO_CONSOLE_IO", "USE_EXTERNAL_JPEG2000", "USE_JPIP", "OPJ_STATIC", "FONT_ENGINE_DISABLE_FILESYSTEM", "IMAGE_CHECKER_DISABLE_XML", - "USE_OPENSSL_HASH" + "USE_OPENSSL_HASH", + "DISABLE_FULL_DOCUMENT_CREATION", "DISABLE_FILESYSTEM" ], "compile_files_array": [ { @@ -75,7 +90,7 @@ }, { "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/", @@ -115,7 +130,7 @@ }, { "folder": "./wasm/src/", - "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp"] + "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp"] }, { "folder": "freetype-2.10.4/src/", @@ -159,7 +174,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/", @@ -188,6 +203,30 @@ { "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", "DropCap.cpp", "Image.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.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 64639466634..52630b622ad 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -458,7 +458,7 @@ SOURCES += \ # XpsFile -XPS_ROOT_DIR = $$PWD/../../../../../XpsFile +XPS_ROOT_DIR = $$CORE_ROOT_DIR/XpsFile HEADERS += \ $$XPS_ROOT_DIR/XpsFile.h \ @@ -485,8 +485,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 \ @@ -608,7 +608,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 \ @@ -643,7 +643,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 +=\ @@ -672,6 +671,53 @@ HEADERS +=\ $$PDF_ROOT_DIR/PdfReader.h \ $$PDF_ROOT_DIR/PdfFile.h +# 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/Image.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/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/DropCap.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Image.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/HtmlRenderer/include/HTMLRendererText.h SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp @@ -680,5 +726,6 @@ HEADERS += \ ../wasm/src/serialize.h SOURCES += \ + ../wasm/src/pdfwriter.cpp \ ../wasm/src/drawingfile.cpp \ ../wasm/src/drawingfile_test.cpp diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js index 838e3c515ed..ba1b0a1e319 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_base.js @@ -158,6 +158,8 @@ this.fontPageIndex = -1; this.fontPageUpdateType = UpdateFontsSource.Undefined; this.fontStreams = {}; + + this.scannedImages = {}; } CFile.prototype["loadFromData"] = function(arrayBuffer) @@ -261,6 +263,7 @@ rec["H"] = reader.readInt(); rec["Dpi"] = reader.readInt(); rec["Rotate"] = reader.readInt(); + rec["originIndex"] = i; rec.fonts = []; rec.fontsUpdateType = UpdateFontsSource.Undefined; rec.text = null; @@ -308,9 +311,20 @@ return this.StartID; }; + function getOriginPage(pages, originIndex) + { + for (let i = 0; i < pages.length; ++i) + { + if (pages[i]["originIndex"] == originIndex) + return pages[i]; + } + return null; + } + CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor) { - if (this.pages[pageIndex].fonts.length > 0) + let page = getOriginPage(this.pages, pageIndex); + if (!page || page.fonts.length > 0) { // waiting fonts return null; @@ -320,7 +334,7 @@ let retValue = Module["_GetPixmap"](this.nativeFile, pageIndex, width, height, backgroundColor === undefined ? 0xFFFFFF : backgroundColor); this.unlockPageNumForFontsLoader(); - if (this.pages[pageIndex].fonts.length > 0) + if (page.fonts.length > 0) { // waiting fonts Module["_free"](retValue); @@ -330,7 +344,8 @@ }; CFile.prototype["getGlyphs"] = function(pageIndex) { - if (this.pages[pageIndex].fonts.length > 0) + let page = getOriginPage(this.pages, pageIndex); + if (!page || page.fonts.length > 0) { // waiting fonts return null; @@ -343,7 +358,7 @@ // you need to call destroyTextInfo() this.unlockPageNumForFontsLoader(); - if (this.pages[pageIndex].fonts.length > 0) + if (page.fonts.length > 0) { // waiting fonts retValue = null; @@ -1125,7 +1140,33 @@ rec["CA"] = reader.readDouble(); // RC if (flags & (1 << 3)) - rec["RC"] = reader.readString(); + { + 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(); @@ -1306,6 +1347,7 @@ } // 0 - left-justified, 1 - centered, 2 - right-justified rec["alignment"] = reader.readByte(); + rec["Rotate"] = reader.readInt(); // Rect and RD differences if (flags & (1 << 15)) { @@ -1575,6 +1617,64 @@ return res; }; + CFile.prototype["scanPage"] = function(page, mode) + { + let data = Module["_ScanPage"](this.nativeFile, page, (mode === undefined) ? 0 : mode); + if (data == 0) + return []; + + let lenArray = new Int32Array(Module["HEAP8"].buffer, data, 4); + if (lenArray == null) + return []; + + let len = lenArray[0]; + if (0 == len) + return []; + + let buffer = new Uint8Array(Module["HEAP8"].buffer, data + 4, len); + let reader = new CBinaryReader(buffer, 0, len); + + let shapesCount = reader.readInt(); + let shapes = new Array(shapesCount); + + for (let i = 0; i < shapesCount; i++) + shapes[i] = reader.readString(); + + Module["_free"](data); + return shapes; + }; + + CFile.prototype["getImageBase64"] = function(rId) + { + let strId = "" + rId; + if (this.scannedImages[strId]) + return this.scannedImages[strId]; + + let strPtr = Module["_GetImageBase64"](this.nativeFile, rId); + if (0 == strPtr) + { + this.scannedImages[strId] = "error"; + return this.scannedImages[strId]; + } + + let len = Module["_GetImageBase64Len"](strPtr); + let ptr = Module["_GetImageBase64Ptr"](strPtr); + + var buffer = new Uint8Array(Module["HEAP8"].buffer, ptr, len); + this.scannedImages[strId] = String.prototype.fromUtf8(buffer, 0, len); + Module["_GetImageBase64Free"](strPtr); + 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; + } + }; + CFile.prototype.memory = function() { return Module["HEAP8"]; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index ccb252acb2c..3801b96d6f6 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -74,9 +74,15 @@ 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; @@ -211,10 +217,7 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) std::wstring sFontName = UTF8_TO_U(sPathA); std::wstring sFontFile = pGraphics->GetFont(sFontName); if (sFontFile.empty()) - return NULL; - - NSWasm::CData oRes; - oRes.SkipLen(); + sFontFile = sFontName; NSFonts::IFontsMemoryStorage* pStorage = NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage(); if (pStorage) @@ -228,20 +231,24 @@ WASM_EXPORT BYTE* GetFontBinary(CGraphicsFileDrawing* pGraphics, char* path) 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; } } } - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; + return NULL; } WASM_EXPORT void DestroyTextInfo(CGraphicsFileDrawing* pGraphics) { @@ -255,6 +262,27 @@ WASM_EXPORT void SetCMapData(CGraphicsFileDrawing* pGraphics, BYTE* data, int si { pGraphics->SetCMapData(data, size); } +WASM_EXPORT BYTE* ScanPage(CGraphicsFileDrawing* pGraphics, int nPageIndex, int mode) +{ + return pGraphics->GetPageShapes(nPageIndex, mode); +} + +WASM_EXPORT void* GetImageBase64(CGraphicsFileDrawing* pGraphics, int rId) +{ + return pGraphics->GetImageBase64(rId); +} +WASM_EXPORT int GetImageBase64Len(std::string* p) +{ + return (int)p->length(); +} +WASM_EXPORT char* GetImageBase64Ptr(std::string* p) +{ + return (char*)p->c_str(); +} +WASM_EXPORT void GetImageBase64Free(std::string* p) +{ + *p = ""; +} #ifdef __cplusplus } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h index bcd36616c02..5fb3f8efc08 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.h @@ -7,6 +7,7 @@ #include "../../../../../../DjVuFile/DjVu.h" #include "../../../../../../PdfFile/PdfFile.h" #include "../../../../../../HtmlRenderer/include/HTMLRendererText.h" +#include "../../../../../../DocxRenderer/DocxRenderer.h" #include "serialize.h" class CGraphicsFileDrawing @@ -16,12 +17,14 @@ class CGraphicsFileDrawing NSFonts::IApplicationFonts* pApplicationFonts; NSFonts::IFontManager* pFontManager; NSHtmlRenderer::CHTMLRendererText* pTextRenderer; + NSDocxRenderer::IImageStorage* pImageStorage; int nType; public: CGraphicsFileDrawing(NSFonts::IApplicationFonts* pFonts) { pReader = NULL; pTextRenderer = NULL; + pImageStorage = NULL; pApplicationFonts = pFonts; pApplicationFonts->AddRef(); @@ -39,6 +42,7 @@ class CGraphicsFileDrawing RELEASEOBJECT(pTextRenderer); RELEASEOBJECT(pFontManager); RELEASEINTERFACE(pApplicationFonts); + RELEASEOBJECT(pImageStorage); nType = -1; } bool Open(BYTE* data, DWORD length, int _nType, const char* password) @@ -185,6 +189,44 @@ class CGraphicsFileDrawing { RELEASEOBJECT(pTextRenderer); } + + BYTE* GetPageShapes(const int& nPageIndex, int mode) + { + if (NULL == pImageStorage) + pImageStorage = NSDocxRenderer::CreateWasmImageStorage(); + + CDocxRenderer oRenderer(pApplicationFonts); + oRenderer.SetExternalImageStorage(pImageStorage); + oRenderer.SetTextAssociationType(NSDocxRenderer::TextAssociationType::tatParagraphToShape); + + std::vector<std::wstring> arShapes; + if (0 == mode) + arShapes = oRenderer.ScanPage(pReader, nPageIndex); + else + arShapes = oRenderer.ScanPagePptx(pReader, 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; + } + + std::string* GetImageBase64(int nRId) + { + if (NULL == pImageStorage) + return NULL; + return pImageStorage->GetBase64(nRId); + } }; #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 1a80dd548c8..d3ddb7fc6ea 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -3,6 +3,7 @@ #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) @@ -1238,11 +1239,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)) { @@ -1523,6 +1597,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"; @@ -1697,7 +1775,7 @@ int main(int argc, char* argv[]) } } - std::cout << std::endl; + std::cout << std::endl << std::endl; } if (pAnnots) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp index 2379a2b3e75..cf6435762ce 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/metafile.cpp @@ -39,6 +39,7 @@ 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 DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; } diff --git a/PdfFile/PdfWriter_empty.cpp b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp similarity index 94% rename from PdfFile/PdfWriter_empty.cpp rename to DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp index 0552f1f71dc..8aca52fb2ca 100644 --- a/PdfFile/PdfWriter_empty.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/pdfwriter.cpp @@ -29,7 +29,7 @@ * 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, bool bCreate) : m_oCommandManager(this) {} @@ -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,6 +128,8 @@ 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, const std::wstring& wsTempDirectory) { return 0; } @@ -143,8 +145,12 @@ 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; } +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) {} +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) { 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; } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h index 72f151d2539..665efebb843 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/serialize.h +++ b/DesktopEditor/graphics/pro/js/wasm/src/serialize.h @@ -1,439 +1,449 @@ #ifndef _WASM_SERIALIZE_H #define _WASM_SERIALIZE_H -#include "../../../../../graphics/IRenderer.h" #include "../../../../../common/StringExt.h" #include "../../../../../common/StringUTF32.h" +#include "../../../../../graphics/IRenderer.h" #include "../../../../../graphics/pro/Fonts.h" +#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); + } + 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; + } + }; +} // namespace NSWasm namespace NSWasm { - struct CPageLinkItem - { - std::string Link; - double Dest; - - double X; - double Y; - double W; - double H; - }; - - class CPageLink - { - public: - std::vector<CPageLinkItem> 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<CPageLinkItem> 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/raster.pri b/DesktopEditor/graphics/pro/raster.pri index feaaad1e2d8..f5e54810fc6 100644 --- a/DesktopEditor/graphics/pro/raster.pri +++ b/DesktopEditor/graphics/pro/raster.pri @@ -28,6 +28,10 @@ core_windows { LIBS += -lUser32 } +core_android { + QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types +} + INCLUDEPATH += \ $$LIB_GRAPHICS_PRI_PATH/cximage/jasper/include \ $$LIB_GRAPHICS_PRI_PATH/cximage/jpeg \ 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/raster/Metafile/Common/MetaFileUtils.h b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h index ae76ba586dd..7767bd9c977 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h @@ -93,7 +93,7 @@ namespace MetaFile { public: - CDataStream() : pBuffer(NULL) + CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pEnd(NULL), pCur(NULL) { } @@ -103,10 +103,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; @@ -120,7 +135,7 @@ namespace MetaFile unsigned char unResult = pCur[0]; pCur++; return unResult; - }; + } unsigned short ReadUShort() { if (pCur + 1 >= pEnd) @@ -129,7 +144,7 @@ namespace MetaFile unsigned short ushResult = (pCur[0]) | ((pCur[1]) << 8); pCur += 2; return ushResult; - }; + } unsigned int ReadULong() { if (pCur + 3 >= pEnd) @@ -138,7 +153,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) @@ -159,19 +174,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); @@ -181,7 +196,7 @@ namespace MetaFile { pBuffer[ulIndex] = ReadChar(); } - }; + } void ReadBytes(unsigned short* pBuffer, unsigned int ulSize) { size_t ulRemainSize = (pEnd - pCur) / 2; @@ -1047,7 +1062,7 @@ namespace MetaFile bool IsEof() const { - if (pCur >= pEnd) + if (pCur >= pBufferEnd) return true; return false; @@ -1060,7 +1075,10 @@ namespace MetaFile void Skip(unsigned int ulSkip) { - pCur += ulSkip; + if (pCur + ulSkip >= pEnd) + pCur = pEnd; + else + pCur += ulSkip; } void SeekBack(unsigned int ulSkipBack) @@ -1071,6 +1089,7 @@ namespace MetaFile void SeekToStart() { pCur = pBuffer; + ClearCurrentBlockSize(); } unsigned int CanRead() @@ -1085,21 +1104,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) { @@ -1116,6 +1145,7 @@ namespace MetaFile private: BYTE *pBuffer; + BYTE *pBufferEnd; BYTE *pCur; BYTE *pEnd; }; diff --git a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp index dc66cba25d9..e3d1d134337 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfInterpretator/CEmfInterpretatorSvg.cpp @@ -1169,6 +1169,7 @@ namespace MetaFile std::wstring wsFontName = pFont->GetFaceName(); +#ifndef BUILDING_WASM_MODULE if (!wsFontName.empty()) { NSFonts::CFontSelectFormat oFormat; @@ -1179,6 +1180,7 @@ namespace MetaFile if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; } +#endif if (!wsFontName.empty()) arNodeAttributes.push_back({L"font-family", wsFontName}); diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp index 078a3bdac2b..f46fecb4b54 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfParser.cpp @@ -63,6 +63,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) @@ -213,6 +215,8 @@ namespace MetaFile m_oStream.Skip(need_skip); ulRecordIndex++; + m_oStream.ClearCurrentBlockSize(); + } while (!CheckError()); if (!CheckError()) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index d0ef37afbb5..542837ff1f6 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -234,6 +234,8 @@ namespace MetaFile m_oStream >> unSize; m_oStream >> m_ulRecordSize; + m_oStream.SetCurrentBlockSize(m_ulRecordSize); + unsigned int unRecordPos = m_oStream.Tell(); LOGGING(ActionNamesEmfPlus[unShType] << L" DataSize = " << m_ulRecordSize) @@ -318,6 +320,7 @@ namespace MetaFile LOGGING(L"Skip: " << nNeedSkip) + m_oStream.ClearCurrentBlockSize(); m_ulRecordSize = 0; }while(m_oStream.CanRead() >= 12 && !m_bEof); diff --git a/DesktopEditor/raster/Metafile/MetaFile.cpp b/DesktopEditor/raster/Metafile/MetaFile.cpp index c482571d395..5fa5c01c38c 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.cpp +++ b/DesktopEditor/raster/Metafile/MetaFile.cpp @@ -81,6 +81,10 @@ namespace MetaFile Close(); RELEASEINTERFACE(m_pFontManager); } + void CMetaFile::SetImageSize(int nWidth, int nHeight) + { + // for meta with empty size + } std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight) { diff --git a/DesktopEditor/raster/Metafile/MetaFile.h b/DesktopEditor/raster/Metafile/MetaFile.h index 74738c1251f..1d1d563877a 100644 --- a/DesktopEditor/raster/Metafile/MetaFile.h +++ b/DesktopEditor/raster/Metafile/MetaFile.h @@ -62,6 +62,7 @@ namespace MetaFile CMetaFile(NSFonts::IApplicationFonts *pAppFonts); virtual ~CMetaFile(); + void SetImageSize(int nWidth, int nHeight); bool LoadFromFile(const wchar_t* wsFilePath); bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize); bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp index 57a4d1e134d..1c860b7517e 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfInterpretator/CInterpretatorSvgBase.cpp @@ -283,6 +283,7 @@ namespace MetaFile std::wstring wsFontName = pFont->GetFaceName(); +#ifndef BUILDING_WASM_MODULE if (!wsFontName.empty()) { NSFonts::CFontSelectFormat oFormat; @@ -293,6 +294,7 @@ namespace MetaFile if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName)) wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'"; } +#endif if (!wsFontName.empty()) arNodeAttributes.push_back({L"font-family", wsFontName}); diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp index 33803d513a6..34ec3fa88cb 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParser.cpp @@ -52,6 +52,8 @@ namespace MetaFile m_unRecordSize = unSize * 2; // Размер указан в WORD + m_oStream.SetCurrentBlockSize(m_unRecordSize); + switch (ushType) { //----------------------------------------------------------- @@ -161,6 +163,7 @@ namespace MetaFile // Пропускаем лишние байты, которые могли быть в записи int need_skip = m_unRecordSize - (m_oStream.Tell() - m_unRecordPos); m_oStream.Skip(need_skip); + m_oStream.ClearCurrentBlockSize(); }; if (!m_bEof) diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp index 6843948df19..08a7727073e 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.cpp @@ -20,6 +20,12 @@ bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize) return false; } +bool CSvgFile::ReadFromWString(const std::wstring &wsContext) +{ + Clear(); + return m_oParser.LoadFromString(wsContext, &m_oContainer, this); +} + bool CSvgFile::OpenFromFile(const std::wstring &wsFile) { Clear(); @@ -36,15 +42,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, SVG_FILE_WIDTH); - dY = oWindow.m_oY .ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); - dWidth = oWindow.m_oWidth .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); - dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); + dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH); + dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT); + + 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 (SVG::Equals(0., dWidth)) - dWidth = (!m_oContainer.GetViewBox().m_oWidth.Empty()) ? m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel) : SVG_FILE_WIDTH; - if (SVG::Equals(0., dHeight)) - dHeight = (!m_oContainer.GetViewBox().m_oHeight.Empty()) ? m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel) : SVG_FILE_HEIGHT; + if (0. == dWidth) + dWidth = SVG_FILE_WIDTH; + if (0. == dHeight) + dHeight = SVG_FILE_HEIGHT; return true; } @@ -59,6 +96,11 @@ 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()) @@ -146,21 +188,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); diff --git a/DesktopEditor/raster/Metafile/svg/CSvgFile.h b/DesktopEditor/raster/Metafile/svg/CSvgFile.h index c2a7f456d09..1f2c71e60ca 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgFile.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgFile.h @@ -7,19 +7,23 @@ #include "CSvgParser.h" #include "SvgObjects/CStyle.h" -class CSvgFile +#define SVG_DECL_IMPORT Q_DECL_IMPORT + +class SVG_DECL_IMPORT CSvgFile { public: CSvgFile(); ~CSvgFile(); bool ReadFromBuffer(BYTE* pBuffer, unsigned int unSize); + bool ReadFromWString(const std::wstring& wsContext); bool OpenFromFile(const std::wstring& wsFile); 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; diff --git a/DesktopEditor/raster/Metafile/svg/CSvgParser.h b/DesktopEditor/raster/Metafile/svg/CSvgParser.h index 12a69d99063..060aecea5df 100644 --- a/DesktopEditor/raster/Metafile/svg/CSvgParser.h +++ b/DesktopEditor/raster/Metafile/svg/CSvgParser.h @@ -1,7 +1,6 @@ #ifndef CSVGPARSER_H #define CSVGPARSER_H -#include "../../graphics/pro/Fonts.h" #include "../../../common/Directory.h" #include "../../../xml/include/xmlutils.h" diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h index a67bd9be416..4d57d48c2ea 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CContainer.h @@ -3,7 +3,7 @@ #include "CObjectBase.h" -#include "../../../graphics/pro/Fonts.h" +#include "../../../../graphics/pro/Fonts.h" class CSvgFile; 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<CGradient*>(pFile->GetMarkedObject(m_wsXlinkHref)); + std::vector<LONG> arColors; + std::vector<double> arPositions; - if (NULL == pGradiend) - return false; - - pGradiend->Apply(pRenderer, pFile, oObjectBounds); - } - else + for (const CStopElement* pStopElement : m_arObjects) { - std::vector<LONG> arColors; - std::vector<double> 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<CGradient*>(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 a83ee934b9e..465c40afdfe 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CImage.cpp @@ -59,21 +59,23 @@ namespace SVG NSBase64::Base64Decode(wsImageData.c_str(), wsImageData.length(), pBuffer, &(int&)ulSize); } - #ifndef METAFILE_DISABLE_FILESYSTEM - 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 true; - - wsFilePath = pFile->GetWorkingDirectory() + L'/' + wsFilePath; + 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 (!NSFile::CFileBinary::Exists(wsFilePath) || !NSFile::CFileBinary::ReadAllBytes(wsFilePath, &pBuffer, ulSize)) - return false; + 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) diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h index 505a6d61c73..66f3b5ed9d1 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CObjectBase.h @@ -5,7 +5,7 @@ #include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h" #include "../../../../xml/include/xmlutils.h" #include "../../../../graphics/IRenderer.h" -#include "../../../common/IGrObject.h" +#include "../../../../common/IGrObject.h" #include "../SvgTypes.h" class CSvgFile; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp index 51d77955801..13a77b341df 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CStyle.cpp @@ -50,7 +50,7 @@ namespace SVG { if (oNode->m_wsClass.find(L' ') != std::wstring::npos) { - std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, L" "); + std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" "); if (arClasses.size() > 1) arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin()); @@ -82,7 +82,7 @@ namespace SVG if (arWords.back()[0] == L'.') { - arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), L" "); + arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" "); arNextNodes.push_back(arWords.back()); arWords.pop_back(); } diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp index 9447a8a9c23..9c6f1165fd8 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.cpp @@ -129,6 +129,14 @@ 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_oTransformtaion.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 @@ -141,10 +149,8 @@ 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 = m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft); - double dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop); + double dX, dY; + CalculatePosition(dX, dY); ApplyFont(pRenderer, dX, dY); @@ -181,10 +187,10 @@ namespace SVG void CTSpan::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const { - if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) + if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true)) nTypePath += c_nStroke; - if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) + if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true)) nTypePath += c_nWindingFillMode; } @@ -366,12 +372,20 @@ 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_oTransformtaion.m_oTransform.GetMatrix().GetFinalValue()); double dXScale = 1., dYScale = 1.; diff --git a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h index 63f7af4e0b4..b67e5390fe5 100644 --- a/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h +++ b/DesktopEditor/raster/Metafile/svg/SvgObjects/CText.h @@ -36,6 +36,8 @@ namespace SVG 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); 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 <QCoreApplication> +// #include <QCoreApplication> +#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/DocxRenderer/DocxRenderer.cpp b/DocxRenderer/DocxRenderer.cpp index 9dc274099c3..b1f7243f99e 100644 --- a/DocxRenderer/DocxRenderer.cpp +++ b/DocxRenderer/DocxRenderer.cpp @@ -34,318 +34,462 @@ #include "../DesktopEditor/common/Directory.h" #include "../OfficeUtils/src/OfficeUtils.h" #include "src/logic/Document.h" +#include "../DesktopEditor/graphics/commands/DocInfo.h" +#include <algorithm> class CDocxRenderer_Private { - public: - NSDocxRenderer::CDocument m_oDocument; - std::wstring m_sTempDirectory; +public: + NSDocxRenderer::CDocument m_oDocument; + std::wstring m_sTempDirectory; - 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); + + m_pInternal->m_oDocument.m_strTempDirectory = L""; + return hr; } -HRESULT CDocxRenderer::CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress) +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& sDstFile, 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 = sDstFile; + + if (bIsOutCompress) + m_pInternal->m_oDocument.m_strTempDirectory = NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory); + else + m_pInternal->m_oDocument.m_strTempDirectory= m_pInternal->m_sTempDirectory; + + 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<std::wstring> 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; + + DrawPage(pFile, nPage); + + std::vector<std::wstring> xml_shapes; + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXml(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arImages) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXml(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + + std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; + if (!arComleteObjects.empty()) + xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end()); + + m_pInternal->m_oDocument.Clear(); + return xml_shapes; } -int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress) +std::vector<std::wstring> 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; + + DrawPage(pFile, nPage); - if (odftPDF == pFile->GetType()) - m_pInternal->m_oDocument.m_bIsNeedPDFTextAnalyzer = true; + std::vector<std::wstring> xml_shapes; + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXmlPptx(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } + for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arImages) + { + if (!shape) continue; + auto writer = new NSStringUtils::CStringBuilder(); + shape->ToXmlPptx(*writer); + xml_shapes.push_back(writer->GetData()); + delete writer; + } - 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; + std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml; + if (!arComleteObjects.empty()) + xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end()); - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + m_pInternal->m_oDocument.Clear(); + return xml_shapes; +} + +void CDocxRenderer::SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage) +{ + m_pInternal->m_oDocument.m_oImageManager.m_pExternalStorage = pStorage; +} + +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 S_OK; + 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<NSDocxRenderer::CImageInfo> 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.m_arCompleteObjectsXml.push_back(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; + // TODO: + return S_OK; } HRESULT CDocxRenderer::put_BrushGradientColors(LONG* pColors, double* pPositions, LONG lCount) { - // TODO: - return S_OK; + // TODO: + return S_OK; +} +HRESULT CDocxRenderer::get_BrushTextureImage(Aggplus::CImage** pImage) +{ + *pImage = m_pInternal->m_oDocument.m_oBrush.Image; + return S_OK; +} +HRESULT CDocxRenderer::put_BrushTextureImage(Aggplus::CImage* pImage) +{ + RELEASEINTERFACE(m_pInternal->m_oDocument.m_oBrush.Image); + + if (NULL == pImage) + return S_FALSE; + + m_pInternal->m_oDocument.m_oBrush.Image = pImage; + m_pInternal->m_oDocument.m_oBrush.Image->AddRef(); + + 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; } //---------------------------------------------------------------------------------------- @@ -353,178 +497,178 @@ HRESULT CDocxRenderer::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { ret //---------------------------------------------------------------------------------------- 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(); } //---------------------------------------------------------------------------------------- @@ -532,11 +676,11 @@ HRESULT CDocxRenderer::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); } //---------------------------------------------------------------------------------------- @@ -544,13 +688,29 @@ HRESULT CDocxRenderer::put_ClipMode(const LONG& 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_oBrush; + if (c_BrushTypeSolid != pBrush->Type) + return S_FALSE; + + NSStructures::CPen* pPen = &m_pInternal->m_oDocument.m_oPen; + if (pBrush->Color1 != pPen->Color || pBrush->Alpha1 != pPen->Alpha) + return S_FALSE; + + Aggplus::CMatrix* pTransform = &m_pInternal->m_oDocument.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..c8ce4f21259 100644 --- a/DocxRenderer/DocxRenderer.h +++ b/DocxRenderer/DocxRenderer.h @@ -43,157 +43,166 @@ #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(); +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); + //---------------------------------------------------------------------------------------- + // Функции для работы с 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 CreateNewFile(const std::wstring& wsPath, bool bIsOutCompress = true); - HRESULT Close(); + // методы, которыми будет пользоваться конвертер + HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); + int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); + std::vector<std::wstring> ScanPage(IOfficeDrawingFile* pFile, size_t nPage); + std::vector<std::wstring> ScanPagePptx(IOfficeDrawingFile* pFile, size_t nPage); - 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); + void SetExternalImageStorage(NSDocxRenderer::IImageStorage* pStorage); - // методы, которыми будет пользоваться конвертер - HRESULT SetTextAssociationType(const NSDocxRenderer::TextAssociationType& eType); - int Convert(IOfficeDrawingFile* pFile, const std::wstring& sDstFile, bool bIsOutCompress = true); + virtual HRESULT IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedCommandType& type); + virtual HRESULT AdvancedCommand(IAdvancedCommand* command); - private: - CDocxRenderer_Private* m_pInternal; +private: + CDocxRenderer_Private* m_pInternal; + void DrawPage(IOfficeDrawingFile* pFile, size_t nPage); }; diff --git a/DocxRenderer/DocxRenderer.pro b/DocxRenderer/DocxRenderer.pro index d63e6d22a56..a1c6860787e 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,67 @@ 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/DropCap.h \ + src/logic/elements/Image.h \ + src/logic/elements/Paragraph.h \ + src/logic/elements/Shape.h \ + src/logic/elements/TextLine.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/DropCap.cpp \ + src/logic/elements/Image.cpp \ + src/logic/elements/Paragraph.cpp \ + src/logic/elements/Shape.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/Document.cpp b/DocxRenderer/src/logic/Document.cpp index cf4e77a3fa8..36e2aed13ef 100644 --- a/DocxRenderer/src/logic/Document.cpp +++ b/DocxRenderer/src/logic/Document.cpp @@ -1,1216 +1,1242 @@ #include "Document.h" +#ifndef DISABLE_FULL_DOCUMENT_CREATION +#include "./../resources/resources.h" +#endif + namespace NSDocxRenderer { - void WriteImageToWriter(NSStringUtils::CStringBuilder& oWriter, const std::shared_ptr<CImageInfo>& info) - { - oWriter.WriteString(L"<Relationship Id=\"rId"); - oWriter.AddInt(c_iStartingIdForImages + info->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_oCurrentPage(pFonts), m_oFontManager(pFonts), m_oFontSelector(pFonts) + { + m_oSimpleGraphicsConverter.SetRenderer(pRenderer); + } + void CDocument::Clear() + { + NewPage(); + + for(auto& val : m_mapXmlString) + delete val.second; + + m_mapXmlString.clear(); + m_oFontSelector.ClearCache(); + } + + CDocument::~CDocument() { + Clear(); + RELEASEINTERFACE(m_pFontManager); + } + + HRESULT CDocument::NewPage() + { + m_oPen.SetDefaultParams(); + m_oBrush.SetDefaultParams(); + m_oFont.SetDefaultParams(); + m_oShadow.SetDefaultParams(); + m_oEdge.SetDefaultParams(); + + m_oTransform.Reset(); + 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; + m_oCurrentPage.m_bIsRecalcFontSize = true; + 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); + 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<CImageInfo> 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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ - <w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" \ - xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" \ - xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" \ - xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" \ - xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" \ - xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" \ - xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" \ - xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" \ - xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" \ - xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" \ - xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ - xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" \ - xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" \ - 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:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \ - xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\" \ - 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: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\" \ - xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \ - xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \ - xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \ - xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" \ - mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">\ - <w:body>"); - - return true; - } - - void CDocument::Close() - { - BuildDocumentXmlRels(); - BuildFontTableXml(); - BuildStylesXml(); - - // document - m_oCurrentPage.WriteSectionToFile(true, m_oWriter); - m_oWriter.WriteString(L"</w:body></w:document>"); - m_oDocumentStream.WriteStringUTF8(m_oWriter.GetData()); - m_oWriter.ClearNoAttack(); - - m_oDocumentStream.CloseFile(); - } - - void CDocument::BuildDocumentXmlRels() - { - // сохраним rels (images & docs) - NSStringUtils::CStringBuilder oWriter; - - oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ -<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\ -<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\ -<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>\ -<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings\" Target=\"webSettings.xml\"/>\ -<Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>\ -<Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme.xml\"/>"); - - 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"</Relationships>"); - - 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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ - <w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ - xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ - 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: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\">"); - - CFontTable* pFontTable = &m_oCurrentPage.m_oFontManager.m_oFontTable; - for (std::map<std::wstring, CFontTableEntry>::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"<w:font w:name=\""); - oWriter.WriteEncodeXmlString(oEntry.m_strFamilyName); - oWriter.WriteString(L"\">"); - - oWriter.WriteString(L"<w:panose1 w:val=\""); - oWriter.WriteString(oEntry.m_strPANOSE); - oWriter.WriteString(L"\"/>"); - - if (oEntry.m_bIsFixedWidth) - oWriter.WriteString(L"<w:pitch w:val=\"fixed\" />"); - else - oWriter.WriteString(L"<w:pitch w:val=\"variable\" />"); - - oWriter.WriteString(L"<w:charset w:val=\"00\"/>"); - - oWriter.WriteString(L"<w:sig w:usb0=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[0]); - oWriter.WriteString(L"\" w:usb1=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[1]); - oWriter.WriteString(L"\" w:usb2=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[2]); - oWriter.WriteString(L"\" w:usb3=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[3]); - oWriter.WriteString(L"\" w:csb0=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[4]); - oWriter.WriteString(L"\" w:csb1=\""); - oWriter.WriteHexInt4(oEntry.m_arSignature[5]); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"</w:font>"); - } - - oWriter.WriteString(L"</w:fonts>"); - NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); - } - - void CDocument::BuildStylesXml() - { - NSStringUtils::CStringBuilder oWriter; - - // сохраним styles - oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ - <w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ - xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ - 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: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\">"); - - oWriter.WriteString(L"<w:docDefaults>"); - oWriter.WriteString(L"<w:rPrDefault><w:rPr>"); - oWriter.WriteString(L"<w:lang w:val=\"en-US\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\"/><w:rFonts w:eastAsiaTheme=\"minorHAnsi\" w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:cs=\"Times New Roman\"/>"); - oWriter.WriteString(L"</w:rPr></w:rPrDefault>"); - oWriter.WriteString(L"<w:pPrDefault><w:pPr/></w:pPrDefault>"); - oWriter.WriteString(L"</w:docDefaults>"); - - oWriter.WriteString(L"<w:latentStyles w:defLockedState=\"false\" w:defUIPriority=\"99\" w:defSemiHidden=\"true\" w:defUnhideWhenUsed=\"true\" w:defQFormat=\"false\" w:count=\"267\">"); - oWriter.WriteString(L"<w:lsdException w:name=\"Normal\" w:semiHidden=\"false\" w:uiPriority=\"0\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 1\" w:semiHidden=\"false\" w:uiPriority=\"9\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 2\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 3\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 4\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 5\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 6\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 7\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 8\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"heading 9\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 1\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 2\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 3\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 4\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 5\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 6\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 7\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 8\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"toc 9\" w:uiPriority=\"39\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"caption\" w:uiPriority=\"35\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Title\" w:semiHidden=\"false\" w:uiPriority=\"10\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Default Paragraph Font\" w:uiPriority=\"1\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Subtitle\" w:semiHidden=\"false\" w:uiPriority=\"11\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Strong\" w:semiHidden=\"false\" w:uiPriority=\"22\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"20\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Table Grid\" w:semiHidden=\"false\" w:uiPriority=\"59\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Placeholder Text\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"No Spacing\" w:semiHidden=\"false\" w:uiPriority=\"1\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Revision\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"List Paragraph\" w:semiHidden=\"false\" w:uiPriority=\"34\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Quote\" w:semiHidden=\"false\" w:uiPriority=\"29\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Intense Quote\" w:semiHidden=\"false\" w:uiPriority=\"30\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Subtle Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"19\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Intense Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"21\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Subtle Reference\" w:semiHidden=\"false\" w:uiPriority=\"31\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Intense Reference\" w:semiHidden=\"false\" w:uiPriority=\"32\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Book Title\" w:semiHidden=\"false\" w:uiPriority=\"33\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"Bibliography\" w:uiPriority=\"37\"/>"); - oWriter.WriteString(L"<w:lsdException w:name=\"TOC Heading\" w:uiPriority=\"39\" w:qFormat=\"true\"/>"); - oWriter.WriteString(L"</w:latentStyles>"); - - oWriter.WriteString(L"<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/>"); - oWriter.WriteString(L"</w:style>"); - - oWriter.WriteString(L"<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\">"); - oWriter.WriteString(L"<w:name w:val=\"Default Paragraph Font\"/>"); - oWriter.WriteString(L"<w:uiPriority w:val=\"1\"/>"); - oWriter.WriteString(L"<w:semiHidden/>"); - oWriter.WriteString(L"<w:unhideWhenUsed/>"); - oWriter.WriteString(L"<w:noProof/>"); //отключение проверки орфографии - oWriter.WriteString(L"<w:b w:val=\"0\"/>"); - oWriter.WriteString(L"<w:bCs w:val=\"0\"/>"); - oWriter.WriteString(L"<w:i w:val=\"0\"/>"); - oWriter.WriteString(L"<w:iCs w:val=\"0\"/>"); - oWriter.WriteString(L"<w:color w:val=\"111111\"/>"); - oWriter.WriteString(L"</w:style>"); - - oWriter.WriteString(L"<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"TableNormal\">"); - oWriter.WriteString(L"<w:name w:val=\"Normal Table\"/>"); - oWriter.WriteString(L"<w:semiHidden/>"); - oWriter.WriteString(L"<w:unhideWhenUsed/>"); - oWriter.WriteString(L"<w:qFormat/>"); - oWriter.WriteString(L"<w:tblPr>"); - oWriter.WriteString(L"<w:tblInd w:w=\"0\" w:type=\"dxa\"/>"); - oWriter.WriteString(L"<w:tblCellMar>"); - oWriter.WriteString(L"<w:top w:w=\"0\" w:type=\"dxa\"/>"); - oWriter.WriteString(L"<w:left w:w=\"108\" w:type=\"dxa\"/>"); - oWriter.WriteString(L"<w:bottom w:w=\"0\" w:type=\"dxa\"/>"); - oWriter.WriteString(L"<w:right w:w=\"108\" w:type=\"dxa\"/>"); - oWriter.WriteString(L"</w:tblCellMar>"); - oWriter.WriteString(L"</w:tblPr>"); - oWriter.WriteString(L"</w:style>"); - - oWriter.WriteString(L"<w:style w:type=\"numbering\" w:default=\"1\" w:styleId=\"NoList\">"); - oWriter.WriteString(L"<w:name w:val=\"No List\"/>"); - oWriter.WriteString(L"<w:semiHidden/>"); - oWriter.WriteString(L"<w:unhideWhenUsed/>"); - oWriter.WriteString(L"<w:uiPriority w:val=\"99\"/>"); - oWriter.WriteString(L"</w:style>"); - - for (const auto &pStyle : m_oStyleManager.m_arStyles) - { - pStyle->ToXml(oWriter); - } - - oWriter.WriteString(L"</w:styles>"); - - 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 = (LONG)lType; + m_oCurrentPage.BeginCommand(lType); + + 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) + { + 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 if (c_nPathType == lType) + { + m_oCurrentPage.PathEnd(); + } + + 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.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<CImageInfo> pInfo = nullptr; + + if ((nType > 0xFF) && (c_BrushTypeTexture == m_oBrush.Type)) + { + double x = 0; + double y = 0; + double w = 0; + double h = 0; + if (m_oBrush.Image) + pInfo = m_oImageManager.WriteImage(m_oBrush.Image, x, y, w, h); + else + 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.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_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 = m_pAppFonts->GenerateFontManager(); + m_pFontManager->CreateOwnerCache(8); + } + + 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; + } + + void CDocument::Init(const bool& bIsClearStreams) + { + // Сбросим кэш шрифтов. По идее можно оставлять кэш для шрифтов "по имени", + // но для шрифтов из темповых папок - нет. Темповая папка для Reader (PDF/XPS/DJVU) + // может быть одной и той же. И создание там файлов функцией создания временных файлов + // может вернуть один и тот же путь. И шрифт возьмется из старого файла. + m_oFontManager.ClearCache(); + if (m_pAppFonts && bIsClearStreams) m_pAppFonts->GetStreams()->Clear(); + + Clear(); + m_lCurrentCommandType = 0; + + m_oCurrentPage.Init(&m_oFont, + &m_oPen, + &m_oBrush, + &m_oShadow, + &m_oEdge, + &m_oTransform, + &m_oSimpleGraphicsConverter, + &m_oFontStyleManager, + &m_oFontManager, + &m_oFontSelector, + &m_oParagraphStyleManager); + + m_oImageManager.Clear(); + m_oFontStyleManager.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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ + <w:document xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" \ + xmlns:cx=\"http://schemas.microsoft.com/office/drawing/2014/chartex\" \ + xmlns:cx1=\"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex\" \ + xmlns:cx2=\"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex\" \ + xmlns:cx3=\"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex\" \ + xmlns:cx4=\"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex\" \ + xmlns:cx5=\"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex\" \ + xmlns:cx6=\"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex\" \ + xmlns:cx7=\"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex\" \ + xmlns:cx8=\"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex\" \ + xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ + xmlns:aink=\"http://schemas.microsoft.com/office/drawing/2016/ink\" \ + xmlns:am3d=\"http://schemas.microsoft.com/office/drawing/2017/model3d\" \ + 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:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \ + xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\" \ + 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: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\" \ + xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \ + xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \ + xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \ + xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" \ + mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">\ + <w:body>"); + + for (size_t i = 0; i < m_mapXmlString.size(); ++i) + { + oDocumentStream.WriteStringUTF8(m_mapXmlString[i]->GetData()); + } + + oDocumentStream.WriteStringUTF8(L"</w:body></w:document>"); + + oDocumentStream.CloseFile(); + } + + void CDocument::BuildDocumentXmlRels() + { + // сохраним rels (images & docs) + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ + <Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\ + <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\ + <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/>\ + <Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings\" Target=\"webSettings.xml\"/>\ + <Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/>\ + <Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\" Target=\"theme/theme.xml\"/>"); + + for (const auto& pImage : m_oImageManager.m_mapImageData) + { + auto pInfo = pImage.second; + + oWriter.WriteString(L"<Relationship Id=\"rId"); + oWriter.AddInt(c_iStartingIdForImages + pInfo->m_nId); + oWriter.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/"); + oWriter.WriteString(pInfo->m_strFileName); + oWriter.WriteString(L"\"/>"); + } + + for (const auto& pImage : m_oImageManager.m_mapImagesFile) + { + auto pInfo = pImage.second;; + + oWriter.WriteString(L"<Relationship Id=\"rId"); + oWriter.AddInt(c_iStartingIdForImages + pInfo->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"</Relationships>"); + + 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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ + <w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ + xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ + 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: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\">"); + + auto oFonts = m_oFontSelector.GetCache(); + for (auto& val : oFonts) + { + if (val.wsSelectedName.empty()) + continue; + + oWriter.WriteString(L"<w:font w:name=\""); + oWriter.WriteEncodeXmlString(val.wsSelectedName); + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L"<w:panose1 w:val=\""); + std::wstring strPANOSE = L""; + for(auto& uc : val.oFontSelectParams.arPANOSE) + { + char c1 = (char)(uc >> 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"<w:pitch w:val=\"fixed\" />"); + else + oWriter.WriteString(L"<w:pitch w:val=\"variable\" />"); + + oWriter.WriteString(L"<w:charset w:val=\"00\"/>"); + + if (!val.oFontSelectParams.arSignature.empty()) + { + oWriter.WriteString(L"<w:sig w:usb0=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[0]); + oWriter.WriteString(L"\" w:usb1=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[1]); + oWriter.WriteString(L"\" w:usb2=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[2]); + oWriter.WriteString(L"\" w:usb3=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[3]); + oWriter.WriteString(L"\" w:csb0=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[4]); + oWriter.WriteString(L"\" w:csb1=\""); + oWriter.WriteHexInt4(val.oFontSelectParams.arSignature[5]); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"</w:font>"); + } + + oWriter.WriteString(L"</w:fonts>"); + NSFile::CFileBinary::SaveToFile(m_strTempDirectory + L"/word/fontTable.xml", oWriter.GetData()); + } + + void CDocument::BuildStylesXml() + { + NSStringUtils::CStringBuilder oWriter; + + // сохраним styles + oWriter.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ + <w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ + xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ + 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: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\">"); + + oWriter.WriteString(L"<w:docDefaults>"); + oWriter.WriteString(L"<w:rPrDefault><w:rPr>"); + oWriter.WriteString(L"<w:lang w:val=\"en-US\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\"/><w:rFonts w:eastAsiaTheme=\"minorHAnsi\" w:ascii=\"Times New Roman\" w:hAnsi=\"Times New Roman\" w:cs=\"Times New Roman\"/>"); + oWriter.WriteString(L"</w:rPr></w:rPrDefault>"); + oWriter.WriteString(L"<w:pPrDefault><w:pPr/></w:pPrDefault>"); + oWriter.WriteString(L"</w:docDefaults>"); + + oWriter.WriteString(L"<w:latentStyles w:defLockedState=\"0\" w:defUIPriority=\"99\" w:defSemiHidden=\"1\" w:defUnhideWhenUsed=\"1\" w:defQFormat=\"0\" w:count=\"267\">"); + oWriter.WriteString(L"<w:lsdException w:name=\"Normal\" w:semiHidden=\"0\" w:uiPriority=\"0\" w:unhideWhenUsed=\"0\" w:qFormat=\"1\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 1\" w:semiHidden=\"0\" w:uiPriority=\"9\" w:unhideWhenUsed=\"0\" w:qFormat=\"1\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 2\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 3\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 4\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 5\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 6\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 7\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 8\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"heading 9\" w:uiPriority=\"9\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 1\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 2\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 3\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 4\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 5\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 6\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 7\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 8\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"toc 9\" w:uiPriority=\"39\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"caption\" w:uiPriority=\"35\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Title\" w:semiHidden=\"false\" w:uiPriority=\"10\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Default Paragraph Font\" w:uiPriority=\"1\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Subtitle\" w:semiHidden=\"false\" w:uiPriority=\"11\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Strong\" w:semiHidden=\"false\" w:uiPriority=\"22\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"20\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Table Grid\" w:semiHidden=\"false\" w:uiPriority=\"59\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Placeholder Text\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"No Spacing\" w:semiHidden=\"false\" w:uiPriority=\"1\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Revision\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"List Paragraph\" w:semiHidden=\"false\" w:uiPriority=\"34\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Quote\" w:semiHidden=\"false\" w:uiPriority=\"29\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Intense Quote\" w:semiHidden=\"false\" w:uiPriority=\"30\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 1\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 2\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 3\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 4\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 5\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Shading Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"60\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"61\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Light Grid Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"62\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"63\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Shading 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"64\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"65\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium List 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"66\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 1 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"67\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 2 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"68\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Medium Grid 3 Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"69\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Dark List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"70\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Shading Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"71\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful List Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"72\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Colorful Grid Accent 6\" w:semiHidden=\"false\" w:uiPriority=\"73\" w:unhideWhenUsed=\"false\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Subtle Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"19\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Intense Emphasis\" w:semiHidden=\"false\" w:uiPriority=\"21\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Subtle Reference\" w:semiHidden=\"false\" w:uiPriority=\"31\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Intense Reference\" w:semiHidden=\"false\" w:uiPriority=\"32\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Book Title\" w:semiHidden=\"false\" w:uiPriority=\"33\" w:unhideWhenUsed=\"false\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"Bibliography\" w:uiPriority=\"37\"/>"); + oWriter.WriteString(L"<w:lsdException w:name=\"TOC Heading\" w:uiPriority=\"39\" w:qFormat=\"true\"/>"); + oWriter.WriteString(L"</w:latentStyles>"); + + oWriter.WriteString(L"<w:style w:type=\"character\" w:default=\"1\" w:styleId=\"DefaultParagraphFont\">"); + oWriter.WriteString(L"<w:name w:val=\"Default Paragraph Font\"/>"); + oWriter.WriteString(L"<w:uiPriority w:val=\"1\"/>"); + oWriter.WriteString(L"<w:semiHidden/>"); + oWriter.WriteString(L"<w:unhideWhenUsed/>"); + oWriter.WriteString(L"<w:noProof/>"); //отключение проверки орфографии + oWriter.WriteString(L"<w:b w:val=\"0\"/>"); + oWriter.WriteString(L"<w:bCs w:val=\"0\"/>"); + oWriter.WriteString(L"<w:i w:val=\"0\"/>"); + oWriter.WriteString(L"<w:iCs w:val=\"0\"/>"); + oWriter.WriteString(L"<w:color w:val=\"111111\"/>"); + oWriter.WriteString(L"</w:style>"); + + oWriter.WriteString(L"<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"TableNormal\">"); + oWriter.WriteString(L"<w:name w:val=\"Normal Table\"/>"); + oWriter.WriteString(L"<w:semiHidden/>"); + oWriter.WriteString(L"<w:unhideWhenUsed/>"); + oWriter.WriteString(L"<w:qFormat/>"); + oWriter.WriteString(L"<w:tblPr>"); + oWriter.WriteString(L"<w:tblInd w:w=\"0\" w:type=\"dxa\"/>"); + oWriter.WriteString(L"<w:tblCellMar>"); + oWriter.WriteString(L"<w:top w:w=\"0\" w:type=\"dxa\"/>"); + oWriter.WriteString(L"<w:left w:w=\"108\" w:type=\"dxa\"/>"); + oWriter.WriteString(L"<w:bottom w:w=\"0\" w:type=\"dxa\"/>"); + oWriter.WriteString(L"<w:right w:w=\"108\" w:type=\"dxa\"/>"); + oWriter.WriteString(L"</w:tblCellMar>"); + oWriter.WriteString(L"</w:tblPr>"); + oWriter.WriteString(L"</w:style>"); + + oWriter.WriteString(L"<w:style w:type=\"numbering\" w:default=\"1\" w:styleId=\"NoList\">"); + oWriter.WriteString(L"<w:name w:val=\"No List\"/>"); + oWriter.WriteString(L"<w:semiHidden/>"); + oWriter.WriteString(L"<w:unhideWhenUsed/>"); + oWriter.WriteString(L"<w:uiPriority w:val=\"99\"/>"); + oWriter.WriteString(L"</w:style>"); + + oWriter.WriteString(L"<w:style w:type=\"table\" w:styleId=\"TableGrid\">"); + oWriter.WriteString(L"<w:name w:val=\"Table Grid\"/>"); + oWriter.WriteString(L"<w:basedOn w:val=\"TableNormal\"/>"); + oWriter.WriteString(L"<w:tblPr>"); + oWriter.WriteString(L"<w:tblBorders>"); + oWriter.WriteString(L"<w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"<w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"<w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"<w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"<w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"<w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"auto\"/>"); + oWriter.WriteString(L"</w:tblBorders>"); + oWriter.WriteString(L"</w:tblPr>"); + oWriter.WriteString(L"</w:style>"); + + //oWriter.WriteString(L"<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/>"); + //oWriter.WriteString(L"</w:style>"); + + m_oFontStyleManager.ToXml(oWriter); + m_oParagraphStyleManager.ToXml(oWriter); + + oWriter.WriteString(L"</w:styles>"); + + 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..68006c1c596 100644 --- a/DocxRenderer/src/logic/Document.h +++ b/DocxRenderer/src/logic/Document.h @@ -1,16 +1,16 @@ #pragma once #include "Page.h" -#include "../DesktopEditor/common/Directory.h" -#include "../resources/resources.h" +#include "../../../DesktopEditor/common/Directory.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; + NSFonts::IApplicationFonts* m_pAppFonts; NSStructures::CPen m_oPen; NSStructures::CBrush m_oBrush; @@ -19,188 +19,189 @@ namespace NSDocxRenderer NSStructures::CEdgeText m_oEdge; NSStructures::CFont m_oInstalledFont; + Aggplus::CMatrix m_oTransform; - NSFonts::IFontManager* m_pFontManager {nullptr}; - Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; + CImageManager m_oImageManager; + CFontStyleManager m_oFontStyleManager; + CParagraphStyleManager m_oParagraphStyleManager; + CFontManager m_oFontManager; + CFontSelector m_oFontSelector; - Aggplus::CMatrix m_oTransform; - - LONG m_lCurrentCommandType {0}; - - LONG m_lClipMode; CPage m_oCurrentPage; - CImageManager m_oImageManager; - CStyleManager m_oStyleManager; + LONG m_lCurrentCommandType {0}; + LONG m_lClipMode; - 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}; + NSFonts::IFontManager* m_pFontManager {nullptr}; + Aggplus::CGraphicsPathSimpleConverter m_oSimpleGraphicsConverter; - bool m_bIsDisablePageCommand {false}; // disable commands inside draw function + std::map<LONG, NSStringUtils::CStringBuilder*> 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); + 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); + 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); + 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); + 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); + 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 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 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 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 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 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 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(const 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"<w:r>"); - oWriter.WriteString(L"<w:rPr>"); - - oWriter.WriteString(L"<w:noProof/>"); //отключение проверки орфографии - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - oWriter.WriteString(L"<w:b w:val=\"true\"/>"); - if (m_oFont.Italic) - oWriter.WriteString(L"<w:i w:val=\"true\"/>"); - - if (m_bIsNeedSpace) - { - m_dWidth += m_dSpaceWidthMM; - m_oText += L" "; - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - oWriter.WriteString(L"<w:b w:val=\"true\"/>"); - if (0x02 == (0x02 & m_lPickFontStyle)) - oWriter.WriteString(L"<w:i w:val=\"true\"/>"); - - 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<LONG>(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<LONG>(dSpacing); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - - if (lSpacing != 0) - { - oWriter.WriteString(L"<w:spacing w:val=\""); - oWriter.AddInt(lSpacing); - oWriter.WriteString(L"\"/>"); - } - } - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L"<w:emboss/>"); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L"<w:imprint/>"); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L"<w:outline/>"); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L"<w:shadow/>"); - } - } - - int lSize = static_cast<int>(2 * m_oFont.Size); - oWriter.WriteString(L"<w:sz w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/><w:szCs w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/>"); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L"<w:rFonts w:ascii=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:hAnsi=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:cs=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\"/>"); - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L"<w:vertAlign w:val=\"subscript\"/>"); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L"<w:vertAlign w:val=\"superscript\"/>"); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L"<w:color w:val=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1)); - oWriter.WriteString(L"\"/>"); - } - - if (m_oFont.Strikeout == TRUE) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L"<w:dstrike/>"); - } - else - { - oWriter.WriteString(L"<w:strike/>"); - } - } - - if (m_oFont.Underline == TRUE) - { - oWriter.WriteString(L"<w:u w:val="); - oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType)); - - if (m_lUnderlineColor != m_oBrush.Color1) - { - oWriter.WriteString(L" w:color=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); - } - - if (m_bIsHighlightPresent) - { - ColorTable& colorTable = SingletonInstance<ColorTable>(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L"<w:highlight w:val=\""); - oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor))); - } - else - { - oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); - } - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"</w:rPr>"); - - oWriter.WriteString(L"<w:t xml:space=\"preserve\">"); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L"</w:t>"); - - oWriter.WriteString(L"</w:r>"); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:r><w:rPr>"); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold && bIsNeedSaveFormat) - oWriter.WriteString(L"<w:b w:val=\"true\"/>"); - if (m_oFont.Italic && bIsNeedSaveFormat) - oWriter.WriteString(L"<w:i w:val=\"true\"/>"); - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L"<w:b w:val=\"true\"/>"); - if (0x02 == (0x02 & m_lPickFontStyle) && bIsNeedSaveFormat) - oWriter.WriteString(L"<w:i w:val=\"true\"/>"); - - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - int lSize = (int)(2 * m_oFont.Size); - oWriter.WriteString(L"<w:sz w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/><w:szCs w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/>"); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L"<w:rFonts w:ascii=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:hAnsi=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:cs=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"<w:color w:val=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1)); - oWriter.WriteString(L"\"/>"); - - LONG lSpacing = static_cast<LONG>((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lSpacing -= 1; - if (lSpacing != 0) - { - oWriter.WriteString(L"<w:spacing w:val=\""); - oWriter.AddInt(lSpacing); - oWriter.WriteString(L"\"/>"); - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor) - { - oWriter.WriteString(L"<w:color w:val=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1)); - oWriter.WriteString(L"\"/>"); - } - - if (m_oFont.Strikeout == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:strike/>"); - } - - if (m_oFont.Underline == TRUE && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:u w:val="); - oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType)); - - if (m_lUnderlineColor != m_oBrush.Color1) - { - oWriter.WriteString(L" w:color=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - ColorTable& colorTable = SingletonInstance<ColorTable>(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L"<w:highlight w:val=\""); - oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor))); - } - else - { - oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); - } - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"</w:rPr>"); - - oWriter.WriteString(L"<w:t xml:space=\"preserve\">"); - oWriter.WriteString(L" "); - oWriter.WriteString(L"</w:t>"); - - oWriter.WriteString(L"</w:r>"); - } - - 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<CParagraph*> 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 <map> - -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<std::wstring, CImageInfo> m_mapImagesFile; - std::map<DWORD, CImageInfo> 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..5c770a4ef8f 100644 --- a/DocxRenderer/src/logic/Page.cpp +++ b/DocxRenderer/src/logic/Page.cpp @@ -1,1549 +1,1657 @@ #include "Page.h" #include "../resources/Constants.h" -#include "../resources/SortElements.h" +#include "../resources/SingletonTemplate.h" #include "../resources/utils.h" #include <memory> 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<CImageInfo> 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<CImageInfo> 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); + CPage::CPage(NSFonts::IApplicationFonts* 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, + CFontStyleManager* pFontStyleManager, + CFontManager *pFontManager, + CFontSelector* pFontSelector, + CParagraphStyleManager* pParagraphStyleManager) + { + m_pFont = pFont; + m_pPen = pPen; + m_pBrush = pBrush; + m_pShadow = pShadow; + m_pEdgeText = pEdge; + + m_pTransform = pMatrix; + m_pSimpleGraphicsConverter = pSimple; + + m_pFontStyleManager = pFontStyleManager; + m_pFontManager = pFontManager; + m_pFontSelector = pFontSelector; + m_pParagraphStyleManager = pParagraphStyleManager; + + m_pCurrentLine = nullptr; + + CShape::ResetRelativeHeight(); + } + + void CPage::BeginCommand(DWORD lType) + { + m_lLastCommand = m_lCurrentCommand; + m_lCurrentCommand = lType; + } + + void CPage::Clear() + { + m_arConts.clear(); + m_arTextLines.clear(); + m_arDiacriticalSymbols.clear(); + m_arImages.clear(); + m_arShapes.clear(); + m_arOutputObjects.clear(); + + m_pCurrentLine = nullptr; + m_oVector.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<CImageInfo> pInfo, double& fX, double& fY, double& fWidth, double& fHeight) + { + auto pImage = std::make_shared<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::PathStart() + { + } + + void CPage::PathEnd() + { + m_oVector.End(); + } + + void CPage::PathClose() + { + m_oVector.Close(); + } + + + void CPage::DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo) + { + double dLeft, dRight, dTop, dBottom; + dLeft = m_oVector.GetLeft(); + dRight = m_oVector.GetRight(); + dTop = m_oVector.GetTop(); + dBottom = m_oVector.GetBottom(); + if ((dLeft <= dRight) && (dTop <= dBottom)) + { + if (!m_arShapes.empty()) + { + auto& pLastShape = m_arShapes.back(); + + if (pLastShape->m_dLeft == dLeft && + pLastShape->m_dTop == dTop && + pLastShape->m_dWidth == dRight - dLeft && + pLastShape->m_dHeight == dBottom - 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 = std::make_shared<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(dLeft - dRight) < 0.3) || (fabs(dTop - dBottom) < 0.3)) + { + pShape->m_oPen.Color = m_pBrush->Color1; + pShape->m_oPen.Alpha = m_pBrush->Alpha1; + } + } 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<CShape*> 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<COldShape>(); - 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"<w:p>"); - //note при удалении строки откуда-то добавляется <w:p/> в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L"<w:pPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr>"); - - for (size_t i = 0; i < m_arImages.size(); i++) - { - m_arImages[i]->ToXml(oWriter); - } - - oWriter.WriteString(L"</w:p>"); - } - - // drawings - if (!m_arShapes.empty()) - { - oWriter.WriteString(L"<w:p>"); - //note при удалении строки откуда-то добавляется <w:p/> в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст - oWriter.WriteString(L"<w:pPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr>"); - - for (size_t i = 0; i < m_arShapes.size(); i++) - { - m_arShapes[i]->ToXml(oWriter); - } - - oWriter.WriteString(L"</w:p>"); - } - - 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"<w:p><w:pPr><w:sectPr>"); - else - oWriter.WriteString(L"<w:sectPr>"); - - oWriter.WriteString(L"<w:pgSz w:w=\""); - oWriter.AddInt((int)(m_dWidth * c_dMMToDx)); - oWriter.WriteString(L"\" w:h=\""); - oWriter.AddInt((int)(m_dHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:orient=\""); - (lWidthDx >= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); - oWriter.WriteString(L"\"/>"); - - if (!bLastPage) - oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\"/></w:sectPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr></w:p>"); - else - oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\" w:header=\"0\" w:footer=\"0\" w:gutter=\"0\"/></w:sectPr>"); - } + + pShape->SetVector(std::move(m_oVector)); + m_arShapes.push_back(pShape); + } + } + + 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) + { + // 9 - \t + if (pUnicodes != nullptr && nCount == 1 && (IsSpaceUtf32(*pUnicodes) || *pUnicodes == 9)) + { + //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); + + 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] = ' '; + + // иногда приходит неверный? размер, нужно перемерить (XPS) + if(m_bIsRecalcFontSize) + { + m_pFont->Size *= ((m_pTransform->sx() + m_pTransform->sy()) / 2); + m_bIsRecalcFontSize = false; + } + m_pFontManager->LoadFontByFile(*m_pFont); + + // закомментив это, все гуд + //if (fabs(dTextW) < 0.01 || (dTextW > 10)) + //{ + + double _x = 0; + double _y = 0; + double _w = 0; + double _h = 0; + + if (nullptr != pGids) + { + m_pFontManager->SetStringGid(1); + m_pFontManager->MeasureStringGids(pGids, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + else + { + // такого быть не должно (только из xps) + m_pFontManager->SetStringGid(0); + m_pFontManager->MeasureStringGids(pUnicodes, nCount, dTextX, dTextY, _x, _y, _w, _h, CFontManager::mtPosition); + } + + //} + double dBaseLinePos = dTextY + fBaseLineOffset; + + auto pCont = std::make_shared<CContText>(m_pFontManager); + + auto oMetrics = m_pFontManager->GetFontMetrics(); + auto oParams = m_pFontManager->GetFontSelectParams(); + + // use forced fold option + bool bForcedBold = oParams.bDefaultBold; + if (m_lCurrentCommand == c_nStrokeTextType && m_pFont->Bold) + bForcedBold = true; + + m_pFontSelector->SelectFont(oParams, oMetrics, oText); + _h = m_pFontManager->GetFontHeight(); + + pCont->m_dBaselinePos = dBaseLinePos; + pCont->m_dTop = pCont->m_dBaselinePos - _h; + pCont->m_dHeight = pCont->m_dBaselinePos - pCont->m_dTop; + + pCont->m_dLeft = dTextX; + pCont->m_dWidth = _w; + pCont->m_dRight = dTextX + _w; + + pCont->m_oText = oText; + + double font_size = m_pFont->Size; + double em_height = oMetrics.dEmHeight; + double ratio = font_size / em_height * c_dPixToMM; + + pCont->m_dTopWithAscent = pCont->m_dBaselinePos - (oMetrics.dAscent * ratio) - oMetrics.dBaselineOffset; + pCont->m_dBotWithDescent = pCont->m_dBaselinePos + (oMetrics.dDescent * ratio) - oMetrics.dBaselineOffset; + + // первичное получение стиля для текущего символа + // при дальнейшем анализе может измениться + pCont->m_pFontStyle = m_pFontStyleManager->GetOrAddFontStyle(*m_pBrush, + m_pFontSelector->GetSelectedName(), + m_pFont->Size, + m_pFontSelector->IsSelectedItalic(), + m_pFontSelector->IsSelectedBold() || bForcedBold); + + pCont->m_dSpaceWidthMM = m_pFontManager->GetSpaceWidthMM(); + + if (m_bUseDefaultFont) + { + pCont->m_oSelectedFont.Path = m_pFont->Path; + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.FaceIndex = m_pFont->FaceIndex; + } + else + { + pCont->m_oSelectedFont.Name = m_pFontSelector->GetSelectedName(); + pCont->m_oSelectedFont.Size = m_pFont->Size; + pCont->m_oSelectedFont.Bold = m_pFontSelector->IsSelectedBold(); + pCont->m_oSelectedFont.Italic = m_pFontSelector->IsSelectedItalic(); + } + pCont->m_bWriteStyleRaw = m_bWriteStyleRaw; + m_pParagraphStyleManager->UpdateAvgFontSize(m_pFont->Size); + m_arConts.push_back(pCont); + } + + void CPage::AddContToTextLine(std::shared_ptr<CContText> pCont) + { + if (nullptr == m_pCurrentLine) + { + auto pLine = std::make_shared<CTextLine>(); + m_pCurrentLine = pLine.get(); + m_pCurrentLine->AddCont(pCont); + m_arTextLines.push_back(pLine); + return; + } + + if (fabs(m_pCurrentLine->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine->AddCont(pCont); + return; + } + + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + if (fabs(m_arTextLines[i]->m_dBaselinePos - pCont->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + m_pCurrentLine = m_arTextLines[i].get(); + m_pCurrentLine->AddCont(pCont); + return; + } + } + + auto pLine = std::make_shared<CTextLine>(); + m_pCurrentLine = pLine.get(); + m_pCurrentLine->AddCont(pCont); + m_arTextLines.push_back(pLine); + } + + void CPage::Analyze() + { + // build m_arDiacriticalSymbols + BuildDiacriticalSymbols(); + + // build text lines from m_arConts + BuildTextLines(); + + // analyze shapes (get type of lines etc) + AnalyzeShapes(); + + // analyze text lines and conts inside + AnalyzeTextLines(); + + // merge conts in text lines + BuildLines(); + + // calc sizes on selected fonts for m_arConts + CalcSelected(); + + // build paragraphs from m_arTextLines + BuildParagraphes(); + + // merge shapes + MergeShapes(); + } + + void CPage::Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage) + { + ToXml(oWriter); + WriteSectionToFile(bIsLastPage, oWriter); + } + + void CPage::BuildDiacriticalSymbols() + { + for (size_t i = 0; i < m_arConts.size(); i++) + if (m_arConts[i] && m_arConts[i]->m_oText.length() == 1 && IsDiacriticalMark(m_arConts[i]->m_oText[0])) + m_arDiacriticalSymbols.push_back(std::move(m_arConts[i])); + + } + void CPage::BuildTextLines() + { + using cont_ptr_t = std::shared_ptr<CContText>; + 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; + + if (fabs(a->m_dBaselinePos - b->m_dBaselinePos) <= c_dTHE_SAME_STRING_Y_PRECISION_MM) + return a->m_dLeft < b->m_dLeft; + + return a->m_dBaselinePos < b->m_dBaselinePos; + }); + + for (auto& cont : m_arConts) + if (cont) + AddContToTextLine(cont); + } + + void CPage::MergeShapes() + { + if (m_arShapes.empty()) + return; + + using shape_ref_ptr_t = std::reference_wrapper<std::shared_ptr<CShape>>; + 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::CalcSelected() + { + for (auto& cont : 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() + { + //BuildTables(); + DetermineLinesType(); + } + + void CPage::DetermineLinesType() + { + using shape_ptr_t = std::shared_ptr<CShape>; + 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; + }); + + 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<size_t> 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::AnalyzeTextLines() + { + // вся логика основана на отсортированных списках объектов + using line_ptr_t = std::shared_ptr<CTextLine>; + 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; + }); + + // analyze drop caps (creates shapes) + AnalyzeDropCaps(); + + // analyze conts in text lines + AnalyzeConts(); + + // assign highlights to conts & delete shapes which is uses in highlights + DetermineStrikeoutsUnderlinesHighlights(); + + // diacritical symbols + AddDiacriticalSymbols(); + + // super/subscript + MergeLinesByVertAlignType(); + + // delete lines out of page + DeleteTextClipPage(); + } + + void CPage::AnalyzeDropCaps() + { + double avg_font_size = m_pParagraphStyleManager->GetAvgFontSize(); + + std::vector<std::pair<std::shared_ptr<CContText>&, std::shared_ptr<CTextLine>&>> possible_caps; + std::vector<std::shared_ptr<CDropCap>> 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->m_oText.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_dBaselinePos - drop_cap_cont->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM) + { + num_of_lines++; + break; + } + + if (line->m_dBaselinePos > drop_cap_cont->m_dBaselinePos) + break; + + if (fabs(line->m_dTop - drop_cap_cont->m_dTop) > c_dTHE_SAME_STRING_Y_PRECISION_MM && line->m_dTop < drop_cap_cont->m_dTop) + continue; + + num_of_lines++; + } + if (num_of_lines > 1) + { + auto drop_cap = std::make_shared<CDropCap>(); + *static_cast<CBaseItem*>(drop_cap.get()) = *drop_cap_cont; + drop_cap->nLines = num_of_lines; + drop_cap->wsFont = drop_cap_cont->m_pFontStyle->wsFontName; + drop_cap->wsText = drop_cap_cont->m_oText.ToStdWString(); + + drop_cap->nFontSize = static_cast<LONG>(drop_cap_cont->m_pFontStyle->dFontSize * 2); + drop_caps.push_back(std::move(drop_cap)); + + drop_cap_cont = nullptr; + if (drop_cap_line->IsCanBeDeleted()) + drop_cap_line = nullptr; + + if (drop_cap_line) + drop_cap_line->RecalcSizes(); + } + } + + // шейпы из буквиц + for (auto&& drop_cap : drop_caps) + { + auto shape = std::make_shared<CShape>(); + shape->m_eType = CShape::eShapeType::stTextBox; + + // перемерим на подобранном шрифте + NSStructures::CFont oFont; + oFont.Name = drop_cap->wsFont; + oFont.Size = static_cast<double>(drop_cap->nFontSize) / 2.0; + m_pFontManager->LoadFontByName(oFont); + + auto metrics = m_pFontManager->GetFontMetrics(); + auto h = m_pFontManager->GetFontHeight(); + + shape->m_dTop = drop_cap->m_dTop; + shape->m_dBaselinePos = drop_cap->m_dTop + h; + shape->m_dHeight = shape->m_dBaselinePos - shape->m_dTop; + + shape->m_dRight = drop_cap->m_dRight; + shape->m_dLeft = drop_cap->m_dLeft; + shape->m_dWidth = drop_cap->m_dWidth; + + shape->m_arOutputObjects.push_back(drop_cap); + shape->m_bIsBehindDoc = false; + 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)) + { + pNextCont = nullptr; + pCurrCont->m_iNumDuplicates++; + } + } + if(pNextLine && pNextLine->IsCanBeDeleted()) + pNextLine = nullptr; + } + } + if(pCurrLine && pCurrLine->IsCanBeDeleted()) + pCurrLine = nullptr; + } + } + + void CPage::DetermineStrikeoutsUnderlinesHighlights() + { + // определение различных эффектов на основании взаимного расположения символов и шейпов + 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& pCurrLine = m_arTextLines[j]; + if (!pCurrLine || (pCurrLine->AreObjectsNoCrossingByVertically(shape.get()) && + (pCurrLine->m_dTop > shape->m_dBaselinePos || + pCurrLine->m_dBaselinePos + pCurrLine->m_dHeight < shape->m_dTop))) + { + continue; + } + + for (size_t k = 0; k < pCurrLine->m_arConts.size(); ++k) + { + if(!shape) + break; + + auto& curr_cont = pCurrLine->m_arConts[k]; + if (!curr_cont) + continue; + + eVerticalCrossingType eVType = curr_cont->CBaseItem::GetVerticalCrossingType(shape.get()); + eHorizontalCrossingType eHType = curr_cont->GetHorizontalCrossingType(shape.get()); + + bool bIsNotComplicatedFigure = shape->m_eGraphicsType != eGraphicsType::gtComplicatedFigure; + bool bIsLineCrossingText = IsLineCrossingText(shape.get(), curr_cont.get(), eHType); + bool bIsItHighlightingBackground = IsItHighlightingBackground(shape.get(), curr_cont.get(), eHType); + bool bIsLineBelowText = IsLineBelowText(shape.get(), curr_cont.get(), eHType); + + if (bIsLineCrossingText) + { + curr_cont->m_bIsStrikeoutPresent = true; + if (shape->m_eLineType == eLineType::ltDouble) + curr_cont->m_bIsDoubleStrikeout = true; + } + + else if (bIsItHighlightingBackground) + { + //Удовлетворяет расположением и размером - привязываем указатель на картинку + curr_cont->m_pShape = shape; + curr_cont->m_bIsHighlightPresent = true; + curr_cont->m_lHighlightColor = shape->m_oBrush.Color1; + } + + else if (bIsLineBelowText) + { + 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; + } + + // проверили - удаляем + if (bIsNotComplicatedFigure && (bIsLineCrossingText || bIsLineBelowText || bIsItHighlightingBackground)) + shape_used = true; + + if (!bIsNotComplicatedFigure) + { + bool bIf1 = curr_cont->m_pFontStyle->oBrush.Color1 == c_iGreyColor; + bool bIf2 = curr_cont->m_bIsShadowPresent && curr_cont->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) + { + auto oBrush = curr_cont->m_pFontStyle->oBrush; + oBrush.Color1 = shape->m_oPen.Color; + + curr_cont->m_pFontStyle = m_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; + } + shape_used = true; + } + } + } + } + if(shape_used) + shape = nullptr; + } + } + + bool CPage::IsLineCrossingText(const CShape *pShape, CContText *pCont, const eHorizontalCrossingType& eHType) + { + // Height - это максимально возможный размер символа. Больше реального размера. + double dTopBorder = pCont->m_dTop + pCont->m_dHeight / 3; + + 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; + + return bIf1 && bIf2 && bIf3 && bIf4; + } + + 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; + + //Условие по вертикали + 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 = eHType != eHorizontalCrossingType::hctUnknown && + eHType != eHorizontalCrossingType::hctCurrentLeftOfNext && + eHType != eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext && + eHType != 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::IsItHighlightingBackground(const 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->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; + } + + 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->m_oText += d_sym->m_oText; + } + else if (bIf3 && bIf7) + { + NSStringUtils::CStringUTF32 oText(d_sym->m_oText); + oText += cont->m_oText; + cont->m_oText = oText; + } + d_sym = nullptr; + isBreak = true; + break; + } + } + if (isBreak) + break; + } + } + } + + void CPage::MergeLinesByVertAlignType() + { + for (auto& line : m_arTextLines) + { + if (!line) + continue; + + if (line->m_eVertAlignType == eVertAlignType::vatSuperscript + || line->m_eVertAlignType == eVertAlignType::vatSubscript) + { + std::shared_ptr<CTextLine>& 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) + { + bool bIsTextShapePresent = false; + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + if (m_arOutputObjects[i]->m_eType == COutputObject::eOutputType::etShape) + { + bIsTextShapePresent = true; + break; + } + } + + bool bIsNeedWP = bIsTextShapePresent || !m_arImages.empty() || !m_arShapes.empty(); + + if (bIsNeedWP) + { + oWriter.WriteString(L"<w:p>"); + //note при удалении строки откуда-то добавляется <w:p/> в начале страницы (если есть графика и текст), что добавляет дополнительную строку и сдвигает текст + oWriter.WriteString(L"<w:pPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr>"); + } + + for (const auto& image : m_arImages) + if (image) + image->ToXml(oWriter); + + + for (const auto& shape : m_arShapes) + if (shape) + shape->ToXml(oWriter); + + if (bIsNeedWP) + { + oWriter.WriteString(L"</w:p>"); + } + + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto& pObj = m_arOutputObjects[i]; + CParagraph* pParagraph = nullptr; + if((pParagraph = dynamic_cast<CParagraph*>(pObj.get())) != nullptr) + pParagraph->ToXml(oWriter); + } + } + + void CPage::BuildLines() + { + for (size_t i = 0; i < m_arTextLines.size(); ++i) + { + auto& pCurrLine = m_arTextLines[i]; + if (!pCurrLine) + continue; + + for (size_t j = 0; j < pCurrLine->m_arConts.size(); ++j) + { + auto& pCurrCont = pCurrLine->m_arConts[j]; + if (!pCurrCont) + continue; + + if (pCurrCont->m_iNumDuplicates > 0) + pCurrLine->m_iNumDuplicates = std::max(pCurrLine->m_iNumDuplicates, pCurrCont->m_iNumDuplicates); + } + pCurrLine->MergeConts(); + } + DetermineDominantGraphics(); + } + + void CPage::DetermineDominantGraphics() + { + std::shared_ptr<CShape> 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; + } + } + void CPage::BuildParagraphes() + { + 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 (curr_line->m_iNumDuplicates > 0) + { + size_t duplicates = curr_line->m_iNumDuplicates; + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + while (duplicates > 0) + { + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + duplicates--; + } + 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)) + { + m_arShapes.push_back(CreateSingleLineShape(prev_line)); + m_arShapes.push_back(CreateSingleLineShape(curr_line)); + prev_line = nullptr; + curr_line = nullptr; + continue; + } + } + } + + + if (m_arTextLines.empty()) + return; + + // переместим nullptr в конец и удалим + auto right = MoveNullptr(m_arTextLines.begin(), m_arTextLines.end()); + m_arTextLines.erase(right, m_arTextLines.end()); + + using line_ptr_t = std::shared_ptr<CTextLine>; + 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; + }); + + if (m_arTextLines.empty()) + return; + + auto build = [this] (const std::vector<std::shared_ptr<CTextLine>>& text_lines) { + std::vector<std::shared_ptr<CParagraph>> ar_paragraphs; + + double avg_spacing{0.0}; + size_t avg_spacing_n{0}; + + double min_left{m_dWidth}; + double max_right{0.0}; + + // совпадает ли left, right, center со строкой ниже + struct Position { + bool left{false}; + bool center{false}; + bool right{false}; + }; + + // параграф будет набиваться строчками + auto paragraph = std::make_shared<CParagraph>(); + + // lamda to setup and add paragpraph + auto add_paragraph = [this, &max_right, &min_left, &ar_paragraphs] (std::shared_ptr<CParagraph>& 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 - max_right; + 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_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; + + // первая строчка левее правой + if (!first_left && prev_line->m_dLeft < curr_line->m_dLeft) + position_curr.left = false; + } + 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) + { + paragraph->m_bIsNeedFirstLineIndent = true; + paragraph->m_dFirstLine = paragraph->m_arLines[0]->m_dLeft - paragraph->m_dLeft; + } + } + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + if (ar_paragraphs.empty()) + paragraph->m_dSpaceBefore = paragraph->m_dTop + c_dCORRECTION_FOR_FIRST_PARAGRAPH; + else + paragraph->m_dSpaceBefore = paragraph->m_dTop - ar_paragraphs.back()->m_dBaselinePos; + } + + ar_paragraphs.push_back(std::move(paragraph)); + paragraph = std::make_shared<CParagraph>(); + + 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] (std::shared_ptr<CParagraph>& paragraph, std::shared_ptr<CTextLine>& 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); + }; + + // 1 строчка в параграфе + if (m_eTextAssociationType == TextAssociationType::tatPlainLine || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for (auto& curr_line : m_arTextLines) + { + add_line(paragraph, curr_line); + add_paragraph(paragraph); + } + } + + else if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatParagraphToShape) + { + // ar_spacing[index]- расстояние строки до строки снизу + // если 0.0 - строка последняя + std::vector<double> ar_spacings(m_arTextLines.size(), 0.0); + + // позиции относительно других линий + std::vector<Position> ar_positions(m_arTextLines.size()); + + // требуется ли отступ + std::vector<bool> ar_indents(m_arTextLines.size(), false); + + // если ar_delims[index] == true, после строчки index нужно начинать новый параграф + std::vector<bool> ar_delims(m_arTextLines.size(), false); + + // calcs spacings & positions + for (size_t index = 0; index < m_arTextLines.size() - 1; ++index) + { + ar_spacings[index] = m_arTextLines[index + 1]->m_dBaselinePos - m_arTextLines[index]->m_dTop; + avg_spacing = (avg_spacing / (avg_spacing_n + 1)) * avg_spacing_n + (ar_spacings[index] / (avg_spacing_n + 1)); + + auto& left_curr = m_arTextLines[index]->m_dLeft; + auto& left_next = m_arTextLines[index + 1]->m_dLeft; + + auto& right_curr = m_arTextLines[index]->m_dRight; + auto& right_next = m_arTextLines[index + 1]->m_dRight; + + auto center_curr = (m_arTextLines[index]->m_dLeft + m_arTextLines[index]->m_dWidth / 2); + auto center_next = (m_arTextLines[index + 1]->m_dLeft + m_arTextLines[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; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position& position = ar_positions[index]; + + auto& line_top = m_arTextLines[index]; + auto& line_bot = m_arTextLines[index + 1]; + + if (index == 0 || ar_delims[index - 1]) + is_first_line = true; + else + is_first_line = false; + + // первая строка может быть с отступом + if (is_first_line && line_bot->m_dLeft < line_top->m_dLeft) + { + // если больше трех линий - проверим третью + 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; + } + + bool is_unknown = !((position.left || ar_indents[index]) || position.right || position.center); + if (is_unknown) + 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 = m_arTextLines[0]->m_dRight; + double curr_min_left = m_arTextLines[0]->m_dLeft; + for (size_t index = 0; index < ar_positions.size() - 1; ++index) + { + Position position = ar_positions[index]; + auto& line_top = m_arTextLines[index]; + auto& line_bot = m_arTextLines[index + 1]; + + if (ar_delims[index]) + { + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; + continue; + } + + std::shared_ptr<CContText> cont = line_bot->m_arConts[0]; + double line_with_first_right = line_top->m_dRight + cont->m_dFirstWordWidth; + double line_with_first_left = line_top->m_dLeft - cont->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) + { +// if (diff > -c_dERROR_GAP) +// { +// auto& last_cont = line_top->m_arConts[line_top->m_arConts.size() - 1]; +// last_cont->m_bIsAddBrEnd = true; +// } +// else + continue; + } + else + { + ar_delims[index] = true; + curr_max_right = line_bot->m_dRight; + curr_min_left = line_bot->m_dLeft; + } + } + + // на основе ar_delims разбиваем на параграфы + for (size_t index = 0; index < ar_delims.size(); ++index) + { + add_line(paragraph, m_arTextLines[index]); + if (ar_delims[index] || index == ar_delims.size() - 1) + add_paragraph(paragraph); + } + } + + return ar_paragraphs; + }; + + std::vector<std::shared_ptr<CParagraph>> ar_paragraphs; + + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + ar_paragraphs = build(m_arTextLines); + } + + else if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + ar_paragraphs = build(m_arTextLines); + } + + using paragraph_ptr_t = std::shared_ptr<CParagraph>; + 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; + }); + + if (m_eTextAssociationType == TextAssociationType::tatPlainParagraph || + m_eTextAssociationType == TextAssociationType::tatPlainLine) + { + for(auto&& p : ar_paragraphs) + m_arOutputObjects.push_back(std::move(p)); + } + + else if (m_eTextAssociationType == TextAssociationType::tatParagraphToShape || + m_eTextAssociationType == TextAssociationType::tatShapeLine) + { + for(auto&& p : ar_paragraphs) + m_arShapes.push_back(CreateSingleParagraphShape(p)); + } + } + + std::shared_ptr<CShape> CPage::CreateSingleLineShape(std::shared_ptr<CTextLine>& pLine) + { + auto pParagraph = std::make_shared<CParagraph>(); + + 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; + + if (pLine->m_pDominantShape) + { + pParagraph->m_bIsShadingPresent = true; + pParagraph->m_lColorOfShadingFill = pLine->m_pDominantShape->m_oBrush.Color1; + pParagraph->RemoveHighlightColor(); + } + + auto pShape = std::make_shared<CShape>(); + 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; + } + + std::shared_ptr<CShape> CPage::CreateSingleParagraphShape(std::shared_ptr<CParagraph>& pParagraph) + { + std::shared_ptr<CShape> pShape; + + pShape = std::make_shared<CShape>(); + + 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; + + 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) + { + // section + int lWidthDx = (int)(m_dWidth * c_dMMToDx); + int lHeightDx = (int)(m_dHeight * c_dMMToDx); + + if (!bLastPage) + oWriter.WriteString(L"<w:p><w:pPr><w:sectPr>"); + else + oWriter.WriteString(L"<w:sectPr>"); + + oWriter.WriteString(L"<w:pgSz w:w=\""); + oWriter.AddInt((int)(m_dWidth * c_dMMToDx)); + oWriter.WriteString(L"\" w:h=\""); + oWriter.AddInt((int)(m_dHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:orient=\""); + (lWidthDx >= lHeightDx) ? oWriter.WriteString(L"landscape") : oWriter.WriteString(L"portrait"); + oWriter.WriteString(L"\"/>"); + + if (!bLastPage) + oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\"/></w:sectPr><w:spacing w:line=\"1\" w:lineRule=\"exact\"/></w:pPr></w:p>"); + else + oWriter.WriteString(L"<w:pgMar w:top=\"0\" w:right=\"0\" w:bottom=\"0\" w:left=\"0\" w:header=\"0\" w:footer=\"0\" w:gutter=\"0\"/></w:sectPr>"); + } } diff --git a/DocxRenderer/src/logic/Page.h b/DocxRenderer/src/logic/Page.h index 98cb0d94dbc..594bd18bb80 100644 --- a/DocxRenderer/src/logic/Page.h +++ b/DocxRenderer/src/logic/Page.h @@ -1,128 +1,142 @@ #pragma once -#include "../DesktopEditor/graphics/pro/Graphics.h" -#include "elements/OldShape.h" +#include "../../../DesktopEditor/graphics/pro/Graphics.h" #include "elements/Paragraph.h" #include "elements/Shape.h" -#include "managers/StyleManager.h" +#include "managers/FontStyleManager.h" +#include "managers/ParagraphStyleManager.h" +#include "styles/ParagraphStyle.h" +#include "elements/DropCap.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<CShape*> m_arImages; - std::vector<CContText*> m_arSymbol ; - std::vector<CTextLine*> m_arTextLine; - std::vector<CShape*> m_arShapes; - std::vector<CParagraph*> 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<CImageInfo> 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<CImageInfo> 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); - - 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); - }; + class CPage + { + public: + double m_dWidth {0.0}; + double m_dHeight {0.0}; + + LONG m_lCurrentCommand {0}; + + TextAssociationType m_eTextAssociationType {TextAssociationType::tatPlainParagraph}; + + bool m_bUseDefaultFont{false}; + bool m_bWriteStyleRaw {false}; + + 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}; + + CFontStyleManager* m_pFontStyleManager {nullptr}; + CParagraphStyleManager* m_pParagraphStyleManager{nullptr}; + CFontManager* m_pFontManager {nullptr}; + CFontSelector* m_pFontSelector {nullptr}; + CVectorGraphics m_oVector; + + std::vector<std::shared_ptr<CContText>> m_arConts; + std::vector<std::shared_ptr<CTextLine>> m_arTextLines; + std::vector<std::shared_ptr<CContText>> m_arDiacriticalSymbols; + std::vector<std::shared_ptr<CShape>> m_arImages; + std::vector<std::shared_ptr<CShape>> m_arShapes; + + std::vector<std::wstring> m_arCompleteObjectsXml; + + std::vector<std::shared_ptr<COutputObject>> m_arOutputObjects; + + CTextLine* m_pCurrentLine {nullptr}; + + bool m_bIsDeleteTextClipPage {true}; + bool m_bIsRecalcFontSize {true}; + LONG m_lLastCommand = 0; + + 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, + CFontStyleManager* pStyleManager, + CFontManager *pFontManager, + CFontSelector* pFontSelector, + CParagraphStyleManager* pParagraphStyleManager); + + void BeginCommand(DWORD lType); + void Clear(); + + //удаляем то, что выходит за границы страницы + void DeleteTextClipPage(); + + // image commands + //набивается содержимым вектор m_arImages + void WriteImage(const std::shared_ptr<CImageInfo> 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 PathStart(); + void PathEnd(); + void PathClose(); + + //набивается содержимым вектор m_arShapes + void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> 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); + + void Analyze(); + void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage); + + private: + // methods to build text lines + void BuildDiacriticalSymbols(); + void BuildTextLines(); + void AddContToTextLine(std::shared_ptr<CContText> pCont); + + void AnalyzeTextLines(); + void AnalyzeConts(); + void DetermineStrikeoutsUnderlinesHighlights(); + + void AnalyzeDropCaps(); + void AddDiacriticalSymbols(); + void MergeLinesByVertAlignType(); + void DetermineTextColumns(); + + bool IsLineCrossingText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsLineBelowText(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + bool IsItHighlightingBackground(const CShape* pGraphicItem, CContText* pCont, const eHorizontalCrossingType& eHType); + + void AnalyzeShapes(); + void DetermineLinesType(); + + void BuildLines(); + void DetermineDominantGraphics(); + + void BuildParagraphes(); + + std::shared_ptr<CShape> CreateSingleLineShape(std::shared_ptr<CTextLine>& pLine); + std::shared_ptr<CShape> CreateSingleParagraphShape(std::shared_ptr<CParagraph>& pParagraph); + + void MergeShapes(); + void CalcSelected(); + + // конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку + void ToXml(NSStringUtils::CStringBuilder& oWriter); + void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter); + }; } diff --git a/DocxRenderer/src/logic/elements/BaseItem.cpp b/DocxRenderer/src/logic/elements/BaseItem.cpp index 333d9d9932e..a5cc55b0b15 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.cpp +++ b/DocxRenderer/src/logic/elements/BaseItem.cpp @@ -4,123 +4,159 @@ 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_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; - 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; + } - return *this; - } + 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_Y_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_Y_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_Y_PRECISION_MM && + fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_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::IsBigger(const CBaseItem* oSrc) - { - return (m_dLeft > oSrc->m_dLeft) ? true : false; - } + bool CBaseItem::AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept + { + eVerticalCrossingType eVType = GetVerticalCrossingType(pObj); - bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dLeft >= oSrc->m_dLeft) ? true : false; - } + return (eVType == eVerticalCrossingType::vctNoCrossingCurrentAboveNext || + eVType == eVerticalCrossingType::vctNoCrossingCurrentBelowNext); + } + bool CBaseItem::AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept + { + eHorizontalCrossingType eHType = GetHorizontalCrossingType(pObj); - 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; - } - } + return (eHType == eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext || + eHType == eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext); + } - 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; - } - } + void CBaseItem::RecalcWithNewItem(const CBaseItem* pItem) + { + m_dBaselinePos = std::max(m_dBaselinePos, pItem->m_dBaselinePos); + + if ((pItem->m_dLeft < m_dLeft) || (pItem->m_dLeft > 0 && m_dLeft == 0.0)) + m_dLeft = pItem->m_dLeft; + + if ((pItem->m_dRight > m_dRight) || (pItem->m_dRight > 0 && m_dRight == 0.0)) + m_dRight = pItem->m_dRight; + + if (m_dTop > pItem->m_dTop || m_dTop == 0.0) + m_dTop = pItem->m_dTop; + + m_dWidth = m_dRight - m_dLeft; + m_dHeight = m_dBaselinePos - m_dTop; + } + + COutputObject& COutputObject::operator= (const COutputObject& oObj) + { + m_eType = oObj.m_eType; + return *this; + } } diff --git a/DocxRenderer/src/logic/elements/BaseItem.h b/DocxRenderer/src/logic/elements/BaseItem.h index 23525509115..9632d1abfe5 100644 --- a/DocxRenderer/src/logic/elements/BaseItem.h +++ b/DocxRenderer/src/logic/elements/BaseItem.h @@ -1,91 +1,88 @@ #pragma once -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" +#include "../../resources/Constants.h" +#include <vector> +#include <memory> namespace NSDocxRenderer { - enum class eVerticalCrossingType - { - vctUnknown, - vctCurrentInsideNext, - vctCurrentOutsideNext, - vctCurrentAboveNext, - vctCurrentBelowNext, - vctDublicate, - vctTopBordersMatch, - vctBottomBordersMatch, - vctNoCrossingCurrentAboveNext, - vctNoCrossingCurrentBelowNext - }; + // взаимное расположение по вертикали со следующим объектом + enum class eVerticalCrossingType + { + vctUnknown, + vctCurrentInsideNext, + vctCurrentOutsideNext, + vctCurrentAboveNext, + vctCurrentBelowNext, + vctDublicate, + vctTopAndBottomBordersMatch, + vctTopBorderMatch, + vctBottomBorderMatch, + vctNoCrossingCurrentAboveNext, + vctNoCrossingCurrentBelowNext + }; - enum class eHorizontalCrossingType - { - hctUnknown, - hctCurrentInsideNext, - hctCurrentOutsideNext, - hctCurrentLeftOfNext, - hctCurrentRightOfNext, - hctDublicate, - hctLeftBordersMatch, - hctRightBordersMatch, - hctNoCrossingCurrentLeftOfNext, - hctNoCrossingCurrentRightOfNext - }; + // взаимное расположение по горизонтали со следующим объектом + enum class eHorizontalCrossingType + { + hctUnknown, + hctCurrentInsideNext, + hctCurrentOutsideNext, + hctCurrentLeftOfNext, + hctCurrentRightOfNext, + hctDublicate, + hctLeftAndRightBordersMatch, + hctLeftBorderMatch, + hctRightBorderMatch, + hctNoCrossingCurrentLeftOfNext, + hctNoCrossingCurrentRightOfNext + }; - class CBaseItem - { - public: - enum class ElemType - { - etContText = 0, - etTextLine = 1, - etParagraph = 2, - etImage = 3, - etShape = 4, - etOldShape = 5, - }; + class CBaseItem + { + public: + double m_dTop {0.0}; + double m_dBaselinePos {0.0}; + double m_dHeight {0.0}; - ElemType m_eType; + double m_dLeft {0.0}; + double m_dRight {0.0}; + double m_dWidth {0.0}; - bool m_bIsNotNecessaryToUse {false}; + CBaseItem() = default; + virtual ~CBaseItem() = default; - //General - double m_dLeft {0.0}; - double m_dTop {0.0}; - double m_dWidth {0.0}; - double m_dHeight {0.0}; + virtual void Clear() = 0; + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const = 0; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const = 0; - //Secondary - double m_dBaselinePos {0.0}; - double m_dRight {0.0}; + virtual eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc) const; + virtual eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc) const; + virtual void RecalcWithNewItem(const CBaseItem* pObj); - public: - CBaseItem(const ElemType& eType): m_eType(eType) {} - virtual ~CBaseItem() {} + bool AreObjectsNoCrossingByVertically(const CBaseItem* pObj) const noexcept; + bool AreObjectsNoCrossingByHorizontally(const CBaseItem* pObj) const noexcept; - CBaseItem& operator=(const CBaseItem& oSrc); + CBaseItem& operator=(const CBaseItem& oSrc); + }; - friend bool operator == (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft == rh.m_dLeft) ? true : false; - } + class COutputObject : public CBaseItem + { + public: + enum class eOutputType + { + etAny = 0, + etParagraph = 1, + etShape = 2, + etTable = 3 + }; - friend bool operator < (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft < rh.m_dLeft) ? true : false; - } + COutputObject() : m_eType(eOutputType::etAny) {} + COutputObject(eOutputType eType) : m_eType(eType) {} + virtual ~COutputObject() = default; - friend bool operator > (const CBaseItem& lh, const CBaseItem& rh) - { - return (lh.m_dLeft > rh.m_dLeft) ? true : false; - } + COutputObject& operator= (const COutputObject& oObj); - virtual bool IsBigger(const CBaseItem* oSrc); - virtual bool IsBiggerOrEqual(const CBaseItem* oSrc); - - virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) = 0; - virtual void Clear() = 0; - - eVerticalCrossingType GetVerticalCrossingType(const CBaseItem* oSrc); - eHorizontalCrossingType GetHorizontalCrossingType(const CBaseItem* oSrc); - }; + eOutputType m_eType; + }; } diff --git a/DocxRenderer/src/logic/elements/ContText.cpp b/DocxRenderer/src/logic/elements/ContText.cpp index b7bfa8cd32d..481a127c488 100644 --- a/DocxRenderer/src/logic/elements/ContText.cpp +++ b/DocxRenderer/src/logic/elements/ContText.cpp @@ -5,461 +5,591 @@ 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"<w:r>"); - oWriter.WriteString(L"<w:rPr>"); - - oWriter.WriteString(L"<w:rStyle w:val=\""); - oWriter.WriteString(m_pFontStyle->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<LONG>(dSpacing); - } - } - - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - //note 1 -> 0.5pt - lCalculatedSpacing -= 1; - - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L"<w:spacing w:val=\""); - oWriter.AddInt(lCalculatedSpacing); - oWriter.WriteString(L"\"/>"); - } - - if (m_bIsEmbossPresent) - { - oWriter.WriteString(L"<w:emboss/>"); - } - else if (m_bIsEngravePresent) - { - oWriter.WriteString(L"<w:imprint/>"); - } - else - { - if (m_bIsOutlinePresent) - { - oWriter.WriteString(L"<w:outline/>"); - } - if (m_bIsShadowPresent) - { - oWriter.WriteString(L"<w:shadow/>"); - } - } - - if (m_bIsStrikeoutPresent) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L"<w:dstrike/>"); - } - else - { - oWriter.WriteString(L"<w:strike/>"); - } - } - - if (m_bIsUnderlinePresent) - { - oWriter.WriteString(L"<w:u w:val="); - oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType)); - - if (m_lUnderlineColor != m_pFontStyle->m_oBrush.Color1) - { - oWriter.WriteString(L" w:color=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); - } - - if (m_bIsHighlightPresent) - { - //note В <w:style это не работает - ColorTable& colorTable = SingletonInstance<ColorTable>(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L"<w:highlight w:val=\""); - oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor))); - } - else - { - oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); - } - oWriter.WriteString(L"\"/>"); - } - - if (m_eVertAlignType == eVertAlignType::vatSubscript) - { - oWriter.WriteString(L"<w:vertAlign w:val=\"subscript\"/>"); - } - else if (m_eVertAlignType == eVertAlignType::vatSuperscript) - { - oWriter.WriteString(L"<w:vertAlign w:val=\"superscript\"/>"); - } - - oWriter.WriteString(L"</w:rPr>"); - - oWriter.WriteString(L"<w:t xml:space=\"preserve\">"); - oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); - oWriter.WriteString(L"</w:t>"); - - oWriter.WriteString(L"</w:r>"); - } - - void CContText::AddWideSpaceToXml(double dSpacingMM, - NSStringUtils::CStringBuilder& oWriter, - bool bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:r><w:rPr>"); - - oWriter.WriteString(L"<w:rStyle w:val=\""); - oWriter.WriteString(m_pFontStyle->GetStyleId()); - oWriter.WriteString(L"\"/>"); - - double dSpaceMMSize = m_dSpaceWidthMM; - if (!m_pFontStyle->m_strPickFontName.empty()) - { - dSpaceMMSize = m_pManagerLight->GetSpaceWidth(); - } - - LONG lCalculatedSpacing = static_cast<LONG>((dSpacingMM - dSpaceMMSize) * c_dMMToDx); - //note принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу - lCalculatedSpacing -= 1; - if (lCalculatedSpacing != 0) - { - oWriter.WriteString(L"<w:spacing w:val=\""); - oWriter.AddInt(lCalculatedSpacing); - oWriter.WriteString(L"\"/>"); - } - - if (m_bIsEmbossPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:emboss/>"); - } - else if (m_bIsEngravePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:imprint/>"); - } - else - { - if (m_bIsOutlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:outline/>"); - } - if (m_bIsShadowPresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:shadow/>"); - } - } - - if (m_bIsStrikeoutPresent && bIsNeedSaveFormat) - { - if (m_bIsDoubleStrikeout) - { - oWriter.WriteString(L"<w:dstrike/>"); - } - else - { - oWriter.WriteString(L"<w:strike/>"); - } - } - - if (m_bIsUnderlinePresent && bIsNeedSaveFormat) - { - oWriter.WriteString(L"<w:u w:val="); - oWriter.WriteString(SingletonInstance<LinesTable>().ConverLineToString(m_eUnderlineType)); - - if (m_lUnderlineColor != m_pFontStyle->m_oBrush.Color1) - { - oWriter.WriteString(L" w:color=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); - } - - if (m_bIsHighlightPresent && bIsNeedSaveFormat) - { - //note В <w:style это не работает - ColorTable& colorTable = SingletonInstance<ColorTable>(); - if (colorTable.IsStandardColor(m_lHighlightColor)) - { - oWriter.WriteString(L"<w:highlight w:val=\""); - oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor))); - } - else - { - oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); - } - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"</w:rPr>"); - - oWriter.WriteString(L"<w:t xml:space=\"preserve\">"); - oWriter.WriteString(L" "); - oWriter.WriteString(L"</w:t>"); - - oWriter.WriteString(L"</w:r>"); - } - - 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; + + 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; + + 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; + } + } + + 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 && + m_dLeft == pCont->m_dLeft && m_dRight == pCont->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 CContText::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L"<w:r>"); + oWriter.WriteString(L"<w:rPr>"); + oWriter.WriteString(L"<w:noProof/>"); + + if (!m_bWriteStyleRaw) + { + oWriter.WriteString(L"<w:rStyle w:val=\""); + oWriter.WriteString(m_pFontStyle->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<LONG>(dSpacing); + } + + // принудительно уменьшаем spacing чтобы текстовые линии не выходили за правую границу + // lCalculatedSpacing -= 1; + + if (lCalculatedSpacing != 0) + { + oWriter.WriteString(L"<w:spacing w:val=\""); + oWriter.AddInt(lCalculatedSpacing); + oWriter.WriteString(L"\"/>"); + } + + if (m_bIsEmbossPresent) + oWriter.WriteString(L"<w:emboss/>"); + else if(m_bIsEngravePresent) + oWriter.WriteString(L"<w:imprint/>"); + else + { + if (m_bIsOutlinePresent) + oWriter.WriteString(L"<w:outline/>"); + if (m_bIsShadowPresent) + oWriter.WriteString(L"<w:shadow/>"); + } + + if (m_bIsStrikeoutPresent) + { + if (m_bIsDoubleStrikeout) + oWriter.WriteString(L"<w:dstrike/>"); + else + oWriter.WriteString(L"<w:strike/>"); + } + + if (m_bIsUnderlinePresent) + { + oWriter.WriteString(L"<w:u w:val="); + oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(m_eUnderlineType)); + if (m_lUnderlineColor != m_pFontStyle->oBrush.Color1) + { + oWriter.WriteString(L" w:color=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L"/>"); + } + + if (m_bIsHighlightPresent) + { + //note В <w:style это не работает + ColorTable& colorTable = SingletonInstance<ColorTable>(); + if (colorTable.IsStandardColor(m_lHighlightColor)) + { + oWriter.WriteString(L"<w:highlight w:val=\""); + oWriter.WriteString(colorTable.ConverColorToString(ConvertColorBGRToRGB(m_lHighlightColor))); + } + else + { + oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); + } + oWriter.WriteString(L"\"/>"); + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + { + int lSize = static_cast<int>(3.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L"<w:sz w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/><w:szCs w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/>"); + } + else if (m_bWriteStyleRaw) + { + int lSize = static_cast<int>(2.0 * m_pFontStyle->dFontSize); + oWriter.WriteString(L"<w:sz w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/><w:szCs w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/>"); + } + + if (m_bWriteStyleRaw) + { + oWriter.WriteString(L"<w:rFonts w:ascii=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->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:hint=\"default\"/>"); + + if (m_pFontStyle->bBold) + { + oWriter.WriteString(L"<w:b/>"); + oWriter.WriteString(L"<w:bCs/>"); + } + if (m_pFontStyle->bItalic) + { + oWriter.WriteString(L"<w:i/>"); + oWriter.WriteString(L"<w:iCs/>"); + } + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L"<w:color w:val=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + } + } + + if (m_eVertAlignType == eVertAlignType::vatSubscript) + oWriter.WriteString(L"<w:vertAlign w:val=\"subscript\"/>"); + else if (m_eVertAlignType == eVertAlignType::vatSuperscript) + oWriter.WriteString(L"<w:vertAlign w:val=\"superscript\"/>"); + + oWriter.WriteString(L"</w:rPr>"); + oWriter.WriteString(L"<w:t xml:space=\"preserve\">"); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L"</w:t>"); + if (m_bIsAddBrEnd) oWriter.WriteString(L"<w:br/>"); + oWriter.WriteString(L"</w:r>"); + } + + void CContText::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L"<a:r>"); + oWriter.WriteString(L"<a:rPr noProof=\"1\""); + + LONG lCalculatedSpacing = 0; + if (!m_oText.empty()) + { + double dSpacing = (m_dWidth - m_oSelectedSizes.dWidth) / (m_oText.length()); + dSpacing *= c_dMMToPt * 100; + lCalculatedSpacing = static_cast<LONG>(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<LinesTable>().ConvertLineToStringPptx(m_eUnderlineType)); + } + + UINT lSize = 0; + if (m_eVertAlignType == eVertAlignType::vatSubscript || m_eVertAlignType == eVertAlignType::vatSuperscript) + lSize = static_cast<int>(1.5 * m_pFontStyle->dFontSize) * 100; + else if (m_bWriteStyleRaw) + lSize = static_cast<int>(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"<a:sym typeface=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"<a:cs typeface=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"<a:latin typeface=\""); + oWriter.WriteEncodeXmlString(m_pFontStyle->wsFontName); + oWriter.WriteString(L"\"/>"); + + if (m_bIsUnderlinePresent && m_lUnderlineColor != m_pFontStyle->oBrush.Color1) + { + oWriter.WriteString(L"<a:uFill>"); + oWriter.WriteString(L"<a:solidFill>"); + oWriter.WriteString(L"<a:srgbClr val=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lUnderlineColor)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:solidFill>"); + oWriter.WriteString(L"</a:uFill>"); + } + + if (m_bIsHighlightPresent) + { + oWriter.WriteString(L"<a:highlight>"); + oWriter.WriteString(L"<a:srgbClr val=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lHighlightColor)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:highlight>"); + } + + if (ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1) != c_iBlackColor) + { + oWriter.WriteString(L"<a:solidFill>"); + oWriter.WriteString(L"<a:srgbClr val=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_pFontStyle->oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:solidFill>"); + } + + + oWriter.WriteString(L"</a:rPr>"); + oWriter.WriteString(L"<a:t>"); + oWriter.WriteEncodeXmlString(m_oText.ToStdWString()); + oWriter.WriteString(L"</a:t>"); + if (m_bIsAddBrEnd) oWriter.WriteString(L"<a:br/>"); + oWriter.WriteString(L"</a:r>"); + } + + 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) const noexcept + { + if (eVType == eVerticalCrossingType::vctDublicate && m_oText == pCont->m_oText) + return true; + return false; + } + + bool CContText::CheckFontEffects + (std::shared_ptr<CContText>& pFirstCont, + std::shared_ptr<CContText>& 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<CContText> pFirstCont, + std::shared_ptr<CContText> 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; + return true; + } + else if (bIf2 && bIf5) + { + pSecondCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pSecondCont->m_pCont = pFirstCont; + pFirstCont->m_eVertAlignType = eVertAlignType::vatBase; + pFirstCont->m_pCont = pSecondCont; + return true; + } + else if (bIf1 && bIf6) + { + pFirstCont->m_eVertAlignType = eVertAlignType::vatSuperscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; + return true; + } + else if (bIf2 && bIf6) + { + pFirstCont->m_eVertAlignType = eVertAlignType::vatSubscript; + pFirstCont->m_pCont = pSecondCont; + pSecondCont->m_eVertAlignType = eVertAlignType::vatBase; + pSecondCont->m_pCont = pFirstCont; + return true; + } + } + return false; + } + + double CContText::CalculateWideSpace() const noexcept + { + return m_dSpaceWidthMM * 3; + } + + double CContText::CalculateThinSpace() const noexcept + { + return m_dSpaceWidthMM * 0.35; + } } diff --git a/DocxRenderer/src/logic/elements/ContText.h b/DocxRenderer/src/logic/elements/ContText.h index 978e443f4d6..fb1128e6e5c 100644 --- a/DocxRenderer/src/logic/elements/ContText.h +++ b/DocxRenderer/src/logic/elements/ContText.h @@ -1,83 +1,114 @@ #pragma once #include "BaseItem.h" -#include "../DesktopEditor/common/StringBuilder.h" +#include "../../../../DesktopEditor/common/StringBuilder.h" #include "../managers/FontManager.h" -#include "../managers/StyleManager.h" -#include "../styles/FontStyle.h" +#include "../managers/FontStyleManager.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<CFontStyle> 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<const CFontStyle> m_pFontStyle{nullptr}; + CFontManager* m_pManager {nullptr}; + + // background graphics + std::shared_ptr<CShape> m_pShape {nullptr}; + + // super/sub script + std::weak_ptr<CContText> 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}; + + // font to calc selected sizes + NSStructures::CFont m_oSelectedFont{}; + + // sizes + double m_dSpaceWidthMM{0}; + CSelectedSizes m_oSelectedSizes{}; + + double m_dTopWithAscent{0}; + double m_dBotWithDescent{0}; + + NSStringUtils::CStringUTF32 m_oText{}; + UINT m_iNumDuplicates{0}; + + bool m_bIsAddBrEnd{false}; + bool m_bWriteStyleRaw{false}; + + double m_dFirstWordWidth{0}; + + 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_pFontStyle & m_pManager) + void CalcSelected(); + + CContText& operator=(const CContText& rCont); + bool IsEqual(const CContText* pCont) const noexcept; + + UINT GetNumberOfFeatures() const noexcept; + bool IsDuplicate(CContText *pCont, eVerticalCrossingType eVType) const noexcept; + + // check font effect and delete not needed cont + // return true if was deleted + static bool CheckFontEffects + (std::shared_ptr<CContText>& pFirstCont, + std::shared_ptr<CContText>& pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType); + + static bool CheckVertAlignTypeBetweenConts + (std::shared_ptr<CContText> pFirstCont, + std::shared_ptr<CContText> pSecondCont, + eVerticalCrossingType eVType, + eHorizontalCrossingType eHType); + + double CalculateWideSpace() const noexcept; + double CalculateThinSpace() const noexcept; + }; } diff --git a/DocxRenderer/src/logic/elements/DropCap.cpp b/DocxRenderer/src/logic/elements/DropCap.cpp new file mode 100644 index 00000000000..22e42426d63 --- /dev/null +++ b/DocxRenderer/src/logic/elements/DropCap.cpp @@ -0,0 +1,39 @@ +#include "DropCap.h" +#include "../../resources/Constants.h" + +namespace NSDocxRenderer +{ + void CDropCap::BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const + { + oWriter.WriteString(L"<" + wsTag + L":p>"); + oWriter.WriteString(L"<" + wsTag + L":pPr>"); + oWriter.WriteString(L"<" + wsTag + L":spacing " + wsTag + L":after=\"0\""); + oWriter.WriteString(L" " + wsTag + L":line=\""); + oWriter.AddInt(static_cast<LONG>((m_dBaselinePos - m_dTop) * c_dMMToDx)); + oWriter.WriteString(L"\" "); + oWriter.WriteString(wsTag + L":lineRule=\"exact\" />"); + oWriter.WriteString(L"</" + wsTag + L":pPr>"); + oWriter.WriteString(L"<" + wsTag + L":r>"); + oWriter.WriteString(L"<" + wsTag + L":rPr>"); + oWriter.WriteString(L"<" + wsTag + L":rFonts " + wsTag + L":ascii=\"" + wsFont + + L"\" " + wsTag + L":hAnsi=\"" + wsFont + + L"\" " + wsTag + L":eastAsia=\"" + wsFont + + L"\" " + wsTag + L":cs=\"" + wsFont + L"\" />"); + + oWriter.WriteString(L"<" + wsTag + L":sz " + wsTag + L":val=\""); + oWriter.AddInt(nFontSize); + oWriter.WriteString(L"\" />"); + oWriter.WriteString(L"</" + wsTag + L":rPr>"); + oWriter.WriteString(L"<" + wsTag + L":t xml:space=\"preserve\">" + wsText + L"</" + wsTag + L":t>"); + oWriter.WriteString(L"</" + wsTag + L":r>"); + oWriter.WriteString(L"</" + wsTag + L":p>"); + } + void CDropCap::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"w"); + } + void CDropCap::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + BuildXml(oWriter, L"a"); + } +} diff --git a/DocxRenderer/src/logic/elements/DropCap.h b/DocxRenderer/src/logic/elements/DropCap.h new file mode 100644 index 00000000000..8ad094990f3 --- /dev/null +++ b/DocxRenderer/src/logic/elements/DropCap.h @@ -0,0 +1,30 @@ +#ifndef DROPCAP_H +#define DROPCAP_H + +#include "BaseItem.h" + +namespace NSDocxRenderer +{ + class CDropCap : public COutputObject + { + public: + size_t nLines; + + std::wstring wsText; + std::wstring wsFont; + LONG nFontSize; // Pt * 2 + LONG nOffset; + + CDropCap() = default; + ~CDropCap() = default; + + virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final; + virtual void Clear() override {} + + private: + void BuildXml(NSStringUtils::CStringBuilder& oWriter, const std::wstring& wsTag) const; + }; +} + +#endif // DROPCAP_H diff --git a/DocxRenderer/src/logic/elements/Image.cpp b/DocxRenderer/src/logic/elements/Image.cpp index 43e90af5a65..815f24923c4 100644 --- a/DocxRenderer/src/logic/elements/Image.cpp +++ b/DocxRenderer/src/logic/elements/Image.cpp @@ -4,47 +4,37 @@ 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"<w:r><w:pict><v:shape id=\"\" type=\"\" style=\"position:absolute;"); - - oWriter.WriteString(L"margin-left:"); - oWriter.AddDouble(m_dLeft, 2); - oWriter.WriteString(L"mm;margin-top:"); - oWriter.AddDouble(m_dTop, 2); - oWriter.WriteString(L"mm;width:"); - oWriter.AddDouble(m_dWidth, 2); - oWriter.WriteString(L"mm;height:"); - oWriter.AddDouble(m_dHeight, 2); - oWriter.WriteString(L"mm;"); - - if (fabs(m_dRotate) > 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"<v:imagedata r:id=\"rId"); - oWriter.AddInt(c_iStartingIdForImages + m_oImageInfo.m_nId); - oWriter.WriteString(L"\" o:title=\"\"/>"); - - oWriter.WriteString(L"</v:shape></w:pict></w:r>"); - } + CImage::CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia) + : m_oImageInfo(oInfo), m_strPath(strDstMedia) + { + } + + void CImage::ToXml(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L"<w:r><w:pict><v:shape id=\"\" type=\"\" style=\"position:absolute;"); + oWriter.WriteString(L"margin-left:"); + oWriter.AddDouble(m_dLeft, 2); + oWriter.WriteString(L"mm;margin-top:"); + oWriter.AddDouble(m_dTop, 2); + oWriter.WriteString(L"mm;width:"); + oWriter.AddDouble(m_dWidth, 2); + oWriter.WriteString(L"mm;height:"); + oWriter.AddDouble(m_dHeight, 2); + oWriter.WriteString(L"mm;"); + + if (fabs(m_dRotate) > 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"<v:imagedata r:id=\"rId"); + oWriter.AddInt(c_iStartingIdForImages + m_oImageInfo.m_nId); + oWriter.WriteString(L"\" o:title=\"\"/>"); + + oWriter.WriteString(L"</v:shape></w:pict></w:r>"); + } } diff --git a/DocxRenderer/src/logic/elements/Image.h b/DocxRenderer/src/logic/elements/Image.h index a8ecbda02a8..b5dbe9fb8f8 100644 --- a/DocxRenderer/src/logic/elements/Image.h +++ b/DocxRenderer/src/logic/elements/Image.h @@ -4,24 +4,25 @@ namespace NSDocxRenderer { - class CImage : public CBaseItem + class CImage : public CBaseItem { public: - CImageInfo m_oImageInfo; + CImageInfo m_oImageInfo; - std::wstring m_strPath {L""}; + std::wstring m_strPath {L""}; - bool m_bIsNoFill {true}; - bool m_bIsNoStroke {true}; - bool m_bIsBehindDoc {true}; + bool m_bIsNoFill{true}; + bool m_bIsNoStroke{true}; + bool m_bIsBehindDoc{true}; - double m_dRotate {0.0}; + 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; + CImage() = default; + CImage(const CImageInfo& oInfo, const std::wstring& strDstMedia); + void Clear() override final {}; + void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final; + void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const 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<CVectorGraphics::VectorGraphicsType>((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast<LONG>((*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<LONG>((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY = static_cast<LONG>((*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<LONG>((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY1 = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX2 = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY2 = static_cast<LONG>((*pData - m_dTop) * lCoordSize / dHeight); - ++pData; - - LONG lX3 = static_cast<LONG>((*pData - m_dLeft) * lCoordSize / dWidth); - ++pData; - LONG lY3 = static_cast<LONG>((*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"<w:r><w:pict><v:shape id=\"\" o:spid=\"\" style=\"position:absolute;"); - - //oWriter.WriteString(L"left:0;text-align:left;"); - - oWriter.WriteString(L"margin-left:"); - oWriter.AddDouble(m_dLeft, 2); - oWriter.WriteString(L"mm;margin-top:"); - oWriter.AddDouble(m_dTop, 2); - oWriter.WriteString(L"mm;width:"); - oWriter.AddDouble(m_dWidth, 2); - oWriter.WriteString(L"mm;height:"); - oWriter.AddDouble(m_dHeight, 2); - oWriter.WriteString(L"mm;"); - - oWriter.WriteString(L"z-index:-1;mso-position-horizontal-relative:page;mso-" - L"position-vertical-relative:page;\""); - - oWriter.WriteString(L" coordsize=\""); - oWriter.AddInt(static_cast<int>(m_lCoordSizeX)); - oWriter.AddCharSafe(','); - oWriter.AddInt(static_cast<int>(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<int>(ConvertColorBGRToRGB(m_oBrush.Color1))); - } - oWriter.WriteString(L"\" strokecolor=\"#"); - oWriter.WriteHexInt3(static_cast<int>(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"<v:fill opacity=\"%.2lf\"/>"; - std::wstring g_string_stroke_opacity = L"<v:stroke opacity=\"%.2lf\"/>"; - - if (c_BrushTypeTexture == m_oBrush.Type && !m_bIsNoFill) - { - oWriter.WriteString(L"<v:imagedata r:id=\"rId"); - oWriter.AddInt(c_iStartingIdForImages + m_lTxId); - oWriter.WriteString(L"\" o:title=\"\"/>"); - - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"<v:fill opacity=\""); - oWriter.AddDouble(static_cast<double>(m_oBrush.TextureAlpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - else - { - if (0xFF != m_oBrush.Alpha1) - { - oWriter.WriteString(L"<v:fill opacity=\""); - oWriter.AddDouble(static_cast<double>(m_oBrush.Alpha1 / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"<v:stroke opacity=\""); - oWriter.AddDouble(static_cast<double>(m_oPen.Alpha / 255.0), 2); - oWriter.WriteString(L"\"/>"); - } - } - - oWriter.WriteString(L"<w10:wrap anchorx=\"page\" " - L"anchory=\"page\"/>"); - - if (!m_arParagraphs.empty()) - { - oWriter.WriteString(L"<v:textbox><w:txbxContent>"); - - for (const auto& pParagraph : m_arParagraphs) - { - pParagraph->ToXml(oWriter); - } - oWriter.WriteString(L"</w:txbxContent></v:textbox>"); - } - - oWriter.WriteString(L"</v:shape></w:pict></w:r>"); - } -} // 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<CParagraph*> 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..36494e905a5 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.cpp +++ b/DocxRenderer/src/logic/elements/Paragraph.cpp @@ -1,225 +1,198 @@ #include "Paragraph.h" -#include "src/resources/ColorTable.h" -#include "src/resources/utils.h" +#include "../../resources/ColorTable.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"<w:p>"); - oWriter.WriteString(L"<w:pPr>"); - - switch (m_eTextConversionType) - { - case tctTextToFrame: - { - oWriter.WriteString(L"<w:framePr"); - - if (m_eTextAssociationType == tatPlainParagraph) - { - if (m_bIsAroundTextWrapping) - { - oWriter.WriteString(L" w:wrap=\"around\""); - } - else - { - oWriter.WriteString(L" w:wrap=\"notBeside\""); - } - } - - oWriter.WriteString(L" w:hAnchor=\"page\""); - oWriter.WriteString(L" w:vAnchor=\"page\""); - - oWriter.WriteString(L" w:x=\""); - oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L" w:y=\""); - oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToDx)); - oWriter.WriteString(L"\""); - - oWriter.WriteString(L"/>"); //конец w:framePr - break; - } - case tctTextToShape: - case tctTextToParagraph: - { - oWriter.WriteString(L"<w:spacing"); - if (m_eTextConversionType == tctTextToParagraph) - { - oWriter.WriteString(L" w:before=\""); - oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_eTextConversionType == tctTextToShape) - { - oWriter.WriteString(L" w:after=\""); - oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - - if (m_dHeight > 0) - { - oWriter.WriteString(L" w:line=\""); - oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToDx)); - oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки - } - - oWriter.WriteString(L"/>"); //конец w:spacing - - oWriter.WriteString(L"<w:ind"); - if (m_dLeft > 0) - { - oWriter.WriteString(L" w:left=\""); - oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - if (m_dRight > 0) - { - oWriter.WriteString(L" w:right=\""); - oWriter.AddInt(static_cast<int>(m_dRight * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - if (m_bIsNeedFirstLineIndent) - { - oWriter.WriteString(L" w:firstLine=\""); - oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L"/>"); //конец w:ind - - - if (m_eTextAssociationType == tatPlainParagraph) - { - switch (m_eTextAlignmentType) - { - case tatByCenter: - oWriter.WriteString(L"<w:jc w:val=\"center\"/>"); - break; - case tatByRightEdge: - oWriter.WriteString(L"<w:jc w:val=\"end\"/>"); - break; - case tatByWidth: - oWriter.WriteString(L"<w:jc w:val=\"both\"/>"); - break; - case tatByLeftEdge: - oWriter.WriteString(L"<w:jc w:val=\"begin\"/>"); - break; - case tatUnknown: - default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять - break; - } - } - - if (m_bIsShadingPresent) - { - oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill)); - oWriter.WriteString(L"\"/>"); - } - break; - } - default: - break; - } - - oWriter.WriteString(L"</w:pPr>"); - - for(const auto &pLine : m_arLines) - { - pLine->ToXml(oWriter); - } - - oWriter.WriteString(L"</w:p>"); - } - - 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"<w:p>"); + oWriter.WriteString(L"<w:pPr>"); + + // styles + if(!m_wsStyleId.empty()) oWriter.WriteString(L"<w:pStyle w:val=\"" + m_wsStyleId + L"\"/>"); + + oWriter.WriteString(L"<w:spacing"); + if (m_dSpaceBefore > 0) + { + oWriter.WriteString(L" w:before=\""); + oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dSpaceAfter > 0) + { + oWriter.WriteString(L" w:after=\""); + oWriter.AddInt(static_cast<int>(m_dSpaceAfter * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + + if (m_dLineHeight > 0) + { + oWriter.WriteString(L" w:line=\""); + oWriter.AddInt(static_cast<int>(m_dLineHeight * c_dMMToDx)); + oWriter.WriteString(L"\" w:lineRule=\"exact\""); // exact - точный размер строки + } + + oWriter.WriteString(L"/>"); //конец w:spacing + + oWriter.WriteString(L"<w:ind"); + if (m_dLeftBorder > 0) + { + oWriter.WriteString(L" w:left=\""); + oWriter.AddInt(static_cast<int>(m_dLeftBorder * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + if (m_dRightBorder > 0) + { + oWriter.WriteString(L" w:right=\""); + oWriter.AddInt(static_cast<int>(m_dRightBorder * c_dMMToDx)); //здесь m_dRight - расстояние от правого края + oWriter.WriteString(L"\""); + } + if (m_bIsNeedFirstLineIndent) + { + oWriter.WriteString(L" w:firstLine=\""); + oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToDx)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L"/>"); //конец w:ind + + switch (m_eTextAlignmentType) + { + case tatByCenter: + oWriter.WriteString(L"<w:jc w:val=\"center\"/>"); + break; + case tatByRight: + oWriter.WriteString(L"<w:jc w:val=\"end\"/>"); + break; + case tatByWidth: + oWriter.WriteString(L"<w:jc w:val=\"both\"/>"); + break; + case tatByLeft: + oWriter.WriteString(L"<w:jc w:val=\"begin\"/>"); + break; + case tatUnknown: + default: //по умолчанию выравнивание по левому краю - можно ничего не добавлять + break; + } + + if (m_bIsShadingPresent) + { + oWriter.WriteString(L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_lColorOfShadingFill)); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"</w:pPr>"); + for(const auto& line : m_arLines) + if(line) + line->ToXml(oWriter); + oWriter.WriteString(L"</w:p>"); + } + + void CParagraph::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const + { + oWriter.WriteString(L"<a:p>"); + oWriter.WriteString(L"<a:pPr algn=\""); + switch (m_eTextAlignmentType) + { + case tatByCenter: + oWriter.WriteString(L"ctr"); + break; + case tatByRight: + oWriter.WriteString(L"r"); + break; + case tatByWidth: + oWriter.WriteString(L"just"); + break; + case tatByLeft: + oWriter.WriteString(L"l"); + break; + case tatUnknown: + default: + oWriter.WriteString(L"l"); + break; + } + + oWriter.WriteString(L"\""); + + if (m_bIsNeedFirstLineIndent) + { + oWriter.WriteString(L" indent=\""); + oWriter.AddInt(static_cast<int>(m_dFirstLine * c_dMMToEMU)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + oWriter.WriteString(L"<a:spcBef>"); + oWriter.WriteString(L"<a:spcPts val=\""); + oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:spcBef>"); + + + oWriter.WriteString(L"<a:spcAft>"); + oWriter.WriteString(L"<a:spcPts val=\""); + oWriter.AddInt(static_cast<int>(m_dSpaceBefore * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:spcAft>"); + + oWriter.WriteString(L"<a:lnSpc>"); + oWriter.WriteString(L"<a:spcPts val=\""); + oWriter.AddInt(static_cast<int>(m_dLineHeight * c_dMMToPt * 100)); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"</a:lnSpc>"); + + oWriter.WriteString(L"</a:pPr>"); + for(const auto& line : m_arLines) + if(line) + line->ToXmlPptx(oWriter); + oWriter.WriteString(L"</a:p>"); + } + + 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]; + + pLastCont->m_oText += L" "; + } + } } diff --git a/DocxRenderer/src/logic/elements/Paragraph.h b/DocxRenderer/src/logic/elements/Paragraph.h index aeb552dc304..f6b7976fc80 100644 --- a/DocxRenderer/src/logic/elements/Paragraph.h +++ b/DocxRenderer/src/logic/elements/Paragraph.h @@ -5,53 +5,44 @@ 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<CTextLine*> 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 COutputObject + { + 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<std::shared_ptr<CTextLine>> m_arLines; + std::wstring m_wsStyleId; + + public: + CParagraph() : COutputObject(COutputObject::eOutputType::etParagraph) {} + 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..51769617ae7 100644 --- a/DocxRenderer/src/logic/elements/Shape.cpp +++ b/DocxRenderer/src/logic/elements/Shape.cpp @@ -1,931 +1,1005 @@ #include "Shape.h" -#include <limits.h> #include "../../resources/Constants.h" #include "../../resources/utils.h" +#include <limits.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<CImageInfo> 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"<a:path w=\""); - oWriter.AddInt(static_cast<int>(dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" h=\""); - oWriter.AddInt(static_cast<int>(dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\">"); - - size_t nPeacks = 0; - size_t nCurves = 0; - - while (nCount > 0) - { - CVectorGraphics::VectorGraphicsType eType = static_cast<CVectorGraphics::VectorGraphicsType>((int)(0.5 + *pData++)); - - switch (eType) - { - case CVectorGraphics::vgtMove: - { - LONG lX = static_cast<LONG>((*pData - m_dLeft) * c_dMMToEMU); - ++pData; - LONG lY = static_cast<LONG>((*pData - m_dTop) * c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"<a:moveTo><a:pt x=\""); - oWriter.AddInt(static_cast<int>(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast<int>(lY)); - oWriter.WriteString(L"\"/></a:moveTo>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtLine: - { - LONG lX = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"<a:lnTo><a:pt x=\""); - oWriter.AddInt(static_cast<int>(lX)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast<int>(lY)); - oWriter.WriteString(L"\"/></a:lnTo>"); - - nPeacks++; - nCount -= 3; - break; - } - case CVectorGraphics::vgtCurve: - { - LONG lX1 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY1 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX2 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY2 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU); - ++pData; - LONG lX3 = static_cast<LONG>((*pData - m_dLeft)* c_dMMToEMU); - ++pData; - LONG lY3 = static_cast<LONG>((*pData - m_dTop)* c_dMMToEMU); - ++pData; - - oWriter.WriteString(L"<a:cubicBezTo>"); - - oWriter.WriteString(L"<a:pt x=\""); - oWriter.AddInt(static_cast<int>(lX1)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast<int>(lY1)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"<a:pt x=\""); - oWriter.AddInt(static_cast<int>(lX2)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast<int>(lY2)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"<a:pt x=\""); - oWriter.AddInt(static_cast<int>(lX3)); - oWriter.WriteString(L"\" y=\""); - oWriter.AddInt(static_cast<int>(lY3)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"</a:cubicBezTo>"); - - nCurves++; - nCount -= 7; - break; - } - case CVectorGraphics::vgtClose: - default: - --nCount; - break; - } - } - oWriter.WriteString(L"<a:close/>"); - oWriter.WriteString(L"</a:path>"); - - 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"<w:r>"); - - oWriter.WriteString(L"<w:rPr><w:noProof/></w:rPr>"); //отключение проверки орфографии - - oWriter.WriteString(L"<w:drawing>"); - - BuildGeneralProperties(oWriter); - - oWriter.WriteString(L"</w:drawing>"); - - oWriter.WriteString(L"</w:r>"); - } - - void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"<wp:anchor"); - oWriter.WriteString(L" distT=\"0\""); //Определяет минимальное расстояние, которое должно сохраняться между краем - oWriter.WriteString(L" distB=\"0\""); //этого объекта рисования и любым последующим текстом в документе, когда - oWriter.WriteString(L" distL=\"0\""); //этот графический объект объект отображается в содержимом документа. - oWriter.WriteString(L" distR=\"0\""); - oWriter.WriteString(L" simplePos=\"0\""); //true/1 Указывает, что этот объект должен быть позиционирован с использованием информации о позиционировании в дочернем элементе simplePos - oWriter.WriteString(L" relativeHeight=\""); //Определяет относительное упорядочивание по Z всех объектов DrawingML в этом документе. - oWriter.AddUInt(m_nRelativeHeight); - oWriter.WriteString(L"\""); - oWriter.WriteString(L" behindDoc=\""); //позади текста - 1, перед текстом - 0 - oWriter.AddUInt(static_cast<UINT>(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"<wp:simplePos x=\"0\" y=\"0\"/>"); - - oWriter.WriteString(L"<wp:positionH relativeFrom=\"page\">"); - oWriter.WriteString(L"<wp:posOffset>"); - oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToEMU)); - oWriter.WriteString(L"</wp:posOffset>"); - oWriter.WriteString(L"</wp:positionH>"); - - oWriter.WriteString(L"<wp:positionV relativeFrom=\"page\">"); - oWriter.WriteString(L"<wp:posOffset>"); - oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToEMU)); - oWriter.WriteString(L"</wp:posOffset>"); - oWriter.WriteString(L"</wp:positionV>"); - - //координаты конца границы шейпа - oWriter.WriteString(L"<wp:extent"); - oWriter.WriteString(L" cx=\""); - oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML - - oWriter.WriteString(L"<wp:wrapNone/>"); - - m_nShapeId = GenerateShapeId(); - - oWriter.WriteString(L"<wp:docPr id=\""); - oWriter.AddUInt(m_nShapeId); - switch (m_eType) - { - case eShapeType::stTextBox: - oWriter.WriteString(L"\" name=\"Text Box "); - break; - case eShapeType::stPicture: - oWriter.WriteString(L"\" name=\"Picture "); - break; - case eShapeType::stVectorGraphics: - oWriter.WriteString(L"\" name=\"Freeform: Shape "); - break; - case eShapeType::stVectorTexture: - oWriter.WriteString(L"\" name=\"Freeform: Texture "); - break; - case eShapeType::stCanvas: - oWriter.WriteString(L"\" name=\"Canvas "); - break; - case eShapeType::stGroup: - oWriter.WriteString(L"\" name=\"Group "); - break; - default: - oWriter.WriteString(L"\" name=\"Shape "); - break; - } - oWriter.AddUInt(m_nShapeId); - //oWriter.WriteString(L" descr=\"Alt Text!\""); //Коммент к картинке - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"<wp:cNvGraphicFramePr/>"); - - BuildSpecificProperties(oWriter); - - oWriter.WriteString(L"</wp:anchor>"); - } - - void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"); - - 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"</a:graphic>"); - } - - void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"); - - oWriter.WriteString(L"<wps:wsp>"); - - oWriter.WriteString(L"<wps:cNvSpPr/>"); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php - - oWriter.WriteString(L"<wps:spPr>"); //shape properties. http://officeopenxml.com/drwSp-SpPr.php - - //не работает - //oWriter.WriteString(L"<wps:style/>"); //shape styles. http://officeopenxml.com/drwSp-styles.php - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L"</wps:spPr>"); - - BuildTextBox(oWriter); - - oWriter.WriteString(L"</wps:wsp>"); - - oWriter.WriteString(L"</a:graphicData>"); - } - - void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); - - oWriter.WriteString(L"<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); - oWriter.WriteString(L"<pic:nvPicPr>"); - oWriter.WriteString(L"<pic:cNvPr id=\""); - oWriter.AddUInt(m_pImageInfo->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"<pic:cNvPicPr preferRelativeResize=\"0\">"); - oWriter.WriteString(L"<a:picLocks noChangeArrowheads=\"1\"/>"); - oWriter.WriteString(L"</pic:cNvPicPr>"); - oWriter.WriteString(L"</pic:nvPicPr>"); - oWriter.WriteString(L"<pic:blipFill>"); - oWriter.WriteString(L"<a:blip r:embed=\"rId"); - oWriter.AddUInt(c_iStartingIdForImages + m_pImageInfo->m_nId); - oWriter.WriteString(L"\">"); - oWriter.WriteString(L"<a:alphaModFix/>"); - oWriter.WriteString(L"</a:blip>"); - oWriter.WriteString(L"<a:srcRect/>"); - oWriter.WriteString(L"<a:stretch>"); - oWriter.WriteString(L"<a:fillRect/>"); - oWriter.WriteString(L"</a:stretch>"); - oWriter.WriteString(L"</pic:blipFill>"); - oWriter.WriteString(L"<pic:spPr bwMode=\"auto\">"); - - BuildGraphicProperties(oWriter); - - oWriter.WriteString(L"</pic:spPr>"); - oWriter.WriteString(L"</pic:pic>"); - - oWriter.WriteString(L"</a:graphicData>"); - } - - void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) - { - oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\">"); - oWriter.WriteString(L"<wpg:wgp>"); - oWriter.WriteString(L"<wpg:cNvGrpSpPr/>"); - oWriter.WriteString(L"<wpg:grpSpPr>"); - BuildGraphicProperties(oWriter); - oWriter.WriteString(L"</wpg:grpSpPr>"); - - //todo довабить любое количество элементов в группе - BuildPictureProperties(oWriter); - BuildShapeProperties(oWriter); - - oWriter.WriteString(L"</wps:wsp>"); - oWriter.WriteString(L"</wpg:wgp>"); - oWriter.WriteString(L"</a:graphicData>"); - } - - void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) - { - //todo добавить реализацию - oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\">"); - } - - void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) - { - //отвечает за размеры прямоугольного фрейма шейпа - oWriter.WriteString(L"<a:xfrm"); - if (fabs(m_dRotate) > 0.01) - { - oWriter.WriteString(L" rot=\""); - oWriter.AddInt(static_cast<int>(m_dRotate * c_dDegreeToAngle)); - oWriter.WriteString(L"\""); - } - oWriter.WriteString(L">"); - oWriter.WriteString(L"<a:off x=\"0\" y=\"0\"/>"); - oWriter.WriteString(L"<a:ext"); - oWriter.WriteString(L" cx=\""); - oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); - oWriter.WriteString(L"\" cy=\""); - oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); - oWriter.WriteString(L"\"/>"); - oWriter.WriteString(L"</a:xfrm>"); - - //Если просто текст без графики - if (m_strPath.empty()) - { - oWriter.WriteString(L"<a:prstGeom prst=\"rect\">"); - oWriter.WriteString(L"<a:avLst/>"); - oWriter.WriteString(L"</a:prstGeom>"); - } - else - { - //Рисуем сложный путь - oWriter.WriteString(L"<a:custGeom>"); - oWriter.WriteString(L"<a:avLst/>"); - oWriter.WriteString(L"<a:gdLst/>"); - oWriter.WriteString(L"<a:ahLst/>"); - oWriter.WriteString(L"<a:cxnLst/>"); - oWriter.WriteString(L"<a:rect l=\"l\" t=\"t\" r=\"r\" b=\"b\"/>"); - oWriter.WriteString(L"<a:pathLst>"); - oWriter.WriteString(m_strPath); - oWriter.WriteString(L"</a:pathLst>"); - oWriter.WriteString(L"</a:custGeom>"); - } - - if (m_bIsNoFill) - { - //Нет заливки - oWriter.WriteString(L"<a:noFill/>"); - } - else - { - //Есть заливка - oWriter.WriteString(L"<a:solidFill>"); - oWriter.WriteString(L"<a:srgbClr val=\""); - oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oBrush.Color1))); - if (0xFF != m_oBrush.TextureAlpha) - { - oWriter.WriteString(L"\"><a:alpha val=\""); - oWriter.AddInt(static_cast<int>(m_oBrush.TextureAlpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/></a:srgbClr>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - oWriter.WriteString(L"</a:solidFill>"); - } - - if (m_bIsNoStroke) - { - oWriter.WriteString(L"<a:ln>"); // w - width по умолчанию 0.75pt = 9525 - oWriter.WriteString(L"<a:noFill/>"); - oWriter.WriteString(L"</a:ln>"); - } - else - { - oWriter.WriteString(L"<a:ln w=\""); - //todo Некоторые m_oPen.Size приходят увеличенными в 10 раз - oWriter.AddInt(static_cast<int>(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм - oWriter.WriteString(L"\">"); - - oWriter.WriteString(L"<a:solidFill>"); - - oWriter.WriteString(L"<a:srgbClr val=\""); - oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" - if (0xFF != m_oPen.Alpha) - { - oWriter.WriteString(L"\"><a:alpha val=\""); - oWriter.AddInt(static_cast<int>(m_oPen.Alpha / 255.0 * 100.0)); - oWriter.WriteString(L"%\"/></a:srgbClr>"); - } - else - { - oWriter.WriteString(L"\"/>"); - } - - oWriter.WriteString(L"</a:solidFill>"); - oWriter.WriteString(L"</a:ln>"); - } - } - - void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) - { - if (m_eType == eShapeType::stTextBox && !m_arParagraphs.empty()) - { - oWriter.WriteString(L"<wps:txbx>"); //text within the shape. http://officeopenxml.com/drwSp-text.php - oWriter.WriteString(L"<w:txbxContent>"); - for (size_t i = 0; i < m_arParagraphs.size(); i++) - { - m_arParagraphs[i]->ToXml(oWriter); - } - oWriter.WriteString(L"</w:txbxContent>"); - oWriter.WriteString(L"</wps:txbx>"); - - oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры - 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"<a:prstTxWarp prst=\"textNoShape\">"); - oWriter.WriteString(L"<a:avLst/>"); - oWriter.WriteString(L"</a:prstTxWarp>"); - oWriter.WriteString(L"<a:noAutofit/>"); - oWriter.WriteString(L"</wps:bodyPr>"); - } - else - { - oWriter.WriteString(L"<wps:bodyPr/>"); - } - } + UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight; + + CShape::CShape() + { + COutputObject::m_eType = COutputObject::eOutputType::etShape; + m_nRelativeHeight = m_gRelativeHeight; + m_gRelativeHeight += c_iStandartRelativeHeight; + } + + CShape::CShape(std::shared_ptr<CImageInfo> 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::eVectorGraphicsType::vgtMove: + nPeacks++; + break; + + case CVectorGraphics::eVectorGraphicsType::vgtLine: + nPeacks++; + break; + + case CVectorGraphics::eVectorGraphicsType::vgtCurve: + nCurves++; + break; + + case CVectorGraphics::eVectorGraphicsType::vgtClose: + 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; + } + + bool CShape::TryMergeShape(std::shared_ptr<CShape>& 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; + return true; + } + return false; + } + + std::wstring CShape::PathToWString() const + { + auto arData = m_oVector.GetData(); + + if(arData.empty()) + return m_strDstMedia; + + NSStringUtils::CStringBuilder oWriter; + + oWriter.WriteString(L"<a:path w=\""); + oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" h=\""); + oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\">"); + + for(auto& path_command : arData) + { + switch (path_command.type) + { + case CVectorGraphics::eVectorGraphicsType::vgtMove: + oWriter.WriteString(L"<a:moveTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtLine: + oWriter.WriteString(L"<a:lnTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtCurve: + oWriter.WriteString(L"<a:cubicBezTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtClose: + default: + break; + } + + for(auto& point : path_command.points) + { + LONG lX = static_cast<LONG>((point.x - m_dLeft) * c_dMMToEMU); + LONG lY = static_cast<LONG>((point.y - m_dTop) * c_dMMToEMU); + + oWriter.WriteString(L"<a:pt x=\""); + oWriter.AddInt(static_cast<int>(lX)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast<int>(lY)); + oWriter.WriteString(L"\"/>"); + } + + switch (path_command.type) + { + case CVectorGraphics::eVectorGraphicsType::vgtMove: + oWriter.WriteString(L"</a:moveTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtLine: + oWriter.WriteString(L"</a:lnTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtCurve: + oWriter.WriteString(L"</a:cubicBezTo>"); + break; + + case CVectorGraphics::eVectorGraphicsType::vgtClose: + default: + break; + } + + } + oWriter.WriteString(L"<a:close/>"); + oWriter.WriteString(L"</a:path>"); + + std::wstring strPath = oWriter.GetData(); + oWriter.ClearNoAttack(); + return strPath; + } + + void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) noexcept + { + //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 (dHeight < 0.7) + { + if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltHLongDash; + } + else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltHDash; + } + else //максимальная точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltHDot; + } + } + else if (dWidth < 0.7) + { + if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman + { + m_eSimpleLineType = eSimpleLineType::sltVLongDash; + } + else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash + { + m_eSimpleLineType = eSimpleLineType::sltVDash; + } + else //максимальна точка - 0.5mm + { + m_eSimpleLineType = eSimpleLineType::sltVDot; + } + } + } + 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<const CShape> 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; + } + + void CShape::CheckLineType(std::shared_ptr<CShape>& 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<CShape>& pFirstShape, std::shared_ptr<CShape>& 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; + } + + // проверка на двойную линию + if(pFirstShape->m_eLineType == eLineType::ltDouble || pFirstShape->m_eLineType == eLineType::ltWavyDouble) + { + if(pFirstShape->m_eLineType == eLineType::ltDouble) + { + if(pFirstShape->m_dTop < pSecondShape->m_dTop) + { + pFirstShape->m_eLineType = eLineType::ltDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; + } + else + { + pSecondShape->m_eLineType = eLineType::ltDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; + } + } + else if(pFirstShape->m_eLineType == eLineType::ltWavyDouble) + { + if(pFirstShape->m_dTop < pSecondShape->m_dTop) + { + pFirstShape->m_eLineType = eLineType::ltWavyDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; + } + else + { + pSecondShape->m_eLineType = eLineType::ltWavyDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; + } + } + 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) + { + pFirstShape->m_eLineType = eLineType::ltDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; + } + else + { + pSecondShape->m_eLineType = eLineType::ltDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; + } + } + else if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave) + { + if (pFirstShape->m_dTop < pSecondShape->m_dTop) + { + pFirstShape->m_eLineType = eLineType::ltWavyDouble; + pFirstShape->RecalcWithNewItem(pSecondShape.get()); + pSecondShape = nullptr; + } + else + { + pSecondShape->m_eLineType = eLineType::ltWavyDouble; + pSecondShape->RecalcWithNewItem(pFirstShape.get()); + pFirstShape = nullptr; + } + } + 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()); + 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()); + pSecondShape = nullptr; + } + } + + void CShape::ToXml(NSStringUtils::CStringBuilder &oWriter) const + { + //todo для уменьшения размера каждого шейпа ипользовавать только то, что необходимо - для графики, текста, графика+текст + //todo добавить все возможные параметры/атрибуты + + oWriter.WriteString(L"<w:r>"); + oWriter.WriteString(L"<w:rPr><w:noProof/></w:rPr>"); //отключение проверки орфографии + oWriter.WriteString(L"<w:drawing>"); + BuildGeneralProperties(oWriter); + oWriter.WriteString(L"</w:drawing>"); + oWriter.WriteString(L"</w:r>"); + } + + void CShape::BuildGeneralProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"<wp:anchor"); + oWriter.WriteString(L" distT=\"0\""); //Определяет минимальное расстояние, которое должно сохраняться между краем + oWriter.WriteString(L" distB=\"0\""); //этого объекта рисования и любым последующим текстом в документе, когда + oWriter.WriteString(L" distL=\"0\""); //этот графический объект объект отображается в содержимом документа. + oWriter.WriteString(L" distR=\"0\""); + oWriter.WriteString(L" simplePos=\"0\""); //true/1 Указывает, что этот объект должен быть позиционирован с использованием информации о позиционировании в дочернем элементе simplePos + oWriter.WriteString(L" relativeHeight=\""); //Определяет относительное упорядочивание по Z всех объектов DrawingML в этом документе. + oWriter.AddUInt(m_nRelativeHeight); + oWriter.WriteString(L"\""); + oWriter.WriteString(L" behindDoc=\""); //позади текста - 1, перед текстом - 0 + oWriter.AddUInt(static_cast<UINT>(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"<wp:simplePos x=\"0\" y=\"0\"/>"); + + oWriter.WriteString(L"<wp:positionH relativeFrom=\"page\">"); + oWriter.WriteString(L"<wp:posOffset>"); + oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L"</wp:posOffset>"); + oWriter.WriteString(L"</wp:positionH>"); + + oWriter.WriteString(L"<wp:positionV relativeFrom=\"page\">"); + oWriter.WriteString(L"<wp:posOffset>"); + oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L"</wp:posOffset>"); + oWriter.WriteString(L"</wp:positionV>"); + + //координаты конца границы шейпа + oWriter.WriteString(L"<wp:extent"); + oWriter.WriteString(L" cx=\""); + oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"); //Этот элемент определяет дополнительное расстояние, которое должно быть добавлено к каждому краю изображения, чтобы компенсировать любые эффекты рисования, применяемые к объекту DrawingML + oWriter.WriteString(L"<wp:wrapNone/>"); + + oWriter.WriteString(L"<wp:docPr id=\""); + oWriter.AddUInt(GenerateShapeId()); + switch (m_eType) + { + case eShapeType::stTextBox: + oWriter.WriteString(L"\" name=\"Text Box "); + break; + case eShapeType::stPicture: + oWriter.WriteString(L"\" name=\"Picture "); + break; + case eShapeType::stVectorGraphics: + oWriter.WriteString(L"\" name=\"Freeform: Shape "); + break; + case eShapeType::stVectorTexture: + oWriter.WriteString(L"\" name=\"Freeform: Texture "); + break; + case eShapeType::stCanvas: + oWriter.WriteString(L"\" name=\"Canvas "); + break; + case eShapeType::stGroup: + oWriter.WriteString(L"\" name=\"Group "); + break; + default: + oWriter.WriteString(L"\" name=\"Shape "); + break; + } + oWriter.AddUInt(m_nShapeId); + //oWriter.WriteString(L" descr=\"Alt Text!\""); //Коммент к картинке + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"<wp:cNvGraphicFramePr/>"); + + BuildSpecificProperties(oWriter); + + oWriter.WriteString(L"</wp:anchor>"); + } + + void CShape::BuildSpecificProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"); + + 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"</a:graphic>"); + } + + void CShape::BuildShapeProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"); + + oWriter.WriteString(L"<wps:wsp>"); + + oWriter.WriteString(L"<wps:cNvSpPr/>"); //non-visual shape properties. http://officeopenxml.com/drwSp-nvSpPr.php + + oWriter.WriteString(L"<wps:spPr>"); //shape properties. http://officeopenxml.com/drwSp-SpPr.php + + //не работает + //oWriter.WriteString(L"<wps:style/>"); //shape styles. http://officeopenxml.com/drwSp-styles.php + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L"</wps:spPr>"); + + BuildTextBox(oWriter); + + oWriter.WriteString(L"</wps:wsp>"); + + oWriter.WriteString(L"</a:graphicData>"); + } + + void CShape::BuildPictureProperties(NSStringUtils::CStringBuilder &oWriter) const + { + // TODO: Clip path as geometry + tile!!! + + oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); + + oWriter.WriteString(L"<pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); + oWriter.WriteString(L"<pic:nvPicPr>"); + oWriter.WriteString(L"<pic:cNvPr id=\""); + oWriter.AddUInt(m_pImageInfo->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"<pic:cNvPicPr preferRelativeResize=\"0\">"); + oWriter.WriteString(L"<a:picLocks noChangeArrowheads=\"1\"/>"); + oWriter.WriteString(L"</pic:cNvPicPr>"); + oWriter.WriteString(L"</pic:nvPicPr>"); + oWriter.WriteString(L"<pic:blipFill>"); + oWriter.WriteString(L"<a:blip r:embed=\"rId"); + oWriter.AddUInt(c_iStartingIdForImages + m_pImageInfo->m_nId); + oWriter.WriteString(L"\">"); + oWriter.WriteString(L"<a:alphaModFix/>"); + oWriter.WriteString(L"</a:blip>"); + oWriter.WriteString(L"<a:srcRect/>"); + oWriter.WriteString(L"<a:stretch>"); + oWriter.WriteString(L"<a:fillRect/>"); + oWriter.WriteString(L"</a:stretch>"); + oWriter.WriteString(L"</pic:blipFill>"); + oWriter.WriteString(L"<pic:spPr bwMode=\"auto\">"); + + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + + oWriter.WriteString(L"</pic:spPr>"); + oWriter.WriteString(L"</pic:pic>"); + + oWriter.WriteString(L"</a:graphicData>"); + } + + void CShape::BuildGroupProperties(NSStringUtils::CStringBuilder &oWriter) const + { + oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\">"); + oWriter.WriteString(L"<wpg:wgp>"); + oWriter.WriteString(L"<wpg:cNvGrpSpPr/>"); + oWriter.WriteString(L"<wpg:grpSpPr>"); + BuildForm(oWriter); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L"</wpg:grpSpPr>"); + + //todo довабить любое количество элементов в группе + BuildPictureProperties(oWriter); + BuildShapeProperties(oWriter); + + oWriter.WriteString(L"</wps:wsp>"); + oWriter.WriteString(L"</wpg:wgp>"); + oWriter.WriteString(L"</a:graphicData>"); + } + + void CShape::BuildCanvasProperties(NSStringUtils::CStringBuilder &oWriter) const + { + //todo добавить реализацию + oWriter.WriteString(L"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\">"); + } + + void CShape::BuildGraphicProperties(NSStringUtils::CStringBuilder &oWriter) const + { + std::wstring strPath = PathToWString(); + + //Если просто текст без графики + if (strPath.empty()) + { + oWriter.WriteString(L"<a:prstGeom prst=\"rect\">"); + oWriter.WriteString(L"<a:avLst/>"); + oWriter.WriteString(L"</a:prstGeom>"); + } + else + { + //Рисуем сложный путь + oWriter.WriteString(L"<a:custGeom>"); + oWriter.WriteString(L"<a:avLst/>"); + oWriter.WriteString(L"<a:gdLst/>"); + oWriter.WriteString(L"<a:ahLst/>"); + oWriter.WriteString(L"<a:cxnLst/>"); + oWriter.WriteString(L"<a:rect l=\"l\" t=\"t\" r=\"r\" b=\"b\"/>"); + oWriter.WriteString(L"<a:pathLst>"); + oWriter.WriteString(strPath); + oWriter.WriteString(L"</a:pathLst>"); + oWriter.WriteString(L"</a:custGeom>"); + } + + if (m_bIsNoFill) + { + //Нет заливки + oWriter.WriteString(L"<a:noFill/>"); + } + else + { + //Есть заливка + oWriter.WriteString(L"<a:solidFill>"); + oWriter.WriteString(L"<a:srgbClr val=\""); + oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oBrush.Color1))); + if (0xFF != m_oBrush.TextureAlpha) + { + oWriter.WriteString(L"\"><a:alpha val=\""); + oWriter.AddInt(static_cast<int>(m_oBrush.TextureAlpha / 255.0 * 100.0)); + oWriter.WriteString(L"%\"/></a:srgbClr>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + oWriter.WriteString(L"</a:solidFill>"); + } + + if (m_bIsNoStroke) + { + oWriter.WriteString(L"<a:ln>"); // w - width по умолчанию 0.75pt = 9525 + oWriter.WriteString(L"<a:noFill/>"); + oWriter.WriteString(L"</a:ln>"); + } + else + { + oWriter.WriteString(L"<a:ln w=\""); + //todo Некоторые m_oPen.Size приходят увеличенными в 10 раз + oWriter.AddInt(static_cast<int>(m_oPen.Size * c_dMMToEMU)); //note можно писать в мм + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L"<a:solidFill>"); + + oWriter.WriteString(L"<a:srgbClr val=\""); + oWriter.WriteHexInt3(static_cast<int>(ConvertColorBGRToRGB(m_oPen.Color))); //note можно вместо цвета использовать слова типа "black" + if (0xFF != m_oPen.Alpha) + { + oWriter.WriteString(L"\"><a:alpha val=\""); + oWriter.AddInt(static_cast<int>(m_oPen.Alpha / 255.0 * 100.0)); + oWriter.WriteString(L"%\"/></a:srgbClr>"); + } + else + { + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"</a:solidFill>"); + oWriter.WriteString(L"</a:ln>"); + } + } + + void CShape::BuildForm(NSStringUtils::CStringBuilder &oWriter, const bool& bIsLT) const + { + // отвечает за размеры прямоугольного фрейма шейпа + oWriter.WriteString(L"<a:xfrm"); + if (fabs(m_dRotate) > 0.01) + { + oWriter.WriteString(L" rot=\""); + oWriter.AddInt(static_cast<int>(m_dRotate * c_dDegreeToAngle)); + oWriter.WriteString(L"\""); + } + oWriter.WriteString(L">"); + + if (!bIsLT) + { + oWriter.WriteString(L"<a:off x=\"0\" y=\"0\"/>"); + } + else + { + oWriter.WriteString(L"<a:off x=\""); + oWriter.AddInt(static_cast<int>(m_dLeft * c_dMMToEMU)); + oWriter.WriteString(L"\" y=\""); + oWriter.AddInt(static_cast<int>(m_dTop * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + } + + oWriter.WriteString(L"<a:ext"); + oWriter.WriteString(L" cx=\""); + oWriter.AddInt(static_cast<int>(m_dWidth * c_dMMToEMU)); + oWriter.WriteString(L"\" cy=\""); + oWriter.AddInt(static_cast<int>(m_dHeight * c_dMMToEMU)); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"</a:xfrm>"); + } + + 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"<a:prstTxWarp prst=\"textNoShape\">"); + oWriter.WriteString(L"<a:avLst/>"); + oWriter.WriteString(L"</a:prstTxWarp>"); + oWriter.WriteString(L"<a:noAutofit/>"); + } + + void CShape::BuildTextBox(NSStringUtils::CStringBuilder &oWriter) const + { + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L"<wps:txbx>"); //text within the shape. http://officeopenxml.com/drwSp-text.php + oWriter.WriteString(L"<w:txbxContent>"); + for (size_t i = 0; i < m_arOutputObjects.size(); ++i) + { + auto pObj = m_arOutputObjects[i]; + pObj->ToXml(oWriter); + } + oWriter.WriteString(L"</w:txbxContent>"); + oWriter.WriteString(L"</wps:txbx>"); + + oWriter.WriteString(L"<wps:bodyPr"); //определяет свойства тела текста внутри фигуры + BuildTextBoxParams(oWriter); + oWriter.WriteString(L"</wps:bodyPr>"); + } + else + { + oWriter.WriteString(L"<wps:bodyPr/>"); + } + } + void CShape::ToXmlPptx(NSStringUtils::CStringBuilder &oWriter) const + { + if (m_eType == eShapeType::stPicture || + m_eType == eShapeType::stVectorTexture) + { + // TODO: Clip path as geometry + tile!!! + oWriter.WriteString(L"<p:pic>"); + oWriter.WriteString(L"<p:nvPicPr>"); + oWriter.WriteString(L"<p:cNvPr id=\""); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\" name=\"Picture "); + oWriter.AddUInt(m_pImageInfo->m_nId); + oWriter.WriteString(L"\"/>"); + oWriter.WriteString(L"<p:cNvPicPr><a:picLocks noChangeAspect=\"1\"/></p:cNvPicPr>"); + oWriter.WriteString(L"<p:nvPr/>"); + oWriter.WriteString(L"</p:nvPicPr>"); + + oWriter.WriteString(L"<p:blipFill>"); + oWriter.WriteString(L"<a:blip r:embed=\"rId"); + oWriter.AddUInt(c_iStartingIdForImages + m_pImageInfo->m_nId); + oWriter.WriteString(L"\">"); + oWriter.WriteString(L"</a:blip>"); + oWriter.WriteString(L"<a:stretch><a:fillRect/></a:stretch>"); + oWriter.WriteString(L"</p:blipFill>"); + + oWriter.WriteString(L"<p:spPr>"); + BuildForm(oWriter, true); + oWriter.WriteString(L"<a:prstGeom prst=\"rect\">"); + oWriter.WriteString(L"<a:avLst/>"); + oWriter.WriteString(L"</a:prstGeom>"); + oWriter.WriteString(L"</p:spPr>"); + oWriter.WriteString(L"</p:pic>"); + return; + } + + oWriter.WriteString(L"<p:sp>"); + oWriter.WriteString(L"<p:spPr>"); + + BuildForm(oWriter, true); + BuildGraphicProperties(oWriter); + oWriter.WriteString(L"</p:spPr>"); + + if (m_eType == eShapeType::stTextBox && !m_arOutputObjects.empty()) + { + oWriter.WriteString(L"<a:txBody>"); + oWriter.WriteString(L"<a:bodyPr"); + BuildTextBoxParams(oWriter); + oWriter.WriteString(L"</a:bodyPr>"); + + for (const auto& obj : m_arOutputObjects) + obj->ToXmlPptx(oWriter); + + oWriter.WriteString(L"</a:txBody>"); + } + oWriter.WriteString(L"</p:sp>"); + } + + }; // namespace NSDocxRenderer diff --git a/DocxRenderer/src/logic/elements/Shape.h b/DocxRenderer/src/logic/elements/Shape.h index a96207695ae..e6b2477b2a4 100644 --- a/DocxRenderer/src/logic/elements/Shape.h +++ b/DocxRenderer/src/logic/elements/Shape.h @@ -1,91 +1,108 @@ #pragma once #include "Paragraph.h" +#include "TextLine.h" #include "../../resources/ImageInfo.h" #include "../../resources/LinesTable.h" #include "../../resources/VectorGraphics.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<CParagraph*> m_arParagraphs; - - std::shared_ptr<CImageInfo> 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<CImageInfo> 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 COutputObject + { + public: + enum class eShapeType + { + stUnknown, + stTextBox, + stPicture, + stVectorGraphics, + stVectorTexture, + stGroup, + stCanvas, + }; + + public: + eShapeType m_eType {eShapeType::stUnknown}; + + NSStructures::CBrush m_oBrush{}; + NSStructures::CPen m_oPen {}; + + CVectorGraphics m_oVector {}; + std::wstring m_strDstMedia {}; + + double m_dRotate {0.0}; + + bool m_bIsNoFill {true}; + bool m_bIsNoStroke {true}; + bool m_bIsBehindDoc {true}; + bool m_bIsUseInTable{false}; + + eGraphicsType m_eGraphicsType {eGraphicsType::gtUnknown}; + eSimpleLineType m_eSimpleLineType{eSimpleLineType::sltUnknown}; + eLineType m_eLineType {eLineType::ltUnknown}; + + std::vector<std::shared_ptr<COutputObject>> m_arOutputObjects; + std::shared_ptr<CImageInfo> m_pImageInfo{nullptr}; + + private: + + + public: + CShape(); + CShape(std::shared_ptr<CImageInfo> 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); + + // tries merge shape, return true if ok and pShape was deleted + bool TryMergeShape(std::shared_ptr<CShape>& 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<const CShape> pShape) const noexcept; + + bool IsPeak() const noexcept; + bool IsSide() 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; + + static void ResetRelativeHeight(); + + // check type of line and delete not needed shape + // one shape in line + static void CheckLineType(std::shared_ptr<CShape>& pShape); + + // many shapes in line + static void CheckLineType(std::shared_ptr<CShape>& pFirstShape, std::shared_ptr<CShape>& 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/TextLine.cpp b/DocxRenderer/src/logic/elements/TextLine.cpp index 96d38113cee..b63318a0282 100644 --- a/DocxRenderer/src/logic/elements/TextLine.cpp +++ b/DocxRenderer/src/logic/elements/TextLine.cpp @@ -1,301 +1,270 @@ #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<const CTextLine*>(oSrc)->m_dBaselinePos) ? true : false; - } - - bool CTextLine::IsBiggerOrEqual(const CBaseItem* oSrc) - { - return (m_dBaselinePos >= dynamic_cast<const CTextLine*>(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(); + } + void CTextLine::AddCont(std::shared_ptr<CContText> oCont) + { + RecalcWithNewItem(oCont.get()); + m_arConts.push_back(oCont); + } + + bool CTextLine::IsCanBeDeleted() const + { + for (size_t i = 0; i < m_arConts.size(); ++i) + if (m_arConts[i]) + return false; + + return true; + } + + void CTextLine::MergeConts() + { + if (m_arConts.empty()) + return; + + using cont_ptr_t = std::shared_ptr<CContText>; + 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<CContText> 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 dSpaceDefaultSize = pCurrent->CalculateThinSpace(); + double dSpaceWideSize = pCurrent->CalculateWideSpace(); + double dDifference = fabs(pCurrent->m_dLeft - pFirst->m_dRight); + + bool bIsEqual = pFirst->IsEqual(pCurrent.get()); + bool bIsBigDelta = dDifference > dSpaceDefaultSize; + bool bIsVeryBigDelta = dDifference > dSpaceWideSize; + + if (bIsBigDelta && pFirst->m_dFirstWordWidth == 0.0) + pFirst->m_dFirstWordWidth = pFirst->m_dWidth; + + if (bIsVeryBigDelta) + { + auto wide_space = std::make_shared<CContText>(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_oText = L" "; + wide_space->m_pFontStyle = pFirst->m_pFontStyle; + wide_space->m_pShape = nullptr; + wide_space->m_iNumDuplicates = 0; + + // cache that value? (calls rarely) + wide_space->CalcSelected(); + }; + + if (bIsEqual) + { + // assign all + *wide_space = *pFirst; + + // then set all for wide space + set_base(); + } + else + set_base(); + + m_arConts.insert(m_arConts.begin() + i, wide_space); + + i++; + while (!m_arConts[i]) i++; + pFirst = m_arConts[i]; + } + else if (bIsEqual) + { + if (!bIsBigDelta) + { + pFirst->m_oText += pCurrent->m_oText; + } + else + { + pFirst->m_oText += uint32_t(' '); + pFirst->m_oText += pCurrent->m_oText; + } + + pFirst->m_dWidth = pCurrent->m_dRight - pFirst->m_dLeft; + pFirst->m_dRight = pCurrent->m_dRight; + + if (pFirst->m_pCont.expired()) + { + pFirst->m_pCont = pCurrent->m_pCont; + pFirst->m_eVertAlignType = pCurrent->m_eVertAlignType; + } + pCurrent = nullptr; + } + 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 += (pCurrent->m_dLeft - pFirst->m_dRight); + } + else + { + NSStringUtils::CStringUTF32 oNewText = L" "; + oNewText += pCurrent->m_oText; + pCurrent->m_oText = oNewText; + pCurrent->m_dWidth += (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<CContText>; + 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::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->m_oText.length(); + + return len; + } } diff --git a/DocxRenderer/src/logic/elements/TextLine.h b/DocxRenderer/src/logic/elements/TextLine.h index 3f0d7477bb2..fdb9bd25875 100644 --- a/DocxRenderer/src/logic/elements/TextLine.h +++ b/DocxRenderer/src/logic/elements/TextLine.h @@ -1,57 +1,52 @@ #pragma once #include "ContText.h" +#include "BaseItem.h" + namespace NSDocxRenderer { - class CTextLine : public CBaseItem - { - public: - enum AssumedTextAlignmentType - { - atatUnknown, - atatByLeftEdge, - atatByCenter, - atatByRightEdge, - atatByWidth - }; - - std::vector<CContText*> 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<std::shared_ptr<CContText>> m_arConts; + + AssumedTextAlignmentType m_eAlignmentType{atatUnknown}; + eVertAlignType m_eVertAlignType {eVertAlignType::vatUnknown}; + + std::shared_ptr<CTextLine> m_pLine; + std::shared_ptr<CShape> m_pDominantShape {nullptr}; + + UINT m_iNumDuplicates {0}; + + double m_dTopWithMaxAscent{0}; + double m_dBotWithMaxDescent{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<CContText> pCont); + void MergeConts(); + void RecalcSizes(); + void SetVertAlignType(const eVertAlignType& oType); + + bool IsShadingPresent(const CTextLine* pLine) const noexcept; + bool IsCanBeDeleted() const; + + size_t GetLength() const; + }; } diff --git a/DocxRenderer/src/logic/managers/ExternalImageStorage.h b/DocxRenderer/src/logic/managers/ExternalImageStorage.h new file mode 100644 index 00000000000..1784da1a7b9 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ExternalImageStorage.h @@ -0,0 +1,28 @@ +#pragma once +#include "../../../../DesktopEditor/raster/BgraFrame.h" +#include "../../resources/ImageInfo.h" +#include <map> +#include <memory> + +#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<CImageInfo> 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..62d75cce640 100644 --- a/DocxRenderer/src/logic/managers/FontManager.cpp +++ b/DocxRenderer/src/logic/managers/FontManager.cpp @@ -1,258 +1,780 @@ #include "FontManager.h" #include "../../resources/Constants.h" +#include "../../../../DesktopEditor/xml/include/xmlutils.h" +#include "../../../../DesktopEditor/common/Directory.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<std::wstring, CFontTableEntry>(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<std::wstring, CFontTableEntry>(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<CUnicodeRange>::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::CFontSelectInfo>& 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, + NSStringUtils::CStringUTF32& oText) + { + BYTE lRangeNum = 0xFF; + BYTE lRange = 0xFF; + + m_oRanges.CheckRange(oText[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); + + 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(oFontSelectParams.bDefaultBold); + oFormat.bItalic = new INT(oFontSelectParams.bDefaultItalic); + 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); + +// oFormat.shAscent = new SHORT(oFontMetrics.dAscent); +// oFormat.shDescent = new SHORT(oFontMetrics.dDescent); + + 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"); + CheckFontNameStyle(wsName, L"semibold"); + 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); + } + + void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont) + { + if(m_oFont.IsEqual2(&oFont)) + return; + + m_oFont = oFont; + m_pManager->LoadFontFromFile(m_oFont.Path, (int)m_oFont.FaceIndex, (float)m_oFont.Size, c_dDpiX, c_dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontSelectParams(); + + if (m_oFontSelectParams.wsDefaultName.empty()) + m_oFontSelectParams.wsDefaultName = m_oFont.Name; + + CheckPdfResources(); + } + void CFontManager::LoadFontByName(const NSStructures::CFont& oFont) + { + if(m_oFont.IsEqual2(&oFont)) + return; + + m_oFont = oFont; + m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY); + m_pManager->AfterLoad(); + + LoadFontMetrics(); + LoadFontSelectParams(); + } + + 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..04f440aeca0 100644 --- a/DocxRenderer/src/logic/managers/FontManager.h +++ b/DocxRenderer/src/logic/managers/FontManager.h @@ -1,96 +1,164 @@ #pragma once -#include "FontManagerBase.h" -#include "../DesktopEditor/graphics/Matrix.h" +#include <list> +#include <vector> + +#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<UINT> m_arSignature; - bool m_bIsFixedWidth {false}; - - public: - CFontTableEntry(){} - virtual ~CFontTableEntry(){} - - CFontTableEntry(const CFontTableEntry& oSrc); - - CFontTableEntry& operator =(const CFontTableEntry& oSrc); - }; - - class CFontTable - { - public: - std::map<std::wstring, CFontTableEntry> 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<CUnicodeRange> 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<UINT> 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, + NSStringUtils::CStringUTF32& oText); + std::wstring GetSelectedName() const noexcept; + bool IsSelectedBold() const noexcept; + bool IsSelectedItalic() const noexcept; + + const std::list<CFontSelectInfo>& GetCache() const; + void ClearCache(); + + private: + std::list<CFontSelectInfo> 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(); + + void LoadFontByFile(const NSStructures::CFont& oFont); + void 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<CUnicodeRange>::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<CFontPickUp>::iterator posStart, pos; - posStart = pos = m_arListPicUps.begin(); - - while (m_arListPicUps.end() != pos) - { - std::list<CFontPickUp>::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 <list> - -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<CUnicodeRange> 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<UINT> 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<CFontPickUp> 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..619e542d1e5 --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.cpp @@ -0,0 +1,74 @@ +#include "FontStyleManager.h" +#include <utility> + +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<const CFontStyle> CFontStyleManager::GetOrAddFontStyle(const CFontStyle& oFontStyle) + { + return GetOrAddFontStyle(oFontStyle.oBrush, + oFontStyle.wsFontName, + oFontStyle.dFontSize, + oFontStyle.bItalic, + oFontStyle.bBold); + } + std::shared_ptr<const CFontStyle> 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<CFontStyle>(); + 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..a46075fd97b --- /dev/null +++ b/DocxRenderer/src/logic/managers/FontStyleManager.h @@ -0,0 +1,28 @@ +#pragma once +#include <list> + +#include "../styles/FontStyle.h" + +namespace NSDocxRenderer +{ + class CFontStyleManager + { + public: + CFontStyleManager(); + ~CFontStyleManager(); + + void Clear(); + void ToXml(NSStringUtils::CStringBuilder& oWriter); + + std::shared_ptr<const CFontStyle> GetOrAddFontStyle(const CFontStyle& oFontStyle); + std::shared_ptr<const CFontStyle> GetOrAddFontStyle(const NSStructures::CBrush& oBrush, + const std::wstring& wsFontName, + double dFontSize, + bool bItalic, + bool bBold); + + private: + std::list<std::shared_ptr<CFontStyle>> m_arFontStyles; + }; +} + diff --git a/DocxRenderer/src/logic/managers/ImageManager.cpp b/DocxRenderer/src/logic/managers/ImageManager.cpp index 6483fdd6aa8..ad08a20e491 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.cpp +++ b/DocxRenderer/src/logic/managers/ImageManager.cpp @@ -1,13 +1,134 @@ #include "ImageManager.h" -#include "../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../resources/Constants.h" namespace NSDocxRenderer { - void CImageManager::NewDocument() + IImageStorage::IImageStorage(){} + IImageStorage::~IImageStorage(){} + + class CDataImageStorage : public IImageStorage + { + private: + std::map<DWORD, std::shared_ptr<CImageInfo>> m_mapImageData; + std::map<int, std::string> m_mapImages; + + int m_lMaxSizeImage{1200}; + int m_lNextIDImage{0}; + + CCalculatorCRC32 m_oCRC; + + public: + CDataImageStorage() : IImageStorage() + { + } + virtual ~CDataImageStorage() + { + } + + virtual std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage) + { + BYTE* pData = pImage->GetData(); + DWORD nWidth = pImage->GetWidth(); + DWORD nHeight = pImage->GetHeight(); + long nStride = pImage->GetStride(); + + int nSize = pImage->GetStride() * nHeight; + if (nSize < 0) + nSize = -nSize; + + DWORD dwSum = m_oCRC.Calc(pData, nSize); + + auto find = m_mapImageData.find(dwSum); + if (find != m_mapImageData.end()) + return find->second; + + ++m_lNextIDImage; + + auto pInfo = std::make_shared<NSDocxRenderer::CImageInfo>(); + 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"); + + CBgraFrame oBgraFrame; + oBgraFrame.put_Width(nWidth); + oBgraFrame.put_Height(nHeight); + oBgraFrame.put_Stride(nStride); + oBgraFrame.put_Data(pData); + bool bIsResized = false; + + 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); + } + + BYTE* pEncodeBuffer = NULL; + int nEncodeBufferSize = 0; + oBgraFrame.Encode(pEncodeBuffer, nEncodeBufferSize, (pInfo->m_eType == CImageInfo::itJPG) ? 3 : 4); + + if (!bIsResized) + oBgraFrame.put_Data(NULL); + + int nBase64DataSize = NSBase64::Base64EncodeGetRequiredLength(nEncodeBufferSize); + int nHeaderSize = (pInfo->m_eType == CImageInfo::itPNG) ? 22 : 23; + + 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); + + NSBase64::Base64Encode(pEncodeBuffer, nEncodeBufferSize, (BYTE*)pBase64Data + nHeaderSize, &nBase64DataSize, NSBase64::B64_BASE64_FLAG_NOCRLF); + RELEASEARRAYOBJECTS(pEncodeBuffer); + + m_mapImages.insert(std::pair<int, std::string>((int)pInfo->m_nId, std::string(pBase64Data, nHeaderSize + nBase64DataSize))); + RELEASEARRAYOBJECTS(pBase64Data); + + m_mapImageData.insert(std::pair<DWORD, std::shared_ptr<CImageInfo>>(dwSum, pInfo)); + return pInfo; + } + + virtual std::string* GetBase64(const int& nRId) + { + std::map<int, std::string>::iterator iter = m_mapImages.find(nRId - c_iStartingIdForImages); + if (iter == m_mapImages.end()) + return NULL; + + return &iter->second; + } + }; + + IImageStorage* CreateWasmImageStorage() + { + return new CDataImageStorage(); + } +} + +namespace NSDocxRenderer +{ + void CImageManager::Clear() { - m_strDstMedia = L""; + m_strDstMedia = L""; m_lMaxSizeImage = 1200; - m_lNextIDImage = 0; + m_lNextIDImage = 0; m_mapImageData.clear(); m_mapImagesFile.clear(); @@ -35,27 +156,11 @@ namespace NSDocxRenderer NSFile::CFileBinary::Copy(strFileSrc, strFileDst); } - void CImageManager::SaveEmptyImage(std::shared_ptr<CImageInfo> pInfo) + void CImageManager::SaveImage(const std::wstring& strFileSrc, std::shared_ptr<CImageInfo> pInfo) { - Aggplus::CImage oFrame; - - int nW = 10; - int nH = 10; - int nMax = nW * nH; - BYTE* pDataExternal = new BYTE[nMax * 4]; - memset(pDataExternal, 0xFF, 4 * nMax); - - BYTE* pDataCurrent = pDataExternal + 3; - for (int i = 0; i < nMax; i++, pDataCurrent += 4) - *pDataCurrent = 0; - - oFrame.Create(pDataExternal, nW, nH, 4 * nW, true); - - pInfo->m_eType = CImageInfo::itPNG; - pInfo->m_strFileName += (L"image" + std::to_wstring(pInfo->m_nId) + L".png"); - - oFrame.SaveFile(m_strDstMedia + L"/" + pInfo->m_strFileName, 4); - delete[] pDataExternal; + Aggplus::CImage oFrame(strFileSrc); + if (nullptr != oFrame.GetData()) + return SaveImage(&oFrame, pInfo); } void CImageManager::SaveImage(Aggplus::CImage* pImage, std::shared_ptr<CImageInfo> pInfo) @@ -102,6 +207,9 @@ namespace NSDocxRenderer std::shared_ptr<CImageInfo> CImageManager::GenerateImageID(Aggplus::CImage* pImage) { + if (m_pExternalStorage) + return m_pExternalStorage->GenerateImageID(pImage); + BYTE* pData = pImage->GetData(); int nSize = pImage->GetStride() * pImage->GetHeight(); if (nSize < 0) @@ -128,29 +236,10 @@ namespace NSDocxRenderer if (find != m_mapImagesFile.end()) return find->second; - Aggplus::CImage oFrame(strFileName); - - if (nullptr == oFrame.GetData()) - { - if (m_pEmptyInfo) - return m_pEmptyInfo; - - ++m_lNextIDImage; - m_pEmptyInfo = std::make_shared<CImageInfo>(); - 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; - } - ++m_lNextIDImage; auto pInfo = std::make_shared<CImageInfo>(); pInfo->m_nId = m_lNextIDImage; - SaveImage(&oFrame, pInfo); + SaveImage(strFileName, pInfo); m_mapImagesFile.insert(std::pair<std::wstring, std::shared_ptr<CImageInfo>>(strFileName, pInfo)); return pInfo; @@ -201,8 +290,8 @@ namespace NSDocxRenderer memcpy(pBuffer, pBufferEnd, stride); memcpy(pBufferEnd, pBufferMem, stride); - pBuffer += stride; - pBufferEnd -= stride; + pBuffer += stride; + pBufferEnd -= stride; } RELEASEARRAYOBJECTS(pBufferMem); @@ -224,7 +313,7 @@ namespace NSDocxRenderer if ((w * 4) != stride) return; - DWORD* pBufferDWORD = (DWORD*)pBuffer; + DWORD* pBufferDWORD = (DWORD*)pBuffer; LONG lW2 = w / 2; for (LONG lIndexV = 0; lIndexV < h; ++lIndexV) @@ -241,4 +330,4 @@ namespace NSDocxRenderer } } } -} // namespace NSDocxRenderer +} diff --git a/DocxRenderer/src/logic/managers/ImageManager.h b/DocxRenderer/src/logic/managers/ImageManager.h index bcd2b45db47..67a9119df56 100644 --- a/DocxRenderer/src/logic/managers/ImageManager.h +++ b/DocxRenderer/src/logic/managers/ImageManager.h @@ -1,30 +1,29 @@ #pragma once -#include "../DesktopEditor/common/CalculatorCRC32.h" -#include "../DesktopEditor/raster/BgraFrame.h" -#include "../../resources/ImageInfo.h" -#include <map> -#include <memory> +#include "../../../../DesktopEditor/common/CalculatorCRC32.h" +#include "./ExternalImageStorage.h" namespace NSDocxRenderer { class CImageManager { public: - std::map<std::wstring, std::shared_ptr<CImageInfo>> m_mapImagesFile; - std::map<DWORD, std::shared_ptr<CImageInfo>> m_mapImageData; - std::shared_ptr<CImageInfo> m_pEmptyInfo; + std::map<std::wstring, std::shared_ptr<CImageInfo>> m_mapImagesFile; + std::map<DWORD, std::shared_ptr<CImageInfo>> m_mapImageData; - std::wstring m_strDstMedia{L""}; + std::wstring m_strDstMedia {L""}; - int m_lMaxSizeImage{1200}; - int m_lNextIDImage{0}; + int m_lMaxSizeImage {1200}; + int m_lNextIDImage {0}; - CCalculatorCRC32 m_oCRC; + CCalculatorCRC32 m_oCRC; + + IImageStorage* m_pExternalStorage = nullptr; public: + CImageManager(){}; - void NewDocument(); + void Clear(); public: std::shared_ptr<CImageInfo> WriteImage(Aggplus::CImage* pImage, double& x, double& y, double& width, double& height); @@ -34,18 +33,18 @@ namespace NSDocxRenderer protected: void CopyFile(std::wstring& strFileSrc, std::wstring& strFileDst); - void SaveImage(Aggplus::CImage* pImage, std::shared_ptr<CImageInfo> pInfo); + void SaveImage(const std::wstring& strFileSrc, std::shared_ptr<CImageInfo> pInfo); - void SaveEmptyImage(std::shared_ptr<CImageInfo> pInfo); - - std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage); + void SaveImage(Aggplus::CImage* pImage, std::shared_ptr<CImageInfo> pInfo); std::shared_ptr<CImageInfo> GenerateImageID(const std::wstring& strFileName); - CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); - void FlipY(Aggplus::CImage* pImage); void FlipX(CBgraFrame* pImage); + + public: + static CImageInfo::ImageType GetImageType(Aggplus::CImage* pFrame); + std::shared_ptr<CImageInfo> GenerateImageID(Aggplus::CImage* pImage); }; -} // namespace NSDocxRenderer +} diff --git a/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp new file mode 100644 index 00000000000..97d12ff7785 --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.cpp @@ -0,0 +1,58 @@ +#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..fce153122ce --- /dev/null +++ b/DocxRenderer/src/logic/managers/ParagraphStyleManager.h @@ -0,0 +1,29 @@ +#pragma once +#include <list> +#include <memory> + +#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<CParagraphStyle> m_arDefaultParagraphStyles; + // std::list<CParagraphStyle> 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 <utility> - -namespace NSDocxRenderer -{ - CStyleManager::CStyleManager() - { - m_pCurrentStyle = std::make_shared<CFontStyle>(); - } - - CStyleManager::~CStyleManager() - { - Clear(); - } - - void CStyleManager::Clear() - { - m_arStyles.clear(); - } - - void CStyleManager::NewDocument() - { - Clear(); - } - - std::shared_ptr<CFontStyle> 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<CFontStyle>(); - - 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 <vector> -#include "../styles/FontStyle.h" - -namespace NSDocxRenderer -{ - class CStyleManager - { - public: - std::vector<std::shared_ptr<CFontStyle>> m_arStyles; - - std::shared_ptr<CFontStyle> m_pCurrentStyle; - - public: - CStyleManager(); - virtual ~CStyleManager(); - - void Clear(); - - void NewDocument(); - - std::shared_ptr<CFontStyle> 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..1fb978b6513 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.cpp +++ b/DocxRenderer/src/logic/styles/FontStyle.cpp @@ -4,169 +4,115 @@ 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<CFontStyle> 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"<w:style"); - oWriter.WriteString(L" w:type=\"character\""); - oWriter.WriteString(L" w:customStyle=\"1\""); - oWriter.WriteString(L" w:styleId=\""); - oWriter.WriteString(m_strStyleId); - oWriter.WriteString(L"\">"); - - oWriter.WriteString(L"<w:name w:val=\""); - oWriter.WriteString(m_strStyleId); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"<w:basedOn w:val=\""); - oWriter.WriteString(L"DefaultParagraphFont"); //todo сделать дерево зависимостей - oWriter.WriteString(L"\"/>"); - - //oWriter.WriteString(L"<w:rsid w:val=\"00BB76B0\"/>"); - - oWriter.WriteString(L"<w:rPr>"); - - std::wstring& strFontName = m_strPickFontName.empty() ? m_oFont.Name : m_strPickFontName; - oWriter.WriteString(L"<w:rFonts w:ascii=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:hAnsi=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:cs=\""); - oWriter.WriteEncodeXmlString(strFontName); - oWriter.WriteString(L"\" w:hint=\"default\"/>"); - - if (m_strPickFontName.empty()) - { - if (m_oFont.Bold) - { - oWriter.WriteString(L"<w:b/>"); - oWriter.WriteString(L"<w:bCs/>"); - } - if (m_oFont.Italic) - { - oWriter.WriteString(L"<w:i/>"); - oWriter.WriteString(L"<w:iCs/>"); - } - } - else - { - if (0x01 == (0x01 & m_lPickFontStyle)) - { - oWriter.WriteString(L"<w:b/>"); - oWriter.WriteString(L"<w:bCs/>"); - } - if (0x02 == (0x02 & m_lPickFontStyle)) - { - oWriter.WriteString(L"<w:i/>"); - oWriter.WriteString(L"<w:iCs/>"); - } - } - - if (ConvertColorBGRToRGB(m_oBrush.Color1) != c_iBlackColor2) - { - oWriter.WriteString(L"<w:color w:val=\""); - oWriter.WriteHexInt3(ConvertColorBGRToRGB(m_oBrush.Color1)); - oWriter.WriteString(L"\"/>"); - } - - int lSize = static_cast<int>(2 * m_oFont.Size); - oWriter.WriteString(L"<w:sz w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/><w:szCs w:val=\""); - oWriter.AddInt(lSize); - oWriter.WriteString(L"\"/>"); - - oWriter.WriteString(L"</w:rPr>"); - - oWriter.WriteString(L"</w:style>"); - } + 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"<w:style"); + oWriter.WriteString(L" w:type=\"character\""); + oWriter.WriteString(L" w:customStyle=\"1\""); + oWriter.WriteString(L" w:styleId=\""); + oWriter.WriteString(wsFontStyleId); + oWriter.WriteString(L"\">"); + + oWriter.WriteString(L"<w:name w:val=\""); + oWriter.WriteString(wsFontStyleId); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"<w:basedOn w:val=\""); + oWriter.WriteString(L"DefaultParagraphFont"); //todo сделать дерево зависимостей + oWriter.WriteString(L"\"/>"); + + //oWriter.WriteString(L"<w:rsid w:val=\"00BB76B0\"/>"); + + oWriter.WriteString(L"<w:rPr>"); + + oWriter.WriteString(L"<w:rFonts w:ascii=\""); + oWriter.WriteEncodeXmlString(wsFontName); + oWriter.WriteString(L"\" w:hAnsi=\""); + oWriter.WriteEncodeXmlString(wsFontName); + oWriter.WriteString(L"\" w:cs=\""); + oWriter.WriteEncodeXmlString(wsFontName); + oWriter.WriteString(L"\" w:hint=\"default\"/>"); + + if (bBold) + { + oWriter.WriteString(L"<w:b/>"); + oWriter.WriteString(L"<w:bCs/>"); + } + if (bItalic) + { + oWriter.WriteString(L"<w:i/>"); + oWriter.WriteString(L"<w:iCs/>"); + } + + if (ConvertColorBGRToRGB(oBrush.Color1) != c_iBlackColor2) + { + oWriter.WriteString(L"<w:color w:val=\""); + oWriter.WriteHexInt3(ConvertColorBGRToRGB(oBrush.Color1)); + oWriter.WriteString(L"\"/>"); + } + + int lSize = static_cast<int>(2 * dFontSize); + oWriter.WriteString(L"<w:sz w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/><w:szCs w:val=\""); + oWriter.AddInt(lSize); + oWriter.WriteString(L"\"/>"); + + oWriter.WriteString(L"</w:rPr>"); + oWriter.WriteString(L"</w:style>"); + } } diff --git a/DocxRenderer/src/logic/styles/FontStyle.h b/DocxRenderer/src/logic/styles/FontStyle.h index 469ad7c0ac0..f0df1ab9d38 100644 --- a/DocxRenderer/src/logic/styles/FontStyle.h +++ b/DocxRenderer/src/logic/styles/FontStyle.h @@ -1,36 +1,34 @@ #pragma once #include <memory> -#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<CFontStyle> 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); + + 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"; + }; } 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"<w:style w:type=\"paragraph\" "); + if(bIsDefault) oWriter.WriteString(L"w:default=\"1\" "); + oWriter.WriteString(L"w:styleId=\"" + wsStyleId + L"\">"); + oWriter.WriteString(L"<w:name w:val=\"" + wsName + L"\"/>"); + + if(!wsBasedOn.empty()) oWriter.WriteString(L"<w:basedOn w:val=\"" + wsBasedOn + L"\"/>"); + if(bIsUnhideWhenUsed) oWriter.WriteString(L"<w:unhideWhenUsed/>"); + if(bIsSemiHidden) oWriter.WriteString(L"<w:semiHidden/>"); + oWriter.WriteString(L"<w:uiPriority w:val=\"" + std::to_wstring(nUiPriority) + L"\"/>"); + oWriter.WriteString(L"<w:qFormat/>"); + + oWriter.WriteString(L"</w:style>"); + } +} + diff --git a/DocxRenderer/src/logic/styles/ParagraphStyle.h b/DocxRenderer/src/logic/styles/ParagraphStyle.h new file mode 100644 index 00000000000..9cbe775da96 --- /dev/null +++ b/DocxRenderer/src/logic/styles/ParagraphStyle.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../../../../DesktopEditor/graphics/structures.h" +#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..8ec2dc81e7c 100644 --- a/DocxRenderer/src/resources/ColorTable.h +++ b/DocxRenderer/src/resources/ColorTable.h @@ -5,61 +5,61 @@ 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<unsigned int, std::wstring> m_Table; +private: + std::map<unsigned int, std::wstring> 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..c33d0e1b19a 100644 --- a/DocxRenderer/src/resources/Constants.h +++ b/DocxRenderer/src/resources/Constants.h @@ -1,7 +1,8 @@ #pragma once -#include "../DesktopEditor/common/Types.h" +#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; @@ -18,9 +19,9 @@ const 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_dLINE_DISTANCE_ERROR_MM = 0.03; +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; @@ -28,6 +29,9 @@ 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_dCORRECTION_FOR_FIRST_PARAGRAPH = -1.5; +const double c_dCOEFFICIENT_LENGTHS_LINES_IN_PARAGRAPH = 0.8; +const double c_dLINE_DISTANCE_MAX_MM = 50.0; +const double c_dSHAPE_X_OFFSET = 1.5; const UINT c_iWhiteColor = 0xFFFFFF; const UINT c_iBlackColor = 0x000000; diff --git a/DocxRenderer/src/resources/ImageInfo.h b/DocxRenderer/src/resources/ImageInfo.h index 6fa00e408c1..48e4f195529 100644 --- a/DocxRenderer/src/resources/ImageInfo.h +++ b/DocxRenderer/src/resources/ImageInfo.h @@ -1,44 +1,44 @@ #pragma once #include <string> -#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<eLineType, std::wstring> 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<eLineType, std::wstring> m_Table; + std::map<eLineType, std::wstring> 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 T> 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<class T> inline T& SingletonInstance() { - return SingletonTemplate<T>::GetInstance(); + return SingletonTemplate<T>::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 <vector> - -// у класса T должен быть метод IsBigger, IsBiggerOrEqual -template<typename T> -void SortElements(std::vector<T*>& 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..442b2df7ce8 100644 --- a/DocxRenderer/src/resources/VectorGraphics.cpp +++ b/DocxRenderer/src/resources/VectorGraphics.cpp @@ -1,175 +1,141 @@ #include <algorithm> -#include "VectorGraphics.h" -#include "../DesktopEditor/common/Types.h" #include <string.h> +#include <numeric> +#include <limits> + +#include "VectorGraphics.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() + { + m_dLeftDefault = std::numeric_limits<double>().max(); + m_dTopDefault = std::numeric_limits<double>().max(); + m_dRightDefault = std::numeric_limits<double>().min(); + m_dBottomDefault = std::numeric_limits<double>().min(); + + ResetBorders(); + } + + CVectorGraphics::~CVectorGraphics() + { + m_arData.clear(); + } + CVectorGraphics& CVectorGraphics::operator=(CVectorGraphics&& other) + { + 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; + } + + void CVectorGraphics::ResetBorders() + { + m_dLeft = m_dLeftDefault; + m_dTop = m_dTopDefault; + m_dRight = m_dRightDefault; + m_dBottom = m_dBottomDefault; + } + + 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; + } + + const std::list<CVectorGraphics::PathCommand>& CVectorGraphics::GetData() const + { + return m_arData; + } + + void CVectorGraphics::MoveTo(const double &x1, const double &y1) + { + Point point = {x1, y1}; + eVectorGraphicsType type = eVectorGraphicsType::vgtMove; + m_arData.push_back({type, {point}}); + + CheckPoint(point); + } + + void CVectorGraphics::LineTo(const double &x1, const double &y1) + { + Point point = {x1, y1}; + eVectorGraphicsType type = eVectorGraphicsType::vgtLine; + 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) + { + std::list<Point> points = {{x1, y1}, {x2, y2}, {x3, y3}}; + eVectorGraphicsType type = eVectorGraphicsType::vgtCurve; + m_arData.push_back({type, points}); + + for(auto& point : points) + CheckPoint(point); + } + + void CVectorGraphics::Close() + { + eVectorGraphicsType type = eVectorGraphicsType::vgtClose; + m_arData.push_back({type, {}}); + } + + void CVectorGraphics::Clear() + { + m_arData.clear(); + ResetBorders(); + } + + void CVectorGraphics::End() + { + Clear(); + } + 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) + { + 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) + { + Point point = {x, y}; + CheckPoint(point); + } } diff --git a/DocxRenderer/src/resources/VectorGraphics.h b/DocxRenderer/src/resources/VectorGraphics.h index ff09addc5db..89802ee95b0 100644 --- a/DocxRenderer/src/resources/VectorGraphics.h +++ b/DocxRenderer/src/resources/VectorGraphics.h @@ -1,50 +1,69 @@ #pragma once +#include <list> 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); - }; + class CVectorGraphics + { + public: + enum class eVectorGraphicsType + { + vgtMove = 0, + vgtLine = 1, + vgtCurve = 2, + vgtClose = 3 + }; + + struct Point + { + double x; + double y; + }; + + struct PathCommand + { + eVectorGraphicsType type; + std::list<Point> points; + }; + + CVectorGraphics(); + ~CVectorGraphics(); + + CVectorGraphics& operator=(CVectorGraphics&& other); + + const std::list<PathCommand>& GetData() const; + + double GetLeft() const noexcept; + double GetTop() const noexcept; + double GetRight() const noexcept; + double GetBottom() 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 End(); + + void Add(const PathCommand& command); + void Join(CVectorGraphics&& other); + + void Clear(); + void CheckPoint(const Point& point); + void CheckPoint(const double& x, const double& y); + + private: + std::list<PathCommand> m_arData; + + double m_dLeft; + double m_dTop; + double m_dRight; + double m_dBottom; + + double m_dLeftDefault; + double m_dTopDefault; + double m_dRightDefault; + double m_dBottomDefault; + + void ResetBorders(); + }; } diff --git a/DocxRenderer/src/resources/resources.cpp b/DocxRenderer/src/resources/resources.cpp index c22ff541ff1..93b7e3db505 100644 --- a/DocxRenderer/src/resources/resources.cpp +++ b/DocxRenderer/src/resources/resources.cpp @@ -10,58 +10,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 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"><Template>Normal.dotm</Template><TotalTime>1</TotalTime><Pages>1</Pages><Words>0</Words><Characters>0</Characters><Application>ONLYOFFICE</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>0</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged></Properties>"; - std::string str_resource_contenttypes = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Default Extension=\"png\" ContentType=\"image/png\"/><Default Extension=\"jpg\" ContentType=\"image/jpg\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/><Override PartName=\"/word/webSettings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml\"/><Override PartName=\"/word/fontTable.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml\"/><Override PartName=\"/word/theme/theme.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>"; - std::string str_resource_core = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"><dc:title/><dc:subject/><dc:creator/><cp:keywords/><dc:description/><cp:lastModifiedBy/><cp:revision>1</cp:revision></cp:coreProperties>"; - std::string str_resource_rels = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/></Relationships>"; - std::string str_resource_settings = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:zoom w:percent=\"100\"/><w:defaultTabStop w:val=\"708\"/><w:drawingGridHorizontalSpacing/><w:displayHorizontalDrawingGridEvery/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:compat/><m:mathPr><m:mathFont m:val=\"Cambria Math\"/><m:brkBin m:val=\"before\"/><m:brkBinSub m:val=\"--\"/><m:smallFrac m:val=\"off\"/><m:dispDef/><m:lMargin m:val=\"0\"/><m:rMargin m:val=\"0\"/><m:defJc m:val=\"centerGroup\"/><m:wrapIndent m:val=\"1440\"/><m:intLim m:val=\"subSup\"/><m:naryLim m:val=\"undOvr\"/></m:mathPr><w:themeFontLang w:val=\"en-US\"/><w:clrSchemeMapping w:bg1=\"light1\" w:t1=\"dark1\" w:bg2=\"light2\" w:t2=\"dark2\" w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:hyperlink=\"hyperlink\" w:followedHyperlink=\"followedHyperlink\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"3074\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/><o:rules v:ext=\"\"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val=\",\"/><w:listSeparator w:val=\";\"/></w:settings>"; - std::string str_resource_theme = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\"><a:themeElements><a:clrScheme name=\"Office\"><a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1><a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2><a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2><a:accent1><a:srgbClr val=\"4F81BD\"/></a:accent1><a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2><a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3><a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4><a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5><a:accent6><a:srgbClr val=\"F79646\"/></a:accent6><a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink><a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office\"><a:majorFont><a:latin typeface=\"Cambria\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/><a:font script=\"Jpan\" typeface=\"MS ゴシック\"/><a:font script=\"Hang\" typeface=\"맑은 고딕\"/><a:font script=\"Hans\" typeface=\"宋体\"/><a:font script=\"Hant\" typeface=\"新細明體\"/><a:font script=\"Arab\" typeface=\"Times New Roman\"/><a:font script=\"Hebr\" typeface=\"Times New Roman\"/><a:font script=\"Thai\" typeface=\"Angsana New\"/><a:font script=\"Ethi\" typeface=\"Nyala\"/><a:font script=\"Beng\" typeface=\"Vrinda\"/><a:font script=\"Gujr\" typeface=\"Shruti\"/><a:font script=\"Khmr\" typeface=\"MoolBoran\"/><a:font script=\"Knda\" typeface=\"Tunga\"/><a:font script=\"Guru\" typeface=\"Raavi\"/><a:font script=\"Cans\" typeface=\"Euphemia\"/><a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/><a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/><a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/><a:font script=\"Thaa\" typeface=\"MV Boli\"/><a:font script=\"Deva\" typeface=\"Mangal\"/><a:font script=\"Telu\" typeface=\"Gautami\"/><a:font script=\"Taml\" typeface=\"Latha\"/><a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/><a:font script=\"Orya\" typeface=\"Kalinga\"/><a:font script=\"Mlym\" typeface=\"Kartika\"/><a:font script=\"Laoo\" typeface=\"DokChampa\"/><a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/><a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/><a:font script=\"Viet\" typeface=\"Times New Roman\"/><a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/></a:majorFont><a:minorFont><a:latin typeface=\"Calibri\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/><a:font script=\"Jpan\" typeface=\"MS 明朝\"/><a:font script=\"Hang\" typeface=\"맑은 고딕\"/><a:font script=\"Hans\" typeface=\"宋体\"/><a:font script=\"Hant\" typeface=\"新細明體\"/><a:font script=\"Arab\" typeface=\"Arial\"/><a:font script=\"Hebr\" typeface=\"Arial\"/><a:font script=\"Thai\" typeface=\"Cordia New\"/><a:font script=\"Ethi\" typeface=\"Nyala\"/><a:font script=\"Beng\" typeface=\"Vrinda\"/><a:font script=\"Gujr\" typeface=\"Shruti\"/><a:font script=\"Khmr\" typeface=\"DaunPenh\"/><a:font script=\"Knda\" typeface=\"Tunga\"/><a:font script=\"Guru\" typeface=\"Raavi\"/><a:font script=\"Cans\" typeface=\"Euphemia\"/><a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/><a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/><a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/><a:font script=\"Thaa\" typeface=\"MV Boli\"/><a:font script=\"Deva\" typeface=\"Mangal\"/><a:font script=\"Telu\" typeface=\"Gautami\"/><a:font script=\"Taml\" typeface=\"Latha\"/><a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/><a:font script=\"Orya\" typeface=\"Kalinga\"/><a:font script=\"Mlym\" typeface=\"Kartika\"/><a:font script=\"Laoo\" typeface=\"DokChampa\"/><a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/><a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/><a:font script=\"Viet\" typeface=\"Arial\"/><a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/></a:minorFont></a:fontScheme><a:fmtScheme name=\"Office\"><a:fillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill><a:prstDash val=\"solid\"/></a:ln><a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln><a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst=\"orthographicFront\"><a:rot lat=\"0\" lon=\"0\" rev=\"0\"/></a:camera ><a:lightRig rig=\"threePt\" dir=\"t\"><a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w=\"63500\" h=\"25400\"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/></a:path></a:gradFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>"; - std::string str_resource_websettings = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:webSettings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:optimizeForBrowser/></w:webSettings>"; + std::string str_resource_app = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\"><Template>Normal.dotm</Template><TotalTime>1</TotalTime><Pages>1</Pages><Words>0</Words><Characters>0</Characters><Application>ONLYOFFICE</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>0</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged></Properties>"; + std::string str_resource_contenttypes = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/><Default Extension=\"png\" ContentType=\"image/png\"/><Default Extension=\"jpg\" ContentType=\"image/jpg\"/><Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/><Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/><Override PartName=\"/word/settings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\"/><Override PartName=\"/word/webSettings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml\"/><Override PartName=\"/word/fontTable.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml\"/><Override PartName=\"/word/theme/theme.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>"; + std::string str_resource_core = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"><dc:title/><dc:subject/><dc:creator/><cp:keywords/><dc:description/><cp:lastModifiedBy/><cp:revision>1</cp:revision></cp:coreProperties>"; + std::string str_resource_rels = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/></Relationships>"; + std::string str_resource_settings = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:zoom w:percent=\"100\"/><w:defaultTabStop w:val=\"708\"/><w:drawingGridHorizontalSpacing/><w:displayHorizontalDrawingGridEvery/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:compat/><m:mathPr><m:mathFont m:val=\"Cambria Math\"/><m:brkBin m:val=\"before\"/><m:brkBinSub m:val=\"--\"/><m:smallFrac m:val=\"off\"/><m:dispDef/><m:lMargin m:val=\"0\"/><m:rMargin m:val=\"0\"/><m:defJc m:val=\"centerGroup\"/><m:wrapIndent m:val=\"1440\"/><m:intLim m:val=\"subSup\"/><m:naryLim m:val=\"undOvr\"/></m:mathPr><w:themeFontLang w:val=\"en-US\"/><w:clrSchemeMapping w:bg1=\"light1\" w:t1=\"dark1\" w:bg2=\"light2\" w:t2=\"dark2\" w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:hyperlink=\"hyperlink\" w:followedHyperlink=\"followedHyperlink\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"3074\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/><o:rules v:ext=\"\"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val=\",\"/><w:listSeparator w:val=\";\"/></w:settings>"; + std::string str_resource_theme = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" name=\"Office Theme\"><a:themeElements><a:clrScheme name=\"Office\"><a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1><a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2><a:srgbClr val=\"1F497D\"/></a:dk2><a:lt2><a:srgbClr val=\"EEECE1\"/></a:lt2><a:accent1><a:srgbClr val=\"4F81BD\"/></a:accent1><a:accent2><a:srgbClr val=\"C0504D\"/></a:accent2><a:accent3><a:srgbClr val=\"9BBB59\"/></a:accent3><a:accent4><a:srgbClr val=\"8064A2\"/></a:accent4><a:accent5><a:srgbClr val=\"4BACC6\"/></a:accent5><a:accent6><a:srgbClr val=\"F79646\"/></a:accent6><a:hlink><a:srgbClr val=\"0000FF\"/></a:hlink><a:folHlink><a:srgbClr val=\"800080\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office\"><a:majorFont><a:latin typeface=\"Cambria\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/><a:font script=\"Jpan\" typeface=\"MS ゴシック\"/><a:font script=\"Hang\" typeface=\"맑은 고딕\"/><a:font script=\"Hans\" typeface=\"宋体\"/><a:font script=\"Hant\" typeface=\"新細明體\"/><a:font script=\"Arab\" typeface=\"Times New Roman\"/><a:font script=\"Hebr\" typeface=\"Times New Roman\"/><a:font script=\"Thai\" typeface=\"Angsana New\"/><a:font script=\"Ethi\" typeface=\"Nyala\"/><a:font script=\"Beng\" typeface=\"Vrinda\"/><a:font script=\"Gujr\" typeface=\"Shruti\"/><a:font script=\"Khmr\" typeface=\"MoolBoran\"/><a:font script=\"Knda\" typeface=\"Tunga\"/><a:font script=\"Guru\" typeface=\"Raavi\"/><a:font script=\"Cans\" typeface=\"Euphemia\"/><a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/><a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/><a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/><a:font script=\"Thaa\" typeface=\"MV Boli\"/><a:font script=\"Deva\" typeface=\"Mangal\"/><a:font script=\"Telu\" typeface=\"Gautami\"/><a:font script=\"Taml\" typeface=\"Latha\"/><a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/><a:font script=\"Orya\" typeface=\"Kalinga\"/><a:font script=\"Mlym\" typeface=\"Kartika\"/><a:font script=\"Laoo\" typeface=\"DokChampa\"/><a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/><a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/><a:font script=\"Viet\" typeface=\"Times New Roman\"/><a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/></a:majorFont><a:minorFont><a:latin typeface=\"Calibri\"/><a:ea typeface=\"\"/><a:cs typeface=\"\"/><a:font script=\"Jpan\" typeface=\"MS 明朝\"/><a:font script=\"Hang\" typeface=\"맑은 고딕\"/><a:font script=\"Hans\" typeface=\"宋体\"/><a:font script=\"Hant\" typeface=\"新細明體\"/><a:font script=\"Arab\" typeface=\"Arial\"/><a:font script=\"Hebr\" typeface=\"Arial\"/><a:font script=\"Thai\" typeface=\"Cordia New\"/><a:font script=\"Ethi\" typeface=\"Nyala\"/><a:font script=\"Beng\" typeface=\"Vrinda\"/><a:font script=\"Gujr\" typeface=\"Shruti\"/><a:font script=\"Khmr\" typeface=\"DaunPenh\"/><a:font script=\"Knda\" typeface=\"Tunga\"/><a:font script=\"Guru\" typeface=\"Raavi\"/><a:font script=\"Cans\" typeface=\"Euphemia\"/><a:font script=\"Cher\" typeface=\"Plantagenet Cherokee\"/><a:font script=\"Yiii\" typeface=\"Microsoft Yi Baiti\"/><a:font script=\"Tibt\" typeface=\"Microsoft Himalaya\"/><a:font script=\"Thaa\" typeface=\"MV Boli\"/><a:font script=\"Deva\" typeface=\"Mangal\"/><a:font script=\"Telu\" typeface=\"Gautami\"/><a:font script=\"Taml\" typeface=\"Latha\"/><a:font script=\"Syrc\" typeface=\"Estrangelo Edessa\"/><a:font script=\"Orya\" typeface=\"Kalinga\"/><a:font script=\"Mlym\" typeface=\"Kartika\"/><a:font script=\"Laoo\" typeface=\"DokChampa\"/><a:font script=\"Sinh\" typeface=\"Iskoola Pota\"/><a:font script=\"Mong\" typeface=\"Mongolian Baiti\"/><a:font script=\"Viet\" typeface=\"Arial\"/><a:font script=\"Uigh\" typeface=\"Microsoft Uighur\"/></a:minorFont></a:fontScheme><a:fmtScheme name=\"Office\"><a:fillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill><a:prstDash val=\"solid\"/></a:ln><a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln><a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:prstDash val=\"solid\"/></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst><a:scene3d><a:camera prst=\"orthographicFront\"><a:rot lat=\"0\" lon=\"0\" rev=\"0\"/></a:camera ><a:lightRig rig=\"threePt\" dir=\"t\"><a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/></a:lightRig></a:scene3d><a:sp3d><a:bevelT w=\"63500\" h=\"25400\"/></a:sp3d></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/></a:path></a:gradFill><a:gradFill rotWithShape=\"1\"><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"><a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/></a:path></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/><a:extraClrSchemeLst/></a:theme>"; + std::string str_resource_websettings = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:webSettings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"><w:optimizeForBrowser/></w: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 = "<Application>" + U_TO_UTF8(str_resource_app_replace) + "</Application>"; - NSStringUtils::string_replaceA(str_resource_app, "<Application>ONLYOFFICE</Application>", str_resource_app_replace_a); + std::string str_resource_app_replace_a = "<Application>" + U_TO_UTF8(str_resource_app_replace) + "</Application>"; + NSStringUtils::string_replaceA(str_resource_app, "<Application>ONLYOFFICE</Application>", 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..1bab2dca820 100644 --- a/DocxRenderer/src/resources/utils.h +++ b/DocxRenderer/src/resources/utils.h @@ -1,41 +1,54 @@ #pragma once -#include "../DesktopEditor/common/Types.h" -#include "../DesktopEditor/common/StringUTF32.h" + +#include <type_traits> + +#include "../../../DesktopEditor/common/Types.h" +#include "../../../DesktopEditor/common/StringUTF32.h" inline LONG ConvertColorBGRToRGB(LONG lBGR) { - return (0x00FFFFFF & (((lBGR & 0xFF) << 16) | (lBGR & 0x0000FF00) | ((lBGR >> 16) & 0xFF))); + 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; + 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]); + if (1 != oText.length()) + return false; + return IsSpaceUtf32(oText.ToStdWString()[0]); } inline bool IsUnicodeSymbol(const int& symbol ) { - if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) || - ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) || - ( ( 0x10000 <= symbol ) && symbol ) ) - { - return true; - } - return false; + if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) || + ( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) || + ( ( 0x10000 <= symbol ) && symbol ) ) + { + return true; + } + return false; +} + + +inline bool IsDiacriticalMark(const int& symbol ) +{ + if ( 0x0300 <= symbol && 0x036F >= symbol ) + { + return true; + } + return false; } // 2-byte number inline short little_endian_2_big_endian( short s ) { - return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 ); + return ( ( s >> 8) & 0xff ) + ( ( s << 8 ) & 0xff00 ); } /*========================================================================================================*/ @@ -43,5 +56,23 @@ inline short little_endian_2_big_endian( short s ) // 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 ( ( i & 0xff ) << 24 ) + ( ( i & 0xff00 ) << 8 ) + ( ( i & 0xff0000 ) >> 8 ) + ( ( i >> 24 ) & 0xff ); +} + +// перемещает nullptr в конец и возвращает итератор, после которого начинаются nullptr +template<typename It> +It MoveNullptr(It start, It end) +{ + 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; + + return right; } diff --git a/DocxRenderer/test/main.cpp b/DocxRenderer/test/main.cpp index bfcdfd2f5d1..5ada59aa562 100644 --- a/DocxRenderer/test/main.cpp +++ b/DocxRenderer/test/main.cpp @@ -93,7 +93,7 @@ int main(int argc, char *argv[]) //Или добавляем любой нужный файл 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); @@ -107,6 +107,8 @@ int main(int argc, char *argv[]) for (size_t nIndex = 0; nIndex < sSourceFiles.size(); nIndex++) { + // нужно скинуть тип, чтобы не определялся как OOXML всегда (см чеккер). + oChecker.nFileType = 0; if (oChecker.isOfficeFile(sSourceFiles[nIndex])) { nFileType = oChecker.nFileType; @@ -127,10 +129,7 @@ int main(int argc, char *argv[]) } if (!pReader) - { - pFonts->Release(); - return 0; - } + continue; pReader->SetTempDirectory(sTempDir); @@ -166,18 +165,24 @@ int main(int argc, char *argv[]) // проверить все режимы 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); + //auto shapes = oDocxRenderer.ScanPage(pReader, 0); + //Если сразу нужен zip-архив //oDocxRenderer.Convert(pReader, sPlainParagraphDirOut+sZip); #endif - delete pReader; + RELEASEOBJECT(pReader); + + RELEASEOBJECT(pExternalImagheStorage); } pFonts->Release(); diff --git a/DocxRenderer/test/test.pro b/DocxRenderer/test/test.pro index 2f2b2beeadd..ed324f5db8b 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 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..587fa3fda56 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(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,11 +143,13 @@ 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"; @@ -153,7 +161,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s { 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.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..97f6dd3cde2 100644 --- a/HtmlFile2/HtmlFile2.pro +++ b/HtmlFile2/HtmlFile2.pro @@ -10,6 +10,7 @@ CONFIG += plugin DEFINES += HTMLFILE2_USE_DYNAMIC_LIBRARY DEFINES += CSSCALCULATOR_LIBRARY_STATIC +DEFINES += CSS_CALCULATOR_WITH_XHTML CORE_ROOT_DIR = $$PWD/.. PWD_ROOT_DIR = $$PWD @@ -29,4 +30,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 db52ed531d3..17fda948829 100644 --- a/HtmlFile2/htmlfile2.cpp +++ b/HtmlFile2/htmlfile2.cpp @@ -23,55 +23,861 @@ #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 "../DesktopEditor/raster/Metafile/MetaFileCommon.h" +#include "../DesktopEditor/raster/Metafile/svg/CSvgFile.h" + #include "htmlfile2.h" +#include "src/Languages.h" + +#include <boost/regex.hpp> + +#ifndef VALUE2STR +#define VALUE_TO_STRING(x) #x +#define VALUE2STR(x) VALUE_TO_STRING(x) +#endif + +#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 SAVE_NORMALIZED_HTML 0 + +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 "; + +// Ячейка таблицы +struct CTc +{ + int i; + int j; + std::wstring sGridSpan = L"1"; + std::wstring sPr = L""; + + 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) + { + return (i == c2.i && j == c2.j && sGridSpan == c2.sGridSpan); + } +}; + +// Настройки текста +struct CTextSettings +{ + bool bBdo; // Реверс текста + bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) + bool bAddSpaces; // Добавлять пробелы перед текстом? + bool bMergeText; // Объединять подяр идущий текст в 1? + int nLi; // Уровень списка + std::wstring sRStyle; // w:rStyle + std::wstring sPStyle; // w:pStyle + + CTextSettings(bool _bBdo, bool _bPre, bool _bAddSpaces, bool _bMergeText, int _nLi, const std::wstring& _sRStyle, const std::wstring& _sPStyle) : + bBdo(_bBdo), bPre(_bPre), bAddSpaces(_bAddSpaces), bMergeText(_bMergeText), nLi(_nLi), sRStyle(_sRStyle), sPStyle(_sPStyle) + {} + + CTextSettings(const CTextSettings& oTS) : + bBdo(oTS.bBdo), bPre(oTS.bPre), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) + {} + + void AddRStyle(const std::wstring& wsStyle) + { + if (std::wstring::npos == sRStyle.find(wsStyle)) + sRStyle += wsStyle; + } + + void AddPStyle(const std::wstring& wsStyle) + { + if (std::wstring::npos == sPStyle.find(wsStyle)) + sPStyle += wsStyle; + } +}; + +std::wstring CreateBorders(const NSCSS::NSProperties::CBorder& oBorder, const NSCSS::NSProperties::CIndent* pPadding = NULL) +{ + if (oBorder.EqualSides() && (NULL == pPadding || pPadding->Equals())) + { + const std::wstring wsBorderStyle = NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft())))); + + return L"<w:top " + wsBorderStyle + L"/>" + + L"<w:left " + wsBorderStyle + L"/>" + + L"<w:bottom " + wsBorderStyle + L"/>" + + L"<w:right " + wsBorderStyle + L"/>"; + } + else + { + std::wstring wsTable; + + if (oBorder.GetTopBorder().Valid()) + wsTable += L"<w:top " + NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetTopBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetTop())))) + L"/>"; + + if (oBorder.GetLeftBorder().Valid()) + wsTable += L"<w:left " + NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetLeftBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetLeft())))) + L"/>"; + + if (oBorder.GetBottomBorder().Valid()) + wsTable += L"<w:bottom " + NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetBottomBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetBottom())))) + L"/>"; + + if (oBorder.GetRightBorder().Valid()) + wsTable += L"<w:right " + NSCSS::CDocumentStyle::CalculateBorderStyle(oBorder.GetRightBorder(), ((NULL == pPadding) ? NULL : (&(pPadding->GetRight())))) + L"/>"; + + return wsTable; + } + + return L""; +} + +void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = false, bool bInP = false) +{ + if (NULL == pXml) + return; + + if (!bInP) + pXml->WriteString(L"<w:p><w:pPr>"); + + pXml->WriteString(L"<w:r><w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/>"); + + if (bVahish) + pXml->WriteString(L"<w:vanish/>"); + + pXml->WriteString(L"</w:rPr></w:r>"); + + if (!bInP) + pXml->WriteString(L"</w:pPr></w:p>"); +} + +void WriteLine(NSStringUtils::CStringBuilder* pXml, double dHeight, const std::wstring& wsColor) +{ + pXml->WriteNodeBegin(L"w:pict"); + pXml->WriteString(L"<v:rect style=\"width:0;height:" + std::to_wstring(dHeight) + L"pt\" o:hralign=\"center\" o:hrstd=\"t\" o:hr=\"t\" fillcolor=\"#" + wsColor + L"\" stroked=\"f\"/>"); + pXml->WriteNodeEnd(L"w:pict"); +} + +bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors) +{ + return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; }); +} + +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; + bool m_bHaveBorderAttribute; + + std::wstring m_wsAlign; + + TTableStyles() + : m_nCellSpacing(-1), m_bHaveBorderAttribute(false) + {} + + bool Empty() const + { + return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && false == m_bHaveBorderAttribute && m_wsAlign.empty(); + } +}; + +struct TTableRowStyle +{ + UINT m_unMaxIndex; + UINT m_unMaxHeight; + bool m_bIsHeader; + + TTableRowStyle() + : m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false) + {} + + 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; + } +}; + +class CTableCell +{ +public: + CTableCell() + : m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_enMode(ParseModeBody) + {} + + CTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty) + : m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged), m_bIsEmpty(bIsEmpty), m_enMode(ParseModeBody) + {} + + CTableCell(CTableCell& oCell) + : m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged), + m_bIsEmpty(oCell.m_bIsEmpty), m_enMode(oCell.m_enMode), m_oStyles(oCell.m_oStyles) + { + m_oData.SetText(oCell.m_oData.GetData()); + } + + bool Empty() + { + return m_bIsEmpty; + } + + 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; + } + + void SetMode(ERowParseMode eMode) + { + m_enMode = eMode; + } + + 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; + } + + 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 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 TTableStyles& oTableStyles) + { + NSStringUtils::CStringBuilder oCell; + + oCell.WriteNodeBegin(L"w:tc"); + oCell.WriteNodeBegin(L"w:tcPr"); + + if (ParseModeHeader == m_enMode) + oCell += L"<w:tblHeader/>"; + + if (!m_oStyles.m_oWidth.Empty()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oCell += L"<w:tcW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>"; + else + { + if (!m_oStyles.m_oWidth.Zero()) + { + int nWidth; + if (NSCSS::UnitMeasure::None != m_oStyles.m_oWidth.GetUnitMeasure()) + nWidth = m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips); + else + nWidth = static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(m_oStyles.m_oWidth.ToDouble(), NSCSS::UnitMeasure::Twips, 96) + 0.5); + + oCell += L"<w:tcW w:w=\"" + std::to_wstring(nWidth) + L"\" w:type=\"dxa\"/>"; + } + else + oCell += L"<w:tcW w:w=\"6\" w:type=\"dxa\"/>"; + } + } + else + oCell += L"<w:tcW w:w=\"0\" w:type=\"auto\"/>"; + + if (1 != m_unColspan) + oCell += L"<w:gridSpan w:val=\"" + std::to_wstring(m_unColspan) + L"\"/>"; + + if (m_bIsMerged) + oCell += L"<w:vMerge w:val=\"continue\"/>"; + else if (1 < m_unRowSpan) + oCell += L"<w:vMerge w:val=\"restart\"/>"; + + if (!m_oStyles.m_oBorder.Zero() && !m_oStyles.m_oBorder.Empty()) + oCell += L"<w:tcBorders>" + CreateBorders(m_oStyles.m_oBorder) + L"</w:tcBorders>"; + else if (oTableStyles.m_bHaveBorderAttribute) + oCell += L"<w:tcBorders><w:top w:val=\"outset\" w:sz=\"6\" w:space=\"0\" w:color=\"auto\"/><w:left w:val=\"outset\" w:sz=\"6\" w:space=\"0\" w:color=\"auto\"/><w:bottom w:val=\"outset\" w:sz=\"6\" w:space=\"0\" w:color=\"auto\"/><w:right w:val=\"outset\" w:sz=\"6\" w:space=\"0\" w:color=\"auto\"/></w:tcBorders>"; + + if (!m_oStyles.m_oBackground.Empty()) + { + const std::wstring wsShdFill{(NSCSS::NSProperties::ColorNone == m_oStyles.m_oBackground.GetType()) ? L"auto" : m_oStyles.m_oBackground.ToWString()}; + oCell += L"<w:shd w:val=\"clear\" w:color=\"auto\" w:fill=\"" + wsShdFill + L"\"/>"; + } + + if (!m_oStyles.m_wsVAlign.empty()) + oCell += L"<w:vAlign w:val=\"" + m_oStyles.m_wsVAlign + L"\"/>"; + else + oCell += L"<w:vAlign w:val=\"center\"/>"; + + if (!m_oStyles.m_oPadding.Empty() && oTableStyles.m_oPadding != m_oStyles.m_oPadding) + { + const int nTopPadding = std::max(oTableStyles.m_oPadding.GetTop() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT), + m_oStyles .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), + m_oStyles .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), + m_oStyles .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), + m_oStyles .m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH)); + + oCell += L"<w:tcMar>" + "<w:top w:w=\"" + std::to_wstring(nTopPadding) + L"\" w:type=\"dxa\"/>" + "<w:left w:w=\"" + std::to_wstring(nLeftPadding) + L"\" w:type=\"dxa\"/>" + "<w:bottom w:w=\"" + std::to_wstring(nBottomPadding) + L"\" w:type=\"dxa\"/>" + "<w:right w:w=\"" + std::to_wstring(nRightPadding) + L"\" w:type=\"dxa\"/>" + "</w:tcMar>"; + } + + oCell += L"<w:hideMark/>"; + 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(); + } + +private: + UINT m_unColspan; + UINT m_unRowSpan; + + bool m_bIsMerged; + bool m_bIsEmpty; + ERowParseMode m_enMode; + + 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<CTableCell*>::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty(); }); + + if (m_arCells.end() != itFoundEmpty) + { + --m_oStyles.m_unMaxIndex; + delete *itFoundEmpty; + *itFoundEmpty = pCell; + + if (1 != pCell->GetColspan()) + { + 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()) + { + UINT unDeleteCount = pCell->GetColspan() - 1; + while (m_arCells[nPosition]->Empty() && nPosition < m_arCells.size() && 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 TTableStyles& oTableStyles) + { + if (m_arCells.empty()) + return std::wstring(); + + NSStringUtils::CStringBuilder oRow; + oRow.WriteNodeBegin(L"w:tr"); + + if (!m_oStyles.Empty() || 0 < oTableStyles.m_nCellSpacing) + { + oRow.WriteNodeBegin(L"w:trPr"); + + if (m_oStyles.m_bIsHeader) + oRow += L"<w:tblHeader/>"; + + if (0 < m_oStyles.m_unMaxHeight) + oRow += L"<w:trHeight w:val=\"" + std::to_wstring(m_oStyles.m_unMaxHeight) + L"\"/>"; + + if (0 < oTableStyles.m_nCellSpacing) + oRow += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(oTableStyles.m_nCellSpacing) + L"\" w:type=\"dxa\"/>"; + + oRow.WriteNodeEnd(L"w:trPr"); + } + + for (CTableCell* pCell : m_arCells) + oRow += pCell->ConvertToOOXML(oTableStyles); + + oRow.WriteNodeEnd(L"w:tr"); + + return oRow.GetData(); + } + + CTableCell* operator[](UINT unIndex) + { + if (unIndex >= m_arCells.size()) + return NULL; + + return m_arCells[unIndex]; + } +private: + TTableRowStyle m_oStyles; + std::vector<CTableCell*> m_arCells; +}; + +class CTable +{ +public: + CTable() + {} + + ~CTable() + { + for (CTableRow* pRow : m_arRows) + RELEASEOBJECT(pRow); + } + + 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(); + } + + UINT GetRowCount() const + { + return m_arRows.size(); + } + + void AddRow(CTableRow* pRow) + { + 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(); + } + + m_arRows.push_back(pRow); + } + + void AddCaption(NSStringUtils::CStringBuilder& oCaption) + { + m_oCaption += oCaption.GetData(); + } + + 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 HaveBorderAttribute() + { + m_oStyles.m_bHaveBorderAttribute = true; + } + + bool IsHaveBorderAttribute() const + { + return m_oStyles.m_bHaveBorderAttribute; + } + + UINT GetMaxColumns() + { + UINT unMaxColumns = 0; + + for (const CTableRow* pRow : m_arRows) + unMaxColumns = std::max(unMaxColumns, pRow->GetIndex()); + + return unMaxColumns; + } + + 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() && unIndex + pCell->GetColspan() > m_arMinColspan[unIndex]) + { + pCell->SetColspan(m_arMinColspan[unIndex] - 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; + } + } -#include <boost/regex.hpp> + void CompleteTable() + { + UINT unMaxIndex = 0; -#ifndef VALUE2STR -#define VALUE_TO_STRING(x) #x -#define VALUE2STR(x) VALUE_TO_STRING(x) -#endif + for (CTableRow* pRow : m_arRows) + unMaxIndex = std::max(unMaxIndex, pRow->GetIndex()); -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 "; + for (CTableRow* pRow : m_arRows) + { + for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex) + pRow->InsertCell(CTableCell::CreateEmpty(), unIndex); + } + } -//struct CTree -//{ -// NSCSS::CNode m_oNode; -// std::vector<CTree> m_arrChild; -//}; + std::wstring ConvertToOOXML() + { + if (m_arRows.empty()) + return std::wstring(); -// Ячейка таблицы -struct CTc -{ - int i; - int j; - std::wstring sGridSpan = L"1"; + NSStringUtils::CStringBuilder oTable; - CTc(int _i, int _j, const std::wstring& sColspan) : i(_i), j(_j), sGridSpan(sColspan) {} + oTable.WriteNodeBegin(L"w:tbl"); + oTable.WriteNodeBegin(L"w:tblPr"); - bool operator==(const CTc& c2) - { - return (i == c2.i && j == c2.j && sGridSpan == c2.sGridSpan); - } -}; + if (!m_oStyles.m_oWidth.Empty() && !m_oStyles.m_oWidth.Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure()) + oTable += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>"; + else + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>"; + } + else + oTable += L"<w:tblW w:w=\"0\" w:type=\"auto\"/>"; -// Настройки текста -struct CTextSettings -{ - bool bBdo; // Реверс текста - bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк) - int nLi; // Уровень списка - std::wstring sRStyle; // w:rStyle - std::wstring sPStyle; // w:pStyle + if (!m_oStyles.m_oMargin.GetLeft().Empty() && !m_oStyles.m_oMargin.GetLeft().Zero()) + { + if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oMargin.GetLeft().GetUnitMeasure()) + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>"; + else + oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>"; + } - 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) {} + if (!m_oStyles.m_wsAlign.empty()) + oTable += L"<w:jc w:val=\"" + m_oStyles.m_wsAlign + L"\"/>"; - CTextSettings(const CTextSettings& oTS) : - bBdo(oTS.bBdo), bPre(oTS.bPre), nLi(oTS.nLi), sRStyle(oTS.sRStyle), sPStyle(oTS.sPStyle) {} + if (0 < m_oStyles.m_nCellSpacing && m_oStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse) + oTable += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(m_oStyles.m_nCellSpacing) + L"\" w:type=\"dxa\"/>"; + + if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero()) + oTable += L"<w:tblBorders>" + CreateBorders(m_oStyles.m_oBorder) + L"</w:tblBorders>"; + + 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 )); + + oTable.WriteNodeBegin(L"w:tblCellMar"); + + if (0 != nTopPadding) + oTable += L"<w:top w:w=\"" + std::to_wstring(nTopPadding) + L"\" w:type=\"dxa\"/>"; + + if (0 != nLeftPadding) + oTable += L"<w:left w:w=\"" + std::to_wstring(nLeftPadding) + L"\" w:type=\"dxa\"/>"; + + if (0 != nBottomPadding) + oTable += L"<w:bottom w:w=\"" + std::to_wstring(nBottomPadding) + L"\" w:type=\"dxa\"/>"; + + if (0 != nRightPadding) + oTable += L"<w:right w:w=\"" + std::to_wstring(nRightPadding) + L"\" w:type=\"dxa\"/>"; + + oTable.WriteNodeEnd(L"w:tblCellMar"); + } + else + oTable += L"<w:tblCellMar><w:top w:w=\"15\" w:type=\"dxa\"/><w:left w:w=\"15\" w:type=\"dxa\"/><w:bottom w:w=\"15\" w:type=\"dxa\"/><w:right w:w=\"15\" w:type=\"dxa\"/></w:tblCellMar>"; + + oTable += L"<w:tblLook w:val=\"04A0\" w:noVBand=\"1\" w:noHBand=\"0\" w:lastColumn=\"0\" w:firstColumn=\"1\" w:lastRow=\"0\" w:firstRow=\"1\"/>"; + oTable.WriteNodeEnd(L"w:tblPr"); + + if (HaveCaption()) + { + oTable.WriteNodeBegin(L"w:tr"); + oTable.WriteNodeBegin(L"w:tc"); + oTable.WriteNodeBegin(L"w:tcPr"); + oTable += L"<w:tcW w:w=\"0\" w:type=\"auto\"/>"; + oTable += L"<w:gridSpan w:val=\"" + std::to_wstring(GetMaxColumns()) + L"\"/>"; + oTable += L"<w:tcBorders><w:top w:val=\"nil\"/><w:left w:val=\"nil\"/><w:bottom w:val=\"nil\"/><w:right w:val=\"nil\"/></w:tcBorders>"; + oTable += L"<w:vAlign w:val=\"center\"/>"; + oTable += L"<w:hideMark/>"; + oTable.WriteNodeEnd(L"w:tcPr"); + oTable.WriteString(m_oCaption.GetData()); + oTable.WriteNodeEnd(L"w:tc"); + oTable.WriteNodeEnd(L"w:tr"); + } + + for (CTableRow* pRow : m_arRows) + oTable += pRow->ConvertToOOXML(m_oStyles); + + oTable.WriteNodeEnd(L"w:tbl"); + + return oTable.GetData(); + } +private: + std::vector<CTableRow*> m_arRows; + std::vector<UINT> m_arMinColspan; + + NSStringUtils::CStringBuilder m_oCaption; + + TTableStyles m_oStyles; }; void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2) @@ -86,6 +892,12 @@ void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2 } } +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; @@ -128,6 +940,8 @@ class CHtmlFile2_Private 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; // Директория назначения @@ -138,8 +952,8 @@ class CHtmlFile2_Private private: int m_nFootnoteId; // ID сноски int m_nHyperlinkId; // ID ссылки - int m_nCrossId; // ID перекрестной ссылки int m_nNumberingId; // ID списка + int m_nId; // ID остальные элементы NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml NSStringUtils::CStringBuilder m_oDocXmlRels; // document.xml.rels @@ -148,20 +962,32 @@ class CHtmlFile2_Private NSStringUtils::CStringBuilder m_oNoteXml; // footnotes.xml NSStringUtils::CStringBuilder m_oNumberXml; // numbering.xml - bool m_bInP; // <w:p> открыт? - bool m_bWasPStyle; // <w:pStyle> записан? - bool m_bWasSpace; // Был пробел? + struct TState + { + bool m_bInP; // <w:p> открыт? + bool m_bInR; // <w:r> открыт? + bool m_bInT; // <w:t> открыт? + bool m_bWasPStyle; // <w:pStyle> записан? + bool m_bWasSpace; // Был пробел? + bool m_bInHyperlink; // <w:hyperlink> открыт? + + TState() + : m_bInP(false), m_bInR(false), m_bInT(false), m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false) + {} + } m_oState; std::vector<std::wstring> m_arrImages; // Картинки std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски + std::map<std::wstring, UINT> m_mBookmarks; // Закладки public: - CHtmlFile2_Private() : m_nFootnoteId(1), m_nHyperlinkId(1), m_nCrossId(1), m_nNumberingId(1), m_bInP(false), m_bWasPStyle(false), m_bWasSpace(false) + CHtmlFile2_Private() + : m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1) { - //Установим размер исходного и нового окна для Css калькулятора (должны быть одинаковые единицы измерения (желательно пункты)) - //Это нужно для масштабирования некоторых значений - m_oStylesCalculator.SetSizeSourceWindow(NSCSS::CSizeWindow(4940 * (1366 * (25.4 / m_oStylesCalculator.GetDpi())), 0)); - m_oStylesCalculator.SetSizeDeviceWindow(NSCSS::CSizeWindow(4940, 0)); + 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() @@ -195,7 +1021,7 @@ class CHtmlFile2_Private NSDirectory::CreateDirectory(m_sDst + L"/word/theme"); // theme1.xml - std::wstring sTheme = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" name=\"Office Theme\"><a:themeElements><a:clrScheme name=\"Office\"><a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1><a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2><a:srgbClr val=\"44546A\"/></a:dk2><a:lt2><a:srgbClr val=\"E7E6E6\"/></a:lt2><a:accent1><a:srgbClr val=\"5B9BD5\"/></a:accent1><a:accent2><a:srgbClr val=\"ED7D31\"/></a:accent2><a:accent3><a:srgbClr val=\"A5A5A5\"/></a:accent3><a:accent4><a:srgbClr val=\"FFC000\"/></a:accent4><a:accent5><a:srgbClr val=\"4472C4\"/></a:accent5><a:accent6><a:srgbClr val=\"70AD47\"/></a:accent6><a:hlink><a:srgbClr val=\"0563C1\"/></a:hlink><a:folHlink><a:srgbClr val=\"954F72\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office Classic 2\"><a:majorFont><a:latin typeface=\"Arial\"/><a:ea typeface=\"Arial\"/><a:cs typeface=\"Arial\"/></a:majorFont><a:minorFont><a:latin typeface=\"Arial\"/><a:ea typeface=\"Arial\"/><a:cs typeface=\"Arial\"/></a:minorFont></a:fontScheme><a:fmtScheme name=\"Office\"><a:fillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"6350\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill></a:ln><a:ln w=\"12700\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln><a:ln w=\"19050\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/></a:theme>"; + std::wstring sTheme = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><a:theme xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" name=\"Office Theme\"><a:themeElements><a:clrScheme name=\"Office\"><a:dk1><a:sysClr val=\"windowText\" lastClr=\"000000\"/></a:dk1><a:lt1><a:sysClr val=\"window\" lastClr=\"FFFFFF\"/></a:lt1><a:dk2><a:srgbClr val=\"44546A\"/></a:dk2><a:lt2><a:srgbClr val=\"E7E6E6\"/></a:lt2><a:accent1><a:srgbClr val=\"5B9BD5\"/></a:accent1><a:accent2><a:srgbClr val=\"ED7D31\"/></a:accent2><a:accent3><a:srgbClr val=\"A5A5A5\"/></a:accent3><a:accent4><a:srgbClr val=\"FFC000\"/></a:accent4><a:accent5><a:srgbClr val=\"4472C4\"/></a:accent5><a:accent6><a:srgbClr val=\"70AD47\"/></a:accent6><a:hlink><a:srgbClr val=\"0563C1\"/></a:hlink><a:folHlink><a:srgbClr val=\"954F72\"/></a:folHlink></a:clrScheme><a:fontScheme name=\"Office Classic 2\"><a:majorFont><a:latin typeface=\"Times New Roman\"/><a:ea typeface=\"Times New Roman\"/><a:cs typeface=\"Times New Roman\"/></a:majorFont><a:minorFont><a:latin typeface=\"Times New Roman\"/><a:ea typeface=\"Times New Roman\"/><a:cs typeface=\"Times New Roman\"/></a:minorFont></a:fontScheme><a:fmtScheme name=\"Office\"><a:fillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"50000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"35000\"><a:schemeClr val=\"phClr\"><a:tint val=\"37000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:tint val=\"15000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"1\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:shade val=\"51000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"80000\"><a:schemeClr val=\"phClr\"><a:shade val=\"93000\"/><a:satMod val=\"130000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"94000\"/><a:satMod val=\"135000\"/></a:schemeClr></a:gs></a:gsLst><a:lin ang=\"16200000\" scaled=\"0\"/></a:gradFill></a:fillStyleLst><a:lnStyleLst><a:ln w=\"6350\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"><a:shade val=\"95000\"/><a:satMod val=\"105000\"/></a:schemeClr></a:solidFill></a:ln><a:ln w=\"12700\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln><a:ln w=\"19050\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\"><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill></a:ln></a:lnStyleLst><a:effectStyleLst><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"38000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle><a:effectStyle><a:effectLst><a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\"><a:srgbClr val=\"000000\"><a:alpha val=\"35000\"/></a:srgbClr></a:outerShdw></a:effectLst></a:effectStyle></a:effectStyleLst><a:bgFillStyleLst><a:solidFill><a:schemeClr val=\"phClr\"/></a:solidFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"40000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"40000\"><a:schemeClr val=\"phClr\"><a:tint val=\"45000\"/><a:shade val=\"99000\"/><a:satMod val=\"350000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"20000\"/><a:satMod val=\"255000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill><a:gradFill><a:gsLst><a:gs pos=\"0\"><a:schemeClr val=\"phClr\"><a:tint val=\"80000\"/><a:satMod val=\"300000\"/></a:schemeClr></a:gs><a:gs pos=\"100000\"><a:schemeClr val=\"phClr\"><a:shade val=\"30000\"/><a:satMod val=\"200000\"/></a:schemeClr></a:gs></a:gsLst><a:path path=\"circle\"/></a:gradFill></a:bgFillStyleLst></a:fmtScheme></a:themeElements><a:objectDefaults/></a:theme>"; NSFile::CFileBinary oThemeWriter; if (oThemeWriter.CreateFileW(m_sDst + L"/word/theme/theme1.xml")) { @@ -239,7 +1065,7 @@ class CHtmlFile2_Private } // fontTable.xml - std::wstring sFontTable = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" 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\" mc:Ignorable=\"w14 w15\"><w:font w:name=\"Wingdings\"><w:panose1 w:val=\"05000000000000000000\"/></w:font><w:font w:name=\"Courier New\"><w:panose1 w:val=\"02070309020205020404\"/></w:font><w:font w:name=\"Symbol\"><w:panose1 w:val=\"05050102010706020507\"/></w:font><w:font w:name=\"Arial\"><w:panose1 w:val=\"020B0604020202020204\"/></w:font><w:font w:name=\"Calibri\"><w:panose1 w:val=\"020F0502020204030204\"/></w:font><w:font w:name=\"Times New Roman\"><w:panose1 w:val=\"02020603050405020304\"/></w:font><w:font w:name=\"Cambria\"><w:panose1 w:val=\"02040503050406030204\"/></w:font></w:fonts>"; + std::wstring sFontTable = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:fonts xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" 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\" mc:Ignorable=\"w14 w15\"><w:font w:name=\"Wingdings\"><w:panose1 w:val=\"05000000000000000000\"/></w:font><w:font w:name=\"Courier New\"><w:panose1 w:val=\"02070309020205020404\"/></w:font><w:font w:name=\"Symbol\"><w:panose1 w:val=\"05050102010706020507\"/></w:font><w:font w:name=\"Times New Roman\"><w:panose1 w:val=\"020B0604020202020204\"/></w:font><w:font w:name=\"Calibri\"><w:panose1 w:val=\"020F0502020204030204\"/></w:font><w:font w:name=\"Times New Roman\"><w:panose1 w:val=\"02020603050405020304\"/></w:font><w:font w:name=\"Cambria\"><w:panose1 w:val=\"02040503050406030204\"/></w:font></w:fonts>"; NSFile::CFileBinary oFontTableWriter; if (oFontTableWriter.CreateFileW(m_sDst + L"/word/fontTable.xml")) { @@ -248,7 +1074,7 @@ class CHtmlFile2_Private } // settings.xml - std::wstring sSettings = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:clrSchemeMapping w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:bg1=\"light1\" w:bg2=\"light2\" w:followedHyperlink=\"followedHyperlink\" w:hyperlink=\"hyperlink\" w:t1=\"dark1\" w:t2=\"dark2\"/><w:defaultTabStop w:val=\"708\"/><m:mathPr/><w:trackRevisions w:val=\"false\"/><w:footnotePr><w:footnote w:id=\"-1\"/><w:footnote w:id=\"0\"/><w:numFmt w:val=\"decimal\"/><w:numRestart w:val=\"continuous\"/><w:numStart w:val=\"1\"/><w:pos w:val=\"pageBottom\"/></w:footnotePr><w:decimalSymbol w:val=\".\"/><w:listSeparator w:val=\",\"/><w:compat><w:compatSetting w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"14\"/><w:compatSetting w:name=\"overrideTableStyleFontSizeAndJustification\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"enableOpenTypeFeatures\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"doNotFlipMirrorIndents\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/></w:compat><w:zoom w:percent=\"100\"/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout></w:shapeDefaults></w:settings>"; + std::wstring sSettings = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:clrSchemeMapping w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:bg1=\"light1\" w:bg2=\"light2\" w:followedHyperlink=\"followedHyperlink\" w:hyperlink=\"hyperlink\" w:t1=\"dark1\" w:t2=\"dark2\"/><w:defaultTabStop w:val=\"708\"/><m:mathPr/><w:trackRevisions w:val=\"false\"/><w:footnotePr><w:footnote w:id=\"-1\"/><w:footnote w:id=\"0\"/><w:numFmt w:val=\"decimal\"/><w:numRestart w:val=\"continuous\"/><w:numStart w:val=\"1\"/><w:pos w:val=\"pageBottom\"/></w:footnotePr><w:decimalSymbol w:val=\".\"/><w:listSeparator w:val=\",\"/><w:compat><w:compatSetting w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"15\"/><w:compatSetting w:name=\"overrideTableStyleFontSizeAndJustification\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"enableOpenTypeFeatures\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"doNotFlipMirrorIndents\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"useWord2013TrackBottomHyphenation\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"0\"/></w:compat><w:zoom w:percent=\"100\"/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout></w:shapeDefaults></w:settings>"; NSFile::CFileBinary oSettingsWriter; if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml")) { @@ -281,6 +1107,8 @@ class CHtmlFile2_Private m_oNumberXml.AddCharSafe(167); m_oNumberXml += L"\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"6480\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:cs=\"Wingdings\" w:eastAsia=\"Wingdings\"/></w:rPr></w:lvl></w:abstractNum>"; + std::wstring wsCurrentLanguage; + // core.xml std::wstring sCore = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"; if(oParams) @@ -315,6 +1143,14 @@ class CHtmlFile2_Private sCore += EncodeXmlString(oParams->m_sDescription); sCore += L"</dc:description>"; } + if (!oParams->m_sLanguage.empty()) + { + wsCurrentLanguage = IndentifyLanguage(oParams->m_sLanguage); + + sCore += L"<dc:language>"; + sCore += wsCurrentLanguage; + sCore += L"</dc:language>"; + } } sCore += L"<cp:lastModifiedBy/></cp:coreProperties>"; NSFile::CFileBinary oCoreWriter; @@ -339,24 +1175,38 @@ class CHtmlFile2_Private m_oNoteXml += L"<w:footnote w:type=\"separator\" w:id=\"-1\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type=\"continuationSeparator\" w:id=\"0\"><w:p><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:r><w:continuationSeparator/></w:r></w:p></w:footnote>"; m_oStylesXml += L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:styles xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" 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\" mc:Ignorable=\"w14 w15\">"; + m_nId += 7; + // docDefaults по умолчанию if(oParams && !oParams->m_sdocDefaults.empty()) m_oStylesXml += oParams->m_sdocDefaults; else - m_oStylesXml += L"<w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:ascii=\"Arial\" w:hAnsi=\"Arial\" w:cs=\"Arial\" w:eastAsia=\"Arial\" w:hint=\"default\"/><w:sz w:val=\"22\"/><w:szCs w:val=\"22\"/><w:lang w:val=\"ru-RU\" w:bidi=\"ar-SA\" w:eastAsia=\"en-US\"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"276\" w:after=\"200\"/></w:pPr></w:pPrDefault></w:docDefaults>"; + { + m_oStylesXml += L"<w:rPrDefault><w:rPr>"; + m_oStylesXml += L"<w:rFonts w:ascii=\"" + DEFAULT_FONT_FAMILY + L"\" w:eastAsia=\"" + DEFAULT_FONT_FAMILY + L"\" w:hAnsi=\"" + DEFAULT_FONT_FAMILY + L"\" w:cs=\"" + DEFAULT_FONT_FAMILY + L"\"/>"; + m_oStylesXml += L"<w:sz w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/><w:szCs w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/>"; + m_oStylesXml += L"<w:lang w:val=\"" + ((!wsCurrentLanguage.empty()) ? wsCurrentLanguage : DEFAULT_LANGUAGE) + L"\" w:eastAsia=\"en-US\" w:bidi=\"ar-SA\"/>"; + m_oStylesXml += L"</w:rPr></w:rPrDefault>"; + +// m_oStylesXml += L"<w:pPrDefault><w:pPr><w:spacing w:after=\"200\" w:line=\"276\" w:lineRule=\"auto\"/></w:pPr></w:pPrDefault>"; + } // normal по умолчанию if(oParams && !oParams->m_sNormal.empty()) m_oStylesXml += oParams->m_sNormal; else - m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"normal\" w:default=\"1\"><w:name w:val=\"Normal\"/><w:qFormat/></w:style>"; + { + m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"normal\" w:default=\"1\"><w:name w:val=\"Normal\"/><w:qFormat/><w:rPr><w:rFonts w:eastAsiaTheme=\"minorEastAsia\"/>"; + m_oStylesXml += L"<w:sz w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/><w:szCs w:val=\"" + std::to_wstring(DEFAULT_FONT_SIZE) + L"\"/>"; + m_oStylesXml += L"</w:rPr></w:style>"; + } // Маркированный список m_oStylesXml += L"<w:style w:type=\"paragraph\" w:styleId=\"li\"><w:name w:val=\"List Paragraph\"/><w:basedOn w:val=\"normal\"/><w:qFormat/><w:uiPriority w:val=\"34\"/><w:pPr><w:contextualSpacing w:val=\"true\"/><w:ind w:left=\"720\"/></w:pPr></w:style>"; // Ссылки m_oStylesXml += L"<w:style w:type=\"character\" w:styleId=\"a\"><w:name w:val=\"Hyperlink\"/><w:uiPriority w:val=\"99\"/><w:unhideWhenUsed/><w:rPr><w:color w:val=\"0000FF\" w:themeColor=\"hyperlink\"/><w:u w:val=\"single\"/></w:rPr></w:style>"; // Таблицы - m_oStylesXml += L"<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"table-based\"><w:name w:val=\"Normal Table\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w=\"0\" w:type=\"dxa\"/><w:tblCellMar><w:top w:w=\"0\" w:type=\"dxa\"/><w:left w:w=\"108\" w:type=\"dxa\"/><w:bottom w:w=\"0\" w:type=\"dxa\"/><w:right w:w=\"108\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr></w:style><w:style w:type=\"table\" w:styleId=\"table\"><w:name w:val=\"Table Grid\"/><w:basedOn w:val=\"table-based\"/><w:uiPriority w:val=\"59\"/><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/></w:tblBorders></w:tblPr></w:style>"; +// m_oStylesXml += L"<w:style w:type=\"table\" w:default=\"1\" w:styleId=\"table-based\"><w:name w:val=\"Normal Table\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w=\"0\" w:type=\"dxa\"/><w:tblCellMar><w:top w:w=\"0\" w:type=\"dxa\"/><w:left w:w=\"108\" w:type=\"dxa\"/><w:bottom w:w=\"0\" w:type=\"dxa\"/><w:right w:w=\"108\" w:type=\"dxa\"/></w:tblCellMar></w:tblPr></w:style><w:style w:type=\"table\" w:styleId=\"table\"><w:name w:val=\"Table Grid\"/><w:basedOn w:val=\"table-based\"/><w:uiPriority w:val=\"59\"/><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"0\"/></w:pPr><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:left w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:bottom w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:right w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideH w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/><w:insideV w:val=\"single\" w:sz=\"4\" w:space=\"0\" w:color=\"000000\"/></w:tblBorders></w:tblPr></w:style>"; // Сноски m_oStylesXml += L"<w:style w:type=\"character\" w:styleId=\"footnote\"><w:name w:val=\"footnote reference\"/><w:uiPriority w:val=\"99\"/><w:unhideWhenUsed/><w:rPr><w:vertAlign w:val=\"superscript\"/></w:rPr></w:style><w:style w:type=\"paragraph\" w:styleId=\"footnote-p\"><w:name w:val=\"footnote text\"/><w:basedOn w:val=\"normal\"/><w:link w:val=\"footnote-c\"/><w:uiPriority w:val=\"99\"/><w:semiHidden/><w:unhideWhenUsed/><w:rPr><w:sz w:val=\"18\"/></w:rPr><w:pPr><w:spacing w:lineRule=\"auto\" w:line=\"240\" w:after=\"40\"/></w:pPr></w:style><w:style w:type=\"character\" w:styleId=\"footnote-c\" w:customStyle=\"1\"><w:name w:val=\"footnote text character\"/><w:link w:val=\"footnote-p\"/><w:uiPriority w:val=\"99\"/><w:rPr><w:sz w:val=\"18\"/></w:rPr></w:style>"; } @@ -396,9 +1246,20 @@ class CHtmlFile2_Private oRelsWriter.CloseFile(); } - if (m_bInP) + if (m_oState.m_bInP) m_oDocXml.WriteString(L"</w:p>"); - m_oDocXml.WriteString(L"<w:sectPr w:rsidR=\"0007083F\" w:rsidRPr=\"0007083F\" w:rsidSect=\"0007612E\"><w:pgSz w:w=\"12240\" w:h=\"15840\"/><w:pgMar w:gutter=\"0\" w:footer=\"720\" w:header=\"720\" w:left=\"720\" w:bottom=\"720\" w:right=\"720\" w:top=\"720\"/><w:cols w:space=\"720\"/><w:docGrid w:linePitch=\"360\"/></w:sectPr></w:body></w:document>"); + + m_oDocXml.WriteString(L"<w:sectPr w:rsidR=\"0007083F\" w:rsidRPr=\"0007083F\" w:rsidSect=\"0007612E\">"); + m_oDocXml.WriteString(L"<w:pgSz w:w=\"" + std::to_wstring(m_oPageData.GetWidth().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L" w:h=\"" + std::to_wstring(m_oPageData.GetHeight().ToInt(NSCSS::Twips)) + L"\"/>"); + m_oDocXml.WriteString(L"<w:pgMar w:top=\"" + std::to_wstring(m_oPageData.GetMargin().GetTop().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:right=\"" + std::to_wstring(m_oPageData.GetMargin().GetRight().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:bottom=\"" + std::to_wstring(m_oPageData.GetMargin().GetBottom().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:left=\"" + std::to_wstring(m_oPageData.GetMargin().GetLeft().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:header=\"" + std::to_wstring(m_oPageData.GetHeader().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:footer=\"" + std::to_wstring(m_oPageData.GetFooter().ToInt(NSCSS::Twips)) + L"\" "); + m_oDocXml.WriteString(L"w:gutter=\"0\"/><w:cols w:space=\"720\"/><w:docGrid w:linePitch=\"360\"/></w:sectPr></w:body></w:document>"); + NSFile::CFileBinary oDocumentWriter; if (oDocumentWriter.CreateFileW(m_sDst + L"/word/document.xml")) { @@ -453,6 +1314,7 @@ class CHtmlFile2_Private return false; std::string sFileContent = XmlUtils::GetUtf8FromFileContent(pData, nLength); + bool bNeedConvert = true; if (nLength > 4) { @@ -466,6 +1328,7 @@ class CHtmlFile2_Private if (pData[0] == 0 && pData[1] == 0 && pData[2] == 0xFE && pData[3] == 0xFF) bNeedConvert = false; } + RELEASEARRAYOBJECTS(pData); size_t nFind = sFileContent.find("version=\""); @@ -476,15 +1339,20 @@ class CHtmlFile2_Private 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); } @@ -507,8 +1375,10 @@ class CHtmlFile2_Private file.CloseFile(); std::string xml_string = XmlUtils::GetUtf8FromFileContent(buffer, dwReadBytes); + const std::string sContentType = NSStringFinder::FindPropety(xml_string, "content-type", ":", ";"); bool bRes = false; - if (std::string::npos != xml_string.find("Content-Type: multipart/related")) + + if(NSStringFinder::Equals(sContentType, "multipart/related")) { BYTE* pData; DWORD nLength; @@ -658,10 +1528,151 @@ class CHtmlFile2_Private void PageBreakBefore() { - m_oDocXml.WriteString(L"<w:p><w:pPr><w:pageBreakBefore/></w:pPr></w:p>"); + if (!m_oState.m_bInP) + m_oDocXml.WriteString(L"<w:p>"); + + m_oDocXml.WriteString(L"<w:pPr><w:pageBreakBefore/></w:pPr>"); + + if (!m_oState.m_bInP) + m_oDocXml.WriteString(L"</w:p>"); } 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"<w:p>"); + 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"<w:r>"); + m_oState.m_bInR = true; + return true; + } + + void CloseR(NSStringUtils::CStringBuilder* pXml) + { + if (!m_oState.m_bInR) + return; + + pXml->WriteString(L"</w:r>"); + m_oState.m_bInR = false; + } + + bool OpenT(NSStringUtils::CStringBuilder* pXml) + { + if (m_oState.m_bInT) + return false; + + pXml->WriteString(L"<w:t xml:space=\"preserve\">"); + m_oState.m_bInT = true; + return true; + } + + void CloseT(NSStringUtils::CStringBuilder* pXml) + { + if (!m_oState.m_bInT) + return; + + pXml->WriteString(L"</w:t>"); + m_oState.m_bInT = false; + } + + void CloseP(NSStringUtils::CStringBuilder* pXml, const std::vector<NSCSS::CNode>& 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"</w:hyperlink>"); + m_oState.m_bInHyperlink = false; + } + } + + pXml->WriteString(L"</w:p>"); + m_oState.m_bInP = false; + } + + 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 + { + sName = wsId; + m_mBookmarks.insert({wsId, 1}); + } + + pXml->WriteString(L"<w:bookmarkStart w:id=\""); + pXml->WriteString(sCrossId); + pXml->WriteString(L"\" w:name=\""); + pXml->WriteEncodeXmlString(sName); + pXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); + pXml->WriteString(sCrossId); + pXml->WriteString(L"\"/>"); + } std::wstring GetSubClass(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors) { @@ -673,25 +1684,21 @@ class CHtmlFile2_Private { std::wstring sName = m_oLightReader.GetName(); if(sName == L"class") - oNode.m_wsClass = m_oLightReader.GetText(); + oNode.m_wsClass = EncodeXmlString(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"<w:bookmarkStart w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteEncodeXmlString(oNode.m_wsId); - oXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\"/>"); + 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 - oNode.m_mAttributes[sName] = m_oLightReader.GetText(); + { + if (CheckArgumentMath(oNode.m_wsName, sName)) + oNode.m_mAttributes[sName] = m_oLightReader.GetText(); + } } m_oLightReader.MoveToElement(); sSelectors.push_back(oNode); @@ -701,7 +1708,9 @@ class CHtmlFile2_Private std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bP) { // NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - bP ? m_oXmlStyle.WritePStyle(oStyle) : m_oXmlStyle.WriteRStyle(oStyle); + if ((bP && !m_oXmlStyle.WritePStyle(oStyle)) || (!bP && !m_oXmlStyle.WriteRStyle(oStyle))) + return L""; + m_oStylesXml.WriteString(m_oXmlStyle.GetStyle()); return m_oXmlStyle.GetIdAndClear(); } @@ -713,15 +1722,13 @@ class CHtmlFile2_Private int nDeath = m_oLightReader.GetDepth(); while (m_oLightReader.ReadNextSiblingNode(nDeath)) { + const std::wstring wsName = m_oLightReader.GetName(); // Базовый адрес - if (m_oLightReader.GetName() == L"base") - { - while (m_oLightReader.MoveToNextAttribute()) - if (m_oLightReader.GetName() == L"href") - m_sBase = m_oLightReader.GetText(); - m_oLightReader.MoveToElement(); - } + if (L"base" == wsName) + m_sBase = GetArgumentValue(L"href"); } + + m_oLightReader.MoveToElement(); } void readBody() @@ -742,36 +1749,46 @@ class CHtmlFile2_Private m_oDocXml.WriteString(L"\"/>"); */ - readStream(&m_oDocXml, sSelectors, { false, false, -1, L"", L"" }); + readStream(&m_oDocXml, sSelectors, { false, false, true, false, -1, L"", L"" }); } - void readInside (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& sName) + bool readInside (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& sName) { + //TODO:: обработать все варианты return'а + if(sName == L"#text") { std::wstring sText = m_oLightReader.GetText(); - size_t find = sText.find_first_not_of(L" \n\t\r"); - if (find == std::wstring::npos) + + if (sText.end() == std::find_if_not(sText.begin(), sText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})) + return false; + + bool bInT = m_oState.m_bInT; + + if (!oTS.sRStyle.empty() || oTS.bPre) { - m_bWasSpace = true; - return; + CloseT(oXml); + CloseR(oXml); + } + + if (oTS.bAddSpaces && m_oState.m_bInP && !m_oState.m_bInR && !iswspace(sText.front()) && !m_oState.m_bWasSpace) + { + oXml->WriteString(L"<w:r><w:rPr><w:rFonts w:eastAsia=\"Times New Roman\"/></w:rPr><w:t xml:space=\"preserve\"> </w:t></w:r>"); + m_oState.m_bWasSpace = true; } - else if (find != 1 || m_bWasSpace || sText.front() != L' ') - sText.erase(0, find); std::wstring sPStyle = wrP(oXml, sSelectors, oTS); - oXml->WriteString(L"<w:r>"); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); - oXml->WriteString(L"<w:t xml:space=\"preserve\">"); + std::wstring sRStyle; - std::wstring::iterator end; - if(oTS.bBdo) - std::reverse(sText.begin(), sText.end()); - if (m_bWasSpace) + if (OpenR(oXml)) { - sText.insert(sText.begin(), L' '); - m_bWasSpace = false; + sRStyle = wrRPr(oXml, sSelectors, oTS); + OpenT(oXml); } + + if(oTS.bBdo) + std::reverse(sText.begin(), sText.end()); + if(oTS.bPre) { size_t nAfter = sText.find_first_of(L"\n\r"); @@ -779,35 +1796,62 @@ class CHtmlFile2_Private { oXml->WriteEncodeXmlString(sText.c_str(), nAfter); oXml->WriteString(L"</w:t></w:r></w:p><w:p>"); - if(!sPStyle.empty()) + if(!sPStyle.empty() || !oTS.sPStyle.empty()) { - oXml->WriteString(L"<w:pPr><w:pStyle w:val=\""); - oXml->WriteString(sPStyle); - oXml->WriteString(L"\"/>"); + oXml->WriteNodeBegin(L"w:pPr"); + + if (!sPStyle.empty()) + oXml->WriteString(L"<w:pStyle w:val=\"" + sPStyle + L"\"/>"); + oXml->WriteString(oTS.sPStyle); - oXml->WriteString(L"</w:pPr>"); + + oXml->WriteNodeEnd(L"w:pPr"); } - oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\""); - oXml->WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L"</w:rPr><w:t xml:space=\"preserve\">"); + oXml->WriteNodeBegin(L"w:r"); + if (!sRStyle.empty() || !oTS.sRStyle.empty()) + { + oXml->WriteNodeBegin(L"w:rPr"); + + if (!sRStyle.empty()) + oXml->WriteString(L"<w:rStyle w:val=\"" + sRStyle + L"\"/>"); + + oXml->WriteString(oTS.sRStyle); + + oXml->WriteNodeEnd(L"w:rPr"); + } + oXml->WriteString(L"<w:t xml:space=\"preserve\">"); sText.erase(0, nAfter + 1); nAfter = sText.find_first_of(L"\n\r"); } - end = sText.end(); + + if (sText.empty()) + return true; } else - end = std::unique(sText.begin(), sText.end(), [] (wchar_t l, wchar_t r) { return std::iswspace(l) && std::iswspace(r); }); + ReplaceSpaces(sText); + + if (std::iswspace(sText.front()) && m_oState.m_bWasSpace) + sText.erase(0, 1); + + if (oTS.bMergeText && !m_oState.m_bWasSpace && bInT) + oXml->WriteEncodeXmlString(L" "); + + if (!sText.empty()) + m_oState.m_bWasSpace = std::iswspace(sText.back()); - sText = std::wstring(sText.begin(), end); oXml->WriteEncodeXmlString(sText); - oXml->WriteString(L"</w:t></w:r>"); - return; + + if (!oTS.bMergeText) + { + CloseT(oXml); + CloseR(oXml); + } + + return true; } std::wstring sNote = GetSubClass(oXml, sSelectors); - + bool bResult = true; // Ссылка // Область ссылки if(sName == L"a" || sName == L"area") @@ -817,8 +1861,8 @@ class CHtmlFile2_Private else if(sName == L"b" || sName == L"strong") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:b/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:b/><w:bCs/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Направление текста else if(sName == L"bdo") @@ -831,38 +1875,43 @@ class CHtmlFile2_Private CTextSettings oTSBdo(oTS); oTSBdo.bBdo = (sDir == L"rtl"); - readStream(oXml, sSelectors, oTSBdo); + bResult = readStream(oXml, sSelectors, oTSBdo); } // Отмена направления текста else if(sName == L"bdi") { CTextSettings oTSBdo(oTS); oTSBdo.bBdo = false; - readStream(oXml, sSelectors, oTSBdo); + bResult = readStream(oXml, sSelectors, oTSBdo); } // Увеличивает размер шрифта else if(sName == L"big") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:sz w:val=\"26\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:sz w:val=\"26\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Перенос строки else if(sName == L"br") { - wrP(oXml, sSelectors, oTS); - oXml->WriteString(L"<w:r>"); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); - if(oStyle.m_oText.GetAlign() == L"both") - oXml->WriteString(L"<w:tab/>"); - oXml->WriteString(L"<w:br/></w:r>"); - m_bWasSpace = false; + if (m_oState.m_bInP) + { + oXml->WriteString(L"<w:r>"); + NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors); + if(oStyle.m_oText.GetAlign() == L"both") + oXml->WriteString(L"<w:tab/>"); + oXml->WriteString(L"<w:br/></w:r>"); + } + else + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); + + m_oState.m_bWasSpace = true; } else if(sName == L"center") { CTextSettings oTSP(oTS); - oTSP.sPStyle += L"<w:jc w:val=\"center\"/>"; - readStream(oXml, sSelectors, oTSP); + oTSP.AddPStyle(L"<w:jc w:val=\"center\"/>"); + bResult = readStream(oXml, sSelectors, oTSP); } // Цитата, обычно выделяется курсивом // Новый термин, обычно выделяется курсивом @@ -872,8 +1921,8 @@ class CHtmlFile2_Private else if(sName == L"cite" || sName == L"dfn" || sName == L"em" || sName == L"i" || sName == L"var") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Код // Моноширинный шрифт, например, Consolas @@ -881,15 +1930,15 @@ class CHtmlFile2_Private else if(sName == L"code" || sName == L"kbd" || sName == L"samp" || sName == L"tt") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Зачеркнутый текст else if(sName == L"del" || sName == L"s") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:strike/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:strike/>"); + bResult = readStream(oXml, sSelectors, oTSR); } else if(sName == L"font") { @@ -903,22 +1952,34 @@ class CHtmlFile2_Private else if(sAName == L"size") { int nSize = 3; - std::wstring sSize = m_oLightReader.GetText(); + const std::wstring sSize = m_oLightReader.GetText(); if(!sSize.empty()) { if(sSize.front() == L'+') - nSize += std::stoi(sSize.substr(1)); + nSize += NSStringFinder::ToInt(sSize.substr(1)); else if(sSize.front() == L'-') - nSize -= std::stoi(sSize.substr(1)); + nSize -= NSStringFinder::ToInt(sSize.substr(1)); else - nSize = std::stoi(sSize); + nSize = NSStringFinder::ToInt(sSize); } - sSize = nSize >= 1 && nSize <= 7 ? std::to_wstring(10 + nSize * 5) : L"22"; - sSelectors.back().m_wsStyle += L"; font-size: " + sSize; + + switch (nSize) + { + case 1: nSize = 10; break; + case 2: nSize = 12; break; + case 3: + default: nSize = 14; break; + case 4: nSize = 18; break; + case 5: nSize = 24; break; + case 6: nSize = 32; break; + case 7: nSize = 48; break; + } + + sSelectors.back().m_wsStyle += L"; font-size: " + std::to_wstring(nSize) + L"px"; } } m_oLightReader.MoveToElement(); - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); } // Картинки else if(sName == L"img") @@ -927,61 +1988,67 @@ class CHtmlFile2_Private else if(sName == L"ins" || sName == L"u") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:u w:val=\"single\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:u w:val=\"single\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Выделенный текст, обычно выделяется желтым else if(sName == L"mark") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:highlight w:val=\"yellow\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:highlight w:val=\"yellow\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Цитата, выделенная кавычками, обычно выделяется курсивом else if(sName == L"q") { wrP(oXml, sSelectors, oTS); oXml->WriteString(L"<w:r>"); - std::wstring sRStyle = wrR(oXml, sSelectors, oTS); + std::wstring sRStyle = wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t></w:r>"); CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); readStream(oXml, sSelectors, oTSR); wrP(oXml, sSelectors, oTS); - oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\""); - oXml->WriteString(sRStyle); - oXml->WriteString(L"\"/>"); - oXml->WriteString(oTS.sRStyle); - oXml->WriteString(L"</w:rPr><w:t xml:space=\"preserve\">"</w:t></w:r>"); + oXml->WriteString(L"<w:r>"); + if (!sRStyle.empty()) + { + oXml->WriteString(L"<w:rPr><w:rStyle w:val=\""); + oXml->WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + oXml->WriteString(oTS.sRStyle); + oXml->WriteString(L"</w:rPr>"); + } + oXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t></w:r>"); } // Текст верхнего регистра else if(sName == L"rt" || sName == L"sup") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:vertAlign w:val=\"superscript\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:vertAlign w:val=\"superscript\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Уменьшает размер шрифта else if(sName == L"small") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:sz w:val=\"18\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:sz w:val=\"18\"/>"); + bResult = readStream(oXml, sSelectors, oTSR); } // Текст нижнего регистра else if(sName == L"sub") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:vertAlign w:val=\"subscript\"/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:vertAlign w:val=\"subscript\"/>"); + bResult = 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); + if (readSVG(m_oLightReader.GetOuterXml())) + ImageRels(oXml, -1, L"", L"png"); } else if(sName == L"input") readInput(oXml, sSelectors, oTS); @@ -991,53 +2058,57 @@ class CHtmlFile2_Private sName == L"bgsound" || sName == L"applet" || sName == L"blink" || sName == L"keygen"|| sName == L"script" || sName == L"comment" || sName == L"title" || sName == L"style") { + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); sSelectors.pop_back(); - return; + return true; } else if (sName == L"span") { if (sSelectors.back().m_wsClass == L"MsoFootnoteReference") { sSelectors.pop_back(); - return; + return false; } - readStream(oXml, sSelectors, oTS); + bResult = readStream(oXml, sSelectors, oTS); + } + else if (sName == L"nobr") + { + CTextSettings oTSPre(oTS); + oTSPre.bPre = true; + bResult = readStream(oXml, sSelectors, oTSPre); } // Без нового абзаца 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); + bResult = readStream(oXml, sSelectors, oTS); // С нового абзаца else { - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - } - m_bWasSpace = false; + NSStringUtils::CStringBuilder oXmlData; + TState oCurentState{m_oState}; + + CloseP(&oXmlData, sSelectors); // Адрес if(sName == L"address") { CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:i/>"; - readStream(oXml, sSelectors, oTSR); + oTSR.AddRStyle(L"<w:i/><w:iCs/>"); + bResult = readStream(&oXmlData, sSelectors, oTSR); } // Определение термина, отступ от левого края else if(sName == L"dd") { CTextSettings oTSP(oTS); oTSP.sPStyle += L"<w:ind w:left=\"567\"/>"; - readStream(oXml, sSelectors, oTSP); + bResult = readStream(&oXmlData, sSelectors, oTSP); } // aside возможно использовать для сносок в epub else if (sName == L"aside" || sName == L"div") { + m_oStylesCalculator.CalculatePageStyle(m_oPageData, sSelectors); + int bMsoFootnote = 0; std::wstring sFootnoteID; while (m_oLightReader.MoveToNextAttribute()) @@ -1068,7 +2139,7 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L"</w:footnote>"); } else - readStream(oXml, sSelectors, oTS); + bResult = readStream(&oXmlData, sSelectors, oTS); } // С нового абзаца else if(sName == L"article" || sName == L"header" || sName == L"blockquote" || sName == L"main" || sName == L"dir" || @@ -1076,7 +2147,7 @@ class CHtmlFile2_Private 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); + bResult = readStream(&oXmlData, sSelectors, oTS); // Горизонтальная линия else if(sName == L"hr") { @@ -1090,424 +2161,316 @@ class CHtmlFile2_Private } } if (bPrint) - oXml->WriteString(L"<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr></w:pPr></w:p>"); + { + const bool bOpenedP = OpenP(&oXmlData); + OpenR(&oXmlData); + WriteLine(&oXmlData, 1.5, L"a0a0a0"); + CloseR(&oXmlData); + if (bOpenedP) + CloseP(&oXmlData, sSelectors); + } +// oXml->WriteString(L"<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr></w:pPr></w:p>"); } // Меню // Маркированный список else if(sName == L"menu" || sName == L"ul" || sName == L"select" || sName == L"datalist") - readLi(oXml, sSelectors, oTS, true); + readLi(&oXmlData, sSelectors, oTS, true); // Нумерованный список else if(sName == L"ol") - readLi(oXml, sSelectors, oTS, false); + readLi(&oXmlData, sSelectors, oTS, false); // Предварительно форматированный текст else if(sName == L"pre" || sName == L"xmp") { CTextSettings oTSPre(oTS); + sSelectors.back().m_wsStyle += L"; font-family:Consolas"; oTSPre.bPre = true; - oTSPre.sRStyle += L"<w:rFonts w:ascii=\"Consolas\" w:hAnsi=\"Consolas\"/>"; - oTSPre.sPStyle += L"<w:spacing w:after=\"0\"/>"; - readStream(oXml, sSelectors, oTSPre); + bResult = readStream(&oXmlData, sSelectors, oTSPre); } // Таблицы else if(sName == L"table") - readTable(oXml, sSelectors, oTS); + ParseTable(&oXmlData, sSelectors, oTS); // Текст с границами else if(sName == L"textarea" || sName == L"fieldset") { CTextSettings oTSP(oTS); - oTSP.sPStyle += L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"; - readStream(oXml, sSelectors, oTSP); + oTSP.AddPStyle(L"<w:pBdr><w:left w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:top w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:right w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/><w:bottom w:val=\"single\" w:color=\"000000\" w:sz=\"8\" w:space=\"0\"/></w:pBdr>"); + bResult = readStream(&oXmlData, sSelectors, oTSP); + } + else if (sName == L"xml") + { + sSelectors.pop_back(); + return false; } // Неизвестный тэг. Выделять ли его абзацем? else - readStream(oXml, sSelectors, oTS); - readNote(oXml, sSelectors, sNote); - sNote = L""; + bResult = readStream(&oXmlData, sSelectors, oTS); - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - } - m_bWasSpace = false; + readNote(&oXmlData, sSelectors, sNote); + sNote = L""; + + CloseP(&oXmlData, sSelectors); + + if (bResult) + oXml->WriteString(oXmlData.GetData()); + else + m_oState = oCurentState; } readNote(oXml, sSelectors, sNote); sSelectors.pop_back(); + return bResult; } - bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) + bool readStream (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const 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; - } - - void readTr (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& sBorders) - { - std::vector<CTc> mTable; - int nDeath = m_oLightReader.GetDepth(); - int i = 1; // Строка - while(m_oLightReader.ReadNextSiblingNode(nDeath)) + if (!bResult && bInsertEmptyP) { - // tr - строки в таблице - if(m_oLightReader.GetName() != L"tr") - continue; - int nTrDeath = m_oLightReader.GetDepth(); - if(m_oLightReader.IsEmptyNode() || !m_oLightReader.ReadNextSiblingNode(nTrDeath)) - continue; + wrP(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); + CloseP(oXml, sSelectors); + m_oState.m_bInP = false; + } - int j = 1; // Столбец - oXml->WriteString(L"<w:tr>"); - 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(); + return bResult; + } - // Вставляем ячейки до - std::vector<CTc>::iterator it1 = std::find_if(mTable.begin(), mTable.end(), [i, j](const CTc& item){ return item.i == i && item.j == j; }); - std::vector<CTc>::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"<w:tc><w:tcPr><w:tcBorders>"); - oXml->WriteString(!sBorders.empty() ? sBorders : L"<w:left w:val=\"none\" w:color=\"000000\"/><w:top w:val=\"none\" w:color=\"000000\"/><w:right w:val=\"none\" w:color=\"000000\"/><w:bottom w:val=\"none\" w:color=\"000000\"/>"); - oXml->WriteString(L"</w:tcBorders><w:vMerge w:val=\"continue\"/><w:gridSpan w:val=\""); - std::wstring sCol = (it1 != mTable.end() ? it1->sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/><w:noWrap w:val=\"false\"/><w:textDirection w:val=\"lrTb\"/></w:tcPr><w:p></w:p></w:tc>"); - 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; }); - } + void CalculateCellStyles(CTableCell* pCell, const std::vector<NSCSS::CNode>& arSelectors) + { + if (NULL == pCell) + return; - GetSubClass(oXml, sSelectors); - oXml->WriteString(L"<w:tc><w:tcPr>"); + std::vector<NSCSS::CNode> arNewSelectors{(std::vector<NSCSS::CNode>::const_iterator)std::find_if(arSelectors.begin(), arSelectors.end(), [](const NSCSS::CNode& oNode){ return L"table" == oNode.m_wsName; }), arSelectors.cend()}; - NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, true); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle({sSelectors.back()}, false); + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, arNewSelectors); - NSCSS::CCompiledStyle::StyleEquation(oStyle, oStyleSetting); + pCell->SetVAlign(oStyle.m_oDisplay.GetVAlign().ToWString()); + pCell->SetHAlign(oStyle.m_oDisplay.GetHAlign().ToWString()); + pCell->SetBackground(oStyle.m_oBackground.GetColor()); + pCell->SetHeight(oStyle.m_oDisplay.GetHeight()); + pCell->SetWidth(oStyle.m_oDisplay.GetWidth()); + pCell->SetPadding(oStyle.m_oPadding); + pCell->SetBorder(oStyle.m_oBorder); - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsType = L"dxa"; + if (pCell->GetStyles()->m_wsHAlign.empty()) + pCell->SetHAlign(oStyle.m_oText.GetAlign().ToWString()); + } - //Если ширина указана в %, то используем тип 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 + void ParseTableCaption(CTable& oTable, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) + { + GetSubClass(NULL, sSelectors); - if (bIsWidthPct) - wsType = L"pct"; - else - { - nWidth *= 10; - // ограничиваем, примерно как в ms (22 inch) - if (nWidth > 31680) - nWidth = 31680; - } - //------------------------- + NSStringUtils::CStringBuilder oData; - if (nWidth > 0) - oXml->WriteString(L"<w:tcW w:w=\"" + std::to_wstring(nWidth) + L"\" w:type=\"" + wsType + L"\"/>"); - else - oXml->WriteString(L"<w:tcW w:w=\"0\" w:type=\"auto\"/>"); + CTextSettings oTSCaption{oTS}; + oTSCaption.sPStyle += L"<w:jc w:val=\"center\"/>"; - if(nColspan != 1) - { - oXml->WriteString(L"<w:gridSpan w:val=\""); - oXml->WriteString(std::to_wstring(nColspan)); - oXml->WriteString(L"\"/>"); + wrP(&oData, sSelectors, oTSCaption); + readStream(&oData, sSelectors, oTSCaption); + CloseP(&oData, sSelectors); - j += nColspan - 1; - } + oTable.AddCaption(oData); - oXml->WriteString(L"<w:tcBorders>"); - oXml->WriteString(!sBorders.empty() ? sBorders : L"<w:left w:val=\"none\" w:color=\"000000\"/><w:top w:val=\"none\" w:color=\"000000\"/><w:right w:val=\"none\" w:color=\"000000\"/><w:bottom w:val=\"none\" w:color=\"000000\"/>"); - oXml->WriteString(L"</w:tcBorders>"); - if(nRowspan != 1) - { - oXml->WriteString(L"<w:vMerge w:val=\"restart\"/>"); - 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}); - } + sSelectors.pop_back(); + return; + } + + struct TRowspanElement + { + UINT m_unRowSpan; + UINT m_unColumnIndex; + const CTableCell* m_pCell; - std::wstring wsVerticalAlign = oStyle.m_oDisplay.GetVAlign().ToWString(); + TRowspanElement(UINT unRowSpan, UINT unColumnIndex, const CTableCell* pCell) + : m_unRowSpan(unRowSpan), m_unColumnIndex(unColumnIndex), m_pCell(pCell) + {} + }; - if (!wsVerticalAlign.empty()) - oXml->WriteString(L"<w:vAlign w:val=\"" + wsVerticalAlign + L"\"/>"); + void ParseTableRows(CTable& oTable, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, ERowParseMode eMode) + { + std::vector<TRowspanElement> arRowspanElements; - oXml->WriteString(L"<w:noWrap w:val=\"false\"/><w:textDirection w:val=\"lrTb\"/><w:hideMark/></w:tcPr>"); - m_bWasPStyle = false; + int nDeath = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nDeath)) + { + if (L"tr" != m_oLightReader.GetName()) + continue; - // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным - if(m_oLightReader.GetName() == L"th") - { - CTextSettings oTSR(oTS); - oTSR.sRStyle += L"<w:b/>"; - readStream(oXml, sSelectors, oTSR); - } - // Читаем 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"</w:hyperlink>"); - oXml->WriteString(L"<w:r></w:r></w:p>"); - m_bInP = false; - } - else if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"</w:p>") - oXml->WriteString(L"<w:p></w:p>"); - m_bWasSpace = false; - oXml->WriteString(L"</w:tc>"); - 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()) - { - oXml->WriteString(L"<w:tc><w:tcPr><w:tcBorders>"); - oXml->WriteString(!sBorders.empty() ? sBorders : L"<w:left w:val=\"none\" w:color=\"000000\"/><w:top w:val=\"none\" w:color=\"000000\"/><w:right w:val=\"none\" w:color=\"000000\"/><w:bottom w:val=\"none\" w:color=\"000000\"/>"); - oXml->WriteString(L"</w:tcBorders><w:vMerge w:val=\"continue\"/><w:gridSpan w:val=\""); - std::wstring sCol = (it1 != mTable.end() ? it1->sGridSpan : it2->sGridSpan); - oXml->WriteString(sCol); - oXml->WriteString(L"\"/><w:noWrap w:val=\"false\"/><w:textDirection w:val=\"lrTb\"/></w:tcPr><w:p></w:p></w:tc>"); - 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; }); - } - } while(m_oLightReader.ReadNextSiblingNode(nTrDeath)); - oXml->WriteString(L"</w:tr>"); - i++; - } - } + GetSubClass(NULL, sSelectors); - void readTable (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) - { - if(m_oLightReader.IsEmptyNode()) - return; + CTableRow *pRow = new CTableRow(); - NSStringUtils::CStringBuilder oHead; - NSStringUtils::CStringBuilder oBody; - NSStringUtils::CStringBuilder oFoot; + for (std::vector<TRowspanElement>::iterator itElement = arRowspanElements.begin(); itElement < arRowspanElements.end();) + { + pRow->InsertCell(CTableCell::CreateEmpty(itElement->m_pCell->GetColspan(), true, itElement->m_pCell->GetStyles()), itElement->m_unColumnIndex); - NSCSS::CCompiledStyle oStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + itElement->m_unRowSpan--; + if (1 == itElement->m_unRowSpan) + itElement = arRowspanElements.erase(itElement); + else + ++itElement; + } - if (oXml->GetSubData(oXml->GetCurSize() - 6) != L"</w:p>") - oXml->WriteString(L"<w:p><w:pPr><w:spacing w:beforeLines=\"0\" w:before=\"0\" w:afterLines=\"0\" w:after=\"0\"/><w:rPr><w:vanish/><w:sz w:val=\"2\"/><w:szCs w:val=\"2\"/></w:rPr></w:pPr></w:p>"); - m_bWasSpace = false; + UINT unColumnIndex = 0; + int nTrDepth = m_oLightReader.GetDepth(); + while (m_oLightReader.ReadNextSiblingNode(nTrDepth)) + { + CTableCell *pCell = new CTableCell(); - // Начало таблицы - std::wstring wsTable = L"<w:tbl><w:tblPr>"; + if (NULL == pCell) + continue; - int nWidth = oStyle.m_oDisplay.GetWidth().ToInt(NSCSS::UnitMeasure::Point, m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth); - std::wstring wsAlign = oStyle.m_oDisplay.GetHAlign().ToWString(); + pCell->SetMode(eMode); - if (0 < nWidth) - wsTable += L"<w:tblW w:w=\"" + std::to_wstring(nWidth) + L"\" w:type=\"pct\"/>"; - else if (m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth != 0) - wsTable += L"<w:tblW w:w=\"" + std::to_wstring(m_oStylesCalculator.GetSizeDeviceWindow().m_ushWidth) + L"\" w:type=\"pct\"/>"; - else - wsTable += L"<w:tblW w:w=\"0\" w:type=\"auto\"/>"; + GetSubClass(pCell->GetData(), sSelectors); + CalculateCellStyles(pCell, sSelectors); - if (wsAlign.empty()) - { - NSCSS::CNode oLastNode = sSelectors.back(); - sSelectors.pop_back(); + 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}); + } + } - NSCSS::CCompiledStyle oTempSettingsStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); + m_oLightReader.MoveToElement(); + m_oState.m_bWasPStyle = false; - wsAlign = oTempSettingsStyle.m_oText.GetAlign().ToWString(); + // Читаем th. Ячейка заголовка таблицы. Выравнивание посередине. Выделяется полужирным + if(m_oLightReader.GetName() == L"th") + { + CTextSettings oTSR(oTS); - if (wsAlign.empty()) - { - NSCSS::CCompiledStyle oTempStyle = m_oStylesCalculator.GetCompiledStyle(sSelectors, false); + if (pCell->GetStyles()->m_wsHAlign.empty()) + oTSR.sPStyle += L"<w:jc w:val=\"center\"/>"; - wsAlign = oTempStyle.m_oText.GetAlign().ToWString(); - } + oTSR.AddRStyle(L"<w:b/><w:bCs/>"); + readStream(pCell->GetData(), sSelectors, oTSR, true); + } + // Читаем td. Ячейка таблицы + else if(m_oLightReader.GetName() == L"td") + readStream(pCell->GetData(), sSelectors, oTS, true); - sSelectors.push_back(oLastNode); - } + if (pRow->GetIndex() == MAXCOLUMNSINTABLE - 1) + { + CTextSettings oTrTS{oTS}; + oTrTS.bMergeText = true; + oTrTS.bAddSpaces = true; + m_oState.m_bWasSpace = true; - if (!oStyle.m_oMargin.Empty() && (0 < oStyle.m_oMargin.GetTop().ToInt() || 0 < oStyle.m_oMargin.GetBottom().ToInt())) - { - wsTable += L"<w:tblCellMar>"; + while (m_oLightReader.ReadNextSiblingNode(nTrDepth) && (L"td" == m_oLightReader.GetName() || L"th" == m_oLightReader.GetName())) + { + GetSubClass(pCell->GetData(), sSelectors); + readStream(pCell->GetData(), sSelectors, oTrTS, true); + sSelectors.pop_back(); + } + } + CloseP(pCell->GetData(), sSelectors); + + pRow->AddCell(pCell); - if (0 < oStyle.m_oMargin.GetTop().ToInt()) - wsTable += L"<w:top w:w=\"" + std::to_wstring(static_cast<short int>(oStyle.m_oMargin.GetTop().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + sSelectors.pop_back(); -// if (0 < oStyle.m_pMargin.GetLeftSide()) -// wsTable += L"<w:left w:w=\"" + std::to_wstring(static_cast<short int>(oStyle.m_pMargin.GetLeftSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + ++unColumnIndex; - if (0 < oStyle.m_oMargin.GetBottom().ToInt()) - wsTable += L"<w:bottom w:w=\"" + std::to_wstring(static_cast<short int>(oStyle.m_oMargin.GetBottom().ToInt() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + if (pRow->GetIndex() == MAXCOLUMNSINTABLE) + break; + } -// if (0 < oStyle.m_pMargin.GetRightSide()) -// wsTable += L"<w:right w:w=\"" + std::to_wstring(static_cast<short int>(oStyle.m_pMargin.GetRightSide() * 10 + 0.5f)) + L"\" w:type=\"dxa\"/>"; + sSelectors.pop_back(); - wsTable += L"</w:tblCellMar>"; + oTable.AddRow(pRow); } + } - if (!wsAlign.empty()) - wsTable += L"<w:jc w:val=\"" + wsAlign + L"\"/>"; + void ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) + { + if(m_oLightReader.IsEmptyNode()) + return; - wsTable += L"<w:tblLook w:val=\"04A0\" w:noVBand=\"1\" w:noHBand=\"0\" w:lastColumn=\"0\" w:firstColumn=\"1\" w:lastRow=\"0\" w:firstRow=\"1\"/>"; - wsTable += L"</w:tblPr>"; + CTable oTable; - // borders - std::wstring sBorders; - oStyle.m_oBorder.Unblock(); - if (oStyle.m_oBorder.Empty()) - { - sBorders = L"<w:left w:val=\"none\" w:sz=\"4\" w:color=\"auto\" w:space=\"0\"/><w:top w:val=\"none\" w:sz=\"4\" w:color=\"auto\" w:space=\"0\"/><w:right w:val=\"none\" w:sz=\"4\" w:color=\"auto\" w:space=\"0\"/><w:bottom w:val=\"none\" w:color=\"auto\" w:sz=\"4\" w:space=\"0\"/>"; - } - else + //Table styles + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"border")) { - if (oStyle.m_oBorder.EqualSides()) + const int nWidth = NSStringFinder::ToInt(sSelectors.back().m_mAttributes[L"border"]); + + if (0 < nWidth) { - 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(); - - sBorders = L"<w:top w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>" + - L"<w:left w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>" + - L"<w:bottom w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>" + - L"<w:right w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>" + - L"<w:insideH w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>" + - L"<w:insideV w:val=\"" + sStyle + L"\" w:color=\"" + sColor + L"\" w:sz=\"" + sSz + L"\" w:space=\"0\"/>"; + sSelectors.back().m_mAttributes[L"border"] = L"outset " + std::to_wstring(nWidth) + L"px auto"; + oTable.HaveBorderAttribute(); } 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(); - - sBorders = L"<w:left w:val=\"" + sStyleLeftSide + L"\" w:color=\"" + sColorLeftSide + L"\" w:sz=\"" + sSzLeftSide + L"\" w:space=\"0\"/>" + - L"<w:top w:val=\"" + sStyleTopSide + L"\" w:color=\"" + sColorTopSide + L"\" w:sz=\"" + sSzTopSide + L"\" w:space=\"0\"/>" + - L"<w:right w:val=\"" + sStyleRightSide + L"\" w:color=\"" + sColorRightSide + L"\" w:sz=\"" + sSzRightSide + L"\" w:space=\"0\"/>" + - L"<w:bottom w:val=\"" + sStyleBottomSide + L"\" w:color=\"" + sColorBottomSide + L"\" w:sz=\"" + sSzBottomSide + L"\" w:space=\"0\"/>"; - - } + sSelectors.back().m_mAttributes[L"border"] = L"none"; } - oXml->WriteString(wsTable); + NSCSS::CCompiledStyle oStyle; + m_oStylesCalculator.GetCompiledStyle(oStyle, 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"<w:pBdr>"); - if (nBdr != std::wstring::npos) - { - nBdr += 8; - size_t nBdrEnd = sPSettings.find(L"</w:pBdr>", nBdr); - if (nBdrEnd != std::wstring::npos) - { - sBorders = sPSettings.substr(nBdr, nBdrEnd - nBdr); - size_t nSpace = sBorders.find(L"w:space=\""); - while (nSpace != std::wstring::npos) - { - nSpace += 9; - size_t nSpaceEnd = sBorders.find(L'\"', nSpace); - sBorders.replace(nSpace, nSpaceEnd - nSpace, L"0"); - nSpace = sBorders.find(L"w:space=\"", nSpace); - } - } - } - */ + if (sSelectors.back().m_mAttributes.end() != sSelectors.back().m_mAttributes.find(L"cellpadding")) + oStyle.m_oPadding.SetValues(sSelectors.back().m_mAttributes[L"cellpadding"] + L"px", 0, true); + + 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)) + while(m_oLightReader.ReadNextSiblingNode(nDeath)) { - std::wstring sName = m_oLightReader.GetName(); + const std::wstring sName = m_oLightReader.GetName(); GetSubClass(oXml, sSelectors); - // Заголовок таблицы + if(sName == L"caption") - { - size_t nHyp = 0; - if (!m_bInP) - { - oXml->WriteString(L"<w:p>"); - for (const NSCSS::CNode& item : sSelectors) - { - if (item.m_wsName == L"a") - { - oXml->WriteString(L"<w:hyperlink>"); - nHyp++; - } - } - m_bInP = true; - m_bWasPStyle = false; - } - // Заголовок таблицы выравнивание посередине - CTextSettings oTSP { oTS.bBdo, oTS.bPre, oTS.nLi, oTS.sRStyle, oTS.sPStyle + L"<w:jc w:val=\"center\"/>" }; - readStream(oXml, sSelectors, oTSP); - if (m_bInP) - { - for (size_t i = 0; i < nHyp; i++) - oXml->WriteString(L"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - m_bWasPStyle = false; - } - m_bWasSpace = false; - } + 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, oTS, ERowParseMode::ParseModeHeader); + if(sName == L"tbody") + ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeBody); else if(sName == L"tfoot") - readTr(&oFoot, sSelectors, oTS, sBorders); + ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother); + sSelectors.pop_back(); } - // Конец таблицы - oXml->WriteString(oHead.GetData()); - oXml->WriteString(oBody.GetData()); - oXml->WriteString(oFoot.GetData()); - oXml->WriteString(L"</w:tbl>"); + oTable.Shorten(); + oTable.CompleteTable(); + oXml->WriteString(oTable.ConvertToOOXML()); + WriteEmptyParagraph(oXml, true); } void readInput (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) @@ -1534,12 +2497,13 @@ class CHtmlFile2_Private { wrP(oXml, sSelectors, oTS); oXml->WriteString(L"<w:r>"); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"); oXml->WriteEncodeXmlString(sValue + L' '); oXml->WriteString(L"</w:t></w:r>"); } - readStream(oXml, sSelectors, oTS); + + readStream(oXml, sSelectors, oTS, ElementInTable(sSelectors)); } void readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, bool bType) @@ -1564,18 +2528,10 @@ 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"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); wrP(oXml, sSelectors, oTS); oXml->WriteString(L"<w:r>"); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"); oXml->WriteEncodeXmlString(m_oLightReader.GetText()); oXml->WriteString(L"</w:t></w:r>"); @@ -1597,29 +2553,16 @@ class CHtmlFile2_Private sStart = m_oLightReader.GetText(); m_oLightReader.MoveToElement(); - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - } - m_bWasSpace = false; + CloseP(oXml, sSelectors); + CTextSettings oTSLiP(oTS); oTSLiP.nLi++; oTSLiP.sPStyle += L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(oTSLiP.nLi) + L"\"/><w:numId w:val=\"" + - (bType ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/></w:numPr>"; + (bType ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/></w:numPr>"; readStream(oXml, sSelectors, oTSLiP); - if (m_bInP) - { - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"</w:hyperlink>"); - oXml->WriteString(L"</w:p>"); - m_bInP = false; - } - m_bWasSpace = false; + + CloseP(oXml, sSelectors); + sSelectors.pop_back(); } // Нумерованный список @@ -1666,16 +2609,7 @@ class CHtmlFile2_Private bCross = true; } else if(sName == L"name") - { - std::wstring sCrossId = std::to_wstring(m_nCrossId++); - oXml->WriteString(L"<w:bookmarkStart w:id=\""); - oXml->WriteString(sCrossId); - oXml->WriteString(L"\" w:name=\""); - oXml->WriteString(sText); - oXml->WriteString(L"\"/><w:bookmarkEnd w:id=\""); - oXml->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) @@ -1690,19 +2624,12 @@ class CHtmlFile2_Private if (bCross && sFootnote == L"href") sFootnote = sRef.substr(sRef.find('#') + 1); - if (!m_bInP) - { - oXml->WriteString(L"<w:p>"); - for (size_t i = 0; i < sSelectors.size() - 1; i++) - if (sSelectors[i].m_wsName == L"a") - oXml->WriteString(L"<w:hyperlink>"); - m_bInP = true; - m_bWasPStyle = false; - } wrP(oXml, sSelectors, oTS); + // Перекрестная ссылка внутри файла if(bCross) { + m_oState.m_bInHyperlink = true; oXml->WriteString(L"<w:hyperlink w:tooltip=\"Current Document\" w:anchor=\""); size_t nSharp = sRef.find('#'); if(nSharp == std::wstring::npos) @@ -1723,6 +2650,7 @@ class CHtmlFile2_Private oRelationshipXml->WriteEncodeXmlString(sRef); oRelationshipXml->WriteString(L"\" TargetMode=\"External\"/>"); + m_oState.m_bInHyperlink = true; // Пишем в document.xml oXml->WriteString(L"<w:hyperlink w:tooltip=\""); oXml->WriteEncodeXmlString(sNote); @@ -1734,14 +2662,19 @@ class CHtmlFile2_Private if(!readStream(oXml, sSelectors, oTS)) { oXml->WriteString(L"<w:r>"); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"); - oXml->WriteEncodeXmlString(sAlt); + oXml->WriteEncodeXmlString(!sAlt.empty() ? sAlt : L" "); oXml->WriteString(L"</w:t></w:r>"); } - if (m_bInP) + + if (m_oState.m_bInP) { - oXml->WriteString(L"</w:hyperlink>"); + if (m_oState.m_bInHyperlink) + { + oXml->WriteString(L"</w:hyperlink>"); + m_oState.m_bInHyperlink = false; + } bool bFootnote = false; if (sSelectors.size() > 1) @@ -1764,8 +2697,11 @@ class CHtmlFile2_Private else oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteRef/></w:r>"); } + + CloseP(oXml, sSelectors); } - sNote = L""; + + sNote.clear(); } bool readBase64 (const std::wstring& sSrcM, std::wstring& sExtention) @@ -1781,29 +2717,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) { - int nOffset = nBase + 7; - int nSrcLen = (int)(sSrcM.length() - nBase + 1); + BYTE* pImageData = new BYTE[nDecodeLen]; - int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen); - if (nDecodeLen != 0) + 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(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen)) - { - oImageWriter.WriteFile(pImageData, (DWORD)nDecodeLen); - bRes = true; - } - RELEASEARRAYOBJECTS(pImageData); + std::wstring wsSvg(pImageData, pImageData + nDecodeLen); + bRes = readSVG(wsSvg); + sExtention = L"png"; + } + 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(); } - oImageWriter.CloseFile(); + + RELEASEARRAYOBJECTS(pImageData); } return bRes; @@ -1835,14 +2783,34 @@ 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<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt) + void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc) { if (wsAlt.empty()) + { + //TODO:: реализовать отображение того, что картинку не удалось получить + if (wsSrc.empty()) + WriteEmptyParagraph(oXml, false, m_oState.m_bInP); + else + { + m_oDocXmlRels.WriteString(L"<Relationship Id=\"rId"); + m_oDocXmlRels.WriteString(std::to_wstring(m_nId)); + m_oDocXmlRels.WriteString(L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\""); + m_oDocXmlRels.WriteEncodeXmlString(wsSrc); + m_oDocXmlRels.WriteString(L"\" TargetMode=\"External\"/>"); + + const bool bOpenedP{OpenP(oXml)}; + + WriteEmptyImage(oXml, 304800, 304800); + + if (bOpenedP) + CloseP(oXml, sSelectors); + } return; + } wrP(oXml, sSelectors, oTS); oXml->WriteString(L"<w:r>"); - wrR(oXml, sSelectors, oTS); + wrRPr(oXml, sSelectors, oTS); oXml->WriteString(L"<w:t xml:space=\"preserve\">"); oXml->WriteEncodeXmlString(wsAlt); oXml->WriteString(L"</w:t></w:r>"); @@ -1864,7 +2832,7 @@ class CHtmlFile2_Private if (sSrcM.empty()) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); return; } @@ -1874,11 +2842,13 @@ class CHtmlFile2_Private if (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"data" && sSrcM.find(L"/", 4) != std::wstring::npos) bIsBase64 = true; - if (!bIsBase64) + if (!bIsBase64 && (sSrcM.length() <= 7 || L"http" != sSrcM.substr(0, 4))) + { sSrcM = NSSystemPath::ShortenPath(sSrcM); - if (!CanUseThisPath(sSrcM, bIsAllowExternalLocalFiles)) - return; + if (!CanUseThisPath(sSrcM, bIsAllowExternalLocalFiles)) + return; + } int nImageId = -1; std::wstring sImageSrc, sExtention; @@ -1893,7 +2863,7 @@ class CHtmlFile2_Private std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower); if (NotValidExtension(sExtention)) { - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); return; } @@ -1939,7 +2909,7 @@ class CHtmlFile2_Private } if (!bRes) - ImageAlternative(oXml, sSelectors, oTS, wsAlt); + ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM); else { wrP(oXml, sSelectors, oTS); @@ -1949,18 +2919,10 @@ class CHtmlFile2_Private std::wstring wrP(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) - { - oXml->WriteString(L"<w:p>"); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"<w:hyperlink>"); - m_bInP = true; - m_bWasPStyle = false; - } - if (m_bWasPStyle) + OpenP(oXml); + + if (m_oState.m_bWasPStyle) return L""; - oXml->WriteString(L"<w:pPr><w:pStyle w:val=\""); std::vector<std::pair<size_t, NSCSS::CNode>> temporary; size_t i = 0; @@ -1981,6 +2943,9 @@ class CHtmlFile2_Private std::wstring sPStyle = GetStyle(oStyle, true); + if (sPStyle.empty() && oTS.sPStyle.empty()) + return L""; + m_oXmlStyle.WriteLitePStyle(oStyleSetting); std::wstring sPSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); @@ -2004,17 +2969,25 @@ class CHtmlFile2_Private } } - oXml->WriteString(sPStyle); - oXml->WriteString(L"\"/>"); + oXml->WriteNodeBegin(L"w:pPr"); + + if (!sPStyle.empty()) + { + oXml->WriteString(L"<w:pStyle w:val=\""); + oXml->WriteString(sPStyle); + oXml->WriteString(L"\"/>"); + } + oXml->WriteString(oTS.sPStyle + L' ' + sPSettings); - oXml->WriteString(L"</w:pPr>"); - m_bWasPStyle = true; + oXml->WriteNodeEnd(L"w:pPr"); + m_oState.m_bWasPStyle = true; + return sPStyle; } - std::wstring wrR(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) + std::wstring wrRPr(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS) { - if (!m_bInP) + if (!m_oState.m_bInP) return L""; NSCSS::CCompiledStyle oStyleSetting = m_oStylesCalculator.GetCompiledStyle(sSelectors, true); @@ -2028,15 +3001,54 @@ class CHtmlFile2_Private const std::wstring sRSettings = m_oXmlStyle.GetStyle(); m_oXmlStyle.Clear(); - oXml->WriteString(L"<w:rPr><w:rStyle w:val=\""); - oXml->WriteString(sRStyle); - oXml->WriteString(L"\"/>"); + if (!sRStyle.empty() || !oTS.sRStyle.empty()) + { + oXml->WriteString(L"<w:rPr>"); + if (!sRStyle.empty()) + { + oXml->WriteString(L"<w:rStyle w:val=\""); + oXml->WriteString(sRStyle); + oXml->WriteString(L"\"/>"); + } - oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); - oXml->WriteString(L"</w:rPr>"); + oXml->WriteString(oTS.sRStyle + L' ' + sRSettings); + oXml->WriteString(L"</w:rPr>"); + } return sRStyle; } + void WriteImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight, const std::wstring& wsId) + { + // Пишем в document.xml + pXml->WriteString(L"<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\""); + pXml->WriteString(std::to_wstring(nWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(nHeight)); + pXml->WriteString(L"\"/><wp:docPr id=\""); + pXml->WriteString(wsId); + pXml->WriteString(L"\" name=\"\"/><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\""); + pXml->WriteString(wsId); + pXml->WriteString(L"\" name=\"\"/><pic:cNvPicPr></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rPic"); + pXml->WriteString(wsId); + pXml->WriteString(L"\"/><a:stretch/></pic:blipFill><pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\""); + pXml->WriteString(std::to_wstring(nWidth)); + pXml->WriteString(L"\" cy=\""); + pXml->WriteString(std::to_wstring(nHeight)); + pXml->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + } + + void WriteEmptyImage(NSStringUtils::CStringBuilder* pXml, int nWidth, int nHeight) + { + pXml->WriteString(L"<w:r><w:rPr><w:noProof/></w:rPr><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"); + pXml->WriteString(L"<wp:docPr id=\"" + std::to_wstring(m_nId - 7) + L"\" name=\"\"/>"); + pXml->WriteString(L"<wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></wp:cNvGraphicFramePr>"); + pXml->WriteString(L"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"); + pXml->WriteString(L"<pic:nvPicPr><pic:cNvPr id=\"0\" name=\"\"/><pic:cNvPicPr><a:picLocks noChangeAspect=\"1\" noChangeArrowheads=\"1\"/></pic:cNvPicPr></pic:nvPicPr>"); + pXml->WriteString(L"<pic:blipFill><a:blip r:link=\"rId" + std::to_wstring(m_nId++) + L"\"><a:extLst><a:ext uri=\"{28A0092B-C50C-407E-A947-70E740481C1C}\"><a14:useLocalDpi xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\" val=\"0\"/></a:ext></a:extLst></a:blip><a:srcRect/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>"); + pXml->WriteString(L"<pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"" + std::to_wstring(nWidth) + L"\" cy=\"" + std::to_wstring(nHeight) + L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom><a:noFill/><a:ln><a:noFill/></a:ln></pic:spPr>"); + pXml->WriteString(L"</pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + } + void ImageRels (NSStringUtils::CStringBuilder* oXml, int nImageId, const std::wstring& sImageSrc, const std::wstring& sExtention) { bool bNew = nImageId < 0; @@ -2047,8 +3059,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) { @@ -2086,37 +3100,16 @@ class CHtmlFile2_Private nWx = nW; } - // Пишем в document.xml - oXml->WriteString(L"<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\"><wp:extent cx=\""); - oXml->WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/><wp:docPr id=\""); - oXml->WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\""); - oXml->WriteString(sImageId); - oXml->WriteString(L"\" name=\"\"/><pic:cNvPicPr></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rPic"); - oXml->WriteString(sImageId); - oXml->WriteString(L"\"/><a:stretch/></pic:blipFill><pic:spPr bwMode=\"auto\"><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\""); - oXml->WriteString(std::to_wstring(nWx)); - oXml->WriteString(L"\" cy=\""); - oXml->WriteString(std::to_wstring(nHy)); - oXml->WriteString(L"\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>"); + WriteImage(oXml, nWx, nHy, sImageId); } void readNote (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const std::wstring& sNote) { if(sNote.empty()) return; - if (!m_bInP) - { - oXml->WriteString(L"<w:p>"); - for (const NSCSS::CNode& item : sSelectors) - if (item.m_wsName == L"a") - oXml->WriteString(L"<w:hyperlink>"); - m_bInP = true; - m_bWasPStyle = false; - } + + OpenP(oXml); + oXml->WriteString(L"<w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteReference w:id=\""); oXml->WriteString(std::to_wstring(m_nFootnoteId)); oXml->WriteString(L"\"/></w:r>"); @@ -2127,92 +3120,107 @@ class CHtmlFile2_Private m_oNoteXml.WriteString(L"</w:t></w:r></w:p></w:footnote>"); } - void readSVG (NSStringUtils::CStringBuilder* oXml) + bool readSVG (const std::wstring& wsSvg) { - // Сохранить как .svg картинку - NSStringUtils::CStringBuilder oSVG; - oSVG.WriteString(L"<svg "); - while (m_oLightReader.MoveToNextAttribute()) + if (wsSvg.empty()) + return false; + + CSvgFile oSvgReader; + + NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create(); + NSFonts::IFontManager* pFontManager = pFonts->GenerateFontManager(); + NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create(); + + pFontCache->SetStreams(pFonts->GetStreams()); + pFontManager->SetOwnerCache(pFontCache); + + oSvgReader.SetFontManager(pFontManager); + + if (!oSvgReader.ReadFromWString(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(pFontManager); + pFonts->Release(); + 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(pFontManager); - 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; + double dX, dY, dW, dH; + oSvgReader.GetBounds(dX, dY, dW, dH); - const std::wstring sImageName = NSSystemPath::ShortenPath(sSVG.substr(nHRef, nHRefLen - nHRef)); + if (dW < 0) dW = -dW; + if (dH < 0) dH = -dH; - if (!CanUseThisPath(sImageName, GetStatusUsingExternalLocalFiles())) - break; + double dOneMaxSize = (double)1000.; - 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); + 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"</svg>"); + int nWidth = static_cast<int>(dW + 0.5); + int nHeight = static_cast<int>(dH + 0.5); - 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)) + double dWidth = 25.4 * nWidth / 96; + double dHeight = 25.4 * nHeight / 96; + + 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"; - MetaFile::ConvertToRasterMaxSize(pMetafile, sPngFile.data(), 4, 1000); + ((unsigned int*)pBgraData)[i] = alfa; } - pMetafile->Release(); + 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); + + oSvgReader.SetWorkingDirectory(m_sSrc); + oSvgReader.Draw(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(pFontManager); + RELEASEINTERFACE(pGrRenderer); + + if (pBgraData) + free(pBgraData); + pFonts->Release(); - ImageRels(oXml, -1, L"", L"png"); + return true; } }; diff --git a/HtmlFile2/htmlfile2.h b/HtmlFile2/htmlfile2.h index 9ecb12486df..80ed8f1214a 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; diff --git a/HtmlFile2/src/Languages.h b/HtmlFile2/src/Languages.h new file mode 100644 index 00000000000..e267415ebec --- /dev/null +++ b/HtmlFile2/src/Languages.h @@ -0,0 +1,84 @@ +#ifndef LANGUAGES_LIST_H +#define LANGUAGES_LIST_H + +#include <map> +#include <string> +#include <algorithm> + +const static std::map<std::wstring, std::wstring> 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<std::wstring, std::wstring>::const_iterator itFounded = m_Languages_HTML.find(wsLanguage); + + if (m_Languages_HTML.end() != itFounded) + return itFounded->first + L"-" + itFounded->second; + + return std::wstring(); +} + +#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 <boost/algorithm/string.hpp> +#include <boost/regex.hpp> +#include <vector> + +#if defined(_WIN32) || defined (_WIN64) +#include <tchar.h> +#elif __linux__ || MAC +#include <libgen.h> +#endif + +namespace NSStringFinder +{ + template<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> + 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<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> + 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<typename StringType::const_iterator> 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<char>(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<wchar_t>(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<char>(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<wchar_t>(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); + } + + template<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> + TFoundedData<CharType> FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector<StringType>& arDelimiters, const std::vector<StringType>& arEndings, const size_t& unStarting) + { + if (sString.length() < unStarting) + return TFoundedData<CharType>(); + + 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<typename StringType::const_iterator> oResult; + + if (!boost::regex_search(sString.begin() + unStarting, sString.end(), oResult, oRegex)) + return TFoundedData<CharType>(); + + TFoundedData<CharType> 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<char> FindPropety(const std::string& sString, const std::string& sProperty, const std::vector<std::string>& arDelimiters, const std::vector<std::string>& arEndings, const size_t& unStarting = 0) + { + return FindPropetyTemplate<char>(sString, sProperty, arDelimiters, arEndings, unStarting); + } + + TFoundedData<wchar_t> FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector<std::wstring>& arDelimiters, const std::vector<std::wstring>& arEndings, const size_t& unStarting = 0) + { + return FindPropetyTemplate<wchar_t>(wsString, wsProperty, arDelimiters, arEndings, unStarting); + } + + template<class CharType, class StringType = std::basic_string<CharType, std::char_traits<CharType>, std::allocator<CharType>>> + 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<typename StringType::const_iterator> 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<char>(sValue, sTagName, unStart); + } + + bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0) + { + return RemoveEmptyTagTemplate<wchar_t>(sValue, sTagName, unStart); + } + + template <typename StringType, typename StringEndgeType> + void CutInside(StringType& sString, const StringEndgeType& sLeftEdge, const StringEndgeType& sRightEdge) + { + typedef const boost::iterator_range<typename StringType::const_iterator> 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 <typename StringType, typename StringEdgeType> + void CutInside(StringType& sString, const StringEdgeType& sEdge) + { + CutInside(sString, sEdge, sEdge); + } + + template <typename StringFirstType, typename StringSecondType> + bool Equals(const StringFirstType& sFirstString, const StringSecondType& sSecondString) + { + return boost::iequals(sFirstString, sSecondString); + } + + template <typename StringFirstType, typename StringSecondType> + bool EqualOf(const StringFirstType& sFirstString, const std::vector<StringSecondType>& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template <typename StringFirstType, typename StringSecondType> + bool EqualOf(const StringFirstType& sFirstString, const std::initializer_list<StringSecondType>& arStrings) + { + for (const StringFirstType& sString : arStrings) + if (boost::iequals(sFirstString, sString)) + return true; + + return false; + } + + template <typename StringType, typename StringValueType> + 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<typename std::wstring::const_iterator> 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<typename std::wstring::const_iterator> 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/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<PROJECTINFORMATION>(reader); ReferencesRecord = boost::make_shared<PROJECTREFERENCES>(reader); ModulesRecord = boost::make_shared<PROJECTMODULES>(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<std::string> 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<std::wstring> 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/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/OleObject.cpp b/MsBinaryFile/DocFile/OleObject.cpp index 7d039d1e871..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(); 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<WideString*>(_ctx->_doc->AssocNames->operator[]( 17 )); + CRYPT::_ecmaWriteProtectData data; + + WideString* passw = static_cast<WideString*>(_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/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<BorderCode> brcHorz; std::shared_ptr<BorderCode> 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<SinglePropertyModifier>::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<BorderCode>(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 4), size); + brcLeft = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); + + memcpy(brc80, (iter->Arguments + 8), size); + brcBottom = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); - memcpy(brc80, iter->Arguments, size); - brcTop = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 12), size); + brcRight = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 4), size); - brcLeft = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 16), size); + brcHorz = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); - memcpy(brc80, (iter->Arguments + 8), size); - brcBottom = std::shared_ptr<BorderCode>(new BorderCode(brc80, size)); + memcpy(brc80, (iter->Arguments + 20), size); + brcVert = std::shared_ptr<BorderCode>(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<BorderCode>(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<BorderCode>(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<BorderCode>(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/PptFile/Drawing/Attributes.h b/MsBinaryFile/PptFile/Drawing/Attributes.h index f504f1be85f..7029dedc8d3 100644 --- a/MsBinaryFile/PptFile/Drawing/Attributes.h +++ b/MsBinaryFile/PptFile/Drawing/Attributes.h @@ -83,22 +83,27 @@ namespace PPT eftHyperlink = 3, eftObject = 4, eftSlide = 5, - eftFile = 6 + eftFile = 6, + eftOleObject = 7 }; - ExFilesType m_type = eftNone; - _UINT32 m_dwID = 0; - std::wstring m_strFilePath = L""; - std::wstring m_name; + 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; + 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; + bool m_bLoop = false; + bool m_fNarration = false; // isNarration pptx + bool m_fRewind = false; CExFilesInfo() { @@ -168,6 +173,7 @@ namespace PPT std::vector<CExFilesInfo> m_arHyperlinks; std::vector<CExFilesInfo> m_arSlides; std::vector<CExFilesInfo> m_arFiles; + std::vector<CExFilesInfo> m_arOleObjects; std::vector<CExFilesInfo> m_arAudioCollection; @@ -177,9 +183,10 @@ namespace PPT m_arImages.clear(); m_arAudios.clear(); m_arAudioCollection.clear(); + m_arOleObjects.clear(); } - CExMedia() : m_arVideos(), m_arImages(), m_arAudios() + CExMedia() { } @@ -198,6 +205,8 @@ namespace PPT 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; } @@ -266,6 +275,19 @@ namespace PPT return NULL; } + CExFilesInfo* LockOleObject(_UINT32 dwID) + { + 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; + } CExFilesInfo* LockAudioFromCollection(_UINT32 dwID) { size_t nCount = m_arAudioCollection.size(); @@ -302,6 +324,12 @@ namespace PPT eType = CExFilesInfo::eftAudio; return pInfo; } + pInfo = LockOleObject(dwID); + if (NULL != pInfo) + { + eType = CExFilesInfo::eftOleObject; + return pInfo; + } pInfo = LockSlide(dwID); if (NULL != pInfo) { 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 4c8bfa4ecf3..bcbae43ce2c 100644 --- a/MsBinaryFile/PptFile/Drawing/Elements.cpp +++ b/MsBinaryFile/PptFile/Drawing/Elements.cpp @@ -490,7 +490,24 @@ namespace PPT strXmlPPTX += L"</a:custGeom>"; 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; 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/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 a2b6a03c20d..943564f3c67 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -118,6 +118,8 @@ namespace PPT 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(); @@ -164,6 +166,7 @@ namespace PPT 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(); @@ -236,7 +239,7 @@ namespace PPT <Default Extension=\"bin\" ContentType=\"application/vnd.openxmlformats-officedocument.oleObject\" />\ <Default Extension=\"jpg\" ContentType=\"image/jpeg\"/>"; - if (m_pDocument->m_bMacros) + if (m_pDocument->m_bMacroEnabled) { strContentTypes += L"<Override PartName=\"/ppt/presentation.xml\" ContentType=\"application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml\" />\ <Override PartName=\"/ppt/vbaProject.bin\" ContentType=\"application/vnd.ms-office.vbaProject\" />"; @@ -532,7 +535,7 @@ namespace PPT strPresRels += L"<Relationship Id=\"rId" + std::to_wstring(nCurrentRels++) + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles\" Target=\"tableStyles.xml\"/>"; strPresRels += L"<Relationship Id=\"rId" + std::to_wstring(nCurrentRels++) + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps\" Target=\"viewProps.xml\"/>"; - if (m_pDocument->m_bMacros) + if (m_pDocument->m_bMacroEnabled) { std::wstring strVbaProject = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR + L"vbaProject.bin"; @@ -589,7 +592,6 @@ namespace PPT { std::wstring strPptDirectory = m_strDestPath + FILE_SEPARATOR_STR + L"ppt" + FILE_SEPARATOR_STR; - NSDirectory::CreateDirectory(strPptDirectory + L"media"); NSDirectory::CreateDirectory(strPptDirectory + L"theme"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters"); NSDirectory::CreateDirectory(strPptDirectory + L"slideMasters" + FILE_SEPARATOR_STR + L"_rels"); @@ -1544,7 +1546,14 @@ namespace PPT } oWriter.WriteString(std::wstring(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")); - oWriter.WriteString(std::wstring(L"<p:sld xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\"")); + oWriter.WriteString(std::wstring(L"<p:sld \ +xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" \ +xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" \ +xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\" \ +xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ +xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" \ +xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\"")); + if (!pSlide->m_bShowMasterShapes) oWriter.WriteString(std::wstring(L" showMasterSp=\"0\"")); if (pSlide->m_bHidden) diff --git a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp index b8a2601462f..831f83be9a2 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.cpp @@ -32,8 +32,9 @@ #include "ImageManager.h" #include <boost/algorithm/string.hpp> #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() @@ -46,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) @@ -57,6 +59,10 @@ 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; @@ -66,27 +72,83 @@ void CMediaManager::SetTempMedia(const std::wstring& strSrc) OOX::CPath pathSrc(strSrc); m_strTempMedia = pathSrc.GetPath(); } -std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput) +std::wstring CMediaManager::GenerateVideo(const std::wstring &strInput, const std::wstring& strExt) { - return GenerateMedia(strInput, L"video", m_lIndexNextVideo, L".avi"); + 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<std::wstring, std::wstring>::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<std::wstring, std::wstring>::iterator pPair = m_mapMedia.find(strInput); if (m_mapMedia.end() != pPair) @@ -98,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 } @@ -116,25 +178,33 @@ std::wstring CMediaManager::GenerateMedia(const std::wstring &strInput, const st 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 + } + std::wstring strMediaName = Template + std::to_wstring(++Indexer); std::wstring strOutput = m_strDstMedia + strMediaName + strExts; - strMediaName = L"../media/" + strMediaName + strExts; + strMediaName = L"../media/" + strMediaName + strExts; - OOX::CPath pathInput(strInput); + 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""; @@ -150,7 +220,7 @@ void CMediaManager::WriteAudioCollection(const std::vector<PPT::CExFilesInfo> &a for (auto& audio : audioCont) { - auto pathAudio = GenerateAudio(audio.m_strFilePath); + auto pathAudio = GenerateAudio(audio.m_strFilePath, audio.m_strFileExt); } } @@ -359,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) @@ -389,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 bcb71b8a8dd..5e357909ec8 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ImageManager.h @@ -43,27 +43,36 @@ class CMediaManager { private: - std::map<std::wstring, std::wstring> m_mapMedia; + std::map<std::wstring, std::wstring> 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); void SetTempMedia(const std::wstring& strSrc); - std::wstring GenerateVideo(const std::wstring& strInput); - std::wstring GenerateAudio(const std::wstring& strInput); + + 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<PPT::CExFilesInfo>& audioCont); bool IsNeedDownload(const std::wstring& strFile); }; @@ -72,11 +81,11 @@ std::wstring CorrectXmlString3(const std::wstring & str); class CRelsGenerator { private: - PPT::CStringWriter m_oWriter; - int m_lNextRelsID; - std::map<std::wstring, int> m_mapMediaRelsID; - CMediaManager* m_pManager; - std::map<std::wstring, std::wstring> m_mapHyperlinks; + PPT::CStringWriter m_oWriter; + int m_lNextRelsID; + std::map<std::wstring, int> m_mapMediaRelsID; + CMediaManager* m_pManager; + std::map<std::wstring, std::wstring> m_mapHyperlinks; public: CRelsGenerator(CMediaManager* pManager); @@ -90,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 f9b19860a26..c22e19b8f07 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.cpp @@ -552,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<COleObjectElement*>(m_pElement.get()); + std::wstring strShapeID = std::to_wstring(pOleObjectElement ? 0 : pImageElement->m_lID); m_oWriter.WriteString(std::wstring(L"<p:cNvPr id=\"") + strShapeID + L"\"" ); @@ -577,7 +578,6 @@ void PPT::CShapeWriter::WriteImageInfo() } m_oWriter.WriteString(std::wstring(L">")); - WriteHyperlink(m_pElement->m_arrActions); m_oWriter.WriteString(std::wstring(L"</p:cNvPr><p:cNvPicPr><a:picLocks")); @@ -702,7 +702,86 @@ void PPT::CShapeWriter::WriteGroupInfo() std::wstring str2 = L"</p:nvGrpSpPr>"; m_oWriter.WriteString(str2); } +void PPT::CShapeWriter::WriteOleObjectInfo(const std::wstring& strRid, const std::wstring& xfrm) +{ + COleObjectElement* pOleObjectElement = dynamic_cast<COleObjectElement*>(m_pElement.get()); + if (!pOleObjectElement) return; + + m_oWriter.WriteString(std::wstring(L"<p:graphicFrame>")); + + m_oWriter.WriteString(std::wstring(L"<p:nvGraphicFramePr>")); + + 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"<p:cNvPr id=\"") + strTableID + L"\""); + + if (pOleObjectElement->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"<a:hlinkClick")); + m_oWriter.WriteString(std::wstring(L" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"")); + m_oWriter.WriteString(std::wstring(L" r:id=\"" + rId)); + m_oWriter.WriteString(std::wstring(L"\"></a:hlinkClick>")); + } + } + m_oWriter.WriteString(std::wstring(L"</p:cNvPr>")); + + m_oWriter.WriteString(std::wstring(L"<p:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect=\"1\"/></p:cNvGraphicFramePr>")); + + ++m_lNextShapeID; + + m_oWriter.WriteString(std::wstring(L"<p:nvPr/>")); + + m_oWriter.WriteString(std::wstring(L"</p:nvGraphicFramePr>")); + + if (pOleObjectElement->m_bChildAnchorEnabled || pOleObjectElement->m_bAnchorEnabled) + { + m_oWriter.WriteString(std::wstring(L"<p:xfrm") + xfrm + std::wstring(L"</p:xfrm>")); + } + + m_oWriter.WriteString(std::wstring(L"<a:graphic>")); + m_oWriter.WriteString(std::wstring(L"<a:graphicData uri=\"http://schemas.openxmlformats.org/presentationml/2006/ole\">")); + m_oWriter.WriteString(std::wstring(L"<p:oleObj")); + if (false == pOleObjectElement->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"><p:embed/>")); +} void PPT::CShapeWriter::WriteTableInfo() { CGroupElement* pGroupElement = dynamic_cast<CGroupElement*>(m_pElement.get()); @@ -1725,7 +1804,7 @@ std::vector<CInteractiveInfo> CShapeWriter::getActionsByNum(const int num) } // TODO! Not work correct -std::wstring PPT::CShapeWriter::ConvertTable () +std::wstring PPT::CShapeWriter::ConvertTable() { CGroupElement* pGroupElement = dynamic_cast<CGroupElement*>(m_pElement.get()); if (!pGroupElement) return L""; @@ -2001,12 +2080,11 @@ void PPT::CShapeWriter::ParseXmlAlternative(const std::wstring & xml) } } - std::wstring PPT::CShapeWriter::ConvertImage() -{ +{ CImageElement* pImageElement = dynamic_cast<CImageElement*>(m_pElement.get()); if (!pImageElement) return L""; - + if (pImageElement->m_bImagePresent == false) { if (pImageElement->m_sName.empty()) return L""; @@ -2027,21 +2105,69 @@ std::wstring PPT::CShapeWriter::ConvertImage() if (strRid.empty()) return L""; - m_oWriter.WriteString(std::wstring(L"<p:pic>")); - - 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"<a:off x=\"" + + std::to_wstring(pImageElement->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"<a:ext cx=\"" + std::to_wstring(width) + L"\" cy=\"" + std::to_wstring(height) + L"\"/>"; + } + else + { + strAnchor += L"<a:ext cx=\"0\" cy=\"0\"/>"; + } + } + + COleObjectElement* pOleObjectElement = dynamic_cast<COleObjectElement*>(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"<p:pic>")); + + WriteImageInfo(); m_oWriter.WriteString(std::wstring(L"<p:blipFill>")); @@ -2107,41 +2233,7 @@ std::wstring PPT::CShapeWriter::ConvertImage() if (pImageElement->m_bChildAnchorEnabled || pImageElement->m_bAnchorEnabled) { - std::wstring str; - - m_oWriter.WriteString(std::wstring(L"<a:xfrm")); - if (0 != pImageElement->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"<a:off x=\"" + - std::to_wstring(pImageElement->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"<a:ext cx=\"" + std::to_wstring(width) + L"\" cy=\"" + std::to_wstring(height) + L"\"/>"); - } - else - { - m_oWriter.WriteString(L"<a:ext cx=\"0\" cy=\"0\"/>"); - } - m_oWriter.WriteString(std::wstring(L"</a:xfrm>")); + m_oWriter.WriteString(std::wstring(L"<a:xfrm") + strAnchor + std::wstring(L"</a:xfrm>")); } m_oWriter.WriteString(std::wstring(L"<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom>")); @@ -2155,6 +2247,14 @@ std::wstring PPT::CShapeWriter::ConvertImage() m_oWriter.WriteString(std::wstring(L"</p:spPr>")); m_oWriter.WriteString(std::wstring(L"</p:pic>")); + + if (pOleObjectElement) + { + m_oWriter.WriteString(std::wstring(L"</p:oleObj>")); + m_oWriter.WriteString(std::wstring(L"</a:graphicData>")); + m_oWriter.WriteString(std::wstring(L"</a:graphic>")); + m_oWriter.WriteString(std::wstring(L"</p:graphicFrame>")); + } pImageElement = NULL; return m_oWriter.GetData(); diff --git a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h index f97df3fe0e5..76cebf1e0f9 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h +++ b/MsBinaryFile/PptFile/PPTXWriter/ShapeWriter.h @@ -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..47245d0fe19 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/TableWriter.cpp @@ -243,7 +243,15 @@ bool ProtoTable::fillCells(std::vector<CElementPtr> &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<CElementPtr> &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<CShapeElement*>(m_ptrSpElCell.get()); auto pShape = pShapeEl->m_pShape; //anchor 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<CPPTUserInfo*> m_arUsers; std::map<int, std::wstring> 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 7efa111bd39..70603dae79e 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.cpp @@ -55,7 +55,6 @@ m_pStorageDecrypt(NULL), m_pDecryptor(NULL), m_arOffsetPictures() { - m_VbaProjectStg = NULL; m_pDocumentInfo = NULL; m_lIndexThisUser = -1; @@ -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) { @@ -411,51 +409,7 @@ bool CPPTUserInfo::ReadDocumentPersists(POLE::Stream* pStream) m_mapHandoutMasters.insert(std::pair<_UINT32, CRecordSlide*>(0, pSlide)); } } - if (m_bMacros) - { - m_bMacros = false; - std::vector<CRecordDocInfoListContainer*> 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; } //-------------------------------------------------------------------------------------------- @@ -507,6 +461,27 @@ void CPPTUserInfo::ReadExtenalObjects() m_bIsSetupEmpty = TRUE; m_arrBlipStore[0]->SetUpPicturesInfos(&m_arOffsetPictures); } + + if (m_bMacroEnabled) + { + m_bMacroEnabled = false; + std::vector<CRecordDocInfoListContainer*> 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() @@ -2380,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 + L".audio"; + 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); @@ -2394,15 +2370,22 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) return; // читаем видео ---------------------------------------------- - std::vector<CRecordExVideoContainer*> oArray; - pExObjects->GetRecordsByType(&oArray, true); + std::vector<CRecordExVideoContainer*> 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<CRecordExOleEmbedContainer*> oArrayObj; + pExObjects->GetRecordsByType(&oArrayObj, true); - oArray.clear(); + for (size_t nIndex = 0; nIndex < oArrayObj.size(); ++nIndex) + { + LoadExOleObject(oArrayObj[nIndex]); + } + oArrayObj.clear(); // ----------------------------------------------------------- // читаем аудио ---------------------------------------------- @@ -2528,8 +2511,44 @@ void CPPTUserInfo::LoadExternal(CRecordExObjListContainer* pExObjects) } } +void CPPTUserInfo::LoadExOleObject(CRecordsContainer* pExObject) +{ + //exOleEmbedAtom + //exOleObjAtom + //menuNameAtom + //progIdAtom + //clipboardNameAtom + //metafile(variable) + + std::vector<CRecordExOleEmbedAtom*> oArrayExOleEmbed; + std::vector<CRecordExOleObjAtom*> oArrayExOleObj; + std::vector<CRecordCString*> 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) { diff --git a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h index 18221edeef1..3812682dffa 100644 --- a/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h +++ b/MsBinaryFile/PptFile/Reader/PPTDocumentInfoOneUser.h @@ -100,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; @@ -161,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/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/Records/Drawing/ShapeContainer.cpp b/MsBinaryFile/PptFile/Records/Drawing/ShapeContainer.cpp index 7a4728febc8..d4c1d52c57e 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; } @@ -1641,10 +1653,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 +1686,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 +1801,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<CRecordSlideNumberMetaAtom*> oArraySlideNumberMeta; 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/XlsFile/Converter/xlsx_drawing_context.cpp b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp index 98d5f9a8f63..f0d2708d5e1 100644 --- a/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp +++ b/MsBinaryFile/XlsFile/Converter/xlsx_drawing_context.cpp @@ -997,7 +997,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) { @@ -1368,12 +1368,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) { @@ -1448,7 +1448,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) { @@ -1500,7 +1500,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); @@ -1601,7 +1601,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) { diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 88bfd184ea7..3bf7f063c0b 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 > 16384) { - column = 255; + column = 16384; } 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 > 1048576) { - row = 65535; + row = 1048576; } return row; } @@ -692,6 +704,28 @@ 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 definenames2index(std::wstring name) { unsigned int index; @@ -736,6 +770,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..305d4066912 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,7 @@ 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); } diff --git a/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp b/MsBinaryFile/XlsFile/Format/Binary/CFRecord.cpp index eff534e0173..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) @@ -262,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; } @@ -302,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) @@ -311,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]); + } } @@ -387,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); } @@ -432,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/Logic/Biff_records/BOF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/BOF.cpp index 777ab4d89c0..57fb2d8a772 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 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/Label.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp index 937691a8da9..96200f2720d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Label.cpp @@ -57,7 +57,7 @@ void Label::readFields(CFRecord& record) record >> cell; - if (global_info_->Version == 0x0200) + if (global_info_->Version == 0x0200 || global_info_->Version == 0x0400) { ShortXLAnsiString name; record >> name; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp index 18c975d9a26..3b7549da4d9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.cpp @@ -94,7 +94,7 @@ int Number::serialize(std::wostream & stream) return 0; } //--------------------------------------------------------------------------------- -Integer_BIFF2::Integer_BIFF2() +Integer_BIFF2::Integer_BIFF2() : num(0) {} Integer_BIFF2::~Integer_BIFF2() {} @@ -106,7 +106,18 @@ void Integer_BIFF2::readFields(CFRecord& record) { global_info_ = record.getGlobalWorkbookInfo(); - record >> cell >> num; + record >> cell; + + if (record.getRdPtr() + 2 < record.getDataSize()) + { + record >> num; + } + else + { + _INT16 num_2byte = 0; + record >> num_2byte; + num = num_2byte; + } } 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<std::wstring >(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<std::wstring >(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/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<std::wstring >(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_structures/BiffString.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffString.h index 0be5d56720f..03443bef33f 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(); 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/Cell.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp index b4cff4fc916..f8b19e0b4bd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp @@ -59,7 +59,8 @@ void Cell::load(CFRecord& record) { record >> rw >> col; - if (record.getGlobalWorkbookInfo()->Version == 0x0200) + if (record.getGlobalWorkbookInfo()->Version == 0x0200 || + record.getGlobalWorkbookInfo()->Version == 0x0400) { unsigned char flags1, flags2, flags3; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRangeRef.cpp index dd5354f3ce6..8c05c0ff1ab 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 = 1048576; + rowFirstRelative = false; + rowLastRelative = false; } if(-1 == columnFirst || -1 == columnLast) // no column specified - means whole row or range of rows { columnFirst = 0; - columnLast = 255; + columnLast = 16384; + 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 9d9605b83ff..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<class NameProducer, class RwType, class ColType, RELATIVE_INFO rel_info class CellRangeRef_T : public CellRangeRef { public: - CellRangeRef_T(const std::wstring & str_ref) : CellRangeRef(str_ref) {} + CellRangeRef_T(const std::wstring & str_ref) : CellRangeRef(str_ref) + { + if(sizeof(RwType) < 4) + { + columnFirst = AUX::normalizeColumn(columnFirst); + columnLast = AUX::normalizeColumn(columnLast); + rowFirst = AUX::normalizeRow(rowFirst); + rowLast = AUX::normalizeRow(rowLast); + } + } CellRangeRef_T() {} template<class otherNameProducer, class otherRwType, class otherColType, RELATIVE_INFO otherRel_info> @@ -185,24 +194,44 @@ class CellRangeRef_T : public CellRangeRef 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) { - case rel_Present: - colFirst = (columnFirst >> 2) << 2; - colLast = (columnLast >> 2) << 2; - break; - case rel_Absent: - colFirst = columnFirst; - colLast = columnLast; - break; + switch (rel_info) + { + case rel_Present: + colFirst = (columnFirst >> 2) << 2; + colLast = (columnLast >> 2) << 2; + break; + case rel_Absent: + colFirst = columnFirst; + colLast = columnLast; + break; + } + } + else + { + 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; } 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 ba503160405..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<class NameProducer, class RwType, class ColType, RELATIVE_INFO rel_info class CellRef_T : public CellRef { public: - CellRef_T(const std::wstring & str_ref) : CellRef(str_ref) {} + CellRef_T(const std::wstring & str_ref) : CellRef(str_ref) + { + if(sizeof(RwType) < 4) + { + column = AUX::normalizeColumn(column); + row = AUX::normalizeRow(row); + } + } CellRef_T() {} CellRef_T(const int row_init, const int column_init, const bool row_relative_init, const bool col_relative_init) : CellRef(row_init, column_init, row_relative_init, col_relative_init) {} @@ -180,10 +187,20 @@ class CellRef_T : public CellRef 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<ExtProp::_type, ExtProp>::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/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<XLS::PtgList*>(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<XLS::PtgList*>(rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } return *this; } 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/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..1caae069fa2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExtraArray.cpp @@ -99,7 +99,9 @@ void PtgExtraArray::save(CFRecord& record) } else { - record << cols << rows; + cols++; + rows++; + record << rows << cols; } for (auto& item : array_) { 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/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 f0e1c277d67..06211778517 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.cpp @@ -144,6 +144,21 @@ 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(); +} + } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h index e1680a9ebd1..b349e8d251d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgFuncVar.h @@ -58,6 +58,12 @@ class PtgFuncVar : public OperandPtg void setParamsNum(const unsigned char num); + const unsigned char getParamsNum(); + + const bool getFCeFunc(); + + const unsigned short getFuncIndex() const; + static const unsigned short fixed_id = 0x02; private: unsigned char cparams; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp index fae7a7ed1cd..f43c6ce7512 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgList.cpp @@ -135,7 +135,12 @@ 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; + 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/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 <<serType <<f; + if (record.getGlobalWorkbookInfo()->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..2ec84fb0066 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.cpp @@ -71,6 +71,26 @@ 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 <<serType << cch; + for(auto i:rgch) + { + record.storeAnyData(i); + } + } +} const std::wstring SerStr::toString() const { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.h index dbd792719db..e3aef2b5c51 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SerStr.h @@ -45,6 +45,7 @@ class SerStr : public SerAr SerStr(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/SharedParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp index 066752eb2a5..14d90b2532f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp @@ -44,7 +44,7 @@ SharedParsedFormula::SharedParsedFormula(const bool is_part_of_a_revision, const SharedParsedFormula& SharedParsedFormula::operator=(const std::wstring& value) { - ParsedFormula::operator = (value); + parseStringFormula(value, L"SharedParsedFormula"); return *this; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index 08f56fb64e4..43359c6508c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -70,6 +70,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 +218,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<PtgFunc>(ptg_stack.top())) @@ -236,20 +238,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<PtgParen>(ptg_stack.top())) && operand_expected) { @@ -265,7 +269,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 +286,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 +308,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 +327,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 +343,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 +353,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 +365,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 +381,51 @@ 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 { - func = PtgFuncVar::create(L"USER_DEFINED_FUNCTION", OperandPtg::ptg_VALUE); + 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 PtgNameX(operand_str, 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 +443,200 @@ 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<XLS::PtgList*>(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<PtgFunc*>(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<PtgFuncVar*>(i.get()); + auto paramsNum = funcPtr->getParamsNum(); + 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(); + } + } + } + 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<bool> StringPtgParser::PosValArgs(const unsigned int &index) const +{ + std::vector<bool> 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 0x00ED: + 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.push_back(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.push_back(true); + argVector.push_back(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 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.push_back(true); + argVector.push_back(true); + argVector.push_back(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.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(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.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + break; + case 0x001D: + argVector.push_back(false); + argVector.push_back(true); + argVector.push_back(true); + argVector.push_back(true); + case 0x0159: case 0x0145: case 0x0146: case 0x0147: case 0x0148: + argVector.push_back(false); + argVector.push_back(true); + break; + case 0x0066: case 0x0065: + argVector.push_back(true); + argVector.push_back(false); + argVector.push_back(false); + argVector.push_back(true); + break; + case 0x01E1: + for(auto i = 0; i < 127; i++) + { + argVector.push_back(false); + argVector.push_back(true); + } + 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<bool> 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..ecd56dff23e 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -296,8 +296,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 +428,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<std::wstring::const_iterator> results; if(boost::regex_search(first, last, results, reg_name)) @@ -447,7 +448,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<std::wstring::const_iterator> results; if (boost::regex_search(first, last, results, reg_table_name)) @@ -458,15 +459,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 +530,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 +542,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 +554,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 +571,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 +591,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 +614,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 +722,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<std::wstring::const_iterator> 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<std::wstring::const_iterator> 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<std::wstring::const_iterator> 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<std::wstring::const_iterator> results; if(boost::regex_search(first, last, results, reg_undef)) { @@ -737,6 +831,14 @@ const bool SyntaxPtg::extract_PtgFunc(std::wstring::const_iterator& first, std:: return false; } +// 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..90becefd32b 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.h @@ -86,6 +86,7 @@ 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 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<GradStop> 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<LPWideString*>(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<LPWideString*>(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<BIFF_WORD*>(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<BIFF_BYTE*>(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/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<ColWidth>(0, 255) : proc.repeated<ColInfo>(0, 255); + if (count < 1) + {//version 0x0400 ???? ColWidth + count = (global_info_->Version == 0x0200) ? proc.repeated<ColInfo>(0, 255) : proc.repeated<ColWidth>(0, 255); + } + int last_add = 0; for (std::list<XLS::BaseObjectPtr>::iterator it = elements_.begin(); it != elements_.end(); ++it) 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<boost::shared_array<unsigned char>, size_t> data; - data.first = boost::shared_array<BYTE>(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<BYTE>(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 2d6878c420c..d331eb57836 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.cpp @@ -95,6 +95,7 @@ std::vector<GlobalWorkbookInfo::_xti> GlobalWorkbookInfo::arXti_External_stat std::unordered_map<int, std::wstring> GlobalWorkbookInfo::mapTableNames_static; std::unordered_map<int, std::vector<std::wstring>> GlobalWorkbookInfo::mapTableColumnNames_static; std::vector<std::wstring> GlobalWorkbookInfo::arDefineNames_static; +std::unordered_map<int, std::vector<int>> GlobalWorkbookInfo::mapXtiTables_static; GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConverter * converter) : CodePage(code_page), xls_converter(converter) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h index c2ceff53d71..ebacd3e197d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h @@ -221,6 +221,7 @@ class GlobalWorkbookInfo static std::unordered_map<int, std::wstring> mapTableNames_static; static std::unordered_map<int, std::vector<std::wstring>> mapTableColumnNames_static; std::unordered_map<std::wstring, int> mapTableGuidsIndex; + static std::unordered_map<int, std::vector<int>> mapXtiTables_static; std::unordered_map<int, std::vector<XLS::ElementType>> pivotCacheRecordType; int currentPivotCacheRecord; diff --git a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp index ca0dabd0420..2ff7d550bf4 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.cpp @@ -807,8 +807,8 @@ void GlobalsSubstream::UpdateDefineNames() else { std::vector<std::wstring> 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/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 297b16a8ea1..6ea8b89951c 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/Readers.cpp @@ -875,7 +875,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 +1042,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; @@ -1872,6 +1888,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; diff --git a/OOXML/Binary/Document/BinReader/Readers.h b/OOXML/Binary/Document/BinReader/Readers.h index d04c875f17e..d32e5bde641 100644 --- a/OOXML/Binary/Document/BinReader/Readers.h +++ b/OOXML/Binary/Document/BinReader/Readers.h @@ -509,9 +509,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 fa5219571eb..d3a7032942f 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -356,7 +356,9 @@ extern int g_nCurFormatVersion; Tab_Item_PosTwips = 42, Tab_Item_Val = 43, SuppressLineNumbers = 44, - CnfStyle = 45 + CnfStyle = 45, + SnapToGrid = 46, + Bidi = 47 };} namespace c_oSerProp_rPrType{enum c_oSerProp_rPrType { @@ -415,7 +417,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 { @@ -486,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 { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index de701a62a39..3dfe6e90e7b 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -913,6 +913,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 +1138,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; @@ -1665,6 +1682,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) { @@ -6619,6 +6654,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) { @@ -6651,6 +6688,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); 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<OOX::File> 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<OOX::File> 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<OOX::File> &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/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 1c8ac5ae10f..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<std::wstring, _imageManager2Info>::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput : strBase64Image); + std::map<std::wstring, _imageManager2Info>::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) @@ -695,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() { @@ -732,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) @@ -1399,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(); @@ -1412,7 +1416,7 @@ namespace NSBinPptxRW { m_pWriter->ClearNoAttack(); m_lNextRelsID = 1; - m_mapImages.clear(); + m_mapRelsImages.clear(); m_mapLinks.clear(); } @@ -1614,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<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapRelsImages.find(strMediaRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1640,16 +1644,16 @@ namespace NSBinPptxRW if (type == 0) { m_pWriter->WriteString( L"<Relationship Id=\"" + strRid + - L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + strImageRelsPath + L"\"/>"); + L"\" Type=\"http://schemas.microsoft.com/office/2007/relationships/media\" Target=\"" + strMediaRelsPath + L"\"/>"); } else if (type == 1) { m_pWriter->WriteString( L"<Relationship Id=\"" + strRid + - L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio\" Target=\"" + strImageRelsPath + L"\"/>"); + L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio\" Target=\"" + strMediaRelsPath + L"\"/>"); } } - m_mapImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(strMediaRelsPath, oRelsGeneratorInfo)); return oRelsGeneratorInfo; } @@ -1668,9 +1672,9 @@ namespace NSBinPptxRW { strImageRelsPath += OOX::CPath(oImageManagerInfo.sFilepathImage).GetFilename(); - std::map<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapImages.find(strImageRelsPath); + std::map<std::wstring, _relsGeneratorInfo>::iterator pPair = m_mapRelsImages.find(strImageRelsPath); - if (m_mapImages.end() != pPair) + if (m_mapRelsImages.end() != pPair) { return pPair->second; } @@ -1756,7 +1760,7 @@ namespace NSBinPptxRW } } } - m_mapImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(strImageRelsPath, oRelsGeneratorInfo)); + m_mapRelsImages.insert(std::pair<std::wstring, _relsGeneratorInfo>(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<CSeekTableEntry> 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<std::wstring, _relsGeneratorInfo> m_mapImages; + std::map<std::wstring, _relsGeneratorInfo> m_mapRelsImages; std::map<std::wstring, unsigned int> 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/PPTXWriter.cpp b/OOXML/Binary/Presentation/PPTXWriter.cpp index 2d9fd164ffc..47d45c37b05 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; diff --git a/OOXML/Binary/Presentation/PPTXWriter.h b/OOXML/Binary/Presentation/PPTXWriter.h index 51194a45a52..b14c951cfa2 100644 --- a/OOXML/Binary/Presentation/PPTXWriter.h +++ b/OOXML/Binary/Presentation/PPTXWriter.h @@ -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..b450431349d 100644 --- a/OOXML/Binary/Presentation/imagemanager.cpp +++ b/OOXML/Binary/Presentation/imagemanager.cpp @@ -527,10 +527,12 @@ namespace NSShapeImageGen CDirectory::CopyFile(strFileName, pathSaveItem.GetPath()); ::MetaFile::IMetaFile* pMetafile = MetaFile::Create(m_pFontManager->GetApplication()); + + pMetafile->SetImageSize(lWidth, lHeight); if (pMetafile->LoadFromFile(strFileName.c_str())) { // пробуем сохранить в svg напрямую из метафайлов - std::wstring sInternalSvg = pMetafile->ConvertToSvg(); + std::wstring sInternalSvg = pMetafile->ConvertToSvg(/*lWidth, lHeight*/); if (!sInternalSvg.empty()) { diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index f7469f9bac3..fbbb4ab6e62 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 };} @@ -238,6 +238,7 @@ namespace BinXlsxRW ExternalLinksAutoRefresh = 26, TimelineCaches = 27, TimelineCache = 28, + Metadata = 29 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -586,7 +587,9 @@ namespace BinXlsxRW Formula = 4, RefRowCol = 5, ValueText = 6, - ValueCache = 7 + ValueCache = 7, + CellMetadata = 8, + ValueMetadata = 9 };} namespace c_oSerFormulaTypes{enum c_oSerFormulaTypes { @@ -662,6 +665,7 @@ namespace BinXlsxRW ChildChain = 5, NewThread = 6 };} +//------------------------------------------------------------------------------------------------------------------------------ namespace c_oSer_Timeline {enum c_oSer_Timeline { Name = 0, @@ -717,6 +721,116 @@ namespace BinXlsxRW 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, @@ -1241,12 +1355,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 { @@ -1415,7 +1531,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/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index ba79f56c674..9f28194c7ab 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -71,8 +71,10 @@ #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" namespace BinXlsxRW { @@ -2263,6 +2265,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<OOX::Spreadsheet::CMetadataFile*>(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) { @@ -3022,8 +3032,11 @@ void BinaryWorkbookTableWriter::WriteExternalReferences(const OOX::Spreadsheet:: smart_ptr<OOX::File> 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<OOX::OleObject*>(pFile.operator ->()); - sLink = pLinkFile->filename().GetPath(); + smart_ptr<OOX::OleObject> pLinkFile = pFile.smart_dynamic_cast<OOX::OleObject>(); + if (pLinkFile.IsInit()) + { + sLink = pLinkFile->filename().GetPath(); + } } } if (!sLink.empty()) @@ -3235,6 +3248,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) { @@ -3538,6 +3557,556 @@ void BinaryWorkbookTableWriter::WriteTimelineState(OOX::Spreadsheet::CTimelineSt 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()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxMemeberProp->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks) +{ + if (!pMetadataBlocks) return; + + for (size_t i = 0; i < pMetadataBlocks->m_arrItems.size(); ++i) + { + if (!pMetadataBlocks->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataBlock); + WriteMetadataBlock(pMetadataBlocks->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock) +{ + if (!pMetadataBlock) return; + + for (size_t i = 0; i < pMetadataBlock->m_arrItems.size(); ++i) + { + 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::WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord) +{ + if (!pMetadataRecord) return; + + if (pMetadataRecord->m_oT.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordType); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oT); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataRecord->m_oV.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordValue); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oV); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +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) + { + if (!pFutureMetadataBlock->m_oExtLst->m_arrExt[i]) continue; + + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties.IsInit()) + { + 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::WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pFutureMetadata) +{ + if (!pFutureMetadata) return; + + if (pFutureMetadata->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::Name); + m_oBcw.m_oStream.WriteStringW3(*pFutureMetadata->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pFutureMetadata->m_arrItems.size(); ++i) + { + if (!pFutureMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::FutureMetadataBlock); + WriteFutureMetadataBlock(pFutureMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} + void BinaryWorkbookTableWriter::WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange) { if (!pTimelineRange) return; @@ -4014,18 +4583,21 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet smart_ptr<OOX::File> pFile = oWorksheet.Find(oWorksheet.m_oPicture->m_oId->GetValue()); if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast<OOX::Image*>(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<OOX::Image> pImageFileCache = pFile.smart_dynamic_cast<OOX::Image>(); + 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()) @@ -5048,14 +5620,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); @@ -5068,6 +5666,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) { @@ -5264,7 +5874,8 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh olePic->blipFill.blip->oleFilepathBin = olePic->oleObject->m_OleObjectFile->filename().GetPath(); } - OOX::Image* pImageFileCache = NULL; + smart_ptr<OOX::Image> pImageFileCache; + std::wstring sIdImageFileCache; if ((NULL != pShapeElem) && (OOX::et_v_shapetype != pShapeElem->getType())) { @@ -5295,23 +5906,23 @@ void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksh if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast<OOX::Image*>(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast<OOX::Image>(); } } } } } - 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<OOX::File> pFile = oWorksheet.Find(sIdImageFileCache); if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - pImageFileCache = static_cast<OOX::Image*>(pFile.GetPointer()); + pImageFileCache = pFile.smart_dynamic_cast<OOX::Image>(); } } - if (pImageFileCache) + if (pImageFileCache.IsInit()) { OOX::CPath pathImage = pImageFileCache->filename(); @@ -5480,257 +6091,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) @@ -5800,6 +6410,11 @@ void BinaryWorksheetTableWriter::WriteDrawings(const OOX::Spreadsheet::CWorkshee { //преобразуем ClientData в CellAnchor OOX::Vml::CClientData* pClientData = static_cast<OOX::Vml::CClientData*>(pElemShape); + + if (pClientData->m_oObjectType.IsInit() && pClientData->m_oObjectType->GetValue() == SimpleTypes::Vml::vmlclientdataobjecttypeNote) + { + continue; + } SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); @@ -5884,6 +6499,11 @@ 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) { std::map<std::wstring, OOX::CVmlDrawing::_vml_shape>::iterator pFind = pVmlDrawing->m_mapShapes.find(pCellAnchor->m_sVmlSpId.get2()); @@ -7437,25 +8057,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) @@ -7956,11 +8588,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)); diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.h b/OOXML/Binary/Sheets/Reader/BinaryWriter.h index bead4217d97..f07dd9d740a 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.h +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.h @@ -84,6 +84,23 @@ namespace OOX 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; } } @@ -188,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); @@ -197,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); @@ -207,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); @@ -216,6 +236,7 @@ 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); @@ -224,6 +245,22 @@ namespace BinXlsxRW 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 { diff --git a/OOXML/Binary/Sheets/Reader/CSVReader.cpp b/OOXML/Binary/Sheets/Reader/CSVReader.cpp index e9f32647fce..29aba988e6d 100644 --- a/OOXML/Binary/Sheets/Reader/CSVReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CSVReader.cpp @@ -219,6 +219,8 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C smart_ptr<OOX::Spreadsheet::CWorksheet> pWorksheet(new OOX::Spreadsheet::CWorksheet(NULL)); pWorksheet->m_oSheetData.Init(); + pWorksheet->m_oSheetFormatPr.Init(); + pWorksheet->m_oSheetFormatPr->m_oBaseColWidth = 9; //----------------------------------------------------------------------------------- DWORD nFileSize = 0; @@ -311,6 +313,7 @@ _UINT32 CSVReader::Impl::Read(const std::wstring &sFileName, OOX::Spreadsheet::C INT nIndexRow = 0; INT nIndexCol = 0; OOX::Spreadsheet::CRow *pRow = new OOX::Spreadsheet::CRow(); + pRow->m_oR.Init(); pRow->m_oR->SetValue(nIndexRow + 1); diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp index 265c6ae7f89..353c032162b 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/CellFormatController.cpp @@ -42,10 +42,21 @@ #include <iomanip> #include <cctype> + const std::wstring DefaultDateFormat = L"dd.mm.yyyy"; const std::wstring DefaultPercentFormat = L"0.0%"; const std::wstring DefaultDollarFormat = L"#,##0.00$"; +std::map<std::wstring, std::uint16_t> defaultDataFormats +{ + {DefaultDateFormat, 14}, + {L"d-mmm-yy", 15}, + {L"d-mmm", 16}, + {L"mmm-yy", 17}, + {L"m/d/yy h:mm", 22}, + {L"h:mm", 20} +}; + CellFormatController::CellFormatController(OOX::Spreadsheet::CStyles *styles): m_pStyles{styles} { @@ -170,23 +181,29 @@ void CellFormatController::ProcessCellType(OOX::Spreadsheet::CCell *pCell, const void CellFormatController::createFormatStyle(const std::wstring &format) { - if (!m_pStyles->m_oNumFmts.IsInit()) + auto prepareFormat = defaultDataFormats.find(format); + if(prepareFormat == defaultDataFormats.end()) { - m_pStyles->m_oNumFmts.Init(); + 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()); } - 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/DateReader.cpp b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp index 41db554ed56..8282dc05edc 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.cpp @@ -43,7 +43,7 @@ // Определение основных форматов даты std::vector<std::wstring> DateFormats = { - L"%d.%m.%Y", L"%d.%m.%y", L"%Y-%m-%d", L"%m/%d/%Y", + L"%d.%m.%Y", L"%d.%m.%y", L"%Y-%m-%d",L"%d/%m/%Y",L"%d/%m/%y", 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", @@ -67,7 +67,10 @@ bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) if(time.tm_year > 0) { - result = getStandartDate(time); + if(time.tm_year >= 70) + result = getStandartDate(time); + else + result = getNonUnixDate(time); return true; } return false; @@ -80,8 +83,44 @@ bool DateReader::GetDigitalDate(const std::wstring &date, _INT32 &result) _INT32 DateReader::getStandartDate(tm &date) { // Преобразование даты в формат 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 = tp.time_since_epoch().count(); + #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) + excelTime = excelTime / 10000000; + #else + excelTime = excelTime / 1000000000; + #endif + excelTime += 2209161600; _INT32 tempTime = round(excelTime / 86400.0); return tempTime; -} \ No newline at end of file +} + +// Функция для определения високосного года +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; +} diff --git a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h index 7a79f827e97..0194100e05a 100644 --- a/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h +++ b/OOXML/Binary/Sheets/Reader/CellFormatController/DateReader.h @@ -51,5 +51,10 @@ class DateReader /// @param datetime структура с датой /// @return дата в формате excel _INT32 getStandartDate(tm &date); + + /// @brief получение даты в виде числа в формате excel из дат от 1900 года и до 1970 + /// @param datetime структура с датой + /// @return дата в формате excel + _INT32 getNonUnixDate(tm &date); }; diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp index 67eb2a92172..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; @@ -1134,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; @@ -7033,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) { @@ -7391,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()) { @@ -12604,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()) diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.h index d6cd9a31e27..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<PPTX::Theme> 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); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 97367b858f0..bd4047514f9 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -73,6 +73,7 @@ #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" @@ -2324,6 +2325,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<OOX::Spreadsheet::CMetadataFile> oMetadataFile(new OOX::Spreadsheet::CMetadataFile(NULL)); + oMetadataFile->m_oMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadata, oMetadataFile->m_oMetadata.GetPointer()); + + smart_ptr<OOX::File> oFile = oMetadataFile.smart_dynamic_cast<OOX::File>(); + m_oWorkbook.Add(oFile); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -3221,8 +3231,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) { @@ -3234,6 +3243,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; @@ -6288,7 +6301,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()); @@ -6307,6 +6320,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) { @@ -6365,6 +6398,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; @@ -6834,6 +6875,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; @@ -6854,6 +6900,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; @@ -7916,6 +7967,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<OOX::Spreadsheet::CMetadata*>(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<OOX::Spreadsheet::CMetadataTypes*>(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<OOX::Spreadsheet::CMetadataType*>(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<OOX::Spreadsheet::CMetadataStrings*>(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<OOX::Spreadsheet::CMdxMetadata*>(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<OOX::Spreadsheet::CMdx*>(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<OOX::Spreadsheet::CMetadataBlocks*>(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<OOX::Spreadsheet::CMetadataBlock*>(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<OOX::Spreadsheet::CMetadataRecord*>(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<OOX::Spreadsheet::CDynamicArrayProperties*>(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<OOX::Spreadsheet::CMetadataStringIndex*>(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<OOX::Spreadsheet::CMdxMemeberProp*>(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<OOX::Spreadsheet::CMdxKPI*>(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<OOX::Spreadsheet::CMdxSet*>(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<OOX::Spreadsheet::CMdxTuple*>(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<OOX::Spreadsheet::CFutureMetadata*>(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<OOX::Spreadsheet::CFutureMetadataBlock*>(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() { @@ -8026,7 +8572,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; @@ -8119,7 +8665,7 @@ 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; @@ -8127,8 +8673,8 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD BYTE saveFileType; SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType); - // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. - + // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. + if (BinXlsxRW::c_oFileTypes::CSV == fileType) { sDstPath = pOfficeDrawingConverter->GetTempPath(); @@ -8137,36 +8683,59 @@ 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); @@ -8174,7 +8743,7 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD 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 { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 3ad6d9a7a9e..d1551af149a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -219,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); @@ -228,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); @@ -236,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); @@ -245,7 +248,9 @@ 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); @@ -253,6 +258,24 @@ namespace BinXlsxRW 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 { @@ -425,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/XlsbFormat/FileTypes_SpreadsheetBin.h b/OOXML/Binary/XlsbFormat/FileTypes_SpreadsheetBin.h index e6e53f35b39..f52d79a2ec5 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", 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<SimpleTypes::COnOff > m_oAnchorLock; - nullable<SimpleTypes::CDropCap > m_oDropCap; - nullable<SimpleTypes::CTwipsMeasure > m_oH; - nullable<SimpleTypes::CHAnchor > m_oHAnchor; - nullable<SimpleTypes::CHeightRule > m_oHRule; - nullable<SimpleTypes::CTwipsMeasure > m_oHSpace; - nullable<SimpleTypes::CDecimalNumber > m_oLines; - nullable<SimpleTypes::CVAnchor > m_oVAnchor; - nullable<SimpleTypes::CTwipsMeasure > m_oVSpace; - nullable<SimpleTypes::CTwipsMeasure > m_oW; - nullable<SimpleTypes::CWrap > m_oWrap; - nullable<SimpleTypes::CSignedTwipsMeasure > m_oX; - nullable<SimpleTypes::CXAlign > m_oXAlign; - nullable<SimpleTypes::CSignedTwipsMeasure > m_oY; - nullable<SimpleTypes::CYAlign > m_oYAlign; + nullable<SimpleTypes::COnOff> m_oAnchorLock; + nullable<SimpleTypes::CDropCap> m_oDropCap; + nullable<SimpleTypes::CTwipsMeasure> m_oH; + nullable<SimpleTypes::CHAnchor> m_oHAnchor; + nullable<SimpleTypes::CHeightRule> m_oHRule; + nullable<SimpleTypes::CTwipsMeasure> m_oHSpace; + nullable<SimpleTypes::CDecimalNumber> m_oLines; + nullable<SimpleTypes::CVAnchor> m_oVAnchor; + nullable<SimpleTypes::CTwipsMeasure> m_oVSpace; + nullable<SimpleTypes::CTwipsMeasure> m_oW; + nullable<SimpleTypes::CWrap> m_oWrap; + nullable<SimpleTypes::CSignedTwipsMeasure> m_oX; + nullable<SimpleTypes::CXAlign> m_oXAlign; + nullable<SimpleTypes::CSignedTwipsMeasure> m_oY; + nullable<SimpleTypes::CYAlign> m_oYAlign; }; //-------------------------------------------------------------------------------- diff --git a/OOXML/Common/SimpleTypes_Drawing.cpp b/OOXML/Common/SimpleTypes_Drawing.cpp index f30ec34625f..64d8902a909 100644 --- a/OOXML/Common/SimpleTypes_Drawing.cpp +++ b/OOXML/Common/SimpleTypes_Drawing.cpp @@ -5324,7 +5324,7 @@ 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; diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 9373dd4aa63..24d91f3e28f 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -3291,5 +3291,129 @@ namespace SimpleTypes } 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 ba71925b992..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) @@ -1406,5 +1406,48 @@ namespace SimpleTypes 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_Word.cpp b/OOXML/Common/SimpleTypes_Word.cpp index 334169dd67c..9f8c41aba0c 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; } @@ -4333,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; 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/Document.cpp b/OOXML/DocxFormat/Document.cpp index 588a809522a..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) { } @@ -401,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<OOX::Logic::CDrawing> m_oDrawing; nullable<OOX::Vml::CBackground> 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<OOX::Logic::CBinData> 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<OOX::Vml::CBackground> 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<Document*>(this)) @@ -53,19 +55,21 @@ namespace OOX } CDocxFlat::CDocxFlat(const CPath& oFilePath) : File(dynamic_cast<Document*>(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<Document*>(this)); m_currentContainer = dynamic_cast<OOX::IFileContainer*>(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<Document*>(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<BYTE> 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<std::wstring> msoStores = storage.entries(); + + int index = 0; + for (std::list<std::wstring>::iterator it = msoStores.begin(); it != msoStores.end(); ++it) + { + POLE::Stream stream(&storage, *it); + if (stream.fail()) continue; + + smart_ptr<OOX::OleObject> pOleObjectFile = smart_ptr<OOX::OleObject>(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<OOX::File> file = pOleObjectFile.smart_dynamic_cast<OOX::File>(); + m_mapOleData[*it] = file; + } + + } + void CDocxFlat::ParsingSuppData() + { + if (false == m_oDocSuppData.IsInit()) return; + if (false == m_oDocSuppData->m_oBinData.IsInit()) return; + + std::vector<BYTE> 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<CNumbering> m_pNumbering; nullable<CSettings> m_pSettings; nullable<Logic::CBgPict> m_pBgPict; + nullable<Logic::CDocSuppData> m_oDocSuppData; + nullable<Logic::CDocSuppData> m_oDocOleData; nullable<CComments> m_pComments; nullable<CFootnotes> m_pFootnotes; @@ -96,9 +98,15 @@ namespace OOX nullable<CApp> m_pApp; nullable<CCore> m_pCore; //----------------------------------------------------------- + nullable_string m_sCompatibilityMode; + std::map<std::wstring, NSCommon::smart_ptr<OOX::File>> m_mapImages; + std::map<std::wstring, NSCommon::smart_ptr<OOX::File>> 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 ea3e04725c8..46c4db44ba3 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -47,6 +47,7 @@ #include "../../XlsxFormat/Chart/ChartSerialize.h" #include "../../XlsxFormat/Worksheets/WorksheetChildOther.h" #include "../../XlsxFormat/Timelines/Timeline.h" +#include "../../XlsxFormat/Workbook/Metadata.h" #include "../Comments.h" @@ -68,6 +69,7 @@ #include "../../XlsbFormat/Biff12_unions/TABLESLICERSEX.h" #include "../../XlsbFormat/Biff12_unions/FRTWORKBOOK.h" #include "../../XlsbFormat/Biff12_unions/FRTPIVOTCACHEDEF.h" +#include "../../XlsbFormat/Biff12_records/FRTBegin.h" namespace OOX { @@ -224,6 +226,8 @@ namespace OOX *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"http://schemas.microsoft.com/office/drawing/2008/diagram")) { int nCurDepth = oReader.GetDepth(); @@ -355,6 +359,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)) { @@ -367,6 +372,14 @@ namespace OOX } } } + else if (sName == L"dynamicArrayProperties") + { + m_oDynamicArrayProperties = oReader; + } + else if (sName == L"rvb") + { + m_oRichValueBlock = oReader; + } } } else @@ -585,11 +598,22 @@ 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(); + } sResult += L"</" + sNamespace + L"ext>"; return sResult; @@ -681,6 +705,209 @@ 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(); + } + } + 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->toBin()); + }*/ + } + 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; + } void COfficeArtExtensionList::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeFRTWORKBOOK) @@ -694,6 +921,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 ); diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.h b/OOXML/DocxFormat/Drawing/DrawingExt.h index 0ddb4dad199..44ce87b9072 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.h +++ b/OOXML/DocxFormat/Drawing/DrawingExt.h @@ -60,6 +60,8 @@ namespace OOX class CTimelineRefs; class CTimelineCacheRefs; class CTimelineStyles; + class CDynamicArrayProperties; + class CRichValueBlock; } namespace Drawing @@ -108,7 +110,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtension 20.1.2.2.14 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtension : public WritingElement { @@ -157,9 +159,12 @@ namespace OOX std::vector<OOX::Spreadsheet::CSlicerCachePivotTable*> m_oSlicerCachePivotTables; nullable<OOX::Spreadsheet::CTableSlicerCache> m_oTableSlicerCache; nullable<OOX::Spreadsheet::CSlicerCacheHideNoData> m_oSlicerCacheHideItemsWithNoData; - + std::vector<OOX::Spreadsheet::CConditionalFormatting*> m_arrConditionalFormatting; + nullable < OOX::Spreadsheet::CDynamicArrayProperties> m_oDynamicArrayProperties; + nullable < OOX::Spreadsheet::CRichValueBlock> m_oRichValueBlock; + nullable<OOX::CPresenceInfo> m_oPresenceInfo; nullable_string m_oFileKey; @@ -176,7 +181,7 @@ namespace OOX //-------------------------------------------------------------------------------- // COfficeArtExtensionList 20.1.2.2.15 (Part 1) - //-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- class COfficeArtExtensionList : public WritingElement { @@ -194,6 +199,13 @@ 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(); virtual EElementType getType() const; std::vector<OOX::Drawing::COfficeArtExtension*> 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..7bfc0f950d7 100644 --- a/OOXML/DocxFormat/HeaderFooter.cpp +++ b/OOXML/DocxFormat/HeaderFooter.cpp @@ -91,93 +91,116 @@ 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; - if ( pItem ) - { - pItem->fromXML(oReader); - m_arrItems.push_back( pItem ); - } + while (oReader.ReadNextSiblingNode(Depth)) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + WritingElement* pItem = NULL; + + 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); } } } @@ -278,10 +301,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/Logic/ParagraphProperty.cpp b/OOXML/DocxFormat/Logic/ParagraphProperty.cpp index f2782061277..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"\" "; } 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<BYTE> CBinData::GetBytes() + { + std::vector<BYTE> 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<OOX::Image> pImageFile = smart_ptr<OOX::Image>(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<OOX::File> file = pImageFile.smart_dynamic_cast<OOX::File>(); 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("<w:pict>"); + std::wstring sResult = m_oOLEObject.IsInit() ? L"<w:object>" : L"<w:pict>"; 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("</w:pict>"); + sResult += m_oOLEObject.IsInit() ? L"</w:object>" : L"</w:pict>"; return sResult; } @@ -518,9 +562,24 @@ namespace OOX //альтернатива pptx std::wstring sXml; //??? + ole наверно что то (лень ...) - sXml += _T("<root xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" 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:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"); + sXml += L"<root \ +xmlns:wpc=\"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas\" \ +xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \ +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:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" \ +xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" \ +xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" \ +xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"; sXml += m_sXml.get(); - sXml += _T("</root>"); + sXml += L"</root>"; 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("<w:object/>"); + return L"<w:object/>"; } 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<BYTE> GetBytes(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - public: nullable<std::wstring> m_sName; nullable<std::string> m_sData; 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/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<SimpleTypes::CChapterSep > m_oChapSep; - nullable<SimpleTypes::CDecimalNumber > m_oChapStyle; - nullable<SimpleTypes::CNumberFormat > m_oFmt; - nullable<SimpleTypes::CDecimalNumber > m_oStart; + nullable<SimpleTypes::CChapterSep> m_oChapSep; + nullable<SimpleTypes::CDecimalNumber> m_oChapStyle; + nullable<SimpleTypes::CNumberFormat> m_oFmt; + nullable<SimpleTypes::CDecimalNumber> 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..01aa049fc49 100644 --- a/OOXML/DocxFormat/Logic/Vml.cpp +++ b/OOXML/DocxFormat/Logic/Vml.cpp @@ -195,14 +195,10 @@ namespace OOX if (docx_flat) { smart_ptr<OOX::Image> pImageFile = smart_ptr<OOX::Image>(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); @@ -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)) 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<OOX::CDocxFlat*>(m_pMainDocument); + if (docx_flat && false == m_oId.IsInit() && m_sObjectId.IsInit()) + { + std::map<std::wstring, NSCommon::smart_ptr<OOX::File>>::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 c584a4583c1..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<OOX::File> pFileControlBin; + pFileControlBin = this->Find(OOX::RId(m_oId->GetValue())); + + smart_ptr<OOX::ActiveX_bin> pActiveX_bin = pFileControlBin.smart_dynamic_cast<OOX::ActiveX_bin>(); + + if (pActiveX_bin.IsInit()) + { + oContent.Registration(pActiveX_bin->type().OverrideType(), oDirectory, pActiveX_bin->filename().GetFilename()); + } + } + + IFileContainer::Write(oPath, oDirectory, oContent); } //--------------------------------------------------------------------------------------------------------- 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<CDocxFlat*>(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/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 1a44d490295..9a941aeeae5 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -788,6 +788,7 @@ namespace OOX et_w_bdo, // <w:bdo> et_w_binData, // <w:binData> et_w_bgPict, // <w:bgPict> + et_w_docSuppData, // <w:docSuppData> et_w_bookmarkEnd, // <w:bookmarkEnd> et_w_bookmarkStart, // <w:bookmarkStart> et_w_br, // <w:br> @@ -1514,7 +1515,28 @@ namespace OOX et_x_Timeslicer, et_x_TimelineStyles, et_x_TimelineStyle, - et_x_TimelineStyleElement + 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; @@ -1526,6 +1548,7 @@ namespace OOX virtual ~Document(); std::wstring m_sDocumentPath; + std::wstring m_sTempPath; std::map<std::wstring, NSCommon::smart_ptr<OOX::File>> m_mapContent; }; diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index bb27d86df0d..07ef977c65e 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -2074,10 +2074,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(); @@ -2200,26 +2206,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; } } @@ -2238,13 +2244,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)) @@ -2275,10 +2281,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); @@ -2291,7 +2297,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; @@ -2922,11 +2928,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; @@ -3430,11 +3436,11 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L"<w:sz w:val=\"" + std::to_wstring(nFontSize * 2) + L"\"/><w:szCs w:val=\"" + std::to_wstring(nFontSize * 2) + L"\"/>"; nullable_string sStrokeColor; - nullable_string sStrokeWeight; + nullable<SimpleTypes::CEmu> 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"); @@ -3574,18 +3580,13 @@ void CDrawingConverter::ConvertWordArtShape(PPTX::Logic::SpTreeElem* elem, XmlUt strRPr += L"</w14:textFill>"; //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"<w14:textOutline w14:w=\"" + strStrokeW + L"\">"; smart_ptr<PPTX::Logic::SolidFill> pSolid = new PPTX::Logic::SolidFill(); @@ -3903,7 +3904,6 @@ void CDrawingConverter::LoadCoordPos(XmlUtils::CXmlNode& oNode, CShapePtr pShape } } } - pShape->getBaseShape()->m_oPath.SetCoordpos((LONG)pShape->m_dXLogic, (LONG)pShape->m_dYLogic); } @@ -4122,11 +4122,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"); @@ -5375,22 +5375,16 @@ void CDrawingConverter::CheckPenShape(PPTX::Logic::SpTreeElem* oElem, XmlUtils:: } } - nullable_string sStrokeWeight; - XmlMacroReadAttributeBase(oNode, L"strokeweight", sStrokeWeight); - if (sStrokeWeight.is_init()) + nullable<SimpleTypes::CEmu> oStrokeWeight; + XmlMacroReadAttributeBase(oNode, L"strokeweight", oStrokeWeight); + if (oStrokeWeight.is_init()) { pPPTShape->m_bIsStroked = true; if (!pSpPr->ln.is_init()) pSpPr->ln = new PPTX::Logic::Ln(); - if (sStrokeWeight->length() > 0 && sStrokeWeight->at(0) == wchar_t('.')) - { - sStrokeWeight = (L"0" + *sStrokeWeight); - } - - SimpleTypes::CPoint oPoint; - int size = (int)(g_emu_koef * oPoint.FromString(*sStrokeWeight)); + int size = oStrokeWeight->ToEmu(); pSpPr->ln->w = size; pPPTShape->m_bIsStroked = true; diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h index a4f61a6edbc..1516e096604 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFile.h @@ -74,8 +74,10 @@ class CPPTXFile void SetThemesDir (std::wstring bsDir); void SetUseSystemFonts (bool useSystemFonts); - void SetIsNoBase64 (bool val); - void SetMacroEnabled (bool val); + void SetIsNoBase64 (bool val); + + void SetMacroEnabled (bool val); + bool GetMacroEnabled (); _UINT32 OpenFileToPPTY (std::wstring bsInput, std::wstring bsOutput); _UINT32 OpenDirectoryToPPTY (std::wstring bsInput, std::wstring bsOutput); diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp index ba599090a9a..091a4cb702e 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficePPTXFileRealization.cpp @@ -176,6 +176,10 @@ void CPPTXFile::SetMacroEnabled(bool val) { m_bIsMacro = val; } +bool CPPTXFile::GetMacroEnabled() +{ + return m_bIsMacro; +} _UINT32 CPPTXFile::OpenFileToPPTY(std::wstring bsInput, std::wstring bsOutput) { if (m_strTempDir.empty()) m_strTempDir = NSDirectory::GetTempPath(); @@ -261,7 +265,7 @@ _UINT32 CPPTXFile::ConvertPPTYToPPTX(std::wstring bsInput, std::wstring bsOutput BYTE* pSrcBuffer = new BYTE[lFileSize]; oFileBinary.ReadFile(pSrcBuffer, (DWORD)lFileSize); oFileBinary.CloseFile(); - + std::wstring strBsInput = bsInput; std::wstring srcFolder = NSDirectory::GetFolderPath(strBsInput); @@ -275,8 +279,8 @@ _UINT32 CPPTXFile::ConvertPPTYToPPTX(std::wstring bsInput, std::wstring bsOutput { hRes = S_FALSE; } - RELEASEARRAYOBJECTS(pSrcBuffer); + m_bIsMacro = oWriter.GetMacroEnabled(); return hRes; } diff --git a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp index 5ac86fbd345..4d3cebf7aa6 100644 --- a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp +++ b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp @@ -530,6 +530,14 @@ namespace PPTX if (olePic.is_init()) { + if (nvGraphicFramePr.IsInit()) + { + if (olePic->nvPicPr.cNvPr.id < 1) + olePic->nvPicPr.cNvPr.id = nvGraphicFramePr->cNvPr.id; + + if (olePic->nvPicPr.cNvPr.name.empty()) + olePic->nvPicPr.cNvPr.name = nvGraphicFramePr->cNvPr.name; + } olePic->toPPTY(pWriter); return; } @@ -896,7 +904,8 @@ namespace PPTX } void GraphicFrame::ChartToOlePackageInStorage(OOX::IFileContainer* pRels, const std::wstring &sTempDirectory, int nCurrentGenerateId) - { + { +// AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE if (!chartRec.IsInit()) return; if (olePic.IsInit()) return; diff --git a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp index 7354751380a..4066a8e0987 100644 --- a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp +++ b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp @@ -184,6 +184,9 @@ namespace PPTX pWriter->WriteLimit2(0, bwMode); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->m_dCxCurShape = pWriter->m_dCyCurShape = 1; + pWriter->m_bInGroup = true; + pWriter->WriteRecord2(0, xfrm); pWriter->WriteRecord1(1, Fill); pWriter->WriteRecord1(2, EffectList); diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 63eb8f616f1..c6f76fcc982 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -282,7 +282,9 @@ namespace PPTX ooxml_file = ole_file->filename().GetPath() + (bMacro ? L".docm" : L".docx"); } - + else if (checker.nFileType == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT) + {//todooo + } if (0 == nRes) { COfficeUtils oCOfficeUtils(NULL); @@ -296,6 +298,46 @@ namespace PPTX ole_file->set_filename(ooxml_file, false); } } + else if (checker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_PACKAGE_IN_OLE) + { + POLE::Storage* storageIn = new POLE::Storage(ole_file->filename().GetPath().c_str()); + if ((storageIn) && (storageIn->open(false, false))) //storage in storage + { + POLE::Stream stream(storageIn, L"Package"); + if (false == stream.fail()) + {//test package stream??? xls ole -> xlsx ole + + POLE::uint64 size = stream.size(); + unsigned char* data = new unsigned char[size]; + stream.read(data, size); + storageIn->close(); + + std::wstring package = ole_file->filename().GetPath() + L".temp"; + + NSFile::CFileBinary file; + + file.CreateFileW(package); + file.WriteFile(data, (DWORD)size); + file.CloseFile(); + + COfficeFileFormatChecker checker2; + checker2.isOfficeFile(package); + if (checker2.nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) + { + std::wstring package2 = package + checker2.GetExtensionByType(checker2.nFileType); + + file.CreateFileW(package2); + file.WriteFile(data, (DWORD)size); + file.CloseFile(); + + ole_file->set_MsPackage(true); + ole_file->set_filename(package2, false); + } + delete[]data; + } + } + delete storageIn; + } } if (ole_file.IsInit() && 0 == sProgID.find(L"asc.")) @@ -419,7 +461,7 @@ namespace PPTX delete pXlsxEmbedded; } //else if (office_checker.nFileType == AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX) - //{ + //{ todooo //} else {//unknown ms package @@ -865,8 +907,8 @@ namespace PPTX pWriter->WriteRecord2(4, oleObject); pWriter->WriteRecord1(0, nvPicPr); - pWriter->WriteRecord1(1, blipFill); pWriter->WriteRecord1(2, spPr); + pWriter->WriteRecord1(1, blipFill); pWriter->WriteRecord2(3, style); if (macro.IsInit()) @@ -896,8 +938,32 @@ namespace PPTX { if (oleObject.IsInit() && oleObject->isValid()) { + int _id = nvPicPr.cNvPr.id; + if (_id <= 0) + { + _id = pWriter->m_lObjectId; + ++pWriter->m_lObjectId; + } + else + { + if (pWriter->m_lObjectId <= (unsigned int)_id) + { + pWriter->m_lObjectId = _id + 1; + } + } + bOle = true; - pWriter->WriteString(L"<p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id=\"0\" name=\"\"/><p:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/></p:cNvGraphicFramePr><p:nvPr><p:extLst><p:ext uri=\"{D42A27DB-BD31-4B8C-83A1-F6EECF244321}\"><p14:modId xmlns:p14=\"http://schemas.microsoft.com/office/powerpoint/2010/main\" val=\"2157879785\"/></p:ext></p:extLst></p:nvPr></p:nvGraphicFramePr>"); + pWriter->WriteString(L"<p:graphicFrame><p:nvGraphicFramePr>"); + pWriter->WriteString(L"<p:cNvPr id=\"" + std::to_wstring(_id) + L"\""); + pWriter->WriteString(L" name=\"" + nvPicPr.cNvPr.name + L"\""); + pWriter->WriteString(L"/><p:cNvGraphicFramePr>"); + pWriter->WriteString(L"<a:graphicFrameLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>"); + pWriter->WriteString(L"</p:cNvGraphicFramePr>"); + pWriter->WriteString(L"<p:nvPr>"); + //pWriter->WriteString(L"<p:extLst><p:ext uri=\"{D42A27DB-BD31-4B8C-83A1-F6EECF244321}\">"); + //pWriter->WriteString(L"<p14:modId xmlns:p14=\"http://schemas.microsoft.com/office/powerpoint/2010/main\" val=\"2157879785\"/>"); + //pWriter->WriteString(L"</p:ext></p:extLst>"); + pWriter->WriteString(L"</p:nvPr></p:nvGraphicFramePr>"); if (spPr.xfrm.IsInit()) { std::wstring oldName = spPr.xfrm->node_name; diff --git a/OOXML/PPTXFormat/Logic/SmartArt.cpp b/OOXML/PPTXFormat/Logic/SmartArt.cpp index 528bd9f1ba1..ca865536900 100644 --- a/OOXML/PPTXFormat/Logic/SmartArt.cpp +++ b/OOXML/PPTXFormat/Logic/SmartArt.cpp @@ -650,7 +650,6 @@ namespace PPTX pWriter->StartRecord(/*c_oserct_chartspaceTHEMEOVERRIDE = */15); pThemeOverride->toPPTY(pWriter); pWriter->EndRecord(); - break; } else if (OOX::FileTypes::ChartStyle == container[i]->type()) { diff --git a/OOXML/PPTXFormat/Logic/SpTree.cpp b/OOXML/PPTXFormat/Logic/SpTree.cpp index 6c4078b8041..16178058be9 100644 --- a/OOXML/PPTXFormat/Logic/SpTree.cpp +++ b/OOXML/PPTXFormat/Logic/SpTree.cpp @@ -400,8 +400,25 @@ namespace PPTX pWriter->WriteRecord1(0, nvGrpSpPr); pWriter->WriteRecord1(1, grpSpPr); - pWriter->WriteRecordArray(2, 0, SpTreeElems); +//--------------------------------------------------------------------------------------- + //pWriter->WriteRecordArray(2, 0, SpTreeElems); + pWriter->StartRecord(2); + + _UINT32 len = (_UINT32)SpTreeElems.size(); + pWriter->WriteULONG(len); + + double oldCxCurShape = pWriter->m_dCxCurShape; + double oldCyCurShape = pWriter->m_dCyCurShape; + for (_UINT32 i = 0; i < len; ++i) + { + pWriter->WriteRecord1(0, SpTreeElems[i]); + + pWriter->m_dCxCurShape = oldCxCurShape; + pWriter->m_dCyCurShape = oldCyCurShape; + } + pWriter->EndRecord(); +//--------------------------------------------------------------------------------------- pWriter->EndRecord(); } void SpTree::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) diff --git a/OOXML/PPTXFormat/Logic/Timing/CTn.cpp b/OOXML/PPTXFormat/Logic/Timing/CTn.cpp index b71c4abf383..ec49fdc9aa6 100644 --- a/OOXML/PPTXFormat/Logic/Timing/CTn.cpp +++ b/OOXML/PPTXFormat/Logic/Timing/CTn.cpp @@ -138,6 +138,7 @@ namespace PPTX pWriter->WriteAttribute(L"grpId", grpId); pWriter->WriteAttribute(L"afterEffect", afterEffect); pWriter->WriteAttribute(L"nodeType", nodeType); + pWriter->WriteAttribute(L"nodePh", nodePh); pWriter->EndAttributes(); if (stCondLst.IsInit()) diff --git a/OOXML/PPTXFormat/Logic/Xfrm.cpp b/OOXML/PPTXFormat/Logic/Xfrm.cpp index 7370e76518c..c45f861ad6d 100644 --- a/OOXML/PPTXFormat/Logic/Xfrm.cpp +++ b/OOXML/PPTXFormat/Logic/Xfrm.cpp @@ -291,6 +291,16 @@ namespace PPTX } void Xfrm::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { + if (chExtX.IsInit() && extX.IsInit()) + pWriter->m_dCxCurShape = pWriter->m_dCyCurShape * (double)*extX / (double)*chExtX; + else if (extX.IsInit()) + pWriter->m_dCxCurShape = (pWriter->m_bInGroup ? pWriter->m_dCxCurShape : 1) * *extX; + + if (chExtY.IsInit() && extY.IsInit()) + pWriter->m_dCyCurShape = pWriter->m_dCyCurShape * (double)*extY / (double)*chExtY; + else if (extY.IsInit()) + pWriter->m_dCyCurShape = (pWriter->m_bInGroup ? pWriter->m_dCyCurShape : 1) * *extY; + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); pWriter->WriteInt2(0, offX); pWriter->WriteInt2(1, offY); diff --git a/OOXML/PPTXFormat/Presentation.cpp b/OOXML/PPTXFormat/Presentation.cpp index d7eb9890b72..46ba195f6b2 100644 --- a/OOXML/PPTXFormat/Presentation.cpp +++ b/OOXML/PPTXFormat/Presentation.cpp @@ -371,8 +371,9 @@ namespace PPTX } } } - pReader->Seek(_end_pos); + + m_bMacroEnabled = m_pVbaProject.IsInit(); } void Presentation::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const diff --git a/OOXML/PPTXFormat/Slide.cpp b/OOXML/PPTXFormat/Slide.cpp index 1c7723b0f24..0765cc60410 100644 --- a/OOXML/PPTXFormat/Slide.cpp +++ b/OOXML/PPTXFormat/Slide.cpp @@ -200,6 +200,7 @@ namespace PPTX pWriter->WriteAttribute(L"xmlns:p", PPTX::g_Namespaces.p.m_strLink); pWriter->WriteAttribute(L"xmlns:m", PPTX::g_Namespaces.m.m_strLink); pWriter->WriteAttribute(L"xmlns:w", PPTX::g_Namespaces.w.m_strLink); + pWriter->WriteAttribute(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006"); pWriter->WriteAttribute(L"showMasterPhAnim", showMasterPhAnim); pWriter->WriteAttribute(L"showMasterSp", showMasterSp); diff --git a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro index 4ce6ae9f766..e5e719c5109 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro +++ b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro @@ -183,7 +183,9 @@ SOURCES += \ ../../../XlsxFormat/Drawing/Pos.cpp \ ../../../XlsxFormat/ExternalLinks/ExternalLinkPath.cpp \ ../../../XlsxFormat/ExternalLinks/ExternalLinks.cpp \ - ../../../XlsxFormat/Ole/OleObjects.cpp + ../../../XlsxFormat/Workbook/Metadata.cpp \ + ../../../XlsxFormat/RichData/RdRichValue.cpp \ + ../../../XlsxFormat/Ole/OleObjects.cpp } @@ -375,4 +377,6 @@ HEADERS += \ ../../../XlsxFormat/Slicer/SlicerCacheExt.h \ ../../../XlsxFormat/Slicer/Slicer.h \ ../../../XlsxFormat/NamedSheetViews/NamedSheetViews.h \ - docx_format.h + ../../../XlsxFormat/Workbook/Metadata.h \ + ../../../XlsxFormat/RichData/RdRichValue.h \ + docx_format.h diff --git a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp index 0249679a97a..a661caff6ab 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp @@ -95,3 +95,5 @@ #include "../../../XlsxFormat/SharedStrings/XlsxRun.cpp" #include "../../../XlsxFormat/SharedStrings/SharedStrings.cpp" #include "../../../XlsxFormat/Timelines/Timeline.cpp" +#include "../../../XlsxFormat/Workbook/Metadata.cpp" +#include "../../../XlsxFormat/RichData/RdRichValue.cpp" diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj index 71e929716b2..b016c3bc601 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj @@ -82,7 +82,6 @@ <ClInclude Include="..\..\..\Binary\Document\BinWriter\BinEquationWriter.h" /> <ClInclude Include="..\..\..\Binary\Document\BinWriter\BinReaderWriterDefines.h" /> <ClInclude Include="..\..\..\Binary\Document\BinWriter\BinWriters.h" /> - <ClInclude Include="..\..\..\Binary\Document\DocWrapper\ChartWriter.h" /> <ClInclude Include="..\..\..\Binary\Document\DocWrapper\DocxSerializer.h" /> <ClInclude Include="..\..\..\Binary\Document\DocWrapper\FontProcessor.h" /> <ClInclude Include="..\..\..\Binary\Document\DocWrapper\XlsxSerializer.h" /> diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters index 1ac5444aa80..eb22134e169 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters @@ -161,9 +161,6 @@ </ClCompile> </ItemGroup> <ItemGroup> - <ClInclude Include="..\..\..\Binary\Document\DocWrapper\ChartWriter.h"> - <Filter>Document</Filter> - </ClInclude> <ClInclude Include="..\..\..\Binary\Document\DocWrapper\DocxSerializer.h"> <Filter>Document</Filter> </ClInclude> diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj index d1bea1396ca..203228103c7 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -354,6 +354,7 @@ <ClInclude Include="..\..\..\XlsxFormat\Pivot\PivotCacheDefinitionExt.h" /> <ClInclude Include="..\..\..\XlsxFormat\Pivot\PivotCacheRecords.h" /> <ClInclude Include="..\..\..\XlsxFormat\Pivot\PivotTable.h" /> + <ClInclude Include="..\..\..\XlsxFormat\RichData\RdRichValue.h" /> <ClInclude Include="..\..\..\XlsxFormat\SharedStrings\PhoneticPr.h" /> <ClInclude Include="..\..\..\XlsxFormat\SharedStrings\Run.h" /> <ClInclude Include="..\..\..\XlsxFormat\SharedStrings\SharedStrings.h" /> @@ -383,6 +384,7 @@ <ClInclude Include="..\..\..\XlsxFormat\Workbook\CalcPr.h" /> <ClInclude Include="..\..\..\XlsxFormat\Workbook\DefinedNames.h" /> <ClInclude Include="..\..\..\XlsxFormat\Workbook\ExternalReferences.h" /> + <ClInclude Include="..\..\..\XlsxFormat\Workbook\Metadata.h" /> <ClInclude Include="..\..\..\XlsxFormat\Workbook\Sheets.h" /> <ClInclude Include="..\..\..\XlsxFormat\Workbook\Workbook.h" /> <ClInclude Include="..\..\..\XlsxFormat\Workbook\WorkbookPr.h" /> @@ -513,6 +515,7 @@ <ClCompile Include="..\..\..\XlsxFormat\Ole\OleObjects.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Pivot\PivotCacheDefinitionExt.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Pivot\Pivots.cpp" /> + <ClCompile Include="..\..\..\XlsxFormat\RichData\RdRichValue.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\SharedStrings\PhoneticPr.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\SharedStrings\XlsxRun.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\SharedStrings\SharedStrings.cpp" /> @@ -540,6 +543,7 @@ <ClCompile Include="..\..\..\XlsxFormat\Workbook\CalcPr.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Workbook\DefinedNames.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Workbook\ExternalReferences.cpp" /> + <ClCompile Include="..\..\..\XlsxFormat\Workbook\Metadata.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Workbook\Sheets.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Workbook\Workbook.cpp" /> <ClCompile Include="..\..\..\XlsxFormat\Workbook\WorkbookPr.cpp" /> diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 92b050244f7..0320b64eca4 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -85,6 +85,9 @@ <Filter Include="XlsxFormat\Timelines"> <UniqueIdentifier>{34deda6e-7347-49f2-be67-d088cdd469db}</UniqueIdentifier> </Filter> + <Filter Include="XlsxFormat\RichData"> + <UniqueIdentifier>{db25162b-705e-4c13-b6c5-f7c018c6f39a}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\..\Base\Base.h"> @@ -538,6 +541,12 @@ <ClInclude Include="..\..\..\XlsxFormat\Timelines\Timeline.h"> <Filter>XlsxFormat\Timelines</Filter> </ClInclude> + <ClInclude Include="..\..\..\XlsxFormat\RichData\RdRichValue.h"> + <Filter>XlsxFormat\RichData</Filter> + </ClInclude> + <ClInclude Include="..\..\..\XlsxFormat\Workbook\Metadata.h"> + <Filter>XlsxFormat\Workbook</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\Base\codecvt.cpp"> @@ -948,5 +957,11 @@ <ClCompile Include="..\..\..\XlsxFormat\Timelines\Timeline.cpp"> <Filter>XlsxFormat\Timelines</Filter> </ClCompile> + <ClCompile Include="..\..\..\XlsxFormat\RichData\RdRichValue.cpp"> + <Filter>XlsxFormat\RichData</Filter> + </ClCompile> + <ClCompile Include="..\..\..\XlsxFormat\Workbook\Metadata.cpp"> + <Filter>XlsxFormat\Workbook</Filter> + </ClCompile> </ItemGroup> </Project> \ No newline at end of file diff --git a/OOXML/SystemUtility/SystemUtility.cpp b/OOXML/SystemUtility/SystemUtility.cpp index 03280da835c..ac6d93af756 100644 --- a/OOXML/SystemUtility/SystemUtility.cpp +++ b/OOXML/SystemUtility/SystemUtility.cpp @@ -242,8 +242,8 @@ namespace OOX } std::wstring CPath::GetExtention(bool bIsPoint) const { - int nFind = (int)m_strFilename.rfind('.'); - if (-1 == nFind) + size_t nFind = m_strFilename.rfind('.'); + if (std::wstring::npos == nFind) return L""; if (!bIsPoint) @@ -251,6 +251,19 @@ namespace OOX return m_strFilename.substr(nFind); } + void CPath::SetExtention(const std::wstring& ext) + { + size_t nFind = m_strFilename.rfind('.'); + if (std::wstring::npos == nFind) + { + m_strFilename += L"." + ext; + } + else + { + m_strFilename = m_strFilename.substr(0, nFind + 1) + ext; + } + + } std::wstring CPath::GetDirectory(bool bIsSlash) const { int nPos = (int)m_strFilename.rfind(FILE_SEPARATOR_CHAR); diff --git a/OOXML/SystemUtility/SystemUtility.h b/OOXML/SystemUtility/SystemUtility.h index 279e113a4c0..ad13efc14aa 100644 --- a/OOXML/SystemUtility/SystemUtility.h +++ b/OOXML/SystemUtility/SystemUtility.h @@ -42,7 +42,6 @@ namespace OOX //флаг введен, чтобы отличать относительные и абсолютные пути в rels bool m_bIsRoot; - public: CPath(); CPath(const std::wstring& sName, bool bIsNorm = true); CPath(const char*& sName, bool bIsNorm = true); @@ -70,6 +69,8 @@ namespace OOX std::wstring GetPath() const; std::wstring GetFilename() const; + void SetExtention(const std::wstring & ext); + void Normalize(); void SetName(std::wstring sName, bool bNormalize); diff --git a/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp b/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp index 0d3f298110e..9999b924d19 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginComment.cpp @@ -59,10 +59,18 @@ namespace XLSB void BeginComment::writeFields(XLS::CFRecord& record) { + if(!guid.empty()) + { _GUID_ guid_; STR::bstr2guid(guid, guid_); record << iauthor << rfx << guid_; + } + else + { + record << iauthor << rfx; + record.reserveNunBytes(16); + } } } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp b/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp index d3382ca305a..02040d7c562 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginExtConnection.cpp @@ -107,6 +107,7 @@ namespace XLSB SETBIT(flags, 16, fLoadSourceDataFile) SETBIT(flags, 17, fLoadSourceConnectionFile) SETBIT(flags, 18, fLoadConnectionDesc) + SETBIT(flags, 19, 1) SETBIT(flags, 20, fLoadSSOApplicationID) record << wInterval << flags; diff --git a/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp b/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp index 25e7d9dc887..632c2505499 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp +++ b/OOXML/XlsbFormat/Biff12_records/BeginSupBook.cpp @@ -97,7 +97,7 @@ namespace XLSB RelID relID; XLNullableWideString str; relID.value = string1; - str = string2; + str.setSize(0xFFFFFFFF); record << relID << str; break; } diff --git a/OOXML/XlsbFormat/Biff12_records/CFVO.cpp b/OOXML/XlsbFormat/Biff12_records/CFVO.cpp index a21b557c2b5..8afa7c88624 100644 --- a/OOXML/XlsbFormat/Biff12_records/CFVO.cpp +++ b/OOXML/XlsbFormat/Biff12_records/CFVO.cpp @@ -62,8 +62,16 @@ namespace XLSB { record << iType << numParam << fSaveGTE << fGTE << cbFmla; - if (cbFmla) - record << formula; + if (cbFmla) + { + auto rdPtr = record.getRdPtr(); + record << formula; + auto size = record.getRdPtr() - rdPtr; + record.RollRdPtrBack(size + 4); + _UINT32 cce = formula.cce; + record << cce; + record.skipNunBytes(size); + } } } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_records/SupTabs.h b/OOXML/XlsbFormat/Biff12_records/SupTabs.h index a8691072efa..e9f0e02d526 100644 --- a/OOXML/XlsbFormat/Biff12_records/SupTabs.h +++ b/OOXML/XlsbFormat/Biff12_records/SupTabs.h @@ -53,8 +53,7 @@ namespace XLSB _UINT32 cTab; std::vector<XLWideString> sheetNames; - }; - + typedef boost::shared_ptr<SupTabs> SupTabsPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp b/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp index f2fed5fd5e2..a41231ccd4d 100644 --- a/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp +++ b/OOXML/XlsbFormat/Biff12_structures/ECTxtWizData.cpp @@ -88,6 +88,7 @@ namespace XLSB SETBIT(flags, 16, fSemiColon) SETBIT(flags, 17, fConsecutive) SETBITS(flags, 18, 19, fTextDelim) + SETBIT(flags, 20, 1) SETBIT(flags, 21, fPromptForFile) SETBIT(flags, 22, fCustom) diff --git a/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp b/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp index 73c6196d2e7..f01dd92287e 100644 --- a/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp +++ b/OOXML/XlsbFormat/Biff12_structures/PCDIDateTime_bs.cpp @@ -87,15 +87,54 @@ namespace XLSB void PCDIDateTime::fromString(const std::wstring& str) { std::string ts(str.begin(), str.end()); - boost::posix_time::ptime pt(boost::posix_time::time_from_string(ts)); - tm pt_tm = boost::posix_time::to_tm(pt); - - yr = pt_tm.tm_year; - mon = pt_tm.tm_mon; - dom = pt_tm.tm_mday; - hr = pt_tm.tm_hour; - min = pt_tm.tm_min; - sec = pt_tm.tm_sec; + boost::posix_time::ptime pt; + bool timeValid = false; + try + { + pt = (boost::posix_time::time_from_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + if(!timeValid) + { + try + { + pt = (boost::posix_time::from_iso_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + } + if(!timeValid) + { + try + { + pt = (boost::posix_time::from_iso_extended_string(ts)); + timeValid = true; + } + catch(std::exception) + {} + } + if(timeValid) + { + tm pt_tm = boost::posix_time::to_tm(pt); + yr = pt_tm.tm_year; + mon = pt_tm.tm_mon; + dom = pt_tm.tm_mday; + hr = pt_tm.tm_hour; + min = pt_tm.tm_min; + sec = pt_tm.tm_sec; + } + else + { + yr = 0; + mon = 0; + dom = 0; + hr = 0; + min = 0; + sec = 0; + } } diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h index a439c497840..2d6d18f3d06 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEM.h @@ -56,6 +56,6 @@ namespace XLSB ExternalReferenceType sbt; }; - + typedef boost::shared_ptr<DDEOLEITEM> DDEOLEITEMPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h index 4e0dad286c0..6e82c2e139d 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUE.h @@ -51,6 +51,6 @@ namespace XLSB XLS::BaseObjectPtr m_source; }; - + typedef boost::shared_ptr<DDEOLEITEMVALUE> DDEOLEITEMVALUEPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h index b470e5b9da0..3a507facd3c 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLEITEMVALUES.h @@ -55,6 +55,6 @@ namespace XLSB bool m_bBrtSupNameValueEnd; }; - + typedef boost::shared_ptr<DDEOLEITEMVALUES> DDEOLEITEMVALUESPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h b/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h index d58ea61a01f..1d21a1c8c4d 100644 --- a/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h +++ b/OOXML/XlsbFormat/Biff12_unions/DDEOLELINK.h @@ -55,6 +55,7 @@ namespace XLSB ExternalReferenceType sbt; }; + typedef boost::shared_ptr<DDEOLELINK> DDEOLELINKPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h b/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h index 90c3546f025..a301bb27aed 100644 --- a/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h +++ b/OOXML/XlsbFormat/Biff12_unions/EXTERNALBOOK.h @@ -57,6 +57,7 @@ namespace XLSB ExternalReferenceType sbt; }; + typedef boost::shared_ptr<EXTERNALBOOK> EXTERNALBOOKPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h b/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h index d97dd76eeac..0498a8ac6a5 100644 --- a/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h +++ b/OOXML/XlsbFormat/Biff12_unions/EXTERNALLINK.h @@ -56,8 +56,8 @@ namespace XLSB XLS::BaseObjectPtr m_DDEOLELINK; std::vector<XLS::BaseObjectPtr> m_arFRT; bool m_bBrtEndSupBook; - }; + typedef boost::shared_ptr<EXTERNALLINK> EXTERNALLINKPtr; } // namespace XLSB diff --git a/OOXML/XlsbFormat/PivotTableStream.cpp b/OOXML/XlsbFormat/PivotTableStream.cpp index 59a7b082e6c..98b716a6cee 100644 --- a/OOXML/XlsbFormat/PivotTableStream.cpp +++ b/OOXML/XlsbFormat/PivotTableStream.cpp @@ -74,7 +74,7 @@ BaseObjectPtr PivotTableStream::clone() } const bool PivotTableStream::loadContent(BinProcessor& proc) -{ +{ while (true) { CFRecordType::TypeId type = proc.getNextRecordType(); @@ -331,6 +331,7 @@ const bool PivotTableStream::saveContent(XLS::BinProcessor & proc) if (m_FRTSXVIEW != nullptr) proc.mandatory(*m_FRTSXVIEW); + proc.mandatory<EndSXView>(); return true; } diff --git a/OOXML/XlsbFormat/SlicerCachesStream.cpp b/OOXML/XlsbFormat/SlicerCachesStream.cpp index 82415305ffb..e2ae61c71c4 100644 --- a/OOXML/XlsbFormat/SlicerCachesStream.cpp +++ b/OOXML/XlsbFormat/SlicerCachesStream.cpp @@ -76,7 +76,7 @@ const bool SlicerCachesStream::loadContent(BinProcessor& proc) proc.SkipRecord(); }break; } - } + } return true; } diff --git a/OOXML/XlsbFormat/WorkBookStream.cpp b/OOXML/XlsbFormat/WorkBookStream.cpp index f0ef8874406..c9f2c30062e 100644 --- a/OOXML/XlsbFormat/WorkBookStream.cpp +++ b/OOXML/XlsbFormat/WorkBookStream.cpp @@ -492,6 +492,7 @@ void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_) { XTI* xti = dynamic_cast<XTI*>(extern_sheet->rgXTI[i].get()); if (!xti) continue; + if(externals->m_arSUP.size() <= xti->iSupBook) continue; SUP* index_book = dynamic_cast<SUP*>(externals->m_arSUP[xti->iSupBook].get()); if (!index_book) continue; @@ -521,7 +522,7 @@ void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_) else if (xti->itabFirst < global_info_->sheets_info.size()) { strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L""); - if (xti->itabFirst != xti->itabLast) + if (xti->itabFirst != xti->itabLast && xti->itabLast < global_info_->sheets_info.size()) { strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L""); } diff --git a/OOXML/XlsbFormat/WorkSheetStream.cpp b/OOXML/XlsbFormat/WorkSheetStream.cpp index b9d929134de..44a2bf4ed2e 100644 --- a/OOXML/XlsbFormat/WorkSheetStream.cpp +++ b/OOXML/XlsbFormat/WorkSheetStream.cpp @@ -182,13 +182,13 @@ const bool WorkSheetStream::loadContent(BinProcessor& proc) }*/ m_SheetaDataPosition = proc.GetRecordPosition(); while (proc.getNextRecordType() != rt_EndSheetData) - proc.SkipRecord(); + proc.SkipRecord(false); }break; case rt_BeginUserShViews: { while (proc.getNextRecordType() != rt_EndUserShViews) - proc.SkipRecord(); + proc.SkipRecord(false); }break; case rt_WsFmtInfo: @@ -453,103 +453,103 @@ const bool WorkSheetStream::saveContent(XLS::BinProcessor & proc) { proc.mandatory<BeginSheet>(); + if (m_BrtWsProp != nullptr) + proc.mandatory(*m_BrtWsProp); + + if (m_BrtWsDim != nullptr) + proc.mandatory(*m_BrtWsDim); + + if (m_WSVIEWS2 != nullptr) + proc.mandatory(*m_WSVIEWS2); + + if (m_BrtWsFmtInfo != nullptr) + proc.mandatory(*m_BrtWsFmtInfo); + for (auto &item : m_arCOLINFOS) { proc.mandatory(*item); } - if (m_BrtWsDim != nullptr) - proc.mandatory(*m_BrtWsDim); - - if (m_BrtDrawing != nullptr) - proc.mandatory(*m_BrtDrawing); - - if (m_BrtLegacyDrawing != nullptr) - proc.mandatory(*m_BrtLegacyDrawing); - - if (m_BrtLegacyDrawingHF != nullptr) - proc.mandatory(*m_BrtLegacyDrawingHF); + if (m_CELLTABLE != nullptr) + proc.mandatory(*m_CELLTABLE); - if (m_HLINKS != nullptr) - proc.mandatory(*m_HLINKS); + if (m_BrtSheetProtectionIso != nullptr) + proc.mandatory(*m_BrtSheetProtectionIso); - if (m_MERGECELLS != nullptr) - proc.mandatory(*m_MERGECELLS); + if (m_BrtSheetProtection != nullptr) + proc.mandatory(*m_BrtSheetProtection); - if (m_CELLTABLE != nullptr) - proc.mandatory(*m_CELLTABLE); + for (auto &item : m_arBrtRangeProtectionIso) + { + proc.mandatory(*item); + } - if (m_BrtWsFmtInfo != nullptr) - proc.mandatory(*m_BrtWsFmtInfo); + for (auto &item : m_arBrtRangeProtection) + { + proc.mandatory(*item); + } - if (m_WSVIEWS2 != nullptr) - proc.mandatory(*m_WSVIEWS2); + if (m_AUTOFILTER != nullptr) + proc.mandatory(*m_AUTOFILTER); - if (m_BrtMargins != nullptr) - proc.mandatory(*m_BrtMargins); + if (m_SORTSTATE != nullptr) + proc.mandatory(*m_SORTSTATE); - if (m_BrtPageSetup != nullptr) - proc.mandatory(*m_BrtPageSetup); + if (m_DCON != nullptr) + proc.mandatory(*m_DCON); - if (m_BrtPrintOptions != nullptr) - proc.mandatory(*m_BrtPrintOptions); + if (m_MERGECELLS != nullptr) + proc.mandatory(*m_MERGECELLS); - if (m_HEADERFOOTER != nullptr) - proc.mandatory(*m_HEADERFOOTER); - - if (m_BrtSheetProtectionIso != nullptr) - proc.mandatory(*m_BrtSheetProtectionIso); + for (auto &item : m_arCONDITIONALFORMATTING) + { + proc.mandatory(*item); + } - if (m_BrtSheetProtection != nullptr) - proc.mandatory(*m_BrtSheetProtection); + if (m_DVALS != nullptr) + proc.mandatory(*m_DVALS); - if (m_LISTPARTS != nullptr) - proc.mandatory(*m_LISTPARTS); + if (m_HLINKS != nullptr) + proc.mandatory(*m_HLINKS); - if (m_AUTOFILTER != nullptr) - proc.mandatory(*m_AUTOFILTER); + if (m_BrtPrintOptions != nullptr) + proc.mandatory(*m_BrtPrintOptions); - if (m_SORTSTATE != nullptr) - proc.mandatory(*m_SORTSTATE); + if (m_BrtMargins != nullptr) + proc.mandatory(*m_BrtMargins); - for (auto &item : m_arCONDITIONALFORMATTING) - { - proc.mandatory(*item); - } + if (m_BrtPageSetup != nullptr) + proc.mandatory(*m_BrtPageSetup); - if (m_DVALS != nullptr) - proc.mandatory(*m_DVALS); + if (m_HEADERFOOTER != nullptr) + proc.mandatory(*m_HEADERFOOTER); - if (m_OLEOBJECTS != nullptr) - proc.mandatory(*m_OLEOBJECTS); + if (m_RWBRK != nullptr) + proc.mandatory(*m_RWBRK); - if (m_ACTIVEXCONTROLS != nullptr) - proc.mandatory(*m_ACTIVEXCONTROLS); + if (m_COLBRK != nullptr) + proc.mandatory(*m_COLBRK); - if (m_BrtWsProp != nullptr) - proc.mandatory(*m_BrtWsProp); + if (m_BrtDrawing != nullptr) + proc.mandatory(*m_BrtDrawing); - if (m_BrtBkHim != nullptr) - proc.mandatory(*m_BrtBkHim); + if (m_BrtLegacyDrawing != nullptr) + proc.mandatory(*m_BrtLegacyDrawing); - if (m_RWBRK != nullptr) - proc.mandatory(*m_RWBRK); + if (m_BrtLegacyDrawingHF != nullptr) + proc.mandatory(*m_BrtLegacyDrawingHF); - if (m_COLBRK != nullptr) - proc.mandatory(*m_COLBRK); + if (m_BrtBkHim != nullptr) + proc.mandatory(*m_BrtBkHim); - for (auto &item : m_arBrtRangeProtectionIso) - { - proc.mandatory(*item); - } + if (m_OLEOBJECTS != nullptr) + proc.mandatory(*m_OLEOBJECTS); - for (auto &item : m_arBrtRangeProtection) - { - proc.mandatory(*item); - } + if (m_ACTIVEXCONTROLS != nullptr) + proc.mandatory(*m_ACTIVEXCONTROLS); - if (m_DCON != nullptr) - proc.mandatory(*m_DCON); + if (m_LISTPARTS != nullptr) + proc.mandatory(*m_LISTPARTS); if (m_FRTWORKSHEET != nullptr) proc.mandatory(*m_FRTWORKSHEET); diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 32a2ae4c924..81a5d08fda4 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -30,6 +30,8 @@ * */ #include "Xlsb.h" +#include "../DocxFormat/App.h" +#include "../DocxFormat/Core.h" #include "../XlsxFormat/Workbook/Workbook.h" #include "../XlsxFormat/SharedStrings/SharedStrings.h" @@ -60,12 +62,12 @@ using namespace XLS; OOX::Spreadsheet::CXlsb::~CXlsb() { -} +} void OOX::Spreadsheet::CXlsb::init() { workbook_code_page = XLS::WorkbookStreamObject::DefaultCodePage; xls_global_info = boost::shared_ptr<XLS::GlobalWorkbookInfo>(new XLS::GlobalWorkbookInfo(workbook_code_page, nullptr)); - xls_global_info->Version = 0x0800; + xls_global_info->Version = 0x0800; m_binaryReader = boost::shared_ptr<NSBinPptxRW::CBinaryFileReader>(new NSBinPptxRW::CBinaryFileReader); m_binaryWriter = boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter>(new NSBinPptxRW::CXlsbBinaryWriter); m_bWriteToXlsx = false; @@ -93,7 +95,22 @@ bool OOX::Spreadsheet::CXlsb::ReadBin(const CPath& oFilePath, XLS::BaseObject* o return true; } +bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oDirPath, OOX::CContentTypes& oContentTypes) +{ + if (NULL == m_pWorkbook) + return false; + m_bWriteToXlsb = true; + if(!m_oContentTypes.m_mapDefaults.empty() && !m_oContentTypes.m_mapOverrides.empty()) + { + oContentTypes.Merge(&m_oContentTypes); + } + + IFileContainer::Write(oDirPath / L"", OOX::CPath(_T("")), oContentTypes); + + oContentTypes.Write(oDirPath); + return true; +} bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* objStream) { if (m_binaryWriter->CreateFileW(oFilePath.GetPath()) == false) @@ -102,12 +119,29 @@ bool OOX::Spreadsheet::CXlsb::WriteBin(const CPath& oFilePath, XLS::BaseObject* XLS::StreamCacheWriterPtr writer(new XLS::BinaryStreamCacheWriter(m_binaryWriter, xls_global_info)); XLS::BinWriterProcessor proc(writer, objStream); proc.mandatory(*objStream); - m_binaryWriter->WriteFile(m_binaryWriter->GetBuffer(), (static_cast<NSBinPptxRW::CBinaryFileWriter*>(m_binaryWriter.get()))->GetPosition()); + + m_binaryWriter->WriteFile(m_binaryWriter->GetBuffer(), (static_cast<NSBinPptxRW::CBinaryFileWriter*>(m_binaryWriter.get()))->GetPosition()); m_binaryWriter->CloseFile(); return true; } +void OOX::Spreadsheet::CXlsb::WriteSheetData() +{ + for(auto &worksheet : m_arWorksheets) + { + + //для оптимизации по памяти сразу записываем в файл все листы + if(m_bWriteToXlsb) + { + WriteSheet(worksheet); + }// + + //cell_table_temlate.reset(); + //reader.reset(); + } +} + XLS::GlobalWorkbookInfo* OOX::Spreadsheet::CXlsb::GetGlobalinfo() { return xls_global_info.get(); @@ -168,7 +202,7 @@ void OOX::Spreadsheet::CXlsb::ReadSheetData() if(dataFindPair != m_mapSheetNameSheetData.end()) dataPosition = dataFindPair->second; - else + else continue; NSFile::CFileBinary oFile; @@ -234,11 +268,9 @@ void OOX::Spreadsheet::CXlsb::WriteSheet(CWorksheet* worksheet) } void OOX::Spreadsheet::CXlsb::PrepareTableFormula() { - for(auto &worksheet : m_arWorksheets) - { - auto lambdaFormula = [&](std::wstring& formula) { + auto lambdaFormula = [&](std::wstring& formula) { auto str = STR::guidFromStr(formula); - if(!str.empty()) + while(!str.empty()) { auto guidTableIndex = this->xls_global_info->mapTableGuidsIndex.find(str); if (guidTableIndex != this->xls_global_info->mapTableGuidsIndex.end()) @@ -250,9 +282,11 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() formula.replace(formula.find(str), str.size(), tableName); } } + str = STR::guidFromStr(formula); } }; - + for(auto &worksheet : m_arWorksheets) + { if(worksheet->m_oTableParts.IsInit()) { for(size_t i = 0, length = worksheet->m_oTableParts->m_arrItems.size(); i < length; ++i) @@ -273,10 +307,10 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() for(size_t i = 0, length = oTableColumns->m_arrItems.size(); i < length; ++i) { - auto& oTableColumn = oTableColumns->m_arrItems[i]; + auto& oTableColumn = oTableColumns->m_arrItems[i]; if(oTableColumn->m_oCalculatedColumnFormula.IsInit()) - { + { lambdaFormula(oTableColumn->m_oCalculatedColumnFormula.get()); } if(oTableColumn->m_oTotalsRowFormula.IsInit()) @@ -311,6 +345,76 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() }*/ } } + if(m_pWorkbook && m_pWorkbook->m_oDefinedNames.IsInit()) + { + for(auto defName:m_pWorkbook->m_oDefinedNames->m_arrItems) + { + if(defName->m_oRef.IsInit()) + { + lambdaFormula(defName->m_oRef.get()); + } + } + } +} + +void OOX::Spreadsheet::CXlsb::LinkTables() +{ + { + bool tablesExist = false; + for(auto worksheet:m_arWorksheets) + { + if(worksheet->m_oTableParts.IsInit()) + tablesExist = true; + } + if(!tablesExist) + return; + } + for(auto xti:XLS::GlobalWorkbookInfo::arXti_External_static) + { + if(xti.itabFirst != xti.itabLast) + { + continue; + } + auto sheetName = xti.link; + if(!m_pWorkbook || !m_pWorkbook->m_oSheets.IsInit()) + continue; + OOX::Spreadsheet::CSheet * bundle; + for(auto i:m_pWorkbook->m_oSheets->m_arrItems) + { + if(i->m_oName.IsInit() && i->m_oName.get() == sheetName) + { + bundle = i; + } + } + if(!bundle || !bundle->m_oRid.IsInit()) + continue; + auto FilePtr = m_pWorkbook->Find(bundle->m_oRid->GetValue()); + if(!FilePtr.IsInit() || !(OOX::Spreadsheet::FileTypes::Worksheet == FilePtr->type())) + continue; + auto WorksheetFile = static_cast<OOX::Spreadsheet::CWorksheet*>(FilePtr.GetPointer()); + if(!WorksheetFile->m_oTableParts.IsInit()) + continue; + for(auto tablePart : WorksheetFile->m_oTableParts->m_arrItems) + { + if(tablePart->m_oRId.IsInit()) + { + auto tableFilePtr = WorksheetFile->Find(tablePart->m_oRId->GetValue()); + if(tableFilePtr.IsInit() && OOX::Spreadsheet::FileTypes::Table == tableFilePtr->type()) + { + auto tableFile = static_cast<OOX::Spreadsheet::CTableFile*>(tableFilePtr.GetPointer()); + if(tableFile->m_oTable.IsInit() && tableFile->m_oTable->m_oId.IsInit()) + { + if(!XLS::GlobalWorkbookInfo::mapXtiTables_static.count(xti.itabFirst)) + { + XLS::GlobalWorkbookInfo::mapXtiTables_static.emplace(xti.itabFirst, std::vector<int>()); + } + XLS::GlobalWorkbookInfo::mapXtiTables_static.at(xti.itabFirst).push_back(tableFile->m_oTable->m_oId->GetValue()); + + } + } + } + } + } } @@ -318,3 +422,4 @@ void OOX::Spreadsheet::CXlsb::PrepareTableFormula() + diff --git a/OOXML/XlsbFormat/Xlsb.h b/OOXML/XlsbFormat/Xlsb.h index 0757d40c05e..71610640a73 100644 --- a/OOXML/XlsbFormat/Xlsb.h +++ b/OOXML/XlsbFormat/Xlsb.h @@ -60,20 +60,27 @@ namespace OOX init(); } ~CXlsb(); - + bool ReadBin(const CPath& oFilePath, XLS::BaseObject* objStream); bool WriteBin(const CPath& oFilePath, XLS::BaseObject* objStream); + + bool WriteBin(const CPath& oDirPath, OOX::CContentTypes& oContentTypes); + XLS::GlobalWorkbookInfo* GetGlobalinfo(); void PrepareSi(); void PrepareTableFormula(); + void LinkTables(); void ReadSheetData(); + void WriteSheetData(); void SetPropForWriteSheet(const std::wstring &sPath, OOX::CContentTypes& oContentTypes); void WriteSheet(CWorksheet* worksheet); bool IsWriteToXlsx(); void WriteToXlsx(bool isXlsx); - + std::unordered_map<std::wstring, _UINT32> m_mapSheetNameSheetData; + + bool m_bWriteToXlsb = false; private: void init(); @@ -85,8 +92,7 @@ namespace OOX std::wstring m_sPath; OOX::CContentTypes m_oContentTypes; - bool m_bWriteToXlsx; - + bool m_bWriteToXlsx = false; }; } //Spreadsheet diff --git a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp index 38f50909c2f..e02622249f0 100644 --- a/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp +++ b/OOXML/XlsxFormat/Chart/ChartSerializeEx.cpp @@ -657,11 +657,11 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" { m_title = oReader; } - //else if(_T("numFmt") == sName) - //{ - // m_numFmt = new CT_NumFmt; - // m_numFmt->fromXML(oReader); - //} + else if(_T("numFmt") == sName) + { + m_numFmt = new CNumberFormat; + m_numFmt->fromXML(oReader); + } else if(_T("majorTickMark") == sName) { m_majorTickMarks = new CTickMarks; @@ -1405,13 +1405,11 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); if( L"binSize" == sName) { - std::wstring s = oReader.GetText3(); - m_binSize = XmlUtils::GetDouble(s); + m_binSize = oReader; } else if( L"binCount" == sName) { - std::wstring s = oReader.GetText3(); - m_binCount = XmlUtils::GetInteger(s); + m_binCount = oReader; } } } @@ -1432,15 +1430,15 @@ xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"" writer.WriteString(L">"); if (m_binCount.IsInit()) { - writer.WriteString(L"<cx:binCount>"); - writer.WriteString(XmlUtils::ToString(*m_binCount)); - writer.WriteString(L"</cx:binCount>"); + writer.WriteString(L"<cx:binCount "); + writer.WriteString(m_binCount->ToString()); + writer.WriteString(L"/>"); } else if (m_binSize.IsInit()) { - writer.WriteString(L"<cx:binSize>"); - writer.WriteString(std::to_wstring(*m_binSize)); - writer.WriteString(L"</cx:binSize>"); + writer.WriteString(L"<cx:binSize "); + writer.WriteString(m_binSize->ToString()); + writer.WriteString(L"/>"); } writer.WriteString(L"</cx:binning>"); } diff --git a/OOXML/XlsxFormat/Chart/ChartSerializeEx.h b/OOXML/XlsxFormat/Chart/ChartSerializeEx.h index 668fae7962b..01a7b5401a0 100644 --- a/OOXML/XlsxFormat/Chart/ChartSerializeEx.h +++ b/OOXML/XlsxFormat/Chart/ChartSerializeEx.h @@ -60,6 +60,7 @@ namespace ComplexTypes { class CParentLabelLayout; class CRegionLabelLayout; + class CDouble; } } @@ -294,8 +295,8 @@ namespace ChartEx void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - nullable_double m_binSize; - nullable_int m_binCount; + nullable<ComplexTypes::Spreadsheet::CDouble> m_binSize; + nullable<ComplexTypes::CDecimalNumber> m_binCount; nullable<SimpleTypes::Spreadsheet::CIntervalClosedSide> m_intervalClosed; nullable<SimpleTypes::Spreadsheet::CDoubleOrAutomatic<SimpleTypes::Spreadsheet::typeAuto>> m_underflow; diff --git a/OOXML/XlsxFormat/Comments/Comments.h b/OOXML/XlsxFormat/Comments/Comments.h index 9ca4bf5ed13..679287e201d 100644 --- a/OOXML/XlsxFormat/Comments/Comments.h +++ b/OOXML/XlsxFormat/Comments/Comments.h @@ -88,6 +88,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -112,6 +113,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -141,6 +143,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -156,6 +159,7 @@ namespace OOX virtual ~CComments(); 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; @@ -191,6 +195,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Comments/XlsxComments.cpp b/OOXML/XlsxFormat/Comments/XlsxComments.cpp index ff124aa7621..8fb150fb5af 100644 --- a/OOXML/XlsxFormat/Comments/XlsxComments.cpp +++ b/OOXML/XlsxFormat/Comments/XlsxComments.cpp @@ -49,6 +49,8 @@ #include "../SharedStrings/Si.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + namespace OOX { namespace Spreadsheet @@ -122,6 +124,18 @@ namespace OOX } } } + XLS::BaseObjectPtr CAuthors::toBin() + { + auto ptr(new XLSB::COMMENTAUTHORS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + auto author(new XLSB::CommentAuthor); + author->author = i; + ptr->m_arBrtCommentAuthor.push_back(XLS::BaseObjectPtr{author}); + } + return objectPtr; + } EElementType CAuthors::getType () const { return et_x_Authors; @@ -194,6 +208,50 @@ namespace OOX } } } + XLS::BaseObjectPtr CComment::toBin() + { + auto ptr(new XLSB::COMMENT); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginComment); + ptr->m_BrtBeginComment = XLS::BaseObjectPtr{ptr1}; + + if(m_oRef.IsInit()) + ptr1->rfx = m_oRef->GetValue(); + if(m_oAuthorId.IsInit()) + ptr1->iauthor = m_oAuthorId->GetValue(); + else + ptr1->iauthor = 0; + if(m_oUid.IsInit()) + ptr1->guid = m_oUid->ToString(); + else + ptr1->guid = L""; + if(m_oText.IsInit()) + { + auto type = m_oText->getType(); + auto text(new XLSB::CommentText); + if(type == OOX::et_x_Si) + { + text->text.fExtStr = false; + text->text.fRichStr = false; + text->text.str = m_oText->ToString(); + } + else if(type == OOX::et_x_rPh) + { + text->text.fExtStr = true; + text->text.fRichStr = false; + text->text.phoneticStr = m_oText->ToString(); + } + else if(type == OOX::et_x_rPr) + { + text->text.fExtStr = false; + text->text.fRichStr = true; + } + text->text.str = m_oText->ToString(); + ptr->m_BrtCommentText = XLS::BaseObjectPtr{text}; + } + + return objectPtr; + } EElementType CComment::getType () const { return et_x_Comment; @@ -211,7 +269,7 @@ namespace OOX auto ptr = static_cast<XLSB::BeginComment*>(obj.get()); if (ptr != nullptr) { - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); m_oAuthorId = ptr->iauthor; m_oUid = ptr->guid; } @@ -275,6 +333,14 @@ namespace OOX } } } + XLS::BaseObjectPtr CCommentList::toBin() + { + auto ptr(new XLSB::COMMENTLIST); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arCOMMENT.push_back(i->toBin()); + return objectPtr; + } EElementType CCommentList::getType () const { return et_x_CommentList; @@ -332,6 +398,20 @@ namespace OOX //commentsStream.reset(); } } + XLS::BaseObjectPtr CComments::WriteBin() const + { + XLSB::CommentsStreamPtr commentsStream(new XLSB::CommentsStream); + auto ptr(new XLSB::COMMENTS); + commentsStream->m_COMMENTS = XLS::BaseObjectPtr{ptr}; + + if(m_oAuthors.IsInit()) + ptr->m_COMMENTAUTHORS = m_oAuthors->toBin(); + + if(m_oCommentList.IsInit()) + ptr->m_COMMENTLIST = m_oCommentList->toBin(); + + return XLS::BaseObjectPtr{commentsStream}; + } void CComments::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) @@ -379,6 +459,14 @@ namespace OOX } void CComments::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ <comments xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" \ @@ -393,12 +481,17 @@ mc:Ignorable=\"xr\">"); 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 CComments::type() const { + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::CommentsBin; + } return OOX::Spreadsheet::FileTypes::Comments; } const CPath CComments::DefaultDirectory() const @@ -451,6 +544,14 @@ mc:Ignorable=\"xr\">"); { ReadAttributes(obj); } + XLS::BaseObjectPtr CLegacyDrawingWorksheet::toBin() + { + auto castedPtr(new XLSB::LegacyDrawing); + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oId.IsInit()) + castedPtr->stRelId.value = m_oId->GetValue(); + return ptr; + } EElementType CLegacyDrawingWorksheet::getType () const { return et_x_LegacyDrawingWorksheet; diff --git a/OOXML/XlsxFormat/Controls/Controls.cpp b/OOXML/XlsxFormat/Controls/Controls.cpp index c3ac52b8c84..b0d80959d0f 100644 --- a/OOXML/XlsxFormat/Controls/Controls.cpp +++ b/OOXML/XlsxFormat/Controls/Controls.cpp @@ -202,6 +202,25 @@ namespace OOX } } } + XLS::BaseObjectPtr CControl::toBin() + { + auto ptr(new XLSB::ActiveX); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oShapeId.IsInit()) + ptr->shapeId = m_oShapeId->GetValue(); + else + ptr->shapeId = 1; + if (m_oName.IsInit()) + ptr->strName = m_oName.get(); + else + ptr->strName = L""; + + if (!m_oRid.IsInit()) + ptr->strRelID.value = m_oRid->GetValue(); + else + ptr->strRelID.value = L""; + return objectPtr; + } void CControl::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -335,6 +354,18 @@ namespace OOX } } + XLS::BaseObjectPtr CControls::toBin() + { + auto ptr(new XLSB::ACTIVEXCONTROLS); + XLS::BaseObjectPtr objectPtr(ptr); + + for(auto i:m_mapControls) + { + ptr->m_arBrtActiveX.push_back(i.second->toBin()); + } + + return objectPtr; + } CListItem::CListItem() {} CListItem::~CListItem() {} diff --git a/OOXML/XlsxFormat/Controls/Controls.h b/OOXML/XlsxFormat/Controls/Controls.h index cee8bba539e..a721d54c38f 100644 --- a/OOXML/XlsxFormat/Controls/Controls.h +++ b/OOXML/XlsxFormat/Controls/Controls.h @@ -67,10 +67,10 @@ namespace OOX { public: WritingElement_AdditionMethods(CListItem) - + CListItem(); virtual ~CListItem(); - + virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -80,7 +80,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_string m_oVal; }; //----------------------------------------------------------------------------------------------------------------------------- @@ -88,10 +88,10 @@ namespace OOX { public: WritingElement_AdditionMethods(CListItems) - + CListItems(); virtual ~CListItems(); - + virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -101,7 +101,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader){} - + std::vector<nullable<CListItem>> m_arrItems; nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; }; @@ -122,7 +122,7 @@ namespace OOX virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oDropLines; nullable<SimpleTypes::Spreadsheet::CObjectType> m_oObjectType; nullable<SimpleTypes::Spreadsheet::CChecked> m_oChecked; @@ -142,7 +142,7 @@ namespace OOX nullable_string m_oFmlaGroup; nullable_string m_oFmlaLink; nullable_string m_oFmlaRange; - nullable_string m_oFmlaTxbx; + nullable_string m_oFmlaTxbx; nullable_bool m_oColored; nullable_bool m_oFirstButton; nullable_bool m_oHoriz; @@ -215,9 +215,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void toXML2(NSStringUtils::CStringBuilder& writer, bool bControlPr) const; - + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -252,9 +253,10 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - + void read(XmlUtils::CXmlLiteReader& oReader, bool bOldVersion = false); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Drawing/Drawing.h b/OOXML/XlsxFormat/Drawing/Drawing.h index 56f197f22c7..c615372ba51 100644 --- a/OOXML/XlsxFormat/Drawing/Drawing.h +++ b/OOXML/XlsxFormat/Drawing/Drawing.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: diff --git a/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp b/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp index e52a6e2cff1..22bcdbdceb9 100644 --- a/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp +++ b/OOXML/XlsxFormat/Drawing/XlsxDrawing.cpp @@ -72,6 +72,17 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CDrawingWorksheet::toBin() + { + auto castedPtr(new XLSB::Drawing); + XLS::BaseObjectPtr ptr(castedPtr); + if(m_oId.IsInit()) + { + if(!m_oId->GetValue().empty()) + castedPtr->stRelId.value = m_oId->GetValue(); + } + return ptr; + } EElementType CDrawingWorksheet::getType () const { return et_x_FromTo; diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp index a7a1f11a161..63a059d58d4 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.cpp @@ -65,6 +65,9 @@ #include "../../XlsbFormat/Biff12_records/SupName.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include <string> namespace OOX { @@ -118,6 +121,16 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalSheetNames::toBin() + { + XLSB::SupTabsPtr supTabs(new XLSB::SupTabs); + for (auto& item : m_arrItems) + { + XLSB::XLWideString str = *item->m_sVal; + supTabs->sheetNames.push_back(str); + } + return supTabs; + } void CExternalSheetNames::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SupTabs*>(obj.get()); @@ -170,6 +183,34 @@ namespace Spreadsheet { ReadAttributes(obj); } + XLS::BaseObjectPtr CExternalDefinedName::toBin() + { + XLSB::ExternalReferenceType type; + type = XLSB::ExternalReferenceType::WORKBOOK; + auto ptr(new XLSB::EXTERNNAME(type)); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oName.IsInit()) + { + auto nameStart(new XLSB::SupNameStart); + nameStart->name = m_oName.get(); + ptr->m_BrtSupNameStart = XLS::BaseObjectPtr{nameStart}; + } + if(m_oRefersTo.IsInit()) + { + auto nameFmla(new XLSB::SupNameFmla); + ptr->m_BrtSupNameFmla = XLS::BaseObjectPtr{nameFmla}; + nameFmla->fmla = m_oRefersTo.get(); + } + if(m_oSheetId.IsInit()) + { + auto supBits(new XLSB::SupNameBits(type)); + ptr->m_BrtSupNameBits = XLS::BaseObjectPtr{supBits}; + supBits->contentsExtName.iSheet = m_oSheetId->GetValue(); + supBits->contentsExtName.fBuiltIn = false; + } + return objectPtr; + } void CExternalDefinedName::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::EXTERNNAME*>(obj.get()); @@ -262,7 +303,15 @@ namespace Spreadsheet m_arrItems.push_back(new CExternalDefinedName(item)); } } - + std::vector<XLS::BaseObjectPtr> CExternalDefinedNames::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i:m_arrItems) + { + objectVector.push_back(i->toBin()); + } + return objectVector; + } CExternalCell::CExternalCell() { } @@ -298,7 +347,7 @@ namespace Spreadsheet writer.WriteString(L"<cell"); WritingStringNullableAttrString(L"r", m_oRef, m_oRef.get()); WritingStringNullableAttrString(L"t", m_oType, m_oType->ToString()); - WritingStringNullableAttrInt(L"vm", m_oValueMetadata, m_oValueMetadata->GetValue()); + WritingStringNullableAttrInt2(L"vm", m_oValueMetadata); writer.WriteString(L">"); if (m_oValue.IsInit()) m_oValue->toXML2(writer, (L"v")); @@ -310,6 +359,98 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalCell::toBin() + { + + auto ptr(new XLSB::EXTERNVALUE(0)); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oValueMetadata.IsInit()) + { + auto metaPtr(new XLSB::ExternValueMeta); + ptr->m_BrtExternValueMeta = XLS::BaseObjectPtr{metaPtr}; + metaPtr->ivmb = m_oValueMetadata.get(); + } + + auto valuePtr(new XLSB::EXTERNVALUEDATA(0)); + ptr->m_EXTERNVALUEDATA = XLS::BaseObjectPtr{valuePtr}; + XLSB::RgceLoc loc; + if(m_oRef.IsInit()) + loc = XLSB::RgceLoc(m_oRef.get()); + else + loc = XLSB::RgceLoc(L"A1"); + valuePtr->m_Col = loc.getColumn(); + if(!m_oValue.IsInit()) + { auto blanc(new XLSB::ExternCellBlank); + blanc->col = valuePtr->m_Col; + valuePtr->m_source = XLS::BaseObjectPtr{blanc}; + return objectPtr; + } + if(!m_oType.IsInit()) + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + } + switch(m_oType->GetValue()) + { + case SimpleTypes::Spreadsheet::celltypeStr: + { + auto str(new XLSB::ExternCellString); + str->col = valuePtr->m_Col; + str->value = m_oValue->m_sText; + valuePtr->m_source = XLS::BaseObjectPtr{str}; + break; + } + case SimpleTypes::Spreadsheet::celltypeBool: + { + auto boolVal(new XLSB::ExternCellBool); + boolVal->col = valuePtr->m_Col; + boolVal->value = m_oValue->m_sText == L"1" ? true : false; + valuePtr->m_source = XLS::BaseObjectPtr{boolVal}; + break; + } + case SimpleTypes::Spreadsheet::celltypeNumber: + { + auto doubleVal(new XLSB::ExternCellReal); + doubleVal->col = valuePtr->m_Col; + doubleVal->value.data.value = std::stod(m_oValue->m_sText); + valuePtr->m_source = XLS::BaseObjectPtr{doubleVal}; + break; + } + case SimpleTypes::Spreadsheet::celltypeError: + { + auto errVal(new XLSB::ExternCellError); + errVal->col = valuePtr->m_Col; + if(m_oValue->m_sText == L"#NULL!") + errVal->value = 0; + else if(m_oValue->m_sText == L"#DIV/0!") + errVal->value = 0x7; + else if(m_oValue->m_sText == L"#VALUE!") + errVal->value = 0xF; + else if(m_oValue->m_sText == L"#REF!") + errVal->value = 0x17; + else if(m_oValue->m_sText == L"#NAME?") + errVal->value = 0x1D; + else if(m_oValue->m_sText == L"#NUM!") + errVal->value = 0x24; + else if(m_oValue->m_sText == L"#N/A") + errVal->value = 0x2A; + else if(m_oValue->m_sText == L"#GETTING_DATA") + errVal->value = 0x2B; + else + errVal->value = 0x2A; + valuePtr->m_source = XLS::BaseObjectPtr{errVal}; + break; + } + default: + { + auto blanc(new XLSB::ExternCellBlank); + blanc->col = valuePtr->m_Col; + valuePtr->m_source = XLS::BaseObjectPtr{blanc}; + } + }; + + return objectPtr; + } void CExternalCell::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -398,7 +539,7 @@ namespace Spreadsheet WritingElement_ReadAttributes_Read_if(oReader, (L"r"), m_oRef) WritingElement_ReadAttributes_Read_else_if(oReader, (L"t"), m_oType) WritingElement_ReadAttributes_Read_else_if(oReader, (L"vm"), m_oValueMetadata) - WritingElement_ReadAttributes_End(oReader) + WritingElement_ReadAttributes_End(oReader) } CExternalRow::CExternalRow() @@ -455,6 +596,27 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalRow::toBin() + { + auto ptr(new XLSB::EXTERNROW); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::ExternRowHdr); + ptr->m_BrtExternRowHdr = XLS::BaseObjectPtr{ptr1}; + + if(m_oR.IsInit() && m_oR->GetValue() > 0) + { + ptr1->rw = m_oR->GetValue() - 1; + } + else + ptr1->rw = 0; + + for(auto i:m_arrItems) + { + ptr->m_arEXTERNVALUE.push_back(i->toBin()); + } + + return objectPtr; + } void CExternalRow::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -536,6 +698,29 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalSheetData::toBin() + { + auto ptr(new XLSB::EXTERNTABLE); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::ExternTableStart); + ptr->m_BrtExternTableStart = XLS::BaseObjectPtr{ptr1}; + + if(m_oSheetId.IsInit()) + ptr1->iTab = m_oSheetId->GetValue(); + else + ptr1->iTab = 0; + if(m_oRefreshError.IsInit()) + ptr1->fRefreshError = m_oRefreshError->GetValue(); + else + ptr1->fRefreshError = false; + + for(auto i:m_arrItems) + { + ptr->m_arEXTERNROW.push_back(i->toBin()); + } + + return objectPtr; + } void CExternalSheetData::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -619,7 +804,15 @@ namespace Spreadsheet m_arrItems.push_back(new CExternalSheetData(item)); } } - + std::vector<XLS::BaseObjectPtr> CExternalSheetDataSet::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i:m_arrItems) + { + objectVector.push_back(i->toBin()); + } + return objectVector; + } CExternalBook::CExternalBook() { } @@ -697,6 +890,32 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CExternalBook::toBin() + { + XLSB::EXTERNALLINKPtr externalLINK(new XLSB::EXTERNALLINK()); + auto beginSupbook(new XLSB::BeginSupBook); + if(m_oRid.IsInit()) + beginSupbook->string1 = m_oRid->GetValue(); + else + beginSupbook->string1 = L" "; + beginSupbook->sbt = 0; + externalLINK->m_BrtBeginSupBook = XLS::BaseObjectPtr{beginSupbook}; + XLSB::ExternalReferenceType type; + type = XLSB::ExternalReferenceType::WORKBOOK; + XLSB::EXTERNALBOOKPtr externalBOOK(new XLSB::EXTERNALBOOK(type)); + + externalLINK->m_EXTERNALBOOK = externalBOOK; + if (externalBOOK != nullptr) + { + if (m_oSheetNames.IsInit()) + externalBOOK->m_BrtSupTabs = m_oSheetNames->toBin(); + if(m_oDefinedNames.IsInit()) + externalBOOK->m_arEXTERNNAME = m_oDefinedNames->toBin(); + if(m_oSheetDataSet.IsInit()) + externalBOOK->m_arEXTERNTABLE = m_oSheetDataSet->toBin(); + } + return externalLINK; + } void CExternalBook::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::EXTERNALLINK*>(obj.get()); @@ -786,6 +1005,77 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CDdeValue::toBin() + { + XLSB::DDEOLEITEMVALUEPtr ptr(new XLSB::DDEOLEITEMVALUE); + if(!m_oType.IsInit()) + return ptr; + auto type = m_oType->GetValue(); + switch(type) + { + case XLSB::rt_SupNameNum: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameNum}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast<XLSB::SupNameNum*>(ptr->m_source.get()); + castedSource->value.data.value = std::stod(m_arrItems.back()->m_sText); + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameBool: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameBool}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast<XLSB::SupNameBool*>(ptr->m_source.get()); + castedSource->value = std::stoi(m_arrItems.back()->m_sText); + m_arrItems.pop_back(); + } + + } + break; + case XLSB::rt_SupNameErr: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameErr}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast<XLSB::SupNameErr*>(ptr->m_source.get()); + auto error = m_arrItems.back()->m_sText.c_str(); + + if(error == L"#NULL!"){ castedSource->value = 0x00;} + else if(error == L"#DIV/0!"){castedSource->value = 0x07;} + else if(error == L"#VALUE!"){ castedSource->value = 0x0F;} + else if(error == L"#REF!"){ castedSource->value = 0x17;} + else if(error == L"#NAME?"){ castedSource->value = 0x1D;} + else if(error == L"#NUM!"){castedSource->value = 0x24;} + else if(error == L"#N/A"){castedSource->value = 0x2A;} + else if(error == L"#GETTING_DATA"){castedSource->value = 0x2B;} + + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameSt: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameSt}; + if(!m_arrItems.empty()) + { + auto castedSource = reinterpret_cast<XLSB::SupNameSt*>(ptr->m_source.get()); + castedSource->value = m_arrItems.back()->m_sText; + m_arrItems.pop_back(); + } + } + break; + case XLSB::rt_SupNameNil: + { + ptr->m_source = XLS::BaseObjectPtr{new XLSB::SupNameNil}; + } + break; + } + return ptr; + } void CDdeValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -943,6 +1233,18 @@ namespace Spreadsheet m_arrItems.push_back(new CDdeValue(item)); } } + XLS::BaseObjectPtr CDdeValues::toBin() + { + XLSB::DDEOLEITEMVALUESPtr ptr(new XLSB::DDEOLEITEMVALUES); + auto castedPtr = static_cast<XLSB::SupNameValueStart*>(ptr->m_BrtSupNameValueStart.get()); + if(m_oRows.IsInit()) + castedPtr->cRw = m_oRows->GetValue(); + if(m_oCols.IsInit()) + castedPtr->cCol = m_oCols->GetValue(); + for (auto &item : m_arrItems) + ptr->m_arDDEOLEITEMVALUE.push_back(item->toBin()); + return ptr; + } void CDdeValues::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SupNameValueStart*>(obj.get()); @@ -1011,6 +1313,31 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr CDdeItem::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLEITEMPtr ptr(new XLSB::DDEOLEITEM(type)); + if (m_oDdeValues.IsInit()) + ptr->m_DDEOLEITEMVALUES = m_oDdeValues->toBin(); + if(m_oName.IsInit()) + { + ptr->m_BrtSupNameStart = XLS::BaseObjectPtr{new XLSB::SupNameStart}; + auto ptrSupNameStart = static_cast<XLSB::SupNameStart*>(ptr->m_BrtSupNameStart.get()); + ptrSupNameStart->name = m_oName.get(); + } + if(m_oOle.IsInit() || m_oAdvise.IsInit() || m_oPreferPic.IsInit()) + { + ptr->m_BrtSupNameBits = XLS::BaseObjectPtr{new XLSB::SupNameBits(type)}; + auto ptrSupNameBits = static_cast<XLSB::SupNameBits*>(ptr->m_BrtSupNameBits.get()); + if(m_oOle.IsInit()) + ptrSupNameBits->contentsDDE.fOLE = m_oOle->ToBool(); + if(m_oAdvise.IsInit()) + ptrSupNameBits->contentsDDE.fWantAdvise = m_oAdvise->ToBool(); + if(m_oPreferPic.IsInit()) + ptrSupNameBits->contentsDDE.fWantPict = m_oPreferPic->ToBool(); + } + return ptr; + } void CDdeItem::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1108,6 +1435,15 @@ namespace Spreadsheet } } + XLS::BaseObjectPtr CDdeItems::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLELINKPtr ptr(new XLSB::DDEOLELINK(type)); + for (auto item : m_arrItems) + ptr->m_arDDEOLEITEM.push_back(item->toBin()); + return ptr; + } + void CDdeLink::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); @@ -1155,6 +1491,24 @@ namespace Spreadsheet m_oDdeItems = ptr->m_DDEOLELINK; } } + XLS::BaseObjectPtr CDdeLink::toBin() + { + XLSB::EXTERNALLINKPtr ptr(new XLSB::EXTERNALLINK); + ptr->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; + auto castedBook = static_cast<XLSB::BeginSupBook*>(ptr->m_BrtBeginSupBook.get()); + if (m_oDdeService.IsInit()) + castedBook->string1 = m_oDdeService.get(); + else + castedBook->string1 = L""; + if (m_oDdeTopic.IsInit()) + castedBook->string2 = m_oDdeTopic.get(); + else + castedBook->string2 = L""; + if(m_oDdeItems.IsInit()) + ptr->m_DDEOLELINK = m_oDdeItems->toBin(); + castedBook->sbt = 0x0001; + return ptr; + } CDdeLink::CDdeLink() { @@ -1223,6 +1577,29 @@ namespace Spreadsheet toXML(writer); return writer.GetData().c_str(); } + XLS::BaseObjectPtr COleItem::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLEITEMPtr coleItem(new XLSB::DDEOLEITEM(type)); + if(m_oName.IsInit()) + { + coleItem->m_BrtSupNameStart = XLS::BaseObjectPtr{new XLSB::SupNameStart}; + auto castedName = static_cast<XLSB::SupNameStart*>(coleItem->m_BrtSupNameStart.get()); + castedName->name = m_oName.get(); + } + if(m_oIcon.IsInit() || m_oAdvise.IsInit() || m_oPreferPic.IsInit()) + { + coleItem->m_BrtSupNameBits = XLS::BaseObjectPtr{new XLSB::SupNameBits(type)}; + auto ptrSupNameBits = static_cast<XLSB::SupNameBits*>(coleItem->m_BrtSupNameBits.get()); + if(m_oIcon.IsInit()) + ptrSupNameBits->contentsOLE.fIcon = m_oIcon->ToBool(); + if(m_oAdvise.IsInit()) + ptrSupNameBits->contentsOLE.fWantAdvise = m_oAdvise->ToBool(); + if(m_oPreferPic.IsInit()) + ptrSupNameBits->contentsOLE.fWantPict = m_oPreferPic->ToBool(); + } + return coleItem; + } void COleItem::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1316,6 +1693,17 @@ namespace Spreadsheet m_arrItems.push_back(new COleItem(item)); } } + XLS::BaseObjectPtr COleItems::toBin() + { + XLSB::ExternalReferenceType type; + XLSB::DDEOLELINKPtr ptr(new XLSB::DDEOLELINK(type)); + + for(auto i: m_arrItems) + { + ptr->m_arDDEOLEITEM.push_back(i->toBin()); + } + return ptr; + } COleLink::COleLink() { @@ -1377,6 +1765,25 @@ namespace Spreadsheet m_oOleItems = ptr->m_DDEOLELINK; } } + XLS::BaseObjectPtr COleLink::toBin() + { + XLSB::EXTERNALLINKPtr COleLink(new XLSB::EXTERNALLINK); + COleLink->m_BrtBeginSupBook = XLS::BaseObjectPtr{new XLSB::BeginSupBook}; + auto castedBook = static_cast<XLSB::BeginSupBook*>(COleLink->m_BrtBeginSupBook.get()); + castedBook->sbt = 0x0002; + if(m_oRid.IsInit()) + castedBook->string1 = m_oRid->ToString(); + else + castedBook->string1 = L""; + if(m_oProgId.IsInit()) + castedBook->string2 = m_oProgId.get(); + else + castedBook->string2 = L""; + + if(m_oOleItems.IsInit()) + COleLink->m_DDEOLELINK = m_oOleItems->toBin(); + return COleLink; + } void COleLink::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::BeginSupBook*>(obj.get()); @@ -1481,6 +1888,21 @@ namespace Spreadsheet CExternalLink::~CExternalLink() { } + XLS::BaseObjectPtr CExternalLink::writeBin() const + { + XLSB::ExternalLinkStreamPtr externalLinkStreamStream(new XLSB::ExternalLinkStream); + + if (externalLinkStreamStream != nullptr) + { + if (m_oExternalBook.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oExternalBook->toBin(); + else if (m_oDdeLink.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oDdeLink->toBin(); + else if (m_oOleLink.IsInit()) + externalLinkStreamStream->m_EXTERNALLINK = m_oOleLink->toBin(); + } + return externalLinkStreamStream; + } void CExternalLink::readBin(const CPath& oPath) { CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); @@ -1593,6 +2015,14 @@ namespace Spreadsheet } void CExternalLink::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = writeBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); sXml.WriteString(L"<externalLink \ @@ -1628,7 +2058,7 @@ xmlns:xxl21=\"http://schemas.microsoft.com/office/spreadsheetml/2021/extlinks202 std::wstring sPath = oPath.GetPath(); NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); - + } oContent.Registration(type().OverrideType(), oDirectory, oPath.GetFilename()); IFileContainer::Write(oPath, oDirectory, oContent); } @@ -1638,6 +2068,11 @@ xmlns:xxl21=\"http://schemas.microsoft.com/office/spreadsheetml/2021/extlinks202 } const OOX::FileType CExternalLink::type() const { + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::ExternalLinksBin; + } return OOX::Spreadsheet::FileTypes::ExternalLinks; } const CPath CExternalLink::DefaultDirectory() const diff --git a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h index 358ee01686c..8099f9989ca 100644 --- a/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h +++ b/OOXML/XlsxFormat/ExternalLinks/ExternalLinks.h @@ -67,17 +67,18 @@ namespace OOX public: WritingElement_AdditionMethods(CExternalSheetNames) WritingElement_XlsbConstructors(CExternalSheetNames) - + CExternalSheetNames(); virtual ~CExternalSheetNames(); virtual void fromXML(XmlUtils::CXmlNode& oNode); virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; - void fromBin(XLS::BaseObjectPtr& obj); + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; class CAlternateUrls : public WritingElement @@ -103,7 +104,7 @@ namespace OOX nullable<SimpleTypes::CRelationshipId> m_oAbsoluteUrlRid; nullable<SimpleTypes::CRelationshipId> m_oRelativeUrlRid; - + nullable_string m_oDriveId; nullable_string m_oItemId; }; @@ -122,6 +123,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -145,6 +147,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType() const; }; @@ -162,16 +165,17 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); - + XLS::BaseObjectPtr toBin(); + virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - - nullable<std::wstring> m_oRef; - nullable<SimpleTypes::Spreadsheet::CCellTypeType> m_oType; - nullable<SimpleTypes::CUnsignedDecimalNumber> m_oValueMetadata; - nullable<CText> m_oValue; + nullable_string m_oRef; + nullable<SimpleTypes::Spreadsheet::CCellTypeType> m_oType; + nullable_uint m_oValueMetadata; + + nullable<CText> m_oValue; }; class CExternalRow : public WritingElementWithChilds<CExternalCell> @@ -188,6 +192,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -210,6 +215,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -233,7 +239,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(std::vector<XLS::BaseObjectPtr>& obj); - + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType() const; }; @@ -251,6 +257,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -278,6 +285,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -301,6 +309,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -324,6 +333,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -353,6 +363,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; @@ -371,6 +382,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -396,6 +408,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); @@ -420,6 +433,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; }; @@ -437,6 +451,7 @@ namespace OOX virtual std::wstring toXML() const; void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType() const; void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -454,7 +469,9 @@ namespace OOX CExternalLink(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath, const std::wstring & rId); virtual ~CExternalLink(); + XLS::BaseObjectPtr writeBin() const; void readBin(const CPath& oPath); + 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/FileFactory_Spreadsheet.cpp b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp index fba046b2618..8b692b6291a 100644 --- a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp @@ -58,6 +58,8 @@ #include "Slicer/Slicer.h" #include "NamedSheetViews/NamedSheetViews.h" #include "Timelines/Timeline.h" +#include "RichData/RdRichValue.h" +#include "Workbook/Metadata.h" #include "Table/Table.h" #include "Table/QueryTable.h" @@ -181,6 +183,14 @@ namespace OOX return smart_ptr<OOX::File>(new CTimelineFile(pMain, oRootPath, oFileName)); else if ( oRelation.Type() == FileTypes::TimelineCache) return smart_ptr<OOX::File>(new CTimelineCacheFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Metadata) + return smart_ptr<OOX::File>(new CMetadataFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValueStructure) + return smart_ptr<OOX::File>(new CRdRichValueStructureFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValue) + return smart_ptr<OOX::File>(new CRdRichValueFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::RdRichValueTypes) + return smart_ptr<OOX::File>(new CRdRichValueTypesFile(pMain, oRootPath, oFileName)); return smart_ptr<OOX::File>( new UnknowTypeFile(pMain) ); } @@ -313,6 +323,14 @@ namespace OOX return smart_ptr<OOX::File>(new CTimelineFile(pMain, oRootPath, oFileName)); else if (pRelation->Type() == FileTypes::TimelineCache) return smart_ptr<OOX::File>(new CTimelineCacheFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Metadata) + return smart_ptr<OOX::File>(new CMetadataFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValueStructure) + return smart_ptr<OOX::File>(new CRdRichValueStructureFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValue) + return smart_ptr<OOX::File>(new CRdRichValueFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::RdRichValueTypes) + return smart_ptr<OOX::File>(new CRdRichValueTypesFile(pMain, oRootPath, oFileName)); return smart_ptr<OOX::File>( new UnknowTypeFile(pMain) ); } diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp index 52076231ba6..e5c88368dee 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp @@ -155,12 +155,28 @@ namespace OOX L"http://schemas.microsoft.com/office/2011/relationships/timelineCache", L"timelineCaches/timelineCache", true, true); //onlyoffice workbook comments - const FileType WorkbookComments(L"", L"workbookComments.bin", + const FileType WorkbookComments (L"", L"workbookComments.bin", L"", L"http://schemas.onlyoffice.com/workbookComments"); + + const FileType Metadata (L"", L"metadata.xml", + L"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata"); - const FileType SpreadsheetFlat(L"", L"", L"", L""); + const FileType RdRichValue (L"richData", L"rdrichvalue.xml", + L"application/vnd.ms-excel.rdrichvalue+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValue"); + + const FileType RdRichValueStructure(L"richData", L"rdrichvaluestructure.xml", + L"application/vnd.ms-excel.rdrichvaluestructure+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure"); + + const FileType RdRichValueTypes (L"richData", L"rdRichValueTypes..xml", + L"application/vnd.ms-excel.rdrichvaluetypes+xml", + L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueTypes"); + + const FileType SpreadsheetFlat (L"", L"", L"", L""); } // namespace FileTypes } diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h index e73ba16a926..0204c805660 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h @@ -93,6 +93,13 @@ namespace OOX extern const FileType TimelineCache; + extern const FileType Metadata; + + extern const FileType RdRichValue; + + extern const FileType RdRichValueStructure; + + extern const FileType RdRichValueTypes; } // namespace FileTypes } } // namespace OOX diff --git a/OOXML/XlsxFormat/Ole/OleObjects.cpp b/OOXML/XlsxFormat/Ole/OleObjects.cpp index b6f273cb8a0..c4adf6178ef 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.cpp +++ b/OOXML/XlsxFormat/Ole/OleObjects.cpp @@ -293,6 +293,50 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr COleObject::toBin() + { + auto ptr(new XLSB::OleObject); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oDvAspect.IsInit()) + { + if(m_oDvAspect == SimpleTypes::Spreadsheet::EDvAspect::Content) + ptr->dwAspect = 0x00000001; + else if(m_oDvAspect == SimpleTypes::Spreadsheet::EDvAspect::Icon) + ptr->dwAspect = 0x00000004; + } + if(m_oOleUpdate.IsInit()) + { + if(m_oOleUpdate == SimpleTypes::Spreadsheet::EOleUpdate::Always) + ptr->dwOleUpdate = 0x00000001; + else if(m_oOleUpdate == SimpleTypes::Spreadsheet::EOleUpdate::OnCall) + ptr->dwOleUpdate = 0x00000003; + } + + if(m_oShapeId.IsInit()) + ptr->shapeId = m_oShapeId->GetValue(); + if(m_oAutoLoad.IsInit()) + ptr->fAutoLoad = m_oAutoLoad->GetValue(); + else + ptr->fAutoLoad = false; + + if(m_oProgId.IsInit()) + ptr->strProgID = m_oProgId.get(); + + if(m_oLink.IsInit()) + { + ptr->fLinked = true; + ptr->link = m_oLink.get(); + } + else + ptr->fLinked = false; + + if(m_oRid.IsInit()) + ptr->strRelID.value = m_oRid->GetValue(); + else + ptr->strRelID.value.setSize(0); + + return objectPtr; + } EElementType COleObject::getType () const { return et_x_OleObject; @@ -455,6 +499,16 @@ namespace OOX } } } + XLS::BaseObjectPtr COleObjects::toBin() + { + auto ptr(new XLSB::OLEOBJECTS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_mapOleObjects) + { + ptr->m_arBrtOleObject.push_back(i.second->toBin()); + } + return objectPtr; + } EElementType COleObjects::getType () const { return et_x_OleObjects; diff --git a/OOXML/XlsxFormat/Ole/OleObjects.h b/OOXML/XlsxFormat/Ole/OleObjects.h index 20c32d0df51..450f1997bcc 100644 --- a/OOXML/XlsxFormat/Ole/OleObjects.h +++ b/OOXML/XlsxFormat/Ole/OleObjects.h @@ -136,6 +136,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; private: @@ -171,6 +172,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/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 4bd71ff7171..4e3ed890fc4 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -57,7 +57,7 @@ namespace OOX WritingElement_XlsbConstructors(CSharedItems) CSharedItems(){} virtual ~CSharedItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -68,12 +68,14 @@ 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_SharedItems; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + XLS::BaseObjectPtr writeAttributes(const unsigned char flags); nullable_bool m_oContainsBlank; nullable_bool m_oContainsDate; @@ -83,7 +85,7 @@ namespace OOX nullable_bool m_oContainsNumber; nullable_bool m_oContainsSemiMixedTypes; nullable_bool m_oContainsString; - + nullable_bool m_oLongText; nullable_double m_oMinValue; nullable_double m_oMaxValue; @@ -98,7 +100,7 @@ namespace OOX WritingElement_XlsbConstructors(COLAPGroupItems) COLAPGroupItems(){} virtual ~COLAPGroupItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -109,6 +111,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_OLAPGroupItems; @@ -124,7 +127,7 @@ namespace OOX WritingElement_XlsbConstructors(CDiscreteGroupingProperties) CDiscreteGroupingProperties(){} virtual ~CDiscreteGroupingProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -135,6 +138,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_DiscreteGroupingProperties; @@ -150,7 +154,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeGroupingProperties) CRangeGroupingProperties(){} virtual ~CRangeGroupingProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -161,6 +165,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_RangeGroupingProperties; @@ -177,9 +182,9 @@ namespace OOX nullable<SimpleTypes::CDateTime> m_oEndDate; nullable_double m_oStartNum; - nullable_double m_oEndNum; + nullable_double m_oEndNum; nullable_double m_oGroupInterval; - + }; class CFieldGroupProperties : public WritingElement { @@ -188,7 +193,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldGroupProperties) CFieldGroupProperties(){} virtual ~CFieldGroupProperties() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -199,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 { return et_x_FieldGroupProperties; @@ -208,7 +214,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oBase; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oPar; - + nullable<CDiscreteGroupingProperties> m_oDiscretePr; nullable<CRangeGroupingProperties> m_oRangePr; nullable<COLAPGroupItems> m_oGroupItems; @@ -220,7 +226,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheField) CPivotCacheField(){} virtual ~CPivotCacheField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -230,11 +236,13 @@ 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 { return et_x_PivotCacheField; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -252,7 +260,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oLevel; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oMappingCount; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oNumFmtId; - + nullable<CSharedItems> m_oSharedItems; //nullable<CMemberPropertiesMap> m_oMpMap; nullable<CFieldGroupProperties> m_oFieldGroup; @@ -265,7 +273,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheFields) CPivotCacheFields(){} virtual ~CPivotCacheFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -276,6 +284,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_PivotCacheFields; @@ -291,7 +300,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeSet) CRangeSet(){} virtual ~CRangeSet() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -302,6 +311,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_RangeSet; @@ -325,7 +335,7 @@ namespace OOX WritingElement_XlsbConstructors(CRangeSets) CRangeSets(){} virtual ~CRangeSets() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -336,6 +346,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_RangeSets; @@ -351,7 +362,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItem) CPageItem(){} virtual ~CPageItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -362,6 +373,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_PageItem; @@ -378,7 +390,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItems) CPageItems(){} virtual ~CPageItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -389,6 +401,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_PageItems; @@ -404,7 +417,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageItemValues) CPageItemValues(){} virtual ~CPageItemValues() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -415,6 +428,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_PageItemValues; @@ -447,12 +461,13 @@ 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_ConsolidationSource; } void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable_bool m_oAutoPage; @@ -466,7 +481,7 @@ namespace OOX WritingElement_XlsbConstructors(CWorksheetSource) CWorksheetSource(){} virtual ~CWorksheetSource() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -477,6 +492,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_WorksheetSource; @@ -511,12 +527,13 @@ 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_PivotCacheSource; } void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable<SimpleTypes::CUnsignedDecimalNumber> m_oConnectionId; nullable<SimpleTypes::Spreadsheet::CSourceCacheType> m_oType; @@ -524,7 +541,7 @@ namespace OOX nullable<CConsolidationSource> m_oConsolidation; nullable<CWorksheetSource> m_oWorksheetSource; nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; - }; + }; class CPivotCacheDefinition : public WritingElement { public: @@ -547,12 +564,14 @@ 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_PivotCacheDefinition; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); //---------- nullable_bool m_oBackgroundQuery; nullable_bool m_oEnableRefresh; @@ -591,10 +610,10 @@ namespace OOX CPivotCacheDefinitionFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; - + bIsWritten = false; } CPivotCacheDefinitionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) @@ -626,9 +645,9 @@ namespace OOX const std::string srIdRecordsA( srIdRecords.begin(), srIdRecords.end() ); std::string rIdAttr = " r:id=\""+ srIdRecordsA +"\""; m_nDataLength = length + (long)rIdAttr.length(); - + m_pData = new BYTE[m_nDataLength]; - + long nTreshold = 220; memcpy(m_pData, pData, nTreshold); memcpy(m_pData + nTreshold, rIdAttr.c_str(), rIdAttr.length()); @@ -642,12 +661,10 @@ namespace OOX } } 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; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotCacheDefinition; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); @@ -664,7 +681,7 @@ namespace OOX nullable<CPivotCacheDefinition> m_oPivotCashDefinition; private: CPath m_oReadPath; - + BYTE *m_pData; long m_nDataLength; @@ -678,7 +695,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCharacterValue) CPivotCharacterValue(){} virtual ~CPivotCharacterValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -689,19 +706,20 @@ 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_PivotCharacterValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -711,7 +729,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oFormatIndex; //tpls - }; + }; class CPivotBooleanValue : public WritingElementWithChilds<CMemberPropertyIndex> { public: @@ -719,7 +737,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotBooleanValue) CPivotBooleanValue(){} virtual ~CPivotBooleanValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -730,6 +748,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_PivotBooleanValue; @@ -742,7 +761,7 @@ namespace OOX nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; - }; + }; class CPivotNumericValue : public WritingElementWithChilds<CMemberPropertyIndex> { public: @@ -750,7 +769,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotNumericValue) CPivotNumericValue(){} virtual ~CPivotNumericValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -761,19 +780,20 @@ 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_PivotNumericValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_double m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -783,7 +803,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oFormatIndex; //tpls - }; + }; class CPivotDateTimeValue : public WritingElementWithChilds<CMemberPropertyIndex> { public: @@ -791,7 +811,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotDateTimeValue) CPivotDateTimeValue(){} virtual ~CPivotDateTimeValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -802,13 +822,14 @@ 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_PivotBooleanValue; + return et_x_PivotDateTimeValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable<SimpleTypes::CDateTime> m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; @@ -822,7 +843,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotErrorValue) CPivotErrorValue(){} virtual ~CPivotErrorValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -833,19 +854,20 @@ 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_PivotErrorValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oValue; nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -855,7 +877,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oFormatIndex; //tpls - }; + }; class CPivotNoValue : public WritingElementWithChilds<CMemberPropertyIndex> { public: @@ -863,7 +885,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotNoValue) CPivotNoValue(){} virtual ~CPivotNoValue() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -874,18 +896,19 @@ 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_PivotNoValue; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - + nullable_string m_oCaption; nullable_bool m_oCalculated; nullable_bool m_oUnused; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; - + nullable_bool m_oBold; nullable_bool m_oItalic; nullable_bool m_oStrike; @@ -895,7 +918,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oFormatIndex; //tpls - }; - + }; + } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp index 6312d219d54..4b13e626f49 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.cpp @@ -54,6 +54,34 @@ void CPivotCacheDefinitionExt::fromXML(XmlUtils::CXmlLiteReader& oReader) return; oReader.ReadTillEnd(); } +XLS::BaseObjectPtr CPivotCacheDefinitionExt::toBin() +{ + auto ptr(new XLSB::PCD14); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginPCD14); + if(m_oSlicerData.IsInit()) + ptr1->fSlicerData = m_oSlicerData.get(); + else + ptr1->fSlicerData = false; + if(m_oSrvSupportAddCalcMems.IsInit()) + ptr1->fSrvSupportAddCalcMems = m_oSrvSupportAddCalcMems.get(); + else + ptr1->fSrvSupportAddCalcMems = false; + if(m_oSrvSupportSubQueryCalcMem.IsInit()) + ptr1->fSrvSupportSubQueryCalcMem = m_oSrvSupportSubQueryCalcMem.get(); + else + ptr1->fSrvSupportSubQueryCalcMem = false; + if(m_oSrvSupportSubQueryNonVisual.IsInit()) + ptr1->fSrvSupportSubQueryNonVisual = m_oSrvSupportSubQueryNonVisual.get(); + else + ptr1->fSrvSupportSubQueryNonVisual = false; + ptr->m_BrtBeginPCD14 = XLS::BaseObjectPtr{ptr1}; + if(m_oPivotCacheId.IsInit()) + ptr1->icacheId = m_oPivotCacheId.get(); + else + ptr1->icacheId = 0; + return objectPtr; +} void CPivotCacheDefinitionExt::fromBin(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typePCD14) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h index 2f1c35cdb9b..8a3cefbcea3 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinitionExt.h @@ -61,6 +61,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(); virtual EElementType getType () const { return et_x_PivotCacheDefinitionExt; diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h b/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h index 8f00b1f924f..354d07ff750 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheRecords.h @@ -57,7 +57,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotCacheRecord) CPivotCacheRecord(){} virtual ~CPivotCacheRecord() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -68,6 +68,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_PivotCacheRecord; @@ -96,11 +97,12 @@ 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_PivotCacheRecords; } - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; @@ -114,7 +116,7 @@ namespace OOX CPivotCacheRecordsFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; } @@ -145,12 +147,10 @@ namespace OOX memcpy(m_pData, pData, length); } 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; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotCacheRecords; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); @@ -165,11 +165,12 @@ namespace OOX } //--------------------------------------------------------------------- nullable<CPivotCacheRecords> m_oPivotCacheRecords; - //--------- + //--------- BYTE *m_pData = NULL; DWORD m_nDataLength = 0; private: - CPath m_oReadPath; + CPath m_oReadPath; + std::wstring prepareData() const; }; } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Pivot/PivotTable.h b/OOXML/XlsxFormat/Pivot/PivotTable.h index 8c0c7328778..f3b94ce4b02 100644 --- a/OOXML/XlsxFormat/Pivot/PivotTable.h +++ b/OOXML/XlsxFormat/Pivot/PivotTable.h @@ -101,6 +101,8 @@ namespace OOX WritingStringNullableAttrInt(L"v", m_oV, m_oV->GetValue()); writer.WriteString(L"/>"); } + XLS::BaseObjectPtr toBinPrfItem(); + XLS::BaseObjectPtr toBinItemIndex(); void fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -176,7 +178,7 @@ namespace OOX CField(){} virtual ~CField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -204,7 +206,7 @@ namespace OOX WritingElement_ReadAttributes_ReadSingle ( oReader, L"x", m_oX ) WritingElement_ReadAttributes_End( oReader ) } - + nullable_int m_oX; }; class CColumnRowFields : public WritingElementWithChilds<CField> @@ -214,7 +216,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowFields) CColumnRowFields(){} virtual ~CColumnRowFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -226,6 +228,8 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinRows(); + XLS::BaseObjectPtr toBinCols(); virtual EElementType getType () const { return et_x_ColumnRowFields; @@ -241,7 +245,7 @@ namespace OOX WritingElement_XlsbConstructors(CDataField) CDataField(){} virtual ~CDataField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -252,13 +256,14 @@ 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_DataField; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_int m_oBaseField; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oBaseItem; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oFld; @@ -276,7 +281,7 @@ namespace OOX WritingElement_XlsbConstructors(CDataFields) CDataFields(){} virtual ~CDataFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -287,6 +292,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_DataFields; @@ -302,7 +308,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageField) CPageField(){} virtual ~CPageField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -313,13 +319,14 @@ 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_PageField; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_int m_oFld; nullable_int m_oHier; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oItem; @@ -335,7 +342,7 @@ namespace OOX WritingElement_XlsbConstructors(CPageFields) CPageFields(){} virtual ~CPageFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -346,6 +353,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_PageFields; @@ -361,7 +369,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldItem) CFieldItem(){} virtual ~CFieldItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -372,13 +380,14 @@ 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_FieldItem; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oChild; nullable_bool m_oExpanded; nullable_bool m_oDrillAcross; @@ -399,7 +408,7 @@ namespace OOX WritingElement_XlsbConstructors(CFieldItems) CFieldItems(){} virtual ~CFieldItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -410,12 +419,13 @@ 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_FieldItems; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; }; class CReference : public WritingElement @@ -425,7 +435,7 @@ namespace OOX WritingElement_XlsbConstructors(CReference) CReference(){} virtual ~CReference() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -436,13 +446,15 @@ 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_Reference; } + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oAvgSubtotal; nullable_bool m_oByPosition; nullable_bool m_oCountASubtotal; @@ -471,7 +483,7 @@ namespace OOX WritingElement_XlsbConstructors(CReferences) CReferences(){} virtual ~CReferences() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -482,12 +494,13 @@ 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_References; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCount; }; class CPivotArea : public WritingElement @@ -497,7 +510,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotArea) CPivotArea(){} virtual ~CPivotArea() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -508,10 +521,12 @@ 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_PivotArea; } + XLS::BaseObjectPtr writeAttribures(); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -538,7 +553,7 @@ namespace OOX WritingElement_XlsbConstructors(CAutoSortScope) CAutoSortScope(){} virtual ~CAutoSortScope() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -549,12 +564,13 @@ 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_AutoSortScope; } void ReadAttributes(XmlUtils::CXmlLiteReader& oReader){} - + nullable<CPivotArea> m_oPivotArea; }; class CPivotField : public WritingElement @@ -564,7 +580,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotField) CPivotField(){} virtual ~CPivotField() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -575,13 +591,15 @@ 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_PivotField; } void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr writeAttributes(); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable_bool m_oAllDrilled; nullable_bool m_oAutoShow; nullable_bool m_oAvgSubtotal; @@ -630,7 +648,7 @@ namespace OOX nullable_string m_oUniqueMemberProperty; nullable_bool m_oVarPSubtotal; nullable_bool m_oVarSubtotal; - + nullable<CAutoSortScope> m_oAutoSortScope; nullable<CFieldItems> m_oItems; nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; @@ -642,7 +660,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotFields) CPivotFields(){} virtual ~CPivotFields() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -653,6 +671,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_PivotFields; @@ -668,7 +687,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowItem) CColumnRowItem(){} virtual ~CColumnRowItem() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -679,17 +698,18 @@ 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_ColumnRowItem; } void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oI; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oR; nullable<SimpleTypes::Spreadsheet::CPivotItemType> m_oT; - }; + }; class CColumnRowItems : public WritingElementWithChilds<CColumnRowItem> { public: @@ -697,7 +717,7 @@ namespace OOX WritingElement_XlsbConstructors(CColumnRowItems) CColumnRowItems(){} virtual ~CColumnRowItems() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -709,6 +729,8 @@ namespace OOX void toXML2(NSStringUtils::CStringBuilder& writer, const std::wstring& sName) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBinRows(); + XLS::BaseObjectPtr toBinCols(); virtual EElementType getType () const { return et_x_ColumnRowItems; @@ -724,7 +746,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableFormat) CPivotTableFormat(){} virtual ~CPivotTableFormat() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -735,6 +757,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_PivotTableFormat; @@ -744,7 +767,7 @@ namespace OOX nullable<SimpleTypes::Spreadsheet::CFormatAction> m_oAction; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oDxfId; - + nullable<CPivotArea> m_oPivotArea; nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; }; @@ -755,7 +778,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableFormats) CPivotTableFormats(){} virtual ~CPivotTableFormats() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -766,6 +789,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_PivotTableFormats; @@ -781,7 +805,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableStyleInfo) CPivotTableStyleInfo(){} virtual ~CPivotTableStyleInfo() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -797,6 +821,7 @@ namespace OOX if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr toBin(); void fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -823,7 +848,7 @@ namespace OOX WritingElement_XlsbConstructors(CPivotTableLocation) CPivotTableLocation(){} virtual ~CPivotTableLocation() {} - + virtual void fromXML(XmlUtils::CXmlNode& node) { } @@ -840,6 +865,7 @@ namespace OOX return; } void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const { return et_x_PivotTableLocation; @@ -876,12 +902,14 @@ 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_PivotTableDefinition; } - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr writeAttributes(); //---------- nullable<CColumnRowFields> m_oColFields; nullable<CColumnRowItems> m_oColItems; @@ -961,11 +989,11 @@ namespace OOX nullable_bool m_oUseAutoFormatting; nullable_string m_oVacatedStyle; nullable_bool m_oVisualTotals; - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCreatedVersion; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oMinRefreshableVersion; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oUpdatedVersion; - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oDataPosition; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oAutoFormatId; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCacheId; @@ -980,7 +1008,7 @@ namespace OOX CPivotTableFile(OOX::Document* pMain) : OOX::FileGlobalEnumerated(pMain), OOX::IFileContainer(pMain) { m_bSpreadsheets = true; - + m_pData = NULL; m_nDataLength = 0; } @@ -1011,12 +1039,10 @@ namespace OOX memcpy(m_pData, pData, length); } 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; - virtual const OOX::FileType type() const - { - return OOX::Spreadsheet::FileTypes::PivotTable; - } + virtual const OOX::FileType type() const; virtual const CPath DefaultDirectory() const { return type().DefaultDirectory(); diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index dcc4ca17f8d..32e6e7dadf3 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -38,6 +38,7 @@ #include "../../XlsbFormat/PivotTableStream.h" #include "../../XlsbFormat/PivotCacheDefStream.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORDS.h" +#include "../../XlsbFormat/Biff12_records/BeginPivotCacheRecords.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORD.h" #include "../../XlsbFormat/Biff12_unions/PIVOTCACHERECORDDT.h" #include "../../XlsbFormat/Biff12_unions/PCDIDT.h" @@ -59,6 +60,7 @@ #include "../../XlsbFormat/Biff12_records/BeginSXLocation.h" #include "../../XlsbFormat/Biff12_unions/SXVDS.h" #include "../../XlsbFormat/Biff12_unions/SXVD.h" +#include "../../XlsbFormat/Biff12_records/BeginSXVDs.h" #include "../../XlsbFormat/Biff12_records/BeginSXVD.h" #include "../../XlsbFormat/Biff12_unions/SXVIS.h" #include "../../XlsbFormat/Biff12_unions/SXVI.h" @@ -76,7 +78,9 @@ #include "../../XlsbFormat/Biff12_records/BeginISXVDRws.h" #include "../../XlsbFormat/Biff12_records/BeginISXVDCols.h" #include "../../XlsbFormat/Biff12_unions/SXLIRWS.h" +#include "../../XlsbFormat/Biff12_records/BeginSXLIRws.h" #include "../../XlsbFormat/Biff12_unions/SXLICOLS.h" +#include "../../XlsbFormat/Biff12_records/BeginSXLICols.h" #include "../../XlsbFormat/Biff12_unions/SXLI.h" #include "../../XlsbFormat/Biff12_unions/ISXVIS.h" #include "../../XlsbFormat/Biff12_records/BeginSXLI.h" @@ -84,6 +88,7 @@ #include "../../XlsbFormat/Biff12_unions/SXDIS.h" #include "../../XlsbFormat/Biff12_unions/SXDI.h" #include "../../XlsbFormat/Biff12_records/BeginSXDI.h" +#include "../../XlsbFormat/Biff12_records/BeginSXDIs.h" #include "../../XlsbFormat/Biff12_unions/SXFORMATS.h" #include "../../XlsbFormat/Biff12_unions/SXFORMAT.h" #include "../../XlsbFormat/Biff12_records/BeginSXFormat.h" @@ -93,6 +98,7 @@ #include "../../XlsbFormat/Biff12_records/BeginSXPI.h" #include "../../XlsbFormat/Biff12_records/BeginPivotCacheDef.h" #include "../../XlsbFormat/Biff12_unions/PCDFIELDS.h" +#include "../../XlsbFormat/Biff12_records/BeginPCDFields.h" #include "../../XlsbFormat/Biff12_unions/PCDFIELD.h" #include "../../XlsbFormat/Biff12_records/BeginPCDField.h" #include "../../XlsbFormat/Biff12_unions/PCDFATBL.h" @@ -121,6 +127,9 @@ #include "../../XlsbFormat/Biff12_unions/PCDSCSET.h" #include "../../XlsbFormat/Biff12_records/BeginPCDSCSet.h" #include "../../XlsbFormat/Biff12_records/PCRRecord.h" +#include "../../XlsbFormat/Biff12_unions/FRTSXVIEW.h" +#include "../../XlsbFormat/Biff12_unions/SXVIEW14.h" +#include "../../XlsbFormat/Biff12_records/BeginSXView14.h" #include "../../XlsbFormat/Biff12_unions/PNAMES.h" #include "../../XlsbFormat/Biff12_unions/PNAME.h" @@ -133,11 +142,39 @@ #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../ComplexTypes_Spreadsheet.h" +#include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" + +#include <codecvt> +#include "boost/date_time/gregorian/gregorian.hpp" namespace OOX { namespace Spreadsheet { + std::wstring getDateFromExcelTime(double excelDate) + { + boost::gregorian::date date(1899, boost::gregorian::Dec, 30); + XLSB::PCDIDateTime datetime; + _UINT64 days = std::floor(excelDate); + excelDate -= days; + date += boost::gregorian::date_duration(days); + datetime.yr = date.year(); + datetime.mon = date.month(); + datetime.dom = date.day(); + if(excelDate > 0) + { + excelDate *= 24; + datetime.hr = std::floor(excelDate); + excelDate -= datetime.hr; + excelDate *= 60; + datetime.min = std::floor(excelDate); + excelDate -= datetime.min; + datetime.sec = std::floor(excelDate*60); + } + return datetime.value(); + + } + //struct NullDeleter {template<typename T> void operator()(T*) {} }; void CPivotTableFile::readBin(const CPath& oPath) { @@ -159,6 +196,10 @@ namespace Spreadsheet //pivotTableStream.reset(); } } + XLS::BaseObjectPtr CPivotTableFile::WriteBin() const + { + return m_oPivotTableDefinition->toBin(); + } void CPivotTableFile::read(const CPath& oRootPath, const CPath& oPath) { @@ -183,30 +224,44 @@ namespace Spreadsheet } void CPivotTableFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - if(m_oPivotTableDefinition.IsInit()) + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotTableDefinition.IsInit()) { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oPivotTableDefinition->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 ); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); } - else if(m_nDataLength > 0 && m_pData) + else { - NSFile::CFileBinary oFile; - oFile.CreateFileW(oPath.GetPath()); - oFile.WriteFile(m_pData, m_nDataLength); - oFile.CloseFile(); + if(m_oPivotTableDefinition.IsInit()) + { + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + m_oPivotTableDefinition->toXML(sXml); - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + else if(m_nDataLength > 0 && m_pData) + { + 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 ); } + const OOX::FileType CPivotTableFile::type() const + { + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::PivotTableBin; + } + return OOX::Spreadsheet::FileTypes::PivotTable; + } //------------------------------------ void CPivotTableDefinition::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -363,6 +418,308 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (L"extLst" == sName) m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotTableDefinition::toBin() + { + auto ptr(new XLSB::PivotTableStream); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginSXView = writeAttributes(); + if(m_oLocation.IsInit()) + ptr->m_SXLOCATION = m_oLocation->toBin(); + if(m_oPivotFields.IsInit()) + ptr->m_SXVDS = m_oPivotFields->toBin(); + if(m_oRowFields.IsInit()) + ptr->m_ISXVDRWS = m_oRowFields->toBinRows(); + if(m_oColFields.IsInit()) + ptr->m_ISXVDCOLS = m_oColFields->toBinCols(); + if(m_oRowItems.IsInit()) + ptr->m_SXLIRWS = m_oRowItems->toBinRows(); + if(m_oColItems.IsInit()) + ptr->m_SXLICOLS = m_oColItems->toBinCols(); + + if(m_oDataFields.IsInit()) + ptr->m_SXDIS = m_oDataFields->toBin(); + if(m_oFormats.IsInit()) + ptr->m_SXFORMATS = m_oFormats->toBin(); + if(m_oPivotTableStyleInfo.IsInit()) + ptr->m_BrtTableStyleClient = m_oPivotTableStyleInfo->toBin(); + if(m_oPageFields.IsInit()) + ptr->m_SXPIS = m_oPageFields->toBin(); + + /*auto frt(new XLSB::FRTSXVIEW); + auto sxview14(new XLSB::SXVIEW14); + auto beginsxview(new XLSB::BeginSXView14); + ptr->m_FRTSXVIEW = XLS::BaseObjectPtr{frt}; + frt->m_SXVIEW14 = XLS::BaseObjectPtr{sxview14}; + sxview14->m_BrtBeginSXView14 = XLS::BaseObjectPtr{beginsxview}; + beginsxview->fAutoApply = false; + beginsxview->fCalcMembersInAdvFilters = false; + beginsxview->fEnableWB = false; + beginsxview->fFillDownLabelsDefault = false; + beginsxview->fShowValuesRow = false; + beginsxview->sxma.value() = 0; + beginsxview->irstAltText = 0xFFFFFFFF; + beginsxview->irstAltTextSummary = 0xFFFFFFFF; + beginsxview->irstWeight = 0xFFFFFFFF;*/ + + return objectPtr; + } + XLS::BaseObjectPtr CPivotTableDefinition::writeAttributes() + { + auto ptr(new XLSB::BeginSXView); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oApplyBorderFormats.IsInit()) + ptr->ibitAtrBdr = m_oApplyBorderFormats.get(); + else + ptr->ibitAtrBdr = false; + if (m_oApplyFontFormats.IsInit()) + ptr->ibitAtrFnt = m_oApplyFontFormats.get(); + else + ptr->ibitAtrFnt = false; + if (m_oApplyNumberFormats.IsInit()) + ptr->ibitAtrNum = m_oApplyNumberFormats.get(); + else + ptr->ibitAtrNum = false; + if (m_oApplyPatternFormats.IsInit()) + ptr->ibitAtrPat = m_oApplyPatternFormats.get(); + else + ptr->ibitAtrPat = false; + if (m_oApplyWidthHeightFormats.IsInit()) + ptr->ibitAtrProt = m_oApplyWidthHeightFormats.get(); + else + ptr->ibitAtrProt = false; + if (m_oApplyAlignmentFormats.IsInit()) + ptr->ibitAtrAlc = m_oApplyAlignmentFormats.get(); + else + ptr->ibitAtrAlc = false; + + if (m_oAsteriskTotals.IsInit()) + ptr->fHideTotAnnotation = m_oAsteriskTotals.get(); + else + ptr->fHideTotAnnotation = false; + if (m_oVisualTotals.IsInit()) + ptr->fNotVisualTotals = m_oVisualTotals.get(); + else + ptr->fNotVisualTotals = false; + if (m_oAutoFormatId.IsInit()) + ptr->itblAutoFmt = m_oAutoFormatId->GetValue(); + else + ptr->itblAutoFmt = 0; + if (m_oCacheId.IsInit()) + ptr->idCache = m_oCacheId->GetValue(); + if (m_oChartFormat.IsInit()) + ptr->dwCrtFmtId = m_oChartFormat->GetValue(); + else + ptr->dwCrtFmtId = 0; + if (m_oColGrandTotals.IsInit()) + ptr->fColGrand = m_oColGrandTotals.get(); + + if (m_oColHeaderCaption.IsInit()) ptr->irstColHdrName = m_oColHeaderCaption.get(); + else + ptr->fUseColHdrName = false; + if (m_oCompact.IsInit()) + ptr->fDefaultCompact = m_oCompact.get(); + else + ptr->fDefaultCompact = false; + if (m_oCompactData.IsInit()) + ptr->fCompactData = m_oCompactData.get(); + else + ptr->fCompactData = false; + if (m_oCreatedVersion.IsInit()) + ptr->bVerSxMacro = m_oCreatedVersion->GetValue(); + else + ptr->bVerSxMacro = false; + if (m_oCustomListSort.IsInit()) + ptr->fDontUseCustomLists = !m_oCustomListSort.get(); + else + ptr->fDontUseCustomLists = false; + if (m_oDataCaption.IsInit()) + ptr->irstData = m_oDataCaption.get(); + else + ptr->irstData = 0xFFFFFFFF; + if (m_oDataOnRows.IsInit()) + ptr->fDefaultCompact = m_oDataOnRows.get(); + else + ptr->fDefaultCompact = false; + if (m_oDataPosition.IsInit()) + ptr->ipos4Data = m_oDataPosition->GetValue(); + else + ptr->ipos4Data = -1; + if (m_oDisableFieldList.IsInit()) + ptr->fDisableFList = m_oDisableFieldList.get(); + else + ptr->fDisableFList = false; + if (m_oEditData.IsInit()) + ptr->fEnableDataEd = m_oEditData.get(); + else + ptr->fEnableDataEd = false; + if (m_oEnableDrill.IsInit()) + ptr->fEnableDrilldown = m_oEnableDrill.get(); + else + ptr->fEnableDrilldown = false; + if (m_oEnableFieldProperties.IsInit()) + ptr->fEnableFieldDialog = m_oEnableFieldProperties.get(); + else + ptr->fEnableFieldDialog = false; + if (m_oEnableWizard.IsInit()) + ptr->fEnableWizard = m_oEnableWizard.get(); + else + ptr->fEnableWizard = false; + if (m_oErrorCaption.IsInit()) + ptr->irstErrorString = m_oErrorCaption.get(); + else + { + ptr->fEmptyDisplayErrorString = true; + ptr->fDisplayErrorString = false; + } + if (m_oFieldListSortAscending.IsInit()) + ptr->fNonDefaultSortInFlist = m_oFieldListSortAscending.get(); + else + ptr->fNonDefaultSortInFlist = false; + if (m_oFieldPrintTitles.IsInit()) + ptr->fPrintTitles = m_oFieldPrintTitles.get(); + else + ptr->fPrintTitles = false; + if (m_oGrandTotalCaption.IsInit()) + ptr->irstGrand = m_oGrandTotalCaption.get(); + else + ptr->fDisplayGrand = false; + if (m_oGridDropZones.IsInit()) + ptr->fNewDropZones = !m_oGridDropZones.get(); + else + ptr->fNewDropZones = false; + if (m_oImmersive.IsInit()) + ptr->fTurnOffImmersive = m_oImmersive.get(); + else + ptr->fTurnOffImmersive = false; + if (m_oIndent.IsInit()) + ptr->cIndentInc = m_oIndent->GetValue(); + else + ptr->cIndentInc = false; + if (m_oItemPrintTitles.IsInit()) + ptr->fRepeatItemsOnEachPrintedPage = m_oItemPrintTitles.get(); + else + ptr->fRepeatItemsOnEachPrintedPage = false; + if (m_oMdxSubqueries.IsInit()) + ptr->fDefaultCompact = m_oMdxSubqueries.get(); + else + ptr->fDefaultCompact = false; + if (m_oMergeItem.IsInit()) + ptr->fMergeLabels = m_oMergeItem.get(); + else + ptr->fMergeLabels = false; + if (m_oMinRefreshableVersion.IsInit()) + ptr->bVerSxUpdateableMin = m_oMinRefreshableVersion->GetValue(); + if (m_oMissingCaption.IsInit()) + ptr->irstNullString = m_oMissingCaption.get(); + else + ptr->fEmptyDisplayNullString = true; + if (m_oMultipleFieldFilters.IsInit()) + ptr->fSingleFilterPerField = !m_oMultipleFieldFilters.get(); + if (m_oName.IsInit()) ptr->irstName = m_oName.get(); + else + ptr->irstName = 0xFFFFFFFF; + if (m_oOutline.IsInit()) + ptr->fDefaultOutline = m_oOutline.get(); + if (m_oOutlineData.IsInit()) + ptr->fOutlineData = m_oOutlineData.get(); + else + ptr->fOutlineData = false; + if (m_oPageOverThenDown.IsInit()) + ptr->fAcrossPageLay = m_oPageOverThenDown.get(); + else + ptr->fAcrossPageLay = false; + if (m_oPageStyle.IsInit()) + ptr->irstPageFieldStyle = m_oPageStyle.get(); + else + ptr->fDisplayPageFieldStyle = false; + if (m_oPageWrap.IsInit()) + ptr->cWrapPage = m_oPageWrap->GetValue(); + else + ptr->cWrapPage = 0; + if (m_oPivotTableStyle.IsInit()) + ptr->irstTableStyle = m_oPivotTableStyle.get(); + else + ptr->fDisplayTableStyle = false; + if (m_oPreserveFormatting.IsInit()) + ptr->fPreserveFormatting = m_oPreserveFormatting.get(); + if (m_oPrintDrill.IsInit()) + ptr->fPrintDrillIndicators = m_oPrintDrill.get(); + else + ptr->fPrintDrillIndicators = false; + if (m_oPublished.IsInit()) + ptr->fPublished = m_oPublished.get(); + else + ptr->fPublished = false; + if (m_oRowGrandTotals.IsInit()) + ptr->fRwGrand = m_oRowGrandTotals.get(); + if (m_oRowHeaderCaption.IsInit()) + ptr->irstRwHdrName = m_oRowHeaderCaption.get(); + else + ptr->fUseRwHdrName = false; + if (m_oShowCalcMbrs.IsInit()) + ptr->fNotViewCalculatedMembers = !m_oShowCalcMbrs.get(); + else + ptr->fNotViewCalculatedMembers = false; + if (m_oShowDataDropDown.IsInit()) + ptr->fHideDDData = !m_oShowDataDropDown.get(); + else + ptr->fHideDDData = false; + if (m_oShowDataTips.IsInit()) + ptr->fNoPivotTips = !m_oShowDataTips.get(); + else + ptr->fNoPivotTips = false; + if (m_oShowDrill.IsInit()) + ptr->fHideDrillIndicators = !m_oShowDrill.get(); + else + ptr->fHideDrillIndicators = false; + if (m_oShowDropZones.IsInit()) + ptr->fNoStencil = !m_oShowDropZones.get(); + else + ptr->fNoStencil = false; + if (m_oShowEmptyCol.IsInit()) + ptr->fIncludeEmptyCol = m_oShowEmptyCol.get(); + else + ptr->fIncludeEmptyCol = false; + if (m_oShowEmptyRow.IsInit()) + ptr->fIncludeEmptyRw = m_oShowEmptyRow.get(); + else + ptr->fIncludeEmptyRw = false; + if (m_oShowError.IsInit()) + ptr->fDisplayErrorString = m_oShowError.get(); + if (m_oShowHeaders.IsInit()) + ptr->fNoHeaders = !m_oShowHeaders.get(); + else + ptr->fNoHeaders = false; + if (m_oShowItems.IsInit()) + ptr->fDisplayImmediateItems = m_oShowItems.get(); + if (m_oShowMemberPropertyTips.IsInit()) + ptr->fMemPropsInTips = m_oShowMemberPropertyTips.get(); + if (m_oShowMissing.IsInit()) + ptr->fDisplayNullString = m_oShowMissing.get(); + if (m_oShowMultipleLabel.IsInit()) + ptr->fPageMultipleItemLabel = m_oShowMultipleLabel.get(); + if (m_oSubtotalHiddenItems.IsInit()) + ptr->fSubtotalHiddenPageItems = m_oSubtotalHiddenItems.get(); + else + ptr->fSubtotalHiddenPageItems = false; + if (m_oTag.IsInit()) + ptr->irstTag = m_oTag.get(); + else + ptr->fDisplayTag = false; + if (m_oUpdatedVersion.IsInit()) + ptr->bVerSxLastUpdated = m_oUpdatedVersion->GetValue(); + if (m_oUseAutoFormatting.IsInit()) + ptr->fAutoFormat = m_oUseAutoFormatting.get(); + if (m_oVacatedStyle.IsInit()) + ptr->irstVacateStyle = m_oVacatedStyle.get(); + else + ptr->fDisplayVacateStyle = false; + ptr->sxaxis4Data = 2; + ptr->fReenterOnLoadOnce = false; + + return objectPtr; + } void CPivotTableDefinition::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PivotTableStream*>(obj.get()); @@ -400,6 +757,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->m_SXPIS != nullptr) m_oPageFields = ptr->m_SXPIS; + if(ptr->m_FRTSXVIEW) + { + auto result = static_cast<XLSB::FRTSXVIEW*>(ptr->m_FRTSXVIEW.get()); + auto result2 = static_cast<XLSB::SXVIEW14*>(result->m_SXVIEW14.get()); + auto result3 = static_cast<XLSB::BeginSXView14*>(result2->m_BrtBeginSXView14.get()); + auto result4 = result3; + } } } void CPivotTableDefinition::ReadAttributes(XLS::BaseObjectPtr& obj) @@ -754,6 +1118,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CColumnRowFields::toBinRows() + { + auto ptr(new XLSB::ISXVDRWS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginISXVDRws); + ptr->m_BrtBeginISXVDRws = XLS::BaseObjectPtr{ptr1}; + if(m_oCount.IsInit()) + ptr1->cisxvd = m_oCount->GetValue(); + else + ptr1->cisxvd = m_arrItems.size(); + for(auto i:m_arrItems) + ptr1->rgisxvdrws.push_back(i->m_oX.get()); + return objectPtr; + } + XLS::BaseObjectPtr CColumnRowFields::toBinCols() + { + auto ptr(new XLSB::ISXVDCOLS); + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginISXVDCols); + ptr->m_BrtBeginISXVDCols = XLS::BaseObjectPtr{ptr1}; + if(m_oCount.IsInit()) + ptr1->cisxvd = m_oCount->GetValue(); + else + ptr1->cisxvd = m_arrItems.size(); + for(auto i:m_arrItems) + ptr1->rgisxvdcols.push_back(i->m_oX.get()); + return objectPtr; + } void CColumnRowFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -799,6 +1191,28 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CColumnRowItems::toBinRows() + { + auto ptr(new XLSB::SXLIRWS); + auto ptr1(new XLSB::BeginSXLIRws); + ptr1->csxlis = m_arrItems.size(); + ptr->m_BrtBeginSXLIRws = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXLI.push_back(i->toBin()); + return objectPtr; + } + XLS::BaseObjectPtr CColumnRowItems::toBinCols() + { + auto ptr(new XLSB::SXLICOLS); + auto ptr1(new XLSB::BeginSXLICols); + ptr1->csxlis = m_arrItems.size(); + ptr->m_BrtBeginSXLICols = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXLI.push_back(i->toBin()); + return objectPtr; + } void CColumnRowItems::fromBin(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeSXLIRWS) @@ -860,6 +1274,78 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CSharedItemsIndex>(oReader)); } } + XLS::BaseObjectPtr CColumnRowItem::toBin() + { + auto ptr(new XLSB::SXLI); + + XLS::BaseObjectPtr objectPtr(ptr); + auto ptr1(new XLSB::BeginSXLI); + ptr1->cisxvis = m_arrItems.size(); + ptr->m_BrtBeginSXLI = XLS::BaseObjectPtr{ptr1}; + if(m_oI.IsInit()) + ptr1->iData = m_oI->GetValue(); + else + ptr1->iData = 0; + if(m_oR.IsInit()) + ptr1->cSic = m_oR->GetValue(); + else + ptr1->cSic = 0; + if(m_oT.IsInit()) + { + if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeData) + ptr1->itmtype = XLSB::PivotItemType::PITDATA; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeDefault) + ptr1->itmtype = XLSB::PivotItemType::PITDEFAULT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeSum) + ptr1->itmtype = XLSB::PivotItemType::PITSUM; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeCountA) + ptr1->itmtype = XLSB::PivotItemType::PITCOUNTA; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeAverage) + ptr1->itmtype = XLSB::PivotItemType::PITAVG; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeMax) + ptr1->itmtype = XLSB::PivotItemType::PITMAX; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeMin) + ptr1->itmtype = XLSB::PivotItemType::PITMIN; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeProduct) + ptr1->itmtype = XLSB::PivotItemType::PITPRODUCT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeCount) + ptr1->itmtype = XLSB::PivotItemType::PITCOUNT; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDev) + ptr1->itmtype = XLSB::PivotItemType::PITSTDDEV; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDevP) + ptr1->itmtype = XLSB::PivotItemType::PITSTDDEVP; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeVar) + ptr1->itmtype = XLSB::PivotItemType::PITVAR; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeVarP) + ptr1->itmtype = XLSB::PivotItemType::PITVARP; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeGrandTotalt) + ptr1->itmtype = XLSB::PivotItemType::PITGRAND; + else if (m_oT == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) + ptr1->itmtype = XLSB::PivotItemType::PITBLANK; + } + else + { + ptr1->itmtype = XLSB::PivotItemType::PITDEFAULT; + } + + if(ptr1->cisxvis > 0) + { + + auto ptr2(new XLSB::ISXVIS(ptr1->cisxvis)); + ptr2->_cisxvis = ptr1->cisxvis; + + ptr->m_ISXVIS = XLS::BaseObjectPtr{ptr2}; + auto ptr3(new XLSB::BeginISXVIs(ptr1->cisxvis)); + ptr2->m_BrtBeginISXVIs = XLS::BaseObjectPtr{ptr3}; + + for(auto i:m_arrItems) + if(i->m_oV.IsInit()) + ptr3->rgisxvis.push_back(i->m_oV->GetValue()); + else + ptr3->rgisxvis.push_back(0); + } + return objectPtr; + } void CColumnRowItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SXLI*>(obj.get()); @@ -1007,6 +1493,17 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CDataFields::toBin() + { + auto ptr(new XLSB::SXDIS); + auto ptr1(new XLSB::BeginSXDIs); + ptr->m_BrtBeginSXDIs = XLS::BaseObjectPtr{ptr1}; + ptr1->csxdis = m_arrItems.size(); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXDI.push_back(i->toBin()); + return objectPtr; + } void CDataFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1042,6 +1539,92 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CDataField::toBin() + { + auto ptr1(new XLSB::SXDI); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXDI); + ptr1->m_BrtBeginSXDI = XLS::BaseObjectPtr{ptr}; + + if(m_oBaseField.IsInit()) + ptr->isxvd = m_oBaseField.get(); + else + ptr->isxvd = 0; + if(m_oBaseItem.IsInit()) + ptr->isxvi = m_oBaseItem->GetValue(); + else + ptr->isxvi = 0; + if(m_oFld.IsInit()) + ptr->isxvdData = m_oFld->GetValue(); + else + ptr->isxvdData = false; + if(m_oNumFmtId.IsInit()) + ptr->ifmt.ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt.ifmt = 0; + if(m_oName.IsInit()) + { + ptr->stDisplayName = m_oName.get(); + ptr->fLoadDisplayName = true; + } + else + ptr->fLoadDisplayName = false; + if(m_oShowDataAs.IsInit()) + { + if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsNormal) + ptr->df = XLSB::ShowDataAs::NORMAL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsDifference) + ptr->df = XLSB::ShowDataAs::DIFFERENCE_; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOff) + ptr->df = XLSB::ShowDataAs::PERCENT; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentDiff) + ptr->df = XLSB::ShowDataAs::PERCENTDIFF; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsIndex) + ptr->df = XLSB::ShowDataAs::INDEX; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfTotal) + ptr->df = XLSB::ShowDataAs::PERCENTOFTOTAL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfCol) + ptr->df = XLSB::ShowDataAs::PERCENTOFCOL; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsPercentOfRow) + ptr->df = XLSB::ShowDataAs::PERCENTOFROW; + else if (m_oShowDataAs == SimpleTypes::Spreadsheet::EShowDataAs::dataAsRunTotal) + ptr->df = XLSB::ShowDataAs::PERCENTOFRUNTOTAL; + } + else + { + ptr->df = XLSB::ShowDataAs::NORMAL; + } + if(m_oSubtotal.IsInit()) + { + if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionSum) + ptr->iiftab = XLSB::DataConsolidationFunction::SUM; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionCount) + ptr->iiftab = XLSB::DataConsolidationFunction::COUNT; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionAverage) + ptr->iiftab = XLSB::DataConsolidationFunction::AVERAGE; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionMaximum) + ptr->iiftab = XLSB::DataConsolidationFunction::MAX; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionMinimum) + ptr->iiftab = XLSB::DataConsolidationFunction::MIN; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionProduct) + ptr->iiftab = XLSB::DataConsolidationFunction::PRODUCT; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionCountNums) + ptr->iiftab = XLSB::DataConsolidationFunction::COUNTNUM; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionStdDev) + ptr->iiftab = XLSB::DataConsolidationFunction::STDDEV; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionStdDevP) + ptr->iiftab = XLSB::DataConsolidationFunction::STDDEVP; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionVariance) + ptr->iiftab = XLSB::DataConsolidationFunction::STDVAR; + else if (m_oSubtotal == SimpleTypes::Spreadsheet::EDataConsolidateFunction::functionVarP) + ptr->iiftab = XLSB::DataConsolidationFunction::STDVARP; + } + else + { + ptr->iiftab = XLSB::DataConsolidationFunction::SUM; + } + return objectPtr; + } void CDataField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SXDI*>(obj.get()); @@ -1203,6 +1786,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPageFields::toBin() + { + auto ptr(new XLSB::SXPIS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXPI.push_back(i->toBin()); + return objectPtr; + } void CPageFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1236,6 +1827,29 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPageField::toBin() + { + auto ptr1(new XLSB::SXPI); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXPI); + ptr1->m_BrtBeginSXPI = XLS::BaseObjectPtr{ptr}; + + if(m_oFld.IsInit()) + ptr->isxvd = m_oFld.get(); + if(m_oItem.IsInit()) + ptr->isxvi = m_oItem->GetValue(); + if(m_oHier.IsInit()) + ptr->isxth = m_oHier.get(); + if(m_oName.IsInit()) + ptr->irstUnique = m_oName.get(); + else + ptr->irstUnique = 0xFFFFFFFF; + if(m_oCap.IsInit()) + ptr->irstDisplay = m_oCap.get(); + else + ptr->irstDisplay = 0xFFFFFFFF; + return objectPtr; + } void CPageField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SXPI*>(obj.get()); @@ -1328,6 +1942,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CFieldItems::toBin() + { + auto ptr(new XLSB::SXVIS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXVI.push_back(i->toBin()); + return objectPtr; + } void CFieldItems::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1358,6 +1980,96 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CFieldItem::toBin()// fix name init + { + auto ptr1(new XLSB::SXVI); + XLS::BaseObjectPtr objectPtr(ptr1); + + auto ptr(new XLSB::BeginSXVI); + ptr1->m_BrtBeginSXVI = XLS::BaseObjectPtr{ptr}; + + if(m_oChild.IsInit()) + ptr->fHasChildrenEst = m_oChild.get(); + else + ptr->fHasChildrenEst = false; + if(m_oExpanded.IsInit()) + ptr->fDrilledMember = m_oExpanded.get(); + else + ptr->fDrilledMember = false; + if(m_oDrillAcross.IsInit()) + ptr->fCollapsedMember = m_oDrillAcross.get(); + else + ptr->fCollapsedMember = false; + if(m_oCalculated.IsInit()) + ptr->fFormula = m_oCalculated.get(); + else + ptr->fFormula = false; + if(m_oHidden.IsInit()) + ptr->fHidden = m_oHidden.get(); + else + ptr->fHidden = false; + if(m_oMissing.IsInit()) + ptr->fMissing = m_oMissing.get(); + else + ptr->fMissing = false; + if(m_oUserCaption.IsInit()) + { + ptr->displayName = m_oUserCaption.get(); + ptr->fDisplayName = true; + } + else + { + ptr->fDisplayName = false; + } + if(m_oCharacter.IsInit()) + ptr->fOlapFilterSelected = m_oCharacter.get(); + else + ptr->fOlapFilterSelected = false; + if(m_oHideDetails.IsInit()) + ptr->fHideDetail = m_oHideDetails.get(); + else + ptr->fHideDetail = false; + if(m_oItemIndex.IsInit()) + ptr->iCache = m_oItemIndex->GetValue(); + else + ptr->iCache = 0; + if(m_oItemType.IsInit()) + { + if(m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeData) + ptr->itmtype = XLSB::PivotItemType::PITDATA; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeDefault) + ptr->itmtype = XLSB::PivotItemType::PITDEFAULT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeSum) + ptr->itmtype = XLSB::PivotItemType::PITSUM; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeCountA) + ptr->itmtype = XLSB::PivotItemType::PITCOUNTA; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeAverage) + ptr->itmtype = XLSB::PivotItemType::PITAVG; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeMax) + ptr->itmtype = XLSB::PivotItemType::PITMAX; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeMin) + ptr->itmtype = XLSB::PivotItemType::PITMIN; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeProduct) + ptr->itmtype = XLSB::PivotItemType::PITPRODUCT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeCount) + ptr->itmtype = XLSB::PivotItemType::PITCOUNT; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDev) + ptr->itmtype = XLSB::PivotItemType::PITSTDDEV; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeStdDevP) + ptr->itmtype = XLSB::PivotItemType::PITSTDDEVP; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeVar) + ptr->itmtype = XLSB::PivotItemType::PITVAR; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeVarP) + ptr->itmtype = XLSB::PivotItemType::PITVARP; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeGrandTotalt) + ptr->itmtype = XLSB::PivotItemType::PITGRAND; + else if (m_oItemType == SimpleTypes::Spreadsheet::EPivotItemType::typeBlank) + ptr->itmtype = XLSB::PivotItemType::PITBLANK; + } + else + ptr->itmtype = XLSB::PivotItemType::PITDATA; + return objectPtr; + } void CFieldItem::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SXVI*>(obj.get()); @@ -1520,7 +2232,17 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(new CPivotField(item)); } } - + XLS::BaseObjectPtr CPivotFields::toBin() + { + auto ptr(new XLSB::SXVDS); + auto ptr1(new XLSB::BeginSXVDs); + ptr1->csxvds = m_arrItems.size(); + ptr->m_BrtBeginSXVDs = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXVD.push_back(i->toBin()); + return objectPtr; + } void CPivotFields::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -1626,6 +2348,276 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //m_oExtLst = ptr->m_FRTSXVD; } } + XLS::BaseObjectPtr CPivotField::toBin() + { + auto ptr(new XLSB::SXVD); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginSXVD = writeAttributes(); + if(m_oItems.IsInit()) + ptr->m_SXVIS = m_oItems->toBin(); + if(m_oAutoSortScope.IsInit()) + ptr->m_AUTOSORTSCOPE = m_oAutoSortScope->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotField::writeAttributes() + { + auto ptr(new XLSB::BeginSXVD); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oAllDrilled.IsInit()) + ptr->fDrilledLevel = m_oAllDrilled.get(); + else + ptr->fDrilledLevel = false; + + if(m_oAutoShow.IsInit()) + ptr->fAutoShow = m_oAutoShow.get(); + else + ptr->fAutoShow = false; + + if(m_oAvgSubtotal.IsInit()) + ptr->fAverage = m_oAvgSubtotal.get(); + else + ptr->fAverage = false; + + ptr->sxaxis.bCol = false; + ptr->sxaxis.bPage = false; + ptr->sxaxis.bRw = false; + ptr->sxaxis.bData = false; + + if(m_oAxis.IsInit()) + { + if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) + ptr->sxaxis.bCol = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisPage) + ptr->sxaxis.bPage = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + ptr->sxaxis.bRw = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) + ptr->sxaxis.bData = true; + } + if(m_oCompact.IsInit()) + ptr->fCompact = m_oCompact.get(); + else + ptr->fCompact = true; + + if(m_oCountASubtotal.IsInit()) + ptr->fCounta = m_oCountASubtotal.get(); + else + ptr->fCounta = false; + + if(m_oCountSubtotal.IsInit()) + ptr->fCount = m_oCountSubtotal.get(); + else + ptr->fCount = false; + if(m_oDataField.IsInit()) + ptr->sxaxis.bData = m_oDataField.get(); + + if(m_oDataSourceSort.IsInit()) + ptr->fTensorSort = m_oDataSourceSort.get(); + else + ptr->fTensorSort = false; + if(m_oDefaultAttributeDrillState.IsInit()) + ptr->fItemsDrilledByDefault = m_oDefaultAttributeDrillState.get(); + else + ptr->fItemsDrilledByDefault = false; + if(m_oDefaultSubtotal.IsInit()) + ptr->fDefault = m_oDefaultSubtotal.get(); + else + ptr->fDefault = false; + if(m_oDragOff.IsInit()) + ptr->fDragToHide = m_oDragOff.get(); + else + ptr->fDragToHide = true; + + if (m_oDragToCol.IsInit()) + ptr->fDragToColumn = m_oDragToCol.get(); + else + ptr->fDragToColumn = true; + if (m_oDragToData.IsInit()) + ptr->fDragToData = m_oDragToData.get(); + else + ptr->fDragToData = true; + if (m_oDragToPage.IsInit()) + ptr->fDragToPage = m_oDragToPage.get(); + else + ptr->fDragToPage = true; + if (m_oDragToRow.IsInit()) + ptr->fDragToRow = m_oDragToRow.get(); + else + ptr->fDragToRow = true; + if (m_oHiddenLevel.IsInit()) + ptr->fHiddenLvl = m_oHiddenLevel.get(); + else + ptr->fHiddenLvl = false; + if (m_oHideNewItems.IsInit()) + ptr->fHideNewItems = m_oHideNewItems.get(); + else + ptr->fHideNewItems = false; + if (m_oIncludeNewItemsInFilter.IsInit()) + ptr->fFilterInclusive = m_oIncludeNewItemsInFilter.get(); + else + ptr->fFilterInclusive = true; + if (m_oInsertBlankRow.IsInit()) + ptr->fInsertBlankRow = m_oInsertBlankRow.get(); + else + ptr->fInsertBlankRow = false; + if (m_oInsertPageBreak.IsInit()) + ptr->fPageBreaksBetweenItems = m_oInsertPageBreak.get(); + else + ptr->fPageBreaksBetweenItems = false; + + if(m_oItemPageCount.IsInit()) + ptr->citmAutoShow = m_oItemPageCount->GetValue(); + else + ptr->citmAutoShow = 10; + + if(m_oMaxSubtotal.IsInit()) + ptr->fMax = m_oMaxSubtotal.get(); + else + ptr->fMax = false; + + if(m_oMeasureFilter.IsInit()) + ptr->fHasAdvFilter = m_oMeasureFilter.get(); + else + ptr->fHasAdvFilter = false; + + if(m_oMinSubtotal.IsInit()) + ptr->fMin = m_oMinSubtotal.get(); + else + ptr->fMin = false; + + if(m_oMultipleItemSelectionAllowed.IsInit()) + ptr->fEnableMultiplePageItems = m_oMultipleItemSelectionAllowed.get(); + else + ptr->fEnableMultiplePageItems = false; + + if(m_oName.IsInit()) + ptr->irstName = m_oName.get(); + else + ptr->fDisplayName = false; + + + if (m_oNonAutoSortDefault.IsInit()) + ptr->fNotAutoSortDft = m_oNonAutoSortDefault.get(); + else + ptr->fNotAutoSortDft = false; + + if (m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt = 0; + + if (m_oOutline.IsInit()) + ptr->fOutline = m_oOutline.get(); + else + ptr->fOutline = true; + + if (m_oProductSubtotal.IsInit()) + ptr->fProduct = m_oProductSubtotal.get(); + else + ptr->fProduct = false; + + if (m_oRankBy.IsInit()) + ptr->isxdiAutoShow = m_oRankBy->GetValue(); + else + ptr->isxdiAutoShow = -1; + + if (m_oServerField.IsInit()) + ptr->fServerBased = m_oServerField.get(); + else + ptr->fServerBased = false; + + if (m_oShowAll.IsInit()) + ptr->fShowAllItems = m_oShowAll.get(); + else + ptr->fShowAllItems = false; + + if (m_oShowDropDowns.IsInit()) + ptr->fHideDD = !m_oShowDropDowns.get(); + else + ptr->fHideDD = false; + + if (m_oShowPropAsCaption.IsInit()) + ptr->fMemPropDisplayInCaption = m_oShowPropAsCaption.get(); + else + ptr->fMemPropDisplayInCaption = false; + + if (m_oShowPropCell.IsInit()) + ptr->fMemPropDisplayInReport = m_oShowPropCell.get(); + else + ptr->fMemPropDisplayInReport = false; + + if (m_oShowPropTip.IsInit()) + ptr->fMemPropDisplayInTip = m_oShowPropTip.get(); + else + ptr->fMemPropDisplayInTip = false; + if(m_oNonAutoSortDefault.IsInit()) + ptr->fAutoSort = !m_oNonAutoSortDefault.get(); + else + ptr->fAutoSort = false; + if(m_oSortType.IsInit()) + { + if(m_oSortType->GetValue() == SimpleTypes::Spreadsheet::EFieldSortType::sortAscending) + ptr->fAscendSort = true; + else + ptr->fAscendSort = false; + } + else + ptr->fAscendSort = false; + + if (m_oStdDevPSubtotal.IsInit()) + ptr->fStdevp = m_oStdDevPSubtotal.get(); + else + ptr->fStdevp = false; + + if (m_oStdDevSubtotal.IsInit()) + ptr->fStdev = m_oStdDevSubtotal.get(); + else + ptr->fStdev = false; + + if (m_oSubtotalCaption.IsInit()) + ptr->irstSub.value() = m_oSubtotalCaption.get(); + else + ptr->fDisplaySub = false; + + if (m_oSubtotalTop.IsInit()) + ptr->fSubtotalAtTop = !m_oSubtotalTop.get(); + else + ptr->fSubtotalAtTop = true; + + if (m_oSumSubtotal.IsInit()) + ptr->fSum = m_oSumSubtotal.get(); + else + ptr->fSum = false; + + if (m_oTopAutoShow.IsInit()) + ptr->fTopAutoShow = !m_oTopAutoShow.get(); + else + ptr->fTopAutoShow = true; + + if (m_oUniqueMemberProperty.IsInit()) + ptr->irstMemberPropertyCaption = m_oUniqueMemberProperty.get(); + else + ptr->fUseMemPropCaption = false; + + if (m_oVarPSubtotal.IsInit()) + ptr->fVarp = m_oVarPSubtotal.get(); + else + ptr->fVarp = false; + + if (m_oVarSubtotal.IsInit()) + ptr->fVar = m_oVarSubtotal.get(); + else + ptr->fVar = false; + if(!ptr->fVar && !ptr->fVarp && !ptr->fStdevp && !ptr->fStdevp + && !ptr->fCount && !ptr->fMin && !ptr->fMax && !ptr->fAverage + && !ptr->fCounta && !ptr->fSum ) + ptr->fDefault = true; + else + ptr->fDefault = false; + + return objectPtr; + } void CPivotField::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::BeginSXVD*>(obj.get()); @@ -1756,7 +2748,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else m_oSortType = SimpleTypes::Spreadsheet::EFieldSortType::sortAscending; - if(ptr->fStdevp) m_oStdDevPSubtotal = ptr->fStdevp; @@ -1876,6 +2867,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CReferences::toBin() + { + auto ptr(new XLSB::PRFILTERS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPRFILTER.push_back(i->toBin()); + return objectPtr; + } void CReferences::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PRFILTERS*>(obj.get()); @@ -1961,7 +2960,100 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CReference::toBin() + { + auto ptr(new XLSB::PRFILTER); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPRFilter = writeAttributes(); + if(m_oX.IsInit()) + ptr->m_arPRFITEM.push_back(m_oX->toBinPrfItem()); + return objectPtr; + } + XLS::BaseObjectPtr CReference::writeAttributes() + { + auto ptr(new XLSB::BeginPRFilter); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oAvgSubtotal.IsInit()) + ptr->prFilter.itmtypeAVERAGE = m_oAvgSubtotal.get(); + else + ptr->prFilter.itmtypeAVERAGE = false; + + if (m_oCountASubtotal.IsInit()) + ptr->prFilter.itmtypeCOUNTA = m_oCountASubtotal.get(); + else + ptr->prFilter.itmtypeCOUNTA = false; + + if (m_oCountSubtotal.IsInit()) + ptr->prFilter.itmtypeCOUNT = m_oCountSubtotal.get(); + else + ptr->prFilter.itmtypeCOUNT = false; + + if (m_oDefaultSubtotal.IsInit()) + ptr->prFilter.itmtypeDEFAULT = m_oDefaultSubtotal.get(); + else + ptr->prFilter.itmtypeDEFAULT = false; + + if (m_oMaxSubtotal.IsInit()) + ptr->prFilter.itmtypeMAX = m_oMaxSubtotal.get(); + else + ptr->prFilter.itmtypeMAX = false; + + if (m_oMinSubtotal.IsInit()) + ptr->prFilter.itmtypeMIN = m_oMinSubtotal.get(); + else + ptr->prFilter.itmtypeMIN = false; + + if (m_oProductSubtotal.IsInit()) + ptr->prFilter.itmtypePRODUCT = m_oProductSubtotal.get(); + else + ptr->prFilter.itmtypePRODUCT = false; + + if (m_oRelative.IsInit()) + ptr->prFilter.itmtypeAVERAGE = m_oRelative.get(); + else + ptr->prFilter.itmtypeAVERAGE = false; + + if (m_oSelected.IsInit()) + ptr->prFilter.fSelected = m_oSelected.get(); + else + ptr->prFilter.fSelected = false; + + if (m_oStdDevPSubtotal.IsInit()) + ptr->prFilter.itmtypeSTDEVP = m_oStdDevPSubtotal.get(); + else + ptr->prFilter.itmtypeSTDEVP = false; + + if (m_oStdDevSubtotal.IsInit()) + ptr->prFilter.itmtypeSTDEV = m_oStdDevSubtotal.get(); + else + ptr->prFilter.itmtypeSTDEV = false; + if (m_oSumSubtotal.IsInit()) + ptr->prFilter.itmtypeSUM = m_oSumSubtotal.get(); + else + ptr->prFilter.itmtypeSUM = false; + + if (m_oVarPSubtotal.IsInit()) + ptr->prFilter.itmtypeVARP = m_oVarPSubtotal.get(); + else + ptr->prFilter.itmtypeVARP = false; + + if (m_oVarSubtotal.IsInit()) + ptr->prFilter.itmtypeVAR = m_oVarSubtotal.get(); + else + ptr->prFilter.itmtypeVAR = false; + + if (m_oField.IsInit()) + ptr->prFilter.isxvd = m_oField->GetValue(); + else + ptr->prFilter.isxvd = 0; + + if (m_oCount.IsInit()) + ptr->prFilter.cItems = m_oCount->GetValue(); + else + ptr->prFilter.cItems = 0; + return objectPtr; + } void CReference::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::BeginPRFilter*>(obj.get()); @@ -2062,6 +3154,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPivotTableFormats::toBin() + { + auto ptr(new XLSB::SXFORMATS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arSXFORMAT.push_back(i->toBin()); + return objectPtr; + } void CPivotTableFormats::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -2100,6 +3200,26 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotTableFormat::toBin() + { + auto ptr(new XLSB::SXFORMAT); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::BeginSXFormat); + ptr->m_BrtBeginSXFormat = XLS::BaseObjectPtr{ptr1}; + if(m_oDxfId.IsInit()) + ptr1->dxfid = m_oDxfId->GetValue(); + else + ptr1->dxfid = 0; + if(m_oAction.IsInit()) + ptr1->rlType = m_oAction->GetValue(); + else + ptr1->rlType = 0; + + if(m_oPivotArea.IsInit()) + ptr->m_PIVOTRULE = m_oPivotArea->toBin(); + return objectPtr; + } void CPivotTableFormat::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SXFORMAT*>(obj.get()); @@ -2166,6 +3286,13 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oPivotArea = ptr->m_PIVOTRULE; } } + XLS::BaseObjectPtr CAutoSortScope::toBin() + { + auto ptr(new XLSB::AUTOSORTSCOPE); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_PIVOTRULE = m_oPivotArea->toBin(); + return objectPtr; + } //------------------------------------ void CPivotArea::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -2207,6 +3334,94 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotArea::toBin() + { + auto ptr(new XLSB::PIVOTRULE); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPRule = writeAttribures(); + if(m_oReferences.IsInit()) + ptr->m_PRFILTERS = m_oReferences->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotArea::writeAttribures() + { + auto ptr(new XLSB::BeginPRule); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->pruleheaderdata.sxaxis.bCol = false; + ptr->pruleheaderdata.sxaxis.bPage = false; + ptr->pruleheaderdata.sxaxis.bRw = false; + ptr->pruleheaderdata.sxaxis.bData = false; + if(m_oAxis.IsInit()) + { + if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisCol) + ptr->pruleheaderdata.sxaxis.bCol = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisPage) + ptr->pruleheaderdata.sxaxis.bPage = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisRow) + ptr->pruleheaderdata.sxaxis.bRw = true; + else if(m_oAxis == SimpleTypes::Spreadsheet::EPivotAxisType::axisValues) + ptr->pruleheaderdata.sxaxis.bData = true; + } + if(m_oCacheIndex.IsInit()) + ptr->pruleheaderdata.fCacheBased = m_oCacheIndex.get(); + else + ptr->pruleheaderdata.fCacheBased = false; + if(m_oCollapsedLevelsAreSubtotals.IsInit()) + ptr->pruleheaderdata.fFuzzy = m_oCollapsedLevelsAreSubtotals.get(); + else + ptr->pruleheaderdata.fFuzzy = false; + if(m_oDataOnly.IsInit()) + ptr->pruleheaderdata.fDataOnly = m_oDataOnly.get(); + else + ptr->pruleheaderdata.fDataOnly = true; + if(m_oField.IsInit()) + ptr->pruleheaderdata.isxvd = m_oField.get(); + else + ptr->pruleheaderdata.isxvd = -1; + if(m_oFieldPosition.IsInit()) + ptr->pruleheaderdata.iDim = m_oFieldPosition->GetValue(); + else + ptr->pruleheaderdata.iDim = 0; + if(m_oGrandCol.IsInit()) + ptr->pruleheaderdata.fGrandCol = m_oGrandCol.get(); + else + ptr->pruleheaderdata.fGrandCol = false; + if(m_oGrandRow.IsInit()) + ptr->pruleheaderdata.fGrandRw = m_oGrandRow.get(); + else + ptr->pruleheaderdata.fGrandRw = false; + if(m_oLabelOnly.IsInit()) + ptr->pruleheaderdata.fLabelOnly = m_oLabelOnly.get(); + else + ptr->pruleheaderdata.fLabelOnly = false; + if(m_oOffsetRef.IsInit()) + ptr->pruleheaderdata.rfxLoc = m_oOffsetRef.get(); + if(m_oOutline.IsInit()) + ptr->pruleheaderdata.fLineMode = m_oOutline.get(); + else + ptr->pruleheaderdata.fLineMode = false; + ptr->pruleheaderdata.fPart = false; + if(m_oType.IsInit()) + { + if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaNone) + ptr->pruleheaderdata.isxrtype = 0x00; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaNormal) + ptr->pruleheaderdata.isxrtype = 0x01; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaData) + ptr->pruleheaderdata.isxrtype = 0x02; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaAll) + ptr->pruleheaderdata.isxrtype = 0x03; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaOrigin) + ptr->pruleheaderdata.isxrtype = 0x04; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaFieldButton) + ptr->pruleheaderdata.isxrtype = 0x05; + else if (m_oType == SimpleTypes::Spreadsheet::EPivotAreaType::areaTopEnd) + ptr->pruleheaderdata.isxrtype = 0x06; + } + else + ptr->pruleheaderdata.isxrtype = 0x01; + return objectPtr; + } void CPivotArea::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PIVOTRULE*>(obj.get()); @@ -2256,7 +3471,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(!ptr->pruleheaderdata.rfxLoc.toString().empty() && (ptr->pruleheaderdata.rfxLoc.rowFirst!=0 || ptr->pruleheaderdata.rfxLoc.columnFirst!=0)) - m_oOffsetRef = ptr->pruleheaderdata.rfxLoc.toString(); + m_oOffsetRef = ptr->pruleheaderdata.rfxLoc.toString(true, true); if(!ptr->pruleheaderdata.fLineMode) m_oOutline = ptr->pruleheaderdata.fLineMode; @@ -2339,6 +3554,32 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } + XLS::BaseObjectPtr CPivotTableLocation::toBin() + { + auto ptr1(new XLSB::SXLOCATION); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginSXLocation); + ptr1->m_BrtBeginSXLocation = XLS::BaseObjectPtr{ptr}; + + if(m_oColPageCount.IsInit()) + ptr->ccolPage = m_oColPageCount->GetValue(); + else + ptr->ccolPage = 0; + if(m_oFirstDataCol.IsInit()) + ptr->colFirstData = m_oFirstDataCol->GetValue(); + if(m_oFirstDataRow.IsInit()) + ptr->rwFirstData = m_oFirstDataRow->GetValue(); + if(m_oFirstHeaderRow.IsInit()) + ptr->rwFirstHead = m_oFirstHeaderRow->GetValue(); + if(m_oRowPageCount.IsInit()) + ptr->crwPage = m_oRowPageCount->GetValue(); + else + ptr->crwPage = 0; + if(m_oRef.IsInit()) + ptr->rfxGeom = m_oRef.get(); + return objectPtr; + } + void CPivotTableLocation::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::BeginSXLocation*>(obj.get()); @@ -2354,7 +3595,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oRowPageCount = ptr->crwPage; if(!ptr->rfxGeom.toString().empty()) - m_oRef = ptr->rfxGeom.toString(); + m_oRef = ptr->rfxGeom.toString(true, true); } } //------------------------------------ @@ -2385,6 +3626,31 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oName = ptr->stStyleName.value(); } } + XLS::BaseObjectPtr CPivotTableStyleInfo::toBin() + { + auto ptr(new XLSB::TableStyleClient); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oShowColHeaders.IsInit()) + ptr->fColumnHeaders = m_oShowColHeaders.get(); + if(m_oShowRowHeaders.IsInit()) + ptr->fRowHeaders = m_oShowRowHeaders.get(); + if(m_oShowColStripes.IsInit()) + ptr->fColumnStripes = m_oShowColStripes.get(); + else + ptr->fColumnStripes = false; + if(m_oShowRowStripes.IsInit()) + ptr->fRowStripes = m_oShowRowStripes.get(); + else + ptr->fRowStripes = false; + if(m_oShowLastColumn.IsInit()) + ptr->fLastColumn = m_oShowLastColumn.get(); + if(m_oName.IsInit()) + ptr->stStyleName = m_oName.get(); + else + ptr->stStyleName = 0xFFFFFFFF; + + return objectPtr; + } void CPivotTableStyleInfo::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -2416,7 +3682,15 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //pivotCacheDefStream.reset(); } } + XLS::BaseObjectPtr CPivotCacheDefinitionFile::WriteBin() const + { + if(m_oPivotCashDefinition.IsInit()) + { + auto pivotCacheDefStream = m_oPivotCashDefinition->toBin(); + return pivotCacheDefStream; + } + } void CPivotCacheDefinitionFile::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; @@ -2445,29 +3719,43 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (bIsWritten) return; bIsWritten = true; - if(m_oPivotCashDefinition.IsInit()) + CXlsb* xlsb = dynamic_cast<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotCashDefinition.IsInit()) { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oPivotCashDefinition->toXML(sXml); + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { + if(m_oPivotCashDefinition.IsInit()) + { + NSStringUtils::CStringBuilder sXml; - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + m_oPivotCashDefinition->toXML(sXml); - oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); - IFileContainer::Write( oPath, oDirectory, oContent ); + std::wstring sPath = oPath.GetPath(); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + else if(m_nDataLength > 0 && m_pData) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(oPath.GetPath()); + oFile.WriteFile(m_pData, m_nDataLength); + oFile.CloseFile(); + } } - else if(m_nDataLength > 0 && m_pData) + oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); + IFileContainer::Write( oPath, oDirectory, oContent ); + } + const OOX::FileType CPivotCacheDefinitionFile::type() const + { + CXlsb* xlsb = dynamic_cast<CXlsb*>(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::PivotCacheDefinitionBin; } + return OOX::Spreadsheet::FileTypes::PivotCacheDefinition; } //------------------------------------ void CPivotCacheDefinition::toXML(NSStringUtils::CStringBuilder& writer) const @@ -2527,6 +3815,102 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" else if (L"extLst" == sName) m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotCacheDefinition::toBin() + { + auto ptr(new XLSB::PivotCacheDefStream); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->m_BrtBeginPivotCacheDef = writeAttributes(); + if(m_oCacheFields.IsInit()) + ptr->m_PCDFIELDS = m_oCacheFields->toBin(); + if(m_oCacheSource.IsInit()) + ptr->m_PCDSOURCE = m_oCacheSource->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTPIVOTCACHEDEF = m_oExtLst->toBinPivotCache(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotCacheDefinition::writeAttributes() + { + auto ptr(new XLSB::BeginPivotCacheDef); + XLS::BaseObjectPtr objectPtr(ptr); + if (m_oBackgroundQuery.IsInit()) + ptr->fBackgroundQuery = m_oBackgroundQuery.get(); + else + ptr->fBackgroundQuery = false; + + if (m_oEnableRefresh.IsInit()) + ptr->fEnableRefresh = !m_oEnableRefresh.get(); + + if (m_oRid.IsInit()) + ptr->stRelIDRecords.value = m_oRid->GetValue(); + else + ptr->fLoadRelIDRecords = false; + + if (m_oInvalid.IsInit()) + ptr->fInvalid = m_oInvalid.get(); + else + ptr->fInvalid = false; + + if (m_oCreatedVersion.IsInit()) + ptr->bVerCacheCreated = m_oCreatedVersion->GetValue(); + + if (m_oMinRefreshableVersion.IsInit()) + ptr->bVerCacheRefreshableMin = m_oMinRefreshableVersion->GetValue(); + else + ptr->bVerCacheRefreshableMin = 0; + if (m_oMissingItemsLimit.IsInit()) + ptr->citmGhostMax = m_oMissingItemsLimit->GetValue(); + else + ptr->citmGhostMax = -1; + + if (m_oOptimizeMemory.IsInit()) + ptr->fOptimizeCache = m_oOptimizeMemory.get(); + else + ptr->fOptimizeCache = false; + + if (m_oRecordCount.IsInit()) + ptr->cRecords = m_oRecordCount->GetValue(); + + if (m_oRefreshedBy.IsInit()) + ptr->stRefreshedWho = m_oRefreshedBy.get(); + else + ptr->stRefreshedWho = L"Aspose"; + + if (m_oRefreshedDateIso.IsInit()) + ptr->xnumRefreshedDate.data.value = std::stod(m_oRefreshedDateIso->GetValue()); + + if (m_oRefreshedVersion.IsInit()) + ptr->bVerCacheLastRefresh = m_oRefreshedVersion->GetValue(); + + if (m_oRefreshOnLoad.IsInit()) + ptr->fRefreshOnLoad = m_oRefreshOnLoad.get(); + else + ptr->fRefreshOnLoad = false; + + if (m_oSaveData.IsInit()) + ptr->fSaveData = m_oSaveData.get(); + + if (m_oSupportAdvancedDrill.IsInit()) + ptr->fSupportAttribDrill = m_oSupportAdvancedDrill.get(); + else + ptr->fSupportAttribDrill = false; + + if (m_oSupportSubquery.IsInit()) + ptr->fSupportSubquery = m_oSupportSubquery.get(); + else + ptr->fSupportSubquery = false; + + if (m_oTupleCache.IsInit()) + ptr->fSheetData = m_oTupleCache.get(); + else + ptr->fSheetData = false; + + if (m_oUpgradeOnRefresh.IsInit()) + ptr->fUpgradeOnRefresh = m_oUpgradeOnRefresh.get(); + else + ptr->fUpgradeOnRefresh = false; + + return objectPtr; + } void CPivotCacheDefinition::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PivotCacheDefStream*>(obj.get()); @@ -2657,7 +4041,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( L"cacheFields" == sName ) + if ( L"cacheField" == sName ) { CPivotCacheField* pPivotCacheField = new CPivotCacheField(); *pPivotCacheField = oReader; @@ -2665,6 +4049,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CPivotCacheFields::toBin() + { + auto ptr(new XLSB::PCDFIELDS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arPCDFIELD.push_back(i->toBin()); + return objectPtr; + } void CPivotCacheFields::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFIELDS*>(obj.get()); @@ -2751,6 +4143,91 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oExtLst = oReader; } } + XLS::BaseObjectPtr CPivotCacheField::toBin() + { + auto ptr(new XLSB::PCDFIELD); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->m_BrtBeginPCDField = writeAttributes(); + if(m_oSharedItems.IsInit() && !m_oSharedItems->m_arrItems.empty()) + ptr->m_PCDFATBL = m_oSharedItems->toBin(); + if(m_oFieldGroup.IsInit()) + ptr->m_PCDFGROUP = m_oFieldGroup->toBin(); + return objectPtr; + } + XLS::BaseObjectPtr CPivotCacheField::writeAttributes() + { + auto ptr(new XLSB::BeginPCDField); + XLS::BaseObjectPtr objectPtr(ptr); + + if (m_oName.IsInit()) + ptr->stFldName = m_oName.get(); + + if (m_oCaption.IsInit()) + ptr->stFldCaption = m_oCaption.get(); + else + ptr->fCaption = false; + + if (m_oDatabaseField.IsInit()) + ptr->fSrcField = m_oDatabaseField.get(); + else + ptr->fSrcField = true; + + if (m_oServerField.IsInit()) + ptr->fServerBased = m_oServerField.get(); + else + ptr->fServerBased = false; + + if (m_oFormula.IsInit()) + ptr->fldFmla = m_oFormula.get(); + else + { + ptr->fLoadFmla = false; + ptr->fldFmla.cSxName = 0; + } + + if (m_oHierarchy.IsInit()) + ptr->ihdb = m_oHierarchy.get(); + else + ptr->ihdb = 0; + + if (m_oMemberPropertyField.IsInit()) + ptr->fOlapMemPropField = m_oMemberPropertyField.get(); + else + ptr->fOlapMemPropField = false; + + if (m_oPropertyName.IsInit()) + ptr->stMemPropName.value() = m_oPropertyName.get(); + else + ptr->fLoadPropName = false; + + if (m_oSqlType.IsInit()) + ptr->wTypeSql = m_oSqlType.get(); + else + ptr->wTypeSql = 0; + + if (m_oUniqueList.IsInit()) + ptr->fCantGetUniqueItems = !m_oUniqueList.get(); + else + ptr->fCantGetUniqueItems = false; + + if (m_oLevel.IsInit()) + ptr->isxtl = m_oLevel->GetValue(); + else + ptr->isxtl = 0; + if(m_oMappingCount.IsInit()) + ptr->cIsxtmps = m_oMappingCount->GetValue(); + else + ptr->cIsxtmps = 0; + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + else + ptr->ifmt = 0; + + ptr->cbRgisxtmp = 0; + + return objectPtr; + } void CPivotCacheField::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFIELD*>(obj.get()); @@ -2923,6 +4400,175 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr CSharedItems::toBin() + { + auto ptr(new XLSB::PCDFATBL); + XLS::BaseObjectPtr objectPtr(ptr); + bool hasBolean = false; + bool hasStr = false; + bool hasDate = false; + bool hasMissing = false; + bool hasNumber = false; + bool hasError = false; + + for(auto i:m_arrItems) + { + + if(i->getType() == et_x_PivotBooleanValue) + { + auto valueBool = static_cast<CPivotBooleanValue*>(i); + XLS::BaseObjectPtr element = valueBool->toBin(); + ptr->m_arSource.push_back(element); + hasBolean = true; + continue; + } + else if(i->getType() == et_x_PivotNoValue) + { + auto noVal = static_cast<CPivotNoValue*>(i); + XLS::BaseObjectPtr element = noVal->toBin(); + ptr->m_arSource.push_back(element); + hasMissing = true; + continue; + } + else if(i->getType() == et_x_PivotNumericValue) + { + auto numVal = static_cast<CPivotNumericValue*>(i); + XLS::BaseObjectPtr element = numVal->toBin(); + ptr->m_arSource.push_back(element); + hasNumber = true; + continue; + } + else if(i->getType() == et_x_PivotCharacterValue) + { + auto charVal = static_cast<CPivotCharacterValue*>(i); + XLS::BaseObjectPtr element = charVal->toBin(); + ptr->m_arSource.push_back(element); + hasStr = true; + continue; + } + else if(i->getType() == et_x_PivotDateTimeValue) + { + auto dateValue = static_cast<CPivotDateTimeValue*>(i); + XLS::BaseObjectPtr element = dateValue->toBin(); + ptr->m_arSource.push_back(element); + hasDate = true; + continue; + } + else if(i->getType() == et_x_PivotErrorValue) + { + auto errorVal = static_cast<CPivotErrorValue*>(i); + XLS::BaseObjectPtr element = errorVal->toBin(); + ptr->m_arSource.push_back(element); + hasError = true; + continue; + } + else + { + auto missingVal(new XLSB::PCDIMissing); + XLS::BaseObjectPtr element(missingVal); + ptr->m_arSource.push_back(element); + hasMissing = true; + continue; + } + } + unsigned char flags = 0; + SETBIT(flags,0, hasBolean); + SETBIT(flags,1, hasStr); + SETBIT(flags,2, hasDate); + SETBIT(flags,3, hasMissing); + SETBIT(flags,4, hasNumber); + SETBIT(flags,5, hasError); + ptr->m_BrtBeginPCDFAtbl = writeAttributes(flags); + return objectPtr; + } + + XLS::BaseObjectPtr CSharedItems::writeAttributes(const unsigned char flags) + { + auto ptr(new XLSB::BeginPCDFAtbl); + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oContainsBlank.IsInit()) + ptr->fHasBlankItem = m_oContainsBlank.get(); + else + ptr->fHasBlankItem = false; + if(m_oContainsDate.IsInit()) + ptr->fDateInField = m_oContainsDate.get(); + else + ptr->fDateInField = false; + if(m_oContainsInteger.IsInit()) + ptr->fIntField = m_oContainsInteger.get(); + else + ptr->fIntField = false; + if(m_oContainsMixedTypes.IsInit()) + ptr->fMixedTypesIgnoringBlanks = m_oContainsMixedTypes.get(); + else + ptr->fMixedTypesIgnoringBlanks = false; + if(m_oContainsNonDate.IsInit()) + ptr->fNonDates = m_oContainsNonDate.get(); + else + ptr->fNonDates = false; + if(m_oContainsNumber.IsInit()) + ptr->fNumField = m_oContainsNumber.get(); + else + ptr->fNumField = false; + if(m_oContainsSemiMixedTypes.IsInit()) + ptr->fTextEtcField = m_oContainsSemiMixedTypes.get(); + else + ptr->fTextEtcField = false; + if(m_oContainsString.IsInit()) + ptr->fHasTextItem = m_oContainsString.get(); + else + ptr->fHasTextItem = false; + if(m_oLongText.IsInit()) + ptr->fHasLongTextItem = m_oLongText.get(); + else + ptr->fHasLongTextItem = false; + if(m_oCount.IsInit()) + ptr->citems = m_oCount->GetValue(); + else + ptr->citems = 0; + if(m_oMinDate.IsInit() && m_oMaxDate.IsInit()) + { + ptr->xnumMin.data.value = std::stod(m_oMinDate->GetValue()); + ptr->xnumMax.data.value =std::stod(m_oMaxDate->GetValue()); + } + else if(m_oMinValue.IsInit() && m_oMaxValue.IsInit()) + { + if(m_oMinValue.IsInit()) + ptr->xnumMin.data.value = m_oMinValue.get(); + if(m_oMaxValue.IsInit()) + ptr->xnumMax.data.value = m_oMaxValue.get(); + } + else + { + ptr->fNumMinMaxValid = false; + } + bool hasBolean = GETBIT(flags,0); + bool hasStr = GETBIT(flags,1); + bool hasDate = GETBIT(flags,2); + bool hasMissing = GETBIT(flags,3); + bool hasNumber = GETBIT(flags,4); + bool hasError = GETBIT(flags,5); + if(!hasDate) + ptr->fNonDates = true; + if(!hasDate && hasNumber) + ptr->fNumField = true; + if(hasStr || hasError || hasBolean) + { + ptr->fTextEtcField = true; + ptr->fHasTextItem = true; + } + if(hasMissing) + { + ptr->fHasBlankItem = true; + ptr->fTextEtcField = true; + } + if(hasDate && hasNumber || hasNumber && ptr->fHasTextItem ||hasDate && ptr->fHasTextItem) + { + ptr->fMixedTypesIgnoringBlanks = true; + } + return objectPtr; + } void CSharedItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFATBL*>(obj.get()); @@ -3074,8 +4720,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->fDateInField && !ptr->fMixedTypesIgnoringBlanks && ptr->fNumMinMaxValid) { - m_oMinDate = std::to_wstring(ptr->xnumMin.data.value); - m_oMaxDate = std::to_wstring(ptr->xnumMax.data.value); + m_oMinDate = getDateFromExcelTime(ptr->xnumMin.data.value); + m_oMaxDate = getDateFromExcelTime(ptr->xnumMax.data.value); } else if(ptr->fNumField && ptr->fNumMinMaxValid) { @@ -3135,6 +4781,14 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CSharedItemsIndex>(oReader)); } } + XLS::BaseObjectPtr CDiscreteGroupingProperties::toBin() + { + auto ptr(new XLSB::PCDFGDISCRETE); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + ptr->m_arBrtPCDIIndex.push_back(i->toBinItemIndex()); + return objectPtr; + } void CDiscreteGroupingProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFGDISCRETE*>(obj.get()); @@ -3221,6 +4875,63 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } } } + XLS::BaseObjectPtr COLAPGroupItems::toBin() + { + auto ptr(new XLSB::PCDFGITEMS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i:m_arrItems) + { + auto boolVal = static_cast<CPivotBooleanValue*>(i); + if(boolVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = boolVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto dataValue = static_cast<CPivotDateTimeValue*>(i); + if(dataValue) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = dataValue->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto errorValue = static_cast<CPivotErrorValue*>(i); + if(errorValue) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = errorValue->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto noVal = static_cast<CPivotNoValue*>(i); + if(noVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = noVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto numericVal = static_cast<CPivotNumericValue*>(i); + if(numericVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = numericVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + auto charVal = static_cast<CPivotCharacterValue*>(i); + if(charVal) + { + auto ptr1(new XLSB::PCDI); + ptr1->m_source = charVal->toBin(); + ptr->m_arPCDI.push_back(XLS::BaseObjectPtr{ptr1}); + continue; + } + } + return objectPtr; + } void COLAPGroupItems::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFGITEMS*>(obj.get()); @@ -3348,6 +5059,44 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if ( oReader.IsEmptyNode() ) return; } + XLS::BaseObjectPtr CRangeGroupingProperties::toBin() + { + auto ptr1(new XLSB::PCDFGRANGE); + XLS::BaseObjectPtr objectPtr(ptr1); + auto ptr(new XLSB::BeginPCDFGRange); + ptr1->m_BrtBeginPCDFGRange = XLS::BaseObjectPtr{ptr}; + + if(m_oAutoStart.IsInit()) + ptr->fAutoStart = m_oAutoStart.get(); + if(m_oAutoEnd.IsInit()) + ptr->fAutoEnd = m_oAutoEnd.get(); + if(m_oGroupInterval.IsInit()) + ptr->xnumBy.data.value = m_oGroupInterval.get(); + if(m_oStartDate.IsInit() && m_oEndDate.IsInit()) + { + ptr->xnumStart.data.value = std::stod(m_oStartDate->GetValue()); + ptr->xnumEnd.data.value = std::stod(m_oEndDate->GetValue()); + } + else + { + if(m_oStartNum.IsInit()) + ptr->xnumStart.data.value = m_oStartNum.get(); + if(m_oEndNum.IsInit()) + ptr->xnumEnd.data.value = m_oEndNum.get(); + } + if(m_oGroupBy.IsInit()) + { + if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByNumericRanges) ptr->iByType = 0x00; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupBySeconds) ptr->iByType = 0x01; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByMinutes) ptr->iByType = 0x02; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByHours) ptr->iByType = 0x03; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByDays) ptr->iByType = 0x04; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByMonths) ptr->iByType = 0x05; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByQuarters) ptr->iByType = 0x06; + else if (m_oGroupBy == SimpleTypes::Spreadsheet::EValuesGroupBy::groupByYears) ptr->iByType = 0x07; + } + return objectPtr; + } void CRangeGroupingProperties::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDFGRANGE*>(obj.get()); @@ -3369,8 +5118,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->fDates) { - m_oStartDate = std::to_wstring(ptr->xnumStart.data.value); - m_oEndDate = std::to_wstring(ptr->xnumEnd.data.value); + m_oStartDate = getDateFromExcelTime(ptr->xnumStart.data.value); + m_oEndDate = getDateFromExcelTime(ptr->xnumEnd.data.value); } else { @@ -3471,6 +5220,53 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CMemberPropertyIndex>(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); @@ -3598,6 +5394,65 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CMemberPropertyIndex>(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); @@ -3747,6 +5602,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 ) @@ -3856,6 +5752,46 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CMemberPropertyIndex>(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()); + 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()); + + return objectPtr; + } + } void CPivotDateTimeValue::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -3944,6 +5880,52 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CMemberPropertyIndex>(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); @@ -4048,7 +6030,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 ) @@ -4166,6 +6177,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<XLSB::BeginPCDSource*>(obj.get()); @@ -4216,6 +6255,29 @@ 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; + return objectPtr; + } void CWorksheetSource::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::PCDSRANGE*>(obj.get()); @@ -4234,8 +6296,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(); @@ -4289,6 +6351,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<XLSB::PCDSCPAGES*>(obj.get()); @@ -4345,6 +6415,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<XLSB::PCDSCPAGE*>(obj.get()); @@ -4379,6 +6457,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<XLSB::PCDSCPITEM*>(obj.get()); @@ -4440,6 +6529,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<XLSB::PCDSCSETS*>(obj.get()); @@ -4481,6 +6578,28 @@ 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->irstSheet = m_oSheet.get(); + if(m_oRef.IsInit()) + ptr->rfx = m_oRef.get(); + if(m_oName.IsInit()) + ptr->irstName = m_oName.get(); + if(m_oRid.IsInit()) + ptr->irstRelId.value = m_oRid->GetValue(); + 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<XLSB::PCDSCSET*>(obj.get()); @@ -4500,7 +6619,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(); @@ -4561,6 +6680,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<XLSB::PCDSCONSOL*>(obj.get()); @@ -4633,6 +6766,26 @@ 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); + if(m_oPar.IsInit() || m_oBase.IsInit()) + { + auto ptr1(new XLSB::BeginPCDFGroup); + if(m_oPar.IsInit()) + ptr1->ifdbParent = m_oPar->GetValue(); + if(m_oBase.IsInit()) + ptr1->ifdbBase = m_oBase->GetValue(); + } + 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<XLSB::PCDFGROUP*>(obj.get()); @@ -4687,6 +6840,23 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //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; @@ -4713,34 +6883,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<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + m_oPivotCacheRecords->toXML(sXml); + NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + } + } - else + else if(m_nDataLength > 0 && m_pData) { - NSStringUtils::CStringBuilder sXml; - sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - 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<CXlsb*>(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<char*>(m_pData), m_nDataLength); + std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; + + return converter.from_bytes(stringData); } //------------------------------------ void CPivotCacheRecords::toXML(NSStringUtils::CStringBuilder& writer) const @@ -4820,6 +7015,18 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.Clear(); } } + 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 ) @@ -4893,6 +7100,75 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_arrItems.push_back(PPTX::CreatePtrXmlContent<CSharedItemsIndex>(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<CPivotBooleanValue*>(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<CPivotDateTimeValue*>(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<CPivotErrorValue*>(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<CPivotNoValue*>(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<CPivotNumericValue*>(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<CPivotCharacterValue*>(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<CSharedItemsIndex*>(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<XLSB::PIVOTCACHERECORD*>(obj.get()); @@ -5004,5 +7280,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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + //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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + //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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + //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<CTimelines> 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<XLSB::PhRun*>(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<XLSB::PhRun*>(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("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"")); - WritingStringNullableAttrInt(L"count", m_oCount, m_oCount->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<CXlsb*>(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("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><sst xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"")); + WritingStringNullableAttrInt(L"count", m_oCount, m_oCount->GetValue()); + WritingStringNullableAttrInt(L"uniqueCount", m_oUniqueCount, m_oUniqueCount->GetValue()); + writer.WriteString(_T(">")); - writer.WriteString(_T("</sst>")); - 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("</sst>")); + 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<CXlsb*>(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<CXlsb*>(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..cfb2f424d72 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<CText*>(m_arrItems[i]); + ptr->str = text->ToString(); + continue; + } + + if(m_arrItems[i]->getType() == OOX::et_x_r) + { + auto crunPtr = static_cast<CRun*>(m_arrItems[i]); + ptr->fRichStr = true; + USHORT ind = 0; + ptr->str = ptr->str.value() + crunPtr->toBin(ind); + XLSB::StrRun run; + run.ifnt = ind; + run.ich = ptr->str.value().size(); + ptr->rgsStrRun.push_back(run); + continue; + } + auto phonPtr = static_cast<CPhonetic*>(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<CRPh*>(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<XLSB::RichStr*>(&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/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<XLSB::BeginSlicer*>(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<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oSlicers->toXML(sXml, L"slicers"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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<CXlsb*>(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..7dbeec3ea36 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<XLSB::SlicerCacheOlapItem*>(obj.get()); @@ -256,6 +276,22 @@ 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; + } + for(auto i:m_oI) + ptr->m_arBrtSlicerCacheOlapItem.push_back(i.toBin()); + return objectPtr; +} void COlapSlicerCacheRange::fromBin(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::SLICERCACHESIRANGE*>(obj.get()); @@ -372,6 +408,17 @@ void CTabularSlicerCacheItem::fromBin(XLS::BiffStructure& obj) { ReadAttributes(obj); } +void CTabularSlicerCacheItem::toBin(XLS::BiffStructure *obj) +{ + auto ptr = static_cast<XLSB::SlicerCacheNativeItemStruct*>(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<XLSB::SlicerCacheNativeItemStruct*>(&obj); @@ -473,6 +520,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<XLSB::SlicerCacheSelection*>(obj.get()); @@ -590,6 +654,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<XLSB::BeginSlicerCacheLevelData*>(obj.get()); @@ -763,7 +863,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 +966,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<XLSB::SLICERCACHESELECTIONS*>(obj.get()); @@ -975,6 +1095,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 +1206,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_BrtSlicerCacheNativeItem = 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<XLSB::BeginSlicerCacheNative*>(obj.get()); @@ -1227,6 +1378,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<XLSB::BeginSlicerCacheOlapImpl*>(obj.get()); @@ -1343,6 +1510,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 +1611,16 @@ void CSlicerCachePivotTable::ReadAttributes(XLS::BiffStructure& obj) m_oName = ptr->stPivotTable.value(); } } - +void CSlicerCachePivotTable::toBin(XLS::BiffStructure* obj) +{ + auto ptr = static_cast<XLSB::SlicerCachePivotTable*>(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 +1714,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<XLSB::BeginSlicerCacheDef*>(obj.get()); @@ -1769,7 +1986,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 +2021,35 @@ void CSlicerCacheFile::write(const CPath& oPath, const CPath& oDirectory, CConte { if(!m_oSlicerCacheDefinition.IsInit()) return; + CXlsb* xlsb = dynamic_cast<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oSlicerCacheDefinition->toXML(sXml, L"slicerCacheDefinition"); - - std::wstring sPath = oPath.GetPath(); - NSFile::CFileBinary::SaveToFile(sPath, sXml.GetData()); + sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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<CXlsb*>(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..ceb34ce64e8 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<XLSB::SlicerCacheLevelData*>(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<XLSB::SlicerCacheLevelData*>(&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<XLSB::BeginTableSlicerCache*>(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,30 @@ 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(); + } + 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(); + } + return objectPtr; +} void CSlicerCache::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -540,6 +638,26 @@ 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(); + 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(); + ptr->m_BrtBeginSlicerEx = XLS::BaseObjectPtr{ptr1}; + + return objectPtr; +} void CSlicerRef::fromBin(XLS::BaseObjectPtr &obj) { ReadAttributes(obj); @@ -557,7 +675,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 +835,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<XLSB::BeginSlicerStyle*>(obj.get()); @@ -725,6 +860,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<XLSB::SLICERCACHEIDS*>(obj.get()); @@ -778,6 +941,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 +1146,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<XLSB::BeginSlicerStyles*>(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<XLSB::Blxf*>(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<XLS::BaseObjectPtr>& 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..505c043d453 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,36 @@ 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(); + if (m_oXfId.IsInit()) + ptr->ixf = m_oXfId->GetValue(); + + return objectPtr; + } EElementType CCellStyle::getType () const { return et_x_CellStyle; @@ -159,6 +192,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<XLS::BaseObjectPtr>& 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<XLSB::Fill*>(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<XLS::BaseObject*>(&ptr->brtColor)); } } + void CGradientStop::toBin(XLS::BaseObjectPtr obj) + { + auto ptr = static_cast<XLSB::Fill*>(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<XLSB::Fill*>(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<XLS::BaseObjectPtr>& 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..0eb205ecf31 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,113 @@ 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; + } + + 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 +516,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<XLS::BaseObjectPtr>& 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..77a1f6b0b79 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,17 @@ 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(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + + return objectPtr; + } EElementType CNumFmt::getType () const { return et_x_NumFmt; @@ -187,6 +200,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<XLS::BaseObjectPtr> 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<XLS::BaseObjectPtr>& 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..46bab13cfe4 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,31 @@ 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(); + + for(auto i:m_arrItems) + ptr->m_arBrtTableStyleElement.push_back(i->toBin()); + return objectPtr; + } EElementType CTableStyle::getType () const { return et_x_TableStyle; @@ -333,6 +437,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..f771a556c5c 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,57 @@ namespace OOX void CAligment::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); + } + void CAligment::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast<XLS::XF*>(obj.get()); + if(m_oIndent.IsInit()) + ptr->cIndent = m_oIndent.get(); + if(m_oJustifyLastLine.IsInit()) + ptr->fJustLast = m_oJustifyLastLine->GetValue(); + if(m_oReadingOrder.IsInit()) + ptr->iReadOrder = m_oReadingOrder.get(); + if(m_oRelativeIndent.IsInit()) + ptr->iReadOrder = m_oRelativeIndent.get(); + if(m_oShrinkToFit.IsInit()) + ptr->fShrinkToFit = m_oShrinkToFit->GetValue(); + if(m_oTextRotation.IsInit()) + ptr->trot = m_oTextRotation.get(); + if(m_oWrapText.IsInit()) + ptr->fWrap = m_oWrapText->GetValue(); + + 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 +276,18 @@ namespace OOX { ReadAttributes(obj); } + void CProtection::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast<XLSB::XF*>(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 +378,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 +541,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 +633,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<CAligment> m_oAligment; nullable<CProtection> m_oProtection; - + }; class CCellXfs : public WritingElementWithChilds<CXfs> @@ -174,6 +177,7 @@ namespace OOX virtual void toXML(NSStringUtils::CStringBuilder& writer) const; virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -202,6 +206,7 @@ namespace OOX virtual EElementType getType () const; void fromBin(std::vector<XLS::BaseObjectPtr>& 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<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + XLS::BaseObjectPtr object = WriteBin(); + xlsb->WriteBin(oPath, object.get()); + } + else + { NSStringUtils::CStringBuilder sXml; sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\ @@ -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<CXlsb*>(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<CXlsb*>(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 <boost/algorithm/string.hpp> +#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<XLS::BaseObjectPtr>& 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..9a73cea573a 100644 --- a/OOXML/XlsxFormat/Styles/rPr.cpp +++ b/OOXML/XlsxFormat/Styles/rPr.cpp @@ -68,6 +68,18 @@ 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(); + } + return objectPtr; + } EElementType CRgbColor::getType () const { return et_x_RgbColor; @@ -136,6 +148,13 @@ namespace OOX m_arrItems.push_back(pRgbColor); } } + std::vector<XLS::BaseObjectPtr> CIndexedColors::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i : m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CIndexedColors::getType () const { return et_x_IndexedColors; @@ -429,6 +448,113 @@ 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 = 0; + ptr.bBlue = 0; + ptr.bGreen = 0; + ptr.bRed = 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 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->bAlpha = 0; + ptr->bAlpha = 0; + ptr->bAlpha = 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; + } EElementType CColor::getType () const { return et_x_Color; @@ -567,6 +693,13 @@ namespace OOX m_arrItems.push_back(color); } } + std::vector<XLS::BaseObjectPtr> CMruColors::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CMruColors::getType () const { return et_x_MruColors; @@ -702,6 +835,10 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); + if(!m_oUnderline.IsInit()) + { + m_oUnderline.Init(); + } } std::wstring CUnderline::toXML() const { diff --git a/OOXML/XlsxFormat/Styles/rPr.h b/OOXML/XlsxFormat/Styles/rPr.h index f0ec51018ae..ddd9a2d7b7b 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<SimpleTypes::Spreadsheet::CHexColor> m_oRgb; }; - + class CIndexedColors : public WritingElementWithChilds<CRgbColor> { public: @@ -114,6 +116,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> 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,9 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::BaseObject* obj); + XLS::BaseObjectPtr toBin(); + XLSB::Color toColor(); + XLSB::Color GetDefaultColor(); virtual EElementType getType () const; @@ -175,6 +181,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Table/Autofilter.cpp b/OOXML/XlsxFormat/Table/Autofilter.cpp index 908052d894a..9cc5103b088 100644 --- a/OOXML/XlsxFormat/Table/Autofilter.cpp +++ b/OOXML/XlsxFormat/Table/Autofilter.cpp @@ -104,6 +104,47 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CSortCondition::toBin() + { + auto ptr(new XLSB::BeginSortCond); + XLS::BaseObjectPtr objectPtr(ptr); + + 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 +171,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 +199,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 +295,38 @@ namespace OOX for(auto &pSORTCOND14 : ptrACSORTCONDS->m_arSORTCOND14) m_arrItems.push_back(new CSortCondition(static_cast<XLSB::SORTCOND14*>(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 +399,15 @@ namespace OOX { ReadAttributes(obj); } + XLS::BaseObjectPtr CColorFilter::toBin() + { + auto ptr(new XLSB::ColorFilter); + XLS::BaseObjectPtr objectPtr(ptr); + ptr->fCellColor = m_oCellColor->GetValue(); + ptr->dxfid = m_oDxfId->GetValue(); + + return objectPtr; + } EElementType CColorFilter::getType () const { return et_x_ColorFilter; @@ -392,6 +472,94 @@ 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; + } + if (m_oVal.IsInit()) + { + ptr->xNumValue.data.value = m_oVal->GetValue(); + } + + if (m_oMaxVal.IsInit()) + { + ptr->xNumValueMax.data.value = m_oMaxVal->GetValue(); + } + return objectPtr; + } EElementType CDynamicFilter::getType () const { return et_x_DynamicFilter; @@ -531,6 +699,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 +849,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 +924,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 +997,44 @@ 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; + } + + ptr->dom = m_oDay->GetValue(); + ptr->hour = m_oHour->GetValue(); + ptr->min = m_oMinute->GetValue(); + ptr->mon = m_oMonth->GetValue(); + ptr->sec = m_oSecond->GetValue(); + ptr->yr = m_oYear->GetValue(); + return objectPtr; + } EElementType CDateGroupItem::getType () const { return et_x_DateGroupItem; @@ -911,6 +1173,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<CFilter*>(i)) { + // Элемент является экземпляром класса CFilter + ptr->m_arBrtFilter.push_back(cfilter->toBin()); + } else if (CDateGroupItem* groupItem = dynamic_cast<CDateGroupItem*>(i)) { + // Элемент является экземпляром класса CDateGroupItem + ptr->m_arBrtAFilterDateGroupItem.push_back(groupItem->toBin()); + } + } + return objectPtr; + } EElementType CFilters::getType () const { return et_x_Filters; @@ -976,6 +1259,25 @@ 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(); + + if (m_oPercent.IsInit()) + ptr->fPercent = m_oPercent->GetValue(); + + if (m_oTop.IsInit()) + ptr->fTop = m_oTop->GetValue(); + + if (m_oVal.IsInit()) + ptr->xNumFilter.data.value = m_oVal->GetValue(); + + return objectPtr; + } EElementType CTop10::getType () const { return et_x_ColorFilter; @@ -1092,6 +1394,33 @@ 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(); + if(m_oHiddenButton.IsInit()) + beginfilter->fHideArrow = m_oHiddenButton->GetValue(); + if(m_oShowButton.IsInit()) + beginfilter->fNoBtn = m_oShowButton->GetValue(); + + 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 +1519,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 +1549,7 @@ namespace OOX auto ptr = static_cast<XLSB::BeginAFilter*>(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..d31eb4cc950 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; @@ -798,6 +1035,153 @@ namespace OOX } } } + XLS::BaseObjectPtr CConnection::toBin15() + { + XLS::BaseObjectPtr objectPtr; + + 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_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(); + else + ptr1->dwConnID = 1; + if(m_oCredentials.IsInit()) + ptr1->iCredMethod = m_oCredentials->GetValue(); + else + ptr1->iCredMethod = 0; + if(m_oBackground.IsInit()) + ptr1->fBackgroundQuery = m_oBackground.get(); + else + ptr1->fBackgroundQuery = false; + if(m_oDeleted.IsInit()) + ptr1->fDeleted = m_oDeleted.get(); + else + ptr1->fDeleted = false; + if(m_oDescription.IsInit()) + ptr1->stConnDesc = m_oDescription.get(); + else + ptr1->fLoadConnectionDesc = false; + if(m_oInterval.IsInit()) + ptr1->wInterval = m_oInterval.get(); + else + ptr1->wInterval = 0; + if(m_oKeepAlive.IsInit()) + ptr1->fMaintain = m_oKeepAlive.get(); + else + ptr1->fMaintain = false; + 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(); + else + ptr1->fNewQuery = false; + if(m_oOdcFile.IsInit()) + ptr1->stConnectionFile = m_oOdcFile.get(); + else + ptr1->fLoadSourceConnectionFile = false; + if(m_oOnlyUseConnectionFile.IsInit()) + ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); + else + ptr1->fAlwaysUseConnectionFile = false; + if(m_oReconnectionMethod.IsInit()) + ptr1->irecontype = m_oReconnectionMethod.get(); + else + ptr1->irecontype = 1; + if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshed = m_oRefreshedVersion.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); + else + ptr1->fRefreshOnLoad = false; + if(m_oSaveData.IsInit()) + ptr1->fSaveData = m_oSaveData.get(); + else + ptr1->fSaveData = false; + if(m_oSavePassword.IsInit()) + ptr1->pc = m_oSavePassword.get(); + else + ptr1->pc = 2; + if(m_oSingleSignOnId.IsInit()) + ptr1->stSso = m_oSingleSignOnId.get(); + else + ptr1->fLoadSSOApplicationID = false; + if(m_oSourceFile.IsInit()) + ptr1->stDataFile = m_oSourceFile.get(); + else + ptr1->fLoadSourceDataFile = false; + + 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 +1326,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 +1372,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<CXlsb*>(File::m_pMainDocument); @@ -1014,21 +1419,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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oConnections->toXML(sXml); + CXlsb* xlsb = dynamic_cast<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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<CXlsb*>(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..07b443d5f1f 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,16 @@ 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(); + if(m_oAltTextSummary.IsInit()) + ptr->stAltTextSummary = m_oAltTextSummary.get(); + return objectPtr; + } void CAltTextTable::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -133,6 +149,24 @@ 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(); + if(m_oShowFirstColumn.IsInit()) + ptr->fFirstColumn = m_oShowFirstColumn->GetValue(); + if(m_oShowLastColumn.IsInit()) + ptr->fLastColumn = m_oShowLastColumn->GetValue(); + if(m_oShowRowStripes.IsInit()) + ptr->fRowStripes = m_oShowRowStripes->GetValue(); + return objectPtr; + } void CTableStyleInfo::ReadAttributes(XLS::BaseObjectPtr& obj) { auto ptr = static_cast<XLSB::TableStyleClient*>(obj.get()); @@ -169,11 +203,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 +272,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 +455,7 @@ namespace Spreadsheet writer.WriteString(L"<tableColumns"); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -334,7 +463,7 @@ namespace Spreadsheet m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L"</tableColumns>"); } void CTableColumns::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -368,6 +497,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<XLS::BaseObjectPtr>& obj) { if(!obj.empty()) @@ -405,17 +542,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 +576,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 +608,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<std::wstring>(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<int, std::vector<std::wstring>>::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 +659,139 @@ 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(); + + 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 +804,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 +824,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") auto ptr = static_cast<XLSB::BeginList*>(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 +920,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 +948,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L"<tableParts"); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -652,8 +956,8 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - - writer.WriteString(L"</tableParts>"); + + writer.WriteString(L"</tableParts>"); } void CTableParts::fromXML(XmlUtils::CXmlLiteReader& oReader) { @@ -689,6 +993,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 +1042,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 +1076,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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oTable->toXML2(sXml, nGlobalNumber); + CXlsb* xlsb = dynamic_cast<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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<CXlsb*>(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::TableBin; + } + return OOX::Spreadsheet::FileTypes::Table; + } //--------------------------------------------------------------------------------------------------------------------- @@ -790,6 +1137,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<XLSB::QSIF*>(obj.get()); @@ -837,7 +1217,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L"<queryTableFields"); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -845,7 +1225,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") m_arrItems[i]->toXML(writer); } } - + writer.WriteString(L"</queryTableFields>"); } void CQueryTableFields::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -868,6 +1248,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<XLSB::QSIFS*>(obj.get()); @@ -899,6 +1289,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<XLSB::DELETEDNAME*>(obj.get()); @@ -931,7 +1331,7 @@ xmlns:xr3=\"http://schemas.microsoft.com/office/spreadsheetml/2016/revision3\"") writer.WriteString(L"<queryTableDeletedFields"); WritingStringAttrInt(L"count", (int)m_arrItems.size()); writer.WriteString(L">"); - + for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -961,6 +1361,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<XLSB::DELETEDNAMES*>(obj.get()); @@ -1026,6 +1438,42 @@ 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(); + if(m_oMinimumVersion.IsInit()) + ptr->wVerBeforeRefreshAlert = m_oMinimumVersion->GetValue(); + if(m_FieldIdWrapped.IsInit()) + ptr->fidWrapped = m_FieldIdWrapped.get(); + else + ptr->fidWrapped = false; + if(m_HeadersInLastRefresh.IsInit()) + ptr->fTitlesOld = m_HeadersInLastRefresh.get(); + if(m_PreserveSortFilterLayout.IsInit()) + ptr->fPersist = m_PreserveSortFilterLayout.get(); + 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<XLSB::QSIR*>(obj.get()); @@ -1071,7 +1519,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 +1555,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 +1584,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<XLSB::QSI*>(obj.get()); @@ -1203,10 +1750,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 +1788,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 +1820,34 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" { if(false == m_oQueryTable.IsInit()) return; - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - m_oQueryTable->toXML(sXml); + CXlsb* xlsb = dynamic_cast<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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<CXlsb*>(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/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index b960837f4da..77c8a1a9aeb 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -74,6 +74,75 @@ 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(); + 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; @@ -183,6 +252,14 @@ namespace OOX m_arrItems.push_back(new CWorkbookView(workbookView)); } } + std::vector<XLS::BaseObjectPtr> CBookViews::toBin() + { + std::vector<XLS::BaseObjectPtr> 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<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> 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..bb0287e3910 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 = 0xFFFFFFFF; + + if(m_oDescription.IsInit()) + ptr->description = m_oDescription.get(); + else + ptr->description = 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 = 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 = 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 = 0xFFFFFFFF; + ptr->unusedstring2 = 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,15 @@ namespace OOX } } } + std::vector<XLS::BaseObjectPtr> CDefinedNames::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + + for(auto i:m_arrItems) + objectVector.push_back(i->toBin()); + + return objectVector; + } void CDefinedNames::fromBin(std::vector<XLS::BaseObjectPtr>& obj) { //ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.h b/OOXML/XlsxFormat/Workbook/DefinedNames.h index 971c6ebc969..4e5c3edc4a7 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,6 +103,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp b/OOXML/XlsxFormat/Workbook/ExternalReferences.cpp index 4e86b9a9811..3a86483d706 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); + if(m_oRid.IsInit()) + { + auto ptr1(new XLSB::SupBookSrc); + ptr->m_source = XLS::BaseObjectPtr{ptr1}; + ptr1->strRelID.value = m_oRid->GetValue(); + } + + return objectPtr; + } + void CExternalReference::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -156,6 +170,13 @@ namespace OOX m_arrItems.push_back(reference); } } + std::vector<XLS::BaseObjectPtr> CExternalReferences::toBin() + { + std::vector<XLS::BaseObjectPtr> 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<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> 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..74cf59e79c1 --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.cpp @@ -0,0 +1,1064 @@ +/* + * (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 "../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 + { + 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"<k"); + WritingStringNullableAttrInt2(L"n", m_oN); + WritingStringNullableAttrInt2(L"np", m_oNp); + WritingStringNullableAttrString(L"p", m_oP, m_oP->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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<p"); + WritingStringNullableAttrInt2(L"n", m_oN); + WritingStringNullableAttrInt2(L"np", m_oNp); + 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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<s>"); + 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"</s>"); + } + 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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<n"); + WritingStringNullableAttrInt2(L"x", m_oX); + WritingStringNullableAttrInt2(L"s", m_oS); + 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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<t>"); + 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"</t>"); + } + 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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<mdx>"); + 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"</mdx>"); + } + 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) + } + //------------------------------------------------------------------------------------- + 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"<mdxMetadata>"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L"</mdxMetadata>"); + } + //------------------------------------------------------------------------------------- + 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"<metadataStrings 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"</metadataStrings>"); + } + //-------------------------------------------------------------------------------------------------------- + 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; + } + void CMetadataString::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"<s"); + WritingStringNullableAttrEncodeXmlString2(L"v", m_oV); + 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"<rc"); + WritingStringNullableAttrInt2(L"t", m_oT); + WritingStringNullableAttrInt2(L"v", m_oV); + 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"<bk>"); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L"</bk>"); + } + //------------------------------------------------------------------------------------- + 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"</" + m_sName + L">"); + } + //------------------------------------------------------------------------------------- + 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"<metadataTypes 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"</metadataTypes>"); + } + //-------------------------------------------------------------------------------------------------------- + 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"<metadataType"); + WritingStringNullableAttrEncodeXmlString2(L"name", m_oName); + WritingStringNullableAttrInt2(L"minSupportedVersion", m_oMinSupportedVersion); + WritingStringNullableAttrBool2(L"ghostRow", m_oGhostRow); + WritingStringNullableAttrBool2(L"ghostCol", m_oGhostCol); + WritingStringNullableAttrBool2(L"edit", m_oEdit); + WritingStringNullableAttrBool2(L"delete", m_oDelete); + WritingStringNullableAttrBool2(L"copy", m_oCopy); + WritingStringNullableAttrBool2(L"pasteAll", m_oPasteAll); + WritingStringNullableAttrBool2(L"pasteFormulas", m_oPasteFormulas); + WritingStringNullableAttrBool2(L"pasteValues", m_oPasteValues); + WritingStringNullableAttrBool2(L"pasteFormats", m_oPasteFormats); + WritingStringNullableAttrBool2(L"pasteComments", m_oPasteComments); + WritingStringNullableAttrBool2(L"pasteDataValidation", m_oPasteDataValidation); + WritingStringNullableAttrBool2(L"pasteBorders", m_oPasteBorders); + WritingStringNullableAttrBool2(L"pasteColWidths", m_oPasteColWidths); + WritingStringNullableAttrBool2(L"pasteNumberFormats", m_oPasteNumberFormats); + WritingStringNullableAttrBool2(L"merge", m_oMerge); + WritingStringNullableAttrBool2(L"splitFirst", m_oSplitFirst); + WritingStringNullableAttrBool2(L"splitAll", m_oSplitAll); + WritingStringNullableAttrBool2(L"rowColShift", m_oRowColShift); + WritingStringNullableAttrBool2(L"clearAll", m_oClearAll); + WritingStringNullableAttrBool2(L"clearFormats", m_oClearFormats); + WritingStringNullableAttrBool2(L"clearContents", m_oClearContents); + WritingStringNullableAttrBool2(L"clearComments", m_oClearComments); + WritingStringNullableAttrBool2(L"assign", m_oAssign); + WritingStringNullableAttrBool2(L"coerce", m_oCoerce); + WritingStringNullableAttrBool2(L"cellMeta", m_oCellMeta); + 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) + } + //-------------------------------------------------------------------------------------------------------- + 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"<bk>"); + + if (m_oExtLst.IsInit()) + { + writer.WriteString(m_oExtLst->toXMLWithNS(L"")); + } + writer.WriteString(L"</bk>"); + } + 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; + } + } + //------------------------------------------------------------------------------------- + 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"<futureMetadata"); + WritingStringNullableAttrEncodeXmlString2(L"name", m_oName); + writer.WriteString(L" count=\"" + std::to_wstring(m_arrItems.size()) + L"\""); + 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"</futureMetadata>"); + } + //-------------------------------------------------------------------------------------------------------- + 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::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"<metadata \ +xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" \ +xmlns:xlrd=\"http://schemas.microsoft.com/office/spreadsheetml/2017/richdata\" \ +xmlns:xda=\"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray\">"); + + 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"</metadata>"); + } + 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 + { + return OOX::Spreadsheet::FileTypes::Metadata; + } + const CPath CMetadataFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const CPath CMetadataFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + const CPath& CMetadataFile::GetReadPath() + { + return m_oReadPath; + } + void CMetadataFile::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 CMetadataFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const + { + if (false == m_oMetadata.IsInit()) return; + + NSStringUtils::CStringBuilder sXml; + + sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + 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"<xda:dynamicArrayProperties"); + WritingStringNullableAttrBool2(L"fDynamic", m_oFDynamic); + WritingStringNullableAttrBool2(L"fCollapsed", m_oFCollapsed); + 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) + } +//------------------------------------------------------------------------------------------------------------------------------------- + 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"<xlrd:rvb"); + WritingStringNullableAttrInt2(L"i", m_oI); + 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) + } + } + +} // namespace OOX + diff --git a/OOXML/XlsxFormat/Workbook/Metadata.h b/OOXML/XlsxFormat/Workbook/Metadata.h new file mode 100644 index 00000000000..f0b17ae8c5a --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/Metadata.h @@ -0,0 +1,506 @@ +/* + * (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_AdditionMethods(CMdxKPI) + CMdxKPI(); + virtual ~CMdxKPI(); + + 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; + + nullable_uint m_oN; + nullable_uint m_oNp; + nullable<SimpleTypes::Spreadsheet::CMdxKPIProperty> m_oP; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMdxMemeberProp : public WritingElement + { + public: + WritingElement_AdditionMethods(CMdxMemeberProp) + CMdxMemeberProp(); + virtual ~CMdxMemeberProp(); + + 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; + + nullable_uint m_oN; + nullable_uint m_oNp; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CMetadataStringIndex : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataStringIndex) + CMetadataStringIndex(); + virtual ~CMetadataStringIndex(); + + 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; + + nullable_uint m_oX; + nullable_bool m_oS; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxSet : public WritingElementWithChilds<CMetadataStringIndex> + { + public: + WritingElement_AdditionMethods(CMdxSet) + CMdxSet(); + virtual ~CMdxSet(); + + 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; + + nullable_uint m_oNs; + nullable_uint m_oC; + nullable<SimpleTypes::Spreadsheet::CMdxSetOrder> m_oO; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxTuple : public WritingElementWithChilds<CMetadataStringIndex> + { + public: + WritingElement_AdditionMethods(CMdxTuple) + CMdxTuple(); + virtual ~CMdxTuple(); + + 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; + + 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_AdditionMethods(CMdx) + CMdx(); + virtual ~CMdx(); + + 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<CMdxTuple> m_oMdxTuple; + nullable<CMdxSet> m_oMdxSet; + nullable<CMdxKPI> m_oCMdxKPI; + nullable<CMdxMemeberProp> m_oMdxMemeberProp; + + nullable_uint m_oN; + nullable<SimpleTypes::Spreadsheet::CMdxFunctionType> m_oF; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMdxMetadata : public WritingElementWithChilds<CMdx> + { + public: + WritingElement_AdditionMethods(CMdxMetadata) + CMdxMetadata(); + virtual ~CMdxMetadata(); + + 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; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataString : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataString) + CMetadataString(); + virtual ~CMetadataString(); + + 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_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_AdditionMethods(CFutureMetadataBlock) + CFutureMetadataBlock(); + virtual ~CFutureMetadataBlock(); + + 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; + + nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataType : public WritingElement + { + public: + WritingElement_AdditionMethods(CMetadataType) + CMetadataType(); + virtual ~CMetadataType(); + + 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_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<CMetadataType> + { + public: + WritingElement_AdditionMethods(CMetadataTypes) + CMetadataTypes(); + virtual ~CMetadataTypes(); + + 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; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataBlock : public WritingElementWithChilds<CMetadataRecord> + { + public: + WritingElement_AdditionMethods(CMetadataBlock) + CMetadataBlock(); + virtual ~CMetadataBlock(); + + 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 CMetadataBlocks : public WritingElementWithChilds<CMetadataBlock> + { + public: + WritingElement_AdditionMethods(CMetadataBlocks) + CMetadataBlocks(); + virtual ~CMetadataBlocks(); + + 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; + + nullable_uint m_oCount; + + std::wstring m_sName; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CMetadataStrings : public WritingElementWithChilds<CMetadataString> + { + public: + WritingElement_AdditionMethods(CMetadataStrings) + CMetadataStrings(); + virtual ~CMetadataStrings(); + + 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; + + nullable_uint m_oCount; + }; +//------------------------------------------------------------------------------------------------------------------------ + class CFutureMetadata : public WritingElementWithChilds<CFutureMetadataBlock> + { + public: + WritingElement_AdditionMethods(CFutureMetadata) + CFutureMetadata(); + virtual ~CFutureMetadata(); + + 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; + + nullable_string m_oName; + nullable_uint m_oCount; + + nullable<OOX::Drawing::COfficeArtExtensionList> 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; + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + public: + nullable<CMetadataTypes> m_oMetadataTypes; + nullable<CMetadataStrings> m_oMetadataStrings; + nullable<CMdxMetadata> m_oMdxMetadata; + nullable<CMetadataBlocks> m_oCellMetadata; + nullable<CMetadataBlocks> m_oValueMetadata; + + std::vector<CFutureMetadata*> m_arFutureMetadata; + + nullable<OOX::Drawing::COfficeArtExtensionList> 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<CMetadata> m_oMetadata; + private: + CPath m_oReadPath; + }; +//----------------------------------------------------------------------------------------------------------------------- + class CDynamicArrayProperties : public WritingElement + { + public: + WritingElement_AdditionMethods(CDynamicArrayProperties) + CDynamicArrayProperties(); + virtual ~CDynamicArrayProperties(); + + 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; + + nullable_bool m_oFDynamic; + nullable_bool m_oFCollapsed; + + nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//----------------------------------------------------------------------------------------------------------------------- + class CRichValueBlock : public WritingElement + { + public: + WritingElement_AdditionMethods(CRichValueBlock) + CRichValueBlock(); + virtual ~CRichValueBlock(); + + 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; + + 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..97c6c4068f6 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -69,6 +69,26 @@ namespace OOX if ( !oReader.IsEmptyNode() ) oReader.ReadTillEnd(); } + XLS::BaseObjectPtr CSheet::toBin() + { + auto ptr(new XLSB::BundleSh); + XLS::BaseObjectPtr objectPtr(ptr); + + ptr->strRelID.value = m_oRid->GetValue(); + ptr->strName = m_oName.get(); + ptr->iTabID = m_oSheetId->GetValue(); + + 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 +99,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 +177,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<XLS::BaseObjectPtr>& obj) { @@ -171,6 +196,13 @@ namespace OOX m_arrItems.push_back(new CSheet(sheet)); } } + std::vector<XLS::BaseObjectPtr> CSheets::toBin() + { + std::vector<XLS::BaseObjectPtr> objectVector; + for(auto i: m_arrItems) + objectVector.push_back(i->toBin()); + return objectVector; + } EElementType CSheets::getType () const { return et_x_Sheets; @@ -178,6 +210,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<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> 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 0ee060bee02..38f7695e6cf 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -32,6 +32,7 @@ #pragma once #include "Workbook.h" +#include "../../XlsbFormat/Xlsb.h" #include "../../XlsbFormat/WorkBookStream.h" @@ -42,16 +43,23 @@ #include "../../XlsbFormat/Biff12_unions/PIVOTCACHEID.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 "../../../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 +92,19 @@ namespace OOX ReadAttributes(ptr->m_BrtBeginPivotCacheID); } } + 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(); + if(m_oRid.IsInit()) + ptr1->irstcacheRelID.value = m_oRid->GetValue(); + return objectPtr; + } EElementType CWorkbookPivotCache::getType() const { return et_x_WorkbookPivotCache; @@ -141,13 +162,12 @@ namespace OOX { 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 +186,16 @@ namespace OOX } } + 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; + } EElementType CWorkbookPivotCaches::getType() const { return et_x_WorkbookPivotCaches; @@ -238,7 +268,7 @@ namespace OOX if (workBookStream->m_FRTWORKBOOK != nullptr) m_oExtLst = workBookStream->m_FRTWORKBOOK; - + if (workBookStream->m_BrtFileSharingIso != nullptr) m_oFileSharing = workBookStream->m_BrtFileSharingIso; else if (workBookStream->m_BrtFileSharing != nullptr) @@ -249,6 +279,65 @@ 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(); + } + if (m_oWorkbookProtection.IsInit()) + workBookStream->m_BrtBookProtection = m_oWorkbookProtection->toBin(); + + workBookStream->m_EXTERNALS = WriteXtiRefs(); + if (m_oExternalReferences.IsInit()) + { + auto ptr = static_cast<XLSB::EXTERNALS*>(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) @@ -381,7 +470,7 @@ xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\"\ WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Read_if(oReader, L"appName", m_oAppName) WritingElement_ReadAttributes_End(oReader) - } + } else if (L"WindowHeight" == sName) { } @@ -398,20 +487,33 @@ xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\"\ } void CWorkbook::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { - NSStringUtils::CStringBuilder sXml; - - sXml.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); + CXlsb* xlsb = dynamic_cast<CXlsb*>(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"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); - 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<CXlsb*>(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; } @@ -421,7 +523,17 @@ xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\"\ } const CPath CWorkbook::DefaultFileName() const { - return type().DefaultFileName(); + CXlsb* xlsb = dynamic_cast<CXlsb*>(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 { @@ -490,6 +602,33 @@ xmlns:xr2=\"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2\"\ 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..a5046deadab 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -81,6 +81,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; @@ -106,6 +107,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; }; @@ -120,6 +122,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 +141,7 @@ namespace OOX void PrepareToWrite(); LONG GetActiveSheetIndex(); + XLS::BaseObjectPtr WriteXtiRefs() const; CPath m_oReadPath; @@ -154,7 +158,7 @@ namespace OOX nullable<OOX::Spreadsheet::CWorkbookPivotCaches>m_oPivotCaches; nullable<std::wstring> m_oPivotCachesXml; nullable<OOX::Spreadsheet::CFileSharing> m_oFileSharing; - + CPersonList* m_pPersonList; bool m_bMacroEnabled; }; diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 658fe94eb41..b868f1f7c56 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,78 @@ 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}; + + ptr->wFlags.fLockRevision = m_oLockRevision->GetValue(); + ptr->wFlags.fLockStructure = m_oLockStructure->GetValue(); + ptr->wFlags.fLockWindow = m_oLockWindows->GetValue(); + + ptr->ipdBookPasswordData.szAlgName = m_oWorkbookAlgorithmName->GetValue(); + ptr->dwBookSpinCount = m_oWorkbookSpinCount->GetValue(); + + 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(); + if(m_oRevisionsSpinCount.IsInit()) + ptr->dwRevSpinCount = m_oRevisionsSpinCount->GetValue(); + + 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 +410,69 @@ 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(); + 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<SimpleTypes::CCryptAlgoritmName> m_oAlgorithmName; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oSpinCount; nullable_string m_oHashValue; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index df7739a53fd..9434ba6cef2 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -81,6 +81,46 @@ 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; + if(m_oMin.IsInit()) + castedPtr->colFirst = m_oMin->m_eValue - 1; + if(m_oOutlineLevel.IsInit()) + castedPtr->iOutLevel = m_oOutlineLevel->m_eValue; + if(m_oPhonetic.IsInit()) + castedPtr->fPhonetic = m_oPhonetic->ToBool(); + 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; + } + return ptr; + } EElementType CCol::getType() const { return et_x_Col; @@ -230,6 +270,15 @@ namespace OOX } } } + std::vector<XLS::BaseObjectPtr> CCols::toBin() + { + std::vector<XLS::BaseObjectPtr> 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<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> toBin(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 3ae020f2a2b..48d907dfdac 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -108,7 +108,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"</" + node_name + L">"); @@ -125,7 +125,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 +180,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 +220,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer CFormulaCF formla; formla.m_sText = m_oVal.get(); formla.toXML2(writer, true); } - + } writer.WriteString(L"</" + node_name + L">"); @@ -228,7 +228,7 @@ void CConditionalFormatValueObject::toXML2(NSStringUtils::CStringBuilder& writer void CConditionalFormatValueObject::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); - + if (oReader.IsEmptyNode()) return; @@ -240,6 +240,52 @@ 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) + //ptr1->numParam.data.value = std::stod(m_oVal.get()); + 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(); + ptr1->cbFmla = 1; + } + else + { + ptr1->cbFmla = 0; + } + + return objectPtr; +} void CConditionalFormatValueObject::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -619,6 +665,16 @@ 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; +} EElementType CColorScale::getType () const { return et_x_ColorScale; @@ -637,7 +693,7 @@ nullable<Type> CColorScale::Merge(const nullable<Type> &oPrev, const nullable<Ty const CColorScale CColorScale::Merge(const CColorScale& oPrev, const CColorScale& oCurrent) { CColorScale oColorScale; - + for (size_t i = 0; i < oPrev.m_arrValues.size(); i++) { if (i < oCurrent.m_arrValues.size()) @@ -665,7 +721,7 @@ const CColorScale CColorScale::Merge(const CColorScale& oPrev, const CColorScale bool CDataBar::isExtended () { if (m_oAxisColor.IsInit() || m_oAxisPosition.IsInit() || m_oDirection.IsInit() || m_oBorderColor.IsInit() - || m_oNegativeFillColor.IsInit() || m_oNegativeBorderColor.IsInit() + || m_oNegativeFillColor.IsInit() || m_oNegativeBorderColor.IsInit() || m_oNegativeBarColorSameAsPositive.IsInit() || m_oNegativeBarBorderColorSameAsPositive.IsInit()) { return true; @@ -841,6 +897,33 @@ void CDataBar::fromBin(XLS::BaseObjectPtr& obj) } } +XLS::BaseObjectPtr CDataBar::toBin() +{ + auto ptr(new XLSB::DATABAR); + XLS::BaseObjectPtr objectPtr(ptr); + + auto ptr1(new XLSB::BeginDatabar); + ptr->m_BrtBeginDatabar = 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(); + else + ptr1->fShowValue = false; + + for(auto i:m_arrValues) + ptr->m_arCFVO.push_back(i->toBin()); + if(m_oColor.IsInit()) + ptr->m_BrtColor = m_oColor->toBin(); + + return objectPtr; +} void CDataBar::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginDatabar) @@ -898,13 +981,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 +1144,159 @@ 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; +} void CIconSet::ReadAttributes(XLS::BaseObjectPtr& obj) { if(obj->get_type() == XLS::typeBeginIconSet) @@ -1309,7 +1545,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 +1619,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 +1632,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 +1670,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 +1696,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 +1795,269 @@ 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(); + } + 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(); + 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; +} template<typename Type> nullable<Type> CConditionalFormattingRule::Merge(const nullable<Type> &oPrev, const nullable<Type> &oCurrent) { @@ -1572,7 +2071,7 @@ nullable<Type> CConditionalFormattingRule::Merge(const nullable<Type> &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 +2103,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 +2628,7 @@ bool CConditionalFormatting::IsExtended() { m_bIsExtended = false; m_bIsValid = false; - + if (m_oSqRef.IsInit() == false) return m_bIsExtended; m_bIsValid = true; @@ -2137,7 +2636,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 +2645,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 +2662,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,6 +2724,40 @@ 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; } bool CConditionalFormatting::IsUsage() { diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.h index 14d011972b7..1918b3aac28 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,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(const bool isIcon = false); virtual EElementType getType () const; bool isExtended (); @@ -166,6 +168,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -199,6 +202,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -214,7 +218,7 @@ namespace OOX nullable<SimpleTypes::CUnsignedDecimalNumber> m_oMaxLength; nullable<SimpleTypes::CUnsignedDecimalNumber> m_oMinLength; nullable<SimpleTypes::COnOff> m_oShowValue; - + nullable<CColor> m_oColor; std::vector<nullable<CConditionalFormatValueObject>> m_arrValues; @@ -229,7 +233,7 @@ namespace OOX nullable<CColor> m_oAxisColor; nullable<CColor> m_oBorderColor; - + nullable<CColor> m_oNegativeFillColor; nullable<CColor> m_oNegativeBorderColor; }; @@ -251,6 +255,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; @@ -295,6 +300,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(const XLS::CellRef &cellRef); virtual EElementType getType () const; bool isValid () const; @@ -306,6 +312,8 @@ namespace OOX private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr WriteAttributes(const XLS::CellRef &cellRef); + public: nullable<CDxf> m_oDxf; @@ -323,7 +331,7 @@ namespace OOX nullable<std::wstring> m_oText; nullable<SimpleTypes::Spreadsheet::ST_TimePeriod> m_oTimePeriod; nullable<SimpleTypes::Spreadsheet::ST_CfType> m_oType; - + nullable<OOX::Drawing::COfficeArtExtensionList> m_oExtLst; nullable_string m_oExtId; @@ -353,10 +361,11 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); 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 5e759fa9863..5fe0cff9ebd 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -212,6 +212,123 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); 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); @@ -516,6 +633,35 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); } 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 32084f50cd8..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; @@ -92,6 +92,7 @@ namespace OOX bool IsExtended(); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -135,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<XLS::BaseObjectPtr>& 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<XLSB::MergeCell*>(obj.get()); - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CMergeCells::CMergeCells(OOX::Document *pMain) : WritingElementWithChilds<CMergeCell>(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<XLS::BaseObjectPtr>& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index da61370bf06..b808b46cb7d 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -62,34 +62,45 @@ #include "../../XlsbFormat/Biff12_records/Cell.h" #include "../../XlsbFormat/Biff12_records/Fmla.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 <boost/regex.hpp> #include <boost/date_time/gregorian/gregorian.hpp> #include <boost/date_time/posix_time/posix_time.hpp> +#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 +108,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" }; //------------------------------------------------------------------------------ @@ -191,7 +202,7 @@ namespace OOX { boost::wregex r(L"([\\d]+)-([\\d]+)-([\\d]+)(?:T([\\d]+):([\\d]+):([\\d]+)(?:\\.([\\d]+))?)?"); boost::match_results<std::wstring::const_iterator> res; - + if (boost::regex_match(Date, res, r)) { Value = 0; @@ -243,7 +254,7 @@ namespace OOX 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 +619,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 +694,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 +735,6 @@ namespace OOX { nFlags = m_oFormula.toXLSB(oStream, bIsBlankFormula); } - if(m_oRichText.IsInit()) { nFlags |= 0x2000; @@ -728,6 +748,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 +951,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.WriteEncodeXmlStringHHHH(m_sText); - writer.WriteString(_T("</f>")); + if(!m_sText.empty()) + { + writer.WriteString(_T(">")); + writer.WriteEncodeXmlStringHHHH(m_sText); + writer.WriteString(_T("</f>")); + } + else + { + writer.WriteString(_T("/>")); + } } void CFormula::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream) { @@ -1021,7 +1057,7 @@ namespace OOX auto formula = dynamic_cast<XLSB::ShrFmla*>(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 +1070,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 +1085,7 @@ namespace OOX } m_oRef.Init(); - m_oRef = dataTable->rfx.toString(); + m_oRef = dataTable->rfx.toString(true, true); if(dataTable->fRw) { @@ -1085,6 +1121,124 @@ namespace OOX } } + void CFormula::toBin(XLS::BaseObjectPtr& obj) + { + switch(m_oT->GetValue()) + { + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal: + { + auto formula = dynamic_cast<XLSB::FmlaBase*>(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<XLS::PtgList*>(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared: + { + auto formula = dynamic_cast<XLSB::ShrFmla*>(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<XLS::PtgList*>(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + } + + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray: + { + auto formula = dynamic_cast<XLSB::ArrFmla*>(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<XLS::PtgList*>(formula->formula.rgce.sequence.rbegin()->get()); + list->type_ = 1; + } + + } + } + break; + case SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeDataTable: + { + auto dataTable = dynamic_cast<XLSB::Table*>(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 +1353,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()) { @@ -1288,18 +1442,30 @@ namespace OOX { CData data_comment; 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<CXlsxFlat*>(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map<int, std::map<int, unsigned int>>::iterator pFindRow = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); std::map<int, unsigned int>::iterator pFind; @@ -1309,8 +1475,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 @@ -1438,7 +1604,7 @@ namespace OOX { std::map<int, unsigned int> 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 +1616,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 +1648,10 @@ namespace OOX void CCell::AfterRead() { CSharedStrings *pSharedStrings = NULL; - + CXlsx* xlsx = dynamic_cast<CXlsx*>(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast<CXlsxFlat*>(m_pMainDocument); - + if (xlsx) { if (false == xlsx->m_arWorksheets.back()->m_bPrepareForBinaryWriter) return; @@ -1525,7 +1691,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 +1748,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,12 +1840,585 @@ 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); } + XLS::BaseObjectPtr CCell::toBin(sharedFormula &sharedFormulas) + { + std::vector<XLS::CellRangeRef> 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()) + { + auto metadata(new XLSB::CellMeta); + pCellMeta->m_BrtCellMeta = XLS::BaseObjectPtr{metadata}; + metadata->icmb = *m_oCellMetadata; + } + + if(m_oValueMetadata.IsInit()) + { + auto metadata(new XLSB::ValueMeta); + pCellMeta->m_BrtValueMeta = XLS::BaseObjectPtr{metadata}; + metadata->ivmb = *m_oValueMetadata; + } + } + + 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; + + 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(!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_MIN) + { + 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) + { + 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); + + 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; + } + } + } + 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; + + } + 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; + + 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; + + 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; + 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<XLS::CellRangeRef> 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<XLSB::FmlaBase*>(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<XLSB::FmlaBase*>(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<XLSB::FmlaBase*>(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); + ReadAttributes(obj); } void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { @@ -1698,7 +2438,7 @@ namespace OOX 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:ArrayRange", sArrayRange ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:StyleID", sStyleId ) WritingElement_ReadAttributes_Read_else_ifChar ( oReader, "ss:HRef", sHyperlink ) @@ -1718,7 +2458,7 @@ namespace OOX { m_oRow = ptr->m_Row; auto pCELLMETA = static_cast<XLSB::CELLMETA*>(ptr->m_CELLMETA.get()); - if(pCELLMETA != nullptr) + if(pCELLMETA != nullptr && false) // not convert without metadata file conversion { auto pCellMeta = static_cast<XLSB::CellMeta*>(pCELLMETA->m_BrtCellMeta.get()); if(pCellMeta != nullptr && pCellMeta->icmb) @@ -1757,7 +2497,7 @@ namespace OOX BiffRecord* pSource = nullptr; XLSB::Cell oCell; if(pDATACELL != nullptr) - { + { m_oCol = pDATACELL->m_Col; pSource = static_cast<BiffRecord*>(pDATACELL->m_source.get()); if(pSource != nullptr) @@ -1777,7 +2517,7 @@ namespace OOX } else if(pFMLACELL != nullptr) { - m_oCol = pFMLACELL->m_Col; + m_oCol = pFMLACELL->m_Col; pSource = static_cast<BiffRecord*>(pFMLACELL->m_source.get()); if(pSource != nullptr) oCell = dynamic_cast<XLSB::FmlaBase*>(pSource)->cell; @@ -1813,7 +2553,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 +2645,7 @@ namespace OOX } } } - } + } } EElementType CCell::getType () const { @@ -1951,7 +2691,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - nRow--; + //nRow--; nCol--; } } @@ -2263,7 +3003,7 @@ namespace OOX if (xlsx_flat) { CWorksheet* sheet = xlsx_flat->m_arWorksheets.back(); - + std::map<int, std::map<int, unsigned int>>::iterator pFind = sheet->m_oSheetData->m_mapStyleMerges2003.find(xlsx_flat->m_nLastReadRow); if (pFind != sheet->m_oSheetData->m_mapStyleMerges2003.end()) @@ -2296,6 +3036,71 @@ namespace OOX m_arrItems.push_back(pCell); }*/ } + XLS::BaseObjectPtr CRow::toBin(sharedFormula &sharedFormulas) + { + std::vector<XLS::CellRangeRef> 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)); + it = m_arrItems.erase(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(); + } + + //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 +3202,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<int, std::map<int, unsigned int>>::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 +3222,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 +3255,7 @@ namespace OOX { m_oHt.Init(); m_oHt->SetValue(atof(oReader.GetTextChar())); - + m_oCustomHeight.Init(); m_oCustomHeight->SetValue(SimpleTypes::onoffTrue); } @@ -2602,7 +3407,7 @@ namespace OOX return; CXlsx* xlsx = dynamic_cast<CXlsx*>(m_pMainDocument); CXlsxFlat* xlsx_flat = dynamic_cast<CXlsxFlat*>(m_pMainDocument); - + if(xlsx) { xlsx->m_nLastReadRow = 0; @@ -2671,11 +3476,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 +3492,7 @@ namespace OOX { CXlsxFlat* xlsx_flat = dynamic_cast<CXlsxFlat*>(m_pMainDocument); if (!xlsx_flat) return; - + CWorksheet* pWorksheet = xlsx_flat->m_arWorksheets.back(); pWorksheet->m_oSheetFormatPr.Init(); @@ -2848,6 +3653,20 @@ namespace OOX m_arrItems.push_back(pRow); }*/ } + 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)); + it = m_arrItems.erase(it); + } + + return objectPtr; + } EElementType CSheetData::getType () const { return et_x_SheetData; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 89cc1773636..fb7b09dc4be 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -33,6 +33,7 @@ #include "../SharedStrings/Si.h" #include "../../Common/SimpleTypes_Shared.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/CellRef.h" namespace NSBinPptxRW { @@ -97,7 +98,9 @@ namespace OOX CTextXLSB m_oValue; CFormulaXLSB m_oFormula; nullable<CSi> m_oRichText; - + + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; protected: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; @@ -125,6 +128,11 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; + struct sharedFormula + { + std::vector<XLS::CellRef> shrFmla; + std::vector<std::pair<XLS::CellRangeRef, XLS::CellRef>> arrfmla; + }; class CFormula : public WritingElement { public: @@ -141,6 +149,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream); void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nFlags); void fromBin(XLS::BaseObjectPtr& obj, SimpleTypes::Spreadsheet::ECellFormulaType eType); + void toBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -215,6 +224,7 @@ namespace OOX void fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, _UINT32 nRow); void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; @@ -234,9 +244,10 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); void ReadComment(XmlUtils::CXmlLiteReader& oReader, CCommentItem* pComment); + bool checkArrayCell(XLS::CellRef &cellref, const sharedFormula& ArrFmlas); void AfterRead(); - //----------- 2003 + //----------- 2003 void After2003Read(); nullable<CCommentItem> pCommentItem; @@ -247,11 +258,11 @@ namespace OOX nullable_int iAcross; nullable_int iDown; public: - nullable<SimpleTypes::CUnsignedDecimalNumber> m_oCellMetadata; - nullable<SimpleTypes::COnOff> m_oShowPhonetic; - nullable_uint m_oStyle; nullable<SimpleTypes::Spreadsheet::CCellTypeType> m_oType; - nullable<SimpleTypes::CUnsignedDecimalNumber> m_oValueMetadata; + nullable<SimpleTypes::COnOff> m_oShowPhonetic; + nullable_uint m_oStyle; + nullable_uint m_oCellMetadata; + nullable_uint m_oValueMetadata; nullable<std::string> m_oRef; nullable_uint m_oRow; @@ -259,7 +270,7 @@ namespace OOX nullable<CFormula> m_oFormula; nullable<CSi> m_oRichText; nullable<CText> m_oValue; -//----------------------------- +//----------------------------- nullable_string m_oCacheValue; }; @@ -281,8 +292,9 @@ 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); + XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); virtual EElementType getType () const; @@ -324,11 +336,12 @@ 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); + XLS::BaseObjectPtr toBin(); virtual EElementType getType () const; - + nullable<SimpleTypes::CUnsignedDecimalNumber> m_oXlsbPos; - + std::map<int, std::map<int, unsigned int>> m_mapStyleMerges2003; // map(row, map(col, style)) void StyleFromMapStyleMerges2003(std::map<int, unsigned int> &mapStyleMerges); void AfterRead(); diff --git a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp index 9263752056f..d407a3461ff 100644 --- a/OOXML/XlsxFormat/Worksheets/Sparkline.cpp +++ b/OOXML/XlsxFormat/Worksheets/Sparkline.cpp @@ -92,6 +92,32 @@ 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.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 +201,17 @@ namespace OOX m_arrItems.push_back(new CSparkline(sparkline)); } } + std::vector<XLS::BaseObjectPtr> CSparklines::toBin() + { + std::vector<XLS::BaseObjectPtr> sparclineVector; + + for(auto i:m_arrItems) + { + sparclineVector.push_back(i->toBin()); + } + + return sparclineVector; + } EElementType CSparklines::getType () const { return et_x_Sparklines; @@ -393,6 +430,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_cast<decltype(ptr->isltype)>(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 +769,14 @@ namespace OOX m_arrItems.push_back(new CSparklineGroup(sparklineGroup)); } } + XLS::BaseObjectPtr CSparklineGroups::toBin() + { + auto ptr(new XLSB::SPARKLINEGROUPS); + XLS::BaseObjectPtr objectPtr(ptr); + 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<XLS::BaseObjectPtr> 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<CXlsb*>(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<CXlsb*>(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<OOX::File> oFile = this->Find(m_oLegacyDrawing->m_oId->GetValue()); smart_ptr<OOX::CVmlDrawing> oVmlDrawing = oFile.smart_dynamic_cast<OOX::CVmlDrawing>(); 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<CXlsb*>(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<CXlsb*>(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 e186cbc5b3b..6a49b1eafb0 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,49 @@ 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 = ptr->ipdPasswordData.rgbHash.rgbData.data(); + 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; + + BYTE* temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + 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 +283,15 @@ namespace OOX } } } + std::vector<XLS::BaseObjectPtr> CProtectedRanges::toBin() + { + std::vector<XLS::BaseObjectPtr> result; + for(auto i:m_arrItems) + { + result.push_back(i->toBin()); + } + return result; + } void CProtectedRanges::fromBin(std::vector<XLS::BaseObjectPtr>& obj) { for (auto &protRange : obj) @@ -386,6 +439,31 @@ 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; + + if(m_oTop.IsInit()) + ptr->xnumTop.data.value = std::round(m_oTop->GetValue()) / 100; + + if(m_oRight.IsInit()) + ptr->xnumRight.data.value = std::round(m_oRight->GetValue()) / 100; + + if(m_oBottom.IsInit()) + ptr->xnumBottom.data.value = std::round(m_oBottom->GetValue()) / 100; + + if(m_oHeader.IsInit()) + ptr->xnumHeader.data.value = std::round(m_oHeader->GetValue()) / 100; + + if(m_oFooter.IsInit()) + ptr->xnumFooter.data.value = std::round(m_oFooter->GetValue()) / 100; + + return objPtr; + } EElementType CPageMargins::getType() const { return et_x_PageMargins; @@ -478,6 +556,145 @@ 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; + 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; + + if (m_oErrors.IsInit()) + ptr->iErrors = m_oErrors->m_eValue; + + 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; + + 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; + if (ptr->fNoColor) + { + 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; + + if (m_oDraft.IsInit()) + ptr->fDraft = m_oDraft->m_eValue; + + if (m_oFirstPageNumber.IsInit()) + ptr->iPageStart = m_oFirstPageNumber->m_eValue; + + if (m_oHorizontalDpi.IsInit()) + ptr->iRes = m_oHorizontalDpi->m_eValue; + + 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; + + if (m_oUseFirstPageNumber.IsInit()) + ptr->fUsePage = m_oUseFirstPageNumber->m_eValue; + + if (m_oVerticalDpi.IsInit()) + ptr->iVRes = m_oVerticalDpi->m_eValue; + return objectPtr; + } + EElementType CPageSetup::getType() const { return et_x_PageSetup; @@ -623,6 +840,23 @@ 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; + if(m_oGridLinesSet.IsInit()) + ptr->fPrintGrid = m_oGridLinesSet->m_eValue; + if(m_oHeadings.IsInit()) + ptr->fPrintHeaders = m_oHeadings->m_eValue; + if(m_oHorizontalCentered.IsInit()) + ptr->fHCenter = m_oHorizontalCentered->m_eValue; + if(m_oVerticalCentered.IsInit()) + ptr->fVCenter = m_oVerticalCentered->m_eValue; + + return objectPtr; + } EElementType CPrintOptions::getType() const { return et_x_PrintOptions; @@ -677,6 +911,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 +933,7 @@ namespace OOX { auto ptr = static_cast<XLSB::WsDim*>(obj.get()); if (ptr != nullptr) - m_oRef = ptr->rfx.toString(); + m_oRef = ptr->rfx.toString(true, true); } CSheetFormatPr::CSheetFormatPr() @@ -732,6 +974,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; @@ -808,6 +1093,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 +1204,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 +1370,111 @@ 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; + if(m_oWorkbookViewId.IsInit()) + pWsView->iWbkView = m_oWorkbookViewId->m_eValue; + if(m_oZoomScale.IsInit()) + pWsView->wScale = m_oZoomScale->m_eValue; + return castedPtr; + } EElementType CSheetView::getType() const { return et_x_SheetView; @@ -1152,6 +1614,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 +1665,18 @@ namespace OOX { ReadAttributes(obj); } + void CPageSetUpPr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast<XLSB::WsProp*>(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 +1687,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 +1731,26 @@ namespace OOX { ReadAttributes(obj); } + void COutlinePr::toBin(XLS::BaseObjectPtr& obj) + { + auto ptr = static_cast<XLSB::WsProp*>(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 +1838,81 @@ 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(); + if(m_oPublished.IsInit()) + ptr->fPublish = m_oPublished->GetValue(); + if(m_oTabColor.IsInit()) + ptr->brtcolorTab = m_oTabColor->toColor(); + return XLS::BaseObjectPtr{ptr}; + } + void CSheetPr::fromBin(XLS::BaseObjectPtr& obj) { if (obj->get_type() == XLS::typeWsProp) @@ -1563,6 +2147,50 @@ 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; + if(m_oDifferentFirst.IsInit()) + castedBegin->fHFDiffFirst = m_oDifferentFirst->m_eValue; + if(m_oDifferentOddEven.IsInit()) + castedBegin->fHFDiffOddEven = m_oDifferentOddEven->m_eValue; + if(m_oScaleWithDoc.IsInit()) + castedBegin->fHFScaleWithDoc = m_oScaleWithDoc->m_eValue; + + 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 +2267,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 +2341,16 @@ 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(); + + return objectPtr; + } void CPictureWorksheet::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1759,6 +2405,24 @@ 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(); + if(m_oMax.IsInit()) + ptr->unColRwStrt = m_oMax->GetValue(); + if(m_oMin.IsInit()) + ptr->unColRwEnd = m_oMin->GetValue(); + if(m_oPt.IsInit()) + ptr->fPivot = m_oPt->GetValue(); + + return objectPtr; + } void CBreak::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -1845,6 +2509,40 @@ 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(); + if(m_oManualBreakCount.IsInit()) + rowPtr->ibrkManMac = m_oManualBreakCount->GetValue(); + 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 +2652,271 @@ 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->GetValue(); + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + if(m_oHashValue.IsInit()) + { + BYTE * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + 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; + } + + if(m_oSaltValue.IsInit()) + { + BYTE * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + + 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->GetValue(); + else + ptr->ipdPasswordData.szAlgName = false; + if(m_oSpinCount.IsInit()) + ptr->dwSpinCount = m_oSpinCount->GetValue(); + else + ptr->dwSpinCount = 0; + + if(m_oHashValue.IsInit()) + { + BYTE * temp = ptr->ipdPasswordData.rgbHash.rgbData.data(); + 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; + } + + if(m_oSaltValue.IsInit()) + { + BYTE * temp2 = ptr->ipdPasswordData.rgbSalt.rgbData.data(); + auto tempSize2 = 0; + NSFile::CBase64Converter::Decode(std::string{m_oSaltValue.get().begin(), + m_oSaltValue.get().end()}.c_str(), m_oSaltValue.get().size(), temp2, tempSize2); + ptr->ipdPasswordData.rgbSalt.cbLength = tempSize2; + } + + 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 +3065,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 +3109,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 +3184,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 +3249,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<XLSB::DCON*>(obj.get()); @@ -2301,6 +3336,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 +3367,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 +3385,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 +3398,7 @@ namespace OOX writer.WriteString(L"<userProtectedRange"); WritingStringNullableAttrEncodeXmlString2(L"name", m_oName); WritingStringNullableAttrString(L"sqref", m_oSqref, *m_oSqref); + WritingStringNullableAttrString(L"type", m_oType, m_oType->ToString()) writer.WriteString(L">"); if (m_oText.IsInit()) @@ -2376,6 +3415,7 @@ namespace OOX writer.WriteString(L"<user"); WritingStringNullableAttrEncodeXmlString2(L"id", m_arUsers[i].id); WritingStringNullableAttrEncodeXmlString2(L"name", m_arUsers[i].name); + WritingStringNullableAttrString(L"type", m_arUsers[i].type, m_arUsers[i].type->ToString()) writer.WriteString(L"/>"); } writer.WriteString(L"</users>"); @@ -2388,6 +3428,7 @@ namespace OOX writer.WriteString(L"<usersGroup"); WritingStringNullableAttrEncodeXmlString2(L"id", m_arUsersGroups[i].id); WritingStringNullableAttrEncodeXmlString2(L"name", m_arUsersGroups[i].name); + WritingStringNullableAttrString(L"type", m_arUsersGroups[i].type, m_arUsersGroups[i].type->ToString()) writer.WriteString(L"/>"); } writer.WriteString(L"</usersGroups>"); 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<XLS::BaseObjectPtr>& obj); + std::vector<XLS::BaseObjectPtr> 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<SimpleTypes::Spreadsheet::CUserProtectedRangeType> type; }; WritingElement_AdditionMethods(CUserProtectedRange) @@ -860,6 +891,7 @@ namespace OOX nullable_string m_oName; nullable_string m_oSqref; nullable_string m_oText; + nullable<SimpleTypes::Spreadsheet::CUserProtectedRangeType> 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/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.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx index 6f10ff38a5c..173807f5668 100644 Binary files a/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx and b/OOXML/test/ExampleFiles/xlsb2xlsx/simple1.xlsx differ diff --git a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx b/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx index e49f4060d7f..0d577fe0801 100644 Binary files a/OOXML/test/ExampleFiles/xlsb2xlsx/simple2.xlsx 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 index cde7cd8c13e..daac3751ae1 100644 --- a/OOXML/test/common.cpp +++ b/OOXML/test/common.cpp @@ -95,14 +95,6 @@ std::wstring CreateParamsFile(const std::wstring &pathFrom, const std::wstring & oBuilder.WriteEncodeXmlString(pathTo); oBuilder.WriteString(L"</m_sFileTo>"); - oBuilder.WriteString(L"<m_nFormatTo>"); - int nFormat = COfficeFileFormatChecker::GetFormatByExtension(L"." + NSFile::GetFileExtention(pathTo)); - oBuilder.WriteString(std::to_wstring(nFormat)); - oBuilder.WriteString(L"</m_nFormatTo>"); - - if (nFormat == AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA) - oBuilder.WriteString(L"<m_bIsPDFA>true</m_bIsPDFA>"); - // changes oBuilder.WriteString(L"<m_bFromChanges>false</m_bFromChanges>"); diff --git a/OOXML/test/test.pro b/OOXML/test/test.pro index 4763e64c7c6..d9ab1094cd3 100644 --- a/OOXML/test/test.pro +++ b/OOXML/test/test.pro @@ -14,7 +14,8 @@ SOURCES += $$X2T_DIR/src/dylib/x2t.cpp SOURCES += main.cpp\ common.cpp\ - xlsb2xlsx/conversion.cpp + xlsb2xlsx/conversion.cpp\ + xlsx2xlsb/conversion.cpp\ HEADERS += common.h diff --git a/OOXML/test/xlsb2xlsx/conversion.cpp b/OOXML/test/xlsb2xlsx/conversion.cpp index 92dd5e9091f..f5677e1ffc6 100644 --- a/OOXML/test/xlsb2xlsx/conversion.cpp +++ b/OOXML/test/xlsb2xlsx/conversion.cpp @@ -92,8 +92,29 @@ class SimpleTests2 : public ::testing::Test 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 ) { @@ -243,3 +264,65 @@ TEST_F(SimpleTests2, WorksheetsTest) 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 <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <fstream> +#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<char> &fileContent, std::vector<char> &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<char>((std::istreambuf_iterator<char>(file1)), std::istreambuf_iterator<char>()); + exampleContent = std::vector<char>((std::istreambuf_iterator<char>(file2)), std::istreambuf_iterator<char>()); + + 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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<char> fileContent; + std::vector<char> 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 79d4ea8c3af..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, @@ -574,6 +575,7 @@ enum ElementType typeOfficeScripts, typeOfficeScript, typeOfficePresentation, + typeOfficeDrawing, typeOfficeChart, typeOfficeEventListeners, diff --git a/OdfFile/DataTypes/borderstyle.cpp b/OdfFile/DataTypes/borderstyle.cpp index 7c37ae92421..2ca43a3561c 100644 --- a/OdfFile/DataTypes/borderstyle.cpp +++ b/OdfFile/DataTypes/borderstyle.cpp @@ -52,6 +52,10 @@ std::wostream & operator << (std::wostream & _Wostream, const border_style & bor 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::dash_dot: _Wostream << L" dash-dot "; break; + case border_style::dash_dot_dot: _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; @@ -126,6 +130,10 @@ border_style::border_style(const std::wstring & Value) : initialized_(false), no 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"dash-dot") style_ = dash_dot; + if (splitted[1] == L"dash-dot-dot") style_ = dash_dot_dot; + if (splitted[1] == L"fine-dashed") style_ = fine_dashed; + if (splitted[1] == L"double-thin") style_ = double_thin; } if (splitted.size() > 2) diff --git a/OdfFile/DataTypes/borderstyle.h b/OdfFile/DataTypes/borderstyle.h index ec77b9f0c07..610607724b0 100644 --- a/OdfFile/DataTypes/borderstyle.h +++ b/OdfFile/DataTypes/borderstyle.h @@ -56,8 +56,11 @@ class border_style ridge, inset, outset, - hidden - + hidden, + dash_dot, + dash_dot_dot, + fine_dashed, + double_thin }; border_style(){none_ = true;} diff --git a/OdfFile/DataTypes/common_attlists.cpp b/OdfFile/DataTypes/common_attlists.cpp index 00dec9e10d3..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_) { diff --git a/OdfFile/DataTypes/custom_shape_types_convert.h b/OdfFile/DataTypes/custom_shape_types_convert.h index b61cb447108..97b7e0e4364 100644 --- a/OdfFile/DataTypes/custom_shape_types_convert.h +++ b/OdfFile/DataTypes/custom_shape_types_convert.h @@ -30,6 +30,7 @@ * */ #pragma once +#include <string> struct _shape_converter { 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/presentationclass.cpp b/OdfFile/DataTypes/presentationclass.cpp index 6b2e55635e0..614a727887e 100644 --- a/OdfFile/DataTypes/presentationclass.cpp +++ b/OdfFile/DataTypes/presentationclass.cpp @@ -102,7 +102,7 @@ std::wstring presentation_class::get_type_ms() res = L"body"; break; case object: - res = L"obj"; + res = L"body"; break; case chart: res = L"chart"; @@ -132,7 +132,7 @@ std::wstring presentation_class::get_type_ms() res = L"body"; break; case page: - res = L"sldImg"; + res = L"pic"; break; } return res; 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 <boost/algorithm/string.hpp> +#include <ostream> + +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 <iosfwd> +#include <string> +#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/Formulas/formulasconvert_oox.cpp b/OdfFile/Formulas/formulasconvert_oox.cpp index ab1bae259ec..a45a6928c67 100644 --- a/OdfFile/Formulas/formulasconvert_oox.cpp +++ b/OdfFile/Formulas/formulasconvert_oox.cpp @@ -773,7 +773,7 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr) 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]) diff --git a/OdfFile/Projects/Linux/OdfFormatLib.pro b/OdfFile/Projects/Linux/OdfFormatLib.pro index 45e696350e0..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,7 +42,8 @@ SOURCES += \ core_debug { SOURCES += \ - ../../DataTypes/mathvariant.cpp \ + ../../DataTypes/referenceformat.cpp \ + ../../DataTypes/mathvariant.cpp \ ../../DataTypes/anchortype.cpp \ ../../DataTypes/animation_attlists.cpp \ ../../DataTypes/backgroundcolor.cpp \ @@ -202,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 \ @@ -445,7 +449,8 @@ 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 \ @@ -592,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 \ diff --git a/OdfFile/Projects/Linux/odf_datatypes.cpp b/OdfFile/Projects/Linux/odf_datatypes.cpp index b13da53e57f..ca12641c14d 100644 --- a/OdfFile/Projects/Linux/odf_datatypes.cpp +++ b/OdfFile/Projects/Linux/odf_datatypes.cpp @@ -153,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/cpcommon.vcxproj b/OdfFile/Projects/Windows/cpcommon.vcxproj index 55607999e58..e4890c3f57a 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj @@ -253,6 +253,7 @@ <ClInclude Include="..\..\DataTypes\presetclass.h" /> <ClInclude Include="..\..\DataTypes\presetid.h" /> <ClInclude Include="..\..\DataTypes\punctuationwrap.h" /> + <ClInclude Include="..\..\DataTypes\referenceformat.h" /> <ClInclude Include="..\..\DataTypes\rotationalign.h" /> <ClInclude Include="..\..\DataTypes\runthrough.h" /> <ClInclude Include="..\..\DataTypes\scripttype.h" /> @@ -383,6 +384,7 @@ <ClCompile Include="..\..\DataTypes\presetclass.cpp" /> <ClCompile Include="..\..\DataTypes\presetid.cpp" /> <ClCompile Include="..\..\DataTypes\punctuationwrap.cpp" /> + <ClCompile Include="..\..\DataTypes\referenceformat.cpp" /> <ClCompile Include="..\..\DataTypes\rotationalign.cpp" /> <ClCompile Include="..\..\DataTypes\runthrough.cpp" /> <ClCompile Include="..\..\DataTypes\scripttype.cpp" /> diff --git a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters index 41ae74406d6..909e9e65ba4 100644 --- a/OdfFile/Projects/Windows/cpcommon.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpcommon.vcxproj.filters @@ -126,6 +126,10 @@ <ClCompile Include="..\..\DataTypes\writingmode.cpp" /> <ClCompile Include="..\..\DataTypes\xlink.cpp" /> <ClCompile Include="..\..\DataTypes\animation_attlists.cpp" /> + <ClCompile Include="..\..\DataTypes\presentationvisibility.cpp" /> + <ClCompile Include="..\..\DataTypes\tabledatatype.cpp" /> + <ClCompile Include="..\..\DataTypes\tableoperator.cpp" /> + <ClCompile Include="..\..\DataTypes\referenceformat.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Common\CPColorUtils.h" /> @@ -143,15 +147,133 @@ <ClInclude Include="..\..\Common\utils.h" /> <ClInclude Include="..\..\Common\writedocelement.h" /> <ClInclude Include="..\..\Common\errors.h" /> - <ClInclude Include="..\..\DataTypes\sparklines.h"> - <Filter>datatypes odf</Filter> - </ClInclude> - <ClInclude Include="..\..\DataTypes\tabledatatype.h"> - <Filter>datatypes odf</Filter> - </ClInclude> - <ClInclude Include="..\..\DataTypes\tableoperator.h"> - <Filter>datatypes odf</Filter> - </ClInclude> + <ClInclude Include="..\..\DataTypes\anchortype.h" /> + <ClInclude Include="..\..\DataTypes\animation_attlists.h" /> + <ClInclude Include="..\..\DataTypes\backgroundcolor.h" /> + <ClInclude Include="..\..\DataTypes\bibliography.h" /> + <ClInclude Include="..\..\DataTypes\bool.h" /> + <ClInclude Include="..\..\DataTypes\bordermodel.h" /> + <ClInclude Include="..\..\DataTypes\borderstyle.h" /> + <ClInclude Include="..\..\DataTypes\borderwidths.h" /> + <ClInclude Include="..\..\DataTypes\calcext_type.h" /> + <ClInclude Include="..\..\DataTypes\chartclass.h" /> + <ClInclude Include="..\..\DataTypes\chartdatalabelnumber.h" /> + <ClInclude Include="..\..\DataTypes\charterrorcategory.h" /> + <ClInclude Include="..\..\DataTypes\chartinterpolation.h" /> + <ClInclude Include="..\..\DataTypes\chartlabelarrangement.h" /> + <ClInclude Include="..\..\DataTypes\chartlabelposition.h" /> + <ClInclude Include="..\..\DataTypes\chartregressiontype.h" /> + <ClInclude Include="..\..\DataTypes\chartseriessource.h" /> + <ClInclude Include="..\..\DataTypes\chartsolidtype.h" /> + <ClInclude Include="..\..\DataTypes\chartsymbol.h" /> + <ClInclude Include="..\..\DataTypes\charttimeunit.h" /> + <ClInclude Include="..\..\DataTypes\clockvalue.h" /> + <ClInclude Include="..\..\DataTypes\color.h" /> + <ClInclude Include="..\..\DataTypes\commandtype.h" /> + <ClInclude Include="..\..\DataTypes\common_attlists.h" /> + <ClInclude Include="..\..\DataTypes\custom_shape_types_convert.h" /> + <ClInclude Include="..\..\DataTypes\dategroup.h" /> + <ClInclude Include="..\..\DataTypes\direction.h" /> + <ClInclude Include="..\..\DataTypes\drawangle.h" /> + <ClInclude Include="..\..\DataTypes\drawfill.h" /> + <ClInclude Include="..\..\DataTypes\dropcaplength.h" /> + <ClInclude Include="..\..\DataTypes\errors.h" /> + <ClInclude Include="..\..\DataTypes\fillimagerefpoint.h" /> + <ClInclude Include="..\..\DataTypes\fobreak.h" /> + <ClInclude Include="..\..\DataTypes\fontfamilygeneric.h" /> + <ClInclude Include="..\..\DataTypes\fontpitch.h" /> + <ClInclude Include="..\..\DataTypes\fontrelief.h" /> + <ClInclude Include="..\..\DataTypes\fontsize.h" /> + <ClInclude Include="..\..\DataTypes\fontstretch.h" /> + <ClInclude Include="..\..\DataTypes\fontstyle.h" /> + <ClInclude Include="..\..\DataTypes\fontvariant.h" /> + <ClInclude Include="..\..\DataTypes\fontweight.h" /> + <ClInclude Include="..\..\DataTypes\gradientstyle.h" /> + <ClInclude Include="..\..\DataTypes\grandtotal.h" /> + <ClInclude Include="..\..\DataTypes\hatchstyle.h" /> + <ClInclude Include="..\..\DataTypes\hyphenationkeep.h" /> + <ClInclude Include="..\..\DataTypes\hyphenationladdercount.h" /> + <ClInclude Include="..\..\DataTypes\iconset_type.h" /> + <ClInclude Include="..\..\DataTypes\keeptogether.h" /> + <ClInclude Include="..\..\DataTypes\layoutgridmode.h" /> + <ClInclude Include="..\..\DataTypes\length.h" /> + <ClInclude Include="..\..\DataTypes\lengthorpercent.h" /> + <ClInclude Include="..\..\DataTypes\letterspacing.h" /> + <ClInclude Include="..\..\DataTypes\linebreak.h" /> + <ClInclude Include="..\..\DataTypes\linemode.h" /> + <ClInclude Include="..\..\DataTypes\linestyle.h" /> + <ClInclude Include="..\..\DataTypes\linetype.h" /> + <ClInclude Include="..\..\DataTypes\linewidth.h" /> + <ClInclude Include="..\..\DataTypes\markerstyle.h" /> + <ClInclude Include="..\..\DataTypes\mathvariant.h" /> + <ClInclude Include="..\..\DataTypes\membertype.h" /> + <ClInclude Include="..\..\DataTypes\messagetype.h" /> + <ClInclude Include="..\..\DataTypes\noteclass.h" /> + <ClInclude Include="..\..\DataTypes\odfattributes.h" /> + <ClInclude Include="..\..\DataTypes\officevaluetype.h" /> + <ClInclude Include="..\..\DataTypes\pageusage.h" /> + <ClInclude Include="..\..\DataTypes\percent.h" /> + <ClInclude Include="..\..\DataTypes\percentorscale.h" /> + <ClInclude Include="..\..\DataTypes\presentationclass.h" /> + <ClInclude Include="..\..\DataTypes\presentationnodetype.h" /> + <ClInclude Include="..\..\DataTypes\presentationvisibility.h" /> + <ClInclude Include="..\..\DataTypes\presetclass.h" /> + <ClInclude Include="..\..\DataTypes\presetid.h" /> + <ClInclude Include="..\..\DataTypes\punctuationwrap.h" /> + <ClInclude Include="..\..\DataTypes\rotationalign.h" /> + <ClInclude Include="..\..\DataTypes\runthrough.h" /> + <ClInclude Include="..\..\DataTypes\scripttype.h" /> + <ClInclude Include="..\..\DataTypes\shadowtype.h" /> + <ClInclude Include="..\..\DataTypes\smil_additive.h" /> + <ClInclude Include="..\..\DataTypes\smil_attributename.h" /> + <ClInclude Include="..\..\DataTypes\smil_fill.h" /> + <ClInclude Include="..\..\DataTypes\smil_keytimes.h" /> + <ClInclude Include="..\..\DataTypes\smil_transitiontype.h" /> + <ClInclude Include="..\..\DataTypes\smil_values.h" /> + <ClInclude Include="..\..\DataTypes\sparklines.h" /> + <ClInclude Include="..\..\DataTypes\stylecellprotect.h" /> + <ClInclude Include="..\..\DataTypes\stylefamily.h" /> + <ClInclude Include="..\..\DataTypes\stylehorizontalpos.h" /> + <ClInclude Include="..\..\DataTypes\stylehorizontalrel.h" /> + <ClInclude Include="..\..\DataTypes\styleleadercolor.h" /> + <ClInclude Include="..\..\DataTypes\stylenumformat.h" /> + <ClInclude Include="..\..\DataTypes\styleposition.h" /> + <ClInclude Include="..\..\DataTypes\styleprint.h" /> + <ClInclude Include="..\..\DataTypes\stylerepeat.h" /> + <ClInclude Include="..\..\DataTypes\styletype.h" /> + <ClInclude Include="..\..\DataTypes\styleverticalpos.h" /> + <ClInclude Include="..\..\DataTypes\styleverticalrel.h" /> + <ClInclude Include="..\..\DataTypes\stylewrap.h" /> + <ClInclude Include="..\..\DataTypes\stylewrapcontourmode.h" /> + <ClInclude Include="..\..\DataTypes\style_ref.h" /> + <ClInclude Include="..\..\DataTypes\svg_type.h" /> + <ClInclude Include="..\..\DataTypes\tablealign.h" /> + <ClInclude Include="..\..\DataTypes\tablecentering.h" /> + <ClInclude Include="..\..\DataTypes\tabledatatype.h" /> + <ClInclude Include="..\..\DataTypes\tablefunction.h" /> + <ClInclude Include="..\..\DataTypes\tablemode.h" /> + <ClInclude Include="..\..\DataTypes\tableoperator.h" /> + <ClInclude Include="..\..\DataTypes\tableorder.h" /> + <ClInclude Include="..\..\DataTypes\tableorientation.h" /> + <ClInclude Include="..\..\DataTypes\tabletype.h" /> + <ClInclude Include="..\..\DataTypes\tablevisibility.h" /> + <ClInclude Include="..\..\DataTypes\targetframename.h" /> + <ClInclude Include="..\..\DataTypes\textalign.h" /> + <ClInclude Include="..\..\DataTypes\textalignsource.h" /> + <ClInclude Include="..\..\DataTypes\textautospace.h" /> + <ClInclude Include="..\..\DataTypes\textcombine.h" /> + <ClInclude Include="..\..\DataTypes\textdisplay.h" /> + <ClInclude Include="..\..\DataTypes\textemphasize.h" /> + <ClInclude Include="..\..\DataTypes\textposition.h" /> + <ClInclude Include="..\..\DataTypes\textrotationscale.h" /> + <ClInclude Include="..\..\DataTypes\texttransform.h" /> + <ClInclude Include="..\..\DataTypes\timeperiod.h" /> + <ClInclude Include="..\..\DataTypes\underlinecolor.h" /> + <ClInclude Include="..\..\DataTypes\verticalalign.h" /> + <ClInclude Include="..\..\DataTypes\wrapoption.h" /> + <ClInclude Include="..\..\DataTypes\writingmode.h" /> + <ClInclude Include="..\..\DataTypes\xlink.h" /> + <ClInclude Include="..\..\DataTypes\referenceformat.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\Common\CPColorUtils.cpp" /> @@ -489,11 +611,5 @@ <ClCompile Include="..\..\DataTypes\sparklines.cpp"> <Filter>datatypes odf</Filter> </ClCompile> - <ClCompile Include="..\..\DataTypes\tabledatatype.cpp"> - <Filter>datatypes odf</Filter> - </ClCompile> - <ClCompile Include="..\..\DataTypes\tableoperator.cpp"> - <Filter>datatypes odf</Filter> - </ClCompile> </ItemGroup> </Project> \ No newline at end of file diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj b/OdfFile/Projects/Windows/cpodf.vcxproj index 9261997573f..dcb8f521d8c 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj +++ b/OdfFile/Projects/Windows/cpodf.vcxproj @@ -282,6 +282,8 @@ <ClCompile Include="..\..\Reader\Converter\pptx_text_context.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> </ClCompile> + <ClCompile Include="..\..\Reader\Converter\StarMath2OOXML\cconversionsmtoooxml.cpp" /> + <ClCompile Include="..\..\Reader\Converter\StarMath2OOXML\cstarmathpars.cpp" /> <ClCompile Include="..\..\Reader\Converter\xlsxconversioncontext.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> </ClCompile> @@ -510,6 +512,7 @@ <ClCompile Include="..\..\Reader\Format\office_document.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> </ClCompile> + <ClCompile Include="..\..\Reader\Format\office_drawing.cpp" /> <ClCompile Include="..\..\Reader\Format\office_elements_create.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> </ClCompile> @@ -551,6 +554,7 @@ </ClCompile> <ClCompile Include="..\..\Reader\Format\styles.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions> </ClCompile> <ClCompile Include="..\..\Reader\Format\styles_list.cpp"> <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions> @@ -675,6 +679,9 @@ <ClInclude Include="..\..\Reader\Converter\pptx_slide_context.h" /> <ClInclude Include="..\..\Reader\Converter\pptx_table_context.h" /> <ClInclude Include="..\..\Reader\Converter\pptx_text_context.h" /> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\cconversionsmtoooxml.h" /> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\cstarmathpars.h" /> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\typeselements.h" /> <ClInclude Include="..\..\Reader\Converter\xlsxconversioncontext.h" /> <ClInclude Include="..\..\Reader\Converter\xlsx_alignment.h" /> <ClInclude Include="..\..\Reader\Converter\xlsx_border.h" /> @@ -747,6 +754,7 @@ <ClInclude Include="..\..\Reader\Format\office_body.h" /> <ClInclude Include="..\..\Reader\Format\office_chart.h" /> <ClInclude Include="..\..\Reader\Format\office_document.h" /> + <ClInclude Include="..\..\Reader\Format\office_drawing.h" /> <ClInclude Include="..\..\Reader\Format\office_elements.h" /> <ClInclude Include="..\..\Reader\Format\office_elements_create.h" /> <ClInclude Include="..\..\Reader\Format\office_event_listeners.h" /> diff --git a/OdfFile/Projects/Windows/cpodf.vcxproj.filters b/OdfFile/Projects/Windows/cpodf.vcxproj.filters index 7ab9701d637..68c27b33cff 100644 --- a/OdfFile/Projects/Windows/cpodf.vcxproj.filters +++ b/OdfFile/Projects/Windows/cpodf.vcxproj.filters @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="oox"> @@ -25,6 +25,9 @@ <Filter Include="elements"> <UniqueIdentifier>{67b2bf43-5673-4a6f-82cb-fe4be01aee5f}</UniqueIdentifier> </Filter> + <Filter Include="starmath"> + <UniqueIdentifier>{7d3e34d2-a224-4d68-9144-4889bbcc3698}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\Reader\Format\abstract_xml.cpp"> @@ -481,6 +484,14 @@ <ClCompile Include="..\..\Reader\Converter\pptx_animation_context.cpp"> <Filter>oox\pptx</Filter> </ClCompile> + <ClCompile Include="..\..\Reader\Converter\StarMath2OOXML\cconversionsmtoooxml.cpp"> + <Filter>starmath</Filter> + </ClCompile> + <ClCompile Include="..\..\Reader\Converter\StarMath2OOXML\cstarmathpars.cpp"> + <Filter>starmath</Filter> + <ClCompile Include="..\..\Reader\Format\office_drawing.cpp"> + <Filter>elements</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\Reader\Format\abstract_xml.h"> @@ -934,5 +945,16 @@ <ClInclude Include="..\..\Reader\Converter\pptx_animation_context.h"> <Filter>oox\pptx</Filter> </ClInclude> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\cconversionsmtoooxml.h"> + <Filter>starmath</Filter> + </ClInclude> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\cstarmathpars.h"> + <Filter>starmath</Filter> + </ClInclude> + <ClInclude Include="..\..\Reader\Converter\StarMath2OOXML\typeselements.h"> + <Filter>starmath</Filter> + <ClInclude Include="..\..\Reader\Format\office_drawing.h"> + <Filter>elements</Filter> + </ClInclude> </ItemGroup> </Project> \ 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..625d8c8076c --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/StarMath2OOXML.pri @@ -0,0 +1,17 @@ + +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(UnicodeConverter, kernel) + +SOURCES += $$PWD/cconversionsmtoooxml.cpp \ + $$PWD/cstarmathpars.cpp + +HEADERS += \ + $$PWD/cconversionsmtoooxml.h \ + $$PWD/cstarmathpars.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..b1d512c0278 --- /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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+3</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00B78</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00D78</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>*2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00F72</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>226</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2295179</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>226</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2299179</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>226</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2297179</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:subHide m:val=\"1\" /><m:supHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub/><m:sup/><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:supHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sub><m:sup/><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:subHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub/><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>666</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>777</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>567</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>23</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>45</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1234</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2216</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15745</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>91</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2215</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>45</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2282</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>77</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2286</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>66</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2283</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>22</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2287</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>21</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2284</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>782</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2288</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>250</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2285</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2289</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2208</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2209</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u220B</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>6</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u21D0</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>9</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u21D4</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u21D2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>12</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>13</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>14</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2260</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>16</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>17</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t><</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>18</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>19</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2264</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>20</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>21</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>></m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>22</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>23</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2265</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>24</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>25</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u226A</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>26</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>27</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u226B</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>28</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>29</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2248</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>30</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>31</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u223C</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>32</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>33</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2243</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>34</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>35</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2261</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>36</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>37</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u221D</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>38</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>39</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2225</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>30</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>41</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22A5</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>42</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>43</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2223</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>44</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>45</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2224</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>46</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>47</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2192</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>48</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>49</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22B7</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>50</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>51</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22B6</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>52</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>53</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u225D</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>54</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>55</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227A</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>56</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>57</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227B</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>58</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>59</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227C</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>60</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>61</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227D</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>62</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>63</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227E</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>64</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>65</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u227F</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>66</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>67</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2280</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>68</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>69</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2281</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>70</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+3</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u005B\" /><m:endChr m:val=\"\u005D\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-5</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u27E6\" /><m:endChr m:val=\"\u27E7\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>6</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+7</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u007B\" /><m:endChr m:val=\"\u007D\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-9</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u27E8\" /><m:endChr m:val=\"\u27E9\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2308\" /><m:endChr m:val=\"\u2309\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>12</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229613</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u230A\" /><m:endChr m:val=\"\u230B\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>14</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u007C\" /><m:endChr m:val=\"\u007C\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>16</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>17</m:t></m:r></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>18</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229519</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cos</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+3</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>sin</m:t></m:r></m:fName><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:den></m:f></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>tan</m:t></m:r></m:fName><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>6</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:den></m:f></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cot</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>9</m:t></m:r></m:den></m:f></m:e></m:d></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>sinh</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2283</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cosh</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+3</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>tanh</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>11</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229712</m:t></m:r></m:e></m:d></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>coth</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>222</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arcsin</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>13</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u229614</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arccos</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-16</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arctan</m:t></m:r></m:fName><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>17</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>18</m:t></m:r></m:den></m:f></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arccot</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>20</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+30</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arsinh</m:t></m:r></m:fName><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:e></m:func></m:num><m:den><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:e></m:nary></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>35</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>27</m:t></m:r></m:num><m:den><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arcosh</m:t></m:r></m:fName><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>23</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>78</m:t></m:r></m:e></m:mr></m:m></m:e></m:func></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arcoth</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>30</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2282</m:t></m:r><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>artanh</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>27</m:t></m:r></m:e></m:func></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2283</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>277</m:t></m:r></m:e></m:mr><m:mr><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>arcoth</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>89</m:t></m:r></m:e></m:func></m:e></m:mr></m:m></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-5</m:t></m:r></m:e><m:e><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>*10</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:nary></m:e></m:mr><m:mr><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cosh</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:e></m:d></m:e></m:func></m:e><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2295</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>100</m:t></m:r></m:den></m:f></m:e></m:mr></m:m></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:e></m:mr><m:mr><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:e></m:mr></m:m></m:e></m:mr><m:mr><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:e><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:e></m:mr></m:m></m:e></m:mr><m:mr></m:mr></m:m></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>25</m:t></m:r></m:num><m:den><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sub></m:sSub></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cos</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:e></m:func></m:e></m:mr><m:mr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:den></m:f></m:e></m:mr></m:m></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sup></m:sSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sPrePr><m:sub /><m:sup><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+3</m:t></m:r></m:e></m:mr><m:mr><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>cos</m:t></m:r></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>15</m:t></m:r></m:e></m:func></m:e></m:mr></m:m></m:sup><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:den></m:f></m:e></m:sPre></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sPrePr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sub><m:sup /><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2222</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sup></m:sSup></m:e></m:sPre></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:groupChr><m:groupChrPr><m:chr m:val=\"\u23DE\" /><m:pos m:val=\"top\" /><m:vertJc m:val=\"bot\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:groupChrPr><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"32\" /><w:szCs w:val=\"32\" /><w:color w:val=\"FF0000\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"32\" /><w:szCs w:val=\"32\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"32\" /><w:szCs w:val=\"32\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:e></m:groupChr></m:e><m:lim><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"36\" /><w:szCs w:val=\"36\" /><w:color w:val=\"000080\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"36\" /><w:szCs w:val=\"36\" /><w:color w:val=\"000080\" /></w:rPr><m:t>10</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"36\" /><w:szCs w:val=\"36\" /><w:color w:val=\"000080\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"36\" /><w:szCs w:val=\"36\" /><w:color w:val=\"000080\" /></w:rPr><m:t>10</m:t></m:r></m:e></m:mr><m:mr></m:mr></m:m></m:lim></m:limUpp></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2230\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"DC143C\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:sub><m:sup><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:e></m:d></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>100</m:t></m:r></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:acc><m:accPr><m:chr m:val=\"\u0307\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:acc><m:accPr><m:chr m:val=\"\u0332\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"800080\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:acc></m:e></m:acc></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFA500\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>3</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"bi\" /></w:rPr><m:t>10</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u221E</m:t></m:r></m:sup><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r></m:e><m:sup><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r></m:e></m:d></m:sup></m:sSup><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub></m:sSub></m:e></m:d></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0021</m:t></m:r></m:den></m:f><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub></m:sSub></m:e></m:d></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r></m:sup></m:sSup></m:e></m:nary></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:d><m:dPr><m:begChr m:val=\"\" /><m:endChr m:val=\"\u23AA\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>E</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>m</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FFFF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:e></m:d></m:e><m:sub><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"DC143C\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>b</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"008080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>a</m:t></m:r></m:den></m:f></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000080\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /><w:strike /></w:rPr><m:t>\u221E</m:t></m:r></m:sup></m:sSubSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>C</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C0</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00B7d</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00B7</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C0</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00B7r</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:e></m:rad></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:acc><m:accPr><m:chr m:val=\"\u20D7\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>F</m:t></m:r></m:e></m:acc><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>m</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00D7</m:t></m:r><m:acc><m:accPr><m:chr m:val=\"\u20D7\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e></m:acc></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>E</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>m</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>G</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BC</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BD</m:t></m:r></m:sub></m:sSub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u039B</m:t></m:r><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>g</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BC</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BD</m:t></m:r></m:sub></m:sSub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C0</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>G</m:t></m:r></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:sup></m:sSup></m:den></m:f><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>T</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BC</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BD</m:t></m:r></m:sub></m:sSub></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>d</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>dt</m:t></m:r></m:den></m:f><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>L</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:acc><m:accPr><m:chr m:val=\"\u0307\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:accPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>q</m:t></m:r></m:e></m:acc></m:den></m:f></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>L</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>q</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:sup><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r></m:e></m:nary><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>dx</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03B4</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>r</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r></m:e></m:d></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2248</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>e</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03BB</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r></m:sup></m:sSup><m:d><m:dPr><m:begChr m:val=\"\u2016\" /><m:endChr m:val=\"\u2016\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03B4</m:t></m:r><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>r</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub></m:sSub></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim</m:t></m:r></m:e><m:lim><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:lim></m:limLow></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:lim></m:limUpp></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:e></m:func></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>244</m:t></m:r></m:lim></m:limLow></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim sup</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:lim></m:limLow></m:e><m:lim><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:lim></m:limUpp></m:lim></m:limUpp></m:fName><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>100</m:t></m:r></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num /><m:den><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00B12</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sub></m:sSub></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f><m:r><w:br /></m:r></m:oMath><m:oMath><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:lim></m:limUpp></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22C3</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u0394</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>t</m:t></m:r></m:num><m:den><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>v</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>c</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:den></m:f></m:e></m:rad></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>6</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>9</m:t></m:r></m:den></m:f><m:r><w:br /></m:r></m:oMath><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22135</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:rad><m:radPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:deg><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-7</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+14</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-8</m:t></m:r></m:e></m:rad><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>9</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:rad><m:radPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:deg><m:e><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:type m:val=\"lin\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>9</m:t></m:r></m:den></m:f></m:e></m:rad></m:e></m:rad></m:e></m:rad></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>i</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u221E</m:t></m:r></m:sup><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:e></m:d></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>i</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>i</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+1</m:t></m:r></m:e></m:d></m:den></m:f></m:e></m:nary><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>i</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+1</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>sin</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d></m:e></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2794</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:lim></m:limLow></m:fName><m:e><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>sin</m:t></m:r></m:fName><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:den></m:f></m:e></m:func></m:e></m:func><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>0</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u221E</m:t></m:r></m:sup><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:e></m:nary><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>e</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-x</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>dx</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2265</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>a</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>b</m:t></m:r></m:e></m:rad></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sPrePr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:sup><m:e><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:sup></m:sSubSup></m:e></m:sPre></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sPrePr><m:sub /><m:sup><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>5</m:t></m:r></m:e><m:lim><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sPrePr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>8</m:t></m:r></m:sub><m:sup /><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>6</m:t></m:r></m:e></m:sPre></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>7</m:t></m:r></m:lim></m:limUpp></m:lim></m:limLow></m:sup><m:e><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>4</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:sup></m:sSubSup></m:e></m:sPre></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sPre><m:sPrePr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sPrePr><m:sub /><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:sup><m:e><m:sSubSup><m:sSubSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>e</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>7</m:t></m:r></m:sup></m:sSubSup></m:e></m:sPre><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>bolt</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:i /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2550</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>257</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"1616FF\" /></w:rPr><m:t>RGB</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"000066\" /></w:rPr><m:t>RGB</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>RGB</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"AACCFF\" /></w:rPr><m:t>RGB</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>RGB</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:sup><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e /><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:sub></m:sSub></m:sup></m:sSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u00AC10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u22287</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:nary><m:naryPr><m:chr m:val=\"\u2211\" /><m:limLoc m:val=\"undOvr\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:naryPr><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:sub><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u221E</m:t></m:r></m:sup><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:num><m:den><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>n</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:sup></m:sSup></m:den></m:f></m:den></m:f></m:e></m:nary><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>pi</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>6</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+zeta</m:t></m:r></m:den></m:f><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:limUpp><m:limUppPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limUppPr><m:e><m:groupChr><m:groupChrPr><m:chr m:val=\"\u23DE\" /><m:pos m:val=\"top\" /><m:vertJc m:val=\"bot\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:groupChrPr><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2216</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e></m:groupChr></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:lim></m:limUpp></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:rad><m:radPr><m:degHide m:val=\"1\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:radPr><m:deg /><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:sup><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>log</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sub></m:sSub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>8</m:t></m:r></m:sup></m:sSup></m:e></m:rad><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>4</m:t></m:r></m:e></m:mr></m:m><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+1</m:t></m:r></m:e></m:mr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>abc</m:t></m:r></m:e></m:mr></m:m><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:d><m:dPr><m:begChr m:val=\"\u005B\" /><m:endChr m:val=\"\u005D\" /><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>2</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /></w:rPr><m:t>10</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>\u2216</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>5</m:t></m:r></m:num><m:den><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:groupChr><m:groupChrPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr></m:ctrlPr></m:groupChrPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>9</m:t></m:r></m:e></m:groupChr></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"00FF00\" /></w:rPr><m:t>3</m:t></m:r></m:lim></m:limLow></m:den></m:f></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:sSub><m:sSubPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSubPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:sub><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>20</m:t></m:r></m:sub></m:sSub><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>28</m:t></m:r></m:sup></m:sSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\x22C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2 + 3</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>goal</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>.25</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>100</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2794</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>5</m:t></m:r></m:lim></m:limLow></m:fName><m:e /></m:func></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e><m:e /></m:mr><m:mr><m:e /><m:e /></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"2\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e /><m:e /></m:mr><m:mr><m:e /><m:e /></m:mr></m:m></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr></m:mr></m:m></m:e></m:mr><m:mr><m:e /></m:mr></m:m><m:m><m:mPr><m:mcs><m:mc><m:mcPr><m:count m:val=\"1\" /><m:mcJc m:val=\"center\" /></m:mcPr></m:mc></m:mcs><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:mPr><m:mr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:e></m:mr><m:mr><m:e /></m:mr></m:m></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>f</m:t></m:r><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2202</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:den></m:f><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>ln</m:t></m:r></m:fName><m:e><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e></m:d><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>+</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>tan</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:sup></m:sSup></m:e></m:func><m:d><m:dPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:dPr><m:e><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup></m:e></m:d></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:func><m:funcPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:funcPr><m:fName><m:limLow><m:limLowPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:limLowPr><m:e><m:r><m:rPr><m:sty m:val=\"p\" /></m:rPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>lim</m:t></m:r></m:e><m:lim><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u2794</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>1</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-</m:t></m:r></m:sup></m:sSup></m:lim></m:limLow></m:fName><m:e><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r></m:e><m:sup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:sup></m:sSup><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>x</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>-1</m:t></m:r></m:den></m:f></m:e></m:func><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C3</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>'</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>=</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>\u03C3</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:sSupPr><m:e><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>e</m:t></m:r></m:e><m:sup><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>2</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"0000ff\" /><m:sty m:val=\"b\" /><w:b /><w:bCs /></w:rPr><m:t>3</m:t></m:r></m:den></m:f></m:sup></m:sSup></m:oMath></m:oMathPara>"; + 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"<m:oMathPara><m:oMathParaPr><m:jc m:val=\"center\" /></m:oMathParaPr><m:oMath><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>2</m:t></m:r><m:f><m:fPr><m:ctrlPr><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr></m:ctrlPr></m:fPr><m:num><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>+</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>-</m:t></m:r><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /><w:color w:val=\"FF0000\" /></w:rPr><m:t>4</m:t></m:r></m:num><m:den><m:r><w:rPr><w:rFonts w:hAnsi=\"Cambria Math\" w:ascii=\"Cambria Math\" /><w:sz w:val=\"30\" /><w:szCs w:val=\"30\" /></w:rPr><m:t>10</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"; + 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..eb9524d4849 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cconversionsmtoooxml.cpp @@ -0,0 +1,502 @@ +/* + * (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 <fstream> +namespace StarMath { + CConversionSMtoOOXML::CConversionSMtoOOXML(): m_pXmlWrite(nullptr) + { + } + CConversionSMtoOOXML::~CConversionSMtoOOXML() + { + delete m_pXmlWrite; + } + //check XMLWrite(if not nullptr == delete) + void CConversionSMtoOOXML::StartConversion(std::vector<StarMath::CElement*> 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->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) + { + 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); + switch(enTypeMatrix) + { + case TypeElement::matrix: + pXmlWrite->WriteAttribute(L"m:val",L"2"); + break; + default: + pXmlWrite->WriteAttribute(L"m:val",L"1"); + break; + } + 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..a3010f5ec3d --- /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<CElement*> 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); + 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/cstarmathpars.cpp b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp new file mode 100644 index 00000000000..b51baa53b00 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.cpp @@ -0,0 +1,3689 @@ +/* + * (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<CElement*> 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); + } + 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<typename T> + bool SetLeft(CElement *pLeftArg, CElement *pElementWhichAdd) + { + T* pTempElement = dynamic_cast<T*>(pElementWhichAdd); + if(pTempElement->GetLeftArg() == nullptr) + { + if(CParserStarMathString::CheckNewline(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<CElementBinOperator*>(pElementWhichAdd); + if(pBinOp->GetType() == TypeElement::neg || (pBinOp->GetAttribute() != nullptr && pBinOp->GetAttribute() != pReader->GetBaseAttribute() && pBinOp->MixedOperators(pBinOp->GetType()))) + return false; + else + return SetLeft<CElementBinOperator>(pLeftArg, pElementWhichAdd); + } + case TypeElement::SetOperations: + { + return SetLeft<CElementSetOperations>(pLeftArg, pElementWhichAdd); + } + case TypeElement::Connection: + { + return SetLeft<CElementConnection>(pLeftArg,pElementWhichAdd); + } + case TypeElement::BracketWithIndex: + { + return SetLeft<CElementBracketWithIndex>(pLeftArg,pElementWhichAdd); + } + case TypeElement::Index: + { + CElementIndex * pIndex = dynamic_cast<CElementIndex*>(pElementWhichAdd); + if(pIndex->GetType() != TypeElement::sqrt && pIndex->GetType() != TypeElement::nroot) + return SetLeft<CElementIndex>(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<CElementSpecialSymbol*>(pElement); + return (pSpecial->GetType() == TypeElement::newline); + } + else + return false; + } + void CParserStarMathString::AddingAnElementToAnArray(std::vector<CElement *> &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<CElement *> &arElements) + { + if(!arElements.empty()) + CElementBinOperator::UnaryCheck(pReader,arElements.back()); + CElement* pTempElement = ParseElement(pReader); + AddingAnElementToAnArray(arElements,pTempElement,pReader); + } +//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<iZero;i++) + m_wsColor.push_back(L'0'); + m_wsColor += wsTempToken; + return true; + } + else if(wsTempToken.size() == 6) + { + m_wsColor = wsTempToken; + return true; + } + else if(wsTempToken.size() > 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(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); + } +//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 + { + pReader->SetMarkForUnar(true); + 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<CElementString*> (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(!CParserStarMathString::CheckNewline(pLastElement) && MixedOperators(pReader->GetLocalType())) + if(pReader->GetAttribute() != nullptr) + pReader->SetMarkForUnar(true); + else pReader->SetMarkForUnar(false); + else pReader->SetMarkForUnar(true); + } + 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; + } +//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<CElement*> &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<CElement*> CElementBracket::GetBracketValue() + { + return m_arBrecketValue; + } + void CElementBracket::Parse(CStarMathReader* pReader) + { + TypeElement enOpen,enClose; + if(m_enTypeBracket == TypeElement::left) + { + pReader->ReadingTheNextToken(); + enOpen = GetBracketOpen(pReader->GetLowerCaseString()); + 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<CElementSpecialSymbol*>(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""; + } + } +//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"?>" == 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(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: + { + 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(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; + } + } +//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; + } +//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"="); + break; + case TypeElement::notequals: + pXmlWrite->WriteString(L"\u2260"); + break; + case TypeElement::learrow: + pXmlWrite->WriteString(L"<"); + break; + case TypeElement::learrowequals: + pXmlWrite->WriteString(L"\u2264"); + break; + case TypeElement::leslant: + pXmlWrite->WriteString(L"\u2A7D"); + break; + case TypeElement::riarrow: + pXmlWrite->WriteString(L">"); + 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; + } +//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; + } +//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); + } +//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); + } +// 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; + } + m_enUnderType = CElementString::GetWord(m_wsLowerCaseToken); + if(m_enUnderType != TypeElement::undefine) + { + m_enGlobalType = TypeElement::String; + 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_itStart == L'(' || L')' == *m_itStart || L'%' == *m_itStart||(L'#' == *m_itStart && L'#' != m_wsElement.back()) ||(L'-' == *m_itStart && L'+' != m_wsElement.back() && L'<' != m_wsElement.back()) || (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()) || (CheckIsalhpaForGetElement(*m_itStart,m_wsElement.back())) || ((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) + 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; +// m_itEnd = m_itStart; + 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; + } +//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); + } +//class methods CElementMatrix + CElementMatrix::CElementMatrix(const TypeElement &enType,const TypeConversion &enTypeConversion) + :CElement(TypeElement::Matrix,enTypeConversion), m_pFirstArgument(nullptr), m_pSecondArgument(nullptr), m_enTypeMatrix(enType) + { + } + 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()); + } + void CElementMatrix::ConversionToOOXML(XmlUtils::CXmlWriter *pXmlWrite) + { + pXmlWrite->WriteNodeBegin(L"m:m",false); + CConversionSMtoOOXML::PropertiesMPr(pXmlWrite,m_enTypeMatrix,GetAttribute(),GetTypeConversion()); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + switch(m_enTypeMatrix) + { + case TypeElement::matrix: + case TypeElement::stack: + { + if(m_pFirstArgument != nullptr) + { + if(m_pFirstArgument->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pTempBracket = dynamic_cast<CElementBracket*>(m_pFirstArgument); + std::vector<CElement*> pTempValue = pTempBracket->GetBracketValue(); + for(CElement* pOneElement:pTempValue) + { + if(pOneElement->GetBaseType() != TypeElement::undefine && pOneElement->GetBaseType() != TypeElement::SpecialSymbol && m_enTypeMatrix == TypeElement::stack) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + else if(pOneElement->GetBaseType() != TypeElement::SpecialSymbol && pOneElement->GetBaseType()!= TypeElement::undefine && m_enTypeMatrix == TypeElement::matrix) + { + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); + } + else if(pOneElement->GetBaseType()!= TypeElement::undefine && pOneElement->GetBaseType() == TypeElement::SpecialSymbol && m_enTypeMatrix == TypeElement::matrix) + { + CElementSpecialSymbol* pTempSpecial = dynamic_cast<CElementSpecialSymbol*>(pOneElement); + if(pTempSpecial->GetType() == TypeElement::transition) + { + pXmlWrite->WriteNodeEnd(L"m:mr",false,false); + pXmlWrite->WriteNodeBegin(L"m:mr",false); + } + else if(pTempSpecial->GetType() != TypeElement::grid) + CConversionSMtoOOXML::WriteNodeConversion(L"m:e",pOneElement,pXmlWrite); + } + } + } + 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; + } + } + 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); + } +//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); + } +} + + diff --git a/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h new file mode 100644 index 00000000000..3e4218ad2b2 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/cstarmathpars.h @@ -0,0 +1,481 @@ +/* + * (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 <iostream> +#include <vector> +#include <iterator> +#include <stack> +#include <queue> +#include <ctype.h> +#include <cwctype> +#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; + }; + + 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<std::wstring::iterator> 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; + 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; + 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; + 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; + 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; + 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; + 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<CElement*>& arValue); + static TypeElement GetBracketOpen(const std::wstring& wsToken); + static TypeElement GetBracketClose(const std::wstring& wsToken); + std::vector<CElement*> GetBracketValue(); + private: + void SetAttribute(CAttribute* pAttribute) override; + void Parse(CStarMathReader* pReader) override; + void ConversionToOOXML(XmlUtils::CXmlWriter* pXmlWrite) override; + bool CheckMline(CElement* pElement); + std::wstring DefiningBracket(const TypeElement& enTypeBracket); + TypeElement m_enTypeBracket,m_enLeftBracket,m_enRightBracket; + std::vector<CElement*> 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; + 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; + 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; + 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; + 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; + 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; + CElement* m_pFirstArgument; + CElement* m_pSecondArgument; + TypeElement m_enTypeMatrix; + }; + + 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; + CElement* m_pValueMark; + TypeElement m_enTypeMark; + }; + + class CParserStarMathString + { + public: + CParserStarMathString(); + ~CParserStarMathString(); + std::vector<CElement*> 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); + //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<CElement*>& 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<CElement*>& 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); + static std::wstring ConvertToLowerCase(const std::wstring& wsToken); + private: + TBaseAttribute m_stBaseAttribute; + std::vector<CElement*> m_arEquation; + unsigned int m_iAlignment; + }; +} + +#endif // CSTARMATHPARS_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..3ee93a9fe15 --- /dev/null +++ b/OdfFile/Reader/Converter/StarMath2OOXML/typeselements.h @@ -0,0 +1,373 @@ +/* + * (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, + //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, +}; +} +#endif // TYPESELEMENTS_H diff --git a/OdfFile/Reader/Converter/docx_conversion_context.cpp b/OdfFile/Reader/Converter/docx_conversion_context.cpp index 3f43a5fbd55..344f467955d 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; @@ -2377,7 +2404,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 +2465,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..8ae7c5c4f95 100644 --- a/OdfFile/Reader/Converter/docx_conversion_context.h +++ b/OdfFile/Reader/Converter/docx_conversion_context.h @@ -803,6 +803,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_; diff --git a/OdfFile/Reader/Converter/docx_drawing.cpp b/OdfFile/Reader/Converter/docx_drawing.cpp index f4bdd4e3e28..4499362aeda 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); } 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"<w:comment w:id=\"" << elm.id << "\" "; if (elm.author.length()>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 d29c86e4295..692fb11fd67 100644 --- a/OdfFile/Reader/Converter/drawing_object_description.h +++ b/OdfFile/Reader/Converter/drawing_object_description.h @@ -76,6 +76,8 @@ struct drawing_object_description _action_desc action_; std::vector<_hlink_desc> hlinks_; + bool hidden_; + std::vector<odf_reader::_property> additional_; //shape properties std::wstring xlink_href_; //ссылка на внешний объект diff --git a/OdfFile/Reader/Converter/mediaitems.cpp b/OdfFile/Reader/Converter/mediaitems.cpp index 66207875b48..01e4e350bb1 100644 --- a/OdfFile/Reader/Converter/mediaitems.cpp +++ b/OdfFile/Reader/Converter/mediaitems.cpp @@ -64,7 +64,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, @@ -270,6 +270,7 @@ std::wstring mediaitems::add_or_find(const std::wstring & href, _rels_type type, } else if ( type == typeMsObject || type == typeOleObject) { + isMediaInternal = is_internal(href, odf_packet_); sub_path = L"embeddings/"; } else if ( type == typeControlProps) diff --git a/OdfFile/Reader/Converter/oox_conversion_context.cpp b/OdfFile/Reader/Converter/oox_conversion_context.cpp index 9ec757fcee9..d42d47ae417 100644 --- a/OdfFile/Reader/Converter/oox_conversion_context.cpp +++ b/OdfFile/Reader/Converter/oox_conversion_context.cpp @@ -265,19 +265,6 @@ void math_context::start() 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"<m:oMathParaPr><m:jc m:val=\""; - switch (base_alignment_) - { - case 0: math_stream_ << L"left"; break; - case 2: math_stream_ << L"right"; break; - case 1: - default: - math_stream_ << L"center"; break; - } - math_stream_ << L"\"/></m:oMathParaPr>"; - - math_stream_ << L"<m:oMath xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; start_level(); } @@ -285,7 +272,6 @@ std::wstring math_context::end() { end_level(); - math_stream_ << L"</m:oMath>"; std::wstring math = math_stream_.str(); math_stream_.str( std::wstring() ); diff --git a/OdfFile/Reader/Converter/oox_drawing.cpp b/OdfFile/Reader/Converter/oox_drawing.cpp index 42b27e20499..819f7160e16 100644 --- a/OdfFile/Reader/Converter/oox_drawing.cpp +++ b/OdfFile/Reader/Converter/oox_drawing.cpp @@ -239,6 +239,7 @@ void oox_serialize_effects(std::wostream & strm, const std::vector<odf_reader::_ double dist = sqrt(offsetX * offsetX + offsetY * offsetY); double dir = (offsetX != 0) ? atan(offsetY / offsetX) * 180. / 3.1415926 : 0; + if (offsetX < 0) dir += 180; if (dir < 0) dir += 360; CP_XML_ATTR(L"dist", (int)(dist)); @@ -578,16 +579,23 @@ 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; 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); + odf_reader::GetProperty(prop, L"style_columns_count", numCol); + odf_reader::GetProperty(prop, L"style_columns_gap" , spcCol); + 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(bool) bAutoGrowWidth; diff --git a/OdfFile/Reader/Converter/oox_package.cpp b/OdfFile/Reader/Converter/oox_package.cpp index 73f71f9cb24..c7ae4fc7f20 100644 --- a/OdfFile/Reader/Converter/oox_package.cpp +++ b/OdfFile/Reader/Converter/oox_package.cpp @@ -314,7 +314,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 +357,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 +371,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) 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_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/pptx_conversion_context.cpp b/OdfFile/Reader/Converter/pptx_conversion_context.cpp index cd06a9bd623..49f975a0eb6 100644 --- a/OdfFile/Reader/Converter/pptx_conversion_context.cpp +++ b/OdfFile/Reader/Converter/pptx_conversion_context.cpp @@ -53,674 +53,678 @@ namespace cpdoccore { } namespace oox { + namespace package + { + class pptx_document; + } - namespace package - { - class pptx_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) + { + } - 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) - { - } + pptx_conversion_context::~pptx_conversion_context() + { + } - pptx_conversion_context::~pptx_conversion_context() - { - } + void pptx_conversion_context::set_output_document(package::pptx_document* document) + { + output_document_ = document; + } - void pptx_conversion_context::set_output_document(package::pptx_document* document) - { - output_document_ = document; - } + 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); + } - 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); -} + const std::vector<std::wstring>& pptx_conversion_context::get_page_names() const + { + return page_names_; + } -const std::vector<std::wstring>& pptx_conversion_context::get_page_names() const -{ - return page_names_; -} + void pptx_conversion_context::process_layouts() + { + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - void pptx_conversion_context::process_layouts() + get_text_context().set_process_layouts(true); + + //актуальные + for (size_t layout_index = 0; layout_index < layouts.content.size(); layout_index++) { - odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); + start_layout(layout_index); - get_text_context().set_process_layouts(true); + odf_reader::style_presentation_page_layout* layout = + root()->odf_context().pageLayoutContainer().presentation_page_layout_by_name(layouts.content[layout_index].layout_name); - //актуальные - for (size_t layout_index = 0; layout_index < layouts.content.size(); layout_index++) + if (layout) { - start_layout(layout_index); - - 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); + 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) + if (master) + { + for (size_t i = 0; i < master->content_.size(); i++) { - for (size_t i = 0; i < master->content_.size(); i++) + odf_reader::draw_frame* frame = dynamic_cast<odf_reader::draw_frame*>(master->content_[i].get()); + if (frame) { - odf_reader::draw_frame* frame = dynamic_cast<odf_reader::draw_frame*>(master->content_[i].get()); - if (frame) + 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_types::common_presentation_attlist& common_presentation_attlist_ = frame->common_draw_attlists_.shape_with_text_and_styles_.common_presentation_attlist_; + odf_types::presentation_class::type type = common_presentation_attlist_.presentation_class_->get_type(); - if (common_presentation_attlist_.presentation_class_) + 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) { - 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); - } + if (frame->idx_in_owner < 0) + frame->idx_in_owner = last_idx_placeHolder++; + + frame->pptx_convert_placeHolder(*this); } } } } - end_layout(); } - get_text_context().set_process_layouts(false); + end_layout(); } - 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); + 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(); - //берем только актуальные - odf_reader::office_element_ptr master_notes_; + process_masters_ = true; + get_text_context().set_process_layouts(true); - for (size_t master_index = 0; master_index < masters.content.size(); master_index++) - { - start_master(master_index); + //берем только актуальные + odf_reader::office_element_ptr master_notes_; - 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); + for (size_t master_index = 0; master_index < masters.content.size(); master_index++) + { + start_master(master_index); - if (!master_notes_ && master->presentation_notes_) - master_notes_ = master->presentation_notes_; - } + 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); - end_master(); + if (!master_notes_ && master->presentation_notes_) + master_notes_ = master->presentation_notes_; } - if (master_notes_) - { - start_master_notes(); - master_notes_->pptx_convert(*this); - end_master_notes(); - } - process_masters_ = false; - get_text_context().set_process_layouts(false); + end_master(); } - void pptx_conversion_context::process_styles() + if (master_notes_) { - + start_master_notes(); + master_notes_->pptx_convert(*this); + end_master_notes(); } - void pptx_conversion_context::process_theme(std::wstring name) - { - int current = themes_.size() + 1; + process_masters_ = false; + get_text_context().set_process_layouts(false); - 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() + void pptx_conversion_context::process_styles() + { + + } + void pptx_conversion_context::process_theme(std::wstring name) + { + int current = themes_.size() + 1; + + if (name.empty()) { - odf_reader::odf_read_context& odfContext = root()->odf_context(); - std::vector<const odf_reader::style_instance*> instances; + 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(); - 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::start_document() + { + odf_reader::odf_read_context& odfContext = root()->odf_context(); + std::vector<const odf_reader::style_instance*> instances; - odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); - odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(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)); - process_masters_ = false; - } + odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances); + odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances); - void pptx_conversion_context::end_document() + process_masters_ = false; + } + + void pptx_conversion_context::end_document() + { + for (size_t i = 0; i < slideMasters_.size(); i++) { - for (size_t i = 0; i < slideMasters_.size(); i++) - { - pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; + pptx_xml_slideMaster_ptr& slideM = slideMasters_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slideM->write_to(content->content()); - content->add_rels(slideM->Rels());//media & links rels + slideM->write_to(content->content()); + content->add_rels(slideM->Rels());//media & links rels - output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml + output_document_->get_ppt_files().add_slideMaster(content);//slideMaster.xml - CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml + CP_XML_WRITER(presentation_.slideMastersData())//presentation.xml + { + CP_XML_NODE(L"p:sldMasterId") { - CP_XML_NODE(L"p:sldMasterId") - { - CP_XML_ATTR(L"id", 0x80000000 + last_uniq_big_id++); - CP_XML_ATTR(L"r:id", slideM->rId()); - } + 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(); + } + if (!slideMasters_.empty()) + presentation_.slidesProperties() << slideMasters_[0]->Sizes().str(); - //////////////////////////////////////////////////////////////////////////////////////////////////// - for (size_t i = 0; i < slides_.size(); i++) - { - pptx_xml_slide_ptr& slide = slides_[i]; + //////////////////////////////////////////////////////////////////////////////////////////////////// + for (size_t i = 0; i < slides_.size(); i++) + { + pptx_xml_slide_ptr& slide = slides_[i]; - package::slide_content_ptr content = package::slide_content::create(); + package::slide_content_ptr content = package::slide_content::create(); - slide->write_to(content->content()); - content->add_rels(slide->Rels());//media & links rels + slide->write_to(content->content()); + content->add_rels(slide->Rels());//media & links rels - output_document_->get_ppt_files().add_slide(content);//slide.xml + output_document_->get_ppt_files().add_slide(content);//slide.xml - CP_XML_WRITER(presentation_.slidesData())//presentation.xml + CP_XML_WRITER(presentation_.slidesData())//presentation.xml + { + CP_XML_NODE(L"p:sldId") { - CP_XML_NODE(L"p:sldId") - { - CP_XML_ATTR(L"id", 0x100 + i); - CP_XML_ATTR(L"r:id", slide->rId()); - } + 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]; + } + //---------------------------------------------------------------------------------- + for (size_t i = 0; i < slideLayouts_.size(); i++) + { + pptx_xml_slideLayout_ptr& slideL = slideLayouts_[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 + slideL->write_to(content->content()); + content->add_rels(slideL->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_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(); - slideN->write_to(content->content()); - content->add_rels(slideN->Rels());//media & links rels + slideN->write_to(content->content()); + content->add_rels(slideN->Rels());//media & links rels - output_document_->get_ppt_files().add_notes(content); - } - if (slideNotesMaster_) - { - package::slide_content_ptr content = package::slide_content::create(); + output_document_->get_ppt_files().add_notes(content); + } + if (slideNotesMaster_) + { + package::slide_content_ptr content = package::slide_content::create(); - slideNotesMaster_->write_to(content->content()); - content->add_rels(slideNotesMaster_->Rels());//media & links rels + slideNotesMaster_->write_to(content->content()); + content->add_rels(slideNotesMaster_->Rels());//media & links rels - output_document_->get_ppt_files().add_notesMaster(content); + output_document_->get_ppt_files().add_notesMaster(content); - CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml + CP_XML_WRITER(presentation_.slideNotesMastersData())//presentation.xml + { + CP_XML_NODE(L"p:notesMasterId") { - CP_XML_NODE(L"p:notesMasterId") - { - CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); - } + CP_XML_ATTR(L"r:id", slideNotesMaster_->rId()); } } - //else - pptx_serialize_size(current_presentation().slidesNotesProperties(), 6858000, 9144000, L"p:notesSz"); + } + //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(); + 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()); + charts_[i]->serialize(content->content()); + charts_[i]->dump_rels(content->get_rel_file()->get_rels()); - output_document_->get_ppt_files().add_charts(content); + 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 < themes_.size(); i++) + { + output_document_->get_ppt_files().add_theme(themes_[i]); - } - package::ppt_comments_files_ptr comments = package::ppt_comments_files::create(comments_context_handle_.content()); + } + 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_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()); - } + output_document_->get_content_types_file().set_media(get_mediaitems()); + } - void pptx_conversion_context::start_body() - { + void pptx_conversion_context::start_body() + { - } + } - void pptx_conversion_context::end_body() + void pptx_conversion_context::end_body() + { + } + pptx_xml_slideNotesMaster& pptx_conversion_context::current_notesMaster() + { + if (slideNotesMaster_) { + return *slideNotesMaster_; } - pptx_xml_slideNotesMaster& pptx_conversion_context::current_notesMaster() + else { - if (slideNotesMaster_) - { - return *slideNotesMaster_; - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideNotes& pptx_conversion_context::current_notes() + } + pptx_xml_slideNotes& pptx_conversion_context::current_notes() + { + if (!notes_.empty()) { - if (!notes_.empty()) - { - return *notes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *notes_.back().get(); } - pptx_xml_slide& pptx_conversion_context::current_slide() + else { - if (!slides_.empty()) - { - return *slides_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideLayout& pptx_conversion_context::current_layout() + } + pptx_xml_slide& pptx_conversion_context::current_slide() + { + if (!slides_.empty()) { - if (!slideLayouts_.empty()) - { - return *slideLayouts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *slides_.back().get(); } - pptx_xml_theme& pptx_conversion_context::current_theme() + else { - if (!themes_.empty()) - { - return *themes_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_presentation& pptx_conversion_context::current_presentation() + } + pptx_xml_slideLayout& pptx_conversion_context::current_layout() + { + if (!slideLayouts_.empty()) { - return presentation_; + return *slideLayouts_.back().get(); } - - oox_chart_context& pptx_conversion_context::current_chart() + else { - if (!charts_.empty()) - { - return *charts_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + throw std::runtime_error("internal error"); } - pptx_xml_slideMaster& pptx_conversion_context::current_master() + } + pptx_xml_theme& pptx_conversion_context::current_theme() + { + if (!themes_.empty()) { - if (!slideMasters_.empty()) - { - return *slideMasters_.back().get(); - } - else - { - throw std::runtime_error("internal error"); - } + return *themes_.back().get(); } - void pptx_conversion_context::create_new_slide(std::wstring const& name) + else { - pptx_xml_slide_ptr s = pptx_xml_slide::create(name, slides_.size() + 1); - slides_.push_back(s); + throw std::runtime_error("internal error"); } - void pptx_conversion_context::create_new_slideNotes() + } + pptx_xml_presentation& pptx_conversion_context::current_presentation() + { + return presentation_; + } + + oox_chart_context& pptx_conversion_context::current_chart() + { + if (!charts_.empty()) { - pptx_xml_slideNotes_ptr s = pptx_xml_slideNotes::create(notes_.size() + 1); - notes_.push_back(s); + return *charts_.back().get(); } - void pptx_conversion_context::create_new_slideNotesMaster() + else { - slideNotesMaster_ = pptx_xml_slideNotesMaster::create(); + throw std::runtime_error("internal error"); } - void pptx_conversion_context::create_new_slideLayout(int id) + } + pptx_xml_slideMaster& pptx_conversion_context::current_master() + { + if (!slideMasters_.empty()) { - pptx_xml_slideLayout_ptr s = pptx_xml_slideLayout::create(id); - slideLayouts_.push_back(s); + return *slideMasters_.back().get(); } - void pptx_conversion_context::create_new_slideMaster(int id) + else { - pptx_xml_slideMaster_ptr s = pptx_xml_slideMaster::create(id); - slideMasters_.push_back(s); + throw std::runtime_error("internal error"); } - 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); + } + 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(); - 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<int, std::wstring> layout_id = - root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName, pageMasterName); + std::pair<int, std::wstring> 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) + bool pptx_conversion_context::start_layout(int layout_index) + { + if (layout_index >= 0) { - 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"");//????? + odf_reader::presentation_layouts_instance& layouts = root()->odf_context().styleContainer().presentation_layouts(); - current_master_page_name_ = layouts.content[layout_index].master_name; - current_layout_page_name_ = L""; + create_new_slideLayout(layouts.content[layout_index].Id); - std::pair<int, std::wstring> master_id = //std::pair<int,std::wstring>(1, L"smId1"); - root()->odf_context().styleContainer().presentation_masters().add_or_find(layouts.content[layout_index].master_name); + get_slide_context().start_slide();//layouts.content[layout_index].layout_name, L"");//????? - root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name, layouts.content[layout_index]); + current_master_page_name_ = layouts.content[layout_index].master_name; + current_layout_page_name_ = L""; - 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")); + std::pair<int, std::wstring> master_id = //std::pair<int,std::wstring>(1, L"smId1"); + root()->odf_context().styleContainer().presentation_masters().add_or_find(layouts.content[layout_index].master_name); - // - } - else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) - { - } + root()->odf_context().styleContainer().presentation_masters().add_layout_to(layouts.content[layout_index].master_name, layouts.content[layout_index]); - //layout type - - //<xsd:enumeration value="title"/> - //1375 <xsd:enumeration value="tx"/> - //1376 <xsd:enumeration value="twoColTx"/> - //1377 <xsd:enumeration value="tbl"/> - //1378 <xsd:enumeration value="txAndChart"/> - //1379 <xsd:enumeration value="chartAndTx"/> - //1380 <xsd:enumeration value="dgm"/> - //1381 <xsd:enumeration value="chart"/> - //1382 <xsd:enumeration value="txAndClipArt"/> - //1383 <xsd:enumeration value="clipArtAndTx"/> - //1384 <xsd:enumeration value="titleOnly"/> - //1385 <xsd:enumeration value="blank"/> - //1386 <xsd:enumeration value="txAndObj"/> - //1387 <xsd:enumeration value="objAndTx"/> - //1388 <xsd:enumeration value="objOnly"/> - //1389 <xsd:enumeration value="obj"/> - //1390 <xsd:enumeration value="txAndMedia"/> - //1391 <xsd:enumeration value="mediaAndTx"/> - //1392 <xsd:enumeration value="objOverTx"/> - //1393 <xsd:enumeration value="txOverObj"/> - //1394 <xsd:enumeration value="txAndTwoObj"/> - //1395 <xsd:enumeration value="twoObjAndTx"/> - //1396 <xsd:enumeration value="twoObjOverTx"/> - //1397 <xsd:enumeration value="fourObj"/> - //1398 <xsd:enumeration value="vertTx"/> - //1399 <xsd:enumeration value="clipArtAndVertTx"/> - //1400 <xsd:enumeration value="vertTitleAndTx"/> - //1401 <xsd:enumeration value="vertTitleAndTxOverChart"/> - //1402 <xsd:enumeration value="twoObj"/> - //1403 <xsd:enumeration value="objAndTwoObj"/> - //1404 <xsd:enumeration value="twoObjAndObj"/> - //1405 <xsd:enumeration value="cust"/>---------------------------------- !!!!!!!!!!!!! - //1406 <xsd:enumeration value="secHead"/> - //1407 <xsd:enumeration value="twoTxTwoObj"/> - //1408 <xsd:enumeration value="objTx"/> - //1409 <xsd:enumeration value="picTx"/> - - return true; - } - 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(); - - current_master_page_name_ = L""; - current_layout_page_name_ = L""; + 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")); - process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами - current_master().add_theme(current_theme().id(), L"tId1"); + // + } + else//общий шаблон (насильно пропишем к темам несоответствующие шалоны) + { + } + + //layout type + + //<xsd:enumeration value="title"/> + //1375 <xsd:enumeration value="tx"/> + //1376 <xsd:enumeration value="twoColTx"/> + //1377 <xsd:enumeration value="tbl"/> + //1378 <xsd:enumeration value="txAndChart"/> + //1379 <xsd:enumeration value="chartAndTx"/> + //1380 <xsd:enumeration value="dgm"/> + //1381 <xsd:enumeration value="chart"/> + //1382 <xsd:enumeration value="txAndClipArt"/> + //1383 <xsd:enumeration value="clipArtAndTx"/> + //1384 <xsd:enumeration value="titleOnly"/> + //1385 <xsd:enumeration value="blank"/> + //1386 <xsd:enumeration value="txAndObj"/> + //1387 <xsd:enumeration value="objAndTx"/> + //1388 <xsd:enumeration value="objOnly"/> + //1389 <xsd:enumeration value="obj"/> + //1390 <xsd:enumeration value="txAndMedia"/> + //1391 <xsd:enumeration value="mediaAndTx"/> + //1392 <xsd:enumeration value="objOverTx"/> + //1393 <xsd:enumeration value="txOverObj"/> + //1394 <xsd:enumeration value="txAndTwoObj"/> + //1395 <xsd:enumeration value="twoObjAndTx"/> + //1396 <xsd:enumeration value="twoObjOverTx"/> + //1397 <xsd:enumeration value="fourObj"/> + //1398 <xsd:enumeration value="vertTx"/> + //1399 <xsd:enumeration value="clipArtAndVertTx"/> + //1400 <xsd:enumeration value="vertTitleAndTx"/> + //1401 <xsd:enumeration value="vertTitleAndTxOverChart"/> + //1402 <xsd:enumeration value="twoObj"/> + //1403 <xsd:enumeration value="objAndTwoObj"/> + //1404 <xsd:enumeration value="twoObjAndObj"/> + //1405 <xsd:enumeration value="cust"/>---------------------------------- !!!!!!!!!!!!! + //1406 <xsd:enumeration value="secHead"/> + //1407 <xsd:enumeration value="twoTxTwoObj"/> + //1408 <xsd:enumeration value="objTx"/> + //1409 <xsd:enumeration value="picTx"/> + + return true; + } + bool pptx_conversion_context::start_master(int master_index) + { + odf_reader::presentation_masters_instance& masters = root()->odf_context().styleContainer().presentation_masters(); - 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++); - } + create_new_slideMaster(masters.content[master_index].Id); - //---------------------------------------------------------------------------------- - //размеры страниц в презентации - const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); + get_slide_context().start_slide(); - odf_reader::page_layout_instance* pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); + current_master_page_name_ = L""; + current_layout_page_name_ = L""; - if (pages_layouts) - pages_layouts->pptx_serialize(current_master().Sizes(), *this); + process_theme(masters.content[master_index].master_name);//add default theme - одинаковые но под разными именами + current_master().add_theme(current_theme().id(), L"tId1"); - return true; - } - void pptx_conversion_context::end_page() + for (size_t i = 0; i < masters.content[master_index].layouts.size(); i++) { - if (!get_comments_context().empty()) - { - std::wstringstream strm; - get_comments_context().serialize(strm); + 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::pair<std::wstring, std::wstring> commentsName = - comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments()); + //---------------------------------------------------------------------------------- + //размеры страниц в презентации + const std::wstring pageProperties = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(masters.content[master_index].master_name); - get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); - } + odf_reader::page_layout_instance* pages_layouts = root()->odf_context().pageLayoutContainer().page_layout_by_name(pageProperties); - get_slide_context().serialize_background(current_slide().Background()); - get_slide_context().serialize_objects(current_slide().Data()); - get_slide_context().serialize_animations(current_slide().Timing()); + if (pages_layouts) + pages_layouts->pptx_serialize(current_master().Sizes(), *this); - { - // NOTE: При использовании operator<< потока буст пушит туда лишний пробел перед значением. - // С этим пробелом наш редактор onlyoffice на распознает значение. - // Example: - // <p:attrName> ppt_y</p:attrName> - // <p:attrName>ppt_y</p:attrName> - // TODO: Figure out how to push value without redundant space character - current_slide().remove_timing_redundant_space(); - } + return true; + } + void pptx_conversion_context::end_page() + { + if (!get_comments_context().empty()) + { + std::wstringstream strm; + get_comments_context().serialize(strm); - get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... + const std::pair<std::wstring, std::wstring> commentsName = + comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments()); - get_slide_context().end_slide(); + get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment); } - 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().serialize_background(current_slide().Background()); + get_slide_context().serialize_objects(current_slide().Data()); + get_slide_context().serialize_animations(current_slide().Timing()); - get_slide_context().start_slide(); + { + // NOTE: При использовании operator<< потока буст пушит туда лишний пробел перед значением. + // С этим пробелом наш редактор onlyoffice на распознает значение. + // Example: + // <p:attrName> ppt_y</p:attrName> + // <p:attrName>ppt_y</p:attrName> + // TODO: Figure out how to push value without redundant space character + current_slide().remove_timing_redundant_space(); + } - 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")); + get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ... - return true; - } + get_slide_context().end_slide(); + } + bool pptx_conversion_context::start_page_notes() + { + create_new_slideNotes(); - void pptx_conversion_context::end_page_notes() - { - get_slide_context().serialize_background(current_notes().Background()); - get_slide_context().serialize_objects(current_notes().Data()); + 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().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... + get_slide_context().start_slide(); - get_slide_context().end_slide(); - } - bool pptx_conversion_context::start_master_notes() - { - create_new_slideNotesMaster(); + 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")); - get_slide_context().start_slide(); + return true; + } - process_theme(L"");//add default theme - одинаковые но под разными именами - current_notesMaster().add_theme(current_theme().id(), L"tId1"); + 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().start_slide(); - return true; - } + get_slide_context().dump_rels(current_notes().Rels());//hyperlinks, mediaitems, ... - void pptx_conversion_context::end_master_notes() - { - get_slide_context().serialize_background(current_notesMaster().Background()); - get_slide_context().serialize_objects(current_notesMaster().Data()); + get_slide_context().end_slide(); + } + bool pptx_conversion_context::start_master_notes() + { + create_new_slideNotesMaster(); - get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... + get_slide_context().start_slide(); - get_slide_context().end_slide(); + process_theme(L"");//add default theme - одинаковые но под разными именами + current_notesMaster().add_theme(current_theme().id(), L"tId1"); - 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().start_slide(); + return true; + } - get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... + void pptx_conversion_context::end_master_notes() + { + get_slide_context().serialize_background(current_notesMaster().Background()); + get_slide_context().serialize_objects(current_notesMaster().Data()); - get_slide_context().end_slide(); - } + get_slide_context().dump_rels(current_notesMaster().Rels());//hyperlinks, mediaitems, ... - std::pair<int, int> pptx_conversion_context::add_author_comments(std::wstring author) - { - if (!authors_comments_) - { - authors_comments_ = pptx_xml_authors_comments::create(); - if (!authors_comments_)return std::pair<int, int>(-1, -1); - } + get_slide_context().end_slide(); - return authors_comments_->add_or_find(author); + 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().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().serialize_objects(current_layout().Data()); - get_slide_context().dump_rels(current_master().Rels());//hyperlinks, mediaitems, ... + get_slide_context().dump_rels(current_layout().Rels());//hyperlinks, mediaitems, ... - 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().end_slide(); + } - void pptx_conversion_context::end_office_presentation() + std::pair<int, int> pptx_conversion_context::add_author_comments(std::wstring author) + { + if (!authors_comments_) { + authors_comments_ = pptx_xml_authors_comments::create(); + if (!authors_comments_)return std::pair<int, int>(-1, -1); } - 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; + return authors_comments_->add_or_find(author); + } - 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_master() + { + get_slide_context().process_drawings(); + + 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().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_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_drawing.cpp b/OdfFile/Reader/Converter/pptx_drawing.cpp index 757b27653d7..1c91de40489 100644 --- a/OdfFile/Reader/Converter/pptx_drawing.cpp +++ b/OdfFile/Reader/Converter/pptx_drawing.cpp @@ -76,7 +76,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 +124,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 +212,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); } @@ -270,6 +273,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); } @@ -342,7 +346,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"); @@ -379,7 +384,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"); @@ -420,7 +426,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"); diff --git a/OdfFile/Reader/Converter/pptx_drawings.cpp b/OdfFile/Reader/Converter/pptx_drawings.cpp index 516633bbf6a..b60312ccc25 100644 --- a/OdfFile/Reader/Converter/pptx_drawings.cpp +++ b/OdfFile/Reader/Converter/pptx_drawings.cpp @@ -31,6 +31,7 @@ */ #include <xml/simple_xml_writer.h> +#include <boost/algorithm/string.hpp> #include "oox_rels.h" @@ -74,8 +75,13 @@ class pptx_drawings::Impl } } - if(!found) - pptx_drawing_rels_.push_back(_rel(false, d.hlinks[i].hId, d.hlinks[i].hRef, typeHyperlink)); + 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()) { diff --git a/OdfFile/Reader/Converter/pptx_slide_context.cpp b/OdfFile/Reader/Converter/pptx_slide_context.cpp index 3a9d5f1845e..a2c2deae66f 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.cpp +++ b/OdfFile/Reader/Converter/pptx_slide_context.cpp @@ -170,6 +170,7 @@ class pptx_slide_context::Impl 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); @@ -289,6 +290,8 @@ 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; @@ -465,6 +468,10 @@ 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) { @@ -688,8 +695,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; @@ -748,6 +754,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); @@ -838,13 +847,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); diff --git a/OdfFile/Reader/Converter/pptx_slide_context.h b/OdfFile/Reader/Converter/pptx_slide_context.h index a7e0d0e7514..85f6412449c 100644 --- a/OdfFile/Reader/Converter/pptx_slide_context.h +++ b/OdfFile/Reader/Converter/pptx_slide_context.h @@ -73,6 +73,7 @@ class pptx_slide_context std::vector<odf_reader::_property> & 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); diff --git a/OdfFile/Reader/Converter/pptx_table_context.cpp b/OdfFile/Reader/Converter/pptx_table_context.cpp index 67202bf10e4..bee8535bdb6 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; diff --git a/OdfFile/Reader/Converter/pptx_table_context.h b/OdfFile/Reader/Converter/pptx_table_context.h index 67e289dc2f6..af6bff6ee91 100644 --- a/OdfFile/Reader/Converter/pptx_table_context.h +++ b/OdfFile/Reader/Converter/pptx_table_context.h @@ -56,6 +56,8 @@ class pptx_table_state void start_column(unsigned int repeated, const std::wstring & defaultCellStyleName); std::wstring get_default_cell_style_col(unsigned int column); std::wstring get_default_cell_style_row(); + void set_default_cell_style_row(const std::wstring& style_name); + void set_default_cell_style_col(unsigned int column, const std::wstring style_name); void start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName); void end_row(); @@ -74,9 +76,25 @@ class pptx_table_state void set_rows_spanned(unsigned int Column, unsigned int Val, unsigned int ColumnsSpanned, const std::wstring & Style); unsigned int current_rows_spanned(unsigned int Column) const; - - std::wstring default_cell_style_name_; + void set_rows(int rows); + int get_rows() const; + int get_current_row() const; + void set_columns(int cols); + int get_columns() const; + void set_template_row_style_name(const std::wstring style_name); + std::wstring get_template_row_style_name() const; + + std::wstring default_cell_style_name_; + std::wstring template_row_style_name_; + + _CP_OPT(std::wstring) first_row_style_name_; + _CP_OPT(std::wstring) last_row_style_name_; + _CP_OPT(std::wstring) odd_rows_style_name_; + + _CP_OPT(std::wstring) first_column_style_name_; + _CP_OPT(std::wstring) last_column_style_name_; + _CP_OPT(std::wstring) odd_columns_style_name; private: pptx_conversion_context & context_; @@ -94,7 +112,10 @@ class pptx_table_state std::vector<unsigned int> columns_; std::vector<std::wstring> 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<pptx_table_state> 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<const odf_reader::style_instance *> & 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 0bfc224aeaf..74d26af8092 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,6 +108,7 @@ 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; @@ -124,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<std::wstring> list_style_stack_; bool first_element_list_item_; + + _CP_OPT(odf_types::length) last_run_font_size_; int new_list_style_number_; // счетчик для нумерации имен созданных в процессе конвертации стилей @@ -195,9 +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; - is_predump = false; + last_paragraph_style_name_ = paragraph_style_name_; + paragraph_style_name_ = styleName; + in_paragraph = true; + is_predump = false; } void pptx_text_context::Impl::end_paragraph() @@ -209,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() @@ -240,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) { @@ -393,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"<a:pPr "; @@ -441,8 +451,10 @@ void pptx_text_context::Impl::write_rPr(std::wostream & strm) text_properties_.pptx_convert(pptx_context_); - strm << get_styles_context().text_style().str(); + 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(); + strm << get_styles_context().text_style().str(); } std::wstring pptx_text_context::Impl::dump_paragraph(/*bool last*/) { @@ -464,9 +476,21 @@ 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; } } } @@ -569,7 +593,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_) { @@ -586,6 +610,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""; } @@ -668,7 +701,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(); } @@ -714,8 +747,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; @@ -731,7 +765,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; @@ -780,6 +814,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_): @@ -865,14 +919,28 @@ 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) +{ + impl_->set_action(action); +} +void pptx_text_context::end_hyperlink() { - return impl_->end_hyperlink(hId); + 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() ; @@ -900,5 +968,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 - <a:fld><a:t></a:fld> 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..6857dc64e14 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"; + { + if (pt > 1.5) retVal = L"mediumDashed"; + else retVal = L"dashed"; + } + else if (borderStyle.get_style() == odf_types::border_style::dash_dot) + { + if (pt > 1.5) retVal = L"mediumDashDot"; + else retVal = L"dashDot"; + } + else if (borderStyle.get_style() == odf_types::border_style::dash_dot_dot) + { + 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..009df1e93ff 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<rule> 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++) + { + 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"formula") + 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<conditionalFormatting> 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; @@ -324,6 +563,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 +594,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 +609,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 +643,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 +727,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 +779,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 +788,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 +849,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..3b983b9276a 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.cpp +++ b/OdfFile/Reader/Converter/xlsx_output_xml.cpp @@ -78,6 +78,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_; @@ -148,6 +149,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_; @@ -312,8 +317,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 +343,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..62c487b6006 100644 --- a/OdfFile/Reader/Converter/xlsx_output_xml.h +++ b/OdfFile/Reader/Converter/xlsx_output_xml.h @@ -61,6 +61,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(); 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..57897738b02 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.cpp +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.cpp @@ -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..7cde938de77 100644 --- a/OdfFile/Reader/Converter/xlsx_tablecontext.h +++ b/OdfFile/Reader/Converter/xlsx_tablecontext.h @@ -88,7 +88,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/xlsxconversioncontext.cpp b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp index acdbf417687..7c7b79323c6 100644 --- a/OdfFile/Reader/Converter/xlsxconversioncontext.cpp +++ b/OdfFile/Reader/Converter/xlsxconversioncontext.cpp @@ -520,7 +520,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()); diff --git a/OdfFile/Reader/Format/anim_elements.cpp b/OdfFile/Reader/Format/anim_elements.cpp index 5aec245829e..b83df357d4d 100644 --- a/OdfFile/Reader/Format/anim_elements.cpp +++ b/OdfFile/Reader/Format/anim_elements.cpp @@ -1185,8 +1185,6 @@ void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion 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; @@ -1237,20 +1235,20 @@ void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion else dir = L"d"; } - if (filter_attlist_.smil_subtype_.get() == L"fromTop") 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"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"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"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"; + else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") dir = L"lu"; } 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 2fa5f2097fc..28948d6a16f 100644 --- a/OdfFile/Reader/Format/chart_build_oox.cpp +++ b/OdfFile/Reader/Format/chart_build_oox.cpp @@ -209,7 +209,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_) { @@ -261,7 +261,7 @@ void object_odf_context::docx_convert(oox::docx_conversion_context & Context) 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(); Context.get_drawing_context().get_text_stream_frame() = temp_stream.str(); @@ -307,7 +307,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_) { 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<office_element*> levels; office_element* last_paragraph; diff --git a/OdfFile/Reader/Format/draw_common.cpp b/OdfFile/Reader/Format/draw_common.cpp index 768bac78f91..2f1eb619d77 100644 --- a/OdfFile/Reader/Format/draw_common.cpp +++ b/OdfFile/Reader/Format/draw_common.cpp @@ -381,7 +381,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; @@ -592,7 +592,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..53a0079c753 100644 --- a/OdfFile/Reader/Format/draw_frame.cpp +++ b/OdfFile/Reader/Format/draw_frame.cpp @@ -299,6 +299,14 @@ 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(); diff --git a/OdfFile/Reader/Format/draw_frame.h b/OdfFile/Reader/Format/draw_frame.h index 0a8dbe524ee..6325d12a709 100644 --- a/OdfFile/Reader/Format/draw_frame.h +++ b/OdfFile/Reader/Format/draw_frame.h @@ -177,6 +177,9 @@ class draw_frame : public office_element_impl<draw_frame> 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; diff --git a/OdfFile/Reader/Format/draw_frame_docx.cpp b/OdfFile/Reader/Format/draw_frame_docx.cpp index 64e4e50bf50..010bc35fe7e 100644 --- a/OdfFile/Reader/Format/draw_frame_docx.cpp +++ b/OdfFile/Reader/Format/draw_frame_docx.cpp @@ -881,17 +881,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)//порядок отрисовки объектов @@ -1578,6 +1578,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); //----------------------------------------------------------------------------------------------------- @@ -1644,18 +1649,21 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) 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 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; @@ -1753,8 +1761,7 @@ 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"<w:p><m:oMathPara>") + - content + std::wstring(L"</m:oMathPara></w:p>"))); + drawing->additional.push_back(_property(L"text-content", std::wstring(L"<w:p>") + content + std::wstring(L"</w:p>"))); } else {//in text @@ -1762,9 +1769,7 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context) if (runState) Context.finish_run(); - Context.output_stream() << L"<m:oMathPara>"; Context.output_stream() << content; - Context.output_stream() << L"</m:oMathPara>"; if (runState) Context.add_new_run(_T("")); } @@ -1807,25 +1812,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<oox::_docx_drawing *>(frame->oox_drawing_.get()); + if (href.empty()) return; + + oox::_docx_drawing* drawing = dynamic_cast<oox::_docx_drawing*>(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); - bool isMediaInternal = true; - drawing->objectId = Context.get_mediaitems()->add_or_find(href + extension, drawing->type, isMediaInternal, href, Context.get_type_place()); + 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()); + } + 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 55df515d82c..2307a167ba3 100644 --- a/OdfFile/Reader/Format/draw_frame_pptx.cpp +++ b/OdfFile/Reader/Format/draw_frame_pptx.cpp @@ -88,7 +88,7 @@ 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""); @@ -179,6 +179,9 @@ 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); @@ -191,12 +194,32 @@ void draw_frame::pptx_convert(oox::pptx_conversion_context & Context) Context.get_slide_context().set_placeHolder_idx(idx_in_owner); } + 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()) { 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); + + 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); @@ -341,12 +364,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; @@ -420,9 +444,9 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context) if (!math_content.empty()) { std::wstring text_content = L"<a:p><a14:m xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">"; - text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; +// text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; text_content += math_content; - text_content += L"</m:oMathPara></a14:m></a:p>"; + text_content += L"</a14:m></a:p>"; if (bNewObject) { @@ -465,12 +489,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); @@ -482,6 +512,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 ab7ee9bacf2..0a030d4bd4a 100644 --- a/OdfFile/Reader/Format/draw_frame_xlsx.cpp +++ b/OdfFile/Reader/Format/draw_frame_xlsx.cpp @@ -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"<a:p><a14:m xmlns:a14=\"http://schemas.microsoft.com/office/drawing/2010/main\">"; - text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; +// text_content += L"<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\">"; text_content += math_content; - text_content += L"</m:oMathPara></a14:m></a:p>"; + text_content += L"</a14:m></a:p>"; if (bNewObject) { @@ -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 12fe1fecaba..ac0ab285074 100644 --- a/OdfFile/Reader/Format/draw_page.cpp +++ b/OdfFile/Reader/Format/draw_page.cpp @@ -207,7 +207,6 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context) } Context.end_page(); - Context.get_slide_context().get_animation_context().clear(); if (presentation_notes_) { diff --git a/OdfFile/Reader/Format/draw_shapes_pptx.cpp b/OdfFile/Reader/Format/draw_shapes_pptx.cpp index 5a289712598..04bc9eb8ed0 100644 --- a/OdfFile/Reader/Format/draw_shapes_pptx.cpp +++ b/OdfFile/Reader/Format/draw_shapes_pptx.cpp @@ -139,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++) { @@ -391,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/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 <xml/xmlchar.h> #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<svg_font_face_uri> }; CP_REGISTER_OFFICE_ELEMENT2(svg_font_face_uri); +// svg:title +class svg_title : public office_element_impl<svg_title> +{ +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<svg_desc> { @@ -89,6 +114,8 @@ class svg_desc : public office_element_impl<svg_desc> 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/math_elements.cpp b/OdfFile/Reader/Format/math_elements.cpp index 7e68a62abf0..a47bea07012 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<office_math_element*>(semantics_.get()); - math_element->oox_convert(Context); + math_element->oox_convert(Context,iTypeConversion); } } @@ -93,10 +94,50 @@ 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<math_annotation*>(annotation_.get()); + math_annotation_xml* annotation_xml = dynamic_cast<math_annotation_xml*>(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.set*/ /*?*/ /*converter.set*/ Context.base_font_name_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_size_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_alignment_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_italic_; + /*parser.set*/ /*?*/ /*converter.set*/ Context.base_font_bold_; + + 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()); + + + Context.output_stream() << converter.GetOOXML(); + } + + if (!result) { - office_math_element* math_element = dynamic_cast<office_math_element*>(content_[i].get()); - math_element->oox_convert(Context); + for (size_t i = 0; i < content_.size(); i++) + { + office_math_element* math_element = dynamic_cast<office_math_element*>(content_[i].get()); + math_element->oox_convert(Context); + } } } @@ -126,11 +167,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 +193,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<office_math_element> 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<office_math> 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..3ed2f4a9b14 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" @@ -540,6 +541,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) 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 <xml/xmlchar.h> +#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<presentation_footer_decl*>(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<presentation_date_time_decl*>(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 <iosfwd> + +#include "office_elements.h" +#include "office_elements_create.h" + +namespace cpdoccore { +namespace odf_reader { + +class office_drawing : public office_element_impl<office_drawing> +{ +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/paragraph_elements.cpp b/OdfFile/Reader/Format/paragraph_elements.cpp index 230e98b6252..8ae6163db6e 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"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>"; } } + +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"<w:r><w:fldChar w:fldCharType=\"begin\""; + if (bLock) + { + strm << L" w:fldLock=\"1\""; + } + strm << L"/></w:r>"; + strm << L"<w:r><w:instrText>" << field_name << L"</w:instrText></w:r><w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>"; + } + + docx_serialize_run(content, Context); + + if (false == field_name.empty()) + { + strm << L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>"; + } +} 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"</w:sdtContent></w:sdt>"; } +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"<w:sdt><w:sdtPr><w:alias w:val=\""; + strm << name; + strm << L"\"/><w:temporary/>"; + strm << L"<w:showingPlcHdr/><w:text/></w:sdtPr><w:sdtContent>"; + + docx_serialize_run(content, Context); + + strm << L"</w:sdtContent></w:sdt>"; +} 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""; @@ -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"<w:hyperlink w:anchor=\"" << ref << L"\" w:history=\"1\">"; - 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"); + break; + } + } + + return result; +} + 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"#")) + { + Context.get_text_context().set_action(L"ppaction://hlinksldjump"); + + href = convert_href(Context, href); + } + + 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"<w:fldSimple w:instr=\" SEQ " << XmlUtils::EncodeXmlString(sequence) << L" \\* " << num_format << 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..7551c1ecf52 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_impl<paragraph_content_ virtual void xlsx_convert(oox::xlsx_conversion_context & Context){} virtual void pptx_convert(oox::pptx_conversion_context & Context){} - virtual void docx_serialize_sdt_placeholder(const std::wstring & name, office_element_ptr & text, oox::docx_conversion_context & Context); - virtual void docx_serialize_field(const std::wstring & field_name, office_element_ptr & text, oox::docx_conversion_context & Context, bool bLock = false); - virtual void docx_serialize_run(office_element_ptr & text, oox::docx_conversion_context & Context); + virtual void docx_serialize_sdt_placeholder(const std::wstring& name, office_element_ptr_array& content, oox::docx_conversion_context& Context); + virtual void docx_serialize_sdt_placeholder(const std::wstring & name, office_element_ptr & text, oox::docx_conversion_context & Context); + + virtual void docx_serialize_field(const std::wstring & field_name, office_element_ptr & content, oox::docx_conversion_context & Context, bool bLock = false); + virtual void docx_serialize_field(const std::wstring& field_name, office_element_ptr_array& text, oox::docx_conversion_context& Context, bool bLock = false); + + virtual void docx_serialize_run(office_element_ptr & text, oox::docx_conversion_context & Context); + virtual void docx_serialize_run(office_element_ptr_array& content, oox::docx_conversion_context& Context); + + virtual void xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context); - virtual void xlsx_serialize(std::wostream & _Wostream, oox::xlsx_conversion_context & Context) - { - text_to_stream(_Wostream, true); - } 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){} @@ -245,7 +249,6 @@ class bookmark : public paragraph_content_element virtual void add_text(const std::wstring & Text) {} }; - CP_REGISTER_OFFICE_ELEMENT2(bookmark); //------------------------------------------------------------------------------------------------------------------- // text:bookmark-start @@ -314,12 +317,15 @@ class bookmark_ref : public paragraph_content_element CPDOCCORE_DEFINE_VISITABLE(); CPDOCCORE_OFFICE_DOCUMENT_IMPL_NAME_FUNCS_; - _CP_OPT(std::wstring) ref_name_; - _CP_OPT(std::wstring) reference_format_; - std::wstring content_; + virtual void docx_convert(oox::docx_conversion_context& Context); + + _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + + office_element_ptr_array content_; 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_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); virtual void add_text(const std::wstring & Text); }; CP_REGISTER_OFFICE_ELEMENT2(bookmark_ref); @@ -337,9 +343,10 @@ class reference_ref : public paragraph_content_element CPDOCCORE_DEFINE_VISITABLE(); CPDOCCORE_OFFICE_DOCUMENT_IMPL_NAME_FUNCS_; - _CP_OPT(std::wstring) ref_name_; - _CP_OPT(std::wstring) reference_format_; - std::wstring content_; + _CP_OPT(std::wstring) ref_name_; + _CP_OPT(odf_types::reference_format) reference_format_; + + std::wstring content_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); @@ -613,7 +620,9 @@ class title : public paragraph_content_element virtual void xlsx_convert(oox::xlsx_conversion_context & Context); virtual void pptx_convert(oox::pptx_conversion_context & Context) ; - _CP_OPT(odf_types::Bool) text_fixed_; + virtual void xlsx_serialize(std::wostream& _Wostream, oox::xlsx_conversion_context& Context); + + _CP_OPT(odf_types::Bool) text_fixed_; office_element_ptr text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); @@ -699,10 +708,10 @@ class text_placeholder : public paragraph_content_element _CP_OPT(std::wstring) text_description_; _CP_OPT(std::wstring) text_placeholder_type_; - office_element_ptr text_; + office_element_ptr_array content_; 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_child_element(xml::sax* Reader, const std::wstring& Ns, const std::wstring& Name); virtual void add_text(const std::wstring & Text); }; @@ -1007,7 +1016,7 @@ class sequence : public paragraph_content_element _CP_OPT(std::wstring) ref_name_; _CP_OPT(std::wstring) template_; - office_element_ptr_array text_; + office_element_ptr_array content_; 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); @@ -1086,10 +1095,10 @@ class sequence_ref : public paragraph_content_element void docx_convert(oox::docx_conversion_context & Context); - _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_; - office_element_ptr text_; + office_element_ptr text_; private: virtual void add_attributes( const xml::attributes_wc_ptr & Attributes ); diff --git a/OdfFile/Reader/Format/style_graphic_properties.cpp b/OdfFile/Reader/Format/style_graphic_properties.cpp index 99a0e223aad..485c2b29d2b 100644 --- a/OdfFile/Reader/Format/style_graphic_properties.cpp +++ b/OdfFile/Reader/Format/style_graphic_properties.cpp @@ -249,6 +249,7 @@ void graphic_format_properties::apply_from(const graphic_format_properties * Oth _CP_APPLY_PROP(style_background_image_, Other->style_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> graphic_format_properties_ptr; diff --git a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp index 12ca330a5bf..8e40c414893 100644 --- a/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp +++ b/OdfFile/Reader/Format/style_paragraph_properties_pptx.cpp @@ -35,6 +35,8 @@ #include <xml/simple_xml_writer.h> #include "../../Reader/Converter/pptx_conversion_context.h" +#include "../../Reader/Format/odf_document.h" +#include "../../Reader/Format/odfcontext.h" #include "../../DataTypes/borderstyle.h" namespace cpdoccore { @@ -452,13 +454,35 @@ 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); @@ -475,16 +499,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 +522,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_text_properties.cpp b/OdfFile/Reader/Format/style_text_properties.cpp index 1ed28cf320e..3ffccee4232 100644 --- a/OdfFile/Reader/Format/style_text_properties.cpp +++ b/OdfFile/Reader/Format/style_text_properties.cpp @@ -311,7 +311,7 @@ void text_format_properties::pptx_convert_as_list(oox::pptx_conversion_context & } } } -void text_format_properties::drawing_serialize(std::wostream & strm, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style, std::wstring hlink) +void text_format_properties::drawing_serialize(std::wostream & strm, std::wstring node, fonts_container & fonts, const odf_reader::style_instance *current_style, const oox::hyperlink_data link) { CP_XML_WRITER(strm) { @@ -541,12 +541,15 @@ void text_format_properties::drawing_serialize(std::wostream & strm, std::wstrin } } - if (!hlink.empty()) + if (!link.rId.empty()) { CP_XML_NODE(L"a:hlinkClick") { - CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); - CP_XML_ATTR(L"r:id", hlink); + if (link.action == L"ppaction://hlinksldjump") + CP_XML_ATTR(L"action", link.action); + else + CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + CP_XML_ATTR(L"r:id", link.rId); } } } @@ -1031,7 +1034,9 @@ void text_format_properties::pptx_convert(oox::pptx_conversion_context & Context oox::styles_context & styles_context_ = Context.get_text_context().get_styles_context(); fonts_container & fonts_ = Context.root()->odf_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..54350581f67 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 { @@ -279,6 +281,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 +867,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 +1444,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 +1517,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 +1564,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 +1828,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 +2101,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<text::p*>(content_[i].get()); + for (size_t j = 0; p && j < p->paragraph_.content_.size(); j++) + { + text::paragraph_content_element* paragraph_element = dynamic_cast<text::paragraph_content_element*>(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 +2169,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 +2197,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..4cf374d9dc5 100644 --- a/OdfFile/Reader/Format/styles.h +++ b/OdfFile/Reader/Format/styles.h @@ -676,6 +676,8 @@ class style_columns : public office_element_impl<style_columns> 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 +969,8 @@ class style_page_layout_properties : public office_element_impl<style_page_layou 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); + + int DetectPageSize(double w, double h); }; CP_REGISTER_OFFICE_ELEMENT2(style_page_layout_properties); //------------------------------------------------------------------------------------------------------------------------- @@ -1022,7 +1026,8 @@ class text_linenumbering_configuration : public office_element_impl<text_linenum _CP_OPT(bool) text_count_empty_lines_; _CP_OPT(bool) text_count_in_text_boxes_; _CP_OPT(unsigned int) text_increment_; - _CP_OPT(std::wstring) text_number_position_; //inner, left, outer, right + _CP_OPT(unsigned int) text_start_; + _CP_OPT(std::wstring) text_number_position_; //inner, left, outer, right _CP_OPT(odf_types::length) text_offset_; _CP_OPT(bool) text_restart_on_page_; diff --git a/OdfFile/Reader/Format/styles_lite_container.cpp b/OdfFile/Reader/Format/styles_lite_container.cpp index 59e80fe20f3..0381d1d0160 100644 --- a/OdfFile/Reader/Format/styles_lite_container.cpp +++ b/OdfFile/Reader/Format/styles_lite_container.cpp @@ -35,6 +35,7 @@ #include "styles_lite_container.h" #include "office_settings.h" +#include "../../Common/xml/simple_xml_writer.h" namespace cpdoccore { @@ -107,6 +108,29 @@ std::wstring doc_props_container::get_user_defined(const std::wstring & name) return pFind != impl_->map_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<std::wstring, std::wstring>::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 diff --git a/OdfFile/Reader/Format/styles_lite_container.h b/OdfFile/Reader/Format/styles_lite_container.h index 3d5dedbb2cb..06fc5f34848 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_; 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..20df34a1d62 100644 --- a/OdfFile/Reader/Format/table_pptx.cpp +++ b/OdfFile/Reader/Format/table_pptx.cpp @@ -67,8 +67,19 @@ 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) { @@ -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<table_body_template* >(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<table_first_row_template*>(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<table_last_row_template*>(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<table_odd_rows_template*>(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<table_first_column_template*>(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<table_last_column_template*>(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<table_odd_columns_template*>(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_); + } } } @@ -322,6 +374,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<const style_instance *> style_instances; @@ -336,18 +398,30 @@ void table_table_cell::pptx_convert(oox::pptx_conversion_context & Context) 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_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); 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); + 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, false); + if (style_inst) style_instances.push_back(style_inst); + } + } + style_name = attlist_.table_style_name_.get_value_or(L""); if (!style_name.empty()) { diff --git a/OdfFile/Test/audio.cpp b/OdfFile/Test/audio.cpp index 0152443eeb2..b7df1b30d12 100644 --- a/OdfFile/Test/audio.cpp +++ b/OdfFile/Test/audio.cpp @@ -104,36 +104,40 @@ const cpdoccore::oox::pptx_animation_context::Impl::_animation_element_array& OD return actions; } -TEST_F(ODP2OOX_AnimationAudioTest, r_embed_id) +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(), 4); - const auto audio = dynamic_cast<pptx_animation_context::Impl::_audio*>(actions[3].get()); ; - ASSERT_NE(audio, nullptr); - - const std::wstring rIdExp = L"aId1"; - - EXPECT_EQ(audio->RId.value(), rIdExp); + ASSERT_EQ(actions.size(), 3); + const auto set = dynamic_cast<pptx_animation_context::Impl::_set*>(actions[0].get()); + ASSERT_NE(set, nullptr); } -TEST_F(ODP2OOX_AnimationAudioTest, name) +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(), 4); - const auto audio = dynamic_cast<pptx_animation_context::Impl::_audio*>(actions[3].get()); ; - ASSERT_NE(audio, nullptr); + ASSERT_EQ(actions.size(), 3); + const auto anim = dynamic_cast<pptx_animation_context::Impl::_anim*>(actions[1].get()); + ASSERT_NE(anim, nullptr); +} - const std::wstring nameExp = L"apert.wav"; +TEST_F(ODP2OOX_AnimationAudioTest, anim_2) +{ + using namespace cpdoccore::oox; - EXPECT_EQ(audio->Name.value(), nameExp); + 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<pptx_animation_context::Impl::_anim*>(actions[2].get()); + ASSERT_NE(anim, nullptr); } ////////////////////////////////////////////////////////////////////////// diff --git a/OdfFile/Test/common.cpp b/OdfFile/Test/common.cpp index 42da3e35e8d..c62de29df65 100644 --- a/OdfFile/Test/common.cpp +++ b/OdfFile/Test/common.cpp @@ -191,7 +191,10 @@ const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnerPar(const if (!par) return nullptr; - const anim_par* inner_par = dynamic_cast<anim_par*>(par->anim_par_.get()); + if (par->anim_par_.size() == 0) + return nullptr; + + const anim_par* inner_par = dynamic_cast<anim_par*>(par->anim_par_[0].get()); if (!inner_par) return nullptr; @@ -208,9 +211,9 @@ const cpdoccore::odf_writer::anim_par* OOX2ODP_AnimationTest::GetInnermostPar(co const anim_par* innermost = GetInnerPar(par); - while (innermost->anim_par_) + while (innermost->anim_par_.size()) { - innermost = dynamic_cast<anim_par*>(innermost->anim_par_.get()); + innermost = dynamic_cast<anim_par*>(innermost->anim_par_[0].get()); if (!innermost) return nullptr; } diff --git a/OdfFile/Test/entrance.cpp b/OdfFile/Test/entrance.cpp index ac0dd1cbf48..75001e91cb3 100644 --- a/OdfFile/Test/entrance.cpp +++ b/OdfFile/Test/entrance.cpp @@ -432,8 +432,8 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_1_key_point const pptx_animation_context::Impl::_anim* animate1 = dynamic_cast<pptx_animation_context::Impl::_anim*>(actions[1].get()); std::vector<pptx_animation_context::Impl::_anim::_keypoint> 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)); + 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++) @@ -513,8 +513,8 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_fly_in_action_animate_2_key_point const pptx_animation_context::Impl::_anim* animate2 = dynamic_cast<pptx_animation_context::Impl::_anim*>(actions[2].get()); std::vector<pptx_animation_context::Impl::_anim::_keypoint> 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)); + 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++) @@ -576,9 +576,7 @@ TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_trans const pptx_animation_context::Impl::_animation_element_array& actions = GetAnimationActionsByIndex(animationIndex); const pptx_animation_context::Impl::_anim_effect* animEffect = dynamic_cast<pptx_animation_context::Impl::_anim_effect*>(actions[1].get()); - const std::wstring transitionExp = L"in"; - - EXPECT_EQ(animEffect->Transition.value(), transitionExp); + EXPECT_FALSE(animEffect->Transition.has_value()); } TEST_F(ODP2OOX_EntranceAnimationTest, entrance_venetian_blinds_anim_effect_duration) diff --git a/OdfFile/Test/interactions.cpp b/OdfFile/Test/interactions.cpp index 16860f0de95..8247f9b8569 100644 --- a/OdfFile/Test/interactions.cpp +++ b/OdfFile/Test/interactions.cpp @@ -197,49 +197,69 @@ TEST_F(ODP2OOX_AnimationPlayAudioTest, rels_size) ASSERT_NE(mConversionContext, nullptr); auto rels_ = mConversionContext->current_slide().Rels().relationships(); - const size_t relsSizeExp = 3; + const size_t relsSizeExp = 2; - EXPECT_EQ(rels_.size(), 3); + EXPECT_EQ(rels_.size(), relsSizeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_id) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_type) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring idExp = L"hId1"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"; - EXPECT_EQ(audioRel.id(), idExp); + EXPECT_EQ(slideRel.type(), typeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_type) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring typeExp = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetExp = L"../slideLayouts/slideLayout1.xml"; - EXPECT_EQ(audioRel.type(), typeExp); + EXPECT_EQ(slideRel.target(), targetExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_target) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_slide_rel_target_mode) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring targetExp = L"../../../../X2tConverter/test/win32Test/Res/media_example.wav"; + auto slideRel = mConversionContext->current_slide().Rels().relationships()[0]; + const std::wstring targetModeExp = L""; - EXPECT_EQ(audioRel.target(), targetExp); + EXPECT_EQ(slideRel.target_mode(), targetModeExp); } -TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_rel_target_mode) +TEST_F(ODP2OOX_AnimationPlayAudioTest, audio_notes_rel_type) { ASSERT_NE(mConversionContext, nullptr); - auto audioRel = mConversionContext->current_slide().Rels().relationships()[1]; - const std::wstring targetModeExp = L"External"; + 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(audioRel.target_mode(), targetModeExp); + EXPECT_EQ(notesRel.target_mode(), targetModeExp); } ////////////////////////////////////////////////////////////////////////// diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 3d078d88037..69b6c8857a4 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -397,7 +397,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()) { @@ -433,8 +433,7 @@ void OoxConverter::convert(PPTX::Logic::Pic *oox_picture) if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast<OOX::Image*>(pFile.GetPointer()); - + smart_ptr<OOX::Image> pImageFileCache = pFile.smart_dynamic_cast<OOX::Image>(); pathImage = pImageFileCache->filename().GetPath(); } } @@ -443,7 +442,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(); @@ -452,6 +451,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); { @@ -1676,8 +1680,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()) { @@ -1993,6 +2000,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<PPTX::Logic::RunElem>& runElems) +{ + using namespace PPTX::Logic; + + auto runIt = std::find_if_not(runElems.begin(), runElems.end(), + [](const RunElem& r) { + return !r.is<Run>(); + }); + if (runIt != runElems.end()) + { + const Run& run = runIt->as<Run>(); + 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; @@ -2036,6 +2063,8 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T if (paraPr->ParagraphBullet.is<PPTX::Logic::BuNone>()) 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(); @@ -2061,17 +2090,7 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T } } - std::vector<PPTX::Logic::RunElem>::iterator runIt = std::find_if_not(oox_paragraph->RunElems.begin(), oox_paragraph->RunElems.end(), - [](const PPTX::Logic::RunElem& r) { - return !r.is<PPTX::Logic::Run>(); - }); - if (runIt != oox_paragraph->RunElems.end()) - { - const PPTX::Logic::Run& run = runIt->as<PPTX::Logic::Run>(); - if (!run.HasText()) - list_present = false; - } - else + if (is_empty_run_elems(oox_paragraph->RunElems)) list_present = false; //if (oox_paragraph->RunElems.empty() && list_present) list_present = false; // ms не обозначает присутствие списка, libra - показывает значек @@ -2134,7 +2153,9 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T } else { - odf_context()->text_context()->start_span(true); + bool styled = oox_paragraph->endParaRPr.IsInit() && oox_paragraph->endParaRPr->sz.IsInit(); + + odf_context()->text_context()->start_span(styled); odf_context()->text_context()->end_span(); } @@ -2499,10 +2520,6 @@ 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); } - if (oox_run_pr->hlinkClick.IsInit()) - { - convert(oox_run_pr->hlinkClick.GetPointer()); - } } static std::vector<std::wstring> split_tabs(const std::wstring& text) { @@ -2577,6 +2594,29 @@ 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<OOX::File> file = find_file_by_id(oox_run->rPr->hlinkClick->id.get()); + OOX::HyperLink* hyperlink = dynamic_cast<OOX::HyperLink*>(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 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/DocxConverter.cpp b/OdfFile/Writer/Converter/DocxConverter.cpp index 7bceddb829e..e5bb5d18c8c 100644 --- a/OdfFile/Writer/Converter/DocxConverter.cpp +++ b/OdfFile/Writer/Converter/DocxConverter.cpp @@ -1869,38 +1869,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) @@ -1908,7 +1908,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); @@ -1918,14 +1918,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; @@ -1934,8 +1934,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(); @@ -1953,13 +1953,13 @@ 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 ) + + 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(); @@ -1979,14 +1979,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); @@ -2010,14 +2010,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()); } @@ -2028,9 +2028,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 @@ -2065,9 +2065,9 @@ void DocxConverter::convert(OOX::Logic::CSectionProperty *oox_section_pr, bool b { convert(docx_flat_document->m_pBgPict.GetPointer(), 1); } - //nullable<ComplexTypes::Word::CTextDirection > m_oTextDirection; - //nullable<ComplexTypes::Word::COnOff2 > m_oRtlGutter; - //nullable<ComplexTypes::Word::CVerticalJc > m_oVAlign; + //nullable<ComplexTypes::Word::CTextDirection > m_oTextDirection; + //nullable<ComplexTypes::Word::COnOff2 > m_oRtlGutter; + //nullable<ComplexTypes::Word::CVerticalJc > m_oVAlign; if (oox_section_pr->m_oPgNumType.IsInit()) { @@ -2075,23 +2075,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<SimpleTypes::CChapterSep<> > m_oChapSep; - //nullable<SimpleTypes::CDecimalNumber<> > m_oChapStyle; + odt_context->page_layout_context()->set_page_number_format(format, start); + //nullable<SimpleTypes::CChapterSep<> > m_oChapSep; + //nullable<SimpleTypes::CDecimalNumber<> > 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<int> types; @@ -2099,14 +2099,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)) { @@ -2122,22 +2122,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)) { @@ -2150,12 +2150,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; @@ -2164,16 +2164,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<odf_writer::text_linenumbering_configuration *>(lnNum_elm.get()); + odf_writer::text_linenumbering_configuration* linenumbering = dynamic_cast<odf_writer::text_linenumbering_configuration*>(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()) { @@ -2182,19 +2183,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); @@ -3143,7 +3145,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()) { @@ -3156,7 +3158,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); diff --git a/OdfFile/Writer/Converter/MathConverter.cpp b/OdfFile/Writer/Converter/MathConverter.cpp index 775989c86d7..abea02d0cdf 100644 --- a/OdfFile/Writer/Converter/MathConverter.cpp +++ b/OdfFile/Writer/Converter/MathConverter.cpp @@ -529,6 +529,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; @@ -854,6 +855,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(); @@ -1031,6 +1033,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; @@ -1626,6 +1629,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 +1638,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,7 +1657,7 @@ 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"∫"); @@ -1747,7 +1753,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(); } diff --git a/OdfFile/Writer/Converter/PptxConverter.cpp b/OdfFile/Writer/Converter/PptxConverter.cpp index 0cf8f536ee0..343efc38142 100644 --- a/OdfFile/Writer/Converter/PptxConverter.cpp +++ b/OdfFile/Writer/Converter/PptxConverter.cpp @@ -84,6 +84,7 @@ #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" @@ -1280,22 +1281,44 @@ std::wstring PptxConverter::get_page_name(PPTX::Logic::CSld* oox_slide, _typePag void PptxConverter::fill_in_deferred_hyperlinks() { - for (auto hyperlink : odp_context->get_deferred_hyperlinks()) + auto links = odp_context->get_deferred_hyperlinks(); + auto slidenames_vec = std::vector<std::pair<std::wstring, std::wstring>>(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<cpdoccore::odf_writer::presentation_event_listener*>(hyperlink.first.get()); + cpdoccore::odf_writer::text_a* text = dynamic_cast<cpdoccore::odf_writer::text_a*>(hyperlink.first.get()); const std::wstring& slidename = hyperlink.second; - if (!event_listener) - continue; - + std::wstring href; auto hrefIt = odp_context->map_slidenames_.find(slidename); - if (hrefIt == odp_context->map_slidenames_.end()) + 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; - event_listener->attlist_.common_xlink_attlist_.href_ = std::wstring(L"#") + hrefIt->second; - 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; + 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; + } } } @@ -1807,22 +1830,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) { @@ -1882,8 +1918,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) { diff --git a/OdfFile/Writer/Converter/XlsxConverter.cpp b/OdfFile/Writer/Converter/XlsxConverter.cpp index 7b7dc848464..ec9c8a1dcf5 100644 --- a/OdfFile/Writer/Converter/XlsxConverter.cpp +++ b/OdfFile/Writer/Converter/XlsxConverter.cpp @@ -445,9 +445,10 @@ void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet) if (!oox_sheet->m_arrConditionalFormatting.empty() || oox_sheet->m_oExtLst.IsInit()) { - std::multimap<int, OOX::Spreadsheet::CConditionalFormatting*> mapSorted; + std::multimap<int, std::pair<OOX::Spreadsheet::CConditionalFormatting*, bool>> mapSorted; - std::vector<OOX::Spreadsheet::CConditionalFormatting*> arUnsorted; + std::vector<std::pair<OOX::Spreadsheet::CConditionalFormatting*, bool>> arUnsorted; + std::vector<std::pair<OOX::Spreadsheet::CConditionalFormatting*, bool>> arUnsortedEx; // sort by prioritet for (size_t fmt = 0; fmt < oox_sheet->m_arrConditionalFormatting.size(); fmt++) @@ -465,9 +466,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 +493,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<int, OOX::Spreadsheet::CConditionalFormatting*>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) + for (std::multimap<int, std::pair<OOX::Spreadsheet::CConditionalFormatting*, bool>>::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(); } @@ -1151,6 +1157,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 +1275,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 +1353,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 +1407,19 @@ void XlsxConverter::convert(OOX::Spreadsheet::CExternalLink *oox_external_link) smart_ptr<OOX::External> fileExternal = file.smart_dynamic_cast<OOX::External>(); 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; } @@ -1992,6 +2008,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 +2029,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 +2566,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; } } @@ -2956,7 +3021,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 +3029,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 +3083,9 @@ void XlsxConverter::convert(OOX::Spreadsheet::COleObjects *oox_objects, OOX::Spr if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) { - OOX::Image* pImageFileCache = static_cast<OOX::Image*>(pFile.GetPointer()); - - if (pImageFileCache && odf_ref_image.empty()) + smart_ptr<OOX::Image> pImageFileCache = pFile.smart_dynamic_cast<OOX::Image>(); + + if (pImageFileCache.IsInit() && odf_ref_image.empty()) { odf_ref_image = odf_context()->add_imageobject(pImageFileCache->filename().GetPath()); } @@ -3409,35 +3474,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<std::wstring, OOX::Spreadsheet::CConditionalFormattingRule*>& 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<std::wstring, OOX::Spreadsheet::CConditionalFormattingRule*>& mapCFRuleEx, bool isExt) { - if (!oox_cond_rule)return; + if (!oox_cond_rule) return; + + std::map<std::wstring, OOX::Spreadsheet::CConditionalFormattingRule*>::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()) { @@ -3460,7 +3556,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()); @@ -3476,26 +3572,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<SimpleTypes::CUnsignedDecimalNumber<>> m_oMaxLength; - //nullable<SimpleTypes::CUnsignedDecimalNumber<>> 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<std::wstring, OOX::Spreadsheet::CConditionalFormattingRule*>& mapCFRuleEx, bool isExt); + void convert(OOX::Spreadsheet::CConditionalFormattingRule *oox_cond_rule, + std::map<std::wstring, OOX::Spreadsheet::CConditionalFormattingRule*>& 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/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/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_shapes.cpp b/OdfFile/Writer/Format/draw_shapes.cpp index 7149a8fed2e..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_); diff --git a/OdfFile/Writer/Format/draw_shapes.h b/OdfFile/Writer/Format/draw_shapes.h index ba79801a85d..de272fb8e2d 100644 --- a/OdfFile/Writer/Format/draw_shapes.h +++ b/OdfFile/Writer/Format/draw_shapes.h @@ -311,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_; diff --git a/OdfFile/Writer/Format/odf_conversion_context.cpp b/OdfFile/Writer/Format/odf_conversion_context.cpp index 3415af65cb1..849724ada1e 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.cpp +++ b/OdfFile/Writer/Format/odf_conversion_context.cpp @@ -565,23 +565,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 1a163f5e487..c16098f3c51 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.h +++ b/OdfFile/Writer/Format/odf_conversion_context.h @@ -123,8 +123,8 @@ 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); diff --git a/OdfFile/Writer/Format/odf_drawing_context.cpp b/OdfFile/Writer/Format/odf_drawing_context.cpp index 6492c82691b..7bd677c38a3 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.cpp +++ b/OdfFile/Writer/Format/odf_drawing_context.cpp @@ -433,7 +433,7 @@ 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_; @@ -630,7 +630,7 @@ 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_; @@ -1178,15 +1178,17 @@ 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; - } - else if (impl_->current_drawing_state_.oox_shape_ && !impl_->current_drawing_state_.oox_shape_->modifiers.empty()) + //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; } @@ -1469,11 +1471,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; @@ -2759,12 +2757,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: @@ -2780,9 +2779,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); @@ -3172,6 +3173,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<style_columns>(); + + 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; diff --git a/OdfFile/Writer/Format/odf_drawing_context.h b/OdfFile/Writer/Format/odf_drawing_context.h index c38725eb433..28949e0cf82 100644 --- a/OdfFile/Writer/Format/odf_drawing_context.h +++ b/OdfFile/Writer/Format/odf_drawing_context.h @@ -322,6 +322,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_number_styles_context.cpp b/OdfFile/Writer/Format/odf_number_styles_context.cpp index e4c383a6eed..1520be6bedc 100644 --- a/OdfFile/Writer/Format/odf_number_styles_context.cpp +++ b/OdfFile/Writer/Format/odf_number_styles_context.cpp @@ -929,31 +929,42 @@ void odf_number_styles_context::detect_format(number_format_state & state) std::wstring strFormatCode = boost::regex_replace(state.format_code[0], re_unwanted, &replace_unwanted, boost::match_any | boost::format_all); //find [$<Currency String>-<language info>]. - boost::wregex re(L"(?=(\\[{1}\\${1}(\\w*)\\-(\\d*)\\]{1}))"); + boost::wregex re(L"(\\[\\$.*\-[\\w\\d]+\\])"); std::vector<std::wstring> result; std::wstring tmp = strFormatCode; bool b = boost::regex_split(std::back_inserter(result), tmp, re); - if (b && result.size() >= 3) - { - state.currency_str = result[1]; - - int code = -1; - try + 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) + { + 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()) { - std::wstringstream ss; - ss << std::hex << result[2]; - ss >> state.language_code; - }catch(...){} + size_t pos_digit = (std::min)(strFormatCode.find(L"0"), strFormatCode.find(L"#")); + size_t pos_currency = strFormatCode.find(state.currency_str); + 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"([mM]{2,}|[hH]{2,}|[sS]{2,})"); - boost::wregex re2(L"([mM]{1,}|[dD]{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,})"); tmp = strFormatCode; 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<office_element>::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<office_element_ptr> 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_text_context.cpp b/OdfFile/Writer/Format/odf_text_context.cpp index 468f7ff0e59..aafce02d4cd 100644 --- a/OdfFile/Writer/Format/odf_text_context.cpp +++ b/OdfFile/Writer/Format/odf_text_context.cpp @@ -602,6 +602,18 @@ 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<text_bookmark_ref*>(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; } if (elm) @@ -669,9 +681,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 9bfb87c7931..960a18d382e 100644 --- a/OdfFile/Writer/Format/odf_text_context.h +++ b/OdfFile/Writer/Format/odf_text_context.h @@ -58,6 +58,7 @@ namespace odf_writer fieldDropDown, fieldDate, fieldTime, + fieldRef, fieldBibliography = 0xff + 1, fieldIndex, diff --git a/OdfFile/Writer/Format/odp_conversion_context.h b/OdfFile/Writer/Format/odp_conversion_context.h index 4068241e004..76b32462166 100644 --- a/OdfFile/Writer/Format/odp_conversion_context.h +++ b/OdfFile/Writer/Format/odp_conversion_context.h @@ -103,7 +103,7 @@ class odp_conversion_context : public odf_conversion_context std::vector<IdentifierMap> 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::unordered_map<std::wstring, std::wstring>; + using SlidenameMap = std::map<std::wstring, std::wstring>; SlidenameMap map_slidenames_; private: odp_slide_context slide_context_; diff --git a/OdfFile/Writer/Format/odp_page_state.cpp b/OdfFile/Writer/Format/odp_page_state.cpp index 50b52ecda16..91adaf20ce4 100644 --- a/OdfFile/Writer/Format/odp_page_state.cpp +++ b/OdfFile/Writer/Format/odp_page_state.cpp @@ -627,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); } } } diff --git a/OdfFile/Writer/Format/ods_table_state.cpp b/OdfFile/Writer/Format/ods_table_state.cpp index e51324774f1..745d154b720 100644 --- a/OdfFile/Writer/Format/ods_table_state.cpp +++ b/OdfFile/Writer/Format/ods_table_state.cpp @@ -69,7 +69,7 @@ namespace 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<std::wstring>(hours) - //+ std::wstring(L"H") + - + std::wstring(L":") + + + (bPT ? std::wstring(L"H") : std::wstring(L":")) + (minutes < 10 ? L"0" : L"") + boost::lexical_cast<std::wstring>(minutes) - //+ std::wstring(L"M") + - + std::wstring(L":") + - (sec1 < 10 ? L"0" : L"") + boost::lexical_cast<std::wstring>(sec1); - //+ std::wstring(L"S"); + + (bPT ? std::wstring(L"M") : std::wstring(L":")) + + (sec1 < 10 ? L"0" : L"") + boost::lexical_cast<std::wstring>(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); } }; @@ -1001,16 +997,17 @@ void ods_table_state::set_cell_formula(std::wstring & formula) ods_conversion_context* ods_context = dynamic_cast<ods_conversion_context*>(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; @@ -1019,33 +1016,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++) @@ -1393,7 +1385,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 || @@ -1952,7 +1944,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; @@ -1995,18 +1987,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: @@ -2039,17 +2040,19 @@ void ods_table_state::end_conditional_rule() void ods_table_state::set_conditional_formula(const std::wstring& formula) { calcext_condition* condition = dynamic_cast<calcext_condition*> (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) @@ -2084,18 +2087,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; } } } @@ -2250,7 +2253,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) @@ -2259,7 +2262,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) @@ -2268,7 +2271,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) @@ -2277,9 +2280,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<calcext_data_bar*>(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<calcext_data_bar*>(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<calcext_data_bar*>(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 fccbe0efa1e..af32f5c59ee 100644 --- a/OdfFile/Writer/Format/ods_table_state.h +++ b/OdfFile/Writer/Format/ods_table_state.h @@ -384,7 +384,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 +398,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); diff --git a/OdfFile/Writer/Format/odt_conversion_context.cpp b/OdfFile/Writer/Format/odt_conversion_context.cpp index da0f3a5fc7c..bdebe6ca243 100644 --- a/OdfFile/Writer/Format/odt_conversion_context.cpp +++ b/OdfFile/Writer/Format/odt_conversion_context.cpp @@ -590,6 +590,15 @@ void odt_conversion_context::start_hyperlink(const std::wstring& link, const std text_a* hyperlink = dynamic_cast<text_a*>(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; @@ -767,6 +776,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<std::wstring, std::wstring> options = parse_instr_options(options_str); + + for (std::map<std::wstring, std::wstring>::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) { diff --git a/OdfFile/Writer/Format/oox_shape_defines.h b/OdfFile/Writer/Format/oox_shape_defines.h index 01b987f8550..f281c352aa1 100644 --- a/OdfFile/Writer/Format/oox_shape_defines.h +++ b/OdfFile/Writer/Format/oox_shape_defines.h @@ -82,9 +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; - std::wstring path_stretchpoint_x; - std::wstring path_stretchpoint_y; + _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..7be39843430 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 //---------------------------------------------------------------------------------- diff --git a/OdfFile/Writer/Format/paragraph_elements.h b/OdfFile/Writer/Format/paragraph_elements.h index 78e345513d9..9b1fb663fdf 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<text_bookmark_end> std::wstring text_name_; }; CP_REGISTER_OFFICE_ELEMENT2(text_bookmark_end); +//------------------------------------------------------------------------------------------------------------------- +// text:bookmark-ref +//------------------------------------------------------------------------------------------------------------------- +class text_bookmark_ref : public office_element_impl<text_bookmark_ref> +{ +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<text_reference_mark> @@ -920,18 +947,17 @@ class text_sequence_ref : public office_element_impl<text_sequence_ref> 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); //------------------------------------------------------------------------------------------------------------------- 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 <xml/nodetype.h> #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> graphic_format_properties_ptr; diff --git a/OdfFile/Writer/Format/style_section_properties.h b/OdfFile/Writer/Format/style_section_properties.h index 75847996a2a..670d9a176cf 100644 --- a/OdfFile/Writer/Format/style_section_properties.h +++ b/OdfFile/Writer/Format/style_section_properties.h @@ -67,6 +67,7 @@ class style_columns : public office_element_impl<style_columns> office_element_ptr_array style_column_; }; +typedef shared_ptr<style_columns>::Type style_columns_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_columns); @@ -91,6 +92,7 @@ class style_column : public office_element_impl<style_column> _CP_OPT(odf_types::length) fo_space_after_; }; +typedef shared_ptr<style_column>::Type style_column_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column); @@ -115,6 +117,7 @@ class style_column_sep : public office_element_impl<style_column_sep> _CP_OPT(odf_types::vertical_align) style_vertical_align_; // default top _CP_OPT(odf_types::color) style_color_; // default #000000 }; +typedef shared_ptr<style_column_sep>::Type style_column_sep_ptr; CP_REGISTER_OFFICE_ELEMENT2(style_column_sep); @@ -144,6 +147,7 @@ class style_section_properties : public office_element_impl<style_section_proper office_element_ptr style_columns_; office_element_ptr style_background_image_; }; +typedef shared_ptr<style_section_properties>::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 053ea2984e5..9408af114d3 100644 --- a/OdfFile/Writer/Format/styles.cpp +++ b/OdfFile/Writer/Format/styles.cpp @@ -1423,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 c0acce8f6e1..a932d5dc1f4 100644 --- a/OdfFile/Writer/Format/styles.h +++ b/OdfFile/Writer/Format/styles.h @@ -841,7 +841,8 @@ class text_linenumbering_configuration : public office_element_impl<text_linenum _CP_OPT(odf_types::Bool) text_count_empty_lines_; _CP_OPT(odf_types::Bool) text_count_in_text_boxes_; _CP_OPT(unsigned int) text_increment_; - _CP_OPT(std::wstring) text_number_position_; //inner, left, outer, right + _CP_OPT(unsigned int) text_start_; + _CP_OPT(std::wstring) text_number_position_; //inner, left, outer, right _CP_OPT(odf_types::length) text_offset_; _CP_OPT(odf_types::Bool) text_restart_on_page_; 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/ZipUtilsCP.cpp b/OfficeUtils/src/ZipUtilsCP.cpp index ebb3d1dc2cf..306304fa7d8 100644 --- a/OfficeUtils/src/ZipUtilsCP.cpp +++ b/OfficeUtils/src/ZipUtilsCP.cpp @@ -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; @@ -380,13 +358,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); } } @@ -564,29 +551,37 @@ namespace ZLibZipUtils /*========================================================================================================*/ - int oneZipFile(zipFile & zf, zip_fileinfo* zi, std::wstring & file_name, std::wstring & zip_file_name, int method, int compressionLevel, bool bDateTime) + int oneZipFile(zipFile & zf, std::wstring & file_name, std::wstring & zip_file_name, int method, int compressionLevel, bool bDateTime) { int err = -1; - NSFile::CFileBinary oFile; zip_fileinfo zinfo; - zinfo.dosDate = zinfo.external_fa = zinfo.internal_fa = 0; - zinfo.tmz_date.tm_sec = zinfo.tmz_date.tm_min = zinfo.tmz_date.tm_hour = 0; - zinfo.tmz_date.tm_mday = 1; - zinfo.tmz_date.tm_mon = 0; - zinfo.tmz_date.tm_year = 1980; - - zip_fileinfo* zi_new = zi ? zi : &zinfo; - if (bDateTime ) + zinfo.dosDate = 0; + zinfo.external_fa = 0; + zinfo.internal_fa = 0; + + if (bDateTime) { - zi_new->dosDate = 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); @@ -596,7 +591,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 ) { @@ -651,6 +646,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] ); @@ -668,13 +668,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; @@ -687,7 +688,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 ) { @@ -724,15 +725,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(oFile.OpenFile(inputFile)) + 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)) { DWORD dwSizeRead; BYTE* pData = new BYTE[oFile.GetFileSize()]; @@ -741,26 +759,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 ); @@ -843,13 +845,13 @@ 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 ( uf != NULL && unzipDir != NULL ) { - if (NSDirectory::Exists(unzipDir)) - err = 0; + if (NSDirectory::Exists(unzipDir)) + err = 0; - if ( clearOutputDirectory ) + 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 <iostream> #include <algorithm> +#include <cmath> +#include <cstdlib> #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<std::wstring> expected_general; std::vector<std::wstring> 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 326ade47197..b41b122b247 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -153,7 +153,7 @@ namespace NSOnlineOfficeBinToPdf 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()); @@ -167,7 +167,7 @@ namespace NSOnlineOfficeBinToPdf oCorrector.InitPicker(pPdf->GetFonts()); } - NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nLen); + NSOnlineOfficeBinToPdf::CBufferReader oReader(pBuffer, (int)nBufferLen); while (oReader.Check()) { @@ -191,9 +191,16 @@ 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: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp new file mode 100644 index 00000000000..ec49c354509 --- /dev/null +++ b/PdfFile/PdfEditor.cpp @@ -0,0 +1,1487 @@ +/* + * (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 "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, ""); + 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; + } +} +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 StreamGetCTM(XRef* pXref, Object* oStream, double* dCTM) +{ + Parser* parser = new Parser(pXref, new Lexer(pXref, oStream), 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); +} +void GetCTM(XRef* pXref, Object* oPage, double* dCTM) +{ + if (!oPage || !oPage->isDict()) + return; + + Object oContents; + if (!oPage->dictLookup("Contents", &oContents)) + { + oContents.free(); + return; + } + + if (oContents.isArray()) + { + for (int nIndex = 0; nIndex < oContents.arrayGetLength(); ++nIndex) + { + Object oTemp; + oContents.arrayGet(nIndex, &oTemp); + if (oTemp.isStream()) + StreamGetCTM(pXref, &oTemp, dCTM); + oTemp.free(); + } + } + else if (oContents.isStream()) + StreamGetCTM(pXref, &oContents, dCTM); + 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::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); + 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(); +} +bool CPdfEditor::EditPage(int nPageIndex) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return false; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (pEditPage) + { + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + return true; + } + + XRef* xref = pPDFDocument->getXRef(); + Catalog* pCatalog = pPDFDocument->getCatalog(); + if (!xref || !pCatalog) + return false; + std::pair<int, int> 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 + 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 (pWriter->EditPage(pPage) && pDoc->EditPage(pXref, pPage, nPageIndex)) + { + m_nEditPage = nPageIndex; + pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + 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; + + PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + if (!pEditPage) + { + pEditPage = pDoc->GetCurPage(); + EditPage(nPageIndex); + pDoc->SetCurPage(pEditPage); + pWriter->EditPage(pEditPage); + } + + XRef* xref = pPDFDocument->getXRef(); + std::pair<int, int> 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(); + 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<std::wstring, std::wstring> 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("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(); + } + 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("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) + { + oParentRef.free(); + continue; + } + + ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); + PdfWriter::CArrayObject* pKids = dynamic_cast<PdfWriter::CArrayObject*>(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(); + } + 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; +} +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<int, int> 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<CWidgetsInfo::CParent*> 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<int, int> 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<std::wstring, std::wstring>::iterator it = m_mFonts.find(wsFontName); + if (it == m_mFonts.end()) + return false; + wsFontPath = it->second; + 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") + 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..c87f7df1857 --- /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 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); + + std::wstring wsSrcFile; + std::wstring wsPassword; + std::map<std::wstring, std::wstring> 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 7d4d916ad3c..6524ec080de 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -34,134 +34,36 @@ #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" -#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) +#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(), 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, ""); - 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) { 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 @@ -173,80 +75,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; }; // ------------------------------------------------------------------------ @@ -258,14 +88,13 @@ 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); } NSFonts::IFontManager* CPdfFile::GetFontManager() { @@ -276,109 +105,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) { @@ -412,879 +142,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); - 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) - { - oAcroForm.dictGetVal(nIndex, &oTemp2); - if (!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* chKey = oTemp2.dictGetKey(nIndex2); - oTemp2.dictGetVal(nIndex2, &oTemp); - DictToCDictObject(&oTemp, pDR, false, chKey); - 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(m_pInternal->wsPassword, m_pInternal->wsPassword); - if (!pEncryptDict->UpdateKey(nCryptAlgorithm)) - { - pagesRefObj.free(); - RELEASEOBJECT(pXref); - RELEASEOBJECT(pDRXref); - return false; - } - } - } - - // Применение редактирования для writer - bool bRes = pDoc->EditPdf(wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); - if (bRes) - { - // Воспроизведение дерева страниц во writer - m_pInternal->GetPageTree(xref, &pagesRefObj); - m_pInternal->bEdit = true; - - if (pDR && pDRXref) - bRes = pDoc->EditResources(pDRXref, pDR); - } - 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) + if (!m_pInternal->pEditor) 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<int, int> 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 || 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 = pDoc->GetParent(pParentRef->getRefNum()); - if (pParent) - return pParent; - - 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<int, int> 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(); - 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) - { - 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(); - } - 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("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) - { - oParentRef.free(); - continue; - } - - ((PdfWriter::CWidgetAnnotation*)pAnnot)->SetParent(pParent); - PdfWriter::CArrayObject* pKids = dynamic_cast<PdfWriter::CArrayObject*>(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(); - } - 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; -} -bool CPdfFile::DeleteAnnot(int nID) -{ - // Проверка режима редактирования - 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) + if (!m_pInternal->pEditor) return false; - - XRef* xref = pPDFDocument->getXRef(); - std::pair<int, int> 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; -} -bool CPdfFile::EditWidgets(IAdvancedCommand* pCommand) -{ - CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - - PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument; - - std::vector<CWidgetsInfo::CParent*> 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; + return m_pInternal->pEditor->AddPage(nPageIndex); } HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false); - - PDFDoc* pPDFDocument = m_pInternal->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 = m_pInternal->pWriter->m_pDocument; - 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; + return _ChangePassword(wsPath, wsPassword, m_pInternal->pReader, m_pInternal->pWriter); } #endif // BUILDING_WASM_MODULE @@ -1377,7 +261,7 @@ bool CPdfFile::GetMetaData(const std::wstring& sFile, const std::wstring& sMetaN return false; } pStream += 8; - int nStreamBegin = pStream - (char*)pBuffer; + int nStreamBegin = (int)(pStream - (char*)pBuffer); pMeta += sMeta.length() + 3; char* pMetaLast = strstr(pMeta, " "); @@ -1461,70 +345,43 @@ 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(); } +bool CPdfFile::ValidMetaData() +{ + if (!m_pInternal->pReader) + return false; + return m_pInternal->pReader->ValidMetaData(); +} void CPdfFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) { if (!m_pInternal->pReader) @@ -1655,7 +512,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; @@ -1694,7 +551,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(); } @@ -1708,7 +565,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); } @@ -1722,7 +579,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); } @@ -2029,7 +886,29 @@ 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); + } + } + 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) { @@ -2141,7 +1020,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) { @@ -2265,13 +1144,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) { @@ -2297,6 +1178,10 @@ HRESULT CPdfFile::IsSupportAdvancedCommand(const IAdvancedCommand::AdvancedComma 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: return S_OK; default: break; @@ -2320,6 +1205,13 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) case IAdvancedCommand::AdvancedCommandType::Link: { CLinkCommand* pCommand = (CLinkCommand*)command; + if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + { + PdfWriter::CPage* pCurrent = m_pInternal->pWriter->GetPage(); + m_pInternal->pEditor->EditPage(pCommand->GetPage()); + m_pInternal->pWriter->GetDocument()->SetCurPage(pCurrent); + m_pInternal->pWriter->EditPage(pCurrent); + } return m_pInternal->pWriter->AddLink(pCommand->GetX(), pCommand->GetY(), pCommand->GetW(), pCommand->GetH(), pCommand->GetDestX(), pCommand->GetDestY(), pCommand->GetPage()); } @@ -2337,28 +1229,48 @@ 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 + 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; -#ifndef BUILDING_WASM_MODULE - if (m_pInternal->bEdit && EditWidgets(pCommand)) + if (m_pInternal->pEditor && m_pInternal->pEditor->EditWidgets(pCommand)) return m_pInternal->pWriter->EditWidgetParents(m_pInternal->pAppFonts, pCommand, m_pInternal->wsTempFolder); -#endif + 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; } default: diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 46c9a2aab4e..4877d8362f1 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,9 +97,6 @@ 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); - bool EditWidgets(IAdvancedCommand* pCommand); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif @@ -128,6 +125,7 @@ class PDFFILE_DECL_EXPORT CPdfFile : public IOfficeDrawingFile, public IRenderer virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + bool ValidMetaData(); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfFile.pro b/PdfFile/PdfFile.pro index e4211465d09..9de26c11ee4 100644 --- a/PdfFile/PdfFile.pro +++ b/PdfFile/PdfFile.pro @@ -205,9 +205,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 7d0c7c324a9..a0c4f7bb4f0 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -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(); @@ -107,7 +107,7 @@ CPdfReader::~CPdfReader() RELEASEINTERFACE(m_pFontManager); } -bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nDepth) +bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nDepth, std::vector<int>& arrUniqueResources) { if (nDepth > 5) return false; @@ -126,7 +126,7 @@ bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nD char* sName = oEncoding.getName(); if (std::find(arrCMap.begin(), arrCMap.end(), sName) != arrCMap.end()) { - oEncoding.free();oFonts.free(); + oEncoding.free(); oFonts.free(); return true; } oEncoding.free(); @@ -134,80 +134,109 @@ bool scanFonts(Dict *pResources, const std::vector<std::string>& arrCMap, int nD } oFonts.free(); - auto fScanFonts = [pResources, &arrCMap, &nDepth](const char* sName) + auto fScanFonts = [pResources, nDepth, &arrUniqueResources](const std::vector<std::string>& arrCMap, const char* sName) { Object oObject; - if (pResources->lookup(sName, &oObject)->isDict()) + if (!pResources->lookup(sName, &oObject)->isDict()) { - for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i) + oObject.free(); + return false; + } + for (int i = 0, nLength = oObject.dictGetLength(); i < nLength; ++i) + { + Object oXObj, oResources; + if (!oObject.dictGetVal(i, &oXObj)->isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources)->isDict()) { - Object oXObj, oResources; - if (!oObject.dictGetVal(i, &oXObj)->isStream() || !oXObj.streamGetDict()->lookup("Resources", &oResources)->isDict()) - { - oXObj.free(); oResources.free(); - continue; - } - oXObj.free(); - if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1)) - { - oResources.free(); oObject.free(); - return true; - } - oResources.free(); + oXObj.free(); oResources.free(); + continue; + } + Object oRef; + if (oXObj.streamGetDict()->lookupNF("Resources", &oRef)->isRef() && std::find(arrUniqueResources.begin(), arrUniqueResources.end(), oRef.getRef().num) != arrUniqueResources.end()) + { + 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("XObject") || fScanFonts("Pattern")) + if (fScanFonts(arrCMap, "XObject") || fScanFonts(arrCMap, "Pattern")) return true; Object oExtGState; - if (pResources->lookup("ExtGState", &oExtGState)->isDict()) + if (!pResources->lookup("ExtGState", &oExtGState)->isDict()) { - for (int i = 0, nLength = oExtGState.dictGetLength(); i < nLength; ++i) + 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()) { - 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(); oSMaskGroup.free(); - if (scanFonts(oResources.getDict(), arrCMap, nDepth + 1)) - { - oResources.free(); oExtGState.free(); - return true; - } - oResources.free(); + 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, const std::vector<std::string>& arrCMap) +bool scanAPfonts(Object* oAnnot, const std::vector<std::string>& arrCMap, std::vector<int>& arrUniqueResources) { Object oAP; - if (oAnnot->dictLookup("AP", &oAP)->isDict()) + if (!oAnnot->dictLookup("AP", &oAP)->isDict()) + { + oAP.free(); + return false; + } + auto fScanAPView = [&arrUniqueResources](Object* oAP, const std::vector<std::string>& arrCMap, const char* sName) { - auto fScanAPView = [&oAP, &arrCMap](const char* sName) + Object oAPi, oRes; + if (!oAP->dictLookup(sName, &oAPi)->isStream() || !oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict()) { - Object oAPi, oRes; - if (oAP.dictLookup(sName, &oAPi)->isStream() && oAPi.streamGetDict()->lookup("Resources", &oRes)->isDict() && scanFonts(oRes.getDict(), arrCMap, 0)) - { - oAPi.free(); oRes.free(); oAP.free(); - return true; - } oAPi.free(); oRes.free(); return false; - }; - if (fScanAPView("N") || fScanAPView("D") || fScanAPView("R")) - return true; - } + } + 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() { @@ -234,11 +263,13 @@ bool CPdfReader::IsNeedCMap() if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return false; + std::vector<int> arrUniqueResources; + for (int nPage = 1, nLastPage = m_pPDFDocument->getNumPages(); nPage <= nLastPage; ++nPage) { Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage); Dict* pResources = pPage->getResourceDict(); - if (pResources && scanFonts(pResources, arrCMap, 0)) + if (pResources && scanFonts(pResources, arrCMap, 0, arrUniqueResources)) return true; Object oAnnots; @@ -257,14 +288,14 @@ bool CPdfReader::IsNeedCMap() } Object oDR; - if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); oAnnot.free(); oAnnots.free(); return true; } oDR.free(); - if (scanAPfonts(&oAnnot, arrCMap)) + if (scanAPfonts(&oAnnot, arrCMap, arrUniqueResources)) { oAnnot.free(); oAnnots.free(); return true; @@ -279,7 +310,7 @@ bool CPdfReader::IsNeedCMap() return false; Object oDR; Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; @@ -290,7 +321,7 @@ bool CPdfReader::IsNeedCMap() { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0)) + if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; @@ -302,7 +333,7 @@ bool CPdfReader::IsNeedCMap() oWidgetRef.fetch(m_pPDFDocument->getXRef(), &oWidget); oWidgetRef.free(); - if (scanAPfonts(&oWidget, arrCMap)) + if (scanAPfonts(&oWidget, arrCMap, arrUniqueResources)) { oWidget.free(); return true; @@ -429,7 +460,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 @@ -461,6 +492,33 @@ int CPdfReader::GetMaxRefID() return 0; return m_pPDFDocument->getXRef()->getNumObjects(); } +bool CPdfReader::ValidMetaData() +{ + if (!m_pPDFDocument) + return false; + + XRef* xref = m_pPDFDocument->getXRef(); + 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 || !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) { if (m_pPDFDocument && pRenderer) @@ -469,8 +527,8 @@ void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* 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 + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); } @@ -717,11 +775,13 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, 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; @@ -864,7 +924,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) RELEASEOBJECT(pLinks); int nRotate = 0; -#if 0 //#ifdef BUILDING_WASM_MODULE +#ifdef BUILDING_WASM_MODULE nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); #endif @@ -921,15 +981,15 @@ BYTE* CPdfReader::GetWidgets() oRes.ClearWithoutAttack(); return bRes; } +std::map<std::wstring, std::wstring> CPdfReader::GetAnnotFonts(Object* pRefAnnot) +{ + return PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, pRefAnnot, m_pFontManager, m_pFontList, 3); +} BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) { if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - if (!pAcroForms || !m_pPDFDocument->getXRef()) - return NULL; - NSWasm::CData oRes; oRes.SkipLen(); @@ -937,44 +997,30 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) int nFontsPos = oRes.GetSize(); oRes.AddInt(nFontsID); - std::vector<int> arrFontsRef; - for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + if (pAcroForms) { - AcroFormField* pField = pAcroForms->getField(nField); - if (!pField) - continue; - - // Шрифт и размер шрифта - из DA - Ref fontID; - double dFontSize = 0; - bool bFullFont = true; - pField->getFont(&fontID, &dFontSize); - if (fontID.num < 0) - bFullFont = false; + std::vector<int> arrFontsRef; + for (int nField = 0, nNum = pAcroForms->getNumFields(); nField < nNum; ++nField) + { + AcroFormField* pField = pAcroForms->getField(nField); + if (!pField) + continue; - if (std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) - continue; + // Шрифт и размер шрифта - из DA + Ref fontID; + double dFontSize = 0; + bool bFullFont = true; + pField->getFont(&fontID, &dFontSize); + if (fontID.num < 0) + bFullFont = false; - Object oR, oFonts, oFontRef; - bool bFindResources = false; - if (bFullFont && pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) - { - for (int i = 0; i < oFonts.dictGetLength(); ++i) - { - if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) - { - bFindResources = true; - break; - } - oFontRef.free(); - } - } + if (std::find(arrFontsRef.begin(), arrFontsRef.end(), fontID.num) != arrFontsRef.end()) + continue; - if (bFullFont && !bFindResources) - { - oR.free(); oFonts.free(); - Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + Object oR, oFonts, oFontRef; + bool bFindResources = false; + if (bFullFont && pField->fieldLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) { for (int i = 0; i < oFonts.dictGetLength(); ++i) { @@ -986,40 +1032,141 @@ BYTE* CPdfReader::GetWidgetFonts(int nTypeFonts) oFontRef.free(); } } - } - if (!bFullFont || pField->getAcroFormFieldType() == acroFormFieldPushbutton) - { + if (bFullFont && !bFindResources) + { + oR.free(); oFonts.free(); + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->isDict() && oAcroForm->dictLookup("DR", &oR)->isDict() && oR.dictLookup("Font", &oFonts)->isDict()) + { + for (int i = 0; i < oFonts.dictGetLength(); ++i) + { + if (oFonts.dictGetValNF(i, &oFontRef)->isRef() && oFontRef.getRef() == fontID) + { + bFindResources = true; + break; + } + oFontRef.free(); + } + } + } + + if (!bFullFont) + { + oR.free(); oFonts.free(); oFontRef.free(); + std::string sFontKey; + bool bFind = PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey); + bFindResources = bFind && std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end() && (nTypeFonts & 2); + } + + std::string sFontName; + std::wstring wsFileName; + if (bFindResources) + { + bool bBold = false, bItalic = false; + wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + } + + if (!sFontName.empty()) + { + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (m_mFonts.find(wsFontName) == m_mFonts.end()) + { + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[wsFontName] = wsFileName; + } + } oR.free(); oFonts.free(); oFontRef.free(); - std::string sFontKey; - bool bFind = PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey); - if (bFind && std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end() && - (pField->getAcroFormFieldType() == acroFormFieldPushbutton || (nTypeFonts & 2))) + + if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) { - bFindResources = true; + std::string sFontKey; + bool bFind = PdfReader::GetFontFromAP(m_pPDFDocument, pField, &oR, &oFonts, &oFontRef, sFontKey); + if (bFind && std::find(arrFontsRef.begin(), arrFontsRef.end(), oFontRef.getRefNum()) == arrFontsRef.end()) + { + bool bBold = false, bItalic = false; + wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + + std::wstring wsFontName = UTF8_TO_U(sFontName); + if (m_mFonts.find(wsFontName) == m_mFonts.end()) + { + oRes.WriteString(sFontName); + nFontsID++; + arrFontsRef.push_back(oFontRef.getRefNum()); + m_mFonts[wsFontName] = wsFileName; + } + } } + oR.free(); oFonts.free(); oFontRef.free(); } + } + + for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) + { + Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage + 1); + if (!pPage) + continue; - std::string sFontName; - std::wstring wsFileName; - if (bFindResources) + Object oAnnots; + if (!pPage->getAnnots(&oAnnots)->isArray()) { - bool bBold = false, bItalic = false; - wsFileName = PdfReader::GetFontData(m_pPDFDocument, m_pFontManager, m_pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sFontName, bBold, bItalic); + oAnnots.free(); + continue; } - if (!sFontName.empty()) + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { - std::wstring wsFontName = UTF8_TO_U(sFontName); - if (m_mFonts.find(wsFontName) == m_mFonts.end()) + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + oAnnot.free(); + continue; + } + + Object oSubtype; + std::string sType; + if (oAnnot.dictLookup("Subtype", &oSubtype)->isName()) + sType = oSubtype.getName(); + oSubtype.free(); + + if (sType != "FreeText") + { + oAnnot.free(); + continue; + } + + Object oObj; + if (!oAnnot.dictLookup("RC", &oObj)->isString()) { - oRes.WriteString(sFontName); + oAnnot.free(); oObj.free(); + continue; + } + + 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<PdfReader::CAnnotMarkup::CFontData*> arrRC = PdfReader::AnnotMarkup::ReadRC(sRC); + std::map<std::wstring, std::wstring> mFreeText = PdfReader::AnnotMarkup::SetFont(m_pPDFDocument, &oAnnotRef, m_pFontManager, m_pFontList, arrRC, nTypeFonts); + for (std::map<std::wstring, std::wstring>::iterator it = mFreeText.begin(); it != mFreeText.end(); ++it) + { + if (m_mFonts.find(it->first) != m_mFonts.end()) + continue; + + oRes.WriteString(U_TO_UTF8(it->first)); nFontsID++; - arrFontsRef.push_back(oFontRef.getRefNum()); - m_mFonts[wsFontName] = wsFileName; + m_mFonts[it->first] = it->second; } + oAnnotRef.free(); + for (int j = 0; j < arrRC.size(); ++j) + RELEASEOBJECT(arrRC[j]); } - oR.free(); oFonts.free(); oFontRef.free(); + oAnnots.free(); } oRes.AddInt(nFontsID, nFontsPos); @@ -1419,7 +1566,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase 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, std::map<std::wstring, std::wstring>& m_mFonts, int nPageIndex) { Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); if (!pPage) @@ -1460,7 +1607,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") { @@ -1520,10 +1669,68 @@ BYTE* CPdfReader::GetAnnots(int nPageIndex) oRes.SkipLen(); if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, oRes, nPageIndex); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, m_mFonts, nPageIndex); else for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(m_pPDFDocument, oRes, nPage); + GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, m_mFonts, 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 || !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()) + { + 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(); diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 03a22536d08..3cf92ad79e2 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -61,6 +61,7 @@ class CPdfReader 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(); @@ -76,16 +77,18 @@ class CPdfReader BYTE* GetWidgets(); BYTE* GetWidgetFonts(int nTypeFonts); 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* 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<std::wstring, std::wstring> GetAnnotFonts(Object* pRefAnnot); private: PDFDoc* m_pPDFDocument; std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; - PdfReader::CFontList* m_pFontList; + PdfReader::CPdfFontList* m_pFontList; DWORD m_nFileLength; int m_eError; std::map<std::wstring, std::wstring> m_mFonts; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5ff8a24dc33..52bc1d4bf4a 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,20 +40,22 @@ #include "SrcWriter/Font.h" #include "SrcWriter/FontCidTT.h" #include "SrcWriter/FontTT.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 "../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 "../../UnicodeConverter/UnicodeConverter.h" -#include "../../Common/Network/FileTransporter/include/FileTransporter.h" +#include "../UnicodeConverter/UnicodeConverter.h" +#include "../Common/Network/FileTransporter/include/FileTransporter.h" #if defined(GetTempPath) #undef GetTempPath @@ -166,13 +168,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() { @@ -412,7 +412,6 @@ HRESULT CPdfWriter::put_BrushColor1(const LONG& lColor) if (lColor != m_oBrush.GetColor1()) { m_oBrush.SetColor1(lColor); - m_bNeedUpdateTextColor = true; } return S_OK; } @@ -426,7 +425,6 @@ HRESULT CPdfWriter::put_BrushAlpha1(const LONG& lAlpha) if (lAlpha != m_oBrush.GetAlpha1()) { m_oBrush.SetAlpha1(lAlpha); - m_bNeedUpdateTextAlpha = true; } return S_OK; } @@ -565,7 +563,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; } @@ -603,7 +600,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; } @@ -753,7 +749,7 @@ HRESULT CPdfWriter::CommandDrawTextCHAR2(unsigned int* pUnicodes, const unsigned //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- -HRESULT CPdfWriter::EndCommand(const DWORD& dwType, const LONG& lClipMode) +HRESULT CPdfWriter::EndCommand(const DWORD& dwType) { if (!IsPageValid()) return S_FALSE; @@ -766,7 +762,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) { @@ -1027,6 +1023,16 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con if (!IsPageValid()) return S_OK; + if (m_pDocument->HasImage(wsImagePathSrc, nAlpha)) + { + 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; + } + std::wstring sTempImagePath = GetDownloadFile(wsImagePathSrc, wsTempDirectory); std::wstring wsImagePath = sTempImagePath.empty() ? wsImagePathSrc : sTempImagePath; @@ -1057,8 +1063,10 @@ HRESULT CPdfWriter::DrawImageFromFile(NSFonts::IApplicationFonts* pAppFonts, con } 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); @@ -1093,6 +1101,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; +} //---------------------------------------------------------------------------------------- // Дополнительные функции //---------------------------------------------------------------------------------------- @@ -1200,11 +1218,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie PdfWriter::CPictureField* pField = m_pDocument->CreatePictureField(); pFieldBase = static_cast<PdfWriter::CFieldBase*>(pField); } - else if (oInfo.IsSignature()) - { - PdfWriter::CSignatureField* pField = m_pDocument->CreateSignatureField(); - pFieldBase = static_cast<PdfWriter::CFieldBase*>(pField); - } else if (oInfo.IsDateTime()) { PdfWriter::CDateTimeField* pField = m_pDocument->CreateDateTimeField(); @@ -1575,33 +1588,6 @@ HRESULT CPdfWriter::AddFormField(NSFonts::IApplicationFonts* pAppFonts, CFormFie pField->SetAppearance(pImage); } - else if (oInfo.IsSignature()) - { - const CFormFieldInfo::CSignatureFormPr* pPr = oInfo.GetSignaturePr(); - - PdfWriter::CSignatureField* pField = dynamic_cast<PdfWriter::CSignatureField*>(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(); @@ -1663,6 +1649,49 @@ 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) { if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) @@ -1832,10 +1861,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"<?xml version=\"1.0\"?><body xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\" xfa:APIVersion=\"Acrobat:23.8.0\" xfa:spec=\"2.0.2\"><p dir=\"ltr\">"; + std::vector<CAnnotFieldInfo::CMarkupAnnotPr::CFontData*> 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"<span style=\""; + GetRCSpanStyle(arrRC[i], oRC); + oRC += L"\">"; + oRC.WriteEncodeXmlString(arrRC[i]->sText); + oRC += L"</span>"; + } + oRC += L"</p></body>"; + pMarkupAnnot->SetRC(oRC.GetData()); + // std::wcout << oRC.GetData() << std::endl; } if (nFlags & (1 << 4)) pMarkupAnnot->SetCD(pPr->GetCD()); @@ -1871,6 +1935,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pTextAnnot->SetStateModel(pPr->GetStateModel()); if (nFlags & (1 << 18)) pTextAnnot->SetState(pPr->GetState()); + + pTextAnnot->SetAP(); } else if (oInfo.IsInk()) { @@ -1959,24 +2025,54 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } else if (oInfo.IsFreeText()) { - CAnnotFieldInfo::CFreeTextAnnotPr* pPr = oInfo.GetFreeTextAnnotPr(); + CAnnotFieldInfo::CFreeTextAnnotPr* pFTPr = oInfo.GetFreeTextAnnotPr(); PdfWriter::CFreeTextAnnotation* pFreeTextAnnot = (PdfWriter::CFreeTextAnnotation*)pAnnot; - pFreeTextAnnot->SetQ(pPr->GetQ()); + pFreeTextAnnot->SetQ(pFTPr->GetQ()); + pFreeTextAnnot->SetRotate(pFTPr->GetRotate()); if (nFlags & (1 << 15)) { double dRD1, dRD2, dRD3, dRD4; - pPr->GetRD(dRD1, dRD2, dRD3, dRD4); + pFTPr->GetRD(dRD1, dRD2, dRD3, dRD4); pFreeTextAnnot->SetRD(dRD1, dRD2, dRD3, dRD4); } if (nFlags & (1 << 16)) - pFreeTextAnnot->SetCL(pPr->GetCL()); - if (nFlags & (1 << 17)) - pFreeTextAnnot->SetDS(pPr->GetDS()); + pFreeTextAnnot->SetCL(pFTPr->GetCL()); + + std::wstring sDS = pFTPr->GetDS(); + if (sDS.empty()) + sDS = sDefaultStyle; + pFreeTextAnnot->SetDS(sDS); + if (nFlags & (1 << 18)) - pFreeTextAnnot->SetLE(pPr->GetLE()); + pFreeTextAnnot->SetLE(pFTPr->GetLE()); if (nFlags & (1 << 20)) - pFreeTextAnnot->SetIT(pPr->GetIT()); + pFreeTextAnnot->SetIT(pFTPr->GetIT()); + if (nFlags & (1 << 21)) + pFreeTextAnnot->SetIC(pFTPr->GetIC()); + if (nFlags & (1 << 22)) + { + PdfWriter::CPage* pCurPage = m_pPage; + PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + m_pPage = pFakePage; + m_pDocument->SetCurPage(pFakePage); + + LONG nLen = 0; + BYTE* pRender = pFTPr->GetRender(nLen); + IMetafileToRenderter* pCorrector = new IMetafileToRenderter(m_pRenderer); + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pRender, nLen, pCorrector); + RELEASEOBJECT(pCorrector); + + pFreeTextAnnot->APFromFakePage(pFakePage); + + m_pPage = pCurPage; + m_pDocument->SetCurPage(pCurPage); + RELEASEOBJECT(pFakePage); + } + PdfWriter::CFontDict* pFont = m_pFont; + if (m_pFont14) + pFont = m_pFont14; + pFreeTextAnnot->SetDA(pFont, m_oFont.GetSize(), oInfo.GetC()); } else if (oInfo.IsCaret()) { @@ -2593,6 +2689,14 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi 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()) @@ -2666,7 +2770,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()); @@ -2761,18 +2865,18 @@ 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) { @@ -2783,7 +2887,10 @@ 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()); @@ -2817,24 +2924,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") + 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); @@ -2851,9 +3014,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); @@ -2861,10 +3031,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) { @@ -3041,12 +3215,19 @@ 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) + if (m_pDocument->HasImage(wsTexturePath, nAlpha)) + { + pImage = m_pDocument->GetImage(wsTexturePath, nAlpha); + nImageH = pImage->GetHeight(); + nImageW = pImage->GetWidth(); + } + else if (_CXIMAGE_FORMAT_JPG == oImageFormat.eFileType || _CXIMAGE_FORMAT_JP2 == oImageFormat.eFileType) { pImage = m_pDocument->CreateImage(); CBgraFrame oFrame; @@ -3060,6 +3241,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 || @@ -3103,6 +3286,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 { @@ -3110,11 +3294,11 @@ 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) pImage->AddTransparency(nAlpha); @@ -3154,6 +3338,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; } // Нам нужно, чтобы левый нижний угол границ нашего пата являлся точкой переноса для матрицы преобразования. @@ -3279,6 +3465,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; @@ -3308,6 +3518,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; diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index ab64292c354..1f1eec9426a 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -32,20 +32,17 @@ #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 <string> #include <vector> #include <math.h> -#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/AnnotField.h" -#include "SrcWriter/Metadata.h" +#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" +#include "SrcWriter/States.h" #include "SrcWriter/Annotation.h" namespace PdfWriter @@ -160,7 +157,7 @@ class CPdfWriter //---------------------------------------------------------------------------------------- // Маркеры команд //---------------------------------------------------------------------------------------- - HRESULT EndCommand(const DWORD& lType, const LONG& lClipMode); + HRESULT EndCommand(const DWORD& lType); //---------------------------------------------------------------------------------------- // Функции для работы с патом //---------------------------------------------------------------------------------------- @@ -198,6 +195,8 @@ class CPdfWriter 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 рендерера //---------------------------------------------------------------------------------------- @@ -206,7 +205,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 //---------------------------------------------------------------------------------------- @@ -216,17 +214,20 @@ class CPdfWriter void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); - - PdfWriter::CDocument* m_pDocument; - PdfWriter::CPage* m_pPage; + 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); 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); + 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); 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); @@ -243,34 +244,31 @@ 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); - void DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); + void DrawTextWidget (NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CTextWidget* pTextWidget, const std::wstring& wsValue); void DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter::CChoiceWidget* pChoiceWidget, const std::vector<std::wstring>& 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<TFontInfo> m_vFonts; std::vector<TDestinationInfo>m_vDestinations; unsigned int m_unFieldsCounter; diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9b1ebff9f08..02c1621bb53 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -43,6 +43,11 @@ #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 <map> namespace PdfReader { @@ -448,6 +453,13 @@ GList* tokenize(GString *s) } return toks; } +bool 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"; +} //------------------------------------------------------------------------ // Widget @@ -552,14 +564,11 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot // 3 - Смещение - A if (oIF.dictLookup("A", &oObj)->isArray()) { + m_dA1 = 0.5, m_dA2 = 0.5; Object oObj2; m_unIFFlag |= (1 << 3); m_dA1 = ArrGetNum(&oObj, 0); - if (!m_dA1) - m_dA1 = 0.5; m_dA2 = ArrGetNum(&oObj, 1); - if (!m_dA2) - m_dA2 = 0.5; } oObj.free(); // 4 - Полное соответствие - FB @@ -1049,7 +1058,7 @@ bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oR, Object* oF return bFindResources; } -std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic) +std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic) { XRef* xref = pdfDoc->getXRef(); @@ -1066,12 +1075,10 @@ std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CF } Ref oEmbRef; - const unsigned char* pData14 = NULL; - unsigned int nSize14 = 0; std::wstring wsFontBaseName = NSStrings::GetStringFromUTF32(gfxFont->getName()); std::wstring wsFileName; - if (((nTypeFonts & 1) && gfxFont->getEmbeddedFontID(&oEmbRef)) || ((nTypeFonts & 2) && GetBaseFont(wsFontBaseName, pData14, nSize14))) + if (((nTypeFonts & 1) && gfxFont->getEmbeddedFontID(&oEmbRef)) || ((nTypeFonts & 2) && isBaseFont(wsFontBaseName))) { std::wstring wsFontName; GetFont(xref, pFontManager, pFontList, gfxFont, wsFileName, wsFontName); @@ -1132,7 +1139,7 @@ std::string CAnnotWidget::FieldLookupString(AcroFormField* pField, const char* s oObj.free(); return sRes; } -void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { // Шрифт и размер шрифта - из DA Ref fontID; @@ -1200,7 +1207,7 @@ void CAnnotWidget::SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFont if (bItalic) m_unFontStyle |= (1 << 1); } -void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { // Неполноценный шрифт во внешнем виде pushbutton Object oR, oFonts, oFontRef; @@ -1250,7 +1257,7 @@ 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(); @@ -1262,12 +1269,12 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMar oObj.free(); // 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<std::string> 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<std::string>::iterator p = std::find(arrName.begin(), arrName.end(), sName); if (p != arrName.end()) m_nName = p - arrName.begin(); @@ -1316,7 +1323,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(); @@ -1352,7 +1359,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(); @@ -1460,7 +1467,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(); @@ -1500,7 +1507,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(); @@ -1547,7 +1554,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(); @@ -1623,7 +1630,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(); @@ -1635,6 +1642,11 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex m_nQ = oObj.getInt(); oObj.free(); + m_nRotate = 0; + if (oAnnot.dictLookup("Rotate", &oObj)->isInt()) + m_nRotate = oObj.getInt(); + oObj.free(); + // 15 - Различия Rect и фактического размера - RD if (oAnnot.dictLookup("RD", &oObj)->isArray()) { @@ -1731,7 +1743,7 @@ 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(); @@ -1767,7 +1779,7 @@ CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CM // FileAttachment //------------------------------------------------------------------------ -CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CMarkupAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) { m_pEF = NULL; @@ -1892,7 +1904,7 @@ CAnnotFileAttachment::~CAnnotFileAttachment() // Annots //------------------------------------------------------------------------ -CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList) +CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -2093,7 +2105,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) // 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; @@ -2120,9 +2132,15 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : oObj.free(); // 3 - Форматированный текст - RC - m_sRC = DictLookupString(&oAnnot, "RC", 3); + std::string sRC = DictLookupString(&oAnnot, "RC", 3); + // std::cout << sRC << std::endl; // if (oAnnot.dictLookup("RC", &oObj)->isStream()) // TODO streamGetBlock + m_arrRC = AnnotMarkup::ReadRC(sRC); + if (m_arrRC.empty()) + m_unFlags &= ~(1 << 3); + else + m_unFlags |= (1 << 3); // 4 - Дата создания - CreationDate m_sCreationDate = DictLookupString(&oAnnot, "CreationDate", 4); @@ -2150,6 +2168,414 @@ CMarkupAnnot::CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : 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::CFontData*> AnnotMarkup::ReadRC(const std::string& sRC) +{ + std::vector<CAnnotMarkup::CFontData*> 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) +{ + AnnotMarkup::SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, m_arrRC); +} +bool 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; + } + } + } + oXObject.free(); + return false; +} +std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts) +{ + Object oAnnot, oObj; + XRef* pXref = pdfDoc->getXRef(); + oAnnotRef->fetch(pXref, &oAnnot); + std::map<std::wstring, std::wstring> arrFontFreeText; + + Object oAP, oN, oR, oFonts; + if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oN)->isStream()) + { + oAP.free(); oN.free(); oR.free(); oFonts.free(); + return arrFontFreeText; + } + + if (!FindFonts(&oN, 0, &oFonts)) + { + oAP.free(); oN.free(); oR.free(); oFonts.free(); + return arrFontFreeText; + } + + 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, sActual; + bool bBold = false, bItalic = false; + std::wstring sFontPath = GetFontData(pdfDoc, pFontManager, pFontList, &oFonts, &oFontRef, nTypeFonts, sFontName, sActual, bBold, bItalic); + std::wstring wsFontName = UTF8_TO_U(sFontName); + oFontRef.free(); + if (sFontPath.empty()) + continue; + + if (isBaseFont(sFontPath)) + continue; + + NSFonts::IFontStream* pFontStream = pMemoryStorage ? (NSFonts::IFontStream*)pMemoryStorage->Get(sFontPath) : NULL; + if (pFontStream) + { + bool bNew = true; + std::vector<NSFonts::CFontInfo*>* 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); + } + arrFontFreeText[wsFontName] = sFontPath; + } + + oAP.free(); oN.free(); oR.free(); oFonts.free(); + + oAnnot.free(); + return arrFontFreeText; +} +std::map<std::wstring, std::wstring> AnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, std::vector<CAnnotMarkup::CFontData*>& arrRC, int nTypeFonts) +{ + std::map<std::wstring, std::wstring> mRes; + + std::map<std::wstring, std::wstring> arrFontFreeText = SetFont(pdfDoc, oAnnotRef, pFontManager, pFontList, nTypeFonts); + + 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); + bool bBase = isBaseFont(wsFontName) || sFontName == "Times New Roman"; + if ((nTypeFonts & 2) && bBase) + { + if (sFontName == "Times New Roman") + { + if (bBold && bItalic) + sFontName = "Times-BoldItalic"; + else if (bBold) + sFontName = "Times-Bold"; + else if (bItalic) + sFontName = "Times-Italic"; + else + sFontName = "Times-Roman"; + } + 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; + if (!NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->Get(wsFontName) && GetBaseFont(wsFontName, pData14, nSize14)) + NSFonts::NSApplicationFontStream::GetGlobalMemoryStorage()->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; + } + } + } + if ((nTypeFonts & 1) && !bBase) + { + 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 bFreeText = false; + for (std::map<std::wstring, std::wstring>::iterator it = arrFontFreeText.begin(); it != arrFontFreeText.end(); it++) + { + if (it->second == sFontPath) + { + bFreeText = 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 (bFreeText) + { + 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 = bFreeText ? 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 (bFreeText) + arrRC[j]->sFontFamily = sFontNameNew; + else + { + arrRC[j]->unFontFlags |= (1 << 6); + arrRC[j]->sActualFont = sFontNameNew; + } + arrRC[j]->bFind = true; + } + } + } + } + } + + return mRes; +} +CAnnotMarkup::CFontData::CFontData(const CFontData& oFont) +{ + bFind = oFont.bFind; + nAlign = oFont.nAlign; + unFontFlags = oFont.unFontFlags; + dFontSise = oFont.dFontSise; + dVAlign = oFont.dVAlign; + dColor[0] = oFont.dColor[0]; + dColor[1] = oFont.dColor[1]; + dColor[2] = oFont.dColor[2]; + sFontFamily = oFont.sFontFamily; + sActualFont = oFont.sActualFont; + sText = oFont.sText; +} //------------------------------------------------------------------------ // Annot @@ -2470,7 +2896,7 @@ CAnnot::CBorderType* CAnnot::getBorder(Object* oBorder, bool bBSorBorder) // 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; @@ -2488,7 +2914,7 @@ 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; @@ -2526,9 +2952,12 @@ 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); @@ -2565,6 +2994,7 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontLi m_pRenderer->put_Height((m_dy2 - m_dy1 + (2 + m_dHTale) * dHeight / (double)nRasterH) * 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()); @@ -2579,8 +3009,8 @@ 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_nRx1 = (int)round((m_dx1 - m_dCropX) * m_dWScale) - 1; + m_nRy1 = nRasterH - (int)round((m_dy2 - m_dCropY) * m_dHScale) - 1; } void CAnnotAP::Init(AcroFormField* pField) { @@ -2644,7 +3074,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo 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); + m_pRenderer->SetCoordTransformOffset(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], pView->sASName.c_str()); WriteAppearance(nBackgroundColor, pView); pView->nBlendMode = GetBlendMode(); @@ -2655,7 +3085,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo { 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(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); DrawAppearance(pdfDoc, nPageIndex + 1, pField, m_gfx, arrAPName[j], NULL); WriteAppearance(nBackgroundColor, pView); pView->nBlendMode = GetBlendMode(); @@ -2686,7 +3116,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo 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(-(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2, (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2); Ref ref = oAnnotRef->getRef(); Annot* annot = new Annot(pdfDoc, oAnnot.getDict(), &ref, arrAPName[j]); @@ -3074,7 +3504,7 @@ void CAnnotWidgetSig::ToWASM(NSWasm::CData& oRes) { CAnnotWidget::ToWASM(oRes); } -void CMarkupAnnot::ToWASM(NSWasm::CData& oRes) +void CAnnotMarkup::ToWASM(NSWasm::CData& oRes) { CAnnot::ToWASM(oRes); @@ -3086,7 +3516,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)) @@ -3100,7 +3547,7 @@ 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); @@ -3123,7 +3570,7 @@ 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) @@ -3137,7 +3584,7 @@ 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]); @@ -3173,7 +3620,7 @@ 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) @@ -3183,7 +3630,7 @@ void CAnnotSquareCircle::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(m_nSubtype); // Square, Circle - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -3201,7 +3648,7 @@ 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) @@ -3225,9 +3672,10 @@ 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) @@ -3256,7 +3704,7 @@ void CAnnotCaret::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(13); // Caret - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) { @@ -3270,7 +3718,7 @@ void CAnnotFileAttachment::ToWASM(NSWasm::CData& oRes) { oRes.WriteBYTE(16); // FileAttachment - CMarkupAnnot::ToWASM(oRes); + CAnnotMarkup::ToWASM(oRes); if (m_unFlags & (1 << 15)) oRes.WriteString(m_sName); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 4d053291696..7e7012995d5 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); @@ -134,7 +134,7 @@ class CAnnotAP final void WriteAppearance(unsigned int nColor, CAnnotAPView* pView); BYTE GetBlendMode(); - void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); + 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); @@ -143,6 +143,7 @@ class CAnnotAP final 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; @@ -210,15 +211,15 @@ class CAnnot //------------------------------------------------------------------------ bool GetFontFromAP(PDFDoc* pdfDoc, AcroFormField* pField, Object* oR, Object* oFonts, Object* oFontRef, std::string& sFontKey); -std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic); +std::wstring GetFontData(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, Object* oFonts, Object* oFontRef, int nTypeFonts, std::string& sFontName, std::string& sActualFontName, bool& bBold, bool& bItalic); class CAnnotWidget : public CAnnot { public: virtual ~CAnnotWidget(); - void SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList); - void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CFontList *pFontList); + 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); @@ -321,13 +322,33 @@ 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); + }; + + void SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + protected: - CMarkupAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + virtual ~CAnnotMarkup(); virtual void ToWASM(NSWasm::CData& oRes) override; @@ -337,16 +358,22 @@ 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; // Краткое описание + std::vector<CFontData*> m_arrRC; // Форматированный текст }; +namespace AnnotMarkup +{ +std::map<std::wstring, std::wstring> SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nTypeFonts = 3); +std::map<std::wstring, std::wstring> SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, std::vector<CAnnotMarkup::CFontData*>& arrRC, int nTypeFonts = 3); +std::vector<CAnnotMarkup::CFontData*> ReadRC(const std::string& sRC); +} //------------------------------------------------------------------------ // PdfReader::CAnnotText //------------------------------------------------------------------------ -class CAnnotText final : public CMarkupAnnot +class CAnnotText final : public CAnnotMarkup { public: CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -362,7 +389,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); @@ -377,7 +404,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); @@ -401,7 +428,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); @@ -417,7 +444,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); @@ -434,7 +461,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); @@ -454,7 +481,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); @@ -465,6 +492,7 @@ 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<double> m_arrCFromDA; // Цвет границы @@ -475,7 +503,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); @@ -491,7 +519,7 @@ class CAnnotCaret final : public CMarkupAnnot // PdfReader::CAnnotFileAttachment //------------------------------------------------------------------------ -class CAnnotFileAttachment final : public CMarkupAnnot +class CAnnotFileAttachment final : public CAnnotMarkup { public: CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); @@ -550,7 +578,7 @@ class CAnnotFileAttachment final : public CMarkupAnnot class CAnnots { public: - CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CFontList *pFontList); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index e9943ad7bd8..c8ce8b5732b 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -41,6 +41,7 @@ #include "../lib/xpdf/CMap.h" #include "../lib/xpdf/Dict.h" #include "../lib/xpdf/Stream.h" +#include "../lib/xpdf/PDFDoc.h" //#include "FontFileTrueType.h" //#include "FontFileType1C.h" #include "../lib/xpdf/CharCodeToUnicode.h" @@ -53,6 +54,7 @@ #include "../../DesktopEditor/common/Path.h" #include "../../DesktopEditor/common/Array.h" #include "../../DesktopEditor/graphics/BaseThread.h" +#include "../../DesktopEditor/graphics/commands/DocInfo.h" #include "../Resources/BaseFonts.h" #include <new> @@ -264,17 +266,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) + void CPdfFontList::LoadFromFile(std::wstring wsDirPath) { return; //Clear(); @@ -365,7 +367,7 @@ namespace PdfReader // } //} } - void CFontList::SaveToFile(std::wstring wsDirPath) + void CPdfFontList::SaveToFile(std::wstring wsDirPath) { return; //CStringW wsFilePath = wsDirPath + CStringW( _T("/FontList.rsc") ); @@ -422,7 +424,7 @@ namespace PdfReader //oWriter.SaveToFile( wsFilePath ); } - bool CFontList::Find(Ref oRef, TFontEntry *pEntry) + bool CPdfFontList::Find(Ref oRef, TFontEntry *pEntry) { CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -439,7 +441,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); @@ -462,7 +464,7 @@ 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, std::wstring wsFileName, int *pCodeToGID, int *pCodeToUnicode, unsigned int unLenGID, unsigned int unLenUnicode) { // Данная функция приходит только из Find2, поэтому проверять есть ли данный шрифт уже не надо CTemporaryCS* pCS = new CTemporaryCS(&m_oCS); @@ -482,7 +484,7 @@ 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) @@ -497,7 +499,7 @@ namespace PdfReader m_oFontMap.erase(oPos); } } - void CFontList::Clear() + void CPdfFontList::Clear() { for (auto const &oIt : m_oFontMap) { @@ -511,7 +513,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) @@ -523,7 +525,7 @@ namespace PdfReader //-------------------------------------------------------------------------------------- // 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; @@ -654,6 +656,9 @@ namespace PdfReader } void RendererOutputDev::startPage(int nPageIndex, GfxState *pGState) { + if (nPageIndex < 0) + return; + m_pRenderer->BeginCommand(c_nPageType); // Переводим пункты в миллиметры @@ -667,7 +672,7 @@ namespace PdfReader 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 @@ -1003,7 +1008,7 @@ namespace PdfReader pFontInfo = pFontManager->GetFontInfoByParams(oFontSelect); return pFontInfo; } - void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName) + void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName) { wsFileName = L""; wsFontName = L""; @@ -1125,15 +1130,13 @@ namespace PdfReader 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 @@ -1146,28 +1149,19 @@ namespace PdfReader 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(); } } @@ -1183,11 +1177,6 @@ namespace PdfReader 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(); @@ -1213,16 +1202,6 @@ namespace PdfReader 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(); @@ -1232,8 +1211,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); @@ -1249,38 +1228,24 @@ namespace PdfReader int nFirstChar = 0; Object oDictItem; - pFontDict->lookup("FirstChar", &oDictItem); - if (oDictItem.isInt()) nFirstChar = oDictItem.getInt(); - oDictItem.free(); - - int nLastChar = nFirstChar; - pFontDict->lookup("LastChar", &oDictItem); - if (oDictItem.isInt()) nLastChar = oDictItem.getInt(); + if (oFontObject.dictLookup("FirstChar", &oDictItem)->isInt()) nFirstChar = 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) + 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(); - - 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); @@ -1289,6 +1254,7 @@ namespace PdfReader } oDictItem.free(); } + oFontObject.free(); } fclose(pFile); } @@ -1608,7 +1574,7 @@ namespace PdfReader nLen = 0; } } - else if (L"" != wsFileName && (pFont8bit = dynamic_cast<Gfx8BitFont*>(pFont)) && pFont8bit->getHasEncoding()) + else if (L"" != wsFileName && (pFont8bit = dynamic_cast<Gfx8BitFont*>(pFont))) { char **ppEncoding = pFont8bit->getEncoding(); if (!ppEncoding) @@ -3055,25 +3021,28 @@ namespace PdfReader if (m_bTransparentGroupSoftMask || (!m_arrTransparentGroupSoftMask.empty() && m_bTransparentGroupSoftMaskEnd)) 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()); + if (nX1 - nX0 == 1 && nY1 - nY0 == 1) // Одно изображение, tilingPattern не требуется + { + gfx->drawForm(pStream, pResourcesDict, matrix, pBBox); + return; + } - // Image - long brush; - int alpha = pGState->getFillOpacity() * 255; + if (abs(pBBox[2] - pBBox[0] - dXStep) > 0.001 || abs(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); @@ -3082,16 +3051,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]; @@ -3099,43 +3067,56 @@ 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; + Transform(matrix, pBBox[0], pBBox[1], &xMin, &yMin); + Transform(matrix, pBBox[2], pBBox[3], &xMax, &yMax); + double dW = xMax - xMin; + double dH = yMax - yMin; + xMin += (double)nX0 * dW; + xMax += (double)nX1 * dW; + yMin += (double)nY0 * dH; + yMax += (double)nY1 * dH; + 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<NSGraphics::IGraphicsRenderer*>(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) @@ -3922,7 +3903,7 @@ namespace PdfReader int nRenderMode = pGState->getRender(); - if (3 == nRenderMode) // Невидимый текст + if (3 == nRenderMode && !m_bDrawOnlyText) // Невидимый текст { return; } @@ -3945,8 +3926,8 @@ namespace PdfReader 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 { @@ -4033,10 +4014,11 @@ namespace PdfReader } } - if (nRenderMode == 0 || nRenderMode == 4 || nRenderMode == 6 || (m_bDrawOnlyText && nRenderMode == 2)) + 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()) { @@ -4079,16 +4061,49 @@ namespace PdfReader return; } m_pRenderer->put_FontPath(wsFileName); - sFontPath = wsFileName; + bReplace = true; } } } } #endif m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); + if (bReplace) + m_pRenderer->put_FontPath(sFontPath); } - if (nRenderMode == 1 || nRenderMode == 2 || nRenderMode == 5 || nRenderMode == 6) + 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) + { + lNewStyle |= 0x01; + m_pRenderer->put_FontStyle(lNewStyle); + } + + 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); @@ -4141,6 +4156,65 @@ namespace PdfReader { return; } + GBool RendererOutputDev::beginMarkedContent(GfxState *state, GString* s) + { + return gFalse; + } + GBool RendererOutputDev::beginMCOShapes(GfxState *state, GString *s, Object *ref) + { + IAdvancedCommand::AdvancedCommandType eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; + if (m_pRenderer->IsSupportAdvancedCommand(eAdvancedCommandType) == S_OK) + { + CShapeStart* pCommand = new CShapeStart(); + pCommand->SetShapeXML(s->getCString()); + + 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) + { + CEmptyComand* pCommand = new CEmptyComand(IAdvancedCommand::AdvancedCommandType::ShapeEnd); + m_pRenderer->AdvancedCommand(pCommand); + RELEASEOBJECT(pCommand); + } + } void RendererOutputDev::drawImageMask(GfxState *pGState, Object *pRef, Stream *pStream, int nWidth, int nHeight,GBool bInvert, GBool bInlineImage, GBool interpolate) { if (m_bDrawOnlyText) @@ -4857,8 +4931,14 @@ namespace PdfReader } 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]; + Distance(pMatrix, dUserX, dUserY, pdDeviceX, pdDeviceY); + *pdDeviceX += pMatrix[4]; + *pdDeviceY += pMatrix[5]; + } + void RendererOutputDev::Distance(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY) + { + *pdDeviceX = dUserX * pMatrix[0] + dUserY * pMatrix[2]; + *pdDeviceY = dUserX * pMatrix[1] + dUserY * pMatrix[3]; } void RendererOutputDev::DoPath(GfxState *pGState, GfxPath *pPath, double dPageHeight, double *pCTM, GfxClipMatrix* pCTM2) { diff --git a/PdfFile/SrcReader/RendererOutputDev.h b/PdfFile/SrcReader/RendererOutputDev.h index 263a1aaa0de..8877ab35d24 100644 --- a/PdfFile/SrcReader/RendererOutputDev.h +++ b/PdfFile/SrcReader/RendererOutputDev.h @@ -65,12 +65,12 @@ namespace PdfReader }; - class CFontList + class CPdfFontList { public: - CFontList(); - ~CFontList(); + CPdfFontList(); + ~CPdfFontList(); void LoadFromFile(std::wstring wsDirPath); void SaveToFile(std::wstring wsDirPath); bool Find(Ref oRef, TFontEntry *pEntry); @@ -103,7 +103,7 @@ namespace PdfReader }; NSFonts::CFontInfo* GetFontByParams(XRef* pXref, NSFonts::IFontManager* pFontManager, GfxFont* pFont, std::wstring& wsFontBaseName); - void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); + void GetFont(XRef* pXref, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, GfxFont* pFont, std::wstring& wsFileName, std::wstring& wsFontName); void CheckFontStylePDF(std::wstring& sName, bool& bBold, bool& bItalic); //------------------------------------------------------------------------------------------------------------------------------- template <typename T> @@ -123,7 +123,7 @@ 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() @@ -136,11 +136,7 @@ namespace PdfReader } virtual GBool useTilingPatternFill() { - // TODO Доделать поддержку различных параметров TilingPattern - if (m_bDrawOnlyText) - return true; - - return false; + return true; } virtual GBool useFunctionalShadedFills() { @@ -262,6 +258,10 @@ namespace PdfReader 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 GBool beginMarkedContent(GfxState *state, GString *s) override; + virtual GBool beginMCOShapes(GfxState *state, GString *s, Object *ref) override; + virtual void endMarkedContent(GfxState *state) override; //----- Вывод картинок 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; @@ -299,6 +299,7 @@ namespace PdfReader private: void Transform(double *pMatrix, double dUserX, double dUserY, double *pdDeviceX, double *pdDeviceY); + void Distance(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); @@ -314,7 +315,7 @@ namespace PdfReader //GfxTextClip *m_pBufferTextClip; XRef *m_pXref; // Таблица Xref для данного PDF-документа - CFontList *m_pFontList; + CPdfFontList *m_pFontList; bool *m_pbBreak; // Внешняя остановка рендерера diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 05f9378f3d6..3b3db864c95 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -132,8 +132,6 @@ namespace PdfWriter sDA.append(bCaps ? "K" : "k"); else if (arr.size() == 1) sDA.append(bCaps ? "G" : "g"); - // else - // sDA.append(bCaps ? "SC" : "sc"); return sDA; } std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) @@ -462,19 +460,144 @@ namespace PdfWriter } void CTextAnnotation::SetAP() { + std::string sColor = GetColor(dynamic_cast<CArrayObject*>(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: { - CAnnotAppearanceObject* pAP = new CAnnotAppearanceObject(m_pXref, this); - 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); + } + case 12: + { + pN->AddBBox(0, 0, 20, 20); + pN->DrawTextRightArrow(sColor); + pR->AddBBox(0, 0, 20, 20); + pR->DrawTextRightArrow(sColor); + } + case 13: + { + pN->AddBBox(0, 0, 20, 17); + pN->DrawTextRightPointer(sColor); + pR->AddBBox(0, 0, 20, 17); + pR->DrawTextRightPointer(sColor); + } + case 14: + { + pN->AddBBox(0, 0, 20, 19); + pN->DrawTextStar(sColor); + pR->AddBBox(0, 0, 20, 19); + pR->DrawTextStar(sColor); + } + case 15: + { + pN->AddBBox(0, 0, 17, 20); + pN->DrawTextUpArrow(sColor); + pR->AddBBox(0, 0, 17, 20); + pR->DrawTextUpArrow(sColor); + } + case 16: + { + pN->AddBBox(0, 0, 17, 17); + pN->DrawTextUpLeftArrow(sColor); + pR->AddBBox(0, 0, 17, 17); + pR->DrawTextUpLeftArrow(sColor); + } case 10: default: { + pN->AddBBox(0, 0, 18, 20); + pN->DrawTextNote(sColor); + pR->AddBBox(0, 0, 18, 20); + pR->DrawTextNote(sColor); break; } } @@ -675,6 +798,17 @@ namespace PdfWriter 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; @@ -684,7 +818,7 @@ namespace PdfWriter 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 DrawLineArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) + void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) { double lineEndSize1 = 3, pi = 3.14159265358979323846; switch (nType) @@ -782,6 +916,65 @@ namespace PdfWriter } } } + 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); @@ -789,6 +982,28 @@ namespace PdfWriter CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); CStream* pStream = pNormal->GetStream(); + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + pNormal->Add("BBox", pArray); + + pArray->Add(GetRect().fLeft); + pArray->Add(GetRect().fBottom); + pArray->Add(GetRect().fRight); + pArray->Add(GetRect().fTop); + + pArray = new CArrayObject(); + if (!pArray) + return; + + pNormal->Add("Matrix", pArray); + pArray->Add(1); + pArray->Add(0); + pArray->Add(0); + pArray->Add(1); + pArray->Add(-GetRect().fLeft); + pArray->Add(-GetRect().fBottom); + if (GetBorderType() == EBorderType::Dashed) pStream->WriteStr(GetBorderDash().c_str()); @@ -833,62 +1048,7 @@ namespace PdfWriter if (pObj && pObj->GetType() == object_type_REAL) dLLO = ((CRealObject*)pObj)->Get(); - double dDX = dL[2] - dL[0]; - double dDY = dL[3] - dL[1]; - 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 = dL[0] + dLLO * dDY; - ay1 = dL[1] - dLLO * dDX; - lx1 = ax1 + dLL * dDY; - ly1 = ay1 - dLL * dDX; - bx1 = lx1 + dLLE * dDY; - by1 = ly1 - dLLE * dDX; - ax2 = dL[2] + dLLO * dDY; - ay2 = dL[3] - dLLO * dDX; - lx2 = ax2 + dLL * dDY; - ly2 = ay2 - dLL * dDX; - bx2 = lx2 + dLLE * dDY; - by2 = ly2 - dLLE * dDX; - } - else - { - lx1 = dL[0]; - ly1 = dL[1]; - lx2 = dL[2]; - ly2 = dL[3]; - ax1 = ay1 = ax2 = ay2 = 0; - bx1 = by1 = bx2 = by2 = 0; - } - - double tx1, ty1, tx2, ty2; - AdjustLineEndpoint(m_nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); - AdjustLineEndpoint(m_nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); - - if (dLL != 0) - { - 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"); - - DrawLineArrow(pStream, m_nLE1, tx1, ty1, dDX, dDY, dBorderSize); - DrawLineArrow(pStream, m_nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); + DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); } //---------------------------------------------------------------------------------------- // CPopupAnnotation @@ -910,6 +1070,27 @@ namespace PdfWriter CFreeTextAnnotation::CFreeTextAnnotation(CXref* pXref) : CMarkupAnnotation(pXref, AnnotFreeText) { } + void CFreeTextAnnotation::SetDA(CFontDict* pFont, const double& dFontSize, const std::vector<double>& arrC) + { + CResourcesDict* pFieldsResources = m_pDocument->GetFieldsResources(); + const char* sFontName = pFieldsResources->GetFontName(pFont); + + std::vector<double> _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); @@ -934,6 +1115,10 @@ namespace PdfWriter { 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); @@ -954,6 +1139,52 @@ namespace PdfWriter for (int i = 0; i < arrCL.size(); ++i) pArray->Add(i % 2 == 0 ? (arrCL[i] + m_dPageX) : (m_dPageH - arrCL[i])); } + void CFreeTextAnnotation::SetIC(const std::vector<double>& arrIC) + { + SetC(arrIC); + } + void CFreeTextAnnotation::APFromFakePage(CPage* pFakePage) + { + // xref NULL - тогда у CAnnotAppearanceObject не будет создан stream + m_pAppearance = new CAnnotAppearance(NULL, this); + if (!m_pAppearance) + return; + Add("AP", m_pAppearance); + CAnnotAppearanceObject* pNormal = m_pAppearance->GetNormal((CResourcesDict*)pFakePage->Get("Resources")); + m_pXref->Add(pNormal); + m_pAppearance->Add("N", pNormal); + + CArrayObject* pArray = new CArrayObject(); + if (!pArray) + return; + pNormal->Add("BBox", pArray); + + pArray->Add(GetRect().fLeft); + pArray->Add(GetRect().fBottom); + pArray->Add(GetRect().fRight); + pArray->Add(GetRect().fTop); + + pArray = new CArrayObject(); + if (!pArray) + return; + + pNormal->Add("Matrix", pArray); + pArray->Add(1); + pArray->Add(0); + pArray->Add(0); + pArray->Add(1); + pArray->Add(-GetRect().fLeft); + pArray->Add(-GetRect().fBottom); + + CDictObject* pFPStream = pFakePage->GetContent(); + pNormal->SetStream(m_pXref, pFPStream->GetStream(), false); +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_pDocument->GetCompressionMode() & COMP_TEXT) + pNormal->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + pFPStream->SetStream(NULL); + // RELEASEOBJECT(pFPStream); Нельзя удалять - это объект стрима, он уже в xref + } //---------------------------------------------------------------------------------------- // CTextMarkupAnnotation //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index b833079367c..ac691002ca5 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -349,6 +349,9 @@ namespace PdfWriter }; class CFreeTextAnnotation : public CMarkupAnnotation { + private: + CAnnotAppearance* m_pAppearance; + public: CFreeTextAnnotation(CXref* pXref); EAnnotType GetAnnotationType() const override @@ -356,12 +359,17 @@ namespace PdfWriter return AnnotFreeText; } + void APFromFakePage(CPage* pFakePage); + void SetDA(CFontDict* pFont, const double& dFontSize, const std::vector<double>& 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<double>& arrCL); + void SetIC(const std::vector<double>& arrIC); }; class CCaretAnnotation : public CMarkupAnnotation { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 7310379f5b2..0c207d11e2c 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -80,24 +80,23 @@ 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() { @@ -172,6 +171,8 @@ namespace PdfWriter m_vFillAlpha.clear(); m_vStrokeAlpha.clear(); m_vRadioGroups.clear(); + m_vMetaOForms.clear(); + m_vImages.clear(); m_pTransparencyGroup = NULL; @@ -190,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; @@ -212,6 +214,8 @@ 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); @@ -310,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) { @@ -437,6 +447,27 @@ namespace PdfWriter { 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) @@ -513,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) @@ -543,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++) { @@ -566,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++) { @@ -763,9 +785,24 @@ namespace PdfWriter return pForm; } - CFont14* CDocument::CreateFont14(EStandard14Fonts eType) + CFont14* CDocument::CreateFont14(const std::wstring& wsFontPath, unsigned int unIndex, EStandard14Fonts eType) { - return new CFont14(m_pXref, this, 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) { @@ -1220,6 +1257,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]; @@ -1446,6 +1511,10 @@ namespace PdfWriter return p->second; return NULL; } + CPage* CDocument::CreateFakePage() + { + return new CPage(this, m_pXref); + } bool CDocument::EditCO(const std::vector<int>& arrCO) { if (arrCO.empty()) @@ -1557,13 +1626,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; @@ -1688,4 +1772,94 @@ namespace PdfWriter RELEASEOBJECT(XRef); vXRefForWrite.clear(); } + void CDocument::AddShapeXML(const std::string& sXML) + { + CDictObject* pResources = (CDictObject*)m_pCurPage->Get("Resources"); + if (!pResources) + { + pResources = new CDictObject(); + 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; + } + 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); + + 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(); + pMetaOForm->Add("ID", sID); + } + 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); + m_pCurPage->BeginMarkedContentDict("OShapes", pBDC); + RELEASEOBJECT(pBDC); + } + void CDocument::EndShapeXML() + { + CDictObject* pResources = (CDictObject*)m_pCurPage->Get("Resources"); + 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); + } } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index f8a1dbead25..a9553518ec7 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -157,7 +157,8 @@ namespace PdfWriter CImageDict* CreateImage(); CXObject* CreateForm(CImageDict* pImage, const std::string& sName); - CFont14* CreateFont14(EStandard14Fonts eType); + 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); @@ -178,6 +179,12 @@ 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); @@ -196,8 +203,12 @@ namespace PdfWriter CDictObject* GetParent(int nID); CPage* GetCurPage() { return m_pCurPage; } void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } + CPage* CreateFakePage(); bool EditCO(const std::vector<int>& arrCO); const std::map<int, CAnnotation*>& GetAnnots() { return m_mAnnotations; } + void AddShapeXML(const std::string& sXML); + void EndShapeXML(); + void ClearPage(); private: char* GetTTFontTag(); @@ -245,6 +256,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; @@ -253,6 +277,7 @@ namespace PdfWriter CPageTree* m_pPageTree; CPage* m_pCurPage; int m_nCurPageNum; + CImageDict* m_pCurImage; CInfoDict* m_pInfo; CDictObject* m_pTrailer; CDictObject* m_pResources; @@ -260,6 +285,7 @@ namespace PdfWriter bool m_bEncrypt; CEncryptDict* m_pEncryptDict; std::vector<TSignatureInfo> m_vSignatures; + std::vector<TImageInfo> m_vImages; unsigned int m_unFormFields; unsigned int m_unCompressMode; std::vector<CExtGrState*> m_vExtGrStates; @@ -270,6 +296,7 @@ namespace PdfWriter std::vector<CShading*> m_vShadings; std::vector<TFontInfo> m_vCidTTFonts; std::vector<TFontInfo> m_vTTFonts; + std::vector<TFontInfo> m_vFonts14; CFont14* m_pDefaultCheckBoxFont; CDictObject* m_pTransparencyGroup; std::vector<CFontCidTrueType*> m_vFreeTypeFonts; @@ -280,6 +307,7 @@ namespace PdfWriter CDictObject* m_pAcroForm; CResourcesDict* m_pFieldsResources; std::vector<CRadioGroupField*> m_vRadioGroups; + std::vector<CDictObject*> m_vMetaOForms; std::map<std::string, CFieldBase*> m_mFields; std::map<int, CAnnotation*> m_mAnnotations; std::map<int, CDictObject*> m_mParents; diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 38703828e22..4c769c1a0e7 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -1537,40 +1537,41 @@ namespace PdfWriter m_pRollover = NULL; m_pDown = NULL; } - CAnnotAppearanceObject* CAnnotAppearance::GetNormal() + 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); - Add("N", m_pNormal); + 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) { if (m_pField) m_pRollover = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pRollover = new CAnnotAppearanceObject(m_pXref, 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) { if (m_pField) m_pDown = new CAnnotAppearanceObject(m_pXref, m_pField); else if (m_pAnnot) - m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot); + m_pDown = new CAnnotAppearanceObject(m_pXref, m_pAnnot, pResources); Add("D", m_pDown); } @@ -1621,12 +1622,15 @@ namespace PdfWriter void CAnnotAppearanceObject::Init(CXref* pXref, CResourcesDict* pResources) { m_pXref = pXref ? pXref : NULL; - m_pStream = new CMemoryStream(); m_pFont = NULL; m_dFontSize = 10.0; + m_bStart = true; if (m_pXref) + { + m_pStream = new CMemoryStream(); SetStream(m_pXref, m_pStream); + } Add("Type", "XObject"); Add("Subtype", "Form"); @@ -1648,42 +1652,23 @@ namespace PdfWriter pArray->Add(fabs(pField->GetRect().fRight - pField->GetRect().fLeft)); pArray->Add(fabs(pField->GetRect().fBottom - pField->GetRect().fTop)); } - CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot) + CAnnotAppearanceObject::CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot, CResourcesDict* pResources) { - Init(pXRef, pAnnot->GetDocument()->GetFieldsResources()); + Init(pXRef, pResources ? pResources : pAnnot->GetDocument()->GetFieldsResources()); m_pAnnot = pAnnot; m_pField = NULL; - CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - Add("BBox", pArray); - if (pAnnot->GetAnnotationType() == EAnnotType::AnnotWidget) { - pArray->Add(0); - pArray->Add(0); - pArray->Add(fabs(pAnnot->GetRect().fRight - pAnnot->GetRect().fLeft)); - pArray->Add(fabs(pAnnot->GetRect().fBottom - pAnnot->GetRect().fTop)); - } - else - { - pArray->Add(pAnnot->GetRect().fLeft); - pArray->Add(pAnnot->GetRect().fBottom); - pArray->Add(pAnnot->GetRect().fRight); - pArray->Add(pAnnot->GetRect().fTop); - - pArray = new CArrayObject(); + CArrayObject* pArray = new CArrayObject(); if (!pArray) return; + Add("BBox", pArray); - Add("Matrix", pArray); - pArray->Add(1); pArray->Add(0); pArray->Add(0); - pArray->Add(1); - pArray->Add(-pAnnot->GetRect().fLeft); - pArray->Add(-pAnnot->GetRect().fBottom); + 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) @@ -2620,18 +2605,220 @@ namespace PdfWriter m_pStream->WriteStr("ET\012"); m_pStream->WriteStr("Q\012EMC\012"); } - void CAnnotAppearanceObject::DrawTextComment() + void CAnnotAppearanceObject::AddBBox(double dX, double dY, double dW, double dH) { CArrayObject* pArray = new CArrayObject(); - if (!pArray) - return; - Add("BBox", pArray); - pArray->Add(0); - pArray->Add(0); - pArray->Add(20); - pArray->Add(20); + pArray->Add(dX); + pArray->Add(dY); + pArray->Add(dW); + pArray->Add(dH); + } + 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(""); + 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 9d199d04f9d..0fb7548e7de 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -344,9 +344,9 @@ namespace PdfWriter 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: @@ -382,13 +382,14 @@ namespace PdfWriter { public: CAnnotAppearanceObject(CXref* pXRef, CFieldBase* pField); - CAnnotAppearanceObject(CXref* pXRef, CAnnotation* pAnnot); + 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 StartDraw(const double& dWidth, const double& dHeight); void StartText(CFontDict* pFont, const double& dFontSize); @@ -396,7 +397,25 @@ namespace PdfWriter void EndText(); void EndDraw(); - void DrawTextComment(); + 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() { return m_pStream; } bool m_bStart; 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..da847794fb7 100644 --- a/PdfFile/SrcWriter/Font14.cpp +++ b/PdfFile/SrcWriter/Font14.cpp @@ -30,6 +30,7 @@ * */ #include "Font14.h" +#include "Document.h" namespace PdfWriter { @@ -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<unsigned int, unsigned short>::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<unsigned int, unsigned short>::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<unsigned int, unsigned short>(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<unsigned int, unsigned short> m_mUnicodeToCode; + std::vector<unsigned int> m_vCodeToGid; + std::vector<unsigned int> 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..72ba7d2632d 100644 --- a/PdfFile/SrcWriter/FontCidTT.cpp +++ b/PdfFile/SrcWriter/FontCidTT.cpp @@ -470,7 +470,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<unsigned int> vUnicodes; + for (unsigned int i = 0; i < unCount; i++) + vUnicodes.push_back(pUnicodes[i]); + m_vUnicodes[ushCurCode] = vUnicodes; + } return ushCurCode; + } } if (!OpenFontFace()) @@ -492,6 +501,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; @@ -502,17 +522,9 @@ namespace PdfWriter FT_Get_SubGlyph_Info(m_pFace->glyph, nSubIndex, &nSubGID, &unFlags, &nArg1, &nArg2, &oMatrix); m_mGlyphs.insert(std::pair<unsigned short, bool>(nSubGID, true)); - } - 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.h b/PdfFile/SrcWriter/FontTT.h index 95a19f0cec7..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; diff --git a/PdfFile/SrcWriter/FontTTWriter.cpp b/PdfFile/SrcWriter/FontTTWriter.cpp index a21f0a337f2..25d4685e99e 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 @@ -491,6 +490,7 @@ namespace PdfWriter } pLocaTable[m_nGlyphs].nLen = 0; qsort(pLocaTable, m_nGlyphs + 1, sizeof(TrueTypeLoca), &CompareTrueTypeLocaIndex); + pLocaTable[m_nGlyphs].nLen = 0; nPos = 0; for (i = 0; i <= m_nGlyphs; ++i) @@ -623,11 +623,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; // @@ -645,8 +645,8 @@ namespace PdfWriter for (i = 0; i < unCodesCount; ++i) { - arrNewCmapTable[22 + 2 * i] = pCodeToGID[i] >> 8; - arrNewCmapTable[22 + 2 * i + 1] = pCodeToGID[i] & 0xff; + arrNewCmapTable[22 + 2 * i] = (char)(pCodeToGID[i] >> 8); + arrNewCmapTable[22 + 2 * i + 1] = (char)(pCodeToGID[i] & 0xff); } } else diff --git a/PdfFile/SrcWriter/Image.cpp b/PdfFile/SrcWriter/Image.cpp index 77ae89b1a13..75fabbae3e7 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,22 +68,22 @@ namespace NSImageReSaver oFile.CloseFile(); RELEASEARRAYOBJECTS(data); - if (std::string::npos == sFind.find("Photoshop") && std::string::npos == sFind.find("photoshop")) - return; + if (std::string::npos != sFind.find("Photoshop") || std::string::npos != sFind.find("photoshop")) + { + CBgraFrame oFrame; + if (!oFrame.OpenFile(wsFileName)) + return; - 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(); + } } } diff --git a/PdfFile/SrcWriter/Metadata.cpp b/PdfFile/SrcWriter/Metadata.cpp index 57d56629bda..ad4211b8098 100644 --- a/PdfFile/SrcWriter/Metadata.cpp +++ b/PdfFile/SrcWriter/Metadata.cpp @@ -155,7 +155,7 @@ namespace PdfWriter if (pXref->IsPDFA()) { sXML += "<rdf:Description rdf:about=\"\" xmlns:pdfaid=\"http://www.aiim.org/pdfa/ns/id/\">\n"; - sXML += "<pdfaid:part>1</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance>\n"; + sXML += "<pdfaid:part>2</pdfaid:part><pdfaid:conformance>A</pdfaid:conformance>\n"; sXML += "</rdf:Description>"; } @@ -179,6 +179,12 @@ namespace PdfWriter 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") diff --git a/PdfFile/SrcWriter/Metadata.h b/PdfFile/SrcWriter/Metadata.h index 8e5d0da737f..ea3673035d4 100644 --- a/PdfFile/SrcWriter/Metadata.h +++ b/PdfFile/SrcWriter/Metadata.h @@ -62,6 +62,7 @@ namespace PdfWriter 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; diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index d9018d560c8..1522834b98f 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -651,6 +651,10 @@ namespace PdfWriter } } } + void CDictObject::SetStream(CStream* pStream) + { + m_pStream = pStream; + } void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis) { if (m_pStream) diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index 1852ca57c3c..4a9a28a0abc 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -456,6 +456,7 @@ namespace PdfWriter { return m_pStream; } + void SetStream(CStream* pStream); unsigned int GetFilter() const { return m_unFilter; diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 9654560dc10..82d27c384a8 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 @@ -310,9 +311,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 +385,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"); @@ -457,13 +443,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 +514,7 @@ namespace PdfWriter { return (CArrayObject*)Get("MediaBox"); } - CDictObject* CPage::GetResourcesItem() + CResourcesDict* CPage::GetResourcesItem() { CObjectBase* pObject = Get("Resources"); @@ -556,7 +536,7 @@ namespace PdfWriter } } - return (CDictObject*)pObject; + return (CResourcesDict*)pObject; } CObjectBase* CPage::GetCropBoxItem() { @@ -566,27 +546,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 +1009,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 +1057,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 +1151,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 +1264,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 +1279,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 +1316,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 +1334,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 +1380,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 +1419,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 +1478,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..7defc057b7d 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 //---------------------------------------------------------------------------------------- @@ -90,7 +91,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(); @@ -131,6 +132,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 +140,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 +166,23 @@ namespace PdfWriter void AddContents(CXref* pXref); void SetRotate(int nRotate); int GetRotate(); + void ClearContent(CXref* pXref); + CDictObject* GetContent() const; 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(); + CResourcesDict* 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 +197,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 fdca7a9e50f..a4a94413646 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,14 +113,19 @@ 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); } @@ -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); } @@ -169,7 +184,7 @@ namespace PdfWriter if (pFonts && pFonts->GetType() == object_type_DICT) { m_pFonts = (CDictObject*)pFonts; - m_unFontsCount = m_pFonts->GetSize(); + m_unFontsCount = 0; } // Инициализация текущего ExtGStates @@ -177,7 +192,7 @@ namespace PdfWriter if (pExtGStates && pExtGStates->GetType() == object_type_DICT) { m_pExtGStates = (CDictObject*)pExtGStates; - m_unExtGStatesCount = m_pExtGStates->GetSize(); + m_unExtGStatesCount = 0; } // Инициализация текущего XObject @@ -185,7 +200,7 @@ namespace PdfWriter if (pXObject && pXObject->GetType() == object_type_DICT) { m_pXObjects = (CDictObject*)pXObject; - m_unXObjectsCount = m_pXObjects->GetSize(); + m_unXObjectsCount = 0; } } } diff --git a/PdfFile/SrcWriter/States.cpp b/PdfFile/SrcWriter/States.cpp index 683d0153887..2e8d5363122 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); @@ -177,7 +177,7 @@ void CCommandManager::Flush() 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)) { diff --git a/PdfFile/SrcWriter/Types.h b/PdfFile/SrcWriter/Types.h index 20a211ceb00..bfd04c1398a 100644 --- a/PdfFile/SrcWriter/Types.h +++ b/PdfFile/SrcWriter/Types.h @@ -136,7 +136,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/lib/xpdf/Gfx.cc b/PdfFile/lib/xpdf/Gfx.cc index 9491883a969..4a66ee81a3d 100644 --- a/PdfFile/lib/xpdf/Gfx.cc +++ b/PdfFile/lib/xpdf/Gfx.cc @@ -5053,6 +5053,29 @@ 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, oMCID, oMetadata, oMetadataCur; + if (obj.fetch(xref, &oMetaOForm)->isDict("OShapes") && 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(); 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(); oMCID.free(), oMetadata.free(); oMetadataCur.free(); obj.free(); } mc = new GfxMarkedContent(mcKind, ocState); markedContentStack->append(mc); 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/Stream.cc b/PdfFile/lib/xpdf/Stream.cc index 0d2d284bb5b..5a7b0eefd0e 100644 --- a/PdfFile/lib/xpdf/Stream.cc +++ b/PdfFile/lib/xpdf/Stream.cc @@ -5252,7 +5252,7 @@ void FlateStream::readSome() { totalOut += remain; // check for a 'decompression bomb' - if (totalOut > 50000000 && totalIn < totalOut / 250) { + if (totalOut > 100000000 && 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 3b0f2fe998a..1b2721be139 100644 --- a/PdfFile/lib/xpdf/XRef.cc +++ b/PdfFile/lib/xpdf/XRef.cc @@ -946,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); @@ -953,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]); } @@ -991,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()) { @@ -1005,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 9eb93eb3962..3ea5ba7a393 100644 --- a/PdfFile/lib/xpdf/XRef.h +++ b/PdfFile/lib/xpdf/XRef.h @@ -174,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 0ddac403bb0..9b512f9c754 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -37,6 +37,7 @@ #include "../../DesktopEditor/xmlsec/src/include/CertificateCommon.h" #include "../../DesktopEditor/graphics/MetafileToGraphicsRenderer.h" #include "../PdfFile.h" +#include "../../DjVuFile/DjVu.h" class CPdfFileTest : public testing::Test { @@ -142,6 +143,42 @@ CApplicationFontsWorker* CPdfFileTest::oWorker = NULL; NSFonts::IApplicationFonts* CPdfFileTest::pApplicationFonts = NULL; std::wstring CPdfFileTest::wsTempDir; +TEST_F(CPdfFileTest, DjVuToPdf) +{ + GTEST_SKIP(); + + CDjVuFile* pFile = new CDjVuFile(pApplicationFonts); + + ASSERT_TRUE(pFile->LoadFromFile(NSFile::GetProcessDirectory() + L"/test.djvu")); + + pdfFile->CreatePdf(); + + int nPagesCount = pFile->GetPagesCount(); + for (int i = 0; i < nPagesCount; ++i) + { + pdfFile->NewPage(); + pdfFile->BeginCommand(c_nPageType); + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pFile->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + pdfFile->put_Width(dWidth); + pdfFile->put_Height(dHeight); + + pFile->DrawPageOnRenderer(pdfFile, i, NULL); + + pdfFile->EndCommand(c_nPageType); + } + + pdfFile->SaveToFile(wsDstFile); + + RELEASEOBJECT(pFile); +} + TEST_F(CPdfFileTest, GetMetaData) { GTEST_SKIP(); @@ -149,27 +186,25 @@ TEST_F(CPdfFileTest, GetMetaData) BYTE* pMetaData = NULL; DWORD nMetaLength = 0; - if (pdfFile->GetMetaData(wsSrcFile, L"Test0", &pMetaData, nMetaLength)) + if (pdfFile->GetMetaData(wsSrcFile, L"ONLYOFFICEFORM", &pMetaData, nMetaLength)) { NSFile::CFileBinary oFile; - if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/resGetMetaData0.png")) + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf")) oFile.WriteFile(pMetaData, nMetaLength); oFile.CloseFile(); EXPECT_TRUE(pMetaData); } RELEASEARRAYOBJECTS(pMetaData); +} - if (pdfFile->GetMetaData(wsSrcFile, L"Test1", &pMetaData, nMetaLength)) - { - NSFile::CFileBinary oFile; - if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/resGetMetaData1.png")) - oFile.WriteFile(pMetaData, nMetaLength); - oFile.CloseFile(); +TEST_F(CPdfFileTest, ValidMetaData) +{ + GTEST_SKIP(); - EXPECT_TRUE(pMetaData); - } - RELEASEARRAYOBJECTS(pMetaData); + LoadFromFile(); + + std::cout << "ValidMetaData " << (pdfFile->ValidMetaData() ? "true" : "false") << std::endl; } TEST_F(CPdfFileTest, PdfBinToPng) @@ -201,12 +236,28 @@ TEST_F(CPdfFileTest, PdfBinToPng) TEST_F(CPdfFileTest, PdfFromBin) { - GTEST_SKIP(); + //GTEST_SKIP(); pdfFile->CreatePdf(); EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", 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(); @@ -215,14 +266,9 @@ TEST_F(CPdfFileTest, SetMetaData) BYTE* pFileData = NULL; DWORD nFileSize; - std::wstring sFile = NSFile::GetProcessDirectory() + L"/res0.png"; - EXPECT_TRUE(NSFile::CFileBinary::ReadAllBytes(sFile, &pFileData, nFileSize)); - pdfFile->AddMetaData(L"Test0", pFileData, nFileSize); - RELEASEARRAYOBJECTS(pFileData); - - sFile = NSFile::GetProcessDirectory() + L"/res1.png"; + std::wstring sFile = NSFile::GetProcessDirectory() + L"/ONLYOFFICEFORM.docxf"; EXPECT_TRUE(NSFile::CFileBinary::ReadAllBytes(sFile, &pFileData, nFileSize)); - pdfFile->AddMetaData(L"Test1", pFileData, nFileSize); + pdfFile->AddMetaData(L"ONLYOFFICEFORM", pFileData, nFileSize); RELEASEARRAYOBJECTS(pFileData); EXPECT_HRESULT_SUCCEEDED(pdfFile->OnlineWordToPdfFromBinary(NSFile::GetProcessDirectory() + L"/pdf.bin", wsDstFile)); @@ -281,7 +327,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - //GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); @@ -311,8 +357,11 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) } EXPECT_TRUE(NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen)); - pdfFile->AddToPdfFromBinary(pBuffer, nBufferLen, NULL); + CConvertFromBinParams* pParams = new CConvertFromBinParams(); + pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); + pdfFile->AddToPdfFromBinary(pBuffer, nBufferLen, pParams); + RELEASEOBJECT(pParams); RELEASEARRAYOBJECTS(pBuffer); RELEASEARRAYOBJECTS(pFileContent); diff --git a/PdfFile/test/test.pro b/PdfFile/test/test.pro index d409fdea222..354e3658b57 100644 --- a/PdfFile/test/test.pro +++ b/PdfFile/test/test.pro @@ -13,7 +13,7 @@ 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, ooxmlsignature, DjVuFile) SOURCES += test.cpp diff --git a/RtfFile/Format/DestinationCommand.cpp b/RtfFile/Format/DestinationCommand.cpp index 6d14a90bd70..3fb24dd7b69 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]; diff --git a/RtfFile/Format/RtfChar.cpp b/RtfFile/Format/RtfChar.cpp index 47f322b4adf..8bed8689489 100644 --- a/RtfFile/Format/RtfChar.cpp +++ b/RtfFile/Format/RtfChar.cpp @@ -132,7 +132,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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -142,7 +142,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L"<w:r>"; @@ -173,7 +173,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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -183,7 +183,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += m_oProperty.RenderToOOX(oRenderParameter);//w:rPr внутри @@ -415,7 +415,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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nRevised = PROP_DEF; } if (m_oProperty.m_nDeleted != PROP_DEF) @@ -425,7 +425,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oProperty.m_nDeleted = PROP_DEF; } sResult += L"<w:r>"; diff --git a/RtfFile/Format/RtfField.cpp b/RtfFile/Format/RtfField.cpp index 7efac19245b..a18d902e84f 100644 --- a/RtfFile/Format/RtfField.cpp +++ b/RtfFile/Format/RtfField.cpp @@ -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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(pOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(pOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nRevised = PROP_DEF; } if (m_pInsert->m_oCharProperty.m_nDeleted != PROP_DEF) @@ -299,7 +299,7 @@ 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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(pOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(pOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_pInsert->m_oCharProperty.m_nDeleted = PROP_DEF; } //поверяем на наличие гиперссылки diff --git a/RtfFile/Format/RtfOle.cpp b/RtfFile/Format/RtfOle.cpp index bab4dd3daa4..7a9f0180360 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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; pCharProps->m_nDeleted = PROP_DEF; } //---------- diff --git a/RtfFile/Format/RtfProperty.cpp b/RtfFile/Format/RtfProperty.cpp index a286cb60ab4..f81ac1d4761 100644 --- a/RtfFile/Format/RtfProperty.cpp +++ b/RtfFile/Format/RtfProperty.cpp @@ -1530,7 +1530,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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_nRevised = PROP_DEF; } if (m_nDeleted != PROP_DEF) @@ -1540,7 +1540,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_nDeleted = PROP_DEF; } sResult += L"<w:rPr>"; @@ -1551,14 +1551,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; } if( PROP_DEF != m_nCharStyle ) { @@ -1793,7 +1793,7 @@ std::wstring RtfCharProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"<w:rPrChange w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:rPrChange w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L"<w:rPr>"; sResult += m_pOldCharProp->RenderToOOX(oRenderParameterNew); sResult += L"</w:rPr>"; @@ -3921,7 +3921,7 @@ std::wstring RtfParagraphProperty::RenderToOOX(RenderParameter oRenderParameter) RenderParameter oRenderParameterNew = oRenderParameter; oRenderParameterNew.nType = RENDER_TO_OOX_PARAM_UNKNOWN; - sResult += L"<w:pPrChange w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:pPrChange w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L"<w:pPr>"; sResult += m_pOldParagraphProp->RenderToOOX(oRenderParameterNew); sResult += L"</w:pPr>"; @@ -5060,14 +5060,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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; + // sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; //} std::wstring sAuthor = poRtfDocument->m_oRevisionTable.GetAuthor(m_nTrAuth); std::wstring sDate(RtfUtility::convertDateTime(m_nTrDate).c_str()); @@ -5078,11 +5078,11 @@ std::wstring RtfRowProperty::RenderToOOX(RenderParameter oRenderParameter) if (rowChangeProps.empty()) { - sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\"/>"; } else { - sResult += L"<w:trPrChange w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:trPrChange w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; sResult += L"<w:trPr>"; sResult += rowChangeProps; sResult += L"</w:trPr>"; 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"<w:sectPrChange w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:sectPrChange w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; sResult += m_pOldSectionProp->RenderToOOX(oRenderParameterNew); sResult += L"</w:sectPrChange>"; } diff --git a/RtfFile/Format/RtfShape.cpp b/RtfFile/Format/RtfShape.cpp index f9cbec4508d..c5243517a46 100644 --- a/RtfFile/Format/RtfShape.cpp +++ b/RtfFile/Format/RtfShape.cpp @@ -867,7 +867,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"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:ins w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nRevised = PROP_DEF; } if (m_oCharProperty.m_nDeleted != PROP_DEF) @@ -877,7 +877,7 @@ 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"<w:del w:date=\"" + sDate + L"\" w:author=\"" + sAuthor + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; + sResult += L"<w:del w:date=\"" + sDate + L"\" w:author=\"" + XmlUtils::EncodeXmlString(sAuthor) + L"\" w:id=\"" + std::to_wstring(poOOXWriter->m_nCurTrackChangesId++).c_str() + L"\">"; m_oCharProperty.m_nDeleted = PROP_DEF; } std::wstring sCharProp = m_oCharProperty.RenderToOOX(oRenderParameter); 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<std::wstring, _comment>::iterator it = m_mapComments.begin(); it != m_mapComments.end(); ++it) { sResult += L"<w:comment w:id=\"" + std::to_wstring(it->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"</w:comment>"; diff --git a/Test/Applications/StandardTester/main.cpp b/Test/Applications/StandardTester/main.cpp index d68817925d8..fa29715f0fa 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<std::wstring> files = NSDirectory::GetFiles(dir, false); + for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++) + { + std::wstring sExt = NSFile::GetFileExtention(*i); + if (sExt == L"png") + ++nCount; + } + return nCount; +} + 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; @@ -121,6 +135,13 @@ class CInternalWorker void OpenDir(std::wstring sDir) { m_sInputFolder = sDir; + if (m_bDiffOnly) + { + m_files = NSDirectory::GetDirectories(m_sInputFolder); + m_nCount = (int)m_files.size(); + return; + } + std::vector<std::wstring> arFiles = NSDirectory::GetFiles(sDir, true); for (std::vector<std::wstring>::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++) { @@ -268,6 +289,224 @@ 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 @@ -277,6 +516,7 @@ class CConverter : public NSThreads::CBaseThread std::wstring m_file; std::wstring m_folder_dst; int m_format; + bool m_bDiffOnly{false}; public: CConverter(CInternalWorker* pWorker) : NSThreads::CBaseThread() @@ -291,6 +531,21 @@ class CConverter : public NSThreads::CBaseThread virtual DWORD ThreadProc() { + if (m_bDiffOnly) + { + std::wstring strDirIn = m_file; + std::wstring strDirOut = m_folder_dst; + + std::wstring strDiffsMain = NSFile::GetDirectoryName(strDirOut) + L"/DIFF"; + std::wstring strDiffs = strDiffsMain + L"/" + NSFile::GetFileName(m_file); + + 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) { @@ -393,223 +648,7 @@ class CConverter : public NSThreads::CBaseThread 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; - } - } + checkCode = m_pInternal->GenerateDiff(strDirIn, strDirOut, strDiffs); } m_bRunThread = FALSE; @@ -617,19 +656,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<std::wstring> files = NSDirectory::GetFiles(dir, false); - for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++) - { - std::wstring sExt = NSFile::GetFileExtention(*i); - if (sExt == L"png") - ++nCount; - } - return nCount; - } }; CConverter* CInternalWorker::GetNextConverter() @@ -640,6 +666,7 @@ CConverter* CInternalWorker::GetNextConverter() CConverter* pConverter = new CConverter(this); pConverter->DestroyOnFinish(); pConverter->m_file = m_files[m_nCurrent]; + pConverter->m_bDiffOnly = m_bDiffOnly; ++m_nCurrent; std::wstring sName = NSFile::GetFileName(pConverter->m_file); @@ -737,6 +764,7 @@ int main(int argc, char** argv) { std::vector<std::wstring> arFontsDirs; bool bIsStandard = false; + bool bDiffOnly = false; std::wstring strInputFolder = L""; std::wstring strOutputFolder = L""; bool bIsUseSystemFonts = true; @@ -780,6 +808,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 +885,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/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 <settings> </settings> @@ -95,8 +97,23 @@ You need to create an xml configuration file. It must contain: <input> docx txt pptx xlsx<input> <output> txt doc pdf</output> +## 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") + <extract> </extract> + +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"). + <convertBeforeExtract> </convertBeforeExtract> + +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..6a6a5ccdcc9 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -119,22 +119,23 @@ std::vector<std::wstring> CFormatsList::GetAllExts() const { std::vector<std::wstring> 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); + if (!m_pdf.empty()) + all_formats.push_back(m_pdf); return all_formats; } @@ -259,6 +260,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 +280,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"; @@ -335,6 +354,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 +391,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 +445,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,23 +499,6 @@ 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<std::wstring> files = NSDirectory::GetFiles(m_inputDirectory, true); for(int i = 0; i < files.size(); i++) { @@ -483,8 +516,53 @@ void Cx2tTester::Start() } } - if(files.size() < m_maxProc) - m_maxProc = files.size(); + if (m_bExtract) + { + COfficeFileFormatChecker checker; + COfficeUtils utils; + std::vector<std::wstring> 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<std::wstring> 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,16 +590,13 @@ 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<std::wstring>& 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]; @@ -569,7 +644,7 @@ void Cx2tTester::Convert(const std::vector<std::wstring>& 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; @@ -620,6 +695,8 @@ void Cx2tTester::Convert(const std::vector<std::wstring>& files, bool bNoDirecto NSThreads::Sleep(50); } while(IsAllBusy()); + + m_coresCS.Enter(); // setup & start new coverter @@ -652,6 +729,50 @@ void Cx2tTester::Convert(const std::vector<std::wstring>& files, bool bNoDirecto while(!IsAllFree()) NSThreads::Sleep(150); } +void Cx2tTester::Extract(const std::vector<std::wstring>& 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); @@ -844,7 +965,7 @@ 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; @@ -1077,4 +1198,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<std::wstring>& 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..01ce96ada2a 100644 --- a/Test/Applications/x2tTester/x2tTester.h +++ b/Test/Applications/x2tTester/x2tTester.h @@ -55,7 +55,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<std::wstring> m_documents; @@ -111,6 +114,7 @@ class Cx2tTester // parse string like "docx txt" into vector std::vector<std::wstring> ParseExtensionsString(std::wstring extensions, const CFormatsList& fl); void Convert(const std::vector<std::wstring>& files, bool bNoDirectory = false, bool bTrough = false); + void Extract(const std::vector<std::wstring>& files); // takes from config std::wstring m_reportFile; @@ -121,6 +125,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 +142,7 @@ class Cx2tTester // lists CFormatsList m_inputFormatsList; CFormatsList m_outputFormatsList; + CFormatsList m_extractFormatsList; bool m_bIsErrorsOnly; bool m_bIsTimestamp; @@ -157,6 +163,12 @@ class Cx2tTester std::vector<std::wstring> m_deleteLaterFiles; std::vector<std::wstring> 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 +206,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 +226,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<std::wstring>& extractExts); + void SetFilesCount(int totalFiles, int currFile); + + virtual DWORD ThreadProc(); + +private: + Cx2tTester* m_internal; + std::wstring m_inputFile; + std::wstring m_outputFilesDirectory; + std::vector<std::wstring> m_extractExts; + COfficeUtils m_utils; + + int m_totalFiles; + int m_currFile; + +}; + #endif // X2T_TESTER_H diff --git a/X2tConverter/build/Android/libx2t/build.gradle.kts b/X2tConverter/build/Android/libx2t/build.gradle.kts index ba6e880f933..458116abac0 100644 --- a/X2tConverter/build/Android/libx2t/build.gradle.kts +++ b/X2tConverter/build/Android/libx2t/build.gradle.kts @@ -58,37 +58,36 @@ android { "-DANDROID_STL=c++_static", "-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 + ndk { + if (System.getProperty("os.arch") == "aarch64") { + abiFilters.add("arm64-v8a") + } else { + abiFilters.addAll(arrayOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) + } + } } } 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 - ) - ) } } @@ -113,15 +112,15 @@ 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") - } +// 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") +// } } } diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt b/X2tConverter/build/Android/libx2t/src/main/cpp/CMakeLists.txt index 9bfe12baa0c..0ce57130a30 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 libHtmlRenderer.so libDocxRenderer.so libdoctrenderer.so libx2t.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/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 <jni.h> #include <string> -#include <locale> -#include <codecvt> #include <JniLogUtils.h> #include <vector> +#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<wchar_t>; - std::wstring_convert<convert_typeX, wchar_t> converterX; - return converterX.from_bytes(str); - } - - static std::wstring stringToWString(const std::string & str) { - using convert_typeX = std::codecvt_utf8<wchar_t>; - std::wstring_convert<convert_typeX, wchar_t> converterX; - return converterX.from_bytes(str); - } - - static std::string wStringToString(const std::wstring & str) { - using convert_typeX = std::codecvt_utf8<wchar_t>; - std::wstring_convert<convert_typeX, wchar_t> 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/Qt/X2tConverter.pro b/X2tConverter/build/Qt/X2tConverter.pro index da91d2545d3..28349a3c889 100644 --- a/X2tConverter/build/Qt/X2tConverter.pro +++ b/X2tConverter/build/Qt/X2tConverter.pro @@ -22,6 +22,10 @@ build_x2t_as_library { CONFIG += plugin !core_debug:shared:QMAKE_LFLAGS += -exported_symbols_list $$PWD/../../src/dylib/export + + build_strip_debug { + QMAKE_LFLAGS += -Wl,--strip-debug + } } include(X2tConverter.pri) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index c6c830233af..613b2605ef9 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.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 @@ -462,18 +462,26 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT; 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 = 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; convertParams.m_sTempResultOOXMLDirectory = sDocxDir; nRes = doct_bin2docx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromDocxDir(sDocxDir, sTo, nFormatTo, params, convertParams); + 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 @@ -503,7 +511,9 @@ namespace NExtractTools { 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, params, convertParams); } @@ -526,7 +536,6 @@ namespace NExtractTools } else { - std::wstring sDocxFile; std::wstring sDocxDir = combinePath(convertParams.m_sTempDir, L"docx_unpacked"); NSDirectory::CreateDirectory(sDocxDir); @@ -534,14 +543,13 @@ namespace NExtractTools AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM == nFormatFrom || AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF == nFormatFrom) { - sDocxFile = sFrom; - convertParams.m_sTempParamOOXMLFile = sDocxFile; + convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) { params.setFromChanges(false); - nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, sDocxFile, params, convertParams); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::DOCT, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sDocxFile, sDocxDir); + nRes = zip2dir(convertParams.m_sTempParamOOXMLFile, sDocxDir); if (false == SUCCEEDED_X2T(nRes)) { @@ -782,6 +790,10 @@ namespace NExtractTools 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) //{ // nRes = xlsx_dir2csv(sFrom, sTo, sTemp, params); @@ -812,6 +824,10 @@ namespace NExtractTools { 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; @@ -822,7 +838,9 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::XLST; 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 = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); if (true == NSDirectory::CreateDirectory(sXlsxDir)) @@ -832,8 +850,13 @@ namespace NExtractTools nRes = xlst_bin2xlsx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - std::wstring sXlsxFile; - nRes = fromXlsxDir(sXlsxDir, sTo, nFormatTo, params, convertParams); + 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 @@ -1148,7 +1171,9 @@ namespace NExtractTools NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; 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 = combinePath(convertParams.m_sTempDir, L"pptx_unpacked"); @@ -1162,7 +1187,13 @@ namespace NExtractTools nRes = pptt_bin2pptx_dir(sFrom, sTo, params, convertParams); if (SUCCEEDED_X2T(nRes)) { - nRes = fromPptxDir(sPptxDir, sTo, nFormatTo, params, convertParams); + 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 @@ -1322,6 +1353,28 @@ namespace NExtractTools else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } + else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; + if (sToRender.empty()) + { + sToRender = combinePath(convertParams.m_sTempDir, L"toRender.vsdx"); + nRes = dir2zip(sFrom, sToRender); + } + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT; + if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2pdf(eFromType, sToRender, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + convertParams.m_sInternalMediaDirectory = sFrom; + nRes = doct_bin2image(eFromType, sToRender, sTo, params, convertParams); + } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; @@ -1335,11 +1388,10 @@ namespace NExtractTools nFormatTo = *params.m_nFormatTo; _UINT32 nRes = 0; - std::wstring sVsdxFile; std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"xsdx_unpacked"); NSDirectory::CreateDirectory(sVsdxDir); - if (AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX == nFormatFrom) + if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatFrom)) { convertParams.m_sTempParamOOXMLFile = sFrom; if (params.getFromChanges()) @@ -1347,12 +1399,18 @@ namespace NExtractTools params.setFromChanges(false); nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT, convertParams.m_sTempParamOOXMLFile, params, convertParams); } - nRes = zip2dir(sVsdxFile, sVsdxDir); + nRes = zip2dir(sFrom, sVsdxDir); } else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; if (SUCCEEDED_X2T(nRes)) { + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + nRes = fromVsdxDir(sVsdxDir, sTo, nFormatTo, params, convertParams); } return nRes; @@ -1363,8 +1421,9 @@ namespace NExtractTools _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) @@ -1549,6 +1608,13 @@ namespace NExtractTools 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; @@ -2019,9 +2085,12 @@ namespace NExtractTools { 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, diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index cf995cd0fa4..051792ee9b2 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -56,7 +56,7 @@ namespace NExtractTools 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 = false); + _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); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index abc8ed5dc8f..6f1c8108f8b 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -329,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: @@ -470,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; diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index 0fab20294ae..f88553afb0b 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -95,6 +95,7 @@ namespace NExtractTools TCD_XLTM2XLSM, TCD_XLSB2XLST, TCD_XLSX2XLSB, + TCD_XLST2XLSB, TCD_PPTX2PPTT, TCD_PPTT2PPTX, @@ -915,6 +916,8 @@ 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"<xmlOptions><fileOptions fileType='" + std::to_wstring(nFileType); sRes += L"' codePage='" + std::to_wstring(nCsvEncoding); @@ -1173,7 +1176,6 @@ namespace NExtractTools formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_FB2 || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_MOBI || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT || - formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER || formatFrom == AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF) { diff --git a/X2tConverter/src/lib/common.h b/X2tConverter/src/lib/common.h index 889e31a8668..4e17ab999d8 100644 --- a/X2tConverter/src/lib/common.h +++ b/X2tConverter/src/lib/common.h @@ -453,7 +453,7 @@ namespace NExtractTools else { COfficeUtils oCOfficeUtils(NULL); - hRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOXMLDir, sTo, true)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; + hRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sOOXMLDir, sTo, false)) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; } } else if (AVS_ERROR_DRM == hRes) diff --git a/X2tConverter/src/lib/csv.h b/X2tConverter/src/lib/csv.h index cd01472e477..0ce635462e7 100644 --- a/X2tConverter/src/lib/csv.h +++ b/X2tConverter/src/lib/csv.h @@ -136,6 +136,9 @@ namespace NExtractTools nRes = oCXlsxSerializer.loadFromFile(sTargetBin, sTo, sXmlOptions, sMediaPath, sEmbedPath); } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); return nRes; } diff --git a/X2tConverter/src/lib/docx.h b/X2tConverter/src/lib/docx.h index 0c84b853fb8..224935cdfce 100644 --- a/X2tConverter/src/lib/docx.h +++ b/X2tConverter/src/lib/docx.h @@ -180,6 +180,7 @@ namespace NExtractTools 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) @@ -206,7 +207,6 @@ namespace NExtractTools 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(), convertParams.m_sTempDir) ? 0 : AVS_FILEUTILS_ERROR_CONVERT; return nRes; @@ -220,9 +220,10 @@ namespace NExtractTools BinDocxRW::CDocxSerializer m_oCDocxSerializer; _UINT32 nRes = 0; - if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX)) + if (m_oCDocxSerializer.convertFlat(sFrom, sTempUnpackedDOCX, params.m_bMacro, convertParams.m_sTempDir)) { - nRes = dir2zipMscrypt(sTempUnpackedDOCX, sTo, params, convertParams); + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + nRes = dir2zipMscrypt(sTempUnpackedDOCX, *params.m_sFileTo, params, convertParams); } else { diff --git a/X2tConverter/src/lib/html.h b/X2tConverter/src/lib/html.h index 1b0129f594e..2a9b8d7aa78 100644 --- a/X2tConverter/src/lib/html.h +++ b/X2tConverter/src/lib/html.h @@ -152,7 +152,17 @@ namespace NExtractTools // doct_bin => html _UINT32 doct_bin2html_internal(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sFileFromDir = NSDirectory::GetFolderPath(sFrom); + _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; + + std::wstring sFileFromDir = NSDirectory::GetFolderPath(sTargetBin); std::wstring sImagesDirectory = combinePath(sFileFromDir, L"media"); std::wstring sHtmlFile = combinePath(convertParams.m_sTempDir, L"index.html"); if (!NSDirectory::Exists(sImagesDirectory)) @@ -161,17 +171,21 @@ namespace NExtractTools 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); + sTargetBin, sHtmlFile, sImagesDirectory, convertParams.m_sThemesDir, -1, L"", params); std::wstring sResult; oDoctRenderer.Execute(sXml, sResult); + + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); if (sResult.find(L"error") != std::wstring::npos) { std::wcerr << L"DoctRenderer:" << sResult << std::endl; return AVS_FILEUTILS_ERROR_CONVERT; } - return 0; + return nRes; } // doct_bin -> epub diff --git a/X2tConverter/src/lib/pdf_image.h b/X2tConverter/src/lib/pdf_image.h index 58f4282131f..6372629d20e 100644 --- a/X2tConverter/src/lib/pdf_image.h +++ b/X2tConverter/src/lib/pdf_image.h @@ -564,6 +564,10 @@ namespace NExtractTools } sFileToExt = getExtentionByRasterFormat(nRasterFormat); } + + int nSaveFlags = (nSaveType & 0xF0) >> 4; + nSaveType = nSaveType & 0x0F; + int nPagesCount = pReader->GetPagesCount(); if (bIsOnlyFirst) nPagesCount = 1; @@ -572,12 +576,23 @@ namespace NExtractTools int nRasterWCur = nRasterW; int nRasterHCur = nRasterH; - if (1 == nSaveType) + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + if (nSaveFlags & 0x0F) { - double dPageDpiX, dPageDpiY; - double dWidth, dHeight; - pReader->GetPageInfo(i, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + 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) @@ -926,7 +941,7 @@ namespace NExtractTools CDocxRenderer oDocxRenderer(pApplicationFonts); - NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::tatPlainLine; + NSDocxRenderer::TextAssociationType taType = NSDocxRenderer::TextAssociationType::tatPlainLine; if (params.m_oTextParams) { InputParamsText *oTextParams = params.m_oTextParams; @@ -936,16 +951,16 @@ namespace NExtractTools switch (*oTextParams->m_nTextAssociationType) { case 0: - taType = NSDocxRenderer::tatBlockChar; + taType = NSDocxRenderer::TextAssociationType::tatBlockChar; break; case 1: - taType = NSDocxRenderer::tatBlockLine; + taType = NSDocxRenderer::TextAssociationType::tatBlockLine; break; case 2: - taType = NSDocxRenderer::tatPlainLine; + taType = NSDocxRenderer::TextAssociationType::tatPlainLine; break; case 3: - taType = NSDocxRenderer::tatPlainParagraph; + taType = NSDocxRenderer::TextAssociationType::tatPlainParagraph; break; default: break; diff --git a/X2tConverter/src/lib/pdf_oform.h b/X2tConverter/src/lib/pdf_oform.h index b04aa776e60..24f54c2c358 100644 --- a/X2tConverter/src/lib/pdf_oform.h +++ b/X2tConverter/src/lib/pdf_oform.h @@ -45,9 +45,28 @@ namespace NExtractTools _UINT32 pdfoform2docx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sTempDocx = combinePath(convertParams.m_sTempDir, L"meta.docx"); + 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); diff --git a/X2tConverter/src/lib/pptx.h b/X2tConverter/src/lib/pptx.h index aedc08340b7..9da4314f32f 100644 --- a/X2tConverter/src/lib/pptx.h +++ b/X2tConverter/src/lib/pptx.h @@ -169,6 +169,7 @@ namespace NExtractTools 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 diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 617bebb4104..0c8a12b7cd8 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -157,6 +157,68 @@ namespace NExtractTools 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(); + + 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 @@ -223,6 +285,7 @@ namespace NExtractTools if (SUCCEEDED_X2T(nRes)) { nRes = oCXlsxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sXmlOptions, sMediaPath, sEmbedPath); + params.m_bMacro = oCXlsxSerializer.getMacroEnabled(); } // удаляем EditorWithChanges, потому что он не в Temp if (sFrom != sTargetBin) @@ -235,7 +298,11 @@ namespace NExtractTools { 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); @@ -303,6 +370,23 @@ namespace NExtractTools 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); diff --git a/X2tConverter/src/main.cpp b/X2tConverter/src/main.cpp index 6b19ec11c70..c615cb5cdbb 100644 --- a/X2tConverter/src/main.cpp +++ b/X2tConverter/src/main.cpp @@ -98,7 +98,7 @@ 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); 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..0609df7d328 100644 --- a/X2tConverter/test/win32Test/X2tTest.cpp +++ b/X2tConverter/test/win32Test/X2tTest.cpp @@ -45,7 +45,8 @@ #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") @@ -58,7 +59,8 @@ #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) @@ -75,7 +77,8 @@ #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") @@ -89,7 +92,8 @@ #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 4f3cfd2abb1..8223bda761e 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -194,9 +194,6 @@ <ClInclude Include="..\..\src\lib\xlsx.h" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\..\..\Common\3dParty\cryptopp\vs2019\cryptlib.vcxproj"> - <Project>{c39f4b46-6e89-4074-902e-ca57073044d2}</Project> - </ProjectReference> <ProjectReference Include="..\..\..\Common\cfcpp\CompoundFileLib.vcxproj"> <Project>{fa22bab4-e93e-459d-8a5f-16764fbbed40}</Project> </ProjectReference> @@ -233,9 +230,6 @@ <ProjectReference Include="..\..\..\OdfFile\Projects\Windows\Oox2OdfConverter.vcxproj"> <Project>{bee01b53-244a-44e6-8947-ed9342d9247e}</Project> </ProjectReference> - <ProjectReference Include="..\..\..\OfficeCryptReader\win32\ECMACryptReader.vcxproj"> - <Project>{c27e9a9f-3a17-4482-9c5f-bf15c01e747c}</Project> - </ProjectReference> <ProjectReference Include="..\..\..\OOXML\Projects\Windows\BinaryFormatLib\BinaryFormatLib.vcxproj"> <Project>{cd359215-e183-4ea7-b986-42868b10d8b8}</Project> </ProjectReference>