mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Compare commits
294 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| edfa558a38 | |||
| b80ada4b4e | |||
| 492b821472 | |||
| 8cf78b9e58 | |||
| 28bcfafcc6 | |||
| e527db9515 | |||
| db2660a1a3 | |||
| 03919dcb33 | |||
| cd71bc0672 | |||
| 14c9896773 | |||
| 19694bf32d | |||
| 96e1280082 | |||
| ce41e42851 | |||
| 6447aeafa5 | |||
| aa3e0759d7 | |||
| 3db4bdc93f | |||
| ad69100d3f | |||
| b05a95d54e | |||
| 87a09faefb | |||
| 5e35517d71 | |||
| ca94882699 | |||
| 77ece713ee | |||
| 5b44611560 | |||
| f57af6ecc1 | |||
| 4578731001 | |||
| 72566e8064 | |||
| 346f0e9dd0 | |||
| e32bd8fd96 | |||
| de51108ba7 | |||
| 4eb761eec3 | |||
| baf9fb4a93 | |||
| 0b8e833e77 | |||
| 94bb0f5306 | |||
| fc3ce62ec7 | |||
| 3fac5441cb | |||
| 32bd8166d7 | |||
| 4acdd6dd20 | |||
| 518a4ddb2b | |||
| 895082cc93 | |||
| f16fa656e9 | |||
| f16318aebb | |||
| a5c28b72bb | |||
| 290d50ebcc | |||
| 3de1152a3f | |||
| 109c891c1b | |||
| 1b2d803976 | |||
| 9f4613b15c | |||
| ab7e8a07be | |||
| 7603aceee1 | |||
| 7ea66d0bee | |||
| 0e8230cc7f | |||
| 0229d928ab | |||
| 4bdea2d154 | |||
| 751a5d4d7d | |||
| 4b1bd2fb70 | |||
| cbbf650c56 | |||
| b55cd751d1 | |||
| c7d5b60637 | |||
| 666f5c2f9e | |||
| 42b432b4de | |||
| 08ca60091c | |||
| 88d9827d3f | |||
| bae672f718 | |||
| 00344df9ad | |||
| cfb060e142 | |||
| 0565e6164b | |||
| 306cc3f985 | |||
| 2739dd3abd | |||
| 70e6df5aae | |||
| 96030aa322 | |||
| fee801eeeb | |||
| 750273b526 | |||
| cfdb541c28 | |||
| 11121961d9 | |||
| 45828709ee | |||
| 40916e5ccc | |||
| 319610c58d | |||
| 1837a2737e | |||
| 686fc60860 | |||
| 51216f27f4 | |||
| 2eb33ddd22 | |||
| 58c80b052b | |||
| 5eee408eeb | |||
| b6ae1f272c | |||
| 045f23d921 | |||
| d06b52988c | |||
| 4717b47388 | |||
| 31ce9f6a18 | |||
| e44c9fa4c9 | |||
| 3c59ba7a13 | |||
| 42e84249e8 | |||
| e2dbde8722 | |||
| 36c67d79d5 | |||
| cdc14d22f0 | |||
| baed05236b | |||
| c644f94c0b | |||
| 087e4433f2 | |||
| bc11a5cf5f | |||
| d86303e290 | |||
| 51f1faa51a | |||
| 6775dccc2c | |||
| ee3b4c612d | |||
| 1144bb166c | |||
| a9752208f6 | |||
| 84016cf8cf | |||
| cb7edc373c | |||
| d1e43d68dc | |||
| b5ab5f9b2b | |||
| 761c5bec53 | |||
| 8cc7034c22 | |||
| ee1c385b54 | |||
| ded640825b | |||
| 84301531c8 | |||
| 310cd6d8fd | |||
| 2d37cf634a | |||
| 04880b4e1d | |||
| 1000b5d5bd | |||
| c324b4a11c | |||
| a51fe4134c | |||
| 985d258bc1 | |||
| fee5c112b4 | |||
| 9b50f9fbc2 | |||
| 10f770fdbc | |||
| eb53c40135 | |||
| ded1655a04 | |||
| 20c11889aa | |||
| 910c2418d6 | |||
| e6ffdc0ae8 | |||
| 0335d330b8 | |||
| af2e86e777 | |||
| bcf7d08c51 | |||
| 11886dcdf7 | |||
| 615d0b682c | |||
| 535028fa0e | |||
| 5a6386e08b | |||
| 7ca8b22160 | |||
| ec16e247e9 | |||
| 9a76575082 | |||
| c1a586cb56 | |||
| 7707aeb914 | |||
| 50a8540f75 | |||
| cc2e755bca | |||
| 9c1efdeac2 | |||
| ea1538bc11 | |||
| c0d0fb6f5c | |||
| 5e5e07b406 | |||
| 9b5f762420 | |||
| 7020548f06 | |||
| 2d2e15671a | |||
| 00ad32d420 | |||
| ba2cf66c31 | |||
| 57ed9d0c32 | |||
| 40d82f3287 | |||
| 9bdcbf0d89 | |||
| c1774219ec | |||
| 2a6f0bb1b6 | |||
| a23ce22950 | |||
| b4f0d32b6d | |||
| 83db7f2165 | |||
| 3ce03d897d | |||
| be12237042 | |||
| cf7252b92d | |||
| 523f3f24f9 | |||
| 0196a4bb57 | |||
| 9ee9192cd4 | |||
| 5df63a58b7 | |||
| d107bd5df2 | |||
| f51c1fced2 | |||
| 86cba0bdcd | |||
| cceec83568 | |||
| f733543b44 | |||
| bb9d777c14 | |||
| 694dd852d0 | |||
| 18a18eaa40 | |||
| fb021b33ec | |||
| 95ecd8468a | |||
| fbb57d7009 | |||
| 22e9873208 | |||
| 2581e9235d | |||
| 270fd0601f | |||
| 5f69b4f8e6 | |||
| bdaf9fa10b | |||
| 77e64af80c | |||
| 6e3beac6bf | |||
| 641297ac48 | |||
| dcca1f06f4 | |||
| 22d7cfb240 | |||
| fa51ea21b4 | |||
| 7632be9f2f | |||
| cbf40d36f5 | |||
| 2b8e70e67f | |||
| 4b05eb9a50 | |||
| 3221e41e89 | |||
| 58cc6cf6e8 | |||
| c86a8edd30 | |||
| db1d6a935f | |||
| cb9589f6b4 | |||
| cbad285a9f | |||
| 82a3fa6132 | |||
| 0821eefbd3 | |||
| 38a9dfcd14 | |||
| 0f222c15e9 | |||
| d0a554c701 | |||
| acfec0ceb1 | |||
| 899b27d697 | |||
| 5a5db3e8c6 | |||
| 57fdf7eed5 | |||
| 7f13020f2f | |||
| 020298b023 | |||
| 8eb249056b | |||
| 2ed7e803ca | |||
| b9230ef5ff | |||
| 3907110e44 | |||
| 787575a53f | |||
| b58554a3da | |||
| 9e8c0dfb16 | |||
| 6831820dd4 | |||
| cac79cb66e | |||
| 323213a63d | |||
| 473ef17be3 | |||
| 5e56d26a06 | |||
| a390c1ee18 | |||
| 4158ebcd98 | |||
| 7fc65a84ab | |||
| 69ffd656af | |||
| cb929fc5c5 | |||
| 7cd7c9f98f | |||
| 015c10495c | |||
| e973c8f70b | |||
| a77987488b | |||
| 1cfd17e2f3 | |||
| b4c6f69cee | |||
| 67194499a8 | |||
| 9ec6489083 | |||
| 3971400c78 | |||
| e21ed47019 | |||
| 2cf83df7d0 | |||
| 7f96336e75 | |||
| 99da1e3b8c | |||
| 6d152880bd | |||
| dd9fca2a5c | |||
| 67043cf718 | |||
| ba239f139d | |||
| a99733c5a1 | |||
| a60bc542c7 | |||
| 97d36fa1cd | |||
| 87fa0f93be | |||
| 29a48da730 | |||
| e0352541be | |||
| 2e26a3697d | |||
| cd124d5112 | |||
| 4242d32d95 | |||
| a6b5e7e010 | |||
| 57800ec8dd | |||
| 0f3de35eb4 | |||
| 8c83b18216 | |||
| e1c2bf19d9 | |||
| f38767ccbb | |||
| fc94de8549 | |||
| 812fae8f6c | |||
| c938e2756e | |||
| 5679a7902f | |||
| 056bfb84ce | |||
| 2d745de7e2 | |||
| a5c73127fd | |||
| f0f4e39f5c | |||
| b536d6eb41 | |||
| 0af65b1137 | |||
| 5c3a697880 | |||
| 1b8c59ff87 | |||
| 6b4b645180 | |||
| 30868b81bc | |||
| 4c44edc9c9 | |||
| 60f9021bdd | |||
| fd90fbae21 | |||
| c4979075aa | |||
| 6c067ba6ee | |||
| 2456501f1d | |||
| 07c0c58375 | |||
| db28751875 | |||
| 81c9ae120f | |||
| 830c5ec12c | |||
| 33627ab79c | |||
| f5f0630b2d | |||
| 8c62dc448a | |||
| 3c16ba01f0 | |||
| 0b16086ff5 | |||
| 5904bb3507 | |||
| 6a2d3838ae | |||
| f6c48c1edb | |||
| 4c9c79628f | |||
| 58c35139ea | |||
| 7d804f1c70 | |||
| 5b156d72c0 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -46,3 +46,5 @@ DesktopEditor/fontengine/js/common/freetype-2.10.4
|
||||
|
||||
.qtc_clangd
|
||||
Common/3dParty/openssl/openssl/
|
||||
|
||||
msvc_make.bat
|
||||
|
||||
@ -27,7 +27,7 @@ CLEAN=
|
||||
BOOST_VERSION=1.72.0
|
||||
BOOST_VERSION2=1_72_0
|
||||
MIN_IOS_VERSION=8.0
|
||||
IOS_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="YES" OTHER_CFLAGS="-fembed-bitcode" -showsdks | grep iphoneos | \
|
||||
IOS_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="NO" -showsdks | grep iphoneos | \
|
||||
egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`
|
||||
OSX_SDK_VERSION=`xcodebuild BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE="YES" OTHER_CFLAGS="-fembed-bitcode" -showsdks | grep macosx | \
|
||||
egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`
|
||||
@ -42,7 +42,7 @@ XCODE_ROOT=`xcode-select -print-path`
|
||||
#
|
||||
# Should perhaps also consider/use instead: -BOOST_SP_USE_PTHREADS
|
||||
EXTRA_CPPFLAGS="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -g -DNDEBUG \
|
||||
-std=c++11 -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden -fembed-bitcode"
|
||||
-std=c++11 -stdlib=libc++ -fvisibility=hidden -fvisibility-inlines-hidden"
|
||||
EXTRA_IOS_CPPFLAGS="$EXTRA_CPPFLAGS -mios-version-min=$MIN_IOS_VERSION"
|
||||
EXTRA_OSX_CPPFLAGS="$EXTRA_CPPFLAGS"
|
||||
|
||||
@ -259,20 +259,17 @@ buildBoost()
|
||||
echo Building Boost for iPhone
|
||||
# Install this one so we can copy the headers for the frameworks...
|
||||
./b2 -j16 --build-dir=iphone-build --stagedir=iphone-build/stage \
|
||||
cxxflags="-fembed-bitcode" \
|
||||
--prefix=$PREFIXDIR toolset=darwin architecture=arm target-os=iphone \
|
||||
macosx-version=iphone-${IOS_SDK_VERSION} define=_LITTLE_ENDIAN \
|
||||
link=static stage
|
||||
./b2 -j16 --build-dir=iphone-build --stagedir=iphone-build/stage \
|
||||
--prefix=$PREFIXDIR toolset=darwin architecture=arm \
|
||||
cxxflags="-fembed-bitcode" \
|
||||
target-os=iphone macosx-version=iphone-${IOS_SDK_VERSION} \
|
||||
define=_LITTLE_ENDIAN link=static install
|
||||
doneSection
|
||||
|
||||
echo Building Boost for iPhoneSimulator
|
||||
./b2 -j16 --build-dir=iphonesim-build --stagedir=iphonesim-build/stage \
|
||||
cxxflags="-fembed-bitcode" \
|
||||
toolset=darwin-${IOS_SDK_VERSION}~iphonesim architecture=x86 \
|
||||
target-os=iphone macosx-version=iphonesim-${IOS_SDK_VERSION} \
|
||||
link=static stage
|
||||
|
||||
@ -78,24 +78,24 @@ function set_ios_cpu_feature() {
|
||||
armv7)
|
||||
export CC="xcrun -sdk iphoneos clang -arch armv7"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch armv7"
|
||||
export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
arm64)
|
||||
export CC="xcrun -sdk iphoneos clang -arch arm64"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch arm64"
|
||||
export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
arm64e)
|
||||
# -march=armv8.3 ???
|
||||
export CC="xcrun -sdk iphoneos clang -arch arm64e"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch arm64e"
|
||||
export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
i386)
|
||||
export CC="xcrun -sdk iphonesimulator clang -arch i386"
|
||||
|
||||
@ -18,12 +18,12 @@ namespace NSCSS
|
||||
{
|
||||
typedef std::map<std::wstring, std::wstring>::const_iterator styles_iterator;
|
||||
|
||||
CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point)
|
||||
CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE)
|
||||
{}
|
||||
|
||||
CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) :
|
||||
m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId),
|
||||
m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure),
|
||||
m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), m_dCoreFontSize(oStyle.m_dCoreFontSize),
|
||||
m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground),
|
||||
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){}
|
||||
|
||||
@ -116,7 +116,10 @@ namespace NSCSS
|
||||
void CCompiledStyle::AddStyle(const std::map<std::wstring, std::wstring>& mStyle, const unsigned int unLevel, const bool& bHardMode)
|
||||
{
|
||||
const bool bIsThereBorder = (m_oBorder.Empty()) ? false : true;
|
||||
const double dFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE;
|
||||
const double dParentFontSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE;
|
||||
|
||||
if (0 == unLevel)
|
||||
m_dCoreFontSize = dParentFontSize;
|
||||
|
||||
for (std::pair<std::wstring, std::wstring> pPropertie : mStyle)
|
||||
{
|
||||
@ -128,15 +131,15 @@ namespace NSCSS
|
||||
CASE(L"font"):
|
||||
{
|
||||
m_oFont.SetValue(pPropertie.second, unLevel, bHardMode);
|
||||
m_oFont.UpdateSize(dFontSize);
|
||||
m_oFont.UpdateLineHeight(dFontSize);
|
||||
m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize);
|
||||
m_oFont.UpdateLineHeight(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"font-size"):
|
||||
CASE(L"font-size-adjust"):
|
||||
{
|
||||
m_oFont.SetSize(pPropertie.second, unLevel, bHardMode);
|
||||
m_oFont.UpdateSize(dFontSize);
|
||||
m_oFont.UpdateSize(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"font-stretch"):
|
||||
@ -176,7 +179,7 @@ namespace NSCSS
|
||||
break;
|
||||
|
||||
m_oMargin.SetValues(pPropertie.second, unLevel, bHardMode);
|
||||
m_oMargin.UpdateAll(dFontSize);
|
||||
m_oMargin.UpdateAll(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"margin-top"):
|
||||
@ -196,7 +199,7 @@ namespace NSCSS
|
||||
break;
|
||||
|
||||
m_oMargin.SetRight(pPropertie.second, unLevel, bHardMode);
|
||||
m_oMargin.UpdateRight(dFontSize);
|
||||
m_oMargin.UpdateRight(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"margin-bottom"):
|
||||
@ -206,7 +209,7 @@ namespace NSCSS
|
||||
break;
|
||||
|
||||
m_oMargin.SetBottom(pPropertie.second, unLevel, bHardMode);
|
||||
m_oMargin.UpdateBottom(dFontSize);
|
||||
m_oMargin.UpdateBottom(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"margin-left"):
|
||||
@ -217,7 +220,7 @@ namespace NSCSS
|
||||
break;
|
||||
|
||||
m_oMargin.SetLeft(pPropertie.second, unLevel, bHardMode);
|
||||
m_oMargin.UpdateLeft(dFontSize);
|
||||
m_oMargin.UpdateLeft(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
//PADDING
|
||||
@ -225,35 +228,35 @@ namespace NSCSS
|
||||
CASE(L"mso-padding-alt"):
|
||||
{
|
||||
m_oPadding.SetValues(pPropertie.second, unLevel, bHardMode);
|
||||
m_oPadding.UpdateAll(dFontSize);
|
||||
m_oPadding.UpdateAll(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"padding-top"):
|
||||
CASE(L"mso-padding-top-alt"):
|
||||
{
|
||||
m_oPadding.SetTop(pPropertie.second, unLevel, bHardMode);
|
||||
m_oPadding.UpdateTop(dFontSize);
|
||||
m_oPadding.UpdateTop(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"padding-right"):
|
||||
CASE(L"mso-padding-right-alt"):
|
||||
{
|
||||
m_oPadding.SetRight(pPropertie.second, unLevel, bHardMode);
|
||||
m_oPadding.UpdateRight(dFontSize);
|
||||
m_oPadding.UpdateRight(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"padding-bottom"):
|
||||
CASE(L"mso-padding-bottom-alt"):
|
||||
{
|
||||
m_oPadding.SetBottom(pPropertie.second, unLevel, bHardMode);
|
||||
m_oPadding.UpdateBottom(dFontSize);
|
||||
m_oPadding.UpdateBottom(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
CASE(L"padding-left"):
|
||||
CASE(L"mso-padding-left-alt"):
|
||||
{
|
||||
m_oPadding.SetLeft(pPropertie.second, unLevel, bHardMode);
|
||||
m_oPadding.UpdateLeft(dFontSize);
|
||||
m_oPadding.UpdateLeft(dParentFontSize, m_dCoreFontSize);
|
||||
break;
|
||||
}
|
||||
// TEXT
|
||||
|
||||
@ -22,6 +22,7 @@ namespace NSCSS
|
||||
unsigned short int m_nDpi;
|
||||
UnitMeasure m_UnitMeasure;
|
||||
|
||||
double m_dCoreFontSize;
|
||||
public:
|
||||
NSProperties::CFont m_oFont;
|
||||
NSProperties::CIndent m_oMargin;
|
||||
|
||||
@ -14,6 +14,15 @@ namespace NSCSS
|
||||
return m_wsName.empty() && m_wsClass.empty() && m_wsId.empty() && m_wsStyle.empty();
|
||||
}
|
||||
|
||||
void CNode::Clear()
|
||||
{
|
||||
m_wsName .clear();
|
||||
m_wsClass .clear();
|
||||
m_wsId .clear();
|
||||
m_wsStyle .clear();
|
||||
m_mAttributes.clear();
|
||||
}
|
||||
|
||||
std::vector<std::wstring> CNode::GetData() const
|
||||
{
|
||||
std::vector<std::wstring> arValues;
|
||||
|
||||
@ -22,6 +22,8 @@ namespace NSCSS
|
||||
|
||||
bool Empty() const;
|
||||
|
||||
void Clear();
|
||||
|
||||
std::vector<std::wstring> GetData() const;
|
||||
bool operator< (const CNode& oNode) const;
|
||||
bool operator== (const CNode& oNode) const;
|
||||
|
||||
@ -7,12 +7,18 @@ namespace NSCSS
|
||||
return sValue < oStatistickElement.sValue;
|
||||
}
|
||||
|
||||
void CTree::Clear()
|
||||
{
|
||||
m_arrChild.clear();
|
||||
m_oNode.Clear();
|
||||
}
|
||||
|
||||
void CTree::CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics)
|
||||
{
|
||||
if (!oTree.m_oNode.m_wsId.empty())
|
||||
++mStatictics[StatistickElement{StatistickElement::IsId, L'#' + oTree.m_oNode.m_wsId}];
|
||||
if (!oTree.m_oNode.m_wsStyle.empty())
|
||||
++mStatictics[StatistickElement{StatistickElement::IsStyle, oTree.m_oNode.m_wsStyle}];
|
||||
if (!oTree.m_oNode.m_wsStyle.empty())
|
||||
++mStatictics[StatistickElement{StatistickElement::IsStyle, oTree.m_oNode.m_wsStyle}];
|
||||
|
||||
if (!oTree.m_arrChild.empty())
|
||||
for (const CTree& oChildren : oTree.m_arrChild)
|
||||
@ -82,7 +88,7 @@ namespace NSCSS
|
||||
{L"gainsboro", L"DCDCDC"}, {L"lightgray", L"D3D3D3"}, {L"silver", L"C0C0C0"},
|
||||
{L"darkgray", L"A9A9A9"}, {L"gray", L"808080"}, {L"dimgray", L"696969"},
|
||||
{L"lightslategray", L"778899"}, {L"slategray", L"708090"}, {L"darkslategray", L"2F4F4F"},
|
||||
{L"black", L"000000"},
|
||||
{L"black", L"000000"}, {L"grey", L"808080"},
|
||||
/* Outdated */
|
||||
{L"windowtext", L"000000"}, {L"transparent", L"000000"}
|
||||
};
|
||||
|
||||
@ -33,6 +33,8 @@ namespace NSCSS
|
||||
NSCSS::CNode m_oNode;
|
||||
std::vector<CTree> m_arrChild;
|
||||
|
||||
void Clear();
|
||||
|
||||
static void CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics);
|
||||
};
|
||||
|
||||
|
||||
@ -614,11 +614,11 @@ namespace NSCSS
|
||||
|
||||
void CColor::SetHEX(const std::wstring &wsValue)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (6 != wsValue.length() && 3 != wsValue.length())
|
||||
return;
|
||||
|
||||
Clear();
|
||||
|
||||
if (6 == wsValue.length())
|
||||
m_oValue = new std::wstring(wsValue);
|
||||
else
|
||||
@ -632,8 +632,6 @@ namespace NSCSS
|
||||
|
||||
void CColor::SetUrl(const std::wstring &wsValue)
|
||||
{
|
||||
Clear();
|
||||
|
||||
if (wsValue.empty())
|
||||
return;
|
||||
|
||||
@ -648,6 +646,8 @@ namespace NSCSS
|
||||
return;
|
||||
}
|
||||
|
||||
Clear();
|
||||
|
||||
m_oValue = pURL;
|
||||
m_enType = ColorUrl;
|
||||
}
|
||||
@ -659,6 +659,16 @@ namespace NSCSS
|
||||
m_enType = ColorNone;
|
||||
}
|
||||
|
||||
char NormalizeNegativeColorValue(INT nValue)
|
||||
{
|
||||
if (nValue > 255)
|
||||
return 0xff;
|
||||
else if (nValue < 0)
|
||||
return (char)(std::abs(nValue) % 255);
|
||||
|
||||
return (char)nValue;
|
||||
}
|
||||
|
||||
bool CColor::SetValue(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
|
||||
{
|
||||
if ((CHECK_CONDITIONS && !bHardMode) || (wsValue.empty() && unLevel == m_unLevel))
|
||||
@ -692,6 +702,16 @@ namespace NSCSS
|
||||
SetNone();
|
||||
bResult = true;
|
||||
}
|
||||
else if (L"context-stroke" == wsNewValue)
|
||||
{
|
||||
Clear();
|
||||
m_enType = ColorContextStroke;
|
||||
}
|
||||
else if (L"context-fill" == wsNewValue)
|
||||
{
|
||||
Clear();
|
||||
m_enType = ColorContextFill;
|
||||
}
|
||||
else if (10 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"rgb")
|
||||
{
|
||||
size_t unEnd = wsNewValue.find(L')', 4);
|
||||
@ -704,29 +724,18 @@ namespace NSCSS
|
||||
if (3 > arValues.size())
|
||||
return false;
|
||||
|
||||
INT nRed = std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[0], 255));
|
||||
INT nGreen = std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[1], 255));
|
||||
INT nBlue = std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[2], 255));
|
||||
const char chRed = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[0], 255)));
|
||||
const char chGreen = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[1], 255)));
|
||||
const char chBlue = NormalizeNegativeColorValue(std::ceil(NS_STATIC_FUNCTIONS::CalculatePersentage(arValues[2], 255)));
|
||||
|
||||
if (nRed < 0 || nGreen < 0 || nBlue < 0)
|
||||
{
|
||||
SetEmpty(unLevel);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (255 < nRed) nRed = 255;
|
||||
if (255 < nGreen) nGreen = 255;
|
||||
if (255 < nBlue) nBlue = 255;
|
||||
|
||||
SetRGB(nRed, nGreen, nBlue);
|
||||
SetRGB(chRed, chGreen, chBlue);
|
||||
|
||||
if (wsNewValue.substr(0, 4) == L"rgba" && 4 == arValues.size())
|
||||
m_oOpacity.SetValue(arValues[3], unLevel, bHardMode);
|
||||
|
||||
bResult = true;
|
||||
}
|
||||
|
||||
if (5 <= wsNewValue.length())
|
||||
else if (5 <= wsNewValue.length())
|
||||
{
|
||||
SetUrl(wsValue);
|
||||
|
||||
@ -2292,32 +2301,32 @@ namespace NSCSS
|
||||
return m_oLeft.SetValue(dValue, unLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CIndent::UpdateAll(double dFontSize)
|
||||
void CIndent::UpdateAll(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
UpdateTop (dFontSize);
|
||||
UpdateRight (dFontSize);
|
||||
UpdateBottom(dFontSize);
|
||||
UpdateLeft (dFontSize);
|
||||
UpdateTop (dParentFontSize, dCoreFontSize);
|
||||
UpdateRight (dParentFontSize, dCoreFontSize);
|
||||
UpdateBottom(dParentFontSize, dCoreFontSize);
|
||||
UpdateLeft (dParentFontSize, dCoreFontSize);
|
||||
}
|
||||
|
||||
void CIndent::UpdateTop(double dFontSize)
|
||||
void CIndent::UpdateTop(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
UpdateSide(m_oTop, dFontSize);
|
||||
UpdateSide(m_oTop, dParentFontSize, dCoreFontSize);
|
||||
}
|
||||
|
||||
void CIndent::UpdateRight(double dFontSize)
|
||||
void CIndent::UpdateRight(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
UpdateSide(m_oRight, dFontSize);
|
||||
UpdateSide(m_oRight, dParentFontSize, dCoreFontSize);
|
||||
}
|
||||
|
||||
void CIndent::UpdateBottom(double dFontSize)
|
||||
void CIndent::UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
UpdateSide(m_oBottom, dFontSize);
|
||||
UpdateSide(m_oBottom, dParentFontSize, dCoreFontSize);
|
||||
}
|
||||
|
||||
void CIndent::UpdateLeft(double dFontSize)
|
||||
void CIndent::UpdateLeft(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
UpdateSide(m_oLeft, dFontSize);
|
||||
UpdateSide(m_oLeft, dParentFontSize, dCoreFontSize);
|
||||
}
|
||||
|
||||
const CDigit &CIndent::GetTop() const
|
||||
@ -2386,13 +2395,15 @@ namespace NSCSS
|
||||
return bTopResult || bRightResult || bBottomResult || bLeftResult;
|
||||
}
|
||||
|
||||
void CIndent::UpdateSide(CDigit &oSide, double dFontSize)
|
||||
void CIndent::UpdateSide(CDigit &oSide, const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
if (oSide.Empty())
|
||||
return;
|
||||
|
||||
if (NSCSS::Em == oSide.GetUnitMeasure() || NSCSS::Rem == oSide.GetUnitMeasure())
|
||||
oSide.ConvertTo(NSCSS::Twips, dFontSize);
|
||||
if (NSCSS::Em == oSide.GetUnitMeasure())
|
||||
oSide.ConvertTo(NSCSS::Twips, dParentFontSize);
|
||||
else if (NSCSS::Rem == oSide.GetUnitMeasure())
|
||||
oSide.ConvertTo(NSCSS::Twips, dCoreFontSize);
|
||||
}
|
||||
|
||||
// FONT
|
||||
@ -2635,16 +2646,20 @@ namespace NSCSS
|
||||
std::make_pair(L"700", L"bold"), std::make_pair(L"800", L"bold"), std::make_pair(L"900", L"bold")}, unLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CFont::UpdateSize(double dFontSize)
|
||||
void CFont::UpdateSize(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Rem == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure())
|
||||
m_oSize.ConvertTo(NSCSS::Point, dFontSize);
|
||||
if (NSCSS::Em == m_oSize.GetUnitMeasure() || NSCSS::Percent == m_oSize.GetUnitMeasure())
|
||||
m_oSize.ConvertTo(NSCSS::Point, dParentFontSize);
|
||||
else if (NSCSS::Rem == m_oSize.GetUnitMeasure())
|
||||
m_oSize.ConvertTo(NSCSS::Point, dCoreFontSize);
|
||||
}
|
||||
|
||||
void CFont::UpdateLineHeight(double dFontSize)
|
||||
void CFont::UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize)
|
||||
{
|
||||
if (NSCSS::Em == m_oLineHeight.GetUnitMeasure() || NSCSS::Rem == m_oLineHeight.GetUnitMeasure())
|
||||
m_oLineHeight.ConvertTo(NSCSS::Twips, dFontSize);
|
||||
if (NSCSS::Em == m_oLineHeight.GetUnitMeasure())
|
||||
m_oLineHeight.ConvertTo(NSCSS::Twips, dParentFontSize);
|
||||
else if (NSCSS::Rem == m_oLineHeight.GetUnitMeasure())
|
||||
m_oLineHeight.ConvertTo(NSCSS::Twips, dCoreFontSize);
|
||||
}
|
||||
|
||||
bool CFont::Bold() const
|
||||
|
||||
@ -215,7 +215,9 @@ namespace NSCSS
|
||||
ColorNone,
|
||||
ColorRGB,
|
||||
ColorHEX,
|
||||
ColorUrl
|
||||
ColorUrl,
|
||||
ColorContextStroke,
|
||||
ColorContextFill
|
||||
} ColorType;
|
||||
|
||||
class CColor : public CValue<void*>
|
||||
@ -654,11 +656,11 @@ namespace NSCSS
|
||||
bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
|
||||
bool SetLeft (const double& dValue, unsigned int unLevel, bool bHardMode = false);
|
||||
|
||||
void UpdateAll (double dFontSize);
|
||||
void UpdateTop (double dFontSize);
|
||||
void UpdateRight (double dFontSize);
|
||||
void UpdateBottom(double dFontSize);
|
||||
void UpdateLeft (double dFontSize);
|
||||
void UpdateAll (const double& dParentFontSize, const double& dCoreFontSize);
|
||||
void UpdateTop (const double& dParentFontSize, const double& dCoreFontSize);
|
||||
void UpdateRight (const double& dParentFontSize, const double& dCoreFontSize);
|
||||
void UpdateBottom(const double& dParentFontSize, const double& dCoreFontSize);
|
||||
void UpdateLeft (const double& dParentFontSize, const double& dCoreFontSize);
|
||||
|
||||
const CDigit& GetTop () const;
|
||||
const CDigit& GetRight () const;
|
||||
@ -673,7 +675,7 @@ namespace NSCSS
|
||||
bool operator!=(const CIndent& oIndent) const;
|
||||
private:
|
||||
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);
|
||||
void UpdateSide(CDigit& oSide, const double& dParentFontSize, const double& dCoreFontSize);
|
||||
|
||||
CDigit m_oLeft;
|
||||
CDigit m_oTop;
|
||||
@ -700,8 +702,8 @@ namespace NSCSS
|
||||
bool SetVariant (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
|
||||
bool SetWeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
|
||||
|
||||
void UpdateSize(double dFontSize);
|
||||
void UpdateLineHeight(double dFontSize);
|
||||
void UpdateSize(const double& dParentFontSize, const double& dCoreFontSize);
|
||||
void UpdateLineHeight(const double& dParentFontSize, const double& dCoreFontSize);
|
||||
|
||||
void Clear();
|
||||
|
||||
|
||||
@ -55,6 +55,11 @@ static void replace_all(std::string& s, const std::string& s1, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
static bool NodeIsUnprocessed(const std::string& wsTagName)
|
||||
{
|
||||
return "xml" == wsTagName;
|
||||
}
|
||||
|
||||
static bool IsUnckeckedNodes(const std::string& sValue)
|
||||
{
|
||||
return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue);
|
||||
@ -592,6 +597,9 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde
|
||||
|
||||
std::string tagname = get_tag_name(node);
|
||||
|
||||
if (NodeIsUnprocessed(tagname))
|
||||
return;
|
||||
|
||||
if (bCheckValidNode)
|
||||
bCheckValidNode = !IsUnckeckedNodes(tagname);
|
||||
|
||||
|
||||
1
Common/3dParty/hunspell/.gitignore
vendored
1
Common/3dParty/hunspell/.gitignore
vendored
@ -2,3 +2,4 @@ emsdk/
|
||||
hunspell/
|
||||
deploy/
|
||||
o
|
||||
hunspell.data
|
||||
|
||||
@ -14,6 +14,12 @@ def get_hunspell(stable_commit):
|
||||
base.replaceInFile("./src/hunspell/csutil.cxx", "void free_utf_tbl() {", "void free_utf_tbl() { \n return;\n")
|
||||
# bug fix, we need to keep this utf table
|
||||
# free_utf_tbl doesnt delete anything so we can destroy hunspell object
|
||||
|
||||
# replace & add defines to easy control of time limits (CUSTOM_LIMIT)
|
||||
default_tl_defines = "#define TIMELIMIT_GLOBAL (CLOCKS_PER_SEC / 4)\n#define TIMELIMIT_SUGGESTION (CLOCKS_PER_SEC / 10)\n#define TIMELIMIT (CLOCKS_PER_SEC / 20)\n"
|
||||
custom_tl_defines_tl = "#define TIMELIMIT_GLOBAL CUSTOM_TIMELIMIT_GLOBAL\n#define TIMELIMIT_SUGGESTION CUSTOM_TIMELIMIT_SUGGESTION\n#define TIMELIMIT CUSTOM_TIMELIMIT\n"
|
||||
tl_defines = "#ifndef CUSTOM_TIMELIMITS\n" + default_tl_defines + "#else\n" + custom_tl_defines_tl + "#endif\n"
|
||||
base.replaceInFile("./src/hunspell/atypes.hxx", default_tl_defines, tl_defines)
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
|
||||
@ -14,12 +14,32 @@ DEFINES += KERNEL_USE_DYNAMIC_LIBRARY
|
||||
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += hunspell_build_static
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../../..
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/hunspell/qt/hunspell.pri)
|
||||
|
||||
ADD_DEPENDENCY(UnicodeConverter kernel hunspell)
|
||||
# custom time limits of hunspell in clocks (if before.py was executed)
|
||||
# when increasing the limit for each case, it is important to consider that the total time will
|
||||
# also increase, so it is good to increase the global limit. this works the same for the candidate limit with suggest limit
|
||||
DEFINES += CUSTOM_TIMELIMITS
|
||||
|
||||
escape_bracket=
|
||||
!core_windows:escape_bracket=\\
|
||||
|
||||
# total time limit per word for all cases. (default is CLOCKS_PER_SEC/4)
|
||||
DEFINES += "CUSTOM_TIMELIMIT_GLOBAL=$${escape_bracket}(20*CLOCKS_PER_SEC$${escape_bracket})"
|
||||
|
||||
# total time limit per "1 case" - forgotten char, double char, moved char and so on for all candidates. (default is CLOCKS_PER_SEC/10)
|
||||
DEFINES += "CUSTOM_TIMELIMIT_SUGGESTION=$${escape_bracket}(5*CLOCKS_PER_SEC$${escape_bracket})"
|
||||
|
||||
# time limit per candidate (default is CLOCKS_PER_SEC/20)
|
||||
DEFINES += "CUSTOM_TIMELIMIT=$${escape_bracket}(CLOCKS_PER_SEC$${escape_bracket}\)"
|
||||
|
||||
ADD_DEPENDENCY(UnicodeConverter kernel)
|
||||
|
||||
core_windows:LIBS += -lgdi32 -ladvapi32 -luser32 -lshell32
|
||||
|
||||
|
||||
@ -20,9 +20,9 @@ CONFIG_PREFIX=" --enable-extras=yes \
|
||||
--enable-dyload=no \
|
||||
--with-data-packaging=static"
|
||||
|
||||
CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums -fembed-bitcode"
|
||||
CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums"
|
||||
|
||||
CXXFLAGS="${CFLAGS} -std=c++11 -fembed-bitcode"
|
||||
CXXFLAGS="${CFLAGS} -std=c++11"
|
||||
|
||||
#will set value to 1
|
||||
defines_config_set_1=(
|
||||
@ -215,9 +215,9 @@ function build() {
|
||||
|
||||
export CXX="$(xcrun -find clang++)"
|
||||
export CC="$(xcrun -find clang)"
|
||||
export CFLAGS="-fembed-bitcode -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS $CFLAGS ${ADDITION_FLAG}"
|
||||
export CXXFLAGS="${CXXFLAGS} -fembed-bitcode -stdlib=libc++ -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS ${ADDITION_FLAG}"
|
||||
export LDFLAGS="-fembed-bitcode -stdlib=libc++ -L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip $IOS_MIN_VER -lstdc++ ${ADDITION_FLAG}"
|
||||
export CFLAGS="-isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS $CFLAGS ${ADDITION_FLAG}"
|
||||
export CXXFLAGS="${CXXFLAGS} -stdlib=libc++ -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS ${ADDITION_FLAG}"
|
||||
export LDFLAGS="-stdlib=libc++ -L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip $IOS_MIN_VER -lstdc++ ${ADDITION_FLAG}"
|
||||
|
||||
mkdir -p ${BUILD_DIR}
|
||||
cd ${BUILD_DIR}
|
||||
|
||||
@ -84,24 +84,24 @@ function set_ios_cpu_feature() {
|
||||
armv7)
|
||||
export CC="xcrun -sdk iphoneos clang -arch armv7"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch armv7"
|
||||
export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch armv7 -target armv7-ios-darwin -march=armv7 -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch armv7 -target armv7-ios-darwin -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
arm64)
|
||||
export CC="xcrun -sdk iphoneos clang -arch arm64"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch arm64"
|
||||
export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aarch64-ios-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-ios-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
arm64e)
|
||||
# -march=armv8.3 ???
|
||||
export CC="xcrun -sdk iphoneos clang -arch arm64e"
|
||||
export CXX="xcrun -sdk iphoneos clang++ -arch arm64e"
|
||||
export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -fembed-bitcode -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -fembed-bitcode -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch arm64e -target aarch64-ios-darwin -Wno-unused-function -fstrict-aliasing -DIOS -isysroot ${sysroot} -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64e -target aarch64-ios-darwin -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64e -target aarch64-ios-darwin -fstrict-aliasing -DIOS -miphoneos-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
i386)
|
||||
export CC="xcrun -sdk iphonesimulator clang -arch i386"
|
||||
@ -120,9 +120,9 @@ function set_ios_cpu_feature() {
|
||||
sim-arm64)
|
||||
export CC="xcrun -sdk iphonesimulator clang -arch arm64"
|
||||
export CXX="xcrun -sdk iphonesimulator clang++ -arch arm64"
|
||||
export CFLAGS="-arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -fembed-bitcode -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aaarch64-apple-darwin -march=armv8 -isysroot ${sysroot} -fembed-bitcode -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -fembed-bitcode -DIOS -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export CFLAGS="-arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -Wno-unused-function -fstrict-aliasing -Oz -Wno-ignored-optimization-argument -DIOS -isysroot ${sysroot} -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
export LDFLAGS="-arch arm64 -target aaarch64-apple-darwin -march=armv8 -isysroot ${sysroot} -L${sysroot}/usr/lib "
|
||||
export CXXFLAGS="-std=c++11 -arch arm64 -target aarch64-apple-darwin -march=armv8 -mcpu=generic -fstrict-aliasing -DIOS -mios-simulator-version-min=${ios_min_target} -I${sysroot}/usr/include"
|
||||
;;
|
||||
*)
|
||||
log_error "not support" && exit 1
|
||||
|
||||
@ -107,26 +107,26 @@ function configure_make() {
|
||||
|
||||
# openssl1.1.1d can be set normally, 1.1.0f does not take effect
|
||||
./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2
|
||||
sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
#sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
|
||||
elif [[ "${ARCH_NAME}" == "arm64" ]]; then
|
||||
|
||||
# openssl1.1.1d can be set normally, 1.1.0f does not take effect
|
||||
./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2
|
||||
sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
#sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
|
||||
elif [[ "${ARCH_NAME}" == "i386" ]]; then
|
||||
|
||||
# openssl1.1.1d can be set normally, 1.1.0f does not take effect
|
||||
./Configure darwin-i386-cc no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2
|
||||
sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
#sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
sed -i -e 's/-mtune=intel//g' "Makefile"
|
||||
|
||||
elif [[ "${ARCH_NAME}" == "sim_arm64" ]]; then
|
||||
|
||||
# openssl1.1.1d can be set normally, 1.1.0f does not take effect
|
||||
./Configure iphoneos-cross no-shared --prefix="${PREFIX_DIR}" enable-ssl3 enable-ssl3-method enable-md2
|
||||
sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
#sed -ie "s!-fno-common!-fno-common -fembed-bitcode !" "Makefile"
|
||||
|
||||
else
|
||||
log_error "not support" && exit 1
|
||||
|
||||
@ -238,11 +238,24 @@ bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwByt
|
||||
|
||||
if (NULL == pFirst)
|
||||
{
|
||||
//skip special
|
||||
_UINT16 sz = pBuffer[0] + (pBuffer[1] << 8);
|
||||
if (sz < dwBytes - 8)
|
||||
char* pData = (char*)pBuffer;
|
||||
for (int i = 0; i < dwBytes - 5; ++i)
|
||||
{
|
||||
pFirst = strstr((char*)(pBuffer + sz), "%PDF-");
|
||||
int nPDF = strncmp(&pData[i], "%PDF-", 5);
|
||||
if (!nPDF)
|
||||
{
|
||||
pFirst = (char*)pBuffer + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == pFirst)
|
||||
{
|
||||
//skip special
|
||||
_UINT16 sz = pBuffer[0] + (pBuffer[1] << 8);
|
||||
if (sz < dwBytes - 8)
|
||||
{
|
||||
pFirst = strstr((char*)(pBuffer + sz), "%PDF-");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NULL != pFirst)
|
||||
|
||||
@ -148,7 +148,7 @@ mac {
|
||||
CONFIG += core_mac
|
||||
CONFIG += core_mac_64
|
||||
|
||||
DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
|
||||
DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ core_mac {
|
||||
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
|
||||
QMAKE_LFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH
|
||||
|
||||
# xcode15 add new linker
|
||||
# xcode15 add new linker
|
||||
QMAKE_LFLAGS += -Wl,-ld_classic
|
||||
|
||||
QMAKE_CFLAGS += "-Wno-implicit-function-declaration"
|
||||
@ -301,22 +301,25 @@ linux_arm64 {
|
||||
core_ios {
|
||||
CORE_BUILDS_PLATFORM_PREFIX = ios
|
||||
|
||||
!versionAtLeast(QMAKE_XCODE_VERSION, 16.0) {
|
||||
QMAKE_CFLAGS += -fembed-bitcode
|
||||
QMAKE_CXXFLAGS += -fembed-bitcode
|
||||
QMAKE_LFLAGS += -fembed-bitcode
|
||||
} else {
|
||||
CONFIG -= bitcode
|
||||
}
|
||||
|
||||
|
||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator): {
|
||||
message("iphonesimulator")
|
||||
CORE_BUILDS_PLATFORM_PREFIX = ios_simulator
|
||||
|
||||
QMAKE_CFLAGS += -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
|
||||
|
||||
QMAKE_CFLAGS += -fembed-bitcode
|
||||
QMAKE_CXXFLAGS += -fembed-bitcode
|
||||
QMAKE_LFLAGS += -fembed-bitcode
|
||||
QMAKE_CFLAGS += -fobjc-arc
|
||||
QMAKE_CXXFLAGS += -fobjc-arc
|
||||
|
||||
@ -573,7 +576,7 @@ defineTest(ADD_DEPENDENCY) {
|
||||
libs = $$ARGS
|
||||
for(lib, libs) {
|
||||
CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH
|
||||
|
||||
|
||||
isEqual(lib, videoplayer) {
|
||||
libvlc {
|
||||
CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH/mediaplayer
|
||||
@ -586,7 +589,7 @@ defineTest(ADD_DEPENDENCY) {
|
||||
isEqual(lib, qtascdocumentscore):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp
|
||||
isEqual(lib, videoplayer):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp
|
||||
isEqual(lib, ooxmlsignature):CORE_BUILDS_LIBRARIES_PATH_DST=$$CORE_BUILDS_LIBRARIES_PATH_DST/xp
|
||||
}
|
||||
}
|
||||
!bundle_dylibs:LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH_DST -l$$lib
|
||||
bundle_dylibs:LIBS += -F$$CORE_BUILDS_LIBRARIES_PATH_DST -framework $$lib
|
||||
}
|
||||
|
||||
@ -250,3 +250,123 @@ namespace NSBase64
|
||||
return Base64DecodeBase(szSrc, nSrcLen, pbDest, pnDestLen);
|
||||
}
|
||||
}
|
||||
|
||||
#include <cstring>
|
||||
namespace NSBase32
|
||||
{
|
||||
const unsigned char PADDING_CHAR_32 = '=';
|
||||
|
||||
inline void pad(unsigned char* buf, int len)
|
||||
{
|
||||
for (int i = 0; i < len; i++)
|
||||
buf[i] = PADDING_CHAR_32;
|
||||
}
|
||||
inline unsigned char shift_right(unsigned char byte, signed char offset)
|
||||
{
|
||||
if (offset > 0)
|
||||
return byte >> offset;
|
||||
else
|
||||
return byte << -offset;
|
||||
}
|
||||
inline unsigned char shift_left(unsigned char byte, signed char offset)
|
||||
{
|
||||
return shift_right(byte, - offset);
|
||||
}
|
||||
|
||||
unsigned char encode_char(unsigned char c)
|
||||
{
|
||||
static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
return base32[c & 0x1F];
|
||||
}
|
||||
|
||||
int decode_char(unsigned char c)
|
||||
{
|
||||
char retval = -2;
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
retval = c - 'A';
|
||||
else if (c >= '2' && c <= '7')
|
||||
retval = c - '2' + 26;
|
||||
else if (c == PADDING_CHAR_32)
|
||||
retval = -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int decode_sequence(const unsigned char* coded, unsigned char* plain)
|
||||
{
|
||||
plain[0] = 0;
|
||||
for (int block = 0; block < 8; block++)
|
||||
{
|
||||
int offset = (8 - 5 - (5*block) % 8);
|
||||
int octet = (block*5) / 8;
|
||||
|
||||
int c = decode_char(coded[block]);
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
plain[octet] |= shift_left(c, offset);
|
||||
if (offset < 0)
|
||||
{ // does this block overflows to next octet?
|
||||
plain[octet+1] = shift_left(c, 8 + offset);
|
||||
}
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
|
||||
bool Decode(unsigned char* in, int inLen, unsigned char* out)
|
||||
{
|
||||
for (size_t i = 0, j = 0; (i + 8) <= inLen; i += 8, j += 5)
|
||||
{
|
||||
int n = decode_sequence(&in[i], &out[j]);
|
||||
if (n == -2)
|
||||
return false;
|
||||
if (n < 5)
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void encode_sequence(const unsigned char* plain, int len, unsigned char* coded)
|
||||
{
|
||||
for (int block = 0; block < 8; block++)
|
||||
{
|
||||
int octet = (block*5) / 8;
|
||||
int junk = (8 - 5 - (5*block) % 8);
|
||||
|
||||
if (octet >= len)
|
||||
{
|
||||
pad(&coded[block], 8 - block);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char c = shift_right(plain[octet], junk); // first part
|
||||
|
||||
if (junk < 0 // is there a second part?
|
||||
&& octet < len - 1) // is there still something to read?
|
||||
{
|
||||
c |= shift_right(plain[octet+1], 8 + junk);
|
||||
}
|
||||
coded[block] = encode_char(c);
|
||||
}
|
||||
}
|
||||
|
||||
bool Encode(unsigned char* src, int len, unsigned char* dst)
|
||||
{
|
||||
for (int i = 0, j = 0; i < len; i += 5, j += 8)
|
||||
{
|
||||
int tmpLen = len - i;
|
||||
encode_sequence(&src[i], tmpLen > 5 ? 5 : tmpLen, &dst[j]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int DecodeGetRequiredLength(int bytes)
|
||||
{
|
||||
return (((bytes)/8)*5);
|
||||
}
|
||||
int EncodeGetRequiredLength(int bytes)
|
||||
{
|
||||
return (((bytes)/5)*8 + ((bytes) % 5 ? 8 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,4 +58,13 @@ namespace NSBase64
|
||||
KERNEL_DECL int Base64Decode(const wchar_t* szSrc, int nSrcLen, BYTE *pbDest, int *pnDestLen);
|
||||
}
|
||||
|
||||
namespace NSBase32
|
||||
{
|
||||
KERNEL_DECL bool Decode(unsigned char* in, int inLen, unsigned char* out);
|
||||
KERNEL_DECL bool Encode(unsigned char* in, int inLen, unsigned char* out);
|
||||
|
||||
KERNEL_DECL int DecodeGetRequiredLength(int bytes);
|
||||
KERNEL_DECL int EncodeGetRequiredLength(int bytes);
|
||||
}
|
||||
|
||||
#endif//_BUILD_BASE64_CROSSPLATFORM_DEFINE
|
||||
|
||||
@ -648,7 +648,7 @@ namespace NSStringUtils
|
||||
}
|
||||
void CStringBuilder::AddInt(int val)
|
||||
{
|
||||
AddSize(10);
|
||||
AddSize(11);
|
||||
AddIntNoCheck(val);
|
||||
}
|
||||
void CStringBuilder::AddUInt(unsigned int val)
|
||||
@ -683,6 +683,9 @@ namespace NSStringUtils
|
||||
if (val < 0)
|
||||
{
|
||||
val = -val;
|
||||
if (val < 0)
|
||||
val = 2147483647;
|
||||
|
||||
*m_pDataCur++ = (wchar_t)'-';
|
||||
++m_lSizeCur;
|
||||
}
|
||||
|
||||
@ -145,13 +145,23 @@ namespace NSDoctRenderer
|
||||
NSHyphen::CEngine::Init(private_GetFile(sConfigDir, oNodeDict.GetText()));
|
||||
}
|
||||
|
||||
bool bIsAbsoluteFontsPath = false;
|
||||
if (!m_bIsNotUseConfigAllFontsDir)
|
||||
{
|
||||
std::wstring sAllFontsPath = oNode.ReadNodeText(L"allfonts");
|
||||
if (!sAllFontsPath.empty())
|
||||
{
|
||||
m_strAllFonts = private_GetFile(sConfigDir, sAllFontsPath);
|
||||
if (NSFile::CFileBinary::Exists(sConfigDir + sAllFontsPath))
|
||||
m_strAllFonts = sConfigDir + sAllFontsPath;
|
||||
else if (NSFile::CFileBinary::Exists(sAllFontsPath))
|
||||
m_strAllFonts = sAllFontsPath;
|
||||
else
|
||||
{
|
||||
std::wstring sAllFontsDir = NSFile::GetDirectoryName(sAllFontsPath);
|
||||
if (NSDirectory::Exists(sConfigDir + sAllFontsDir))
|
||||
m_strAllFonts = sConfigDir + sAllFontsPath;
|
||||
else
|
||||
m_strAllFonts = sAllFontsPath;
|
||||
}
|
||||
|
||||
// на папку может не быть прав
|
||||
if (!NSFile::CFileBinary::Exists(m_strAllFonts))
|
||||
@ -163,20 +173,16 @@ namespace NSDoctRenderer
|
||||
if (NSDirectory::CreateDirectory(sAppDir + L"/docbuilder"))
|
||||
{
|
||||
m_strAllFonts = sAppDir + L"/docbuilder/AllFonts.js";
|
||||
// файл может не существовать пока - и тогда private_GetFile не учтет его
|
||||
bIsAbsoluteFontsPath = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(pFileNative);
|
||||
NSFile::CFileBinary::Remove(m_strAllFonts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bIsAbsoluteFontsPath)
|
||||
m_strAllFonts = private_GetFile(sConfigDir, m_strAllFonts);
|
||||
}
|
||||
|
||||
m_strSdkPath = oNode.ReadNodeText(L"sdkjs");
|
||||
|
||||
@ -83,6 +83,10 @@ public class CDocBuilder {
|
||||
return new CDocBuilderContext(c_GetContext(c_internal));
|
||||
}
|
||||
|
||||
public CDocBuilderContext getContext(boolean enterContext) {
|
||||
return new CDocBuilderContext(c_GetContextWithEnterParam(c_internal, enterContext));
|
||||
}
|
||||
|
||||
public static void initialize() {
|
||||
c_Initialize();
|
||||
}
|
||||
@ -135,6 +139,7 @@ public class CDocBuilder {
|
||||
private static native String c_GetVersion(long self);
|
||||
|
||||
private static native long c_GetContext(long self);
|
||||
private static native long c_GetContextWithEnterParam(long self, boolean enterContext);
|
||||
|
||||
private static native void c_Initialize();
|
||||
private static native void c_InitializeWithDirectory(String directory);
|
||||
|
||||
@ -40,7 +40,7 @@ public class NativeLibraryLoader {
|
||||
throw new RuntimeException("Unsupported OS");
|
||||
}
|
||||
|
||||
String[] libs = {"UnicodeConverter", "kernel", "kernel_network", "graphics", "doctrenderer", "docbuilder.jni"};
|
||||
String[] libs = {"UnicodeConverter", "kernel", "kernel_network", "graphics", "PdfFile", "XpsFile", "DjVuFile", "DocxRenderer", "doctrenderer", "docbuilder.jni"};
|
||||
|
||||
String prefix = "";
|
||||
if (OSChecker.isMac() || OSChecker.isLinux()) {
|
||||
|
||||
@ -162,6 +162,12 @@ jlong Java_docbuilder_CDocBuilder_c_1GetContext(JNIEnv* env, jclass cls, jlong s
|
||||
return reinterpret_cast<jlong>(new CDocBuilderContext(pSelf->GetContext()));
|
||||
}
|
||||
|
||||
jlong Java_docbuilder_CDocBuilder_c_1GetContextWithEnterParam(JNIEnv* env, jclass cls, jlong self, jboolean enterContext)
|
||||
{
|
||||
CDocBuilder* pSelf = reinterpret_cast<CDocBuilder*>(self);
|
||||
return reinterpret_cast<jlong>(new CDocBuilderContext(pSelf->GetContext((bool)enterContext)));
|
||||
}
|
||||
|
||||
void Java_docbuilder_CDocBuilder_c_1Initialize(JNIEnv* env, jclass cls)
|
||||
{
|
||||
CDocBuilder::Initialize();
|
||||
|
||||
@ -167,6 +167,14 @@ JNIEXPORT jstring JNICALL Java_docbuilder_CDocBuilder_c_1GetVersion
|
||||
JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilder_c_1GetContext
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: docbuilder_CDocBuilder
|
||||
* Method: c_GetContextWithEnterParam
|
||||
* Signature: (JZ)J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_docbuilder_CDocBuilder_c_1GetContextWithEnterParam
|
||||
(JNIEnv *, jclass, jlong, jboolean);
|
||||
|
||||
/*
|
||||
* Class: docbuilder_CDocBuilder
|
||||
* Method: c_Initialize
|
||||
|
||||
@ -17,7 +17,6 @@ public class Program {
|
||||
builder.createFile(FileTypes.Document.DOCX);
|
||||
|
||||
CDocBuilderContext context = builder.getContext();
|
||||
CDocBuilderContextScope scope = context.createScope();
|
||||
|
||||
CDocBuilderValue global = context.getGlobal();
|
||||
|
||||
|
||||
@ -203,7 +203,7 @@ def _loadLibrary(path):
|
||||
_lib.CDocBuilder_GetVersion.argtypes = [OBJECT_HANDLE]
|
||||
_lib.CDocBuilder_GetVersion.restype = STRING_HANDLE
|
||||
|
||||
_lib.CDocBuilder_GetContext.argtypes = [OBJECT_HANDLE]
|
||||
_lib.CDocBuilder_GetContext.argtypes = [OBJECT_HANDLE, ctypes.c_bool]
|
||||
_lib.CDocBuilder_GetContext.restype = OBJECT_HANDLE
|
||||
|
||||
_lib.CDocBuilder_Initialize.argtypes = []
|
||||
@ -492,8 +492,8 @@ class CDocBuilder:
|
||||
_lib.DeleteCharP(ctypes.cast(strVersion, ctypes.c_char_p))
|
||||
return version
|
||||
|
||||
def GetContext(self):
|
||||
return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal)))
|
||||
def GetContext(self, enterContext=True):
|
||||
return CDocBuilderContext(OBJECT_HANDLE(_lib.CDocBuilder_GetContext(self._internal, ctypes.c_bool(enterContext))))
|
||||
|
||||
@classmethod
|
||||
def Initialize(cls, directory=None):
|
||||
|
||||
@ -301,9 +301,9 @@ char* CDocBuilder_GetVersion(CDocBuilder* self)
|
||||
return self->GetVersion();
|
||||
}
|
||||
|
||||
CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self)
|
||||
CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self, bool enterContext)
|
||||
{
|
||||
return new CDocBuilderContext(self->GetContext());
|
||||
return new CDocBuilderContext(self->GetContext(enterContext));
|
||||
}
|
||||
|
||||
void CDocBuilder_Initialize()
|
||||
|
||||
@ -97,7 +97,7 @@ DOCBUILDER_FUNC_DECL bool CDocBuilder_IsSaveWithDoctrendererMode(CDocBuilder* se
|
||||
|
||||
DOCBUILDER_FUNC_DECL char* CDocBuilder_GetVersion(CDocBuilder* self);
|
||||
|
||||
DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self);
|
||||
DOCBUILDER_FUNC_DECL CDocBuilderContext* CDocBuilder_GetContext(CDocBuilder* self, bool enterContext);
|
||||
|
||||
DOCBUILDER_FUNC_DECL void CDocBuilder_Initialize();
|
||||
DOCBUILDER_FUNC_DECL void CDocBuilder_InitializeWithDirectory(const wchar_t* directory);
|
||||
|
||||
@ -728,22 +728,13 @@ namespace NSDoctRenderer
|
||||
oBuilder.WriteEncodeXmlString(sFolder);
|
||||
oBuilder.WriteString(L"/Editor.bin</m_sFileTo><m_nFormatTo>8192</m_nFormatTo>");
|
||||
|
||||
if (!m_bIsNotUseConfigAllFontsDir)
|
||||
{
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common");
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts));
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts));
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
|
||||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||||
}
|
||||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||||
|
||||
oBuilder.WriteString(L"<m_bIsNoBase64>true</m_bIsNoBase64>");
|
||||
oBuilder.WriteString(L"<m_sThemeDir>./sdkjs/slide/themes</m_sThemeDir><m_bDontSaveAdditional>true</m_bDontSaveAdditional>");
|
||||
@ -1054,22 +1045,13 @@ namespace NSDoctRenderer
|
||||
oBuilder.WriteString(L"</m_sThemeDir><m_bFromChanges>true</m_bFromChanges><m_bDontSaveAdditional>true</m_bDontSaveAdditional>");
|
||||
oBuilder.WriteString(L"<m_nCsvTxtEncoding>46</m_nCsvTxtEncoding><m_nCsvDelimiter>4</m_nCsvDelimiter>");
|
||||
|
||||
if (!m_bIsNotUseConfigAllFontsDir)
|
||||
{
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(m_sX2tPath + L"/sdkjs/common");
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
}
|
||||
else
|
||||
{
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts));
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
oBuilder.WriteString(L"<m_sFontDir>");
|
||||
oBuilder.WriteEncodeXmlString(NSFile::GetDirectoryName(m_strAllFonts));
|
||||
oBuilder.WriteString(L"</m_sFontDir>");
|
||||
|
||||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||||
}
|
||||
oBuilder.WriteString(L"<m_sAllFontsPath>");
|
||||
oBuilder.WriteEncodeXmlString(m_strAllFonts);
|
||||
oBuilder.WriteString(L"</m_sAllFontsPath>");
|
||||
|
||||
if (!sConvertionParams.empty())
|
||||
{
|
||||
|
||||
@ -445,7 +445,7 @@ namespace NSDoctRenderer
|
||||
strError = L"code=\"save\"";
|
||||
bIsBreak = true;
|
||||
}
|
||||
else
|
||||
else if (!js_result2->isNull())
|
||||
{
|
||||
JSSmart<CJSTypedArray> typedArray = js_result2->toTypedArray();
|
||||
NSJSBase::CJSDataBuffer oBuffer = typedArray->getData();
|
||||
|
||||
@ -42,6 +42,8 @@
|
||||
#include "../../HtmlRenderer/include/HTMLRendererText.h"
|
||||
#include "../../DocxRenderer/DocxRenderer.h"
|
||||
|
||||
#define CHECKER_FILE_BUFFER_LEN 4096
|
||||
|
||||
class CDrawingFile
|
||||
{
|
||||
private:
|
||||
@ -122,18 +124,38 @@ public:
|
||||
{
|
||||
CloseFile();
|
||||
|
||||
if (NULL == m_pFile)
|
||||
int nType = DetectFormat(sFile);
|
||||
|
||||
switch (nType)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_pFile = new CPdfFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword))
|
||||
{
|
||||
if (4 != ((CPdfFile*)m_pFile)->GetError())
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
m_pFile = new CDjVuFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword))
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
m_nType = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL == m_pFile)
|
||||
case 2:
|
||||
{
|
||||
m_pFile = new CXpsFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword))
|
||||
@ -143,16 +165,8 @@ public:
|
||||
else
|
||||
m_nType = 2;
|
||||
}
|
||||
|
||||
if (NULL == m_pFile)
|
||||
{
|
||||
m_pFile = new CDjVuFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword))
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return m_pFile ? true : false;
|
||||
@ -162,37 +176,48 @@ public:
|
||||
{
|
||||
CloseFile();
|
||||
|
||||
if (NULL == m_pFile)
|
||||
int nType = DetectFormat(data, size);
|
||||
switch (nType)
|
||||
{
|
||||
m_pFile = new CPdfFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
case 0:
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
m_pFile = new CPdfFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
{
|
||||
if (4 != ((CPdfFile*)m_pFile)->GetError())
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
m_nType = 0;
|
||||
}
|
||||
|
||||
if (NULL == m_pFile)
|
||||
{
|
||||
m_pFile = new CXpsFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
case 1:
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
m_pFile = new CDjVuFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
m_nType = 2;
|
||||
}
|
||||
|
||||
if (NULL == m_pFile)
|
||||
{
|
||||
m_pFile = new CDjVuFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
case 2:
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
m_pFile = new CXpsFile(m_pApplicationFonts);
|
||||
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
|
||||
{
|
||||
RELEASEOBJECT(m_pFile);
|
||||
}
|
||||
else
|
||||
m_nType = 2;
|
||||
}
|
||||
else
|
||||
m_nType = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return m_pFile ? true : false;
|
||||
@ -484,6 +509,14 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::wstring GetFontBinaryNative(const std::wstring& sName)
|
||||
{
|
||||
if (0 != m_nType)
|
||||
return L"";
|
||||
|
||||
return ((CPdfFile*)m_pFile)->GetEmbeddedFontPath(sName);
|
||||
}
|
||||
|
||||
private:
|
||||
int GetPagesCount()
|
||||
{
|
||||
@ -514,7 +547,44 @@ private:
|
||||
nPageDpiX = dPageDpiX;
|
||||
}
|
||||
|
||||
int DetectFormat(const std::wstring& sFile)
|
||||
{
|
||||
NSFile::CFileBinary oFile;
|
||||
if (oFile.OpenFile(sFile))
|
||||
{
|
||||
LONG size = oFile.GetFileSize();
|
||||
if (size > CHECKER_FILE_BUFFER_LEN)
|
||||
size = CHECKER_FILE_BUFFER_LEN;
|
||||
|
||||
BYTE* data = new BYTE[size];
|
||||
oFile.ReadFile(data, size);
|
||||
|
||||
int nType = DetectFormat(data, size);
|
||||
|
||||
RELEASEARRAYOBJECTS(data);
|
||||
return nType;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DetectFormat(BYTE* data, LONG size)
|
||||
{
|
||||
// 0 - PDF
|
||||
// 1 - DJVU
|
||||
// 2 - XPS
|
||||
LONG nSize = size < CHECKER_FILE_BUFFER_LEN ? size : CHECKER_FILE_BUFFER_LEN;
|
||||
char* pData = (char*)data;
|
||||
for (int i = 0; i < nSize - 5; ++i)
|
||||
{
|
||||
int nPDF = strncmp(&pData[i], "%PDF-", 5);
|
||||
if (!nPDF)
|
||||
return 0;
|
||||
}
|
||||
if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] &&
|
||||
0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7]))
|
||||
return 1;
|
||||
return 2;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DRAWINGFILE_H
|
||||
|
||||
@ -71,6 +71,19 @@ JSSmart<CJSValue> CDrawingFileEmbed::DestroyPixmap(JSSmart<CJSValue> typedArray)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSSmart<CJSValue> CDrawingFileEmbed::GetFontBinary(JSSmart<CJSValue> Id)
|
||||
{
|
||||
if (0 != m_pFile->GetType())
|
||||
return NULL;
|
||||
|
||||
std::wstring sName = Id->toStringW();
|
||||
std::wstring sFile = m_pFile->GetFontBinaryNative(sName);
|
||||
if (sFile.empty())
|
||||
return NULL;
|
||||
|
||||
return CJSContext::createUint8Array(sFile);
|
||||
}
|
||||
|
||||
JSSmart<CJSValue> CDrawingFileEmbed::GetGlyphs(JSSmart<CJSValue> nPageIndex)
|
||||
{
|
||||
return WasmMemoryToJS(m_pFile->GetGlyphs(nPageIndex->toInt32()));
|
||||
|
||||
@ -40,6 +40,7 @@ public:
|
||||
JSSmart<CJSValue> GetAnnotationsInfo(JSSmart<CJSValue> nPageIndex);
|
||||
JSSmart<CJSValue> GetAnnotationsAP(JSSmart<CJSValue> nRasterW, JSSmart<CJSValue> nRasterH, JSSmart<CJSValue> nBackgroundColor, JSSmart<CJSValue> nPageIndex, JSSmart<CJSValue> nAnnot, JSSmart<CJSValue> nView);
|
||||
|
||||
JSSmart<CJSValue> GetFontBinary(JSSmart<CJSValue> Id);
|
||||
JSSmart<CJSValue> GetGlyphs(JSSmart<CJSValue> nPageIndex);
|
||||
JSSmart<CJSValue> DestroyTextInfo();
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
-(JSValue*) GetButtonIcons : (JSValue*)nBackgroundColor : (JSValue*)nPageIndex : (JSValue*)bBase64 : (JSValue*)nButtonWidget : (JSValue*)nIconView;
|
||||
-(JSValue*) GetAnnotationsInfo : (JSValue*)nPageIndex;
|
||||
-(JSValue*) GetAnnotationsAP : (JSValue*)nRasterW : (JSValue*)nRasterH : (JSValue*)nBackgroundColor : (JSValue*)nPageIndex : (JSValue*)nAnnot : (JSValue*)nView;
|
||||
-(JSValue*) GetFontBinary : (JSValue*)Id;
|
||||
-(JSValue*) GetGlyphs : (JSValue*)nPageIndex;
|
||||
-(JSValue*) DestroyTextInfo;
|
||||
-(JSValue*) IsNeedCMap;
|
||||
@ -53,6 +54,7 @@ FUNCTION_WRAPPER_JS_7(GetInteractiveFormsAP, GetInteractiveFormsAP)
|
||||
FUNCTION_WRAPPER_JS_5(GetButtonIcons, GetButtonIcons)
|
||||
FUNCTION_WRAPPER_JS_1(GetAnnotationsInfo, GetAnnotationsInfo)
|
||||
FUNCTION_WRAPPER_JS_6(GetAnnotationsAP, GetAnnotationsAP)
|
||||
FUNCTION_WRAPPER_JS_1(GetFontBinary, GetFontBinary)
|
||||
FUNCTION_WRAPPER_JS_1(GetGlyphs, GetGlyphs)
|
||||
FUNCTION_WRAPPER_JS_0(DestroyTextInfo, DestroyTextInfo)
|
||||
FUNCTION_WRAPPER_JS_0(IsNeedCMap, IsNeedCMap)
|
||||
|
||||
@ -23,6 +23,7 @@ namespace NSDrawingFileEmbed
|
||||
FUNCTION_WRAPPER_V8_5(_GetButtonIcons, GetButtonIcons)
|
||||
FUNCTION_WRAPPER_V8_1(_GetAnnotationsInfo, GetAnnotationsInfo)
|
||||
FUNCTION_WRAPPER_V8_6(_GetAnnotationsAP, GetAnnotationsAP)
|
||||
FUNCTION_WRAPPER_V8_1(_GetFontBinary, GetFontBinary)
|
||||
FUNCTION_WRAPPER_V8_1(_GetGlyphs, GetGlyphs)
|
||||
FUNCTION_WRAPPER_V8_0(_DestroyTextInfo, DestroyTextInfo)
|
||||
FUNCTION_WRAPPER_V8_0(_IsNeedCMap, IsNeedCMap)
|
||||
@ -51,6 +52,7 @@ namespace NSDrawingFileEmbed
|
||||
NSV8Objects::Template_Set(result, "GetButtonIcons", _GetButtonIcons);
|
||||
NSV8Objects::Template_Set(result, "GetAnnotationsInfo", _GetAnnotationsInfo);
|
||||
NSV8Objects::Template_Set(result, "GetAnnotationsAP", _GetAnnotationsAP);
|
||||
NSV8Objects::Template_Set(result, "GetFontBinary", _GetFontBinary);
|
||||
NSV8Objects::Template_Set(result, "GetGlyphs", _GetGlyphs);
|
||||
NSV8Objects::Template_Set(result, "DestroyTextInfo", _DestroyTextInfo);
|
||||
NSV8Objects::Template_Set(result, "IsNeedCMap", _IsNeedCMap);
|
||||
|
||||
@ -991,67 +991,76 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N
|
||||
#define PROPERTY_GET(NAME, NAME_EMBED) \
|
||||
void NAME(v8::Local<v8::String> _name, const v8::PropertyCallbackInfo<v8::Value>& info) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(info.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(info.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(); \
|
||||
js_return(info, ret); \
|
||||
}
|
||||
|
||||
#define FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(); \
|
||||
js_return(args, ret); \
|
||||
#define FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
|
||||
#define FUNCTION_WRAPPER_V8(NAME, NAME_EMBED) FUNCTION_WRAPPER_V8_0(NAME, NAME_EMBED)
|
||||
|
||||
#define FUNCTION_WRAPPER_V8_1(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0])); \
|
||||
js_return(args, ret); \
|
||||
#define FUNCTION_WRAPPER_V8_1(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_2(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1])); \
|
||||
js_return(args, ret); \
|
||||
#define FUNCTION_WRAPPER_V8_2(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_3(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_4(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_5(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_6(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5])); \
|
||||
js_return(args, ret); \
|
||||
}
|
||||
#define FUNCTION_WRAPPER_V8_7(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \
|
||||
js_value(args[5]), js_value(args[6])); \
|
||||
js_return(args, ret); \
|
||||
@ -1059,7 +1068,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N
|
||||
#define FUNCTION_WRAPPER_V8_8(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \
|
||||
js_value(args[5]), js_value(args[6]), js_value(args[7])); \
|
||||
js_return(args, ret); \
|
||||
@ -1067,7 +1077,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N
|
||||
#define FUNCTION_WRAPPER_V8_9(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), \
|
||||
js_value(args[5]), js_value(args[6]), js_value(args[7]), js_value(args[8])); \
|
||||
js_return(args, ret); \
|
||||
@ -1075,7 +1086,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N
|
||||
#define FUNCTION_WRAPPER_V8_10(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5]), \
|
||||
js_value(args[6]), js_value(args[7]), js_value(args[8]), js_value(args[9])); \
|
||||
js_return(args, ret); \
|
||||
@ -1083,7 +1095,8 @@ inline void js_return(const v8::PropertyCallbackInfo<v8::Value>& info, JSSmart<N
|
||||
#define FUNCTION_WRAPPER_V8_13(NAME, NAME_EMBED) \
|
||||
void NAME(const v8::FunctionCallbackInfo<v8::Value>& args) \
|
||||
{ \
|
||||
CURRENTWRAPPER* _this = (CURRENTWRAPPER*)unwrap_native(args.Holder()); \
|
||||
CURRENTWRAPPER* _this = dynamic_cast<CURRENTWRAPPER*>(unwrap_native(args.Holder())); \
|
||||
if (!_this) return; \
|
||||
JSSmart<CJSValue> ret = _this->NAME_EMBED(js_value(args[0]), js_value(args[1]), js_value(args[2]), js_value(args[3]), js_value(args[4]), js_value(args[5]), \
|
||||
js_value(args[6]), js_value(args[7]), js_value(args[8]), js_value(args[9]), js_value(args[10]), js_value(args[11]), \
|
||||
js_value(args[12])); \
|
||||
|
||||
@ -109,7 +109,7 @@ FT_Error FT_Load_Glyph_Wrapper( FT_Face face,
|
||||
FT_Err_Invalid_Reference = 0x86;
|
||||
*/
|
||||
|
||||
if ((bHintsSupport == TRUE) && ((nErr > 0x10 && nErr < 0x28) || nErr == 0x83 || nErr == 0x86))
|
||||
if ((bHintsSupport == TRUE) && ((nErr > 0x10 && nErr < 0x28) || (nErr >= 0x83 && nErr <= 0x8D)))
|
||||
{
|
||||
int nErr2 = FT_Load_Glyph(face, glyph_index, 40970);
|
||||
|
||||
|
||||
1935
DesktopEditor/graphics/BooleanOperations.cpp
Normal file
1935
DesktopEditor/graphics/BooleanOperations.cpp
Normal file
File diff suppressed because it is too large
Load Diff
178
DesktopEditor/graphics/BooleanOperations.h
Normal file
178
DesktopEditor/graphics/BooleanOperations.h
Normal file
@ -0,0 +1,178 @@
|
||||
#ifndef BOOLEANOPERATIONS_H
|
||||
#define BOOLEANOPERATIONS_H
|
||||
|
||||
#include "GraphicsPath.h"
|
||||
#include <memory>
|
||||
|
||||
namespace Aggplus
|
||||
{
|
||||
struct Location;
|
||||
|
||||
struct Segment
|
||||
{
|
||||
PointD P{};
|
||||
PointD HI{};
|
||||
PointD HO{};
|
||||
|
||||
bool IsCurve = false;
|
||||
bool Visited = false;
|
||||
bool PolyClosed = false;
|
||||
|
||||
int Index = -1;
|
||||
int Id = 0;
|
||||
int Winding = 0;
|
||||
|
||||
std::shared_ptr<Location> Inters{nullptr};
|
||||
|
||||
Segment() noexcept;
|
||||
Segment(const std::vector<PointD>& points, const bool& isCurve,
|
||||
const int& index, const int& id, const bool& polyClosed) noexcept;
|
||||
Segment(const PointD& point, const bool& isCurve, const int& index,
|
||||
const int& id, const bool& polyClosed) noexcept;
|
||||
Segment(const PointD& p) noexcept;
|
||||
Segment(const PointD& p, const PointD& hi, const PointD& ho) noexcept;
|
||||
|
||||
void SetHandles(const PointD& hi, const PointD& ho) noexcept;
|
||||
void UpdateHandles(const PointD& hi, const PointD& ho) noexcept;
|
||||
|
||||
bool IsValid(const BooleanOpType& op) const noexcept;
|
||||
bool IsEmpty() const noexcept;
|
||||
bool operator==(const Segment& other) const noexcept;
|
||||
bool operator!=(const Segment& other) const noexcept;
|
||||
};
|
||||
|
||||
struct Curve
|
||||
{
|
||||
Segment Segment1{};
|
||||
Segment Segment2{};
|
||||
|
||||
Curve() noexcept;
|
||||
Curve(const Segment& segment1, const Segment& segment2) noexcept;
|
||||
Curve(const std::vector<double>& values) noexcept;
|
||||
Curve(const double& x0, const double& y0, const double& x1, const double& y1,
|
||||
const double& x2, const double& y2, const double& x3, const double& y3) noexcept;
|
||||
|
||||
std::vector<double> GetXValues() const noexcept;
|
||||
std::vector<double> GetYValues() const noexcept;
|
||||
std::vector<double> GetPeeks() const;
|
||||
double GetLength(double a = 0, double b = 1) const;
|
||||
double GetSquaredLineLength() const noexcept;
|
||||
double GetTimeOf(const PointD& point) const noexcept;
|
||||
double GetTimeAt(const double& offset) const noexcept;
|
||||
PointD Get(const double& t, const int& type) const noexcept;
|
||||
PointD GetPoint(const double& t) const noexcept;
|
||||
PointD GetTangent(const double& t) const noexcept;
|
||||
PointD GetTangent(const double& t, const double& offset,
|
||||
const bool& inside, const PointD& p) const noexcept;
|
||||
Curve GetPart(double from, double to) const noexcept;
|
||||
std::vector<Curve> GetMonoCurves(const bool& dir) const noexcept;
|
||||
std::vector<double> GetCurveLineIntersection(const double& px, const double& py,
|
||||
const double& vx, const double& vy) const noexcept;
|
||||
std::vector<std::pair<double, double>> GetOverlaps(const Curve& curve) const noexcept;
|
||||
|
||||
std::vector<Curve> Subdivide(const double& t) const noexcept;
|
||||
Curve DivideAtTime(const double& time) noexcept;
|
||||
|
||||
int SolveCubic(const int& coord, const double& value, std::vector<double>& roots,
|
||||
const double& mn, const double& mx) const noexcept;
|
||||
int SolveCubic(double a, double b, double c, double d, std::vector<double>& roots,
|
||||
const double& mn, const double& mx) const noexcept;
|
||||
|
||||
void Flip() noexcept;
|
||||
|
||||
bool IsStraight() const noexcept;
|
||||
bool HasHandle() const noexcept;
|
||||
bool operator==(const Curve& other) const noexcept;
|
||||
bool operator!=(const Curve& other) const noexcept;
|
||||
};
|
||||
|
||||
struct Location
|
||||
{
|
||||
Curve C{};
|
||||
Segment S{};
|
||||
double Time = -1.0;
|
||||
bool Overlap = false;
|
||||
bool Ends = false;
|
||||
|
||||
std::shared_ptr<Location> Inters{nullptr};
|
||||
std::shared_ptr<Location> Next{nullptr};
|
||||
std::shared_ptr<Location> Prev{nullptr};
|
||||
|
||||
Location() noexcept;
|
||||
Location(const Curve& curve, const double& time, const bool& overlap, const bool& ends) noexcept;
|
||||
|
||||
bool IsTouching() noexcept;
|
||||
};
|
||||
|
||||
class CBooleanOperations
|
||||
{
|
||||
public:
|
||||
CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op);
|
||||
~CBooleanOperations();
|
||||
CGraphicsPath&& GetResult();
|
||||
|
||||
// BooleanOp
|
||||
void TraceBoolean();
|
||||
void TraceOneInters();
|
||||
void TraceAllOverlap();
|
||||
void TracePaths();
|
||||
|
||||
// Path
|
||||
void PreparePath(const CGraphicsPath& path, int id, std::vector<Segment>& segments,
|
||||
std::vector<Curve>& curves, bool reverse = false);
|
||||
void InsertSegment(Segment& segment, const Segment& handles, bool updateHandles);
|
||||
Curve GetCurve(const Segment& segment) const noexcept;
|
||||
Curve GetPreviousCurve(const Curve& curve) const noexcept;
|
||||
Curve GetNextCurve(const Curve& curve) const noexcept;
|
||||
Segment GetNextSegment(const Segment& segment) const noexcept;
|
||||
void SetVisited(const Segment& segment);
|
||||
|
||||
// Bounds
|
||||
std::vector<std::vector<double>> GetBoundsForCurves(const std::vector<Curve>& curves) const noexcept;
|
||||
std::vector<std::vector<int>> FindBoundsCollisions();
|
||||
|
||||
// Intersection
|
||||
bool IsCrossing(std::shared_ptr<Location> loc) noexcept;
|
||||
bool FilterIntersections(std::shared_ptr<Location> loc) noexcept;
|
||||
bool IntersectsBounds() noexcept;
|
||||
void GetIntersection();
|
||||
void GetCurveIntersection(const Curve& curve1, const Curve& curve2);
|
||||
void LinkIntersection(std::shared_ptr<Location> form, std::shared_ptr<Location> to);
|
||||
void AddLineIntersection(const Curve& curve1, const Curve& curve2);
|
||||
void AddCurveLineIntersection(const Curve& curve1, const Curve& curve2, bool flip);
|
||||
int AddCurveIntersection(const Curve& curve1, const Curve& curve2, const Curve& startCurve1, const Curve& startCurve2, bool flip,
|
||||
int recursion = 0, int calls = 0, double tMin = 0.0, double tMax = 1.0, double uMin = 0.0, double uMax = 1.0);
|
||||
int CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const;
|
||||
void SetWinding();
|
||||
|
||||
// Location
|
||||
void DivideLocations();
|
||||
void AddLocation(Curve curve1, Curve curve2, double t1, double t2, bool overlap = false, bool filter = true, bool bothEnds = false);
|
||||
void InsertLocation(std::shared_ptr<Location> loc, bool overlap);
|
||||
bool AllOverlap() const noexcept;
|
||||
bool AllInters(const std::vector<Segment>& segments) const noexcept;
|
||||
void AddOffsets(std::vector<double>& offsets, const Curve& curve, bool end);
|
||||
|
||||
private:
|
||||
BooleanOpType Op = Intersection;
|
||||
|
||||
bool Close1 = true;
|
||||
bool Close2 = true;
|
||||
|
||||
CGraphicsPath Path1;
|
||||
CGraphicsPath Path2;
|
||||
CGraphicsPath Result;
|
||||
|
||||
std::vector<Segment> Segments1;
|
||||
std::vector<Segment> Segments2;
|
||||
|
||||
std::vector<Curve> OriginCurves1;
|
||||
std::vector<Curve> OriginCurves2;
|
||||
std::vector<Curve> Curves1;
|
||||
std::vector<Curve> Curves2;
|
||||
|
||||
std::vector<std::shared_ptr<Location>> Locations;
|
||||
};
|
||||
} // namespace Aggplus
|
||||
|
||||
#endif // BOOLEANOPERATIONS_H
|
||||
File diff suppressed because it is too large
Load Diff
@ -42,125 +42,155 @@
|
||||
|
||||
namespace Aggplus
|
||||
{
|
||||
class CGraphicsPath_private;
|
||||
class GRAPHICS_DECL CGraphicsPath : public NSFonts::ISimpleGraphicsPath
|
||||
{
|
||||
public:
|
||||
CGraphicsPath();
|
||||
~CGraphicsPath();
|
||||
class CGraphicsPath_private;
|
||||
class GRAPHICS_DECL CGraphicsPath : public NSFonts::ISimpleGraphicsPath
|
||||
{
|
||||
public:
|
||||
CGraphicsPath();
|
||||
CGraphicsPath(const CGraphicsPath& other) noexcept;
|
||||
CGraphicsPath(CGraphicsPath&& other) noexcept;
|
||||
CGraphicsPath(const std::vector<CGraphicsPath>& paths) noexcept;
|
||||
virtual ~CGraphicsPath();
|
||||
|
||||
CGraphicsPath* Clone();
|
||||
CGraphicsPath* Clone();
|
||||
|
||||
Status Reset();
|
||||
void SetRuler(bool bEvenOdd);
|
||||
Status Reset();
|
||||
void SetRuler(bool bEvenOdd);
|
||||
|
||||
Status StartFigure();
|
||||
Status CloseFigure();
|
||||
bool Is_poly_closed();
|
||||
Status MoveTo(double x, double y);
|
||||
Status LineTo(double x, double y);
|
||||
Status CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
Status StartFigure();
|
||||
Status CloseFigure();
|
||||
bool Is_poly_closed() const;
|
||||
Status MoveTo(double x, double y);
|
||||
Status LineTo(double x, double y);
|
||||
Status CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
|
||||
// методы, которые просто будем сводить к трем основным
|
||||
Status AddLine(double x1, double y1, double x2, double y2);
|
||||
Status AddLines(double* pPoints, int nCount);
|
||||
Status AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
|
||||
Status AddBeziers(double* pPoints, int nCount);
|
||||
Status AddCurve(double* pPoints, int nCount);
|
||||
Status AddEllipse(double x, double y, double width, double height);
|
||||
Status AddRectangle(double x, double y, double width, double height);
|
||||
Status AddPolygon(double* pPoints, int nCount);
|
||||
Status AddPath(const CGraphicsPath& oPath);
|
||||
Status AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle);
|
||||
// методы, которые просто будем сводить к трем основным
|
||||
Status AddLine(double x1, double y1, double x2, double y2);
|
||||
Status AddLines(double* pPoints, int nCount);
|
||||
Status AddBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
|
||||
Status AddBeziers(double* pPoints, int nCount);
|
||||
Status AddCurve(double* pPoints, int nCount);
|
||||
Status AddEllipse(double x, double y, double width, double height);
|
||||
Status AddRectangle(double x, double y, double width, double height);
|
||||
Status AddPolygon(double* pPoints, int nCount);
|
||||
Status AddPath(const CGraphicsPath& oPath);
|
||||
Status AddArc(double x, double y, double width, double height, double startAngle, double sweepAngle);
|
||||
|
||||
ULONG GetPointCount() const;
|
||||
Status GetPathPoints(PointF* points, int count) const;
|
||||
Status GetLastPoint(double& x, double& y);
|
||||
Status GetPathPoints(double* points, int count) const;
|
||||
void GetBounds(double& left, double& top, double& width, double& height);
|
||||
ULONG GetPointCount() const;
|
||||
Status GetPathPoints(PointF* points, int count) const;
|
||||
Status GetLastPoint(double& x, double& y);
|
||||
Status GetPathPoints(double* points, int count) const;
|
||||
void GetBounds(double& left, double& top, double& width, double& height) const;
|
||||
void GetBoundsAccurate(double& left, double& top, double& width, double& height) const;
|
||||
|
||||
Status Transform(const CMatrix* matrix);
|
||||
virtual bool _MoveTo(double x, double y);
|
||||
virtual bool _LineTo(double x, double y);
|
||||
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
virtual bool _Close();
|
||||
Status Transform(const CMatrix* matrix);
|
||||
virtual bool _MoveTo(double x, double y);
|
||||
virtual bool _LineTo(double x, double y);
|
||||
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
virtual bool _Close();
|
||||
|
||||
Status AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
Status AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y);
|
||||
Status AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
void z_Stroke(const double& size);
|
||||
void Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness);
|
||||
Status AddString(const std::wstring& strText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
Status AddString(const unsigned int* pGids, const unsigned int nGidsCount, NSFonts::IFontManager* pFont, double x, double y);
|
||||
Status AddStringC(const LONG& lText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
void z_Stroke(const double& size);
|
||||
void Widen(const double& size, const Aggplus::LineJoin& join, const CMatrix* matrix, float flatness);
|
||||
|
||||
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
|
||||
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE);
|
||||
int Ellipse(double fX, double fY, double fXRad, double fYRad);
|
||||
Status AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
bool IsPointInPath(const double& x, const double& y);
|
||||
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
|
||||
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double* pfXCur, double* pfYCur, INT bClockDirection = FALSE);
|
||||
int Ellipse(double fX, double fY, double fXRad, double fYRad);
|
||||
Status AddArc2(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
bool IsPointInPath(const double& x, const double& y);
|
||||
|
||||
public:
|
||||
CGraphicsPath_private* m_internal;
|
||||
};
|
||||
// Methods for Path Clip
|
||||
unsigned GetCloseCount() const noexcept;
|
||||
unsigned GetMoveCount() const noexcept;
|
||||
bool IsClockwise() const noexcept;
|
||||
bool IsMovePoint(unsigned idx) const noexcept;
|
||||
bool IsCurvePoint(unsigned idx) const noexcept;
|
||||
bool IsLinePoint(unsigned idx) const noexcept;
|
||||
bool IsClosePoint(unsigned idx) const noexcept;
|
||||
double GetArea() const noexcept;
|
||||
double GetArea(unsigned idx, bool isCurve) const noexcept;
|
||||
std::vector<PointD> GetPoints(unsigned idx, unsigned count) const noexcept;
|
||||
std::vector<CGraphicsPath> GetSubPaths() const;
|
||||
|
||||
class CGraphicsPathSimpleConverter_private;
|
||||
class GRAPHICS_DECL CGraphicsPathSimpleConverter : public NSFonts::ISimpleGraphicsPath
|
||||
{
|
||||
private:
|
||||
IRenderer* m_pRenderer;
|
||||
CGraphicsPathSimpleConverter_private* m_internal;
|
||||
CGraphicsPath& operator=(const CGraphicsPath& other) noexcept;
|
||||
CGraphicsPath& operator=(CGraphicsPath&& other) noexcept;
|
||||
bool operator==(const CGraphicsPath& other) noexcept;
|
||||
|
||||
public:
|
||||
CGraphicsPathSimpleConverter();
|
||||
~CGraphicsPathSimpleConverter();
|
||||
public:
|
||||
CGraphicsPath_private* m_internal;
|
||||
};
|
||||
|
||||
public:
|
||||
void SetRenderer(IRenderer* pRenderer);
|
||||
IRenderer* GetRenderer(INT bIsAddref = FALSE);
|
||||
class CGraphicsPathSimpleConverter_private;
|
||||
class GRAPHICS_DECL CGraphicsPathSimpleConverter : public NSFonts::ISimpleGraphicsPath
|
||||
{
|
||||
private:
|
||||
IRenderer* m_pRenderer;
|
||||
CGraphicsPathSimpleConverter_private* m_internal;
|
||||
|
||||
public:
|
||||
bool PathCommandMoveTo(double fX, double fY);
|
||||
bool PathCommandLineTo(double fX, double fY);
|
||||
bool PathCommandLinesTo(double* pPoints, LONG lCount);
|
||||
bool PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3);
|
||||
bool PathCommandCurvesTo(double* pData, LONG lCount);
|
||||
bool PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
bool PathCommandClose();
|
||||
bool PathCommandEnd();
|
||||
bool PathCommandStart();
|
||||
bool PathCommandGetCurrentPoint(double* fX, double* fY);
|
||||
bool PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset);
|
||||
bool PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags);
|
||||
public:
|
||||
CGraphicsPathSimpleConverter();
|
||||
~CGraphicsPathSimpleConverter();
|
||||
|
||||
bool PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager,
|
||||
const double& x, const double& y, const double& w, const double& h);
|
||||
bool PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager,
|
||||
const double& x, const double& y, const double& w, const double& h);
|
||||
public:
|
||||
void SetRenderer(IRenderer* pRenderer);
|
||||
IRenderer* GetRenderer(INT bIsAddref = FALSE);
|
||||
|
||||
bool PathCommandGetBounds(double& left, double& top, double& width, double &height);
|
||||
public:
|
||||
bool PathCommandMoveTo(double fX, double fY);
|
||||
bool PathCommandLineTo(double fX, double fY);
|
||||
bool PathCommandLinesTo(double* pPoints, LONG lCount);
|
||||
bool PathCommandCurveTo(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3);
|
||||
bool PathCommandCurvesTo(double* pData, LONG lCount);
|
||||
bool PathCommandArcTo(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
bool PathCommandClose();
|
||||
bool PathCommandEnd();
|
||||
bool PathCommandStart();
|
||||
bool PathCommandGetCurrentPoint(double* fX, double* fY);
|
||||
bool PathCommandText(const std::wstring& bsText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset);
|
||||
bool
|
||||
PathCommandTextEx(std::wstring& bsText, std::wstring& bsGidText, NSFonts::IFontManager* pManager, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags);
|
||||
|
||||
public:
|
||||
bool PathCommandText2(const int* pUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, const double& x, const double& y, const double& w, const double& h);
|
||||
bool PathCommandText2(const std::wstring& sUnicodes, const int* pGids, const int& nCount, NSFonts::IFontManager* pManager, const double& x, const double& y, const double& w, const double& h);
|
||||
|
||||
virtual bool _MoveTo(double x, double y);
|
||||
virtual bool _LineTo(double x, double y);
|
||||
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
virtual bool _Close();
|
||||
bool _Reset();
|
||||
bool _Start();
|
||||
bool PathCommandGetBounds(double& left, double& top, double& width, double& height);
|
||||
|
||||
protected:
|
||||
bool AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
public:
|
||||
virtual bool _MoveTo(double x, double y);
|
||||
virtual bool _LineTo(double x, double y);
|
||||
virtual bool _CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
|
||||
virtual bool _Close();
|
||||
bool _Reset();
|
||||
bool _Start();
|
||||
|
||||
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
|
||||
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double *pfXCur, double *pfYCur, INT bClockDirection = FALSE);
|
||||
int Ellipse(double fX, double fY, double fXRad, double fYRad);
|
||||
protected:
|
||||
bool AddString(const std::wstring& bstrText, NSFonts::IFontManager* pFont, double x, double y);
|
||||
|
||||
bool AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
int EllipseArc(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
double AngToEllPrm(double fAngle, double fXRad, double fYRad);
|
||||
int EllipseArc2(double fX, double fY, double fXRad, double fYRad, double fAngle1, double fAngle2, INT bClockDirection);
|
||||
int EllipseArc3(double fX, double fY, double fXRad, double fYRad, double dAngle1, double dAngle2, double* pfXCur, double* pfYCur, INT bClockDirection = FALSE);
|
||||
int Ellipse(double fX, double fY, double fXRad, double fYRad);
|
||||
|
||||
bool Is_poly_closed();
|
||||
};
|
||||
}
|
||||
bool AddArc(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle);
|
||||
|
||||
bool Is_poly_closed();
|
||||
};
|
||||
|
||||
enum BooleanOpType
|
||||
{
|
||||
Intersection = 1,
|
||||
Union = 0,
|
||||
Subtraction = 2,
|
||||
Exclusion = 3
|
||||
};
|
||||
|
||||
GRAPHICS_DECL CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op);
|
||||
|
||||
} // namespace Aggplus
|
||||
|
||||
#endif // _BUILD_GRAPHICSPATH_H_
|
||||
|
||||
@ -123,8 +123,10 @@ public:
|
||||
PointF_T(T x, T y) : X(x), Y(y) { }
|
||||
//~PointF() { }
|
||||
INT Equals(const PointF_T& point) const { return(X==point.X && Y==point.Y); }
|
||||
bool IsZero() const noexcept { return X == 0.0 && Y == 0.0; }
|
||||
PointF_T operator+(const PointF_T& point) const { return PointF_T(X + point.X, Y + point.Y); }
|
||||
PointF_T operator-(const PointF_T& point) const { return PointF_T(X - point.X, Y - point.Y); }
|
||||
PointF_T& operator=(const PointF_T& other) noexcept {X = other.X; Y = other.Y; return *this;}
|
||||
public:
|
||||
T X, Y;
|
||||
};
|
||||
|
||||
521
DesktopEditor/graphics/boolean_operations_math.h
Normal file
521
DesktopEditor/graphics/boolean_operations_math.h
Normal file
@ -0,0 +1,521 @@
|
||||
#ifndef CLIPMATH_H
|
||||
#define CLIPMATH_H
|
||||
|
||||
#include "aggplustypes.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
constexpr double EPSILON = 1e-12;
|
||||
constexpr double POINT_EPSILON = 1e-2;
|
||||
constexpr double GEOMETRIC_EPSILON = 1e-7;
|
||||
constexpr double LOCATION_EPSILON = 1e-7;
|
||||
constexpr double TIME_EPSILON = 1e-8;
|
||||
constexpr double MACHINE_EPSILON = 1.12e-16;
|
||||
constexpr double TRIGANOMETRIC_EPSILON = 1e-8;
|
||||
constexpr double CURVETIME_EPSILON = 1e-8;
|
||||
constexpr double LINE_EPSILON = 1e-9;
|
||||
constexpr double MIN = std::numeric_limits<double>::min();
|
||||
constexpr double MAX = std::numeric_limits<double>::max();
|
||||
const Aggplus::PointD MIN_POINT = Aggplus::PointD(-100000.0, -100000.0);
|
||||
|
||||
const std::vector<double> ABSCISSAS[16] = {
|
||||
{0.5773502691896257645091488},
|
||||
{0,0.7745966692414833770358531},
|
||||
{0.3399810435848562648026658,0.8611363115940525752239465},
|
||||
{0,0.5384693101056830910363144,0.9061798459386639927976269},
|
||||
{0.2386191860831969086305017,0.6612093864662645136613996,0.9324695142031520278123016},
|
||||
{0,0.4058451513773971669066064,0.7415311855993944398638648,0.9491079123427585245261897},
|
||||
{0.1834346424956498049394761,0.5255324099163289858177390,0.7966664774136267395915539,
|
||||
0.9602898564975362316835609},
|
||||
{0,0.3242534234038089290385380,0.6133714327005903973087020,0.8360311073266357942994298,
|
||||
0.9681602395076260898355762},
|
||||
{0.1488743389816312108848260,0.4333953941292471907992659,0.6794095682990244062343274,
|
||||
0.8650633666889845107320967,0.9739065285171717200779640},
|
||||
{0,0.2695431559523449723315320,0.5190961292068118159257257,0.7301520055740493240934163,
|
||||
0.8870625997680952990751578,0.9782286581460569928039380},
|
||||
{0.1252334085114689154724414,0.3678314989981801937526915,0.5873179542866174472967024,
|
||||
0.7699026741943046870368938,0.9041172563704748566784659,0.9815606342467192506905491},
|
||||
{0,0.2304583159551347940655281,0.4484927510364468528779129,0.6423493394403402206439846,
|
||||
0.8015780907333099127942065,0.9175983992229779652065478,0.9841830547185881494728294},
|
||||
{0.1080549487073436620662447,0.3191123689278897604356718,0.5152486363581540919652907,
|
||||
0.6872929048116854701480198,0.8272013150697649931897947,0.9284348836635735173363911,
|
||||
0.9862838086968123388415973},
|
||||
{0,0.2011940939974345223006283,0.3941513470775633698972074,0.5709721726085388475372267,
|
||||
0.7244177313601700474161861,0.8482065834104272162006483,0.9372733924007059043077589,
|
||||
0.9879925180204854284895657},
|
||||
{0.0950125098376374401853193,0.2816035507792589132304605,0.4580167776572273863424194,
|
||||
0.6178762444026437484466718,0.7554044083550030338951012,0.8656312023878317438804679,
|
||||
0.9445750230732325760779884,0.9894009349916499325961542}
|
||||
};
|
||||
|
||||
const std::vector<double> WEIGHT[16] {
|
||||
{1},
|
||||
{0.8888888888888888888888889,0.5555555555555555555555556},
|
||||
{0.6521451548625461426269361,0.3478548451374538573730639},
|
||||
{0.5688888888888888888888889,0.4786286704993664680412915,0.2369268850561890875142640},
|
||||
{0.4679139345726910473898703,0.3607615730481386075698335,0.1713244923791703450402961},
|
||||
{0.4179591836734693877551020,0.3818300505051189449503698,0.2797053914892766679014678,
|
||||
0.1294849661688696932706114},
|
||||
{0.3626837833783619829651504,0.3137066458778872873379622,0.2223810344533744705443560,
|
||||
0.1012285362903762591525314},
|
||||
{0.3302393550012597631645251,0.3123470770400028400686304,0.2606106964029354623187429,
|
||||
0.1806481606948574040584720,0.0812743883615744119718922},
|
||||
{0.2955242247147528701738930,0.2692667193099963550912269,0.2190863625159820439955349,
|
||||
0.1494513491505805931457763,0.0666713443086881375935688},
|
||||
{0.2729250867779006307144835,0.2628045445102466621806889,0.2331937645919904799185237,
|
||||
0.1862902109277342514260976,0.1255803694649046246346943,0.0556685671161736664827537},
|
||||
{0.2491470458134027850005624,0.2334925365383548087608499,0.2031674267230659217490645,
|
||||
0.1600783285433462263346525,0.1069393259953184309602547,0.0471753363865118271946160},
|
||||
{0.2325515532308739101945895,0.2262831802628972384120902,0.2078160475368885023125232,
|
||||
0.1781459807619457382800467,0.1388735102197872384636018,0.0921214998377284479144218,
|
||||
0.0404840047653158795200216},
|
||||
{0.2152638534631577901958764,0.2051984637212956039659241,0.1855383974779378137417166,
|
||||
0.1572031671581935345696019,0.1215185706879031846894148,0.0801580871597602098056333,
|
||||
0.0351194603317518630318329},
|
||||
{0.2025782419255612728806202,0.1984314853271115764561183,0.1861610000155622110268006,
|
||||
0.1662692058169939335532009,0.1395706779261543144478048,0.1071592204671719350118695,
|
||||
0.0703660474881081247092674,0.0307532419961172683546284},
|
||||
{0.1894506104550684962853967,0.1826034150449235888667637,0.1691565193950025381893121,
|
||||
0.1495959888165767320815017,0.1246289712555338720524763,0.0951585116824927848099251,
|
||||
0.0622535239386478928628438,0.0271524594117540948517806}
|
||||
};
|
||||
|
||||
inline double max(const double& v1, const double& v2, const double& v3, const double& v4)
|
||||
{
|
||||
return std::max(std::max(v1, v2), std::max(v3, v4));
|
||||
}
|
||||
|
||||
inline double max(const double& v1, const double& v2, const double& v3)
|
||||
{
|
||||
return std::max(std::max(v1, v2), v3);
|
||||
}
|
||||
|
||||
inline double min(const double& v1, const double& v2, const double& v3, const double& v4)
|
||||
{
|
||||
return std::min(std::min(v1, v2), std::min(v3, v4));
|
||||
}
|
||||
|
||||
inline double min(const double& v1, const double& v2, const double& v3)
|
||||
{
|
||||
return std::min(std::min(v1, v2), v3);
|
||||
}
|
||||
|
||||
inline bool isZero(const double& value)
|
||||
{
|
||||
return value >= -EPSILON && value <= EPSILON;
|
||||
}
|
||||
|
||||
inline bool isMachineZero(const double& value)
|
||||
{
|
||||
return value >= -MACHINE_EPSILON && value <= MACHINE_EPSILON;
|
||||
}
|
||||
|
||||
inline bool isInRange(const double& angle, const double& mn, const double& mx)
|
||||
{
|
||||
return (mn < mx) ? (angle > mn && angle < mx) : (angle > mn || angle < mx);
|
||||
}
|
||||
|
||||
inline double clamp(const double& value, const double& mn, const double& mx)
|
||||
{
|
||||
return value < mn ? mn : value > mx ? mx : value;
|
||||
}
|
||||
|
||||
inline bool isCollinear(const Aggplus::PointD& p1, const Aggplus::PointD& p2)
|
||||
{
|
||||
return fabs(p1.X * p2.X + p1.Y * p2.Y) <= sqrt((p1.X * p1.X + p1.Y * p1.Y) * (p2.X * p2.X + p2.Y * p2.Y)) * TRIGANOMETRIC_EPSILON;
|
||||
}
|
||||
|
||||
inline int getIterations(const double& a, const double& b)
|
||||
{
|
||||
double n1 = 2.0, n2 = 16.0;
|
||||
|
||||
return std::max(n1, std::min(n2, ceil(fabs(b - a) * 32)));
|
||||
}
|
||||
|
||||
inline double CurveLength(const double& t, const double& ax, const double& bx, const double& cx,
|
||||
const double& ay, const double& by, const double& cy)
|
||||
{
|
||||
return sqrt((((ax * t) + bx) * t + cx) * (((ax * t) + bx) * t + cx) + (((ay * t) + by) * t + cy) * (((ay * t) + by) * t + cy));
|
||||
}
|
||||
|
||||
inline double integrate(const double& ax, const double& bx, const double& cx, const double& ay,
|
||||
const double& by, const double& cy, const double& a, const double& b, size_t n = 16)
|
||||
{
|
||||
std::vector<double> x = ABSCISSAS[n - 2],
|
||||
w = WEIGHT[n - 2];
|
||||
|
||||
double A = (b - a) * 0.5,
|
||||
B = A + a;
|
||||
double sum = n & 1 ? CurveLength(B, ax, bx, cx, ay, by, cy) : 0.0;
|
||||
|
||||
for (size_t i = 0; i < (n + 1) >> 1; i++)
|
||||
{
|
||||
double Ax = A * x[i];
|
||||
sum += w[i] * (CurveLength(B + Ax, ax, bx, cx, ay, by, cy) +
|
||||
CurveLength(B - Ax, ax, bx, cx, ay, by, cy));
|
||||
}
|
||||
|
||||
return A * sum;
|
||||
}
|
||||
|
||||
double fLength(const double& t, double& length, double& start, const double& offset,
|
||||
const double& ax, const double& bx, const double& cx, const double& ay,
|
||||
const double& by, const double& cy)
|
||||
{
|
||||
length += integrate(ax, bx, cx, ay, by, cy, start, t, getIterations(start, t));
|
||||
start = t;
|
||||
|
||||
return length - offset;
|
||||
}
|
||||
|
||||
double findRoot(double& length, double& start, const double& offset, const double& ax,
|
||||
const double& bx, const double& cx, const double& ay, const double& by,
|
||||
const double& cy, double x, double a, double b)
|
||||
{
|
||||
for (size_t i = 0; i < 32; i++)
|
||||
{
|
||||
double fx = fLength(x, length, start, offset, ax, bx, cx, ay, by, cy),
|
||||
dx = fx / CurveLength(x, ax, bx, cx, ay, by, cy),
|
||||
nx = x - dx;
|
||||
|
||||
if (fabs(dx) < EPSILON)
|
||||
{
|
||||
x = nx;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fx > 0)
|
||||
{
|
||||
b = x;
|
||||
x = nx <= a ? (a + b) * 0.5 : nx;
|
||||
}
|
||||
else{
|
||||
a = x;
|
||||
x = nx >= b ? (a + b) * 0.5 : nx;
|
||||
}
|
||||
}
|
||||
|
||||
return clamp(x, a, b);
|
||||
}
|
||||
|
||||
bool intersect(std::vector<double> v, Aggplus::PointD& res)
|
||||
{
|
||||
v[2] -= v[0];
|
||||
v[3] -= v[1];
|
||||
v[6] -= v[4];
|
||||
v[7] -= v[5];
|
||||
|
||||
double cross = v[2] * v[7] - v[3] * v[6];
|
||||
if (!isMachineZero(cross))
|
||||
{
|
||||
double dx = v[0] - v[4],
|
||||
dy = v[1] - v[5],
|
||||
u1 = (v[6] * dy - v[7] * dx) / cross,
|
||||
u2 = (v[2] * dy - v[3] * dx) / cross,
|
||||
uMin = -EPSILON,
|
||||
uMax = 1 + EPSILON;
|
||||
|
||||
if (uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax)
|
||||
{
|
||||
u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1;
|
||||
res = Aggplus::PointD(v[0] + u1 * v[2], v[1] + u1 * v[3]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void getConvexHull(const double& dq0, const double& dq1,
|
||||
const double& dq2, const double& dq3,
|
||||
std::vector<Aggplus::PointD>& top,
|
||||
std::vector<Aggplus::PointD>& bottom)
|
||||
{
|
||||
Aggplus::PointD p0 = Aggplus::PointD(0.0, dq0),
|
||||
p1 = Aggplus::PointD(1.0 / 3.0, dq1),
|
||||
p2 = Aggplus::PointD(2.0 / 3.0, dq2),
|
||||
p3 = Aggplus::PointD(1.0, dq3);
|
||||
|
||||
double dist1 = dq1 - (2.0 * dq0 + dq3) / 3.0,
|
||||
dist2 = dq2 - (dq0 + 2.0 * dq3) / 3.0;
|
||||
|
||||
std::vector<Aggplus::PointD>& realTop = top;
|
||||
std::vector<Aggplus::PointD>& realBottom = bottom;
|
||||
if (dist1 < 0.0 || dist2 < 0.0)
|
||||
{
|
||||
realTop = bottom;
|
||||
realBottom = top;
|
||||
}
|
||||
|
||||
if (dist1 * dist2 < 0.0)
|
||||
{
|
||||
realTop.reserve(3);
|
||||
realTop.push_back(p0);
|
||||
realTop.push_back(p1);
|
||||
realTop.push_back(p3);
|
||||
|
||||
realBottom.reserve(3);
|
||||
realBottom.push_back(p0);
|
||||
realBottom.push_back(p2);
|
||||
realBottom.push_back(p3);
|
||||
}
|
||||
else
|
||||
{
|
||||
double distRatio = dist1 / dist2;
|
||||
if (distRatio >= 2.0)
|
||||
{
|
||||
realTop.reserve(3);
|
||||
realTop.push_back(p0);
|
||||
realTop.push_back(p1);
|
||||
realTop.push_back(p3);
|
||||
|
||||
realBottom.reserve(2);
|
||||
realBottom.push_back(p0);
|
||||
realBottom.push_back(p3);
|
||||
}
|
||||
else if (distRatio <= 0.5)
|
||||
{
|
||||
realTop.reserve(3);
|
||||
realTop.push_back(p0);
|
||||
realTop.push_back(p2);
|
||||
realTop.push_back(p3);
|
||||
|
||||
realBottom.reserve(2);
|
||||
realBottom.push_back(p0);
|
||||
realBottom.push_back(p3);
|
||||
}
|
||||
else
|
||||
{
|
||||
realTop.reserve(4);
|
||||
realTop.push_back(p0);
|
||||
realTop.push_back(p1);
|
||||
realTop.push_back(p2);
|
||||
realTop.push_back(p3);
|
||||
|
||||
realBottom.reserve(2);
|
||||
realBottom.push_back(p0);
|
||||
realBottom.push_back(p3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double clipConvexHullPart(const std::vector<Aggplus::PointD>& part, const bool& top,
|
||||
const double& threshold)
|
||||
{
|
||||
double px = part[0].X,
|
||||
py = part[0].Y;
|
||||
for (size_t i = 1; i < part.size(); i++)
|
||||
{
|
||||
double qx = part[i].X,
|
||||
qy = part[i].Y;
|
||||
|
||||
if (top ? qy >= threshold : qy <= threshold)
|
||||
return qy == threshold ? qx : px + (threshold - py) * (qx - px) / (qy - py);
|
||||
|
||||
px = qx;
|
||||
py = qy;
|
||||
}
|
||||
|
||||
return MIN;
|
||||
}
|
||||
|
||||
inline double clipConvexHull(const std::vector<Aggplus::PointD>& top,
|
||||
const std::vector<Aggplus::PointD>& bottom,
|
||||
const double& dMin, const double& dMax)
|
||||
{
|
||||
if (top[0].Y < dMin)
|
||||
return clipConvexHullPart(top, true, dMin);
|
||||
else if (bottom[0].Y > dMax)
|
||||
return clipConvexHullPart(bottom, false, dMax);
|
||||
else
|
||||
return top[0].X;
|
||||
}
|
||||
|
||||
inline int binarySearch(const std::vector<std::vector<double>>& allBounds,
|
||||
const std::vector<int>& indices, const size_t& coord, const double& value)
|
||||
{
|
||||
int lo = 0,
|
||||
hi = static_cast<int>(indices.size());
|
||||
|
||||
while(lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
if (allBounds[indices[mid]][coord] < value)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
return lo - 1;
|
||||
}
|
||||
|
||||
inline double getSignedDistance(const double& px, const double& py, double vx, double vy,
|
||||
const double& x, const double& y, bool asVector = false)
|
||||
{
|
||||
if (!asVector)
|
||||
{
|
||||
vx -= px;
|
||||
vy -= py;
|
||||
}
|
||||
|
||||
bool vx0 = vx == 0.0,
|
||||
vyG = vy > 0.0,
|
||||
vxL = vx < 0.0,
|
||||
vy0 = vy == 0.0,
|
||||
vyGvx = vy > vx;
|
||||
|
||||
double distX = vyG ? x - px : px - x,
|
||||
distY = vxL ? y - py : py - y,
|
||||
distGY = vy * sqrt(1.0 + (vx * vx) / (vy * vy)),
|
||||
distGX = vx * sqrt(1.0 + (vy * vy) / (vx * vx)),
|
||||
distXY = ((x - px) * vy - (y - py) * vx) / (vyGvx ? distGY : distGX);
|
||||
|
||||
return vx0 ? distX : vy0 ? distY : distXY;
|
||||
}
|
||||
|
||||
inline double getDistance(const double& px, const double& py, const double& vx, const double& vy,
|
||||
const double& x, const double& y, const bool& asVector)
|
||||
{
|
||||
return fabs(getSignedDistance(px, py, vx, vy, x, y, asVector));
|
||||
}
|
||||
|
||||
inline double getDistance(const double& px, const double& py, const double& vx, const double& vy,
|
||||
const double& x, const double& y)
|
||||
{
|
||||
if (vx == 0)
|
||||
{
|
||||
if (vy > 0)
|
||||
return std::abs(x - px);
|
||||
else
|
||||
return std::abs(px - x);
|
||||
}
|
||||
if (vy == 0)
|
||||
{
|
||||
if (vx < 0)
|
||||
return std::abs(y - py);
|
||||
else
|
||||
return std::abs(py -y);
|
||||
}
|
||||
|
||||
bool dir = vy > vx;
|
||||
double dist = (x- px) * vy - (y - py) * vx,
|
||||
epsY = vy * sqrt(1 + (vx * vx) / (vy * vy)),
|
||||
epsX = vx * sqrt(1 + (vy * vy) / (vx * vx));
|
||||
|
||||
return dist / (dir ? epsY : epsX);
|
||||
}
|
||||
|
||||
inline double getDistance(const double& x1, const double& y1, const double& x2, const double& y2)
|
||||
{
|
||||
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
|
||||
}
|
||||
|
||||
inline double getDistance(const Aggplus::PointD& point1, const Aggplus::PointD& point2)
|
||||
{
|
||||
return getDistance(point1.X, point1.Y, point2.X, point2.Y);
|
||||
}
|
||||
|
||||
inline std::pair<double, double> split(const double& v)
|
||||
{
|
||||
double x = v * 134217729.0,
|
||||
y = v - x,
|
||||
hi = y + x,
|
||||
lo = v - hi;
|
||||
|
||||
return std::pair<double, double>(hi, lo);
|
||||
}
|
||||
|
||||
inline double getDiscriminant(const double& a, const double& b, const double& c)
|
||||
{
|
||||
double D = b * b - a * c,
|
||||
E = b * b + a * c;
|
||||
|
||||
if (fabs(D) * 3 < E)
|
||||
{
|
||||
std::pair<double, double> ad = split(a),
|
||||
bd = split(b),
|
||||
cd = split(c);
|
||||
|
||||
double p = b * b,
|
||||
dp = (bd.first * bd.first -
|
||||
p + 2 * bd.first * bd.second) +
|
||||
bd.second * bd.second,
|
||||
q = a * c,
|
||||
dq = (ad.first * cd.first -
|
||||
q + ad.first * cd.second +
|
||||
ad.second * cd.first) +
|
||||
ad.second * cd.second;
|
||||
|
||||
D = (p - q) + (dp - dq);
|
||||
}
|
||||
|
||||
return D;
|
||||
}
|
||||
|
||||
int solveQuadratic(double a, double b, double c, std::vector<double>& roots,
|
||||
const double& mn, const double& mx)
|
||||
{
|
||||
double x1 = MAX, x2 = MAX;
|
||||
if (fabs(a) < EPSILON)
|
||||
{
|
||||
if (fabs(b) < EPSILON)
|
||||
return fabs(c) < EPSILON ? -1 : 0;
|
||||
x1 = -c / b;
|
||||
}
|
||||
else
|
||||
{
|
||||
b *= -0.5;
|
||||
|
||||
double D = getDiscriminant(a, b, c);
|
||||
if (D != 0 && fabs(D) < MACHINE_EPSILON)
|
||||
{
|
||||
double f = max(fabs(a), fabs(b), fabs(c));
|
||||
if ((f != 0) && (f < 1e-8 || f < 1e8))
|
||||
{
|
||||
f = pow(2, -round(log2(f)));
|
||||
a *= f;
|
||||
b *= f;
|
||||
c *= f;
|
||||
D = getDiscriminant(a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
if (D >= -MACHINE_EPSILON)
|
||||
{
|
||||
double Q = D < 0 ? 0 : sqrt(D),
|
||||
R = b + (b < 0 ? -Q : Q);
|
||||
if (R == 0)
|
||||
{
|
||||
x1 = c / a;
|
||||
x2 = -x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = R / a;
|
||||
x2 = c / R;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
double minB = mn - EPSILON,
|
||||
maxB = mx + EPSILON;
|
||||
if (x1 != MAX && x1 > minB && x1 < maxB)
|
||||
{
|
||||
roots.push_back(clamp(x1, mn, mx));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (x2 != x1 && x2 != MAX && x2 > minB && x2 < maxB)
|
||||
{
|
||||
roots.push_back(clamp(x2, mn, mx));
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif //CLIPMATH_H
|
||||
@ -221,6 +221,7 @@ BYTE* CAnnotFieldInfo::GetRender(LONG& nLen)
|
||||
}
|
||||
const std::wstring& CAnnotFieldInfo::GetNM() { return m_wsNM; }
|
||||
const std::wstring& CAnnotFieldInfo::GetLM() { return m_wsLM; }
|
||||
const std::wstring& CAnnotFieldInfo::GetOUserID() { return m_wsOUserID; }
|
||||
const std::wstring& CAnnotFieldInfo::GetContents() { return m_wsContents; }
|
||||
const std::vector<double>& CAnnotFieldInfo::GetC() { return m_arrC; }
|
||||
|
||||
@ -348,6 +349,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
|
||||
m_pRender = pReader->GetCurrentBuffer();
|
||||
pReader->Skip(m_nRenderLen);
|
||||
}
|
||||
if (nFlags & (1 << 7))
|
||||
m_wsOUserID = pReader->ReadString();
|
||||
|
||||
if (IsMarkup())
|
||||
{
|
||||
@ -931,6 +934,11 @@ int CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetMaxLen() const { return m
|
||||
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetV() { return m_wsV; }
|
||||
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRV() { return m_wsRV; }
|
||||
const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetAPV() { return m_wsAPV; }
|
||||
BYTE* CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::GetRender(LONG& nLen)
|
||||
{
|
||||
nLen = m_nRenderLen;
|
||||
return m_pRender;
|
||||
}
|
||||
void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag)
|
||||
{
|
||||
if (nFlags & (1 << 9))
|
||||
@ -941,6 +949,12 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf
|
||||
m_wsRV = pReader->ReadString();
|
||||
if (nFlags & (1 << 12))
|
||||
m_wsAPV = pReader->ReadString();
|
||||
if (nFlags & (1 << 13))
|
||||
{
|
||||
m_nRenderLen = pReader->ReadInt() - 4;
|
||||
m_pRender = pReader->GetCurrentBuffer();
|
||||
pReader->Skip(m_nRenderLen);
|
||||
}
|
||||
}
|
||||
|
||||
int CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetTI() const { return m_nTI; }
|
||||
@ -949,6 +963,11 @@ const std::wstring& CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetAPV() {
|
||||
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; }
|
||||
BYTE* CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::GetRender(LONG& nLen)
|
||||
{
|
||||
nLen = m_nRenderLen;
|
||||
return m_pRender;
|
||||
}
|
||||
void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
|
||||
{
|
||||
if (nFlags & (1 << 9))
|
||||
@ -979,6 +998,12 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToP
|
||||
for (int i = 0; i < n; ++i)
|
||||
m_arrI.push_back(pReader->ReadInt());
|
||||
}
|
||||
if (nFlags & (1 << 15))
|
||||
{
|
||||
m_nRenderLen = pReader->ReadInt() - 4;
|
||||
m_pRender = pReader->GetCurrentBuffer();
|
||||
pReader->Skip(m_nRenderLen);
|
||||
}
|
||||
}
|
||||
|
||||
CAnnotFieldDelete::CAnnotFieldDelete() : IAdvancedCommand(AdvancedCommandType::DeleteAnnot) {}
|
||||
|
||||
@ -86,6 +86,7 @@ public:
|
||||
const std::wstring& GetV();
|
||||
const std::wstring& GetRV();
|
||||
const std::wstring& GetAPV();
|
||||
BYTE* GetRender(LONG& nLen);
|
||||
|
||||
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags, int nWidgetFlag);
|
||||
|
||||
@ -94,6 +95,8 @@ public:
|
||||
std::wstring m_wsV;
|
||||
std::wstring m_wsRV;
|
||||
std::wstring m_wsAPV;
|
||||
LONG m_nRenderLen;
|
||||
BYTE* m_pRender;
|
||||
};
|
||||
|
||||
class GRAPHICS_DECL CChoiceWidgetPr
|
||||
@ -105,6 +108,7 @@ public:
|
||||
const std::vector<int>& GetI();
|
||||
const std::vector<std::wstring>& GetArrV();
|
||||
const std::vector< std::pair<std::wstring, std::wstring> >& GetOpt();
|
||||
BYTE* GetRender(LONG& nLen);
|
||||
|
||||
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
|
||||
|
||||
@ -115,6 +119,8 @@ public:
|
||||
std::vector<int> m_arrI;
|
||||
std::vector<std::wstring> m_arrV;
|
||||
std::vector< std::pair<std::wstring, std::wstring> > m_arrOpt;
|
||||
LONG m_nRenderLen;
|
||||
BYTE* m_pRender;
|
||||
};
|
||||
|
||||
class GRAPHICS_DECL CSignatureWidgetPr
|
||||
@ -414,6 +420,7 @@ public:
|
||||
BYTE* GetRender(LONG& nLen);
|
||||
const std::wstring& GetNM();
|
||||
const std::wstring& GetLM();
|
||||
const std::wstring& GetOUserID();
|
||||
const std::wstring& GetContents();
|
||||
const std::vector<double>& GetC();
|
||||
|
||||
@ -466,6 +473,7 @@ private:
|
||||
int m_nPage;
|
||||
std::wstring m_wsNM;
|
||||
std::wstring m_wsLM;
|
||||
std::wstring m_wsOUserID;
|
||||
std::wstring m_wsContents;
|
||||
std::pair<BYTE, double> m_pBE;
|
||||
std::vector<double> m_arrC;
|
||||
|
||||
@ -49,10 +49,13 @@ SOURCES += \
|
||||
# paths
|
||||
HEADERS += \
|
||||
./../GraphicsPath_private.h \
|
||||
./../GraphicsPath.h
|
||||
./../GraphicsPath.h \
|
||||
./../BooleanOperations.h \
|
||||
./../boolean_operations_math.h
|
||||
|
||||
SOURCES += \
|
||||
./../GraphicsPath.cpp
|
||||
./../GraphicsPath.cpp \
|
||||
./../BooleanOperations.cpp
|
||||
|
||||
# alpha mask
|
||||
HEADERS += \
|
||||
|
||||
@ -143,7 +143,7 @@
|
||||
},
|
||||
{
|
||||
"folder": "../../",
|
||||
"files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "GraphicsLayer.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp"]
|
||||
"files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "BooleanOperations.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "GraphicsLayer.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "../../../fontengine/",
|
||||
|
||||
@ -53,6 +53,8 @@ HEADERS += \
|
||||
../../../Matrix.h \
|
||||
../../../Matrix_private.h \
|
||||
../../../GraphicsPath.h \
|
||||
../../../BooleanOperations.h \
|
||||
../../../boolean_operations_math.h \
|
||||
../../../GraphicsPath_private.h \
|
||||
../../../AlphaMask.h \
|
||||
\
|
||||
@ -105,6 +107,7 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
../../../Matrix.cpp \
|
||||
../../../GraphicsPath.cpp \
|
||||
../../../BooleanOperations.cpp \
|
||||
../../../AlphaMask.cpp \
|
||||
../../../../raster/BgraFrame.cpp \
|
||||
../../../../raster/ImageFileFormatChecker.cpp \
|
||||
@ -680,6 +683,7 @@ HEADERS += \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ImageManager.h \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.h \
|
||||
|
||||
@ -73,9 +73,9 @@ CFile.prototype.getOriginPage = function(originIndex)
|
||||
for (let i = 0; i < this.pages.length; ++i)
|
||||
{
|
||||
if (this.pages[i]["originIndex"] == originIndex)
|
||||
return this.pages[i];
|
||||
return i;
|
||||
}
|
||||
return null;
|
||||
return -1;
|
||||
};
|
||||
|
||||
CFile.prototype["getPages"] = function()
|
||||
@ -115,7 +115,7 @@ CFile.prototype["loadFromDataWithPassword"] = function(password)
|
||||
if (0 != this.nativeFile)
|
||||
this._closeFile();
|
||||
|
||||
let isSuccess = this._openFile(arrayBuffer, password);
|
||||
let isSuccess = this._openFile(undefined, password);
|
||||
let error = this._getError(); // 0 - ok, 4 - password, else: error
|
||||
this.type = this._getType();
|
||||
|
||||
@ -236,14 +236,17 @@ CFile.prototype["getLinks"] = function(pageIndex)
|
||||
// TEXT
|
||||
CFile.prototype["getGlyphs"] = function(pageIndex)
|
||||
{
|
||||
let page = this.getOriginPage(pageIndex);
|
||||
let i = this.getOriginPage(pageIndex);
|
||||
if (i < 0)
|
||||
return null;
|
||||
let page = this.pages[i];
|
||||
if (!page || page.fonts.length > 0)
|
||||
{
|
||||
// waiting fonts
|
||||
return null;
|
||||
}
|
||||
|
||||
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
|
||||
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
|
||||
let res = this._getGlyphs(pageIndex);
|
||||
// there is no need to delete the result; this buffer is used as a text buffer
|
||||
// for text commands on other pages. After receiving ALL text pages,
|
||||
@ -488,7 +491,11 @@ function readAnnot(reader, rec)
|
||||
// Date of last change - M
|
||||
if (flags & (1 << 5))
|
||||
rec["LastModified"] = reader.readString();
|
||||
// AP
|
||||
rec["AP"]["have"] = (flags >> 6) & 1;
|
||||
// User ID
|
||||
if (flags & (1 << 7))
|
||||
rec["OUserID"] = reader.readString();
|
||||
}
|
||||
function readAnnotAP(reader, AP)
|
||||
{
|
||||
@ -841,6 +848,8 @@ CFile.prototype["getButtonIcons"] = function(pageIndex, width, height, backgroun
|
||||
let reader = ptr.getReader();
|
||||
|
||||
if (!reader) return {};
|
||||
|
||||
let res = {};
|
||||
|
||||
res["MK"] = [];
|
||||
res["View"] = [];
|
||||
@ -1368,14 +1377,17 @@ CFile.prototype["free"] = function(pointer)
|
||||
// PIXMAP
|
||||
CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor)
|
||||
{
|
||||
let page = this.getOriginPage(pageIndex);
|
||||
let i = this.getOriginPage(pageIndex);
|
||||
if (i < 0)
|
||||
return null;
|
||||
let page = this.pages[i];
|
||||
if (!page || page.fonts.length > 0)
|
||||
{
|
||||
// waiting fonts
|
||||
return null;
|
||||
}
|
||||
|
||||
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
|
||||
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
|
||||
let ptr = this._getPixmap(pageIndex, width, height, backgroundColor);
|
||||
this.unlockPageNumForFontsLoader();
|
||||
|
||||
@ -1433,6 +1445,43 @@ function fontToMemory(file, isCheck)
|
||||
Module["_free"](idPointer);
|
||||
}
|
||||
|
||||
// FONTS
|
||||
CFile.prototype["addPage"] = function(pageIndex, pageObj)
|
||||
{
|
||||
this.pages.splice(pageIndex, 0, pageObj);
|
||||
if (this.fontStreams)
|
||||
{
|
||||
for (let i in this.fontStreams)
|
||||
{
|
||||
let pages = this.fontStreams[i].pages;
|
||||
for (let j = 0; j < pages.length; j++)
|
||||
{
|
||||
if (pages[j] >= pageIndex)
|
||||
pages[j] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
CFile.prototype["removePage"] = function(pageIndex)
|
||||
{
|
||||
let result = this.pages.splice(pageIndex, 1);
|
||||
if (this.fontStreams)
|
||||
{
|
||||
for (let i in this.fontStreams)
|
||||
{
|
||||
let pages = this.fontStreams[i].pages;
|
||||
for (let j = 0; j < pages.length; j++)
|
||||
{
|
||||
if (pages[j] > pageIndex)
|
||||
pages[j] -= 1;
|
||||
else if (pages[j] == pageIndex)
|
||||
pages.splice(j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// ONLY WEB
|
||||
self["AscViewer"]["Free"] = function(pointer)
|
||||
{
|
||||
|
||||
@ -107,7 +107,7 @@ CFile.prototype._setCMap = function(memoryBuffer)
|
||||
|
||||
CFile.prototype._getFontByID = function(ID)
|
||||
{
|
||||
return null;
|
||||
return g_native_drawing_file["GetFontBinary"](ID);
|
||||
};
|
||||
|
||||
CFile.prototype._getInteractiveFormsFonts = function(type)
|
||||
|
||||
@ -82,7 +82,7 @@ CFile.prototype._getUint8ClampedArray = function(ptr, len)
|
||||
// FILE
|
||||
CFile.prototype._openFile = function(buffer, password)
|
||||
{
|
||||
if (this.stream && buffer)
|
||||
if (buffer)
|
||||
{
|
||||
let data = new Uint8Array(buffer);
|
||||
this.stream_size = data.length;
|
||||
@ -94,7 +94,7 @@ CFile.prototype._openFile = function(buffer, password)
|
||||
if (password)
|
||||
{
|
||||
let passwordBuf = password.toUtf8();
|
||||
let passwordPtr = Module["_malloc"](passwordBuf.length);
|
||||
passwordPtr = Module["_malloc"](passwordBuf.length);
|
||||
Module["HEAP8"].set(passwordBuf, passwordPtr);
|
||||
}
|
||||
|
||||
|
||||
@ -267,6 +267,13 @@ void ReadAnnot(BYTE* pWidgets, int& i)
|
||||
std::cout << "YES AP, ";
|
||||
else
|
||||
std::cout << "NO AP, ";
|
||||
if (nFlags & (1 << 7))
|
||||
{
|
||||
nPathLength = READ_INT(pWidgets + i);
|
||||
i += 4;
|
||||
std::cout << "User ID " << std::string((char*)(pWidgets + i), nPathLength) << ", ";
|
||||
i += nPathLength;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadInteractiveForms(BYTE* pWidgets, int& i)
|
||||
@ -821,7 +828,7 @@ void ReadFileAttachment(BYTE* pAnnots, int& i, int n)
|
||||
RELEASEARRAYOBJECTS(res);
|
||||
}
|
||||
|
||||
void ReadInteractiveFormsFonts(CGraphicsFileDrawing* pGrFile, int nType)
|
||||
void ReadInteractiveFormsFonts(CDrawingFile* pGrFile, int nType)
|
||||
{
|
||||
BYTE* pFonts = GetInteractiveFormsFonts(pGrFile, nType);
|
||||
int nLength = READ_INT(pFonts);
|
||||
@ -923,7 +930,7 @@ int main(int argc, char* argv[])
|
||||
if (!NSFile::CFileBinary::ReadAllBytes(sFilePath, &pFileData, nFileDataLen))
|
||||
return 1;
|
||||
|
||||
CGraphicsFileDrawing* pGrFile = Open(pFileData, (LONG)nFileDataLen, "");
|
||||
CDrawingFile* pGrFile = Open(pFileData, (LONG)nFileDataLen, "");
|
||||
int nError = GetErrorCode(pGrFile);
|
||||
|
||||
if (nError != 0)
|
||||
@ -1084,7 +1091,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// INTERACTIVE FORMS
|
||||
if (false)
|
||||
if (true)
|
||||
{
|
||||
ReadInteractiveFormsFonts(pGrFile, 1);
|
||||
ReadInteractiveFormsFonts(pGrFile, 2);
|
||||
@ -1199,7 +1206,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// ANNOTS
|
||||
if (false)
|
||||
if (true)
|
||||
{
|
||||
BYTE* pAnnots = GetAnnotationsInfo(pGrFile, -1);
|
||||
nLength = READ_INT(pAnnots);
|
||||
@ -1801,6 +1808,13 @@ int main(int argc, char* argv[])
|
||||
free(pAnnotAP);
|
||||
}
|
||||
|
||||
if (true)
|
||||
{
|
||||
BYTE* pScan = ScanPage(pGrFile, nTestPage, 1);
|
||||
if (pScan)
|
||||
free(pScan);
|
||||
}
|
||||
|
||||
Close(pGrFile);
|
||||
RELEASEARRAYOBJECTS(pFileData);
|
||||
RELEASEARRAYOBJECTS(pCMapData);
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#include "../agg-2.4/include/agg_color_rgba.h"
|
||||
#include "../graphics/aggplustypes.h"
|
||||
#include "../graphics/Matrix.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
@ -102,6 +103,23 @@ namespace NSStructures
|
||||
}
|
||||
}
|
||||
|
||||
void set_x_min(float x_min)
|
||||
{
|
||||
x_domain_min = x_min;
|
||||
}
|
||||
void set_x_max(float x_max)
|
||||
{
|
||||
x_domain_max = x_max;
|
||||
}
|
||||
void set_y_min(float y_min)
|
||||
{
|
||||
y_domain_min = y_min;
|
||||
}
|
||||
void set_y_max(float y_max)
|
||||
{
|
||||
y_domain_max = y_max;
|
||||
}
|
||||
|
||||
float get_x_min()
|
||||
{
|
||||
return x_domain_min;
|
||||
@ -386,6 +404,75 @@ namespace NSStructures
|
||||
{
|
||||
discrete_step = 1.0f / n;
|
||||
}
|
||||
void transform(const Aggplus::CMatrix& matrix)
|
||||
{
|
||||
// shading transform
|
||||
auto& point1 = shading.point1;
|
||||
auto& point2 = shading.point2;
|
||||
|
||||
double point1_x = static_cast<double>(point1.x);
|
||||
double point1_y = static_cast<double>(point1.y);
|
||||
double point2_x = static_cast<double>(point2.x);
|
||||
double point2_y = static_cast<double>(point2.y);
|
||||
|
||||
matrix.TransformPoint(point1_x, point1_y);
|
||||
matrix.TransformPoint(point2_x, point2_y);
|
||||
|
||||
point1.x = static_cast<float>(point1_x);
|
||||
point1.y = static_cast<float>(point1_y);
|
||||
point2.x = static_cast<float>(point2_x);
|
||||
point2.y = static_cast<float>(point2_y);
|
||||
|
||||
// triangle transform
|
||||
for (auto& p : shading.triangle)
|
||||
{
|
||||
double triangle_x = static_cast<double>(p.x);
|
||||
double triangle_y = static_cast<double>(p.y);
|
||||
|
||||
matrix.TransformPoint(triangle_x, triangle_y);
|
||||
|
||||
p.x = static_cast<float>(triangle_x);
|
||||
p.y = static_cast<float>(triangle_y);
|
||||
}
|
||||
|
||||
// domains transform
|
||||
double x_domain_min = static_cast<double>(shading.function.get_x_min());
|
||||
double y_domain_min = static_cast<double>(shading.function.get_y_min());
|
||||
double x_domain_max = static_cast<double>(shading.function.get_x_max());
|
||||
double y_domain_max = static_cast<double>(shading.function.get_y_max());
|
||||
|
||||
matrix.TransformPoint(x_domain_min, y_domain_min);
|
||||
matrix.TransformPoint(x_domain_max, y_domain_max);
|
||||
|
||||
shading.function.set_x_min(static_cast<float>(x_domain_min));
|
||||
shading.function.set_y_min(static_cast<float>(y_domain_min));
|
||||
shading.function.set_x_max(static_cast<float>(x_domain_max));
|
||||
shading.function.set_y_max(static_cast<float>(y_domain_max));
|
||||
|
||||
// center transform
|
||||
double center_x = static_cast<double>(centerX);
|
||||
double center_y = static_cast<double>(centerY);
|
||||
|
||||
matrix.TransformPoint(center_x, center_y);
|
||||
|
||||
double p0_x = static_cast<double>(p0.x);
|
||||
double p0_y = static_cast<double>(p0.y);
|
||||
double p1_x = static_cast<double>(p1.x);
|
||||
double p1_y = static_cast<double>(p1.y);
|
||||
|
||||
matrix.TransformPoint(p0_x, p0_y);
|
||||
matrix.TransformPoint(p1_x, p1_y);
|
||||
|
||||
p0.x = static_cast<float>(p0_x);
|
||||
p0.y = static_cast<float>(p0_y);
|
||||
p1.x = static_cast<float>(p1_x);
|
||||
p1.y = static_cast<float>(p1_y);
|
||||
|
||||
// sizes scale
|
||||
double sqrt_det = sqrt(fabs(matrix.Determinant()));
|
||||
r0 *= sqrt_det;
|
||||
r1 *= sqrt_det;
|
||||
}
|
||||
|
||||
Point p0, p1;
|
||||
float r0, r1;
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
include(../../../../Common/3dParty/googletest/googletest.pri)
|
||||
|
||||
TEMPLATE = app
|
||||
CONFIG += console c++14
|
||||
CONFIG -= app_bundle
|
||||
CONFIG += thread
|
||||
CONFIG -= qt
|
||||
|
||||
SOURCES += \
|
||||
tst_booleanoperations.cpp
|
||||
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
CORE_ROOT_DIR = $$PWD/../../../../../core
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
|
||||
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
|
||||
@ -0,0 +1,17 @@
|
||||
isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR)
|
||||
|
||||
isEmpty(GOOGLETEST_DIR) {
|
||||
GOOGLETEST_DIR = ""
|
||||
!isEmpty(GOOGLETEST_DIR) {
|
||||
warning("Using googletest src dir specified at Qt Creator wizard")
|
||||
message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message")
|
||||
}
|
||||
}
|
||||
|
||||
!isEmpty(GOOGLETEST_DIR): {
|
||||
INCLUDEPATH *= "$$GOOGLETEST_DIR/include"
|
||||
|
||||
LIBS *= -L"$$GOOGLETEST_DIR/lib" -lgtest -lgmock
|
||||
} else {
|
||||
LIBS *= -lgtest -lgmock
|
||||
}
|
||||
@ -0,0 +1,459 @@
|
||||
|
||||
//#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "../../GraphicsPath.h"
|
||||
|
||||
using namespace testing;
|
||||
|
||||
TEST(BooleanOperations, NoIntersOutside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 200.0);
|
||||
path1.LineTo(200.0, 200.0);
|
||||
path1.LineTo(200.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(300.0, 300.0);
|
||||
path2.LineTo(300.0, 400.0);
|
||||
path2.LineTo(400.0, 400.0);
|
||||
path2.LineTo(400.0, 300.0);
|
||||
path2.LineTo(300.0, 300.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.MoveTo(300.0, 300.0);
|
||||
resultUnite.LineTo(300.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 300.0);
|
||||
resultUnite.LineTo(300.0, 300.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, NoIntersInside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 400.0);
|
||||
path1.LineTo(400.0, 400.0);
|
||||
path1.LineTo(400.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(300.0, 300.0);
|
||||
path2.LineTo(300.0, 200.0);
|
||||
path2.LineTo(200.0, 200.0);
|
||||
path2.LineTo(200.0, 300.0);
|
||||
path2.LineTo(300.0, 300.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(300.0, 300.0);
|
||||
resultIntersect.LineTo(300.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 300.0);
|
||||
resultIntersect.LineTo(300.0, 300.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 400.0);
|
||||
resultSubtract.LineTo(400.0, 400.0);
|
||||
resultSubtract.LineTo(400.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.MoveTo(300.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(300.0, 200.0);
|
||||
resultSubtract.LineTo(300.0, 300.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, OneIntersOutside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 200.0);
|
||||
path1.LineTo(200.0, 200.0);
|
||||
path1.LineTo(200.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(200.0, 150.0);
|
||||
path2.LineTo(300.0, 150.0);
|
||||
path2.LineTo(250.0, 200.0);
|
||||
path2.LineTo(200.0, 150.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(200.0, 150.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 150.0);
|
||||
resultUnite.LineTo(250.0, 200.0);
|
||||
resultUnite.LineTo(300.0, 150.0);
|
||||
resultUnite.LineTo(200.0, 150.0);
|
||||
resultUnite.LineTo(200.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, OneIntersInside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 200.0);
|
||||
path1.LineTo(200.0, 200.0);
|
||||
path1.LineTo(200.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(200.0, 150.0);
|
||||
path2.LineTo(150.0, 150.0);
|
||||
path2.LineTo(175.0, 175.0);
|
||||
path2.LineTo(200.0, 150.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(200.0, 150.0);
|
||||
resultIntersect.LineTo(150.0, 150.0);
|
||||
resultIntersect.LineTo(175.0, 175.0);
|
||||
resultIntersect.LineTo(200.0, 150.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 200.0);
|
||||
resultUnite.LineTo(200.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(200.0, 150.0);
|
||||
resultSubtract.LineTo(175.0, 175.0);
|
||||
resultSubtract.LineTo(150.0, 150.0);
|
||||
resultSubtract.LineTo(200.0, 150.0);
|
||||
resultSubtract.LineTo(200.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, OverlapOutside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 300.0);
|
||||
path1.LineTo(300.0, 300.0);
|
||||
path1.LineTo(300.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(300.0, 200.0);
|
||||
path2.LineTo(300.0, 400.0);
|
||||
path2.LineTo(400.0, 400.0);
|
||||
path2.LineTo(400.0, 200.0);
|
||||
path2.LineTo(300.0, 200.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(300.0, 300.0);
|
||||
resultIntersect.LineTo(300.0, 200.0);
|
||||
resultIntersect.LineTo(300.0, 300.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 300.0);
|
||||
resultUnite.LineTo(300.0, 300.0);
|
||||
resultUnite.LineTo(300.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 200.0);
|
||||
resultUnite.LineTo(300.0, 200.0);
|
||||
resultUnite.LineTo(300.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 300.0);
|
||||
resultSubtract.LineTo(300.0, 300.0);
|
||||
resultSubtract.LineTo(300.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, OverlapInside)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 400.0);
|
||||
path1.LineTo(400.0, 400.0);
|
||||
path1.LineTo(400.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(200.0, 200.0);
|
||||
path2.LineTo(400.0, 200.0);
|
||||
path2.LineTo(400.0, 300.0);
|
||||
path2.LineTo(200.0, 300.0);
|
||||
path2.LineTo(200.0, 200.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(400.0, 300.0);
|
||||
resultIntersect.LineTo(400.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 300.0);
|
||||
resultIntersect.LineTo(400.0, 300.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 400.0);
|
||||
resultSubtract.LineTo(400.0, 400.0);
|
||||
resultSubtract.LineTo(400.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(400.0, 200.0);
|
||||
resultSubtract.LineTo(400.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, LineIntersLine)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.StartFigure();
|
||||
path1.MoveTo(100.0, 100.0);
|
||||
path1.LineTo(100.0, 300.0);
|
||||
path1.LineTo(300.0, 300.0);
|
||||
path1.LineTo(300.0, 100.0);
|
||||
path1.LineTo(100.0, 100.0);
|
||||
path1.CloseFigure();
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(200.0, 200.0);
|
||||
path2.LineTo(400.0, 200.0);
|
||||
path2.LineTo(400.0, 400.0);
|
||||
path2.LineTo(200.0, 400.0);
|
||||
path2.LineTo(200.0, 200.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(200.0, 300.0);
|
||||
resultIntersect.LineTo(300.0, 300.0);
|
||||
resultIntersect.LineTo(300.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 200.0);
|
||||
resultIntersect.LineTo(200.0, 300.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(100.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 300.0);
|
||||
resultUnite.LineTo(200.0, 300.0);
|
||||
resultUnite.LineTo(200.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 400.0);
|
||||
resultUnite.LineTo(400.0, 200.0);
|
||||
resultUnite.LineTo(300.0, 200.0);
|
||||
resultUnite.LineTo(300.0, 100.0);
|
||||
resultUnite.LineTo(100.0, 100.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(100.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 300.0);
|
||||
resultSubtract.LineTo(200.0, 200.0);
|
||||
resultSubtract.LineTo(300.0, 200.0);
|
||||
resultSubtract.LineTo(300.0, 100.0);
|
||||
resultSubtract.LineTo(100.0, 100.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, CurveIntersLine)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.AddEllipse(-300.0, -300.0, 200.0, 200.0);
|
||||
|
||||
path2.StartFigure();
|
||||
path2.MoveTo(-200.0, -200.0);
|
||||
path2.LineTo(0.0, -200.0);
|
||||
path2.LineTo(0.0, 0.0);
|
||||
path2.LineTo(-200.0, 0.0);
|
||||
path2.LineTo(-200.0, -200.0);
|
||||
path2.CloseFigure();
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(-100.0, -200.0);
|
||||
resultIntersect.CurveTo(-100.0, -144.772, -144.772, -100.0, -200.0, -100.0);
|
||||
resultIntersect.LineTo(-200.0, -200.0);
|
||||
resultIntersect.LineTo(-100.0, -200.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(-100.0, -200.0);
|
||||
resultUnite.LineTo(0.0, -200.0);
|
||||
resultUnite.LineTo(0.0, 0.0);
|
||||
resultUnite.LineTo(-200.0, 0.0);
|
||||
resultUnite.LineTo(-200.0, -100.0);
|
||||
resultUnite.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0);
|
||||
resultUnite.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0);
|
||||
resultUnite.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(-100.0, -200.0);
|
||||
resultSubtract.LineTo(-200.0, -200.0);
|
||||
resultSubtract.LineTo(-200.0, -100.0);
|
||||
resultSubtract.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0);
|
||||
resultSubtract.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0);
|
||||
resultSubtract.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
|
||||
TEST(BooleanOperations, CurveIntersCurve)
|
||||
{
|
||||
Aggplus::CGraphicsPath path1, path2, resultIntersect, resultUnite, resultSubtract;
|
||||
|
||||
path1.AddEllipse(-300.0, -300.0, 200.0, 200.0);
|
||||
|
||||
path2.AddEllipse(-200.0, -200.0, 200.0, 200.0);
|
||||
|
||||
resultIntersect.StartFigure();
|
||||
resultIntersect.MoveTo(-100.0, -200.0);
|
||||
resultIntersect.CurveTo(-100.0, -144.772, -144.772, -100.0, -200.0, -100.0);
|
||||
resultIntersect.CurveTo(-200.0, -155.228, -155.228, -200.0, -100.0, -200.0);
|
||||
resultIntersect.CloseFigure();
|
||||
|
||||
resultUnite.StartFigure();
|
||||
resultUnite.MoveTo(-100.0, -200.0);
|
||||
resultUnite.CurveTo(-44.772, -200.0, 0.0, -155.228, 0.0, -100.0);
|
||||
resultUnite.CurveTo(0.0, -44.772, -44.772, 0.0, -100.0, 0.0);
|
||||
resultUnite.CurveTo(-155.228, 0.0, -200.0, -44.772, -200.0, -100.0);
|
||||
resultUnite.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0);
|
||||
resultUnite.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0);
|
||||
resultUnite.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0);
|
||||
resultUnite.CloseFigure();
|
||||
|
||||
resultSubtract.StartFigure();
|
||||
resultSubtract.MoveTo(-100.0, -200.0);
|
||||
resultSubtract.CurveTo(-155.228, -200.0, -200.0, -155.228, -200.0, -100.0);
|
||||
resultSubtract.CurveTo(-255.228, -100.0, -300.0, -144.772, -300.0, -200.0);
|
||||
resultSubtract.CurveTo(-300.0, -255.228, -255.228, -300.0, -200.0, -300.0);
|
||||
resultSubtract.CurveTo(-144.772, -300.0, -100.0, -255.228, -100.0, -200.0);
|
||||
resultSubtract.CloseFigure();
|
||||
|
||||
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Intersection) == resultIntersect);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Union) == resultUnite);
|
||||
EXPECT_TRUE(Aggplus::CalcBooleanOperation(path1, path2, Aggplus::Subtraction) == resultSubtract);
|
||||
}
|
||||
11
DesktopEditor/graphics/tests/booleanPaths/main.cpp
Normal file
11
DesktopEditor/graphics/tests/booleanPaths/main.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
396
DesktopEditor/graphics/tests/booleanPaths/mainwindow.cpp
Normal file
396
DesktopEditor/graphics/tests/booleanPaths/mainwindow.cpp
Normal file
@ -0,0 +1,396 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include <vector>
|
||||
|
||||
CustomLabel::CustomLabel(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
QPointF CustomLabel::GetStartPoint() const noexcept
|
||||
{
|
||||
return StartP;
|
||||
}
|
||||
|
||||
double CustomLabel::GetDifferenceX() const noexcept
|
||||
{
|
||||
return CurrP.x() - StartP.x();
|
||||
}
|
||||
|
||||
double CustomLabel::GetDifferenceY() const noexcept
|
||||
{
|
||||
return CurrP.y() - StartP.y();
|
||||
}
|
||||
|
||||
bool CustomLabel::GetMovable() const noexcept
|
||||
{
|
||||
return Movable;
|
||||
}
|
||||
|
||||
void CustomLabel::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
StartP = event->pos();
|
||||
Movable = true;
|
||||
emit mousePress();
|
||||
}
|
||||
|
||||
void CustomLabel::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
CurrP = event->pos();
|
||||
Movable = false;
|
||||
emit mousePress();
|
||||
}
|
||||
|
||||
void CustomLabel::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
CurrP = event->pos();
|
||||
emit mouseMove();
|
||||
}
|
||||
|
||||
CustomButton::CustomButton(QWidget *parent) : QPushButton(parent)
|
||||
{
|
||||
}
|
||||
|
||||
BooleanButton::BooleanButton(QWidget *parent) : QPushButton(parent)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<QObject*> GetChildsByClassName(QObject* parent, const QString& name)
|
||||
{
|
||||
std::vector<QObject*> res;
|
||||
foreach (QObject* child, parent->children())
|
||||
{
|
||||
if (QString(child->metaObject()->className()) == name)
|
||||
res.push_back(child);
|
||||
else
|
||||
{
|
||||
if (!child->children().empty())
|
||||
{
|
||||
std::vector<QObject*> resChilds = GetChildsByClassName(child, name);
|
||||
res.insert(res.end(), resChilds.begin(), resChilds.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
Figure1 = "";
|
||||
Figure2 = "";
|
||||
Op = Aggplus::Intersection;
|
||||
|
||||
std::vector<QObject*> arrPathButtons = GetChildsByClassName(this, "CustomButton");
|
||||
std::vector<QObject*> arrBooleanButtons = GetChildsByClassName(this, "BooleanButton");
|
||||
|
||||
for (std::vector<QObject*>::iterator i = arrPathButtons.begin(); i != arrPathButtons.end(); i++)
|
||||
connect((QPushButton*)(*i), &QPushButton::clicked, this, &MainWindow::SetFigure);
|
||||
|
||||
for (std::vector<QObject*>::iterator i = arrBooleanButtons.begin(); i != arrBooleanButtons.end(); i++)
|
||||
connect((QPushButton*)(*i), &QPushButton::clicked, this, &MainWindow::SetCommand);
|
||||
|
||||
Path1.StartFigure();
|
||||
Path1.MoveTo(100.0, 100.0);
|
||||
Path1.LineTo(150.0, 150.0);
|
||||
Path1.LineTo(200.0, 150.0);
|
||||
Path1.LineTo(100.0, 100.0);
|
||||
Path1.CloseFigure();
|
||||
Path1.MoveTo(300.0, 300.0);
|
||||
Path1.LineTo(400.0, 300.0);
|
||||
Path1.LineTo(400.0, 400.0);
|
||||
Path1.LineTo(300.0, 400.0);
|
||||
Path1.LineTo(300.0, 300.0);
|
||||
Path1.CloseFigure();
|
||||
|
||||
Path2.StartFigure();
|
||||
Path2.MoveTo(100.0, 125.0);
|
||||
Path2.LineTo(100.0, 350.0);
|
||||
Path2.LineTo(350.0, 350.0);
|
||||
Path2.LineTo(350.0, 125.0);
|
||||
Path2.LineTo(100.0, 125.0);
|
||||
Path2.CloseFigure();
|
||||
|
||||
Result = Aggplus::CalcBooleanOperation(Path1, Path2, Aggplus::Intersection);
|
||||
Draw(true);
|
||||
}
|
||||
|
||||
void MainWindow::SetFigure()
|
||||
{
|
||||
QPushButton* sender = (QPushButton*)this->sender();
|
||||
|
||||
if (((QGroupBox*)sender->parentWidget())->title() == "Path1")
|
||||
{
|
||||
Figure1 = sender->text();
|
||||
DrawPath1();
|
||||
}
|
||||
|
||||
if (((QGroupBox*)sender->parentWidget())->title() == "Path2")
|
||||
{
|
||||
Figure2 = sender->text();
|
||||
DrawPath2();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::SetCommand()
|
||||
{
|
||||
QString text = ((QPushButton*)sender())->text();
|
||||
if (text == "Unite")
|
||||
Op = Aggplus::Union;
|
||||
else if (text == "Intersect")
|
||||
Op = Aggplus::Intersection;
|
||||
else
|
||||
Op = Aggplus::Subtraction;
|
||||
|
||||
BooleanOp();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
Aggplus::CGraphicsPath MainWindow::SetPath(double scale, double offsetX, double offsetY, QString Figure)
|
||||
{
|
||||
Aggplus::CGraphicsPath path;
|
||||
|
||||
path.StartFigure();
|
||||
if (Figure == "Rectangle")
|
||||
{
|
||||
path.MoveTo(RECTANGLE[0] + offsetX,
|
||||
RECTANGLE[1] + offsetY);
|
||||
path.LineTo(RECTANGLE[0] + scale * RECTANGLE[2] + offsetX,
|
||||
RECTANGLE[1] + offsetY);
|
||||
path.LineTo(RECTANGLE[0] + scale * RECTANGLE[2] + offsetX,
|
||||
RECTANGLE[1] + scale * RECTANGLE[3] + offsetY);
|
||||
path.LineTo(RECTANGLE[0] + offsetX,
|
||||
RECTANGLE[1] + scale * RECTANGLE[3] + offsetY);
|
||||
path.LineTo(RECTANGLE[0] + offsetX,
|
||||
RECTANGLE[1] + offsetY);
|
||||
}
|
||||
else if (Figure == "Ellipse")
|
||||
{
|
||||
path.AddEllipse(RECTANGLE[0] + offsetX,
|
||||
RECTANGLE[1] + offsetY,
|
||||
scale * RECTANGLE[2],
|
||||
scale * RECTANGLE[3]);
|
||||
}
|
||||
else if (Figure == "Triangle")
|
||||
{
|
||||
path.MoveTo(TRIANGLE[0] + offsetX,
|
||||
TRIANGLE[1] + offsetY);
|
||||
for (size_t i = 2; i < std::size(TRIANGLE); i += 2)
|
||||
path.LineTo(TRIANGLE[0] + scale * TRIANGLE[i] + offsetX,
|
||||
TRIANGLE[1] + scale * TRIANGLE[i + 1] + offsetY);
|
||||
path.LineTo(TRIANGLE[0] + offsetX,
|
||||
TRIANGLE[1] + offsetY);
|
||||
}
|
||||
else if (Figure == "Cross")
|
||||
{
|
||||
path.MoveTo(CROSS[0] + offsetX,
|
||||
CROSS[1] + offsetY);
|
||||
for (size_t i = 2; i < std::size(CROSS); i += 2)
|
||||
path.LineTo(CROSS[0] + scale * CROSS[i] + offsetX,
|
||||
CROSS[1] + scale * CROSS[i + 1] + offsetY);
|
||||
path.LineTo(CROSS[0] + offsetX,
|
||||
CROSS[1] + offsetY);
|
||||
}
|
||||
path.CloseFigure();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void MainWindow::AddPath(NSGraphics::IGraphicsRenderer* pathRenderer, const Aggplus::CGraphicsPath& path, bool isResult)
|
||||
{
|
||||
if (path.GetPointCount() == 0)
|
||||
return;
|
||||
|
||||
pathRenderer->PathCommandStart();
|
||||
pathRenderer->BeginCommand(c_nPathType);
|
||||
|
||||
size_t length = path.GetPointCount(),
|
||||
compound = path.GetCloseCount();
|
||||
std::vector<Aggplus::PointD> points = path.GetPoints(0, length + compound);
|
||||
|
||||
for (size_t i = 0; i < length + compound; i++)
|
||||
{
|
||||
if (path.IsCurvePoint(i))
|
||||
{
|
||||
pathRenderer->PathCommandCurveTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET,
|
||||
points[i + 1].X + NEGATIVE_OFFSET, points[i + 1].Y + NEGATIVE_OFFSET,
|
||||
points[i + 2].X + NEGATIVE_OFFSET, points[i + 2].Y + NEGATIVE_OFFSET);
|
||||
i += 2;
|
||||
}
|
||||
else if (path.IsMovePoint(i))
|
||||
pathRenderer->PathCommandMoveTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET);
|
||||
else if (path.IsLinePoint(i))
|
||||
pathRenderer->PathCommandLineTo(points[i].X + NEGATIVE_OFFSET, points[i].Y + NEGATIVE_OFFSET);
|
||||
}
|
||||
|
||||
if (isResult)
|
||||
{
|
||||
pathRenderer->put_BrushColor1(0xFF0000);
|
||||
pathRenderer->Fill();
|
||||
}
|
||||
|
||||
pathRenderer->put_PenColor(!isResult ? 0x000000 : 0x0000FF);
|
||||
pathRenderer->DrawPath(c_nStroke);
|
||||
|
||||
pathRenderer->EndCommand(c_nPathType);
|
||||
pathRenderer->PathCommandEnd();
|
||||
}
|
||||
|
||||
void MainWindow::Draw(bool drawResult)
|
||||
{
|
||||
ui->label->clear();
|
||||
|
||||
NSGraphics::IGraphicsRenderer* pathRenderer = NSGraphics::Create();
|
||||
NSFonts::IFontManager* fmp = NSFonts::NSFontManager::Create();
|
||||
pathRenderer->SetFontManager(fmp);
|
||||
|
||||
int nW = ui->label->width();
|
||||
int nH = ui->label->height();
|
||||
|
||||
BYTE* pData = new BYTE[4 * nW * nH];
|
||||
|
||||
CBgraFrame oFrame;
|
||||
oFrame.put_Data(pData);
|
||||
oFrame.put_Width(nW);
|
||||
oFrame.put_Height(nH);
|
||||
oFrame.put_Stride(4 * nW);
|
||||
|
||||
pathRenderer->CreateFromBgraFrame(&oFrame);
|
||||
pathRenderer->SetSwapRGB(true);
|
||||
|
||||
pathRenderer->put_Width(nW);
|
||||
pathRenderer->put_Height(nH);
|
||||
|
||||
AddPath(pathRenderer, Path1);
|
||||
AddPath(pathRenderer, Path2);
|
||||
|
||||
if (drawResult)
|
||||
{
|
||||
AddPath(pathRenderer, Result, true);
|
||||
}
|
||||
|
||||
QImage img = QImage(pData, nW, nH, QImage::Format_RGBA8888, [](void *data){
|
||||
delete [] (BYTE*)data;
|
||||
});
|
||||
ui->label->setPixmap(QPixmap::fromImage(img));
|
||||
}
|
||||
|
||||
void MainWindow::SetCoords(QLabel *label, const Aggplus::CGraphicsPath& path)
|
||||
{
|
||||
size_t length = path.GetPointCount();
|
||||
std::vector<Aggplus::PointD> points = path.GetPoints(0, length);
|
||||
QString text = "";
|
||||
|
||||
for (size_t i = 0; i < length; i++)
|
||||
text += "(" + QString::number(points[i].X) +
|
||||
"; " + QString::number(points[i].Y) + "); ";
|
||||
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void MainWindow::DrawPath1()
|
||||
{
|
||||
if (Path1.GetPointCount() > 0) Path1.Reset();
|
||||
Path1 = SetPath(Scale[0], Offsets[0], Offsets[1], Figure1);
|
||||
Draw();
|
||||
SetCoords(ui->label_4, Path1);
|
||||
}
|
||||
|
||||
void MainWindow::DrawPath2()
|
||||
{
|
||||
if (Path2.GetPointCount() > 0) Path2.Reset();
|
||||
Path2 = SetPath(Scale[1], Offsets[2], Offsets[3], Figure2);
|
||||
Draw();
|
||||
SetCoords(ui->label_5, Path2);
|
||||
}
|
||||
|
||||
void MainWindow::BooleanOp()
|
||||
{
|
||||
if (Path1.GetPointCount() == 0 || Path2.GetPointCount() == 0)
|
||||
return;
|
||||
|
||||
Result = Aggplus::CalcBooleanOperation(Path1, Path2, Op);
|
||||
Draw(true);
|
||||
SetCoords(ui->label_7, Result);
|
||||
}
|
||||
|
||||
void MainWindow::CheckMousePress()
|
||||
{
|
||||
if (!ui->label->GetMovable())
|
||||
{
|
||||
Move1 = false;
|
||||
Move2 = false;
|
||||
disconnect(ui->label, SIGNAL(mouseMove()), this, SLOT(Move()));
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF rect1(RECTANGLE[0] + NEGATIVE_OFFSET + Offsets[0],
|
||||
RECTANGLE[1] + NEGATIVE_OFFSET + Offsets[1],
|
||||
Scale[0] * RECTANGLE[2],
|
||||
Scale[0] * RECTANGLE[3]),
|
||||
rect2(RECTANGLE[0] + NEGATIVE_OFFSET + Offsets[2],
|
||||
RECTANGLE[1] + NEGATIVE_OFFSET + Offsets[3],
|
||||
Scale[1] * RECTANGLE[2],
|
||||
Scale[1] * RECTANGLE[3]);
|
||||
|
||||
Move1 = rect1.contains(ui->label->GetStartPoint()) && Path1.GetPointCount() != 0;
|
||||
Move2 = rect2.contains(ui->label->GetStartPoint()) && Path2.GetPointCount() != 0;
|
||||
if (Move2)
|
||||
Move1 = false;
|
||||
if (Move1 || Move2)
|
||||
{
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
OldOffsets[i] = Offsets[i];
|
||||
connect(ui->label, SIGNAL(mouseMove()), this, SLOT(Move()));
|
||||
}
|
||||
}
|
||||
|
||||
inline double CheckOffset(double offset, double min, double max)
|
||||
{
|
||||
return std::max(min, std::min(max, offset));
|
||||
}
|
||||
|
||||
void MainWindow::Move()
|
||||
{
|
||||
if (Move1)
|
||||
{
|
||||
Offsets[0] = CheckOffset(OldOffsets[0] + ui->label->GetDifferenceX(),
|
||||
static_cast<double>(ui->label->x()),
|
||||
static_cast<double>(ui->label->width()));
|
||||
Offsets[1] = CheckOffset(OldOffsets[1] + ui->label->GetDifferenceY(),
|
||||
static_cast<double>(ui->label->y()),
|
||||
static_cast<double>(ui->label->height()));
|
||||
DrawPath1();
|
||||
}
|
||||
if (Move2)
|
||||
{
|
||||
Offsets[2] = CheckOffset(OldOffsets[2] + ui->label->GetDifferenceX(),
|
||||
static_cast<double>(ui->label->x()),
|
||||
static_cast<double>(ui->label->width()));
|
||||
Offsets[3] = CheckOffset(OldOffsets[3] + ui->label->GetDifferenceY(),
|
||||
static_cast<double>(ui->label->y()),
|
||||
static_cast<double>(ui->label->height()));
|
||||
DrawPath2();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_horizontalSlider_sliderMoved(int position)
|
||||
{
|
||||
Scale[0] = position / 100.0;
|
||||
DrawPath1();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_horizontalSlider_2_sliderMoved(int position)
|
||||
{
|
||||
Scale[1] = position / 100.0;
|
||||
DrawPath2();
|
||||
}
|
||||
|
||||
111
DesktopEditor/graphics/tests/booleanPaths/mainwindow.h
Normal file
111
DesktopEditor/graphics/tests/booleanPaths/mainwindow.h
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QPoint>
|
||||
#include <QMouseEvent>
|
||||
#include "../../pro/Graphics.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
const double NEGATIVE_OFFSET= 400.0;
|
||||
const double RECTANGLE[4] = {-400.0, -400.0, 200.0, 200.0};
|
||||
const double TRIANGLE[6] = {-300.0, -400.0, 100.0, 200.0, -100.0, 100.0};
|
||||
const double CROSS[24] = {-375.0, -325.0, 50.0, 0.0, 50.0, -50.0,
|
||||
100.0, -50.0, 100.0, 0.0, 150.0, 0.0,
|
||||
150.0, 50.0, 100.0, 50.0, 100.0, 100.0,
|
||||
50.0, 100.0, 50.0, 50.0, 0.0, 50.0};
|
||||
|
||||
class CustomLabel : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CustomLabel(QWidget *parent = nullptr);
|
||||
|
||||
QPointF GetStartPoint() const noexcept;
|
||||
double GetDifferenceX() const noexcept;
|
||||
double GetDifferenceY() const noexcept;
|
||||
bool GetMovable() const noexcept;
|
||||
|
||||
signals:
|
||||
void mousePress();
|
||||
void mouseMove();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool Movable = false;
|
||||
QPointF StartP = {0.0, 0.0};
|
||||
QPointF CurrP = {0.0, 0.0};
|
||||
};
|
||||
|
||||
class CustomButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CustomButton(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
class BooleanButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BooleanButton(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
Aggplus::CGraphicsPath SetPath(double scale, double offsetX, double offsetY, QString Figure);
|
||||
void AddPath(NSGraphics::IGraphicsRenderer* pathRenderer, const Aggplus::CGraphicsPath& path, bool isResult = false);
|
||||
void Draw(bool drawResult = false);
|
||||
void SetCoords(QLabel* label, const Aggplus::CGraphicsPath& path);
|
||||
|
||||
void DrawPath1();
|
||||
void DrawPath2();
|
||||
void BooleanOp();
|
||||
|
||||
private slots:
|
||||
void CheckMousePress();
|
||||
void Move();
|
||||
void SetCommand();
|
||||
void SetFigure();
|
||||
void on_horizontalSlider_sliderMoved(int position);
|
||||
void on_horizontalSlider_2_sliderMoved(int position);
|
||||
|
||||
public:
|
||||
QString Figure1;
|
||||
QString Figure2;
|
||||
Aggplus::BooleanOpType Op;
|
||||
|
||||
double Scale[2] = {1.0, 1.0};
|
||||
double Offsets[4] = {100.0, 100.0, 200.0, 200.0};
|
||||
double OldOffsets[4];
|
||||
|
||||
bool Move1 = false;
|
||||
bool Move2 = false;
|
||||
|
||||
Aggplus::CGraphicsPath Path1;
|
||||
Aggplus::CGraphicsPath Path2;
|
||||
Aggplus::CGraphicsPath Result;
|
||||
|
||||
Ui::MainWindow *ui;
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
437
DesktopEditor/graphics/tests/booleanPaths/mainwindow.ui
Normal file
437
DesktopEditor/graphics/tests/booleanPaths/mainwindow.ui
Normal file
@ -0,0 +1,437 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1441</width>
|
||||
<height>859</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="CustomLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>800</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>810</x>
|
||||
<y>0</y>
|
||||
<width>610</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>191</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Path1</string>
|
||||
</property>
|
||||
<widget class="CustomButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>40</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rectangle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>80</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ellipse</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>120</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Triangle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>250</y>
|
||||
<width>63</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Coords:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>270</y>
|
||||
<width>170</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>230</y>
|
||||
<width>160</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>210</y>
|
||||
<width>63</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_8">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>160</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cross</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>210</x>
|
||||
<y>10</y>
|
||||
<width>191</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Path2</string>
|
||||
</property>
|
||||
<widget class="CustomButton" name="pushButton_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>40</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rectangle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_10">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>80</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Ellipse</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_12">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>120</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Triangle</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>250</y>
|
||||
<width>63</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Coords:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>270</y>
|
||||
<width>170</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSlider" name="horizontalSlider_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>230</y>
|
||||
<width>160</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>210</y>
|
||||
<width>63</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="CustomButton" name="pushButton_9">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>160</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cross</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>410</x>
|
||||
<y>10</y>
|
||||
<width>191</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Result</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>250</y>
|
||||
<width>63</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Coords:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>270</y>
|
||||
<width>170</width>
|
||||
<height>200</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="BooleanButton" name="pushButton_15">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>120</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Subtract</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="BooleanButton" name="pushButton_16">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>80</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Intersect</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="BooleanButton" name="pushButton_17">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>40</y>
|
||||
<width>83</width>
|
||||
<height>29</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1441</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CustomButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>mainwindow.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>BooleanButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>mainwindow.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>CustomLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>mainwindow.h</header>
|
||||
<slots>
|
||||
<signal>mousePress()</signal>
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>label</sender>
|
||||
<signal>mousePress()</signal>
|
||||
<receiver>MainWindow</receiver>
|
||||
<slot>CheckMousePress()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>249</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>561</x>
|
||||
<y>276</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>CheckMousePress()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
20
DesktopEditor/graphics/tests/booleanPaths/test.pro
Normal file
20
DesktopEditor/graphics/tests/booleanPaths/test.pro
Normal file
@ -0,0 +1,20 @@
|
||||
QT += core gui widgets
|
||||
|
||||
QMAKE_CXXFLAGS += /permissive-
|
||||
|
||||
SOURCES += \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
CORE_ROOT_DIR = $$PWD/../../../../../core
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
|
||||
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
|
||||
@ -1028,6 +1028,8 @@ l_uint32 *line;
|
||||
pos = (qpos + i) % 8;
|
||||
npx = px + xpostab[pos];
|
||||
npy = py + ypostab[pos];
|
||||
if (npx < 0 || npx >= w || npy < 0 || npy >= h)
|
||||
continue;
|
||||
line = data + npy * wpl;
|
||||
val = GET_DATA_BIT(line, npx);
|
||||
if (val) {
|
||||
|
||||
@ -3228,7 +3228,7 @@ l_int32 i, j, w, h, wplc, wplm, wpld, ncolors, index;
|
||||
l_int32 rval, gval, bval, val, minval, maxval;
|
||||
l_int32 *lut;
|
||||
l_uint32 *datac, *datam, *datad, *linec, *linem, *lined;
|
||||
PIX *pixc, *pixm, *pixg, *pixd;
|
||||
PIX *pix1, *pixc, *pixm, *pixg, *pixd;
|
||||
PIXCMAP *cmap, *cmapd;
|
||||
|
||||
PROCNAME("pixFewColorsOctcubeQuantMixed");
|
||||
@ -3245,8 +3245,10 @@ PIXCMAP *cmap, *cmapd;
|
||||
if (maxspan <= 2) maxspan = 15;
|
||||
|
||||
/* Start with a simple fixed octcube quantizer. */
|
||||
if ((pixc = pixFewColorsOctcubeQuant1(pixs, level)) == NULL)
|
||||
if ((pix1 = pixFewColorsOctcubeQuant1(pixs, level)) == NULL)
|
||||
return (PIX *)ERROR_PTR("too many colors", procName, NULL);
|
||||
pixc = pixConvertTo8(pix1, 1); /* must be 8 bpp */
|
||||
pixDestroy(&pix1);
|
||||
|
||||
/* Identify and save color entries in the colormap. Set up a LUT
|
||||
* that returns -1 for any gray pixel. */
|
||||
|
||||
@ -45,7 +45,7 @@ namespace MetaFile
|
||||
{
|
||||
public:
|
||||
IMetaFileBase()
|
||||
: m_pOutput(NULL), m_pBufferData(NULL), m_bIsExternalBuffer(false), m_bError(false), m_pParent(NULL)
|
||||
: m_pOutput(NULL), m_pParent(NULL), m_pBufferData(NULL), m_bIsExternalBuffer(false), m_bError(false)
|
||||
{
|
||||
m_oStream.SetStream(NULL, 0);
|
||||
}
|
||||
|
||||
@ -1167,23 +1167,29 @@ namespace MetaFile
|
||||
|
||||
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
|
||||
|
||||
std::wstring wsFontName = pFont->GetFaceName();
|
||||
NSStringUtils::CStringBuilder oFontName;
|
||||
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
|
||||
|
||||
#ifndef BUILDING_WASM_MODULE
|
||||
if (!wsFontName.empty())
|
||||
if (0 != oFontName.GetSize())
|
||||
{
|
||||
#ifndef BUILDING_WASM_MODULE
|
||||
NSFonts::CFontSelectFormat oFormat;
|
||||
oFormat.wsName = new std::wstring(pFont->GetFaceName());
|
||||
|
||||
NSFonts::CFontInfo *pFontInfo = m_pParser->GetFontManager()->GetFontInfoByParams(oFormat);
|
||||
|
||||
if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName))
|
||||
wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'";
|
||||
if (NULL != pFontInfo && !StringEquals(*oFormat.wsName, pFontInfo->m_wsFontName))
|
||||
{
|
||||
oFontName.Clear();
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
oFontName.WriteEncodeXmlString(*oFormat.wsName);
|
||||
oFontName.WriteEncodeXmlString(L"\',\'");
|
||||
oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName);
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
}
|
||||
#endif
|
||||
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!wsFontName.empty())
|
||||
arNodeAttributes.push_back({L"font-family", wsFontName});
|
||||
|
||||
if (pFont->GetWeight() > 550)
|
||||
arNodeAttributes.push_back({L"font-weight", L"bold"});
|
||||
@ -1227,7 +1233,7 @@ namespace MetaFile
|
||||
{L"rx", ConvertToWString((oNewRect.Right - oNewRect.Left) / 2)},
|
||||
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
|
||||
@ -177,7 +177,8 @@ namespace MetaFile
|
||||
|
||||
std::wstring CEmfLogFont::GetFaceName() const
|
||||
{
|
||||
return NSFile::CUtf8Converter::GetWStringFromUTF16(oLogFontEx.oLogFont.ushFaceName, 32);
|
||||
const std::wstring wsFaceName{NSFile::CUtf8Converter::GetWStringFromUTF16(oLogFontEx.oLogFont.ushFaceName, 32)};
|
||||
return wsFaceName.substr(0, wsFaceName.find(L'\0'));
|
||||
}
|
||||
|
||||
int CEmfLogFont::GetWeight() const
|
||||
|
||||
@ -177,7 +177,8 @@ namespace MetaFile
|
||||
: m_bBanEmfProcessing(true),
|
||||
m_unLogicalDpiX(96),
|
||||
m_unLogicalDpiY(96),
|
||||
m_dUnitKoef(1)
|
||||
m_dPageTransformX(1.),
|
||||
m_dPageTransformY(1.)
|
||||
{
|
||||
m_oHeader = oHeader;
|
||||
|
||||
@ -1370,16 +1371,19 @@ namespace MetaFile
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::UpdateMatrix(TEmfPlusXForm &oMatrix)
|
||||
double CEmfPlusParser::GetUnitToPixel(const double& dDpi, EEmfPlusUnitType eUnitType) const
|
||||
{
|
||||
const double dKoef{m_dUnitKoef * (m_unLogicalDpiX / 96)};
|
||||
|
||||
oMatrix.M11 *= dKoef;
|
||||
oMatrix.M12 *= dKoef;
|
||||
oMatrix.M21 *= dKoef;
|
||||
oMatrix.M22 *= dKoef;
|
||||
oMatrix.Dx *= dKoef;
|
||||
oMatrix.Dy *= dKoef;
|
||||
switch (eUnitType)
|
||||
{
|
||||
case UnitTypePixel:
|
||||
case UnitTypeWorld:
|
||||
case UnitTypeDisplay:
|
||||
default: return 1.;
|
||||
case UnitTypePoint: return dDpi / 72.;
|
||||
case UnitTypeInch: return dDpi;
|
||||
case UnitTypeDocument: return dDpi / 300.;
|
||||
case UnitTypeMillimeter: return dDpi / 25.4;
|
||||
}
|
||||
}
|
||||
|
||||
bool CEmfPlusParser::SaveImage(const CEmfPlusImage &oEmfPlusImage, std::wstring &wsPathToImage)
|
||||
@ -1412,47 +1416,50 @@ namespace MetaFile
|
||||
return true;
|
||||
}
|
||||
|
||||
BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, TRectL& oNewRect)
|
||||
BYTE* GetClipedImage(const BYTE* pBuffer, LONG lWidth, LONG lHeight, const TRectL& oNewRect, unsigned int& nWidth, unsigned int& nHeight)
|
||||
{
|
||||
if (NULL == pBuffer ||
|
||||
oNewRect.Left < 0 || oNewRect.Right < 0 ||
|
||||
oNewRect.Top < 0 || oNewRect.Bottom < 0)
|
||||
if (NULL == pBuffer)
|
||||
return NULL;
|
||||
|
||||
if (lHeight < (oNewRect.Bottom - oNewRect.Top))
|
||||
oNewRect.Bottom = oNewRect.Top + lHeight;
|
||||
int nBeginX = (std::min)(oNewRect.Left, oNewRect.Right);
|
||||
int nBeginY = (std::min)(oNewRect.Top, oNewRect.Bottom);
|
||||
|
||||
if (lWidth < (oNewRect.Right - oNewRect.Left))
|
||||
oNewRect.Right = oNewRect.Left + lWidth;
|
||||
int nEndX = (std::max)(oNewRect.Left, oNewRect.Right);
|
||||
int nEndY = (std::max)(oNewRect.Top, oNewRect.Bottom);
|
||||
|
||||
if (lHeight == (oNewRect.Bottom - oNewRect.Top) &&
|
||||
lWidth == (oNewRect.Right - oNewRect.Left))
|
||||
if (nBeginX >= lWidth || nEndX <= 0)
|
||||
return NULL;
|
||||
if (nBeginY >= lHeight || nEndY <= 0)
|
||||
return NULL;
|
||||
|
||||
int nBeginX, nBeginY, nEndX, nEndY;
|
||||
if (nBeginX <= 0 && nEndX >= lWidth &&
|
||||
nBeginY <= 0 && nEndY >= lHeight)
|
||||
return NULL;
|
||||
|
||||
nBeginX = (std::min)(oNewRect.Left, oNewRect.Right);
|
||||
nBeginY = (std::min)(oNewRect.Top, oNewRect.Bottom);
|
||||
if (nBeginX < 0)
|
||||
nBeginX = 0;
|
||||
if (nBeginY < 0)
|
||||
nBeginY = 0;
|
||||
|
||||
nEndX = (std::max)(oNewRect.Left, oNewRect.Right);
|
||||
nEndY = (std::max)(oNewRect.Top, oNewRect.Bottom);
|
||||
if (nEndX > lWidth)
|
||||
nEndX = lWidth;
|
||||
if (nEndY > lHeight)
|
||||
nEndY = lHeight;
|
||||
|
||||
int nWidth = nEndX - nBeginX;
|
||||
int nHeight = nEndY - nBeginY;
|
||||
if (nEndX <= nBeginX || nEndY <= nBeginY)
|
||||
return NULL;
|
||||
|
||||
nWidth = nEndX - nBeginX;
|
||||
nHeight = nEndY - nBeginY;
|
||||
|
||||
BYTE* pNewBuffer = new BYTE[nWidth * nHeight * 4];
|
||||
BYTE* pCurrentLine = pNewBuffer;
|
||||
|
||||
ULONG ulPos = 0;
|
||||
|
||||
for (ULONG ulPosY = nBeginY * 4; ulPosY < nEndY * 4; ulPosY += 4)
|
||||
int ulStride = 4 * nWidth;
|
||||
for (int nPosY = nBeginY; nPosY < nEndY; ++nPosY)
|
||||
{
|
||||
for (ULONG ulPosX = nBeginX * 4; ulPosX < nEndX * 4; ulPosX += 4)
|
||||
{
|
||||
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 0];
|
||||
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 1];
|
||||
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 2];
|
||||
pNewBuffer[ulPos++] = (BYTE)pBuffer[ulPosY * lWidth + ulPosX + 3];
|
||||
}
|
||||
memcpy(pCurrentLine, pBuffer + lWidth * 4 * nPosY + 4 * nBeginX, ulStride);
|
||||
pCurrentLine += ulStride;
|
||||
}
|
||||
|
||||
return pNewBuffer;
|
||||
@ -1463,29 +1470,18 @@ namespace MetaFile
|
||||
if (NULL == pImageBuffer || lWidth == 0 || lHeight == 0)
|
||||
return S_FALSE;
|
||||
|
||||
BYTE oBuffer[4] = {0, 0, 0, 0};
|
||||
BYTE* pTempLine = (BYTE*)malloc(lWidth * 4);
|
||||
const ULONG ulStride = 4 * lWidth;
|
||||
|
||||
for (ULONG ulPosY = 0; ulPosY < lHeight / 2 * 4; ulPosY += 4)
|
||||
for (UINT nPosY = 0; nPosY < lHeight / 2; ++nPosY)
|
||||
{
|
||||
for (ULONG ulPosX = 0; ulPosX < lWidth * 4; ulPosX += 4)
|
||||
{
|
||||
oBuffer[0] = pImageBuffer[ulPosY * lWidth + ulPosX + 0];
|
||||
oBuffer[1] = pImageBuffer[ulPosY * lWidth + ulPosX + 1];
|
||||
oBuffer[2] = pImageBuffer[ulPosY * lWidth + ulPosX + 2];
|
||||
oBuffer[3] = pImageBuffer[ulPosY * lWidth + ulPosX + 3];
|
||||
|
||||
pImageBuffer[ulPosY * lWidth + ulPosX + 0] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 0];
|
||||
pImageBuffer[ulPosY * lWidth + ulPosX + 1] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 1];
|
||||
pImageBuffer[ulPosY * lWidth + ulPosX + 2] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 2];
|
||||
pImageBuffer[ulPosY * lWidth + ulPosX + 3] = pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 3];
|
||||
|
||||
pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 0] = oBuffer[0];
|
||||
pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 1] = oBuffer[1];
|
||||
pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 2] = oBuffer[2];
|
||||
pImageBuffer[((lHeight - 1) * 4 - ulPosY) * lWidth + ulPosX + 3] = oBuffer[3];
|
||||
}
|
||||
memcpy(pTempLine, pImageBuffer + nPosY * ulStride, ulStride);
|
||||
memcpy(pImageBuffer + nPosY * ulStride, pImageBuffer + (lHeight - nPosY - 1) * ulStride, ulStride);
|
||||
memcpy(pImageBuffer + (lHeight - nPosY - 1) * ulStride, pTempLine, ulStride);
|
||||
}
|
||||
|
||||
free(pTempLine);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -1633,18 +1629,17 @@ namespace MetaFile
|
||||
|
||||
TRectL oClipRect;
|
||||
|
||||
oClipRect.Left = oSrcRect.dX * dScale;
|
||||
oClipRect.Top = oSrcRect.dY * dScale;
|
||||
oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth) * dScale;
|
||||
oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight) * dScale;
|
||||
oClipRect.Left = std::floor((oSrcRect.dX - oFileBounds.Left) * dScale);
|
||||
oClipRect.Top = std::floor((oSrcRect.dY - oFileBounds.Top) * dScale);
|
||||
oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth - oFileBounds.Left) * dScale);
|
||||
oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight - oFileBounds.Top) * dScale);
|
||||
|
||||
BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect);
|
||||
|
||||
const unsigned int unWidth = std::min(((unsigned int)fabs(oClipRect.Right - oClipRect.Left)), ((unsigned int)nWidth ));
|
||||
const unsigned int unHeight = std::min(((unsigned int)fabs(oClipRect.Bottom - oClipRect.Top)), ((unsigned int)nHeight));
|
||||
unsigned int nW = (unsigned int)nWidth;
|
||||
unsigned int nH = (unsigned int)nHeight;
|
||||
BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect, nW, nH);
|
||||
|
||||
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(),
|
||||
(NULL != pNewBuffer) ? pNewBuffer : pPixels, unWidth, unHeight);
|
||||
(NULL != pNewBuffer) ? pNewBuffer : pPixels, nW, nH);
|
||||
|
||||
RELEASEINTERFACE(pGrRenderer);
|
||||
RELEASEARRAYOBJECTS(pNewBuffer);
|
||||
@ -1655,8 +1650,6 @@ namespace MetaFile
|
||||
|
||||
oParser.PlayFile();
|
||||
|
||||
const TXForm& oXForm{m_pDC->GetTransform()};
|
||||
|
||||
TRectD oRect;
|
||||
|
||||
oRect.Left = arPoints[0].X;
|
||||
@ -1671,9 +1664,7 @@ namespace MetaFile
|
||||
oTempSrcRect.Right = oTempSrcRect.Left + ((dFileWidth > oSrcRect.dWidth) ? oSrcRect.dWidth - GetPixelWidth() : dFileWidth);
|
||||
oTempSrcRect.Bottom = oTempSrcRect.Top + ((dFileHeight > oSrcRect.dHeight) ? oSrcRect.dHeight - GetPixelHeight() : dFileHeight);
|
||||
|
||||
TXForm oTransform;
|
||||
|
||||
oTransform.Copy(oXForm);
|
||||
TXForm oTransform(m_pDC->GetTransform());
|
||||
|
||||
oTransform.Dx -= m_oHeader.oFramePx.Left;
|
||||
oTransform.Dy -= m_oHeader.oFramePx.Top;
|
||||
@ -1717,15 +1708,17 @@ namespace MetaFile
|
||||
|
||||
TRectL oClipRect;
|
||||
|
||||
oClipRect.Left = oSrcRect.dX;
|
||||
oClipRect.Top = oSrcRect.dY;
|
||||
oClipRect.Right = (oSrcRect.dX + oSrcRect.dWidth);
|
||||
oClipRect.Bottom = (oSrcRect.dY + oSrcRect.dHeight);
|
||||
oClipRect.Left = std::floor(oSrcRect.dX);
|
||||
oClipRect.Top = std::floor(oSrcRect.dY);
|
||||
oClipRect.Right = std::floor((oSrcRect.dX + oSrcRect.dWidth));
|
||||
oClipRect.Bottom = std::floor((oSrcRect.dY + oSrcRect.dHeight));
|
||||
|
||||
BYTE* pNewBuffer = GetClipedImage(pBytes, unWidth, unHeight, oClipRect);
|
||||
unsigned int nW = (unsigned int)unWidth;
|
||||
unsigned int nH = (unsigned int)unHeight;
|
||||
BYTE* pNewBuffer = GetClipedImage(pBytes, unWidth, unHeight, oClipRect, nW, nH);
|
||||
|
||||
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X, arPoints[2].Y - arPoints[0].Y,
|
||||
(NULL != pNewBuffer) ? pNewBuffer : pBytes, fabs(oClipRect.Right - oClipRect.Left), fabs(oClipRect.Bottom - oClipRect.Top));
|
||||
(NULL != pNewBuffer) ? pNewBuffer : pBytes, nW, nH);
|
||||
|
||||
if (!bExternalBuffer)
|
||||
RELEASEARRAYOBJECTS(pBytes);
|
||||
@ -3183,24 +3176,16 @@ namespace MetaFile
|
||||
m_bBanEmfProcessing = true;
|
||||
|
||||
short shPageUnit = ExpressValue(unShFlags, 0, 7);
|
||||
double dUnitKoef;
|
||||
|
||||
m_oStream >> m_dUnitKoef;
|
||||
m_oStream >> dUnitKoef;
|
||||
|
||||
switch (shPageUnit)
|
||||
{
|
||||
case UnitTypePixel:
|
||||
case UnitTypeWorld:
|
||||
case UnitTypeDisplay:
|
||||
default: break;
|
||||
case UnitTypePoint: m_dUnitKoef *= m_unLogicalDpiX * 72.f; break;
|
||||
case UnitTypeInch: m_dUnitKoef *= m_unLogicalDpiX; break;
|
||||
case UnitTypeDocument: m_dUnitKoef *= m_unLogicalDpiX / 300.f; break;
|
||||
case UnitTypeMillimeter: m_dUnitKoef *= m_unLogicalDpiX / 25.4f; break;
|
||||
}
|
||||
m_dPageTransformX = dUnitKoef * GetUnitToPixel(m_unLogicalDpiX, static_cast<EEmfPlusUnitType>(shPageUnit));
|
||||
m_dPageTransformY = dUnitKoef * GetUnitToPixel(m_unLogicalDpiY, static_cast<EEmfPlusUnitType>(shPageUnit));
|
||||
|
||||
TXForm oMatrix(m_dUnitKoef, 0, 0, m_dUnitKoef, 0, 0);
|
||||
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
|
||||
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, MWT_LEFTMULTIPLY);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
@ -3210,9 +3195,11 @@ namespace MetaFile
|
||||
|
||||
m_oStream >> oMatrix;
|
||||
|
||||
UpdateMatrix(oMatrix);
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, MWT_SET);
|
||||
|
||||
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
|
||||
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
|
||||
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +87,7 @@ namespace MetaFile
|
||||
template<typename T> std::vector<TEmfPlusPointF> GetConvertedPoints(std::vector<T>arPoints);
|
||||
template<typename T> TEmfPlusRectF GetConvertedRectangle(T oRectangle);
|
||||
|
||||
void UpdateMatrix(TEmfPlusXForm& oMatrix);
|
||||
double GetUnitToPixel(const double& dDpi, EEmfPlusUnitType eUnitType) const;
|
||||
|
||||
bool SaveImage(const CEmfPlusImage& oImage, std::wstring& wsPathToImage);
|
||||
|
||||
@ -176,7 +176,8 @@ namespace MetaFile
|
||||
unsigned int m_unLogicalDpiX;
|
||||
unsigned int m_unLogicalDpiY;
|
||||
|
||||
double m_dUnitKoef;
|
||||
double m_dPageTransformX;
|
||||
double m_dPageTransformY;
|
||||
|
||||
typedef std::map<unsigned int, CEmfPlusObject*> EmfPlusObjects;
|
||||
|
||||
|
||||
@ -469,8 +469,8 @@ namespace MetaFile
|
||||
|
||||
// Обновляем обратную матрицу
|
||||
TEmfXForm* pT = &m_oTransform;
|
||||
double dDet = pT->M11 * pT->M22 - pT->M12 * pT->M21;
|
||||
if (dDet < 0.0001 && dDet > 0.0001)
|
||||
const double dDet = pT->M11 * pT->M22 - pT->M12 * pT->M21;
|
||||
if (Equals(0., dDet, 0.0001))
|
||||
{
|
||||
m_oInverseTransform.M11 = 1;
|
||||
m_oInverseTransform.M12 = 0;
|
||||
@ -479,13 +479,15 @@ namespace MetaFile
|
||||
m_oInverseTransform.Dx = 0;
|
||||
m_oInverseTransform.Dy = 0;
|
||||
}
|
||||
|
||||
m_oInverseTransform.M11 = pT->M22 / dDet;
|
||||
m_oInverseTransform.M12 = -pT->M12 / dDet;
|
||||
m_oInverseTransform.M21 = -pT->M21 / dDet;
|
||||
m_oInverseTransform.M22 = pT->M22 / dDet;
|
||||
m_oInverseTransform.Dx = pT->Dy * pT->M21 / dDet - pT->Dx * pT->M22 / dDet;
|
||||
m_oInverseTransform.Dy = pT->Dx * pT->M12 / dDet - pT->Dy * pT->M11 / dDet;
|
||||
else
|
||||
{
|
||||
m_oInverseTransform.M11 = pT->M22 / dDet;
|
||||
m_oInverseTransform.M12 = -pT->M12 / dDet;
|
||||
m_oInverseTransform.M21 = -pT->M21 / dDet;
|
||||
m_oInverseTransform.M22 = pT->M22 / dDet;
|
||||
m_oInverseTransform.Dx = pT->Dy * pT->M21 / dDet - pT->Dx * pT->M22 / dDet;
|
||||
m_oInverseTransform.Dy = pT->Dx * pT->M12 / dDet - pT->Dy * pT->M11 / dDet;
|
||||
}
|
||||
|
||||
UpdateFinalTransform();
|
||||
}
|
||||
@ -714,20 +716,20 @@ namespace MetaFile
|
||||
const TEmfWindow& oWindow{GetWindow()};
|
||||
const TEmfWindow& oViewPort{GetViewport()};
|
||||
|
||||
double dM11 = (oViewPort.ulW >= 0) ? 1 : -1;
|
||||
double dM22 = (oViewPort.ulH >= 0) ? 1 : -1;
|
||||
double dM11 = ((oViewPort.ulW >= 0) ? 1. : -1.) * GetPixelWidth();
|
||||
double dM22 = ((oViewPort.ulH >= 0) ? 1. : -1.) * GetPixelHeight();
|
||||
|
||||
TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.lX * GetPixelWidth() * dM11), -(oWindow.lY * GetPixelHeight() * dM22));
|
||||
TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, oViewPort.lX, oViewPort.lY);
|
||||
TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.lX * dM11), -(oWindow.lY * dM22));
|
||||
TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.lX, oViewPort.lY);
|
||||
|
||||
m_oFinalTransform.Init();
|
||||
m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
|
||||
m_oFinalTransform2.Init();
|
||||
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
}
|
||||
|
||||
|
||||
@ -281,23 +281,29 @@ namespace MetaFile
|
||||
|
||||
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
|
||||
|
||||
std::wstring wsFontName = pFont->GetFaceName();
|
||||
NSStringUtils::CStringBuilder oFontName;
|
||||
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
|
||||
|
||||
#ifndef BUILDING_WASM_MODULE
|
||||
if (!wsFontName.empty())
|
||||
if (0 != oFontName.GetSize())
|
||||
{
|
||||
#ifndef BUILDING_WASM_MODULE
|
||||
NSFonts::CFontSelectFormat oFormat;
|
||||
oFormat.wsName = new std::wstring(pFont->GetFaceName());
|
||||
|
||||
NSFonts::CFontInfo *pFontInfo = m_pParser->GetFontManager()->GetFontInfoByParams(oFormat);
|
||||
|
||||
if (NULL != pFontInfo && !StringEquals(wsFontName, pFontInfo->m_wsFontName))
|
||||
wsFontName = L"'" + wsFontName + L"', '" + pFontInfo->m_wsFontName + L"'";
|
||||
if (NULL != pFontInfo && !StringEquals(*oFormat.wsName, pFontInfo->m_wsFontName))
|
||||
{
|
||||
oFontName.Clear();
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
oFontName.WriteEncodeXmlString(*oFormat.wsName);
|
||||
oFontName.WriteEncodeXmlString(L"\',\'");
|
||||
oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName);
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
}
|
||||
#endif
|
||||
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!wsFontName.empty())
|
||||
arNodeAttributes.push_back({L"font-family", wsFontName});
|
||||
|
||||
if (pFont->GetWeight() > 550)
|
||||
arNodeAttributes.push_back({L"font-weight", L"bold"});
|
||||
|
||||
@ -27,15 +27,12 @@ namespace MetaFile
|
||||
|
||||
unsigned int unSize;
|
||||
unsigned short ushType;
|
||||
unsigned int ulNumber = 0;
|
||||
|
||||
if (NULL != m_pInterpretator)
|
||||
m_pInterpretator->Begin();
|
||||
|
||||
Read_META_HEADER();
|
||||
|
||||
unsigned int unRecordIndex = 1;
|
||||
|
||||
while (!CheckError())
|
||||
{
|
||||
if (m_oStream.CanRead() < 6)
|
||||
@ -54,6 +51,9 @@ namespace MetaFile
|
||||
|
||||
m_oStream.SetCurrentBlockSize(m_unRecordSize);
|
||||
|
||||
if (NULL != m_pInterpretator)
|
||||
PRINT_WMF_RECORD(ushType);
|
||||
|
||||
switch (ushType)
|
||||
{
|
||||
//-----------------------------------------------------------
|
||||
@ -149,14 +149,11 @@ namespace MetaFile
|
||||
//-----------------------------------------------------------
|
||||
default:
|
||||
{
|
||||
//std::cout << ushType << " ";
|
||||
Read_META_UNKNOWN();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unRecordIndex++;
|
||||
|
||||
if (m_bEof)
|
||||
break;
|
||||
|
||||
|
||||
@ -734,6 +734,10 @@ namespace MetaFile
|
||||
if (oDestRect != oSrcRect)
|
||||
{
|
||||
TRectL oClip = oSrcRect;
|
||||
|
||||
oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth ) - 1;
|
||||
oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight) - 1;
|
||||
|
||||
BYTE* pNewBuffer = ClipBuffer(pBgra, unWidth, unHeight, oClip);
|
||||
|
||||
if (NULL != pNewBuffer)
|
||||
@ -1684,7 +1688,10 @@ namespace MetaFile
|
||||
void CWmfParserBase::HANDLE_META_ESCAPE(unsigned short ushEscapeFunction, unsigned short ushByteCount)
|
||||
{
|
||||
if (NULL != m_pInterpretator)
|
||||
{
|
||||
m_pInterpretator->HANDLE_META_ESCAPE(ushEscapeFunction, ushByteCount);
|
||||
PRINT_WMF_LOG("Escape function type: " << ushEscapeFunction << " size: " << ushByteCount);
|
||||
}
|
||||
|
||||
if (WMF_META_ESCAPE_ENHANCED_METAFILE == ushEscapeFunction)
|
||||
{
|
||||
|
||||
@ -11,6 +11,113 @@
|
||||
#undef DrawText
|
||||
#endif
|
||||
|
||||
#define PRINT_WMF_RECORD(type) do {} while(false)
|
||||
#define PRINT_WMF_LOG(text) do {} while(false)
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LOG_WMF_RECORDS 1
|
||||
|
||||
#ifdef LOG_WMF_RECORDS
|
||||
#if 1 == LOG_WMF_RECORDS
|
||||
#include <iostream>
|
||||
|
||||
#define PRINTING_WMF_RECORDS 1
|
||||
|
||||
#define PRINT_WMF_LOG(text) \
|
||||
std::cout << "[LOG] " << text << std::endl
|
||||
|
||||
#ifdef PRINTING_WMF_RECORDS
|
||||
#if 1 == PRINTING_WMF_RECORDS
|
||||
#define AddRecord(name) {name, #name}
|
||||
|
||||
static const std::map<UINT, std::string> mWmfRecords =
|
||||
{
|
||||
AddRecord(META_EOF),
|
||||
AddRecord(META_SETBKCOLOR),
|
||||
AddRecord(META_SETBKMODE),
|
||||
AddRecord(META_SETMAPMODE),
|
||||
AddRecord(META_SETROP2),
|
||||
AddRecord(META_SETRELABS),
|
||||
AddRecord(META_SETPOLYFILLMODE),
|
||||
AddRecord(META_SETSTRETCHBLTMODE),
|
||||
AddRecord(META_SETTEXTCHAREXTRA),
|
||||
AddRecord(META_SETTEXTCOLOR),
|
||||
AddRecord(META_SETTEXTJUSTIFICATION),
|
||||
AddRecord(META_SETWINDOWORG),
|
||||
AddRecord(META_SETWINDOWEXT),
|
||||
AddRecord(META_SETVIEWPORTORG),
|
||||
AddRecord(META_SETVIEWPORTEXT),
|
||||
AddRecord(META_OFFSETWINDOWORG),
|
||||
AddRecord(META_SCALEWINDOWEXT),
|
||||
AddRecord(META_OFFSETVIEWPORTORG),
|
||||
AddRecord(META_SCALEVIEWPORTEXT),
|
||||
AddRecord(META_LINETO),
|
||||
AddRecord(META_MOVETO),
|
||||
AddRecord(META_EXCLUDECLIPRECT),
|
||||
AddRecord(META_INTERSECTCLIPRECT),
|
||||
AddRecord(META_ARC),
|
||||
AddRecord(META_ELLIPSE),
|
||||
AddRecord(META_FLOODFILL),
|
||||
AddRecord(META_PIE),
|
||||
AddRecord(META_RECTANGLE),
|
||||
AddRecord(META_ROUNDRECT),
|
||||
AddRecord(META_PATBLT),
|
||||
AddRecord(META_SAVEDC),
|
||||
AddRecord(META_SETPIXEL),
|
||||
AddRecord(META_OFFSETCLIPRGN),
|
||||
AddRecord(META_TEXTOUT),
|
||||
AddRecord(META_BITBLT),
|
||||
AddRecord(META_STRETCHBLT),
|
||||
AddRecord(META_POLYGON),
|
||||
AddRecord(META_POLYLINE),
|
||||
AddRecord(META_ESCAPE),
|
||||
AddRecord(META_RESTOREDC),
|
||||
AddRecord(META_FILLREGION),
|
||||
AddRecord(META_FRAMEREGION),
|
||||
AddRecord(META_INVERTREGION),
|
||||
AddRecord(META_PAINTREGION),
|
||||
AddRecord(META_SELECTCLIPREGION),
|
||||
AddRecord(META_SELECTOBJECT),
|
||||
AddRecord(META_SETTEXTALIGN),
|
||||
AddRecord(META_CHORD),
|
||||
AddRecord(META_SETMAPPERFLAGS),
|
||||
AddRecord(META_EXTTEXTOUT),
|
||||
AddRecord(META_SETDIBTODEV),
|
||||
AddRecord(META_SELECTPALETTE),
|
||||
AddRecord(META_REALIZEPALETTE),
|
||||
AddRecord(META_ANIMATEPALETTE),
|
||||
AddRecord(META_SETPALENTRIES),
|
||||
AddRecord(META_POLYPOLYGON),
|
||||
AddRecord(META_RESIZEPALETTE),
|
||||
AddRecord(META_DIBBITBLT),
|
||||
AddRecord(META_DIBSTRETCHBLT),
|
||||
AddRecord(META_DIBCREATEPATTERNBRUSH),
|
||||
AddRecord(META_STRETCHDIB),
|
||||
AddRecord(META_EXTFLOODFILL),
|
||||
AddRecord(META_SETLAYOUT),
|
||||
AddRecord(META_DELETEOBJECT),
|
||||
AddRecord(META_CREATEPALETTE),
|
||||
AddRecord(META_CREATEPATTERNBRUSH),
|
||||
AddRecord(META_CREATEPENINDIRECT),
|
||||
AddRecord(META_CREATEFONTINDIRECT),
|
||||
AddRecord(META_CREATEBRUSHINDIRECT),
|
||||
AddRecord(META_CREATEREGION)
|
||||
};
|
||||
|
||||
#define PRINT_WMF_RECORD(type) \
|
||||
do {\
|
||||
std::map<UINT, std::string>::const_iterator itFound = mWmfRecords.find(type); \
|
||||
if (mWmfRecords.cend() != itFound) \
|
||||
std::cout << itFound->second << std::endl; \
|
||||
else \
|
||||
std::cout << "Unknown record: " << type << std::endl; \
|
||||
} while(false)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace MetaFile
|
||||
{
|
||||
enum WmfParserType
|
||||
|
||||
@ -571,20 +571,20 @@ namespace MetaFile
|
||||
const TWmfWindow& oWindow{GetWindow()};
|
||||
const TWmfWindow& oViewPort{GetViewport()};
|
||||
|
||||
double dM11 = (oViewPort.w >= 0) ? 1 : -1;
|
||||
double dM22 = (oViewPort.h >= 0) ? 1 : -1;
|
||||
double dM11 = ((oViewPort.w >= 0) ? 1. : -1.) * GetPixelWidth();
|
||||
double dM22 = ((oViewPort.h >= 0) ? 1. : -1.) * GetPixelHeight();
|
||||
|
||||
TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * GetPixelWidth() * dM11), -(oWindow.y * GetPixelHeight() * dM22));
|
||||
TEmfXForm oViewportXForm(GetPixelWidth() * dM11, 0, 0, GetPixelHeight() * dM22, oViewPort.x, oViewPort.y);
|
||||
TEmfXForm oWindowXForm(1, 0, 0, 1, -(oWindow.x * dM11), -(oWindow.y * dM22));
|
||||
TEmfXForm oViewportXForm(dM11, 0, 0, dM22, oViewPort.x, oViewPort.y);
|
||||
|
||||
m_oFinalTransform.Init();
|
||||
m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
|
||||
m_oFinalTransform2.Init();
|
||||
m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
// m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,8 @@ namespace SVG
|
||||
return false;
|
||||
|
||||
std::wstring wsXml;
|
||||
NSFile::CFileBinary::ReadAllTextUtf8(wsFile, wsXml);
|
||||
if (!NSFile::CFileBinary::ReadAllTextUtf8(wsFile, wsXml))
|
||||
return false;
|
||||
|
||||
XmlUtils::IXmlDOMDocument::DisableOutput();
|
||||
bool bResult = LoadFromString(wsXml, pContainer, pFile);
|
||||
|
||||
@ -21,7 +21,7 @@ namespace SVG
|
||||
SetFill(mAttributes, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CCircle::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CCircle::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
@ -37,17 +37,17 @@ namespace SVG
|
||||
pRenderer->PathCommandMoveTo(dX + dR, dY);
|
||||
pRenderer->PathCommandArcTo(dX - dR, dY - dR, dR * 2.0, dR * 2.0, 0, 360);
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCircle::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CCircle::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject))
|
||||
nTypePath += c_nStroke;
|
||||
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject))
|
||||
nTypePath += c_nWindingFillMode;
|
||||
}
|
||||
|
||||
|
||||
@ -12,9 +12,9 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override;
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
|
||||
@ -23,8 +23,8 @@ namespace SVG
|
||||
if (NULL == pRenderer || NULL == pFile)
|
||||
return false;
|
||||
|
||||
ApplyClip(pRenderer, &m_oTransformtaion.m_oClip, pFile, oObjectBounds);
|
||||
|
||||
ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oObjectBounds);
|
||||
|
||||
for (const CRenderedObject* pObject : m_oContainer.m_arObjects)
|
||||
pObject->Draw(pRenderer, pFile, CommandeModeClip);
|
||||
|
||||
|
||||
@ -51,17 +51,17 @@ namespace SVG
|
||||
: CRenderedObject(oNode, pParent), m_oWindow{0, 0, dWidth, dHeight}
|
||||
{}
|
||||
|
||||
bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
if (!StartPath(pRenderer, pFile, oOldTransform, oMode))
|
||||
if (!StartPath(pRenderer, pFile, oOldTransform, CommandeModeDraw))
|
||||
return false;
|
||||
|
||||
for (const CRenderedObject* pObject : m_arObjects)
|
||||
pObject->Draw(pRenderer, pFile, oMode, pOtherStyles);
|
||||
pObject->Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, CommandeModeDraw, pOtherStyles, pContexObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ namespace SVG
|
||||
|
||||
void SetData(XmlUtils::CXmlNode& oNode);
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
TRect GetWindow() const;
|
||||
TRect GetViewBox() const;
|
||||
|
||||
@ -22,7 +22,7 @@ namespace SVG
|
||||
SetFill(mAttributes, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
@ -42,17 +42,17 @@ namespace SVG
|
||||
pRenderer->PathCommandMoveTo(dX + dRx, dY);
|
||||
pRenderer->PathCommandArcTo(dX - dRx, dY - dRy, dRx * 2.0, dRy * 2.0, 0, 360);
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CEllipse::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CEllipse::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject))
|
||||
nTypePath += c_nStroke;
|
||||
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject))
|
||||
nTypePath += c_nWindingFillMode;
|
||||
}
|
||||
|
||||
|
||||
@ -13,9 +13,9 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override;
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
|
||||
@ -52,9 +52,9 @@ namespace SVG
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CFont::Draw(const std::wstring &wsText, double dX, double dY, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles) const
|
||||
bool CFont::Draw(const std::wstring &wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (NULL == pRenderer)
|
||||
if (NULL == pRenderer || wsText.empty())
|
||||
return false;
|
||||
|
||||
double dM11, dM12, dM21, dM22, dRx, dRy;
|
||||
@ -64,10 +64,25 @@ namespace SVG
|
||||
Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dRx, dRy);
|
||||
oMatrix.Translate(dX, dY);
|
||||
|
||||
pRenderer->SetTransform(dM11, dM12, dM21, -dM22, oMatrix.tx(), oMatrix.ty());
|
||||
|
||||
MGlyphsMap::const_iterator itFound;
|
||||
TBounds oGlyphBounds;
|
||||
double dGlyphScale = 1.;
|
||||
|
||||
#define DrawGlyph(glyphPtr, function) \
|
||||
const TBounds oGlyphBound{glyphPtr->GetBounds()};\
|
||||
if (Equals(0., dFontHeight) || Equals(oGlyphBound.m_dBottom, oGlyphBound.m_dTop) || Equals(oGlyphBound.m_dRight, oGlyphBound.m_dLeft)) \
|
||||
continue; \
|
||||
dGlyphScale = dFontHeight / 1000.; \
|
||||
if (!Equals(1., dGlyphScale)) \
|
||||
{ \
|
||||
oMatrix.Scale(dGlyphScale, -dGlyphScale); \
|
||||
pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \
|
||||
} \
|
||||
function; \
|
||||
if (!Equals(1., dGlyphScale)) \
|
||||
{ \
|
||||
oMatrix.Scale(1. / dGlyphScale, -1. / dGlyphScale); \
|
||||
pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \
|
||||
} \
|
||||
|
||||
for (wchar_t wchGlyph : wsText)
|
||||
{
|
||||
@ -78,12 +93,13 @@ namespace SVG
|
||||
if (NULL == m_pMissingGlyph)
|
||||
continue;
|
||||
|
||||
m_pMissingGlyph->Draw(pRenderer, pFile, oMode, pStyles);
|
||||
DrawGlyph(m_pMissingGlyph, m_pMissingGlyph->Draw(pRenderer, pFile, oMode, pStyles, pContexObject))
|
||||
|
||||
oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
itFound->second->Draw(pRenderer, pFile, oMode, pStyles);
|
||||
DrawGlyph(itFound->second, itFound->second->Draw(pRenderer, pFile, oMode, pStyles, pContexObject))
|
||||
|
||||
if (!itFound->second->m_oHorizAdvX.Empty())
|
||||
oMatrix.Translate(itFound->second->m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
|
||||
@ -91,9 +107,7 @@ namespace SVG
|
||||
oMatrix.Translate(m_oHorizAdvX.ToDouble(NSCSS::Pixel), 0);
|
||||
}
|
||||
|
||||
oMatrix.Translate(std::abs(oGlyphBounds.m_dRight - oGlyphBounds.m_dLeft), 0);
|
||||
|
||||
pRenderer->SetTransform(dM11, dM12, dM21, -dM22, oMatrix.tx(), oMatrix.ty());
|
||||
pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), -oMatrix.sy(), oMatrix.tx(), oMatrix.ty());
|
||||
}
|
||||
|
||||
pRenderer->SetTransform(dM11, dM12, dM21, dM22, dRx, dRy);
|
||||
|
||||
@ -43,7 +43,7 @@ namespace SVG
|
||||
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
bool Draw(const std::wstring& wsText, double dX, double dY, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL) const;
|
||||
bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
|
||||
private:
|
||||
void ParseGlyphs(XmlUtils::CXmlNode& oNode);
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ namespace SVG
|
||||
m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href")); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
|
||||
}
|
||||
|
||||
bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
@ -114,7 +114,7 @@ namespace SVG
|
||||
pRenderer->PathCommandClose();
|
||||
}
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
delete[] pBuffer;
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ namespace SVG
|
||||
public:
|
||||
CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
private:
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
|
||||
@ -27,9 +27,9 @@ namespace SVG
|
||||
SetMarker(mAttributes, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CLine::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CLine::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true))
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, true, pContexObject))
|
||||
nTypePath += c_nStroke;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override;
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
namespace SVG
|
||||
{
|
||||
CMarker::CMarker(XmlUtils::CXmlNode &oNode)
|
||||
: CObject(oNode), m_pImage(NULL)
|
||||
: CObject(oNode), m_dAngle(0.), m_oBounds{0., 0., 0., 0.}
|
||||
{
|
||||
m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"refX"));
|
||||
m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"refY"));
|
||||
@ -14,6 +14,8 @@ namespace SVG
|
||||
m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"markerWidth", L"3"));
|
||||
m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"markerHeight", L"3"));
|
||||
|
||||
m_oViewBox = m_oWindow;
|
||||
|
||||
const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox");
|
||||
|
||||
if (!wsViewBox.empty())
|
||||
@ -28,28 +30,29 @@ namespace SVG
|
||||
}
|
||||
}
|
||||
|
||||
// if (m_oWindow.m_oWidth.Empty() && !m_oViewBox.m_oWidth.Empty())
|
||||
// m_oWindow.m_oWidth = m_oViewBox.m_oWidth;
|
||||
// else if (!m_oWindow.m_oWidth.Empty() && m_oViewBox.m_oWidth.Empty())
|
||||
// m_oViewBox.m_oWidth = m_oWindow.m_oWidth;
|
||||
|
||||
// if (m_oWindow.m_oHeight.Empty() && !m_oViewBox.m_oHeight.Empty())
|
||||
// m_oWindow.m_oHeight = m_oViewBox.m_oHeight;
|
||||
// else if (!m_oWindow.m_oHeight.Empty() && m_oViewBox.m_oHeight.Empty())
|
||||
// m_oViewBox.m_oHeight = m_oWindow.m_oHeight;
|
||||
|
||||
const std::wstring& wsUnits = oNode.GetAttribute(L"markerUnits");
|
||||
|
||||
if (L"userSpaceOnUse" == wsUnits)
|
||||
m_enUnits = Marker_UserSpaceOnUse;
|
||||
m_enUnits = EMarkerUnits::UserSpaceOnUse;
|
||||
else
|
||||
m_enUnits = Marker_StrokeWidth;
|
||||
m_enUnits = EMarkerUnits::StrokeWidth;
|
||||
|
||||
const std::wstring& wsOrient = oNode.GetAttribute(L"orient");
|
||||
|
||||
if (L"auto" == wsOrient)
|
||||
m_enOrient = EMarkerOrient::Auto;
|
||||
else if (L"auto-start-reverse" == wsOrient)
|
||||
m_enOrient = EMarkerOrient::Auto_start_reverse;
|
||||
else
|
||||
{
|
||||
m_enOrient = EMarkerOrient::Angle;
|
||||
if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
|
||||
StrUtils::ReadDoubleValue(wsOrient, m_dAngle);
|
||||
}
|
||||
}
|
||||
|
||||
CMarker::~CMarker()
|
||||
{
|
||||
if (NULL != m_pImage)
|
||||
delete m_pImage;
|
||||
}
|
||||
|
||||
ObjectType CMarker::GetType() const
|
||||
@ -60,91 +63,48 @@ namespace SVG
|
||||
void CMarker::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{}
|
||||
|
||||
void CMarker::Update(const CSvgFile *pFile)
|
||||
void CMarker::Draw(IRenderer *pRenderer, const CSvgFile* pFile, const TMarkerExternData& oExternalData, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (NULL != m_pImage || (!m_oWindow.m_oWidth.Empty() && m_oWindow.m_oWidth.Zero()) || (!m_oWindow.m_oHeight.Empty() && m_oWindow.m_oHeight.Zero()) ||
|
||||
(!m_oViewBox.m_oWidth.Empty() && m_oViewBox.m_oWidth.Zero()) || (!m_oViewBox.m_oHeight.Empty() && m_oViewBox.m_oHeight.Zero()))
|
||||
if (NULL == oExternalData.m_pPoints || oExternalData.m_pPoints->empty() || m_arObjects.empty() || (EMarkerUnits::StrokeWidth == m_enUnits && Equals(0., oExternalData.m_dStroke)))
|
||||
return;
|
||||
|
||||
double dVBWidth = m_oViewBox.m_oWidth .ToDouble(NSCSS::Pixel);
|
||||
double dVBHeight = m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel);
|
||||
const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) * std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)), (m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel)));
|
||||
|
||||
double dMaxValue = std::max(dVBWidth, dVBHeight);
|
||||
double dM11, dM12, dM21, dM22, dDx, dDy;
|
||||
pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);
|
||||
|
||||
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
|
||||
const double dSkipX = m_oWindow.m_oX.ToDouble(NSCSS::Pixel) * dMaxScale;
|
||||
const double dSkipY = m_oWindow.m_oY.ToDouble(NSCSS::Pixel) * dMaxScale;
|
||||
|
||||
double dMMtoPx = 96. / 25.4;
|
||||
for (const TPointData& oPoint : *oExternalData.m_pPoints)
|
||||
{
|
||||
Aggplus::CMatrix oTransform(dM11, dM12, dM21, dM22, dDx, dDy);
|
||||
oTransform.Translate(oPoint.m_oPoint.dX - dSkipX, oPoint.m_oPoint.dY - dSkipY);
|
||||
|
||||
int nWidth = dMaxValue * dMMtoPx + 1;
|
||||
int nHeight = dMaxValue * dMMtoPx + 1;
|
||||
if (EMarkerOrient::Angle == m_enOrient)
|
||||
oTransform.RotateAt(m_dAngle, -dSkipX, -dSkipY);
|
||||
else if (!Equals(0., oPoint.m_dAngle))
|
||||
oTransform.RotateAt(oPoint.m_dAngle, -dSkipX, -dSkipY);
|
||||
|
||||
if (0 == nWidth || 0 == nHeight)
|
||||
return;
|
||||
Aggplus::CMatrix oTransform2(oTransform);
|
||||
oTransform2.Scale(dMaxScale, dMaxScale);
|
||||
|
||||
BYTE* pBgraData = new(std::nothrow) BYTE[nWidth * nHeight * 4];
|
||||
pRenderer->SetTransform(oTransform2.sx(), oTransform2.shy(), oTransform2.shx(), oTransform2.sy(), oTransform.tx(), oTransform.ty());
|
||||
|
||||
if (!pBgraData)
|
||||
return;
|
||||
for (const CRenderedObject* pObject : m_arObjects)
|
||||
pObject->Draw(pRenderer, pFile, oMode, pOtherStyles, pContexObject);
|
||||
}
|
||||
|
||||
unsigned int alfa = 0xffffff;
|
||||
//дефолтный тон должен быть прозрачным, а не белым
|
||||
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||||
for (int i = 0; i < nWidth * nHeight; i++)
|
||||
((unsigned int*)pBgraData)[i] = alfa;
|
||||
|
||||
CBgraFrame oFrame;
|
||||
oFrame.put_Data(pBgraData);
|
||||
oFrame.put_Width(nWidth);
|
||||
oFrame.put_Height(nHeight);
|
||||
oFrame.put_Stride(-4 * nWidth);
|
||||
|
||||
pGrRenderer->CreateFromBgraFrame(&oFrame);
|
||||
pGrRenderer->put_Width (dMaxValue);
|
||||
pGrRenderer->put_Height(dMaxValue);
|
||||
|
||||
pGrRenderer->SetCoordTransformOffset(((dMaxValue - dVBWidth) / 2. - m_oViewBox.m_oX.ToDouble(NSCSS::Pixel)) * dMMtoPx,
|
||||
((dMaxValue - dVBHeight) / 2. - m_oViewBox.m_oY.ToDouble(NSCSS::Pixel)) * dMMtoPx);
|
||||
|
||||
pGrRenderer->SetSwapRGB(false);
|
||||
pGrRenderer->BeginCommand(c_nImageType);
|
||||
|
||||
for (const CRenderedObject* pObject : m_arObjects)
|
||||
pObject->Draw(pGrRenderer, pFile);
|
||||
|
||||
pGrRenderer->EndCommand(c_nImageType);
|
||||
RELEASEINTERFACE(pGrRenderer);
|
||||
|
||||
oFrame.put_Data(NULL);
|
||||
|
||||
m_pImage = new Aggplus::CImage;
|
||||
m_pImage->Create(pBgraData, oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride());
|
||||
pRenderer->SetTransform(dM11, dM12, dM21, dM22, dDx, dDy);
|
||||
}
|
||||
|
||||
void CMarker::Draw(IRenderer *pRenderer, const std::vector<Point> &arPoints, double dStrokeWidth) const
|
||||
bool CMarker::NeedExternalAngle() const
|
||||
{
|
||||
if (NULL == m_pImage || arPoints.empty() || Equals(0., dStrokeWidth))
|
||||
return;
|
||||
return m_enOrient != EMarkerOrient::Angle;
|
||||
}
|
||||
|
||||
double dWidth = m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) * ((Marker_StrokeWidth == m_enUnits) ? dStrokeWidth : 1.);
|
||||
double dHeight = m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) * ((Marker_StrokeWidth == m_enUnits) ? dStrokeWidth : 1.);
|
||||
|
||||
double dVBWidth = m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel);
|
||||
double dVBHeight = m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel);
|
||||
|
||||
double dMaxValue = std::max(dVBWidth, dVBHeight);
|
||||
double dMaxScale = std::max(dMaxValue / dVBWidth, dMaxValue / dVBHeight);
|
||||
|
||||
double dSkipX = (m_oWindow.m_oX.ToDouble(NSCSS::Pixel) - m_oViewBox.m_oX.ToDouble(NSCSS::Pixel)) / dMaxScale + (dMaxValue - dVBWidth) * (dWidth / (2 * dMaxValue));
|
||||
double dSkipY = (m_oWindow.m_oY.ToDouble(NSCSS::Pixel) - m_oViewBox.m_oY.ToDouble(NSCSS::Pixel)) / dMaxScale + (dMaxValue - dVBHeight) * (dHeight / (2 * dMaxValue));
|
||||
|
||||
for (const Point& oPoint : arPoints)
|
||||
{
|
||||
Point oNewPoint(oPoint);
|
||||
|
||||
oNewPoint.dX -= dSkipX;
|
||||
oNewPoint.dY -= dSkipY;
|
||||
|
||||
pRenderer->DrawImage((IGrObject*)m_pImage, oNewPoint.dX, oNewPoint.dY, dWidth, dHeight);
|
||||
}
|
||||
EMarkerOrient CMarker::GetOrientType() const
|
||||
{
|
||||
return m_enOrient;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,11 +5,43 @@
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
typedef enum
|
||||
enum class EMarkerUnits
|
||||
{
|
||||
Marker_StrokeWidth,
|
||||
Marker_UserSpaceOnUse
|
||||
} MarkerUnits;
|
||||
StrokeWidth,
|
||||
UserSpaceOnUse
|
||||
};
|
||||
|
||||
enum class EMarkerOrient
|
||||
{
|
||||
Auto,
|
||||
Auto_start_reverse,
|
||||
Angle
|
||||
};
|
||||
|
||||
struct TPointData
|
||||
{
|
||||
Point m_oPoint;
|
||||
double m_dAngle;
|
||||
|
||||
TPointData()
|
||||
: m_dAngle(0.)
|
||||
{}
|
||||
};
|
||||
|
||||
struct TMarkerExternData
|
||||
{
|
||||
std::vector<TPointData>* m_pPoints;
|
||||
double m_dStroke;
|
||||
|
||||
TMarkerExternData()
|
||||
: m_pPoints(NULL), m_dStroke(0.)
|
||||
{}
|
||||
|
||||
~TMarkerExternData()
|
||||
{
|
||||
RELEASEOBJECT(m_pPoints);
|
||||
}
|
||||
};
|
||||
|
||||
class CMarker : public CObject, public CContainer<CRenderedObject>
|
||||
{
|
||||
@ -21,16 +53,21 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
void Update(const CSvgFile *pFile);
|
||||
void Draw(IRenderer* pRenderer, const CSvgFile *pFile, const TMarkerExternData& oExternalData, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
|
||||
|
||||
void Draw(IRenderer* pRenderer, const std::vector<Point>& arPoints, double dStrokeWidth) const;
|
||||
bool NeedExternalAngle() const;
|
||||
EMarkerOrient GetOrientType() const;
|
||||
private:
|
||||
MarkerUnits m_enUnits;
|
||||
EMarkerUnits m_enUnits;
|
||||
EMarkerOrient m_enOrient;
|
||||
|
||||
TRect m_oWindow;
|
||||
TRect m_oViewBox;
|
||||
double m_dAngle;
|
||||
|
||||
TRect m_oWindow;
|
||||
TRect m_oViewBox;
|
||||
|
||||
TBounds m_oBounds;
|
||||
|
||||
Aggplus::CImage *m_pImage;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -50,28 +50,28 @@ namespace SVG
|
||||
void CObject::SetTransform(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
if (mAttributes.end() != mAttributes.find(L"transform"))
|
||||
m_oTransformtaion.m_oTransform.SetMatrix(mAttributes.at(L"transform"), ushLevel, bHardMode);
|
||||
m_oTransformation.m_oTransform.SetMatrix(mAttributes.at(L"transform"), ushLevel, bHardMode);
|
||||
else
|
||||
m_oTransformtaion.m_oTransform.SetMatrix(L"", ushLevel, false);
|
||||
m_oTransformation.m_oTransform.SetMatrix(L"", ushLevel, false);
|
||||
}
|
||||
|
||||
void CObject::SetClip(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
if (mAttributes.end() != mAttributes.find(L"clip-path"))
|
||||
m_oTransformtaion.m_oClip.m_oHref.SetValue(mAttributes.at(L"clip-path"), ushLevel, bHardMode);
|
||||
m_oTransformation.m_oClip.m_oHref.SetValue(mAttributes.at(L"clip-path"), ushLevel, bHardMode);
|
||||
else
|
||||
m_oTransformtaion.m_oClip.m_oHref.SetValue(L"", ushLevel, false);
|
||||
m_oTransformation.m_oClip.m_oHref.SetValue(L"", ushLevel, false);
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"clip-rule"))
|
||||
m_oTransformtaion.m_oClip.m_oRule.SetValue(mAttributes.at(L"clip-rule"), std::vector<std::wstring>{L"nonzero", L"evenodd"}, ushLevel, bHardMode);
|
||||
m_oTransformation.m_oClip.m_oRule.SetValue(mAttributes.at(L"clip-rule"), std::vector<std::wstring>{L"nonzero", L"evenodd"}, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CObject::SetMask(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
if (mAttributes.end() != mAttributes.find(L"mask"))
|
||||
m_oTransformtaion.m_oMask.SetValue(mAttributes.at(L"mask"), ushLevel, bHardMode);
|
||||
m_oTransformation.m_oMask.SetValue(mAttributes.at(L"mask"), ushLevel, bHardMode);
|
||||
else
|
||||
m_oTransformtaion.m_oMask.SetValue(L"", ushLevel, false);
|
||||
m_oTransformation.m_oMask.SetValue(L"", ushLevel, false);
|
||||
}
|
||||
|
||||
void CObject::SetDisplay(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
@ -85,15 +85,15 @@ namespace SVG
|
||||
wsVisibility = mAttributes.at(L"visibility");
|
||||
|
||||
if (L"none" == wsDisplay || L"hidden" == wsVisibility || L"collapse" == wsVisibility)
|
||||
m_oTransformtaion.m_bDraw = false;
|
||||
m_oTransformation.m_bDraw = false;
|
||||
else
|
||||
m_oTransformtaion.m_bDraw = true;
|
||||
m_oTransformation.m_bDraw = true;
|
||||
}
|
||||
|
||||
void CObject::SetOpacity(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
if (mAttributes.end() != mAttributes.find(L"opacity"))
|
||||
m_oTransformtaion.m_oOpacity.SetValue(mAttributes.at(L"opacity"), ushLevel, bHardMode);
|
||||
m_oTransformation.m_oOpacity.SetValue(mAttributes.at(L"opacity"), ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CObject::ApplyTransform(IRenderer *pRenderer, const NSCSS::NSProperties::CTransform *pTransform, Aggplus::CMatrix& oOldMatrix) const
|
||||
@ -118,12 +118,9 @@ namespace SVG
|
||||
|
||||
bool CObject::ApplyClip(IRenderer *pRenderer, const TClip *pClip, const CSvgFile *pFile, const TBounds &oBounds) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pClip || NULL == pFile)
|
||||
if (NULL == pRenderer || NULL == pClip || NULL == pFile || pClip->m_oHref.Empty() || NSCSS::NSProperties::ColorType::ColorUrl != pClip->m_oHref.GetType())
|
||||
return false;
|
||||
|
||||
if (pClip->m_oHref.Empty() || NSCSS::NSProperties::ColorType::ColorUrl != pClip->m_oHref.GetType())
|
||||
return true;
|
||||
|
||||
if (pClip->m_oRule == L"evenodd")
|
||||
pRenderer->put_ClipMode(c_nClipRegionTypeEvenOdd);
|
||||
else
|
||||
@ -142,7 +139,7 @@ namespace SVG
|
||||
|
||||
return ApplyDef(pRenderer, pFile, pMask->ToWString(), oBounds);
|
||||
}
|
||||
|
||||
|
||||
bool CObject::ApplyDef(IRenderer *pRenderer, const CSvgFile *pFile, const std::wstring &wsUrl, const TBounds &oBounds) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pFile || wsUrl.empty())
|
||||
@ -241,9 +238,9 @@ namespace SVG
|
||||
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineJoinMiter;
|
||||
|
||||
m_oStyles.m_oStroke.m_oMiterlimit = 4.;
|
||||
|
||||
m_oTransformtaion.m_oOpacity = 1.;
|
||||
m_oTransformtaion.m_bDraw = true;
|
||||
|
||||
m_oTransformation.m_oOpacity = 1.;
|
||||
m_oTransformation.m_bDraw = true;
|
||||
}
|
||||
|
||||
void CRenderedObject::SetStroke(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
@ -282,21 +279,23 @@ namespace SVG
|
||||
m_oStyles.m_oFill.SetOpacity(mAttributes.at(L"fill-opacity"), ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CRenderedObject::StartPath(IRenderer *pRenderer, const CSvgFile *pFile, Aggplus::CMatrix &oOldTransform, CommandeMode oMode) const
|
||||
bool CRenderedObject::StartPath(IRenderer *pRenderer, const CSvgFile *pFile, Aggplus::CMatrix& oOldTransform, CommandeMode oMode) const
|
||||
{
|
||||
if (NULL == pRenderer || !m_oTransformtaion.m_bDraw || Equals(0., m_oTransformtaion.m_oOpacity.ToDouble()))
|
||||
if (NULL == pRenderer || !m_oTransformation.m_bDraw || Equals(0., m_oTransformation.m_oOpacity.ToDouble()))
|
||||
return false;
|
||||
|
||||
ApplyTransform(pRenderer, &m_oTransformtaion.m_oTransform, oOldTransform);
|
||||
ApplyClip(pRenderer, &m_oTransformtaion.m_oClip, pFile, GetBounds());
|
||||
ApplyMask(pRenderer, &m_oTransformtaion.m_oMask, pFile, GetBounds());
|
||||
const TBounds oBounds{GetBounds()};
|
||||
|
||||
ApplyTransform(pRenderer, &m_oTransformation.m_oTransform, oOldTransform);
|
||||
ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oBounds);
|
||||
ApplyMask(pRenderer, &m_oTransformation.m_oMask, pFile, oBounds);
|
||||
|
||||
if (CommandeModeClip == oMode)
|
||||
pRenderer->BeginCommand(c_nClipType);
|
||||
else if (1. != m_oTransformtaion.m_oOpacity.ToDouble())
|
||||
else if (1. != m_oTransformation.m_oOpacity.ToDouble())
|
||||
{
|
||||
pRenderer->BeginCommand(c_nLayerType);
|
||||
pRenderer->put_LayerOpacity(m_oTransformtaion.m_oOpacity.ToDouble());
|
||||
pRenderer->put_LayerOpacity(m_oTransformation.m_oOpacity.ToDouble());
|
||||
}
|
||||
|
||||
pRenderer->BeginCommand(c_nPathType);
|
||||
@ -305,54 +304,58 @@ namespace SVG
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRenderedObject::EndPath(IRenderer *pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix &oOldTransform, CommandeMode oMode, const TSvgStyles* pOtherStyles) const
|
||||
void CRenderedObject::EndPath(IRenderer *pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContextObject) const
|
||||
{
|
||||
if (CommandeModeClip == oMode)
|
||||
{
|
||||
pRenderer->EndCommand(c_nClipType);
|
||||
pRenderer->EndCommand(c_nPathType);
|
||||
pRenderer->PathCommandEnd();
|
||||
pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), oOldTransform.shx(), oOldTransform.sy(), oOldTransform.tx(), oOldTransform.ty());
|
||||
pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(),
|
||||
oOldTransform.shx(), oOldTransform.sy(),
|
||||
oOldTransform.tx(), oOldTransform.ty());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int nPathType = 0;
|
||||
|
||||
if (NULL == pOtherStyles)
|
||||
ApplyStyle(pRenderer, &m_oStyles, pFile, nPathType);
|
||||
ApplyStyle(pRenderer, &m_oStyles, pFile, nPathType, pContextObject);
|
||||
else
|
||||
{
|
||||
TSvgStyles oNewStyles(m_oStyles);
|
||||
oNewStyles += *pOtherStyles;
|
||||
ApplyStyle(pRenderer, &oNewStyles, pFile, nPathType);
|
||||
ApplyStyle(pRenderer, &oNewStyles, pFile, nPathType, pContextObject);
|
||||
}
|
||||
|
||||
pRenderer->DrawPath(nPathType);
|
||||
pRenderer->EndCommand(c_nPathType);
|
||||
pRenderer->PathCommandEnd();
|
||||
|
||||
if (!m_oTransformtaion.m_oClip.m_oHref.Empty())
|
||||
if (!m_oTransformation.m_oClip.m_oHref.Empty())
|
||||
{
|
||||
pRenderer->BeginCommand(c_nResetClipType);
|
||||
pRenderer->EndCommand(c_nResetClipType);
|
||||
}
|
||||
|
||||
if (!m_oTransformtaion.m_oMask.Empty())
|
||||
if (!m_oTransformation.m_oMask.Empty())
|
||||
{
|
||||
pRenderer->BeginCommand(c_nResetMaskType);
|
||||
pRenderer->EndCommand(c_nResetMaskType);
|
||||
}
|
||||
|
||||
if (1. != m_oTransformtaion.m_oOpacity.ToDouble())
|
||||
|
||||
if (1. != m_oTransformation.m_oOpacity.ToDouble())
|
||||
pRenderer->EndCommand(c_nLayerType);
|
||||
|
||||
pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(), oOldTransform.shx(), oOldTransform.sy(), oOldTransform.tx(), oOldTransform.ty());
|
||||
pRenderer->SetTransform(oOldTransform.sx(), oOldTransform.shy(),
|
||||
oOldTransform.shx(), oOldTransform.sy(),
|
||||
oOldTransform.tx(), oOldTransform.ty());
|
||||
}
|
||||
|
||||
void CRenderedObject::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CRenderedObject::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContextObject) const
|
||||
{}
|
||||
|
||||
bool CRenderedObject::ApplyStroke(IRenderer *pRenderer, const TStroke *pStroke, bool bUseDefault) const
|
||||
bool CRenderedObject::ApplyStroke(IRenderer *pRenderer, const TStroke *pStroke, bool bUseDefault, const CRenderedObject* pContextObject) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pStroke || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType() || (!bUseDefault && ((pStroke->m_oWidth.Empty() || pStroke->m_oWidth.Zero()) && pStroke->m_oColor.Empty())))
|
||||
{
|
||||
@ -365,10 +368,14 @@ namespace SVG
|
||||
if (Equals(0., dStrokeWidth))
|
||||
dStrokeWidth = 1.;
|
||||
|
||||
int nColor = (pStroke->m_oColor.Empty() || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType()) ? 0 : pStroke->m_oColor.ToInt();
|
||||
if (NSCSS::NSProperties::ColorType::ColorContextFill == pStroke->m_oColor.GetType() && NULL != pContextObject)
|
||||
pRenderer->put_PenColor(pContextObject->m_oStyles.m_oFill.ToInt());
|
||||
else if (NSCSS::NSProperties::ColorType::ColorContextStroke == pStroke->m_oColor.GetType() && NULL != pContextObject)
|
||||
pRenderer->put_PenColor(pContextObject->m_oStyles.m_oStroke.m_oColor.ToInt());
|
||||
else
|
||||
pRenderer->put_PenColor((pStroke->m_oColor.Empty() || NSCSS::NSProperties::ColorType::ColorNone == pStroke->m_oColor.GetType()) ? 0 : pStroke->m_oColor.ToInt());
|
||||
|
||||
pRenderer->put_PenSize(dStrokeWidth);
|
||||
pRenderer->put_PenColor(nColor);
|
||||
pRenderer->put_PenAlpha(255. * pStroke->m_oColor.GetOpacity());
|
||||
|
||||
if (!pStroke->m_arDash.empty())
|
||||
@ -391,7 +398,7 @@ namespace SVG
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRenderedObject::ApplyFill(IRenderer *pRenderer, const NSCSS::NSProperties::CColor *pFill, const CSvgFile *pFile, bool bUseDefault) const
|
||||
bool CRenderedObject::ApplyFill(IRenderer *pRenderer, const NSCSS::NSProperties::CColor *pFill, const CSvgFile *pFile, bool bUseDefault, const CRenderedObject* pContextObject) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pFill || NSCSS::NSProperties::ColorType::ColorNone == pFill->GetType() || (!bUseDefault && pFill->Empty()))
|
||||
{
|
||||
@ -417,6 +424,10 @@ namespace SVG
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (NSCSS::NSProperties::ColorType::ColorContextFill == pFill->GetType() && NULL != pContextObject)
|
||||
pRenderer->put_BrushColor1(pContextObject->m_oStyles.m_oFill.ToInt());
|
||||
else if (NSCSS::NSProperties::ColorType::ColorContextStroke == pFill->GetType() && NULL != pContextObject)
|
||||
pRenderer->put_BrushColor1(pContextObject->m_oStyles.m_oStroke.m_oColor.ToInt());
|
||||
else if (bUseDefault)
|
||||
{
|
||||
pRenderer->put_BrushColor1(0);
|
||||
|
||||
@ -54,10 +54,9 @@ namespace SVG
|
||||
void SetMask(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
void SetDisplay(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
void SetOpacity(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
|
||||
|
||||
std::wstring GetId() const;
|
||||
virtual std::vector<NSCSS::CNode> GetFullPath() const;
|
||||
|
||||
private:
|
||||
bool ApplyTransform(IRenderer* pRenderer, const SvgTransform* pTransform, Aggplus::CMatrix& oOldMatrix) const;
|
||||
bool ApplyClip(IRenderer* pRenderer, const TClip* pClip, const CSvgFile *pFile, const TBounds& oBounds) const;
|
||||
@ -86,7 +85,7 @@ namespace SVG
|
||||
friend class CClipPath;
|
||||
|
||||
NSCSS::CNode m_oXmlNode;
|
||||
TSvgTransformation m_oTransformtaion;
|
||||
TSvgTransformation m_oTransformation;
|
||||
};
|
||||
|
||||
enum CommandeMode
|
||||
@ -107,7 +106,7 @@ namespace SVG
|
||||
|
||||
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL) const = 0;
|
||||
virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0;
|
||||
|
||||
virtual TBounds GetBounds() const = 0;
|
||||
|
||||
@ -119,12 +118,12 @@ namespace SVG
|
||||
void SetFill(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
|
||||
bool StartPath(IRenderer* pRenderer, const CSvgFile *pFile, Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw) const;
|
||||
void EndPath(IRenderer* pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const;
|
||||
void EndPath(IRenderer* pRenderer, const CSvgFile *pFile, const Aggplus::CMatrix& oOldTransform, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContextObject = NULL) const;
|
||||
|
||||
virtual void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const;
|
||||
virtual void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContextObject = NULL) const;
|
||||
|
||||
bool ApplyStroke(IRenderer* pRenderer, const TStroke* pStroke, bool bUseDefault = false) const;
|
||||
bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false) const;
|
||||
bool ApplyStroke(IRenderer* pRenderer, const TStroke* pStroke, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const;
|
||||
bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const;
|
||||
bool ApplyOpacity(IRenderer* pRenderer, const SvgDigit* pOpacity) const;
|
||||
|
||||
friend class CUse;
|
||||
|
||||
@ -29,6 +29,11 @@ namespace SVG
|
||||
return oBounds;
|
||||
}
|
||||
|
||||
UINT IPathElement::GetPointCount() const
|
||||
{
|
||||
return m_arPoints.size();
|
||||
}
|
||||
|
||||
Point IPathElement::operator[](int nIndex) const
|
||||
{
|
||||
if (m_arPoints.empty() || (nIndex > 0 && nIndex >= m_arPoints.size()) || (nIndex < 0 && -nIndex > m_arPoints.size()))
|
||||
@ -306,7 +311,7 @@ namespace SVG
|
||||
else
|
||||
{
|
||||
dEndAngle = copysign(ceil(std::abs(dStartAngle) / 90.), dStartAngle) * ((dSweep > 0. || dStartAngle < 0.) ? 90. : -90.);
|
||||
|
||||
|
||||
if (dStartAngle < 0. && dSweep > 0.)
|
||||
dEndAngle += 90.;
|
||||
}
|
||||
@ -358,8 +363,8 @@ namespace SVG
|
||||
return;
|
||||
|
||||
pRenderer->PathCommandCurveTo(m_arPoints[0].dX, m_arPoints[0].dY,
|
||||
m_arPoints[1].dX, m_arPoints[1].dY,
|
||||
m_arPoints[2].dX, m_arPoints[2].dY);
|
||||
m_arPoints[1].dX, m_arPoints[1].dY,
|
||||
m_arPoints[2].dX, m_arPoints[2].dY);
|
||||
}
|
||||
|
||||
inline double ClampSinCos(const double& d)
|
||||
@ -469,7 +474,7 @@ namespace SVG
|
||||
}
|
||||
}
|
||||
|
||||
bool CPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
@ -479,7 +484,7 @@ namespace SVG
|
||||
for (const IPathElement* oElement : m_arElements)
|
||||
oElement->Draw(pRenderer);
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
DrawMarkers(pRenderer, pFile, oMode);
|
||||
|
||||
@ -494,16 +499,16 @@ namespace SVG
|
||||
return m_arElements[(nIndex >= 0) ? nIndex : m_arElements.size() + nIndex];
|
||||
}
|
||||
|
||||
void CPath::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CPath::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject))
|
||||
nTypePath += c_nStroke;
|
||||
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject))
|
||||
nTypePath += (m_bEvenOddRule) ? c_nEvenOddFillMode : c_nWindingFillMode;
|
||||
}
|
||||
|
||||
bool CPath::DrawMarkers(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode) const
|
||||
bool CPath::DrawMarkers(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles* pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pFile || m_arElements.empty() || m_oStyles.m_oStroke.m_oWidth.Zero() ||
|
||||
(m_oMarkers.m_oStart.Empty() && m_oMarkers.m_oMid.Empty() && m_oMarkers.m_oEnd.Empty()))
|
||||
@ -514,7 +519,9 @@ namespace SVG
|
||||
if (!StartPath(pRenderer, pFile, oOldMatrix, oMode))
|
||||
return false;
|
||||
|
||||
double dStrokeWidth = (m_oStyles.m_oStroke.m_oWidth.Empty()) ? 1. : m_oStyles.m_oStroke.m_oWidth.ToDouble(NSCSS::Pixel);
|
||||
const double dStrokeWidth = (m_oStyles.m_oStroke.m_oWidth.Empty()) ? 1. : m_oStyles.m_oStroke.m_oWidth.ToDouble(NSCSS::Pixel);
|
||||
|
||||
#define CALCULATE_ANGLE(firstPoint, secondPoint) std::atan2(secondPoint.dY - firstPoint.dY, secondPoint.dX - firstPoint.dX) * 180. / M_PI
|
||||
|
||||
if (!m_oMarkers.m_oStart.Empty() && NSCSS::NSProperties::ColorType::ColorUrl == m_oMarkers.m_oStart.GetType())
|
||||
{
|
||||
@ -522,8 +529,36 @@ namespace SVG
|
||||
|
||||
if (NULL != pStartMarker)
|
||||
{
|
||||
pStartMarker->Update(pFile);
|
||||
pStartMarker->Draw(pRenderer, {(*m_arElements.front())[0]}, dStrokeWidth);
|
||||
TMarkerExternData oExternalData;
|
||||
oExternalData.m_dStroke = dStrokeWidth;
|
||||
oExternalData.m_pPoints = new std::vector<TPointData>(1);
|
||||
|
||||
int unIndex = FindIndexFirstNotEmpty();
|
||||
|
||||
if (0 <= unIndex)
|
||||
{
|
||||
const IPathElement* pFirstElement{m_arElements[unIndex]};
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = (*pFirstElement)[0];
|
||||
|
||||
if (pStartMarker->NeedExternalAngle())
|
||||
{
|
||||
Point oCurent{(*pFirstElement)[0]};
|
||||
Point oNext;
|
||||
|
||||
if (pFirstElement->GetPointCount() > 1)
|
||||
oNext = (*pFirstElement)[1];
|
||||
else if (unIndex < m_arElements.size() - 1 && EPathElement::Close != m_arElements[unIndex + 1]->GetType() && EPathElement::Move != m_arElements[unIndex + 1]->GetType())
|
||||
oNext = (*m_arElements[unIndex + 1])[0];
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oCurent, oNext);
|
||||
|
||||
if (EMarkerOrient::Auto_start_reverse == pStartMarker->GetOrientType())
|
||||
(*oExternalData.m_pPoints)[0].m_dAngle += 180.;
|
||||
}
|
||||
|
||||
pStartMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,15 +566,27 @@ namespace SVG
|
||||
{
|
||||
CMarker *pMidMarker = dynamic_cast<CMarker*>(pFile->GetMarkedObject(m_oMarkers.m_oMid.ToWString()));
|
||||
|
||||
std::vector<Point> arPoints(m_arElements.size() - 2);
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex)
|
||||
arPoints[unIndex - 1] = (*m_arElements[unIndex])[-1];
|
||||
|
||||
if (NULL != pMidMarker)
|
||||
{
|
||||
pMidMarker->Update(pFile);
|
||||
pMidMarker->Draw(pRenderer, arPoints, dStrokeWidth);
|
||||
TMarkerExternData oExternalData;
|
||||
oExternalData.m_dStroke = dStrokeWidth;
|
||||
oExternalData.m_pPoints = new std::vector<TPointData>(m_arElements.size() - 2);
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex)
|
||||
{
|
||||
if (EPathElement::Close != m_arElements[unIndex]->GetType())
|
||||
(*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = (*m_arElements[unIndex])[-1];
|
||||
|
||||
if (pMidMarker->NeedExternalAngle())
|
||||
{
|
||||
const Point oCurrent{(*m_arElements[unIndex])[0]};
|
||||
const Point oPrev{(*m_arElements[unIndex + 1])[-1]};
|
||||
|
||||
(*oExternalData.m_pPoints)[unIndex - 1].m_dAngle = CALCULATE_ANGLE(oCurrent, oPrev);
|
||||
}
|
||||
}
|
||||
|
||||
pMidMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,12 +596,37 @@ namespace SVG
|
||||
|
||||
if (NULL != pEndMarker)
|
||||
{
|
||||
pEndMarker->Update(pFile);
|
||||
pEndMarker->Draw(pRenderer, {(*m_arElements.back())[-1]}, dStrokeWidth);
|
||||
TMarkerExternData oExternalData;
|
||||
oExternalData.m_dStroke = dStrokeWidth;
|
||||
oExternalData.m_pPoints = new std::vector<TPointData>(1);
|
||||
|
||||
int unIndex = FindIndexFirstNotEmpty(true);
|
||||
|
||||
if (0 <= unIndex)
|
||||
{
|
||||
const IPathElement* pLastElement{m_arElements[unIndex]};
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = (*pLastElement)[-1];
|
||||
|
||||
if (pEndMarker->NeedExternalAngle())
|
||||
{
|
||||
Point oCurent{(*pLastElement)[-1]};
|
||||
Point oPrev;
|
||||
|
||||
if (pLastElement->GetPointCount() > 1)
|
||||
oPrev = (*pLastElement)[-2];
|
||||
else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType() && EPathElement::Move != m_arElements[unIndex - 1]->GetType())
|
||||
oPrev = (*m_arElements[unIndex - 1])[0];
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oPrev, oCurent);
|
||||
}
|
||||
|
||||
pEndMarker->Draw(pRenderer, pFile, oExternalData, oMode, pOtherStyles, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EndPath(pRenderer, pFile, oOldMatrix, oMode);
|
||||
EndPath(pRenderer, pFile, oOldMatrix, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -569,6 +641,13 @@ namespace SVG
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"marker-end"))
|
||||
m_oMarkers.m_oEnd.SetValue(mAttributes.at(L"marker-end"), ushLevel, bHardMode);
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"marker"))
|
||||
{
|
||||
m_oMarkers.m_oStart.SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode);
|
||||
m_oMarkers.m_oMid .SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode);
|
||||
m_oMarkers.m_oEnd .SetValue(mAttributes.at(L"marker"), ushLevel, bHardMode);
|
||||
}
|
||||
}
|
||||
|
||||
TBounds CPath::GetBounds() const
|
||||
@ -588,6 +667,24 @@ namespace SVG
|
||||
return oBounds;
|
||||
}
|
||||
|
||||
const int CPath::FindIndexFirstNotEmpty(bool bReverseSearch) const
|
||||
{
|
||||
if (!bReverseSearch)
|
||||
{
|
||||
std::vector<IPathElement*>::const_iterator itFound = std::find_if(m_arElements.cbegin(), m_arElements.cend(), [](const IPathElement* pElement){ return EPathElement::Close != pElement->GetType(); });
|
||||
if (m_arElements.cend() != itFound)
|
||||
return itFound - m_arElements.cbegin();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<IPathElement*>::const_reverse_iterator itFound = std::find_if(m_arElements.crbegin(), m_arElements.crend(), [](const IPathElement* pElement){ return EPathElement::Close != pElement->GetType(); });
|
||||
if (m_arElements.crend() != itFound)
|
||||
return itFound.base() - m_arElements.cbegin() - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CPath::ReadFromString(const std::wstring &wsValue)
|
||||
{
|
||||
CMoveElement *pMoveElement = NULL;
|
||||
@ -608,7 +705,7 @@ namespace SVG
|
||||
}
|
||||
|
||||
oSecondPos = std::find_if(oFirstPos + 1, wsValue.end(), [](wchar_t wChar){return ISPATHCOMMAND(wChar);});
|
||||
|
||||
|
||||
std::vector<double> arValues = StrUtils::ReadDoubleValues(oFirstPos, oSecondPos);
|
||||
|
||||
switch(*oFirstPos)
|
||||
|
||||
@ -35,6 +35,7 @@ namespace SVG
|
||||
virtual void Draw(IRenderer* pRenderer) const = 0;
|
||||
|
||||
TBounds GetBounds() const;
|
||||
UINT GetPointCount() const;
|
||||
virtual Point operator[](int nIndex) const;
|
||||
|
||||
private:
|
||||
@ -110,21 +111,24 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
IPathElement* operator[](int nIndex) const;
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath) const override;
|
||||
bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw) const;
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
|
||||
|
||||
void SetMarker(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode);
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const;
|
||||
|
||||
void ReadFromString(const std::wstring& wsValue);
|
||||
bool AddElement(IPathElement* pElement);
|
||||
|
||||
friend class CLine;
|
||||
friend class CFont;
|
||||
friend class CPolygon;
|
||||
friend class CPolyline;
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ namespace SVG
|
||||
SetFill(mAttributes, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CRect::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles) const
|
||||
bool CRect::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
|
||||
@ -80,17 +80,17 @@ namespace SVG
|
||||
pRenderer->PathCommandClose();
|
||||
}
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles);
|
||||
EndPath(pRenderer, pFile, oOldTransform, oMode, pOtherStyles, pContexObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CRect::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
|
||||
void CRect::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
|
||||
if (ApplyStroke(pRenderer, &pStyles->m_oStroke, false, pContexObject))
|
||||
nTypePath += c_nStroke;
|
||||
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
|
||||
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true, pContexObject))
|
||||
nTypePath += c_nWindingFillMode;
|
||||
}
|
||||
|
||||
|
||||
@ -14,10 +14,10 @@ namespace SVG
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL) const override;
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath) const override;
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user