mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-03-30 23:02:10 +08:00
Compare commits
287 Commits
v9.3.0.107
...
feature/bi
| Author | SHA1 | Date | |
|---|---|---|---|
| 211557cc7a | |||
| 9a4f929510 | |||
| 206ee9c976 | |||
| 7a8669d7f8 | |||
| ea28ff69a9 | |||
| 88626378a7 | |||
| 23e736051f | |||
| 8870516a8a | |||
| dbe56878b1 | |||
| 84aa409b1e | |||
| 8fa5f8944e | |||
| 27dc6403d7 | |||
| ecaef0fbed | |||
| 2addc5a3d8 | |||
| 4e1afe5c55 | |||
| 9ae5855ed0 | |||
| 8d4e216852 | |||
| 866bf08da3 | |||
| 9e1bb2cd22 | |||
| bb97d00ae7 | |||
| 66eaed4f18 | |||
| 4739b9f9dd | |||
| e8f1691348 | |||
| 0b42267c43 | |||
| 6f1bfc3064 | |||
| f57f573ac4 | |||
| 0579b93796 | |||
| 2074785963 | |||
| ed697edba2 | |||
| 686c72a1c8 | |||
| 41124d3301 | |||
| 95d6c6c927 | |||
| 9ae76b07a1 | |||
| da769a642b | |||
| 0d7e535114 | |||
| e0af1357e5 | |||
| d4f80ea036 | |||
| 8e90fbac69 | |||
| 12083ae8c9 | |||
| 322fda0e07 | |||
| b0d70ff38a | |||
| 2a409336a3 | |||
| 6819a41452 | |||
| 4cdc416e0b | |||
| 5d5732161a | |||
| 7046f1d465 | |||
| 61f25af847 | |||
| 9304d10674 | |||
| 21dd6c2a61 | |||
| 278dffc7c7 | |||
| b607aeb4c6 | |||
| bd7aa2df96 | |||
| 3d4dc3116e | |||
| f2fdcf4efd | |||
| ae7dbf291f | |||
| cb0176ecca | |||
| e1b3fe270a | |||
| 615cf0982d | |||
| b75afead99 | |||
| 290a134cdb | |||
| 6d9a2e0d09 | |||
| 32c4964cca | |||
| a027644bf0 | |||
| 9983161e3d | |||
| 33c4b5130e | |||
| c2dd7b5108 | |||
| 0101774675 | |||
| de9709ea50 | |||
| 22e7c5bed4 | |||
| 11000aa465 | |||
| eada4b4ebe | |||
| 6630a882ed | |||
| e20143fa2e | |||
| 57ca5da2c0 | |||
| 08bad0753a | |||
| 6224b6384d | |||
| be1aed4cae | |||
| e40603df61 | |||
| 6d0db29975 | |||
| a43af51577 | |||
| cf0f2be204 | |||
| 44e3e77631 | |||
| e4df8df318 | |||
| 3676400e66 | |||
| 573b85932f | |||
| eca98f612c | |||
| 3b0c9cea7e | |||
| 3dc0f482c8 | |||
| e429ff685f | |||
| 03334267c9 | |||
| 417c3a55ec | |||
| 90eb06ac20 | |||
| 031c1c91e6 | |||
| d17c22772f | |||
| 2a09f9da90 | |||
| 8a8e17562b | |||
| 52f8640b10 | |||
| 9f36c04d33 | |||
| 8a1a45f403 | |||
| 7dffc8245a | |||
| 869774bcc1 | |||
| 27103958fe | |||
| 2b46e0251f | |||
| 078a58772c | |||
| 95c9c95a2e | |||
| 1753007900 | |||
| f43230dcaf | |||
| df576b6e99 | |||
| bb7d2ce8ee | |||
| ed8a47cbb7 | |||
| 3c707ebbf4 | |||
| 3b2721e2da | |||
| b430c3f296 | |||
| c21827825b | |||
| 19c66750a8 | |||
| 0424c73db0 | |||
| dc6a72892c | |||
| 4b61f6e62a | |||
| 927f49291a | |||
| 72b57be353 | |||
| ef295fc115 | |||
| a62528e90e | |||
| d54f0326cd | |||
| 269dd9b8bc | |||
| 9da0b82ead | |||
| e3334cbea5 | |||
| 01c928c724 | |||
| cf72c836a1 | |||
| b9a905f6b2 | |||
| 644ec4e651 | |||
| e5c1dc4bc3 | |||
| 2c5cd93ac5 | |||
| 1ff1334746 | |||
| de096d4229 | |||
| 6c9d795167 | |||
| 8116322018 | |||
| 5428c28874 | |||
| e389b4d799 | |||
| 8c607a429a | |||
| 00e80b68f6 | |||
| 377317892d | |||
| ef77688ea2 | |||
| eb756fab5c | |||
| 2d2bb7cee7 | |||
| 1abe5b2dcc | |||
| 2b4bdfdc05 | |||
| 007c70bcc0 | |||
| 017b43dd66 | |||
| 88a6760086 | |||
| 98a0551123 | |||
| 6ca34d9c69 | |||
| 49cb1cdbca | |||
| 73e00a5096 | |||
| 462eeda60c | |||
| e1f81b6830 | |||
| d63a6e2ba4 | |||
| b9cf1bd204 | |||
| 81ec569f59 | |||
| 236913f902 | |||
| 2a6d9faaf8 | |||
| 7a78e1bbc6 | |||
| f2db0df9f5 | |||
| c2dfac0d27 | |||
| 902497b299 | |||
| 473f6aef1e | |||
| 35aa329619 | |||
| 6ace9b1cc5 | |||
| f6bc46c551 | |||
| 790049d14a | |||
| ccc9f8f91f | |||
| f2eace2b53 | |||
| dfe7a64e1a | |||
| 65f89c1e4b | |||
| ea7ff62816 | |||
| 4ac45f41cb | |||
| 947e5a1f5d | |||
| 3e724e6164 | |||
| 8ef0713adc | |||
| 2f74b3b69b | |||
| 7ce71b6f5d | |||
| 9b5847e653 | |||
| d81e26eff7 | |||
| 67e987e389 | |||
| bc91106ea4 | |||
| d91a19cbc2 | |||
| 970720575a | |||
| 85027065e6 | |||
| f11045c87f | |||
| 70e819c56b | |||
| 5a662b3567 | |||
| 0f920531ac | |||
| 84d3ea7a21 | |||
| 4893ff96fd | |||
| 6a7791ae0a | |||
| 78ac7bb427 | |||
| 8180a20cb8 | |||
| eb51861f39 | |||
| e4cc737c38 | |||
| f66c646c2c | |||
| 6c89a66b3d | |||
| b127bd3ac1 | |||
| 0cca75b662 | |||
| 08dc0c99cf | |||
| d2af89a2f6 | |||
| 836787f151 | |||
| eb78332705 | |||
| f232d0ca51 | |||
| 24d436fb9c | |||
| 1d362cf69a | |||
| 6c0326d660 | |||
| 4400c9d4f4 | |||
| 71c7d25c9e | |||
| ab1dd7a48b | |||
| 6e3d625420 | |||
| ebb0eb8136 | |||
| 10f34fb67d | |||
| 98d2f62f9e | |||
| 096df8fc31 | |||
| a7886c5cd6 | |||
| ee6ea683d1 | |||
| 9343f73818 | |||
| 61aeb6f386 | |||
| 06e8d136bf | |||
| c1d649b506 | |||
| 4386e9c794 | |||
| 4900305b4a | |||
| e1f923c593 | |||
| 07ef2269ac | |||
| cf44441645 | |||
| 7157d209d7 | |||
| 64a560679c | |||
| 2682e49090 | |||
| 7fd4219ff4 | |||
| 4f9c229f77 | |||
| 6d8454c39d | |||
| 58deecba88 | |||
| 1940bc53f7 | |||
| a6ac765676 | |||
| 08624e8334 | |||
| 1f078c8c49 | |||
| e6036b37be | |||
| 04f1c30036 | |||
| 86f84f89de | |||
| 17b80ac96e | |||
| 710bfef301 | |||
| aa75825a73 | |||
| f74caacbd0 | |||
| 4d903b58b8 | |||
| 6434965f09 | |||
| f60f957d00 | |||
| bad5b172d5 | |||
| 7b6f29a5f0 | |||
| b5e1cf9d06 | |||
| 0f73b2aa8b | |||
| e3b5d72ec8 | |||
| 1417b4bbd4 | |||
| b850450c25 | |||
| 098d40d44f | |||
| 8a406c9612 | |||
| 3a004e8495 | |||
| 404748ec5a | |||
| 3b10e1a0f3 | |||
| 70aa8c7e64 | |||
| bff86db600 | |||
| 56b8e41875 | |||
| 565b2ec494 | |||
| a243e60e5a | |||
| 6c95810f63 | |||
| d9260e5eee | |||
| e612306d75 | |||
| 2f34fd917e | |||
| 71b21ea79d | |||
| 22eaf8241b | |||
| 64c7b7a3fd | |||
| 90b329e06c | |||
| 65a4fa90a5 | |||
| 92ec3d854e | |||
| 5e58298d1e | |||
| a9dc790f92 | |||
| 14bb45d2fe | |||
| 347c1f82a9 | |||
| e32b48524e | |||
| 79f8e14d07 | |||
| 7d06219664 | |||
| e936b0e4e7 | |||
| dde96288ed | |||
| a22f0bfb60 |
@ -7,7 +7,6 @@
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
#include <iostream>
|
||||
#include "../../../../../DesktopEditor/common/File.h"
|
||||
#include "StaticFunctions.h"
|
||||
#include "ConstValues.h"
|
||||
@ -18,14 +17,16 @@ namespace NSCSS
|
||||
{
|
||||
typedef std::map<std::wstring, std::wstring>::const_iterator styles_iterator;
|
||||
|
||||
CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE)
|
||||
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_dCoreFontSize(oStyle.m_dCoreFontSize),
|
||||
m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground),
|
||||
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform){}
|
||||
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform)
|
||||
{}
|
||||
|
||||
CCompiledStyle::~CCompiledStyle()
|
||||
{
|
||||
@ -34,6 +35,8 @@ namespace NSCSS
|
||||
|
||||
CCompiledStyle& CCompiledStyle::operator+= (const CCompiledStyle &oElement)
|
||||
{
|
||||
m_arParentsStyles.insert(oElement.m_arParentsStyles.begin(), oElement.m_arParentsStyles.end());
|
||||
|
||||
if (oElement.Empty())
|
||||
return *this;
|
||||
|
||||
@ -49,8 +52,6 @@ namespace NSCSS
|
||||
if (!oElement.m_sId.empty())
|
||||
m_sId += L'+' + oElement.m_sId;
|
||||
|
||||
m_arParentsStyles.insert(oElement.m_arParentsStyles.begin(), oElement.m_arParentsStyles.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -15,29 +15,33 @@ inline static std::wstring StringifyValueList(const KatanaArray* oValues);
|
||||
inline static std::wstring StringifyValue(const KatanaValue* oValue);
|
||||
inline static bool IsTableElement(const std::wstring& wsNameTag);
|
||||
|
||||
bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vector<NSCSS::CNode> &arRightSelectors)
|
||||
{
|
||||
const size_t& sizeLeftSelectors = arLeftSelectors.size();
|
||||
const size_t& sizeRightSelectors = arRightSelectors.size();
|
||||
|
||||
if (sizeLeftSelectors < sizeRightSelectors)
|
||||
return true;
|
||||
else if (sizeLeftSelectors > sizeRightSelectors)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < arLeftSelectors.size(); ++i)
|
||||
{
|
||||
if (arLeftSelectors[i] < arRightSelectors[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace NSCSS
|
||||
{
|
||||
bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vector<NSCSS::CNode> &arRightSelectors)
|
||||
{
|
||||
if (arLeftSelectors.size() < arRightSelectors.size())
|
||||
return true;
|
||||
else if (arLeftSelectors.size() > arRightSelectors.size())
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < arLeftSelectors.size(); ++i)
|
||||
{
|
||||
if (arLeftSelectors[i] == arRightSelectors[i])
|
||||
continue;
|
||||
|
||||
if (arLeftSelectors[i] < arRightSelectors[i])
|
||||
return true;
|
||||
else if (arRightSelectors[i] < arLeftSelectors[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CStyleStorage::CStyleStorage()
|
||||
{}
|
||||
{
|
||||
InitDefaultStyles();
|
||||
}
|
||||
|
||||
CStyleStorage::~CStyleStorage()
|
||||
{
|
||||
@ -62,6 +66,7 @@ namespace NSCSS
|
||||
m_arEmptyStyleFiles.clear();
|
||||
|
||||
ClearEmbeddedStyles();
|
||||
ClearDefaultStyles();
|
||||
ClearAllowedStyleFiles();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
@ -208,6 +213,16 @@ namespace NSCSS
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CElement* CStyleStorage::FindDefaultElement(const std::wstring& wsSelector) const
|
||||
{
|
||||
if (wsSelector.empty())
|
||||
return nullptr;
|
||||
|
||||
const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mDefaultStyleData);
|
||||
|
||||
return (nullptr != pFoundElement) ? pFoundElement : nullptr;
|
||||
}
|
||||
|
||||
void CStyleStorage::AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
if (sStyle.empty())
|
||||
@ -227,6 +242,15 @@ namespace NSCSS
|
||||
m_mEmbeddedStyleData.clear();
|
||||
}
|
||||
|
||||
void CStyleStorage::ClearDefaultStyles()
|
||||
{
|
||||
for (std::map<std::wstring, CElement*>::iterator oIter = m_mDefaultStyleData.begin(); oIter != m_mDefaultStyleData.end(); ++oIter)
|
||||
if (oIter->second != nullptr)
|
||||
delete oIter->second;
|
||||
|
||||
m_mDefaultStyleData.clear();
|
||||
}
|
||||
|
||||
void CStyleStorage::ClearAllowedStyleFiles()
|
||||
{
|
||||
m_arAllowedStyleFiles.clear();
|
||||
@ -480,7 +504,33 @@ namespace NSCSS
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
|
||||
void CStyleStorage::InitDefaultStyles()
|
||||
{
|
||||
m_mDefaultStyleData[L"b"] = new CElement(L"b", {{L"font-weight", L"bold"}});
|
||||
m_mDefaultStyleData[L"center"] = new CElement(L"center", {{L"text-align", L"center"}});
|
||||
m_mDefaultStyleData[L"i"] = new CElement(L"i", {{L"font-style", L"italic"}});
|
||||
m_mDefaultStyleData[L"code"] = new CElement(L"code", {{L"font-family", L"Courier New"}});
|
||||
m_mDefaultStyleData[L"kbd"] = new CElement(L"kbd", {{L"font-family", L"Courier New"},
|
||||
{L"font_weight", L"bold"}});
|
||||
m_mDefaultStyleData[L"s"] = new CElement(L"s", {{L"text-decoration", L"line-through"}});
|
||||
m_mDefaultStyleData[L"u"] = new CElement(L"u", {{L"text-decoration", L"underline"}});
|
||||
m_mDefaultStyleData[L"mark"] = new CElement(L"mark", {{L"background-color", L"yellow"}});
|
||||
m_mDefaultStyleData[L"sup"] = new CElement(L"sup", {{L"vertical-align", L"top"}});
|
||||
m_mDefaultStyleData[L"sub"] = new CElement(L"sub", {{L"vertical-align", L"bottom"}});
|
||||
m_mDefaultStyleData[L"dd"] = new CElement(L"dd", {{L"margin-left", L"720tw"}});
|
||||
m_mDefaultStyleData[L"pre"] = new CElement(L"pre", {{L"font-family", L"Courier New"},
|
||||
{L"margin-top", L"0"},
|
||||
{L"margin-bottom", L"0"}});
|
||||
m_mDefaultStyleData[L"blockquote"] = new CElement(L"blockquote", {{L"margin", L"0px"}});
|
||||
m_mDefaultStyleData[L"ul"] = new CElement(L"ul", {{L"margin-top", L"100tw"},
|
||||
{L"margin-bottom", L"100tw"}});
|
||||
m_mDefaultStyleData[L"textarea"] = new CElement(L"textarea", {{L"border", L"1px solid black"}});
|
||||
}
|
||||
|
||||
CCssCalculator_Private::CCssCalculator_Private()
|
||||
: m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8")
|
||||
{
|
||||
}
|
||||
|
||||
CCssCalculator_Private::~CCssCalculator_Private()
|
||||
{}
|
||||
@ -503,12 +553,17 @@ namespace NSCSS
|
||||
arSelectors.back().m_pCompiledStyle->m_oBorder.Clear();
|
||||
}
|
||||
|
||||
if (arSelectors.size() > 1)
|
||||
arSelectors.back().m_pCompiledStyle->AddParent(arSelectors[arSelectors.size() - 2].m_wsName);
|
||||
|
||||
arSelectors.back().m_pCompiledStyle->SetID(L"text-" + std::to_wstring(++m_nCountNodes));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
|
||||
const std::map<std::vector<CNode>, CCompiledStyle>::const_iterator oItem = m_mUsedStyles.find(arSelectors);
|
||||
|
||||
if (oItem != m_mUsedStyles.end())
|
||||
if (oItem != m_mUsedStyles.cend() && (arSelectors.back().m_wsId.empty() || !HaveStylesById(arSelectors.back().m_wsId)))
|
||||
{
|
||||
arSelectors.back().SetCompiledStyle(new CCompiledStyle(oItem->second));
|
||||
return true;
|
||||
@ -542,7 +597,8 @@ namespace NSCSS
|
||||
if (0 != i)
|
||||
*arSelectors[i].m_pCompiledStyle += *arSelectors[i - 1].m_pCompiledStyle;
|
||||
|
||||
arSelectors[i].m_pCompiledStyle->AddParent(arSelectors[i].m_wsName);
|
||||
if (i != arSelectors.size() - 1)
|
||||
arSelectors[i].m_pCompiledStyle->AddParent(arSelectors[i].m_wsName);
|
||||
|
||||
if (!bInTable)
|
||||
bInTable = IsTableElement(arSelectors[i].m_wsName);
|
||||
@ -615,8 +671,8 @@ namespace NSCSS
|
||||
std::vector<std::wstring> arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
|
||||
|
||||
arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
|
||||
[](std::wstring sRes, const std::wstring& sClass)
|
||||
{return sRes += L'.' + sClass + L' ';}));
|
||||
[](std::wstring sRes, const std::wstring& sClass)
|
||||
{return sRes += L'.' + sClass + L' ';}));
|
||||
}
|
||||
else
|
||||
arNodes.push_back(L'.' + oNode->m_wsClass);
|
||||
@ -644,6 +700,36 @@ namespace NSCSS
|
||||
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
|
||||
}
|
||||
|
||||
inline std::wstring GetAlternativeDefaultNodeName(const std::wstring& wsNodeName)
|
||||
{
|
||||
if (L"strong" == wsNodeName)
|
||||
return L"b";
|
||||
|
||||
if (L"cite" == wsNodeName || L"dfn" == wsNodeName || L"em" == wsNodeName ||
|
||||
L"var" == wsNodeName || L"adress" == wsNodeName)
|
||||
return L"i";
|
||||
|
||||
if (L"tt" == wsNodeName || L"samp" == wsNodeName)
|
||||
return L"code";
|
||||
|
||||
if (L"strike" == wsNodeName || L"del" == wsNodeName)
|
||||
return L"s";
|
||||
|
||||
if (L"ins" == wsNodeName)
|
||||
return L"u";
|
||||
|
||||
if (L"xmp" == wsNodeName || L"nobr" == wsNodeName)
|
||||
return L"pre";
|
||||
|
||||
if (L"ol" == wsNodeName)
|
||||
return L"ul";
|
||||
|
||||
if (L"fieldset" == wsNodeName)
|
||||
return L"textarea";
|
||||
|
||||
return wsNodeName;
|
||||
}
|
||||
|
||||
std::vector<const CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
|
||||
{
|
||||
if (arNodes.empty())
|
||||
@ -702,6 +788,11 @@ namespace NSCSS
|
||||
}
|
||||
}
|
||||
|
||||
const CElement* pFoundDefault = m_oStyleStorage.FindDefaultElement(GetAlternativeDefaultNodeName(wsName));
|
||||
|
||||
if (nullptr != pFoundDefault)
|
||||
arFindedElements.push_back(pFoundDefault);
|
||||
|
||||
const CElement* pFoundName = m_oStyleStorage.FindElement(wsName);
|
||||
|
||||
if (nullptr != pFoundName)
|
||||
|
||||
@ -27,6 +27,7 @@ namespace NSCSS
|
||||
void AddStylesFromFile(const std::wstring& wsFileName);
|
||||
|
||||
void ClearEmbeddedStyles();
|
||||
void ClearDefaultStyles();
|
||||
void ClearAllowedStyleFiles();
|
||||
void ClearStylesFromFile(const std::wstring& wsFileName);
|
||||
|
||||
@ -38,6 +39,7 @@ namespace NSCSS
|
||||
#endif
|
||||
|
||||
const CElement* FindElement(const std::wstring& wsSelector) const;
|
||||
const CElement* FindDefaultElement(const std::wstring& wsSelector) const;
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
@ -49,6 +51,7 @@ namespace NSCSS
|
||||
std::set<std::wstring> m_arAllowedStyleFiles;
|
||||
std::vector<TStyleFileData*> m_arStyleFiles;
|
||||
std::map<std::wstring, CElement*> m_mEmbeddedStyleData;
|
||||
std::map<std::wstring, CElement*> m_mDefaultStyleData;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
typedef struct
|
||||
@ -78,6 +81,8 @@ namespace NSCSS
|
||||
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
|
||||
|
||||
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData) const;
|
||||
|
||||
void InitDefaultStyles();
|
||||
};
|
||||
|
||||
class CCssCalculator_Private
|
||||
|
||||
@ -9,6 +9,13 @@ namespace NSCSS
|
||||
CElement::CElement()
|
||||
{
|
||||
}
|
||||
|
||||
CElement::CElement(const std::wstring& wsSelector, std::map<std::wstring, std::wstring> mStyle)
|
||||
: m_mStyle(mStyle), m_sSelector(wsSelector), m_sFullSelector(wsSelector)
|
||||
{
|
||||
UpdateWeight();
|
||||
}
|
||||
|
||||
CElement::~CElement()
|
||||
{
|
||||
for (CElement* oElement : m_arPrevElements)
|
||||
@ -18,7 +25,6 @@ namespace NSCSS
|
||||
continue;
|
||||
|
||||
m_mStyle.clear();
|
||||
|
||||
}
|
||||
|
||||
std::wstring CElement::GetSelector() const
|
||||
|
||||
@ -22,6 +22,7 @@ namespace NSCSS
|
||||
|
||||
public:
|
||||
CElement();
|
||||
CElement(const std::wstring& wsSelector, std::map<std::wstring, std::wstring> mStyle);
|
||||
~CElement();
|
||||
|
||||
std::wstring GetSelector() const;
|
||||
|
||||
@ -17,8 +17,7 @@ namespace NSCSS
|
||||
m_wsStyle(oNode.m_wsStyle), m_mAttributes(oNode.m_mAttributes)
|
||||
{
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
m_pCompiledStyle = new CCompiledStyle();
|
||||
*m_pCompiledStyle = *oNode.m_pCompiledStyle;
|
||||
m_pCompiledStyle = new CCompiledStyle(*oNode.m_pCompiledStyle);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -42,6 +41,23 @@ namespace NSCSS
|
||||
return m_wsName.empty() && m_wsClass.empty() && m_wsId.empty() && m_wsStyle.empty();
|
||||
}
|
||||
|
||||
bool CNode::GetAttributeValue(const std::wstring& wsAttributeName, std::wstring& wsAttributeValue) const
|
||||
{
|
||||
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mAttributes.find(wsAttributeName)};
|
||||
|
||||
if (m_mAttributes.cend() == itFound)
|
||||
return false;
|
||||
|
||||
wsAttributeValue = itFound->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::wstring CNode::GetAttributeValue(const std::wstring& wsAttributeName) const
|
||||
{
|
||||
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mAttributes.find(wsAttributeName)};
|
||||
return (m_mAttributes.cend() != itFound) ? itFound->second : std::wstring();
|
||||
}
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
void CNode::SetCompiledStyle(CCompiledStyle* pCompiledStyle)
|
||||
{
|
||||
@ -86,6 +102,9 @@ namespace NSCSS
|
||||
if(m_wsStyle != oNode.m_wsStyle)
|
||||
return m_wsStyle < oNode.m_wsStyle;
|
||||
|
||||
if (m_mAttributes.size() != oNode.m_mAttributes.size())
|
||||
return m_mAttributes.size() < oNode.m_mAttributes.size();
|
||||
|
||||
if (m_mAttributes != oNode.m_mAttributes)
|
||||
return m_mAttributes < oNode.m_mAttributes;
|
||||
|
||||
@ -94,10 +113,9 @@ namespace NSCSS
|
||||
|
||||
bool CNode::operator==(const CNode& oNode) const
|
||||
{
|
||||
return((m_wsId == oNode.m_wsId) &&
|
||||
(m_wsName == oNode.m_wsName) &&
|
||||
(m_wsClass == oNode.m_wsClass) &&
|
||||
(m_wsStyle == oNode.m_wsStyle) &&
|
||||
(m_mAttributes == oNode.m_mAttributes));
|
||||
return((m_wsName == oNode.m_wsName) &&
|
||||
(m_wsClass == oNode.m_wsClass) &&
|
||||
(m_wsStyle == oNode.m_wsStyle) &&
|
||||
(m_mAttributes == oNode.m_mAttributes));
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,9 @@ namespace NSCSS
|
||||
|
||||
bool Empty() const;
|
||||
|
||||
bool GetAttributeValue(const std::wstring& wsAttributeName, std::wstring& wsAttributeValue) const;
|
||||
std::wstring GetAttributeValue(const std::wstring& wsAttributeName) const;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
void SetCompiledStyle(CCompiledStyle* pCompiledStyle);
|
||||
#endif
|
||||
|
||||
@ -70,7 +70,9 @@ namespace NSCSS
|
||||
R_Shd,
|
||||
R_SmallCaps,
|
||||
R_Kern,
|
||||
R_Vanish
|
||||
R_Vanish,
|
||||
R_Strike,
|
||||
R_VertAlign
|
||||
} RunnerProperties;
|
||||
|
||||
typedef enum
|
||||
|
||||
@ -22,6 +22,11 @@ namespace NSCSS
|
||||
: m_oStyle(oStyle), m_bIsPStyle(bIsPStyle)
|
||||
{}
|
||||
|
||||
void CStyleUsed::SetFinalId(const std::wstring& wsFinalId)
|
||||
{
|
||||
m_wsFinalId = wsFinalId;
|
||||
}
|
||||
|
||||
bool CheckArrays(const std::vector<std::wstring>& arInitial, const std::set<std::wstring>& arFirst, const std::set<std::wstring>& arSecond)
|
||||
{
|
||||
std::unordered_set<std::wstring> arInitialSet(arInitial.begin(), arInitial.end());
|
||||
@ -57,19 +62,14 @@ namespace NSCSS
|
||||
m_oStyle == oUsedStyle.m_oStyle;
|
||||
}
|
||||
|
||||
std::wstring CStyleUsed::getId()
|
||||
std::wstring CStyleUsed::GetId() const
|
||||
{
|
||||
if (m_bIsPStyle)
|
||||
return m_oStyle.GetId();
|
||||
|
||||
return m_oStyle.GetId() + L"-c";
|
||||
return m_wsFinalId;
|
||||
}
|
||||
|
||||
CDocumentStyle::CDocumentStyle() : m_arStandardStyles(Names_Standard_Styles)
|
||||
{
|
||||
for (const std::wstring& oNameStandardStyle : Names_Standard_Styles)
|
||||
m_arStandardStyles.push_back(oNameStandardStyle + L"-c");
|
||||
}
|
||||
CDocumentStyle::CDocumentStyle()
|
||||
: m_arStandardStyles(Names_Standard_Styles)
|
||||
{}
|
||||
|
||||
CDocumentStyle::~CDocumentStyle()
|
||||
{
|
||||
@ -85,7 +85,7 @@ namespace NSCSS
|
||||
|
||||
std::wstring CDocumentStyle::GetIdAndClear()
|
||||
{
|
||||
std::wstring sId = m_sId;
|
||||
const std::wstring sId = m_sId;
|
||||
Clear();
|
||||
return sId;
|
||||
}
|
||||
@ -110,10 +110,10 @@ namespace NSCSS
|
||||
m_sId = sId;
|
||||
}
|
||||
|
||||
void CDocumentStyle::CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement)
|
||||
bool CDocumentStyle::CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement)
|
||||
{
|
||||
if (arStandartedStyles.empty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
std::vector<std::wstring> arStyles;
|
||||
for (const std::wstring& sStyleName : arStandartedStyles)
|
||||
@ -123,7 +123,7 @@ namespace NSCSS
|
||||
}
|
||||
|
||||
if (arStyles.empty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
std::wstring sId;
|
||||
for (std::vector<std::wstring>::const_reverse_iterator iStyleName = arStyles.rbegin(); iStyleName != arStyles.rend(); ++iStyleName)
|
||||
@ -142,18 +142,25 @@ namespace NSCSS
|
||||
|
||||
oElement.AddBasicProperties(BProperties::B_Name, sId);
|
||||
oElement.AddBasicProperties(BProperties::B_StyleId, sId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDocumentStyle::CreateStandardStyle(const std::wstring& sNameStyle, CXmlElement& oElement)
|
||||
bool CDocumentStyle::CreateStandardStyle(const std::wstring& sNameStyle, CXmlElement& oElement)
|
||||
{
|
||||
if (std::find(m_arStandardStyles.begin(), m_arStandardStyles.end(), sNameStyle) != m_arStandardStyles.end())
|
||||
{
|
||||
oElement.CreateDefaultElement(sNameStyle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CDocumentStyle::ConvertStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle)
|
||||
bool CDocumentStyle::ConvertStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle)
|
||||
{
|
||||
if (oStyle.GetId().empty())
|
||||
return;
|
||||
return false;
|
||||
|
||||
std::wstring sName = oStyle.GetId();
|
||||
const size_t posPoint = sName.find(L'.');
|
||||
@ -183,25 +190,25 @@ namespace NSCSS
|
||||
for (std::wstring& sParentName : arParentsName)
|
||||
sParentName += L"-c";
|
||||
|
||||
bool bResult{false};
|
||||
|
||||
if (!arParentsName.empty())
|
||||
{
|
||||
CombineStandardStyles(arParentsName, oParentStyle);
|
||||
bResult = CombineStandardStyles(arParentsName, oParentStyle);
|
||||
|
||||
if (!oParentStyle.Empty())
|
||||
{
|
||||
oParentStyle.AddBasicProperties(BProperties::B_BasedOn, L"normal");
|
||||
oParentStyle.AddBasicProperties(BProperties::B_StyleId, L"(" + oParentStyle.GetStyleId() + L")");
|
||||
oParentStyle.AddBasicProperties(BProperties::B_StyleId, oParentStyle.GetStyleId());
|
||||
if (!bIsPStyle)
|
||||
{
|
||||
oParentStyle.AddBasicProperties(BProperties::B_StyleId, oParentStyle.GetStyleId() + L"-c");
|
||||
oParentStyle.AddBasicProperties(BProperties::B_Type, L"character");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CXmlElement oStandardXmlElement;
|
||||
if (std::find(m_arStandardStyles.begin(), m_arStandardStyles.end(), sName) != m_arStandardStyles.end())
|
||||
CreateStandardStyle(sName, oStandardXmlElement);
|
||||
if (CreateStandardStyle(sName, oStandardXmlElement))
|
||||
bResult = true;
|
||||
|
||||
if (oStandardXmlElement.Empty() && !oParentStyle.Empty())
|
||||
{
|
||||
@ -221,7 +228,7 @@ namespace NSCSS
|
||||
if (oStyle.Empty())
|
||||
{
|
||||
m_sId = sParentsStyleID;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
oElement.AddBasicProperties(BProperties::B_BasedOn, sParentsStyleID);
|
||||
@ -234,7 +241,7 @@ namespace NSCSS
|
||||
if (oStyle.Empty())
|
||||
{
|
||||
m_sId = sStandPlusParent;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
oElement.AddBasicProperties(BProperties::B_BasedOn, sStandPlusParent);
|
||||
}
|
||||
@ -258,7 +265,7 @@ namespace NSCSS
|
||||
if (oStyle.Empty())
|
||||
{
|
||||
m_sId = sStandPlusParent;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
oElement.AddBasicProperties(BProperties::B_BasedOn, oTempElement.GetStyleId());
|
||||
}
|
||||
@ -281,7 +288,7 @@ namespace NSCSS
|
||||
if (oStyle.Empty())
|
||||
{
|
||||
m_sId = sStandartStyleID;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
oElement.AddBasicProperties(BProperties::B_BasedOn, sStandartStyleID);
|
||||
}
|
||||
@ -289,7 +296,7 @@ namespace NSCSS
|
||||
if (oStyle.Empty() && oElement.Empty())
|
||||
{
|
||||
m_sId = L"normal";
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
m_sId = oStyle.GetId();
|
||||
@ -302,15 +309,19 @@ namespace NSCSS
|
||||
oElement.AddBasicProperties(BProperties::B_Name, m_sId);
|
||||
oElement.AddBasicProperties(BProperties::B_Type, bIsPStyle ? L"paragraph" : L"character");
|
||||
oElement.AddBasicProperties(BProperties::B_CustomStyle, L"1");
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
|
||||
bool CDocumentStyle::SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
|
||||
{
|
||||
bool bResult{false};
|
||||
|
||||
if (!bIsLite)
|
||||
ConvertStyle(oStyle, oXmlElement, true);
|
||||
bResult = ConvertStyle(oStyle, oXmlElement, true);
|
||||
|
||||
if (oStyle.Empty())
|
||||
return;
|
||||
return bResult;
|
||||
|
||||
const bool bInTable{oStyle.HaveThisParent(L"table")};
|
||||
|
||||
@ -390,6 +401,8 @@ namespace NSCSS
|
||||
SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder);
|
||||
}
|
||||
}
|
||||
|
||||
return bResult || !oXmlElement.Empty();
|
||||
}
|
||||
|
||||
void CDocumentStyle::SetBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement, const PProperties &enBorderProperty)
|
||||
@ -473,13 +486,15 @@ namespace NSCSS
|
||||
return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"" + std::to_wstring(nSpace) + L"\" w:color=\"" + wsColor + L"\"";
|
||||
}
|
||||
|
||||
void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
|
||||
bool CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
|
||||
{
|
||||
bool bResult{false};
|
||||
|
||||
if (!bIsLite)
|
||||
ConvertStyle(oStyle, oXmlElement, false);
|
||||
bResult = ConvertStyle(oStyle, oXmlElement, false);
|
||||
|
||||
if (oStyle.Empty() && oXmlElement.Empty())
|
||||
return;
|
||||
return bResult;
|
||||
|
||||
if (!oStyle.m_oFont.GetSize().Empty())
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast<int>(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. * oStyle.m_oTransform.GetMatrix().GetFinalValue().sy() + 0.5))); // Значения шрифта увеличивает на 2
|
||||
@ -516,6 +531,18 @@ namespace NSCSS
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString());
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString());
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_SmallCaps, oStyle.m_oFont.GetVariant().ToWString());
|
||||
|
||||
if (oStyle.m_oText.LineThrough())
|
||||
{
|
||||
if (L"double" == oStyle.m_oText.GetDecoration().m_oStyle.ToWString())
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_Strike, L"dstrike");
|
||||
else
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_Strike, L"strike");
|
||||
}
|
||||
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_VertAlign, oStyle.m_oDisplay.GetVAlign().ToWString());
|
||||
|
||||
return bResult || !oXmlElement.Empty();
|
||||
}
|
||||
|
||||
bool CDocumentStyle::WriteRStyle(const NSCSS::CCompiledStyle& oStyle)
|
||||
@ -531,16 +558,16 @@ namespace NSCSS
|
||||
|
||||
if (oItem != m_arStyleUsed.end())
|
||||
{
|
||||
m_sId = (*oItem).getId();
|
||||
m_sId = (*oItem).GetId();
|
||||
return true;
|
||||
}
|
||||
|
||||
CXmlElement oXmlElement;
|
||||
SetRStyle(oStyle, oXmlElement);
|
||||
|
||||
if (oXmlElement.Empty())
|
||||
if (!SetRStyle(oStyle, oXmlElement))
|
||||
return false;
|
||||
|
||||
structStyle.SetFinalId(m_sId);
|
||||
m_arStyleUsed.push_back(structStyle);
|
||||
m_sStyle += oXmlElement.GetRStyle();
|
||||
|
||||
@ -593,16 +620,16 @@ namespace NSCSS
|
||||
|
||||
if (oItem != m_arStyleUsed.end())
|
||||
{
|
||||
m_sId = (*oItem).getId();
|
||||
m_sId = (*oItem).GetId();
|
||||
return true;
|
||||
}
|
||||
|
||||
CXmlElement oXmlElement;
|
||||
SetPStyle(oStyle, oXmlElement);
|
||||
|
||||
if (oXmlElement.Empty())
|
||||
if (!SetPStyle(oStyle, oXmlElement))
|
||||
return false;
|
||||
|
||||
structStyle.SetFinalId(m_sId);
|
||||
m_arStyleUsed.push_back(structStyle);
|
||||
m_sStyle += oXmlElement.GetPStyle();
|
||||
|
||||
|
||||
@ -12,16 +12,19 @@ namespace NSCSS
|
||||
{
|
||||
CCompiledStyle m_oStyle;
|
||||
bool m_bIsPStyle;
|
||||
std::wstring m_wsFinalId;
|
||||
|
||||
public:
|
||||
CStyleUsed(const CCompiledStyle& oStyle, bool bIsPStyle);
|
||||
|
||||
void SetFinalId(const std::wstring& wsFinalId);
|
||||
|
||||
bool operator==(const CStyleUsed& oUsedStyle) const;
|
||||
|
||||
std::wstring getId();
|
||||
std::wstring GetId() const;
|
||||
};
|
||||
|
||||
static const std::vector<std::wstring> Names_Standard_Styles = {L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6",L"p", L"div"};
|
||||
static const std::vector<std::wstring> Names_Standard_Styles = {L"a", L"a-c", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"h1-c", L"h2-c", L"h3-c", L"h4-c", L"h5-c", L"h6-c"};
|
||||
|
||||
class CSSCALCULATOR_EXPORT CDocumentStyle
|
||||
{
|
||||
@ -36,12 +39,12 @@ namespace NSCSS
|
||||
std::wstring m_sStyle;
|
||||
std::wstring m_sId;
|
||||
|
||||
void CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement);
|
||||
void CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement);
|
||||
void ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle);
|
||||
bool CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement);
|
||||
bool CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement);
|
||||
bool ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle);
|
||||
|
||||
void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
|
||||
void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
|
||||
bool SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
|
||||
bool SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
|
||||
|
||||
void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty);
|
||||
public:
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include <cwctype>
|
||||
#include <functional>
|
||||
|
||||
#include <iostream>
|
||||
#include "../ConstValues.h"
|
||||
|
||||
#define DEFAULTFONTNAME L"Times New Roman"
|
||||
@ -67,7 +66,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"0");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
}
|
||||
else if (sNameDefaultElement == L"h2")
|
||||
{
|
||||
@ -78,7 +77,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"1");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
}
|
||||
else if (sNameDefaultElement == L"h3")
|
||||
{
|
||||
@ -89,7 +88,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"2");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
}
|
||||
else if (sNameDefaultElement == L"h4")
|
||||
{
|
||||
@ -100,7 +99,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"3");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
}
|
||||
else if (sNameDefaultElement == L"h5")
|
||||
{
|
||||
@ -111,7 +110,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"4");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
|
||||
}
|
||||
else if (sNameDefaultElement == L"h6")
|
||||
@ -123,13 +122,13 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6-c");
|
||||
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"5");
|
||||
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
|
||||
}
|
||||
else if (sNameDefaultElement == L"h1-c")
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h1-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 1 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 1 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1");
|
||||
@ -142,7 +141,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h2-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 2 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 2 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
|
||||
@ -155,7 +154,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h3-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 3 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 3 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
|
||||
@ -168,7 +167,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h4-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 4 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 4 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
|
||||
@ -181,7 +180,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h5-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 5 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 5 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
|
||||
@ -194,7 +193,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
|
||||
{
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h6-c");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 6 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 6 Sign");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
|
||||
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
|
||||
@ -479,6 +478,19 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const
|
||||
sRStyle += L"<w:vanish/>";
|
||||
break;
|
||||
}
|
||||
case CSSProperties::RunnerProperties::R_Strike:
|
||||
{
|
||||
sRStyle += L"<w:" + oItem.second + L"/>";
|
||||
break;
|
||||
}
|
||||
case CSSProperties::RunnerProperties::R_VertAlign:
|
||||
{
|
||||
if (L"top" == oItem.second)
|
||||
sRStyle += L"<w:vertAlign w:val=\"superscript\"/>";
|
||||
else if (L"bottom" == oItem.second)
|
||||
sRStyle += L"<w:vertAlign w:val=\"subscript\"/>";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -7,4 +7,5 @@ core_windows:INCLUDEPATH += $$PWD/gumbo-parser/visualc/include
|
||||
HEADERS += $$files($$PWD/gumbo-parser/src/*.h, true) \
|
||||
$$PWD/htmltoxhtml.h
|
||||
|
||||
SOURCES += $$files($$PWD/gumbo-parser/src/*.c, true)
|
||||
SOURCES += $$files($$PWD/gumbo-parser/src/*.c, true) \
|
||||
$$PWD/htmltoxhtml.cpp
|
||||
|
||||
657
Common/3dParty/html/htmltoxhtml.cpp
Normal file
657
Common/3dParty/html/htmltoxhtml.cpp
Normal file
@ -0,0 +1,657 @@
|
||||
#include "htmltoxhtml.h"
|
||||
|
||||
#include <map>
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "gumbo-parser/src/gumbo.h"
|
||||
#include "../../../DesktopEditor/common/File.h"
|
||||
#include "../../../DesktopEditor/common/Directory.h"
|
||||
#include "../../../DesktopEditor/common/StringBuilder.h"
|
||||
#include "../../../UnicodeConverter/UnicodeConverter.h"
|
||||
#include "../../../HtmlFile2/src/StringFinder.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
#if defined(CreateDirectory)
|
||||
#undef CreateDirectory
|
||||
#endif
|
||||
|
||||
static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|";
|
||||
static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|";
|
||||
static std::string preserve_whitespace = "|pre|textarea|script|style|";
|
||||
static std::string special_handling = "|html|body|";
|
||||
static std::string treat_like_inline = "|p|";
|
||||
|
||||
static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6",
|
||||
"ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th",
|
||||
"br","form","input","button","section","nav","header","footer",
|
||||
"main","figure","figcaption","strong","em","i", "b", "u","pre",
|
||||
"code","blockquote","hr","script","link","meta","style","title",
|
||||
"head","body","html","legend","optgroup","option","select","dl",
|
||||
"dt","dd","time","data","abbr","address","area","base","bdi",
|
||||
"bdo","cite","col","iframe","video","source","track","textarea",
|
||||
"label","fieldset","colgroup","del","ins","details","summary",
|
||||
"dialog","embed","kbd","map","mark","menu","meter","object",
|
||||
"output","param","progress","q","samp","small","sub","sup","var",
|
||||
"wbr","acronym","applet","article","aside","audio","basefont",
|
||||
"bgsound","big","blink","canvas","caption","center","command",
|
||||
"comment","datalist","dfn","dir","font","frame","frameset",
|
||||
"hgroup","isindex","keygen","marquee","nobr","noembed","noframes",
|
||||
"noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"};
|
||||
|
||||
static std::vector<std::string> unchecked_nodes_new = {"svg"};
|
||||
|
||||
static void replace_all(std::string& s, const std::string& s1, const std::string& s2)
|
||||
{
|
||||
size_t pos = s.find(s1);
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
s.replace(pos, s1.length(), s2);
|
||||
pos = s.find(s1, pos + s2.length());
|
||||
}
|
||||
}
|
||||
|
||||
static bool NodeIsUnprocessed(const std::string& sTagName)
|
||||
{
|
||||
return "xml" == sTagName;
|
||||
}
|
||||
|
||||
static bool IsUnckeckedNodes(const std::string& sValue)
|
||||
{
|
||||
return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue);
|
||||
}
|
||||
|
||||
static std::string Base64ToString(const std::string& sContent, const std::string& sCharset)
|
||||
{
|
||||
std::string sRes;
|
||||
int nSrcLen = (int)sContent.length();
|
||||
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
|
||||
BYTE* pData = new BYTE[nDecodeLen];
|
||||
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
|
||||
{
|
||||
std::wstring sConvert;
|
||||
if(!sCharset.empty() && NSStringFinder::Equals<std::string>("utf-8", sCharset))
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sConvert = oConverter.toUnicode(reinterpret_cast<char *>(pData), (unsigned)nDecodeLen, sCharset.data());
|
||||
}
|
||||
sRes = sConvert.empty() ? std::string(reinterpret_cast<char *>(pData), nDecodeLen) : U_TO_UTF8(sConvert);
|
||||
}
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
return sRes;
|
||||
}
|
||||
|
||||
static std::string QuotedPrintableDecode(const std::string& sContent, std::string& sCharset)
|
||||
{
|
||||
NSStringUtils::CStringBuilderA sRes;
|
||||
size_t ip = 0;
|
||||
size_t i = sContent.find('=');
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
size_t nIgnore = 12;
|
||||
std::string charset = sContent.substr(0, nIgnore);
|
||||
if(charset == "=00=00=FE=FF")
|
||||
sCharset = "UTF-32BE";
|
||||
else if(charset == "=FF=FE=00=00")
|
||||
sCharset = "UTF-32LE";
|
||||
else if(charset == "=2B=2F=76=38" || charset == "=2B=2F=76=39" ||
|
||||
charset == "=2B=2F=76=2B" || charset == "=2B=2F=76=2F")
|
||||
sCharset = "UTF-7";
|
||||
else if(charset == "=DD=73=66=73")
|
||||
sCharset = "UTF-EBCDIC";
|
||||
else if(charset == "=84=31=95=33")
|
||||
sCharset = "GB-18030";
|
||||
else
|
||||
{
|
||||
nIgnore -= 3;
|
||||
charset.erase(nIgnore);
|
||||
if(charset == "=EF=BB=BF")
|
||||
sCharset = "UTF-8";
|
||||
else if(charset == "=F7=64=4C")
|
||||
sCharset = "UTF-1";
|
||||
else if(charset == "=0E=FE=FF")
|
||||
sCharset = "SCSU";
|
||||
else if(charset == "=FB=EE=28")
|
||||
sCharset = "BOCU-1";
|
||||
else
|
||||
{
|
||||
nIgnore -= 3;
|
||||
charset.erase(nIgnore);
|
||||
if(charset == "=FE=FF")
|
||||
sCharset = "UTF-16BE";
|
||||
else if(charset == "=FF=FE")
|
||||
sCharset = "UTF-16LE";
|
||||
else
|
||||
nIgnore -= 6;
|
||||
}
|
||||
}
|
||||
|
||||
ip = nIgnore;
|
||||
i = sContent.find('=', ip);
|
||||
}
|
||||
|
||||
while(i != std::string::npos && i + 2 < sContent.length())
|
||||
{
|
||||
sRes.WriteString(sContent.c_str() + ip, i - ip);
|
||||
std::string str = sContent.substr(i + 1, 2);
|
||||
if(str.front() == '\n' || str.front() == '\r')
|
||||
{
|
||||
char ch = str[1];
|
||||
if(ch != '\n' && ch != '\r')
|
||||
sRes.WriteString(&ch, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* err;
|
||||
char ch = (int)strtol(str.data(), &err, 16);
|
||||
if(*err)
|
||||
sRes.WriteString('=' + str);
|
||||
else
|
||||
sRes.WriteString(&ch, 1);
|
||||
}
|
||||
ip = i + 3;
|
||||
i = sContent.find('=', ip);
|
||||
}
|
||||
if(ip != std::string::npos)
|
||||
sRes.WriteString(sContent.c_str() + ip);
|
||||
return sRes.GetData();
|
||||
}
|
||||
|
||||
static std::string mhtTohtml(const std::string& sFileContent);
|
||||
|
||||
static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes)
|
||||
{
|
||||
size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos;
|
||||
|
||||
NSStringFinder::TFoundedData<char> oData;
|
||||
|
||||
// Content-Type
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"});
|
||||
const std::string sContentType{oData.m_sValue};
|
||||
|
||||
if (sContentType.empty())
|
||||
return;
|
||||
|
||||
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
|
||||
{
|
||||
oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition)));
|
||||
return;
|
||||
}
|
||||
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetBegin = oData.m_unEndPosition;
|
||||
|
||||
// name
|
||||
// std::string sName = NSStringFinder::FindProperty(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition);
|
||||
// unContentPosition = std::max(unContentPosition, unLastPosition);
|
||||
|
||||
// Content-Location
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"});
|
||||
std::string sContentLocation{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
|
||||
// Content-ID
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"});
|
||||
std::string sContentID{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
{
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
|
||||
NSStringFinder::CutInside<std::string>(sContentID, "<", ">");
|
||||
}
|
||||
|
||||
if (sContentLocation.empty() && !sContentID.empty())
|
||||
sContentLocation = "cid:" + sContentID;
|
||||
|
||||
// Content-Transfer-Encoding
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"});
|
||||
const std::string sContentEncoding{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
{
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
|
||||
}
|
||||
|
||||
// charset
|
||||
std::string sCharset = "utf-8";
|
||||
|
||||
if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd)
|
||||
{
|
||||
sCharset = NSStringFinder::FindProperty(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue;
|
||||
NSStringFinder::CutInside<std::string>(sCharset, "\"");
|
||||
}
|
||||
|
||||
// Content
|
||||
std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition);
|
||||
|
||||
// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName));
|
||||
// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
|
||||
// Основной документ
|
||||
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
|
||||
oRes.WriteString(mhtTohtml(sContent));
|
||||
else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/)
|
||||
|| (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css")))
|
||||
{
|
||||
// Стили заключаются в тэг <style>
|
||||
const bool bAddTagStyle = NSStringFinder::Equals(sContentType, "text/css") /*|| NSStringFinder::Equals(sExtention, L"css")*/ || NSStringFinder::Find(sContentLocation, "css");
|
||||
|
||||
if (bAddTagStyle)
|
||||
oRes.WriteString("<style>");
|
||||
|
||||
if (NSStringFinder::Equals(sContentEncoding, "base64"))
|
||||
sContent = Base64ToString(sContent, sCharset);
|
||||
else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty())
|
||||
{
|
||||
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
|
||||
}
|
||||
}
|
||||
else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable"))
|
||||
{
|
||||
sContent = QuotedPrintableDecode(sContent, sCharset);
|
||||
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
|
||||
}
|
||||
}
|
||||
|
||||
if (NSStringFinder::Equals(sContentType, "text/html"))
|
||||
sContent = U_TO_UTF8(htmlToXhtml(sContent, false));
|
||||
|
||||
oRes.WriteString(sContent);
|
||||
|
||||
if(bAddTagStyle)
|
||||
oRes.WriteString("</style>");
|
||||
}
|
||||
// Картинки
|
||||
else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) &&
|
||||
NSStringFinder::Equals(sContentEncoding, "base64"))
|
||||
{
|
||||
// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico"))
|
||||
// sContentType = "image/jpg";
|
||||
// else if(NSStringFinder::Equals(sExtention, L"gif"))
|
||||
// sContentType = "image/gif";
|
||||
int nSrcLen = (int)sContent.length();
|
||||
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
|
||||
BYTE* pData = new BYTE[nDecodeLen];
|
||||
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
|
||||
sRes.insert(std::make_pair(sContentLocation, "data:" + sContentType + ";base64," + sContent));
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string mhtTohtml(const std::string& sFileContent)
|
||||
{
|
||||
std::map<std::string, std::string> sRes;
|
||||
NSStringUtils::CStringBuilderA oRes;
|
||||
|
||||
// Поиск boundary
|
||||
NSStringFinder::TFoundedData<char> oData{NSStringFinder::FindProperty(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})};
|
||||
|
||||
size_t nFound{oData.m_unEndPosition};
|
||||
std::string sBoundary{oData.m_sValue};
|
||||
|
||||
if (sBoundary.empty())
|
||||
{
|
||||
size_t nFoundEnd = sFileContent.length();
|
||||
nFound = 0;
|
||||
ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes);
|
||||
return oRes.GetData();
|
||||
}
|
||||
|
||||
NSStringFinder::CutInside<std::string>(sBoundary, "\"");
|
||||
|
||||
size_t nFoundEnd{nFound};
|
||||
|
||||
sBoundary = "--" + sBoundary;
|
||||
size_t nBoundaryLength = sBoundary.length();
|
||||
|
||||
nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength;
|
||||
|
||||
// Цикл по boundary
|
||||
while(nFound != std::string::npos)
|
||||
{
|
||||
nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength);
|
||||
if(nFoundEnd == std::string::npos)
|
||||
break;
|
||||
|
||||
ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes);
|
||||
|
||||
nFound = sFileContent.find(sBoundary, nFoundEnd);
|
||||
}
|
||||
|
||||
std::string sFile = oRes.GetData();
|
||||
for(const std::pair<std::string, std::string>& item : sRes)
|
||||
{
|
||||
std::string sName = item.first;
|
||||
size_t found = sFile.find(sName);
|
||||
size_t sfound = sName.rfind('/');
|
||||
if(found == std::string::npos && sfound != std::string::npos)
|
||||
found = sFile.find(sName.erase(0, sfound + 1));
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
size_t fq = sFile.find_last_of("\"\'>=", found);
|
||||
|
||||
if (std::string::npos == fq)
|
||||
break;
|
||||
|
||||
char ch = sFile[fq];
|
||||
if(ch != '\"' && ch != '\'')
|
||||
fq++;
|
||||
size_t tq = sFile.find_first_of("\"\'<> ", found) + 1;
|
||||
|
||||
if (std::string::npos == tq)
|
||||
break;
|
||||
|
||||
if(sFile[tq] != '\"' && sFile[tq] != '\'')
|
||||
tq--;
|
||||
if(ch != '>')
|
||||
{
|
||||
std::string is = '\"' + item.second + '\"';
|
||||
sFile.replace(fq, tq - fq, is);
|
||||
found = sFile.find(sName, fq + is.length());
|
||||
}
|
||||
else
|
||||
found = sFile.find(sName, tq);
|
||||
}
|
||||
}
|
||||
|
||||
return sFile;
|
||||
}
|
||||
|
||||
// Заменяет сущности &,<,> в text
|
||||
static void substitute_xml_entities_into_text(std::string& text)
|
||||
{
|
||||
// replacing & must come first
|
||||
replace_all(text, "&", "&");
|
||||
replace_all(text, "<", "<");
|
||||
replace_all(text, ">", ">");
|
||||
}
|
||||
|
||||
// After running through Gumbo, the values of type "" are replaced with the corresponding code '0x01'
|
||||
// Since the attribute value does not use control characters (value <= 0x09),
|
||||
// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them.
|
||||
// bug#73486
|
||||
static void remove_control_symbols(std::string& text)
|
||||
{
|
||||
std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
|
||||
|
||||
while (itFound != text.end())
|
||||
{
|
||||
itFound = text.erase(itFound);
|
||||
itFound = std::find_if(itFound, text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
|
||||
}
|
||||
}
|
||||
|
||||
// Заменяет сущности " в text
|
||||
static void substitute_xml_entities_into_attributes(std::string& text)
|
||||
{
|
||||
remove_control_symbols(text);
|
||||
substitute_xml_entities_into_text(text);
|
||||
replace_all(text, "\"", """);
|
||||
}
|
||||
|
||||
static std::string handle_unknown_tag(GumboStringPiece* text)
|
||||
{
|
||||
if (text->data == NULL)
|
||||
return "";
|
||||
GumboStringPiece gsp = *text;
|
||||
gumbo_tag_from_original_text(&gsp);
|
||||
std::string sAtr = std::string(gsp.data, gsp.length);
|
||||
size_t found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}");
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
sAtr.erase(found, 1);
|
||||
found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}", found);
|
||||
}
|
||||
return sAtr;
|
||||
}
|
||||
|
||||
static std::string get_tag_name(GumboNode* node)
|
||||
{
|
||||
std::string tagname = (node->type == GUMBO_NODE_DOCUMENT ? "document" : gumbo_normalized_tagname(node->v.element.tag));
|
||||
if (tagname.empty())
|
||||
tagname = handle_unknown_tag(&node->v.element.original_tag);
|
||||
return tagname;
|
||||
}
|
||||
|
||||
static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder)
|
||||
{
|
||||
if (node->v.document.has_doctype)
|
||||
{
|
||||
oBuilder.WriteString("<!DOCTYPE ");
|
||||
oBuilder.WriteString(node->v.document.name);
|
||||
std::string pi(node->v.document.public_identifier);
|
||||
remove_control_symbols(pi);
|
||||
if ((node->v.document.public_identifier != NULL) && !pi.empty())
|
||||
{
|
||||
oBuilder.WriteString(" PUBLIC \"");
|
||||
oBuilder.WriteString(pi);
|
||||
oBuilder.WriteString("\" \"");
|
||||
oBuilder.WriteString(node->v.document.system_identifier);
|
||||
oBuilder.WriteString("\"");
|
||||
}
|
||||
oBuilder.WriteString(">");
|
||||
}
|
||||
}
|
||||
|
||||
static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts)
|
||||
{
|
||||
std::vector<std::string> arrRepeat;
|
||||
for (size_t i = 0; i < attribs->length; ++i)
|
||||
{
|
||||
GumboAttribute* at = static_cast<GumboAttribute*>(attribs->data[i]);
|
||||
std::string sVal(at->value);
|
||||
std::string sName(at->name);
|
||||
|
||||
remove_control_symbols(sVal);
|
||||
remove_control_symbols(sName);
|
||||
|
||||
atts.WriteString(" ");
|
||||
|
||||
bool bCheck = false;
|
||||
size_t nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}");
|
||||
while(nBad != std::string::npos)
|
||||
{
|
||||
sName.erase(nBad, 1);
|
||||
nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}", nBad);
|
||||
if(sName.empty())
|
||||
break;
|
||||
bCheck = true;
|
||||
}
|
||||
if(sName.empty())
|
||||
continue;
|
||||
while(sName.front() >= '0' && sName.front() <= '9')
|
||||
{
|
||||
sName.erase(0, 1);
|
||||
if(sName.empty())
|
||||
break;
|
||||
bCheck = true;
|
||||
}
|
||||
if(bCheck)
|
||||
{
|
||||
GumboAttribute* check = gumbo_get_attribute(attribs, sName.c_str());
|
||||
if(check || std::find(arrRepeat.begin(), arrRepeat.end(), sName) != arrRepeat.end())
|
||||
continue;
|
||||
else
|
||||
arrRepeat.push_back(sName);
|
||||
}
|
||||
|
||||
if(sName.empty())
|
||||
continue;
|
||||
atts.WriteString(sName);
|
||||
|
||||
// determine original quote character used if it exists
|
||||
std::string qs ="\"";
|
||||
atts.WriteString("=");
|
||||
atts.WriteString(qs);
|
||||
substitute_xml_entities_into_attributes(sVal);
|
||||
atts.WriteString(sVal);
|
||||
atts.WriteString(qs);
|
||||
}
|
||||
}
|
||||
|
||||
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true);
|
||||
|
||||
static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode)
|
||||
{
|
||||
std::string key = "|" + get_tag_name(node) + "|";
|
||||
bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos;
|
||||
bool is_inline = nonbreaking_inline.find(key) != std::string::npos;
|
||||
bool is_like_inline = treat_like_inline.find(key) != std::string::npos;
|
||||
|
||||
GumboVector* children = &node->v.element.children;
|
||||
|
||||
for (size_t i = 0; i < children->length; i++)
|
||||
{
|
||||
GumboNode* child = static_cast<GumboNode*> (children->data[i]);
|
||||
|
||||
if (child->type == GUMBO_NODE_TEXT)
|
||||
{
|
||||
std::string val(child->v.text.text);
|
||||
remove_control_symbols(val);
|
||||
substitute_xml_entities_into_text(val);
|
||||
|
||||
// Избавление от FF
|
||||
size_t found = val.find_first_of("\014");
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
val.erase(found, 1);
|
||||
found = val.find_first_of("\014", found);
|
||||
}
|
||||
|
||||
contents.WriteString(val);
|
||||
}
|
||||
else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE))
|
||||
prettyprint(child, contents, bCheckValidNode);
|
||||
else if (child->type == GUMBO_NODE_WHITESPACE)
|
||||
{
|
||||
if (keep_whitespace || is_inline || is_like_inline)
|
||||
contents.WriteString(child->v.text.text);
|
||||
}
|
||||
else if (child->type != GUMBO_NODE_COMMENT)
|
||||
{
|
||||
// Сообщение об ошибке
|
||||
// Does this actually exist: (child->type == GUMBO_NODE_CDATA)
|
||||
// fprintf(stderr, "unknown element of type: %d\n", child->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode)
|
||||
{
|
||||
// special case the document node
|
||||
if (node->type == GUMBO_NODE_DOCUMENT)
|
||||
{
|
||||
build_doctype(node, oBuilder);
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tagname = get_tag_name(node);
|
||||
remove_control_symbols(tagname);
|
||||
|
||||
if (NodeIsUnprocessed(tagname))
|
||||
return;
|
||||
|
||||
if (bCheckValidNode)
|
||||
bCheckValidNode = !IsUnckeckedNodes(tagname);
|
||||
|
||||
if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname))
|
||||
{
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string close = "";
|
||||
std::string closeTag = "";
|
||||
std::string key = "|" + tagname + "|";
|
||||
bool is_empty_tag = empty_tags.find(key) != std::string::npos;
|
||||
|
||||
// determine closing tag type
|
||||
if (is_empty_tag)
|
||||
close = "/";
|
||||
else
|
||||
closeTag = "</" + tagname + ">";
|
||||
|
||||
// build results
|
||||
oBuilder.WriteString("<" + tagname);
|
||||
|
||||
// build attr string
|
||||
const GumboVector* attribs = &node->v.element.attributes;
|
||||
build_attributes(attribs, oBuilder);
|
||||
oBuilder.WriteString(close + ">");
|
||||
|
||||
// prettyprint your contents
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
oBuilder.WriteString(closeTag);
|
||||
}
|
||||
|
||||
std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert)
|
||||
{
|
||||
if (bNeedConvert)
|
||||
{ // Определение кодировки
|
||||
std::string sEncoding = NSStringFinder::FindProperty(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\"", "'"}).m_sValue;
|
||||
|
||||
if (sEncoding.empty())
|
||||
sEncoding = NSStringFinder::FindProperty(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue;
|
||||
|
||||
if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding))
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// Избавляемся от лишних символов до <...
|
||||
boost::regex oRegex("<[a-zA-Z]");
|
||||
boost::match_results<typename std::string::const_iterator> oResult;
|
||||
|
||||
if (boost::regex_search(sFileContent, oResult, oRegex))
|
||||
sFileContent.erase(0, oResult.position());
|
||||
|
||||
//Избавление от <a ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "a"));
|
||||
//Избавление от <title ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "title"));
|
||||
//Избавление от <script ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "script"));
|
||||
|
||||
// Gumbo
|
||||
GumboOptions options = kGumboDefaultOptions;
|
||||
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
|
||||
|
||||
// prettyprint
|
||||
NSStringUtils::CStringBuilderA oBuilder;
|
||||
prettyprint(output->document, oBuilder);
|
||||
|
||||
// Конвертирование из string utf8 в wstring
|
||||
return UTF8_TO_U(oBuilder.GetData());
|
||||
}
|
||||
|
||||
std::wstring mhtToXhtml(std::string& sFileContent)
|
||||
{
|
||||
sFileContent = mhtTohtml(sFileContent);
|
||||
|
||||
// Gumbo
|
||||
GumboOptions options = kGumboDefaultOptions;
|
||||
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
|
||||
|
||||
// prettyprint
|
||||
NSStringUtils::CStringBuilderA oBuilder;
|
||||
prettyprint(output->document, oBuilder);
|
||||
|
||||
// Конвертирование из string utf8 в wstring
|
||||
return UTF8_TO_U(oBuilder.GetData());
|
||||
}
|
||||
}
|
||||
@ -2,658 +2,11 @@
|
||||
#define HTMLTOXHTML_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "gumbo-parser/src/gumbo.h"
|
||||
#include "../../../DesktopEditor/common/File.h"
|
||||
#include "../../../DesktopEditor/common/Directory.h"
|
||||
#include "../../../DesktopEditor/common/StringBuilder.h"
|
||||
#include "../../../DesktopEditor/xml/include/xmlutils.h"
|
||||
#include "../../../UnicodeConverter/UnicodeConverter.h"
|
||||
#include "../../../HtmlFile2/src/StringFinder.h"
|
||||
|
||||
#if defined(CreateDirectory)
|
||||
#undef CreateDirectory
|
||||
#endif
|
||||
|
||||
static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|";
|
||||
static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|";
|
||||
static std::string preserve_whitespace = "|pre|textarea|script|style|";
|
||||
static std::string special_handling = "|html|body|";
|
||||
static std::string treat_like_inline = "|p|";
|
||||
|
||||
static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6",
|
||||
"ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th",
|
||||
"br","form","input","button","section","nav","header","footer",
|
||||
"main","figure","figcaption","strong","em","i", "b", "u","pre",
|
||||
"code","blockquote","hr","script","link","meta","style","title",
|
||||
"head","body","html","legend","optgroup","option","select","dl",
|
||||
"dt","dd","time","data","abbr","address","area","base","bdi",
|
||||
"bdo","cite","col","iframe","video","source","track","textarea",
|
||||
"label","fieldset","colgroup","del","ins","details","summary",
|
||||
"dialog","embed","kbd","map","mark","menu","meter","object",
|
||||
"output","param","progress","q","samp","small","sub","sup","var",
|
||||
"wbr","acronym","applet","article","aside","audio","basefont",
|
||||
"bgsound","big","blink","canvas","caption","center","command",
|
||||
"comment","datalist","dfn","dir","font","frame","frameset",
|
||||
"hgroup","isindex","keygen","marquee","nobr","noembed","noframes",
|
||||
"noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"};
|
||||
|
||||
static std::vector<std::string> unchecked_nodes_new = {"svg"};
|
||||
|
||||
static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true);
|
||||
static std::string mhtTohtml(const std::string &sFileContent);
|
||||
|
||||
// Заменяет в строке s все символы s1 на s2
|
||||
static void replace_all(std::string& s, const std::string& s1, const std::string& s2)
|
||||
namespace HTML
|
||||
{
|
||||
size_t pos = s.find(s1);
|
||||
while(pos != std::string::npos)
|
||||
{
|
||||
s.replace(pos, s1.length(), s2);
|
||||
pos = s.find(s1, pos + s2.length());
|
||||
}
|
||||
}
|
||||
|
||||
static bool NodeIsUnprocessed(const std::string& wsTagName)
|
||||
{
|
||||
return "xml" == wsTagName;
|
||||
}
|
||||
|
||||
static bool IsUnckeckedNodes(const std::string& sValue)
|
||||
{
|
||||
return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue);
|
||||
}
|
||||
|
||||
static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert)
|
||||
{
|
||||
if (bNeedConvert)
|
||||
{ // Определение кодировки
|
||||
std::string sEncoding = NSStringFinder::FindProperty(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\"", "'"}).m_sValue;
|
||||
|
||||
if (sEncoding.empty())
|
||||
sEncoding = NSStringFinder::FindProperty(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue;
|
||||
|
||||
if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding))
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
// Избавляемся от лишних символов до <...
|
||||
boost::regex oRegex("<[a-zA-Z]");
|
||||
boost::match_results<typename std::string::const_iterator> oResult;
|
||||
|
||||
if (boost::regex_search(sFileContent, oResult, oRegex))
|
||||
sFileContent.erase(0, oResult.position());
|
||||
|
||||
//Избавление от <a ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "a"));
|
||||
//Избавление от <title ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "title"));
|
||||
//Избавление от <script ... />
|
||||
while (NSStringFinder::RemoveEmptyTag(sFileContent, "script"));
|
||||
|
||||
// Gumbo
|
||||
GumboOptions options = kGumboDefaultOptions;
|
||||
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
|
||||
|
||||
// prettyprint
|
||||
NSStringUtils::CStringBuilderA oBuilder;
|
||||
prettyprint(output->document, oBuilder);
|
||||
|
||||
// Конвертирование из string utf8 в wstring
|
||||
return UTF8_TO_U(oBuilder.GetData());
|
||||
}
|
||||
|
||||
static std::string Base64ToString(const std::string& sContent, const std::string& sCharset)
|
||||
{
|
||||
std::string sRes;
|
||||
int nSrcLen = (int)sContent.length();
|
||||
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
|
||||
BYTE* pData = new BYTE[nDecodeLen];
|
||||
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
|
||||
{
|
||||
std::wstring sConvert;
|
||||
if(!sCharset.empty() && NSStringFinder::Equals<std::string>("utf-8", sCharset))
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sConvert = oConverter.toUnicode(reinterpret_cast<char *>(pData), (unsigned)nDecodeLen, sCharset.data());
|
||||
}
|
||||
sRes = sConvert.empty() ? std::string(reinterpret_cast<char *>(pData), nDecodeLen) : U_TO_UTF8(sConvert);
|
||||
}
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
return sRes;
|
||||
}
|
||||
|
||||
static std::string QuotedPrintableDecode(const std::string& sContent, std::string& sCharset)
|
||||
{
|
||||
NSStringUtils::CStringBuilderA sRes;
|
||||
size_t ip = 0;
|
||||
size_t i = sContent.find('=');
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
size_t nIgnore = 12;
|
||||
std::string charset = sContent.substr(0, nIgnore);
|
||||
if(charset == "=00=00=FE=FF")
|
||||
sCharset = "UTF-32BE";
|
||||
else if(charset == "=FF=FE=00=00")
|
||||
sCharset = "UTF-32LE";
|
||||
else if(charset == "=2B=2F=76=38" || charset == "=2B=2F=76=39" ||
|
||||
charset == "=2B=2F=76=2B" || charset == "=2B=2F=76=2F")
|
||||
sCharset = "UTF-7";
|
||||
else if(charset == "=DD=73=66=73")
|
||||
sCharset = "UTF-EBCDIC";
|
||||
else if(charset == "=84=31=95=33")
|
||||
sCharset = "GB-18030";
|
||||
else
|
||||
{
|
||||
nIgnore -= 3;
|
||||
charset.erase(nIgnore);
|
||||
if(charset == "=EF=BB=BF")
|
||||
sCharset = "UTF-8";
|
||||
else if(charset == "=F7=64=4C")
|
||||
sCharset = "UTF-1";
|
||||
else if(charset == "=0E=FE=FF")
|
||||
sCharset = "SCSU";
|
||||
else if(charset == "=FB=EE=28")
|
||||
sCharset = "BOCU-1";
|
||||
else
|
||||
{
|
||||
nIgnore -= 3;
|
||||
charset.erase(nIgnore);
|
||||
if(charset == "=FE=FF")
|
||||
sCharset = "UTF-16BE";
|
||||
else if(charset == "=FF=FE")
|
||||
sCharset = "UTF-16LE";
|
||||
else
|
||||
nIgnore -= 6;
|
||||
}
|
||||
}
|
||||
|
||||
ip = nIgnore;
|
||||
i = sContent.find('=', ip);
|
||||
}
|
||||
|
||||
while(i != std::string::npos && i + 2 < sContent.length())
|
||||
{
|
||||
sRes.WriteString(sContent.c_str() + ip, i - ip);
|
||||
std::string str = sContent.substr(i + 1, 2);
|
||||
if(str.front() == '\n' || str.front() == '\r')
|
||||
{
|
||||
char ch = str[1];
|
||||
if(ch != '\n' && ch != '\r')
|
||||
sRes.WriteString(&ch, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* err;
|
||||
char ch = (int)strtol(str.data(), &err, 16);
|
||||
if(*err)
|
||||
sRes.WriteString('=' + str);
|
||||
else
|
||||
sRes.WriteString(&ch, 1);
|
||||
}
|
||||
ip = i + 3;
|
||||
i = sContent.find('=', ip);
|
||||
}
|
||||
if(ip != std::string::npos)
|
||||
sRes.WriteString(sContent.c_str() + ip);
|
||||
return sRes.GetData();
|
||||
}
|
||||
|
||||
static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes)
|
||||
{
|
||||
size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos;
|
||||
|
||||
NSStringFinder::TFoundedData<char> oData;
|
||||
|
||||
// Content-Type
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"});
|
||||
const std::string sContentType{oData.m_sValue};
|
||||
|
||||
if (sContentType.empty())
|
||||
return;
|
||||
|
||||
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
|
||||
{
|
||||
oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition)));
|
||||
return;
|
||||
}
|
||||
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetBegin = oData.m_unEndPosition;
|
||||
|
||||
// name
|
||||
// std::string sName = NSStringFinder::FindProperty(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition);
|
||||
// unContentPosition = std::max(unContentPosition, unLastPosition);
|
||||
|
||||
// Content-Location
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"});
|
||||
std::string sContentLocation{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
|
||||
// Content-ID
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"});
|
||||
std::string sContentID{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
{
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
|
||||
NSStringFinder::CutInside<std::string>(sContentID, "<", ">");
|
||||
}
|
||||
|
||||
if (sContentLocation.empty() && !sContentID.empty())
|
||||
sContentLocation = "cid:" + sContentID;
|
||||
|
||||
// Content-Transfer-Encoding
|
||||
oData = NSStringFinder::FindProperty(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"});
|
||||
const std::string sContentEncoding{oData.m_sValue};
|
||||
|
||||
if (!oData.Empty())
|
||||
{
|
||||
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
|
||||
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
|
||||
}
|
||||
|
||||
// charset
|
||||
std::string sCharset = "utf-8";
|
||||
|
||||
if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd)
|
||||
{
|
||||
sCharset = NSStringFinder::FindProperty(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue;
|
||||
NSStringFinder::CutInside<std::string>(sCharset, "\"");
|
||||
}
|
||||
|
||||
// Content
|
||||
std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition);
|
||||
|
||||
// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName));
|
||||
// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
|
||||
// Основной документ
|
||||
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
|
||||
oRes.WriteString(mhtTohtml(sContent));
|
||||
else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/)
|
||||
|| (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css")))
|
||||
{
|
||||
// Стили заключаются в тэг <style>
|
||||
const bool bAddTagStyle = NSStringFinder::Equals(sContentType, "text/css") /*|| NSStringFinder::Equals(sExtention, L"css")*/ || NSStringFinder::Find(sContentLocation, "css");
|
||||
|
||||
if (bAddTagStyle)
|
||||
oRes.WriteString("<style>");
|
||||
|
||||
if (NSStringFinder::Equals(sContentEncoding, "base64"))
|
||||
sContent = Base64ToString(sContent, sCharset);
|
||||
else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty())
|
||||
{
|
||||
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
|
||||
}
|
||||
}
|
||||
else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable"))
|
||||
{
|
||||
sContent = QuotedPrintableDecode(sContent, sCharset);
|
||||
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
|
||||
}
|
||||
}
|
||||
|
||||
if (NSStringFinder::Equals(sContentType, "text/html"))
|
||||
sContent = U_TO_UTF8(htmlToXhtml(sContent, false));
|
||||
|
||||
oRes.WriteString(sContent);
|
||||
|
||||
if(bAddTagStyle)
|
||||
oRes.WriteString("</style>");
|
||||
}
|
||||
// Картинки
|
||||
else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) &&
|
||||
NSStringFinder::Equals(sContentEncoding, "base64"))
|
||||
{
|
||||
// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico"))
|
||||
// sContentType = "image/jpg";
|
||||
// else if(NSStringFinder::Equals(sExtention, L"gif"))
|
||||
// sContentType = "image/gif";
|
||||
int nSrcLen = (int)sContent.length();
|
||||
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
|
||||
BYTE* pData = new BYTE[nDecodeLen];
|
||||
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
|
||||
sRes.insert(std::make_pair(sContentLocation, "data:" + sContentType + ";base64," + sContent));
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
}
|
||||
}
|
||||
|
||||
static std::string mhtTohtml(const std::string& sFileContent)
|
||||
{
|
||||
std::map<std::string, std::string> sRes;
|
||||
NSStringUtils::CStringBuilderA oRes;
|
||||
|
||||
// Поиск boundary
|
||||
NSStringFinder::TFoundedData<char> oData{NSStringFinder::FindProperty(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})};
|
||||
|
||||
size_t nFound{oData.m_unEndPosition};
|
||||
std::string sBoundary{oData.m_sValue};
|
||||
|
||||
if (sBoundary.empty())
|
||||
{
|
||||
size_t nFoundEnd = sFileContent.length();
|
||||
nFound = 0;
|
||||
ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes);
|
||||
return oRes.GetData();
|
||||
}
|
||||
|
||||
NSStringFinder::CutInside<std::string>(sBoundary, "\"");
|
||||
|
||||
size_t nFoundEnd{nFound};
|
||||
|
||||
sBoundary = "--" + sBoundary;
|
||||
size_t nBoundaryLength = sBoundary.length();
|
||||
|
||||
nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength;
|
||||
|
||||
// Цикл по boundary
|
||||
while(nFound != std::string::npos)
|
||||
{
|
||||
nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength);
|
||||
if(nFoundEnd == std::string::npos)
|
||||
break;
|
||||
|
||||
ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes);
|
||||
|
||||
nFound = sFileContent.find(sBoundary, nFoundEnd);
|
||||
}
|
||||
|
||||
std::string sFile = oRes.GetData();
|
||||
for(const std::pair<std::string, std::string>& item : sRes)
|
||||
{
|
||||
std::string sName = item.first;
|
||||
size_t found = sFile.find(sName);
|
||||
size_t sfound = sName.rfind('/');
|
||||
if(found == std::string::npos && sfound != std::string::npos)
|
||||
found = sFile.find(sName.erase(0, sfound + 1));
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
size_t fq = sFile.find_last_of("\"\'>=", found);
|
||||
|
||||
if (std::string::npos == fq)
|
||||
break;
|
||||
|
||||
char ch = sFile[fq];
|
||||
if(ch != '\"' && ch != '\'')
|
||||
fq++;
|
||||
size_t tq = sFile.find_first_of("\"\'<> ", found) + 1;
|
||||
|
||||
if (std::string::npos == tq)
|
||||
break;
|
||||
|
||||
if(sFile[tq] != '\"' && sFile[tq] != '\'')
|
||||
tq--;
|
||||
if(ch != '>')
|
||||
{
|
||||
std::string is = '\"' + item.second + '\"';
|
||||
sFile.replace(fq, tq - fq, is);
|
||||
found = sFile.find(sName, fq + is.length());
|
||||
}
|
||||
else
|
||||
found = sFile.find(sName, tq);
|
||||
}
|
||||
}
|
||||
|
||||
return sFile;
|
||||
}
|
||||
|
||||
static std::wstring mhtToXhtml(std::string& sFileContent)
|
||||
{
|
||||
sFileContent = mhtTohtml(sFileContent);
|
||||
|
||||
// Gumbo
|
||||
GumboOptions options = kGumboDefaultOptions;
|
||||
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
|
||||
|
||||
// prettyprint
|
||||
NSStringUtils::CStringBuilderA oBuilder;
|
||||
prettyprint(output->document, oBuilder);
|
||||
|
||||
// Конвертирование из string utf8 в wstring
|
||||
return UTF8_TO_U(oBuilder.GetData());
|
||||
}
|
||||
|
||||
// Заменяет сущности &,<,> в text
|
||||
static void substitute_xml_entities_into_text(std::string& text)
|
||||
{
|
||||
// replacing & must come first
|
||||
replace_all(text, "&", "&");
|
||||
replace_all(text, "<", "<");
|
||||
replace_all(text, ">", ">");
|
||||
}
|
||||
|
||||
// After running through Gumbo, the values of type "" are replaced with the corresponding code '0x01'
|
||||
// Since the attribute value does not use control characters (value <= 0x09),
|
||||
// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them.
|
||||
// bug#73486
|
||||
static void remove_control_symbols(std::string& text)
|
||||
{
|
||||
std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
|
||||
|
||||
while (itFound != text.end())
|
||||
{
|
||||
itFound = text.erase(itFound);
|
||||
itFound = std::find_if(itFound, text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
|
||||
}
|
||||
}
|
||||
|
||||
// Заменяет сущности " в text
|
||||
static void substitute_xml_entities_into_attributes(std::string& text)
|
||||
{
|
||||
remove_control_symbols(text);
|
||||
substitute_xml_entities_into_text(text);
|
||||
replace_all(text, "\"", """);
|
||||
}
|
||||
|
||||
static std::string handle_unknown_tag(GumboStringPiece* text)
|
||||
{
|
||||
if (text->data == NULL)
|
||||
return "";
|
||||
GumboStringPiece gsp = *text;
|
||||
gumbo_tag_from_original_text(&gsp);
|
||||
std::string sAtr = std::string(gsp.data, gsp.length);
|
||||
size_t found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}");
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
sAtr.erase(found, 1);
|
||||
found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}", found);
|
||||
}
|
||||
return sAtr;
|
||||
}
|
||||
|
||||
static std::string get_tag_name(GumboNode* node)
|
||||
{
|
||||
std::string tagname = (node->type == GUMBO_NODE_DOCUMENT ? "document" : gumbo_normalized_tagname(node->v.element.tag));
|
||||
if (tagname.empty())
|
||||
tagname = handle_unknown_tag(&node->v.element.original_tag);
|
||||
return tagname;
|
||||
}
|
||||
|
||||
static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder)
|
||||
{
|
||||
if (node->v.document.has_doctype)
|
||||
{
|
||||
oBuilder.WriteString("<!DOCTYPE ");
|
||||
oBuilder.WriteString(node->v.document.name);
|
||||
std::string pi(node->v.document.public_identifier);
|
||||
remove_control_symbols(pi);
|
||||
if ((node->v.document.public_identifier != NULL) && !pi.empty())
|
||||
{
|
||||
oBuilder.WriteString(" PUBLIC \"");
|
||||
oBuilder.WriteString(pi);
|
||||
oBuilder.WriteString("\" \"");
|
||||
oBuilder.WriteString(node->v.document.system_identifier);
|
||||
oBuilder.WriteString("\"");
|
||||
}
|
||||
oBuilder.WriteString(">");
|
||||
}
|
||||
}
|
||||
|
||||
static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts)
|
||||
{
|
||||
std::vector<std::string> arrRepeat;
|
||||
for (size_t i = 0; i < attribs->length; ++i)
|
||||
{
|
||||
GumboAttribute* at = static_cast<GumboAttribute*>(attribs->data[i]);
|
||||
std::string sVal(at->value);
|
||||
std::string sName(at->name);
|
||||
|
||||
remove_control_symbols(sVal);
|
||||
remove_control_symbols(sName);
|
||||
|
||||
atts.WriteString(" ");
|
||||
|
||||
bool bCheck = false;
|
||||
size_t nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}");
|
||||
while(nBad != std::string::npos)
|
||||
{
|
||||
sName.erase(nBad, 1);
|
||||
nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}", nBad);
|
||||
if(sName.empty())
|
||||
break;
|
||||
bCheck = true;
|
||||
}
|
||||
if(sName.empty())
|
||||
continue;
|
||||
while(sName.front() >= '0' && sName.front() <= '9')
|
||||
{
|
||||
sName.erase(0, 1);
|
||||
if(sName.empty())
|
||||
break;
|
||||
bCheck = true;
|
||||
}
|
||||
if(bCheck)
|
||||
{
|
||||
GumboAttribute* check = gumbo_get_attribute(attribs, sName.c_str());
|
||||
if(check || std::find(arrRepeat.begin(), arrRepeat.end(), sName) != arrRepeat.end())
|
||||
continue;
|
||||
else
|
||||
arrRepeat.push_back(sName);
|
||||
}
|
||||
|
||||
if(sName.empty())
|
||||
continue;
|
||||
atts.WriteString(sName);
|
||||
|
||||
// determine original quote character used if it exists
|
||||
std::string qs ="\"";
|
||||
atts.WriteString("=");
|
||||
atts.WriteString(qs);
|
||||
substitute_xml_entities_into_attributes(sVal);
|
||||
atts.WriteString(sVal);
|
||||
atts.WriteString(qs);
|
||||
}
|
||||
}
|
||||
|
||||
static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode)
|
||||
{
|
||||
std::string key = "|" + get_tag_name(node) + "|";
|
||||
bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos;
|
||||
bool is_inline = nonbreaking_inline.find(key) != std::string::npos;
|
||||
bool is_like_inline = treat_like_inline.find(key) != std::string::npos;
|
||||
|
||||
GumboVector* children = &node->v.element.children;
|
||||
|
||||
for (size_t i = 0; i < children->length; i++)
|
||||
{
|
||||
GumboNode* child = static_cast<GumboNode*> (children->data[i]);
|
||||
|
||||
if (child->type == GUMBO_NODE_TEXT)
|
||||
{
|
||||
std::string val(child->v.text.text);
|
||||
remove_control_symbols(val);
|
||||
substitute_xml_entities_into_text(val);
|
||||
|
||||
// Избавление от FF
|
||||
size_t found = val.find_first_of("\014");
|
||||
while(found != std::string::npos)
|
||||
{
|
||||
val.erase(found, 1);
|
||||
found = val.find_first_of("\014", found);
|
||||
}
|
||||
|
||||
contents.WriteString(val);
|
||||
}
|
||||
else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE))
|
||||
prettyprint(child, contents, bCheckValidNode);
|
||||
else if (child->type == GUMBO_NODE_WHITESPACE)
|
||||
{
|
||||
if (keep_whitespace || is_inline || is_like_inline)
|
||||
contents.WriteString(child->v.text.text);
|
||||
}
|
||||
else if (child->type != GUMBO_NODE_COMMENT)
|
||||
{
|
||||
// Сообщение об ошибке
|
||||
// Does this actually exist: (child->type == GUMBO_NODE_CDATA)
|
||||
// fprintf(stderr, "unknown element of type: %d\n", child->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode)
|
||||
{
|
||||
// special case the document node
|
||||
if (node->type == GUMBO_NODE_DOCUMENT)
|
||||
{
|
||||
build_doctype(node, oBuilder);
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tagname = get_tag_name(node);
|
||||
remove_control_symbols(tagname);
|
||||
|
||||
if (NodeIsUnprocessed(tagname))
|
||||
return;
|
||||
|
||||
if (bCheckValidNode)
|
||||
bCheckValidNode = !IsUnckeckedNodes(tagname);
|
||||
|
||||
if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname))
|
||||
{
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string close = "";
|
||||
std::string closeTag = "";
|
||||
std::string key = "|" + tagname + "|";
|
||||
bool is_empty_tag = empty_tags.find(key) != std::string::npos;
|
||||
|
||||
// determine closing tag type
|
||||
if (is_empty_tag)
|
||||
close = "/";
|
||||
else
|
||||
closeTag = "</" + tagname + ">";
|
||||
|
||||
// build results
|
||||
oBuilder.WriteString("<" + tagname);
|
||||
|
||||
// build attr string
|
||||
const GumboVector* attribs = &node->v.element.attributes;
|
||||
build_attributes(attribs, oBuilder);
|
||||
oBuilder.WriteString(close + ">");
|
||||
|
||||
// prettyprint your contents
|
||||
prettyprint_contents(node, oBuilder, bCheckValidNode);
|
||||
oBuilder.WriteString(closeTag);
|
||||
std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert);
|
||||
std::wstring mhtToXhtml(std::string& sFileContent);
|
||||
}
|
||||
|
||||
#endif // HTMLTOXHTML_H
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
<<<<<<<
|
||||
if((c >= 'a' && c <= 'z') || (c>= 'A' && c<= 'Z') || (c >= '0' && c<= '9')){
|
||||
=======
|
||||
if((c >= 'a' && c <= 'z') || (c>= 'A' && c<= 'Z') || (c >= '0' && c<= '9') || ('-' == c) || ('_' == c) || ('.' == c) || ('~' == c)){
|
||||
>>>>>>>
|
||||
@ -105,11 +105,37 @@ namespace NSNetwork
|
||||
{
|
||||
static NSString* StringWToNSString ( const std::wstring& Str )
|
||||
{
|
||||
// Returns +1 retained NSString (alloc/init). Caller must release in non-ARC.
|
||||
NSString* pString = [ [ NSString alloc ]
|
||||
initWithBytes : (char*)Str.data() length : Str.size() * sizeof(wchar_t)
|
||||
encoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE ) ];
|
||||
initWithBytes : (char*)Str.data() length : Str.size() * sizeof(wchar_t)
|
||||
encoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE ) ];
|
||||
return pString;
|
||||
}
|
||||
|
||||
// NSURLComponents correctly handles mixed input (already-encoded + raw characters)
|
||||
// without double-encoding, but normalises unreserved percent-sequences (%5F → _).
|
||||
// If preserving the exact encoding is required, use [NSURL URLWithString:] instead.
|
||||
static NSURL* SafeURLFromString(NSString* urlString)
|
||||
{
|
||||
if (!urlString || urlString.length == 0)
|
||||
return nil;
|
||||
|
||||
NSURL* url = [NSURL URLWithString:urlString];
|
||||
if (url)
|
||||
return url;
|
||||
|
||||
// Fallback: the string contains unencoded characters (spaces, cyrillic,
|
||||
// brackets, etc.). URLFragmentAllowedCharacterSet includes '%', so
|
||||
// existing percent-sequences won't be double-encoded.
|
||||
NSString* encoded =
|
||||
[urlString stringByAddingPercentEncodingWithAllowedCharacters:
|
||||
[NSCharacterSet URLFragmentAllowedCharacterSet]];
|
||||
if (!encoded)
|
||||
return nil;
|
||||
|
||||
return [NSURL URLWithString:encoded];
|
||||
}
|
||||
|
||||
class CFileTransporterBaseCocoa : public CFileTransporterBase
|
||||
{
|
||||
public :
|
||||
@ -145,83 +171,162 @@ namespace NSNetwork
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
// stringURL: +1 retained (alloc/init). Must be released on all exit paths in non-ARC.
|
||||
NSString* stringURL = StringWToNSString(m_sDownloadFileUrl);
|
||||
NSString* escapedURL = [stringURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
NSURL* url = SafeURLFromString(stringURL);
|
||||
|
||||
int nResult = 1;
|
||||
|
||||
if (m_pSession)
|
||||
if (!url)
|
||||
{
|
||||
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:escapedURL]];
|
||||
|
||||
__block NSData* result = nil;
|
||||
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
||||
|
||||
NSURLSession* _session = ((CSessionMAC*)m_pSession->m_pInternal)->m_session;
|
||||
if (nil == _session)
|
||||
_session = [NSURLSession sharedSession];
|
||||
|
||||
[[_session dataTaskWithRequest:urlRequest
|
||||
completionHandler:^(NSData *data, NSURLResponse* response, NSError *error) {
|
||||
if (error == nil)
|
||||
result = data;
|
||||
|
||||
dispatch_semaphore_signal(sem);
|
||||
}] resume];
|
||||
|
||||
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (result)
|
||||
{
|
||||
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
|
||||
[result writeToFile:filePath atomically:YES];
|
||||
|
||||
nResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nResult = 1;
|
||||
}
|
||||
|
||||
return nResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSURL* url = [NSURL URLWithString:escapedURL];
|
||||
NSData* urlData = [NSData dataWithContentsOfURL:url];
|
||||
if ( urlData )
|
||||
{
|
||||
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
|
||||
[urlData writeToFile:filePath atomically:YES];
|
||||
|
||||
#if defined(_IOS)
|
||||
return 0;
|
||||
#else
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
{
|
||||
[stringURL release];
|
||||
//[url release];
|
||||
[urlData release];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_IOS)
|
||||
NSLog(@"[DownloadFile] Invalid URL: %@", stringURL);
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
[stringURL release];
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
#else
|
||||
#ifndef _ASC_USE_ARC_
|
||||
}
|
||||
|
||||
// Select session. If the caller provided one, prefer it; fall back to the shared
|
||||
// singleton. [NSURLSession sharedSession] is a singleton -- never retain/release it.
|
||||
NSURLSession* session = nil;
|
||||
if (m_pSession && m_pSession->m_pInternal)
|
||||
{
|
||||
CSessionMAC* sessionInternal = (CSessionMAC*)m_pSession->m_pInternal;
|
||||
session = sessionInternal->m_session;
|
||||
}
|
||||
if (!session)
|
||||
session = [NSURLSession sharedSession];
|
||||
|
||||
// NSData initWithContentsOfURL / dataWithContentsOfURL must NOT be used for HTTP:
|
||||
// - Fails silently on CDN responses with Transfer-Encoding: chunked
|
||||
// (returns NSCocoaErrorDomain Code=256 on some iOS versions)
|
||||
// - Does not follow HTTP redirects reliably
|
||||
// - Ignores Content-Encoding (gzip, br)
|
||||
// - Has no timeout, can block indefinitely
|
||||
// NSURLSession handles all of the above correctly on all supported iOS/macOS versions.
|
||||
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
|
||||
|
||||
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
||||
|
||||
// In non-ARC, __block variables are NOT automatically retained by the block.
|
||||
// |data| passed to the completion handler is autoreleased; without an explicit
|
||||
// retain it may be deallocated before semaphore_wait returns on the calling thread.
|
||||
// We therefore retain inside the block and release after use below.
|
||||
__block NSData* resultData = nil;
|
||||
|
||||
NSURLSessionDataTask* task =
|
||||
[session dataTaskWithRequest:urlRequest
|
||||
completionHandler:^(NSData* data, NSURLResponse* response, NSError* error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"[DownloadFile] Network error: %@, URL: %@", error, url);
|
||||
}
|
||||
else if ([response isKindOfClass:[NSHTTPURLResponse class]])
|
||||
{
|
||||
NSInteger status = [(NSHTTPURLResponse*)response statusCode];
|
||||
if (status >= 200 && status < 300)
|
||||
{
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
resultData = [data retain];
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
resultData = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[DownloadFile] HTTP %ld, URL: %@", (long)status, url);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-HTTP scheme (e.g. file://) -- accept unconditionally.
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
resultData = [data retain];
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
resultData = data;
|
||||
}
|
||||
|
||||
dispatch_semaphore_signal(sem);
|
||||
}];
|
||||
|
||||
[task resume];
|
||||
|
||||
// 60-second hard timeout. DISPATCH_TIME_FOREVER must not be used: if the network
|
||||
// stack silently drops the connection the completion handler may never fire,
|
||||
// leaving this thread suspended indefinitely (deadlock).
|
||||
const int64_t kTimeoutSeconds = 60;
|
||||
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, kTimeoutSeconds * NSEC_PER_SEC);
|
||||
long waitResult = dispatch_semaphore_wait(sem, timeout);
|
||||
|
||||
// dispatch_semaphore_create returns a +1 object. Release it in non-ARC.
|
||||
// In ARC (including all iOS targets) GCD objects are managed automatically.
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
dispatch_release(sem);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (waitResult != 0)
|
||||
{
|
||||
// Timeout expired. Cancel the in-flight task so that the completion handler
|
||||
// is called with NSURLErrorCancelled (data == nil), preventing it from writing
|
||||
// to resultData after we return and corrupting memory in non-ARC.
|
||||
[task cancel];
|
||||
NSLog(@"[DownloadFile] Timeout after %llds, URL: %@", (long long)kTimeoutSeconds, url);
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
{
|
||||
// resultData could theoretically be non-nil if the completion handler
|
||||
// raced with the timeout check on a multicore device before cancel ran.
|
||||
[resultData release];
|
||||
[stringURL release];
|
||||
//[url release];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!resultData)
|
||||
{
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
[stringURL release];
|
||||
#endif
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
// filePath: +1 retained (alloc/init). Must be released in non-ARC.
|
||||
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
|
||||
BOOL written = [resultData writeToFile:filePath atomically:YES];
|
||||
|
||||
if (!written)
|
||||
NSLog(@"[DownloadFile] Failed to write file: %@", filePath);
|
||||
|
||||
#if !defined(_IOS)
|
||||
#ifndef _ASC_USE_ARC_
|
||||
if (!GetARCEnabled())
|
||||
{
|
||||
[resultData release];
|
||||
[filePath release];
|
||||
[stringURL release];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return written ? 0 : 1;
|
||||
}
|
||||
|
||||
virtual int UploadData() override
|
||||
|
||||
@ -478,6 +478,15 @@ core_android {
|
||||
!core_android_no_unistd {
|
||||
DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H
|
||||
}
|
||||
|
||||
core_release {
|
||||
QMAKE_CFLAGS += -g0
|
||||
QMAKE_CXXFLAGS += -g0
|
||||
QMAKE_LFLAGS += -Wl,-s
|
||||
|
||||
QMAKE_CFLAGS -= -fno-limit-debug-info
|
||||
QMAKE_CXXFLAGS -= -fno-limit-debug-info
|
||||
}
|
||||
}
|
||||
|
||||
core_debug {
|
||||
|
||||
@ -140,8 +140,14 @@ namespace NSStringUtils
|
||||
AddSize(1);
|
||||
*m_pDataCur++ = _c;
|
||||
++m_lSizeCur;
|
||||
}
|
||||
|
||||
}
|
||||
void CStringBuilderA::AddChar2Safe(const char& _c1, const char& _c2)
|
||||
{
|
||||
AddSize(2);
|
||||
*m_pDataCur++ = _c1;
|
||||
*m_pDataCur++ = _c2;
|
||||
m_lSizeCur += 2;
|
||||
}
|
||||
size_t CStringBuilderA::GetCurSize()
|
||||
{
|
||||
return m_lSizeCur;
|
||||
@ -195,6 +201,16 @@ namespace NSStringUtils
|
||||
m_pDataCur = m_pData;
|
||||
m_lSizeCur = m_lSize;
|
||||
}
|
||||
|
||||
CStringBuilder::CStringBuilder(size_t nSize)
|
||||
{
|
||||
m_lSize = nSize;
|
||||
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
|
||||
|
||||
m_lSizeCur = 0;
|
||||
m_pDataCur = m_pData;
|
||||
return;
|
||||
}
|
||||
CStringBuilder::~CStringBuilder()
|
||||
{
|
||||
if (NULL != m_pData)
|
||||
|
||||
@ -63,6 +63,7 @@ namespace NSStringUtils
|
||||
|
||||
void AddCharNoSafe(const char& _c);
|
||||
void AddCharSafe(const char& _c);
|
||||
void AddChar2Safe(const char& _c1, const char& _c2);
|
||||
|
||||
size_t GetCurSize();
|
||||
void SetCurSize(size_t lCurSize);
|
||||
@ -86,6 +87,7 @@ namespace NSStringUtils
|
||||
|
||||
public:
|
||||
CStringBuilder();
|
||||
CStringBuilder(size_t nSize);
|
||||
virtual ~CStringBuilder();
|
||||
|
||||
virtual void AddSize(size_t nSize);
|
||||
|
||||
@ -415,6 +415,34 @@ bool CxImageBMP::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
|
||||
|
||||
bihtoh(pdib);
|
||||
|
||||
if (pdib->biSize < sizeof(BITMAPCOREHEADER))
|
||||
return false;
|
||||
|
||||
if (pdib->biBitCount != 0 && pdib->biBitCount != 1 &&
|
||||
pdib->biBitCount != 4 && pdib->biBitCount != 8 &&
|
||||
pdib->biBitCount != 16 && pdib->biBitCount != 24 &&
|
||||
pdib->biBitCount != 32)
|
||||
return false;
|
||||
|
||||
unsigned long long stride = ((unsigned long long)pdib->biWidth * pdib->biBitCount + 31) / 32 * 4;
|
||||
unsigned long long height = std::llabs((long long)pdib->biHeight);
|
||||
unsigned long long expected = stride * height;
|
||||
|
||||
unsigned long long num_colors = 0;
|
||||
if (pdib->biBitCount > 0 && pdib->biBitCount <= 8) {
|
||||
num_colors = (pdib->biClrUsed != 0)
|
||||
? pdib->biClrUsed
|
||||
: (1ULL << pdib->biBitCount);
|
||||
} else if (pdib->biClrUsed > 0) {
|
||||
num_colors = pdib->biClrUsed;
|
||||
}
|
||||
unsigned long long palette_size = num_colors * 4;
|
||||
|
||||
unsigned long long masks_size = (pdib->biCompression == BI_BITFIELDS) ? 12ULL : 0ULL;
|
||||
unsigned long long fileSize = fh->Size();
|
||||
if ((unsigned long long)pdib->biSize + palette_size + masks_size + expected > fileSize)
|
||||
return false;
|
||||
|
||||
switch (pdib->biSize) // what type of bitmap info is this?
|
||||
{
|
||||
case sizeof(BITMAPINFOHEADER):
|
||||
|
||||
@ -347,11 +347,11 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
|
||||
}
|
||||
|
||||
if (!bIsBreak)
|
||||
bIsBreak = !this->ExecuteCommand(L"Api.asc_nativeInitBuilder();");
|
||||
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_nativeInitBuilder();");
|
||||
if (!bIsBreak)
|
||||
bIsBreak = !this->ExecuteCommand(L"Api.asc_SetSilentMode(true);");
|
||||
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(true);");
|
||||
if (!bIsBreak)
|
||||
bIsBreak = !this->ExecuteCommand(L"Api.asc_showComments();");
|
||||
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_showComments();");
|
||||
|
||||
LOGGER_SPEED_LAP("open");
|
||||
|
||||
@ -425,7 +425,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
|
||||
bIsSilentMode = true;
|
||||
|
||||
if (bIsSilentMode)
|
||||
this->ExecuteCommand(L"Api.asc_SetSilentMode(false);", NULL, isEnterContext);
|
||||
this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(false);", NULL, isEnterContext);
|
||||
|
||||
std::wstring strError;
|
||||
bool bIsError = Doct_renderer_SaveFile_ForBuilder(_formatDst,
|
||||
@ -437,7 +437,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
|
||||
sJsonParams);
|
||||
|
||||
if (bIsSilentMode)
|
||||
this->ExecuteCommand(L"Api.asc_SetSilentMode(true);", NULL, isEnterContext);
|
||||
this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(true);", NULL, isEnterContext);
|
||||
|
||||
if (isEnterContext)
|
||||
m_context->Exit();
|
||||
@ -1507,7 +1507,7 @@ namespace NSDoctRenderer
|
||||
if (m_pInternal->m_oParams.m_bSaveWithDoctrendererMode)
|
||||
{
|
||||
// перед сохранением в такой схеме нужно скинуть изменения
|
||||
this->ExecuteCommand(L"Api.asc_Save();");
|
||||
this->ExecuteCommand(L"Asc.editor.asc_Save();");
|
||||
}
|
||||
|
||||
const wchar_t* sParams = NULL;
|
||||
|
||||
@ -287,7 +287,10 @@ namespace NSDoctRenderer
|
||||
|
||||
JSSmart<CJSObject> js_objectApi = api_js_maybe_null;
|
||||
if (!js_objectApi.IsInit() || js_objectApi->isUndefined())
|
||||
js_objectApi = global_js->get("Api")->toObject();
|
||||
{
|
||||
JSSmart<CJSObject> js_objectAsc = global_js->get("Asc")->toObject();
|
||||
js_objectApi = js_objectAsc->get("editor")->toObject();
|
||||
}
|
||||
|
||||
bool bIsBreak = false;
|
||||
if (js_objectApi->isUndefined() || !js_objectApi->isObject())
|
||||
@ -687,7 +690,8 @@ namespace NSDoctRenderer
|
||||
bIsBreak = true;
|
||||
}
|
||||
|
||||
js_objectApi = global_js->get("Api")->toObject();
|
||||
JSSmart<CJSObject> js_objectAsc = global_js->get("Asc")->toObject();
|
||||
js_objectApi = js_objectAsc->get("editor")->toObject();
|
||||
if (try_catch->Check())
|
||||
{
|
||||
strError = L"code=\"open\"";
|
||||
|
||||
@ -1374,6 +1374,25 @@ namespace Aggplus
|
||||
}
|
||||
}
|
||||
|
||||
template<class span_gen_type>
|
||||
void CGraphics::render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha)
|
||||
{
|
||||
if (m_nBlendMode != agg::comp_op_src_over)
|
||||
{
|
||||
typedef agg::renderer_scanline_aa<comp_renderer_type, span_alloc_type, span_gen_type> aa_renderer_type;
|
||||
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
|
||||
comp_renderer_type ren_base(pixfmt);
|
||||
aa_renderer_type ri(ren_base, span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Renderer>
|
||||
void CGraphics::render_scanlines(Renderer& ren)
|
||||
{
|
||||
@ -1417,12 +1436,9 @@ namespace Aggplus
|
||||
if (m_nBlendMode != agg::comp_op_src_over)
|
||||
{
|
||||
typedef agg::renderer_scanline_aa_solid<comp_renderer_type> solid_comp_renderer_type;
|
||||
solid_comp_renderer_type ren_solid;
|
||||
comp_renderer_type ren_base;
|
||||
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
|
||||
|
||||
ren_base.attach(pixfmt);
|
||||
ren_solid.attach(ren_base);
|
||||
comp_renderer_type ren_base(pixfmt);
|
||||
solid_comp_renderer_type ren_solid(ren_base);
|
||||
|
||||
ren_solid.color(dwColor.GetAggColor());
|
||||
render_scanlines(ren_solid);
|
||||
@ -1727,6 +1743,70 @@ namespace Aggplus
|
||||
}
|
||||
}
|
||||
|
||||
template<typename pixfmt>
|
||||
void CGraphics::DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha)
|
||||
{
|
||||
typedef agg::image_accessor_clone<pixfmt> img_source_type;
|
||||
pixfmt img_pixf(PatRendBuff);
|
||||
img_source_type img_src(img_pixf);
|
||||
|
||||
switch (nCurrentMode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bicubic(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_spline16(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_blackman256(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bilinear(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
render_blendmode(sg, span_allocator, Alpha);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphics::DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha)
|
||||
{
|
||||
span_alloc_type span_allocator;
|
||||
@ -1738,158 +1818,11 @@ namespace Aggplus
|
||||
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
|
||||
|
||||
int nCurrentMode = 255;
|
||||
|
||||
if (!m_bSwapRGB)
|
||||
{
|
||||
typedef agg::pixfmt_bgra32 pixfmt;
|
||||
typedef agg::image_accessor_clone<pixfmt> img_source_type;
|
||||
|
||||
pixfmt img_pixf(PatRendBuff);
|
||||
img_source_type img_src(img_pixf);
|
||||
|
||||
switch (nCurrentMode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bicubic(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_spline16(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_blackman256(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bilinear(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoFillPathTextureClampSz2_Impl<agg::pixfmt_bgra32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
|
||||
else
|
||||
{
|
||||
typedef agg::pixfmt_rgba32 pixfmt;
|
||||
typedef agg::image_accessor_clone<pixfmt> img_source_type;
|
||||
|
||||
pixfmt img_pixf(PatRendBuff);
|
||||
img_source_type img_src(img_pixf);
|
||||
|
||||
switch (nCurrentMode)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
span_gen_type sg(img_src, interpolator);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bicubic(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_spline16(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_blackman256(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
case 255:
|
||||
{
|
||||
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
|
||||
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
|
||||
agg::image_filter_lut filter;
|
||||
filter.calculate(agg::image_filter_bilinear(), false);
|
||||
span_gen_type sg(img_src, interpolator, filter);
|
||||
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
|
||||
render_scanlines_alpha(ri, Alpha);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoFillPathTextureClampSz2_Impl<agg::pixfmt_rgba32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
|
||||
}
|
||||
|
||||
template<class ColorSpacePix>
|
||||
|
||||
@ -430,6 +430,9 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
template<class span_gen_type>
|
||||
void render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha);
|
||||
|
||||
template<class Renderer>
|
||||
void render_scanlines(Renderer& ren);
|
||||
template<class Rasterizer, class Renderer>
|
||||
@ -447,6 +450,9 @@ protected:
|
||||
//--test
|
||||
void DoFillPathHatch(CBrushHatch *pBrush);
|
||||
void DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride);
|
||||
|
||||
template<typename pixfmt>
|
||||
void DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha);
|
||||
void DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha = 255);
|
||||
|
||||
template<class ColorSpacePix>
|
||||
|
||||
@ -481,6 +481,8 @@ namespace NSOnlineOfficeBinToPdf
|
||||
double m3 = oReader.ReadDouble();
|
||||
double m4 = oReader.ReadDouble();
|
||||
|
||||
clipRect = Aggplus::RectF_T<double>(m1, m2, m3, m4);
|
||||
|
||||
long type;
|
||||
pRenderer->get_BrushTextureMode(&type);
|
||||
if (type != c_BrushTextureModeStretch)
|
||||
@ -489,7 +491,6 @@ namespace NSOnlineOfficeBinToPdf
|
||||
m2 = 0.0;
|
||||
}
|
||||
|
||||
clipRect = Aggplus::RectF_T<double>(m1, m2, m3, m4);
|
||||
pRenderer->BrushRect(bIsEnableBrushRect ? 1 : 0, m1, m2, m3, m4);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -151,20 +151,22 @@ CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annot
|
||||
m_oBorder.nType = 0;
|
||||
m_oBorder.dWidth = 0.0;
|
||||
|
||||
m_pMarkupPr = NULL;
|
||||
m_pTextPr = NULL;
|
||||
m_pInkPr = NULL;
|
||||
m_pLinePr = NULL;
|
||||
m_pTextMarkupPr = NULL;
|
||||
m_pSquareCirclePr = NULL;
|
||||
m_pPolygonLinePr = NULL;
|
||||
m_pPopupPr = NULL;
|
||||
m_pFreeTextPr = NULL;
|
||||
m_pCaretPr = NULL;
|
||||
m_pStampPr = NULL;
|
||||
m_pRedactPr = NULL;
|
||||
m_pLinkPr = NULL;
|
||||
m_pWidgetPr = NULL;
|
||||
m_pMarkupPr = NULL;
|
||||
m_pTextPr = NULL;
|
||||
m_pInkPr = NULL;
|
||||
m_pLinePr = NULL;
|
||||
m_pTextMarkupPr = NULL;
|
||||
m_pSquareCirclePr = NULL;
|
||||
m_pPolygonLinePr = NULL;
|
||||
m_pPopupPr = NULL;
|
||||
m_pFreeTextPr = NULL;
|
||||
m_pCaretPr = NULL;
|
||||
m_pStampPr = NULL;
|
||||
m_pRedactPr = NULL;
|
||||
m_pLinkPr = NULL;
|
||||
m_pFileAttachmentPr = NULL;
|
||||
m_pScreenPr = NULL;
|
||||
m_pWidgetPr = NULL;
|
||||
}
|
||||
CAnnotFieldInfo::~CAnnotFieldInfo()
|
||||
{
|
||||
@ -181,6 +183,8 @@ CAnnotFieldInfo::~CAnnotFieldInfo()
|
||||
RELEASEOBJECT(m_pStampPr);
|
||||
RELEASEOBJECT(m_pRedactPr);
|
||||
RELEASEOBJECT(m_pLinkPr);
|
||||
RELEASEOBJECT(m_pFileAttachmentPr);
|
||||
RELEASEOBJECT(m_pScreenPr);
|
||||
RELEASEOBJECT(m_pWidgetPr);
|
||||
}
|
||||
|
||||
@ -274,6 +278,18 @@ void CAnnotFieldInfo::SetType(int nType)
|
||||
m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr();
|
||||
break;
|
||||
}
|
||||
case EAnnotType::FileAttachment:
|
||||
{
|
||||
RELEASEOBJECT(m_pFileAttachmentPr);
|
||||
m_pFileAttachmentPr = new CAnnotFieldInfo::CFileAttachmentAnnotPr();
|
||||
break;
|
||||
}
|
||||
case EAnnotType::Screen:
|
||||
{
|
||||
RELEASEOBJECT(m_pScreenPr);
|
||||
m_pScreenPr = new CAnnotFieldInfo::CScreenAnnotPr();
|
||||
break;
|
||||
}
|
||||
case EAnnotType::Redact:
|
||||
{
|
||||
CreateMarkup();
|
||||
@ -403,21 +419,31 @@ bool CAnnotFieldInfo::IsLink() const
|
||||
{
|
||||
return (m_nType == 1);
|
||||
}
|
||||
bool CAnnotFieldInfo::IsFileAttachment() const
|
||||
{
|
||||
return (m_nType == 16);
|
||||
}
|
||||
bool CAnnotFieldInfo::IsScreen() const
|
||||
{
|
||||
return (m_nType == 20);
|
||||
}
|
||||
|
||||
CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; }
|
||||
CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; }
|
||||
CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; }
|
||||
CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; }
|
||||
CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; }
|
||||
CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; }
|
||||
CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; }
|
||||
CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; }
|
||||
CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; }
|
||||
CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; }
|
||||
CAnnotFieldInfo::CStampAnnotPr* CAnnotFieldInfo::GetStampAnnotPr() { return m_pStampPr; }
|
||||
CAnnotFieldInfo::CRedactAnnotPr* CAnnotFieldInfo::GetRedactAnnotPr() { return m_pRedactPr; }
|
||||
CAnnotFieldInfo::CLinkAnnotPr* CAnnotFieldInfo::GetLinkAnnotPr() { return m_pLinkPr; }
|
||||
CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; }
|
||||
CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; }
|
||||
CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; }
|
||||
CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; }
|
||||
CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; }
|
||||
CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; }
|
||||
CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; }
|
||||
CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; }
|
||||
CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; }
|
||||
CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; }
|
||||
CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; }
|
||||
CAnnotFieldInfo::CStampAnnotPr* CAnnotFieldInfo::GetStampAnnotPr() { return m_pStampPr; }
|
||||
CAnnotFieldInfo::CRedactAnnotPr* CAnnotFieldInfo::GetRedactAnnotPr() { return m_pRedactPr; }
|
||||
CAnnotFieldInfo::CLinkAnnotPr* CAnnotFieldInfo::GetLinkAnnotPr() { return m_pLinkPr; }
|
||||
CAnnotFieldInfo::CFileAttachmentAnnotPr* CAnnotFieldInfo::GetFileAttachmentAnnotPr() { return m_pFileAttachmentPr; }
|
||||
CAnnotFieldInfo::CScreenAnnotPr* CAnnotFieldInfo::GetScreenAnnotPr() { return m_pScreenPr; }
|
||||
CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; }
|
||||
|
||||
bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
|
||||
{
|
||||
@ -506,6 +532,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
|
||||
m_pStampPr->Read(pReader, nFlags);
|
||||
else if (IsRedact())
|
||||
m_pRedactPr->Read(pReader, nFlags);
|
||||
else if (IsFileAttachment())
|
||||
m_pFileAttachmentPr->Read(pReader, nFlags);
|
||||
}
|
||||
else if (IsPopup())
|
||||
m_pPopupPr->Read(pReader);
|
||||
@ -513,6 +541,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
|
||||
m_pWidgetPr->Read(pReader, nType);
|
||||
else if (IsLink())
|
||||
m_pLinkPr->Read(pReader);
|
||||
else if (IsScreen())
|
||||
m_pScreenPr->Read(pReader);
|
||||
|
||||
return m_nType != -1;
|
||||
}
|
||||
@ -834,6 +864,7 @@ CAnnotFieldInfo::CLinkAnnotPr::~CLinkAnnotPr()
|
||||
}
|
||||
BYTE CAnnotFieldInfo::CLinkAnnotPr::GetH() const { return m_nH; }
|
||||
int CAnnotFieldInfo::CLinkAnnotPr::GetFlags() const { return m_nFlags; }
|
||||
void CAnnotFieldInfo::CLinkAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; }
|
||||
const std::vector<double>& CAnnotFieldInfo::CLinkAnnotPr::GetQuadPoints() { return m_arrQuadPoints; }
|
||||
CAnnotFieldInfo::CActionFieldPr* CAnnotFieldInfo::CLinkAnnotPr::GetA() { return m_pAction; }
|
||||
CAnnotFieldInfo::CActionFieldPr* CAnnotFieldInfo::CLinkAnnotPr::GetPA() { return m_pPA; }
|
||||
@ -859,6 +890,126 @@ void CAnnotFieldInfo::CLinkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
|
||||
for (int i = 0; i < n; ++i)
|
||||
m_arrQuadPoints.push_back(pReader->ReadDouble());
|
||||
}
|
||||
if (m_nFlags & (1 << 4))
|
||||
{
|
||||
m_dRD[0] = pReader->ReadDouble();
|
||||
m_dRD[1] = pReader->ReadDouble();
|
||||
m_dRD[2] = pReader->ReadDouble();
|
||||
m_dRD[3] = pReader->ReadDouble();
|
||||
}
|
||||
}
|
||||
|
||||
CAnnotFieldInfo::CFileAttachmentAnnotPr::CFileAttachmentAnnotPr()
|
||||
{
|
||||
|
||||
}
|
||||
CAnnotFieldInfo::CFileAttachmentAnnotPr::~CFileAttachmentAnnotPr()
|
||||
{
|
||||
|
||||
}
|
||||
int CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileFlag() const { return m_nFileFlag; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetName() { return m_wsName; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFS() { return m_wsFS; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetF() { return m_wsF; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetUF() { return m_wsUF; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetDOS() { return m_wsDOS; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetMac() { return m_wsMac; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetUnix() { return m_wsUnix; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetDesc() { return m_wsDesc; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileF() { return m_wsFileF; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileUF() { return m_wsFileUF; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileDOS() { return m_wsFileDOS; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileMac() { return m_wsFileMac; }
|
||||
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileUnix() { return m_wsFileUnix; }
|
||||
const std::pair<std::wstring, std::wstring>& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetID() { return m_wsID; }
|
||||
void CAnnotFieldInfo::CFileAttachmentAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
|
||||
{
|
||||
if (nFlags & (1 << 15))
|
||||
m_wsName = pReader->ReadString();
|
||||
if (nFlags & (1 << 16))
|
||||
m_wsFS = pReader->ReadString();
|
||||
if (nFlags & (1 << 17))
|
||||
m_wsF = pReader->ReadString();
|
||||
if (nFlags & (1 << 18))
|
||||
m_wsUF = pReader->ReadString();
|
||||
if (nFlags & (1 << 19))
|
||||
m_wsDOS = pReader->ReadString();
|
||||
if (nFlags & (1 << 20))
|
||||
m_wsMac = pReader->ReadString();
|
||||
if (nFlags & (1 << 21))
|
||||
m_wsUnix = pReader->ReadString();
|
||||
if (nFlags & (1 << 22))
|
||||
{
|
||||
m_wsID.first = pReader->ReadString();
|
||||
m_wsID.second = pReader->ReadString();
|
||||
}
|
||||
if (nFlags & (1 << 24))
|
||||
{
|
||||
m_nFileFlag = pReader->ReadInt();
|
||||
if (m_nFileFlag & (1 << 0))
|
||||
m_wsFileF = pReader->ReadString();
|
||||
if (m_nFileFlag & (1 << 1))
|
||||
m_wsFileUF = pReader->ReadString();
|
||||
if (m_nFileFlag & (1 << 2))
|
||||
m_wsFileDOS = pReader->ReadString();
|
||||
if (m_nFileFlag & (1 << 3))
|
||||
m_wsFileMac = pReader->ReadString();
|
||||
if (m_nFileFlag & (1 << 4))
|
||||
m_wsFileUnix = pReader->ReadString();
|
||||
}
|
||||
if (nFlags & (1 << 26))
|
||||
m_wsDesc = pReader->ReadString();
|
||||
}
|
||||
|
||||
CAnnotFieldInfo::CScreenAnnotPr::CScreenAnnotPr()
|
||||
{
|
||||
|
||||
}
|
||||
CAnnotFieldInfo::CScreenAnnotPr::~CScreenAnnotPr()
|
||||
{
|
||||
|
||||
}
|
||||
int CAnnotFieldInfo::CScreenAnnotPr::GetR() const { return m_nR; }
|
||||
int CAnnotFieldInfo::CScreenAnnotPr::GetFlags() const { return m_nFlags; }
|
||||
const std::wstring& CAnnotFieldInfo::CScreenAnnotPr::GetT() { return m_wsT; }
|
||||
const std::vector<double>& CAnnotFieldInfo::CScreenAnnotPr::GetBC() { return m_arrBC; }
|
||||
const std::vector<double>& CAnnotFieldInfo::CScreenAnnotPr::GetBG() { return m_arrBG; }
|
||||
const std::vector<CAnnotFieldInfo::CActionFieldPr*>& CAnnotFieldInfo::CScreenAnnotPr::GetActions() { return m_arrAction; }
|
||||
void CAnnotFieldInfo::CScreenAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader)
|
||||
{
|
||||
m_nFlags = pReader->ReadInt();
|
||||
if (m_nFlags & (1 << 0))
|
||||
m_wsT = pReader->ReadString();
|
||||
if (m_nFlags & (1 << 1))
|
||||
{
|
||||
int n = pReader->ReadInt();
|
||||
m_arrBC.reserve(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
m_arrBC.push_back(pReader->ReadDouble());
|
||||
}
|
||||
if (m_nFlags & (1 << 2))
|
||||
m_nR = pReader->ReadInt();
|
||||
if (m_nFlags & (1 << 3))
|
||||
{
|
||||
int n = pReader->ReadInt();
|
||||
m_arrBG.reserve(n);
|
||||
for (int i = 0; i < n; ++i)
|
||||
m_arrBG.push_back(pReader->ReadDouble());
|
||||
}
|
||||
if (m_nFlags & (1 << 4))
|
||||
{
|
||||
int nAction = pReader->ReadInt();
|
||||
for (int i = 0; i < nAction; ++i)
|
||||
{
|
||||
std::wstring wsType = pReader->ReadString();
|
||||
CAnnotFieldInfo::CActionFieldPr* pA = ReadAction(pReader);
|
||||
if (pA)
|
||||
{
|
||||
pA->wsType = wsType;
|
||||
m_arrAction.push_back(pA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; }
|
||||
|
||||
@ -59,6 +59,7 @@ public:
|
||||
Ink = 14,
|
||||
Popup = 15,
|
||||
FileAttachment = 16,
|
||||
Screen = 20,
|
||||
Redact = 25,
|
||||
Widget = 26,
|
||||
WidgetPushButton = 27,
|
||||
@ -488,6 +489,7 @@ public:
|
||||
|
||||
BYTE GetH() const;
|
||||
int GetFlags() const;
|
||||
void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4);
|
||||
const std::vector<double>& GetQuadPoints();
|
||||
CActionFieldPr* GetA();
|
||||
CActionFieldPr* GetPA();
|
||||
@ -497,11 +499,78 @@ public:
|
||||
private:
|
||||
BYTE m_nH;
|
||||
int m_nFlags;
|
||||
double m_dRD[4]{};
|
||||
std::vector<double> m_arrQuadPoints;
|
||||
CActionFieldPr* m_pAction;
|
||||
CActionFieldPr* m_pPA;
|
||||
};
|
||||
|
||||
class GRAPHICS_DECL CFileAttachmentAnnotPr
|
||||
{
|
||||
public:
|
||||
CFileAttachmentAnnotPr();
|
||||
~CFileAttachmentAnnotPr();
|
||||
|
||||
int GetFileFlag() const;
|
||||
const std::wstring& GetName();
|
||||
const std::wstring& GetFS();
|
||||
const std::wstring& GetF();
|
||||
const std::wstring& GetUF();
|
||||
const std::wstring& GetDOS();
|
||||
const std::wstring& GetMac();
|
||||
const std::wstring& GetUnix();
|
||||
const std::wstring& GetDesc();
|
||||
const std::wstring& GetFileF();
|
||||
const std::wstring& GetFileUF();
|
||||
const std::wstring& GetFileDOS();
|
||||
const std::wstring& GetFileMac();
|
||||
const std::wstring& GetFileUnix();
|
||||
const std::pair<std::wstring, std::wstring>& GetID();
|
||||
|
||||
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
|
||||
|
||||
private:
|
||||
int m_nFileFlag;
|
||||
std::wstring m_wsName;
|
||||
std::wstring m_wsFS;
|
||||
std::wstring m_wsF;
|
||||
std::wstring m_wsUF;
|
||||
std::wstring m_wsDOS;
|
||||
std::wstring m_wsMac;
|
||||
std::wstring m_wsUnix;
|
||||
std::wstring m_wsDesc;
|
||||
std::wstring m_wsFileF;
|
||||
std::wstring m_wsFileUF;
|
||||
std::wstring m_wsFileDOS;
|
||||
std::wstring m_wsFileMac;
|
||||
std::wstring m_wsFileUnix;
|
||||
std::pair<std::wstring, std::wstring> m_wsID;
|
||||
};
|
||||
|
||||
class GRAPHICS_DECL CScreenAnnotPr
|
||||
{
|
||||
public:
|
||||
CScreenAnnotPr();
|
||||
~CScreenAnnotPr();
|
||||
|
||||
int GetR() const;
|
||||
int GetFlags() const;
|
||||
const std::wstring& GetT();
|
||||
const std::vector<double>& GetBC();
|
||||
const std::vector<double>& GetBG();
|
||||
const std::vector<CActionFieldPr*>& GetActions();
|
||||
|
||||
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader);
|
||||
|
||||
private:
|
||||
int m_nR;
|
||||
int m_nFlags;
|
||||
std::wstring m_wsT;
|
||||
std::vector<double> m_arrBC;
|
||||
std::vector<double> m_arrBG;
|
||||
std::vector<CActionFieldPr*> m_arrAction;
|
||||
};
|
||||
|
||||
CAnnotFieldInfo();
|
||||
virtual ~CAnnotFieldInfo();
|
||||
|
||||
@ -543,21 +612,25 @@ public:
|
||||
bool IsStamp() const;
|
||||
bool IsRedact() const;
|
||||
bool IsLink() const;
|
||||
bool IsFileAttachment() const;
|
||||
bool IsScreen() const;
|
||||
|
||||
CMarkupAnnotPr* GetMarkupAnnotPr();
|
||||
CTextAnnotPr* GetTextAnnotPr();
|
||||
CInkAnnotPr* GetInkAnnotPr();
|
||||
CLineAnnotPr* GetLineAnnotPr();
|
||||
CTextMarkupAnnotPr* GetTextMarkupAnnotPr();
|
||||
CSquareCircleAnnotPr* GetSquareCircleAnnotPr();
|
||||
CPolygonLineAnnotPr* GetPolygonLineAnnotPr();
|
||||
CPopupAnnotPr* GetPopupAnnotPr();
|
||||
CFreeTextAnnotPr* GetFreeTextAnnotPr();
|
||||
CCaretAnnotPr* GetCaretAnnotPr();
|
||||
CStampAnnotPr* GetStampAnnotPr();
|
||||
CRedactAnnotPr* GetRedactAnnotPr();
|
||||
CLinkAnnotPr* GetLinkAnnotPr();
|
||||
CWidgetAnnotPr* GetWidgetAnnotPr();
|
||||
CMarkupAnnotPr* GetMarkupAnnotPr();
|
||||
CTextAnnotPr* GetTextAnnotPr();
|
||||
CInkAnnotPr* GetInkAnnotPr();
|
||||
CLineAnnotPr* GetLineAnnotPr();
|
||||
CTextMarkupAnnotPr* GetTextMarkupAnnotPr();
|
||||
CSquareCircleAnnotPr* GetSquareCircleAnnotPr();
|
||||
CPolygonLineAnnotPr* GetPolygonLineAnnotPr();
|
||||
CPopupAnnotPr* GetPopupAnnotPr();
|
||||
CFreeTextAnnotPr* GetFreeTextAnnotPr();
|
||||
CCaretAnnotPr* GetCaretAnnotPr();
|
||||
CStampAnnotPr* GetStampAnnotPr();
|
||||
CRedactAnnotPr* GetRedactAnnotPr();
|
||||
CLinkAnnotPr* GetLinkAnnotPr();
|
||||
CFileAttachmentAnnotPr* GetFileAttachmentAnnotPr();
|
||||
CScreenAnnotPr* GetScreenAnnotPr();
|
||||
CWidgetAnnotPr* GetWidgetAnnotPr();
|
||||
|
||||
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector);
|
||||
|
||||
@ -590,20 +663,22 @@ private:
|
||||
LONG m_nRenderLen;
|
||||
BYTE* m_pRender;
|
||||
|
||||
CMarkupAnnotPr* m_pMarkupPr;
|
||||
CTextAnnotPr* m_pTextPr;
|
||||
CInkAnnotPr* m_pInkPr;
|
||||
CLineAnnotPr* m_pLinePr;
|
||||
CTextMarkupAnnotPr* m_pTextMarkupPr;
|
||||
CSquareCircleAnnotPr* m_pSquareCirclePr;
|
||||
CPolygonLineAnnotPr* m_pPolygonLinePr;
|
||||
CPopupAnnotPr* m_pPopupPr;
|
||||
CFreeTextAnnotPr* m_pFreeTextPr;
|
||||
CCaretAnnotPr* m_pCaretPr;
|
||||
CStampAnnotPr* m_pStampPr;
|
||||
CRedactAnnotPr* m_pRedactPr;
|
||||
CLinkAnnotPr* m_pLinkPr;
|
||||
CWidgetAnnotPr* m_pWidgetPr;
|
||||
CMarkupAnnotPr* m_pMarkupPr;
|
||||
CTextAnnotPr* m_pTextPr;
|
||||
CInkAnnotPr* m_pInkPr;
|
||||
CLineAnnotPr* m_pLinePr;
|
||||
CTextMarkupAnnotPr* m_pTextMarkupPr;
|
||||
CSquareCircleAnnotPr* m_pSquareCirclePr;
|
||||
CPolygonLineAnnotPr* m_pPolygonLinePr;
|
||||
CPopupAnnotPr* m_pPopupPr;
|
||||
CFreeTextAnnotPr* m_pFreeTextPr;
|
||||
CCaretAnnotPr* m_pCaretPr;
|
||||
CStampAnnotPr* m_pStampPr;
|
||||
CRedactAnnotPr* m_pRedactPr;
|
||||
CLinkAnnotPr* m_pLinkPr;
|
||||
CFileAttachmentAnnotPr* m_pFileAttachmentPr;
|
||||
CScreenAnnotPr* m_pScreenPr;
|
||||
CWidgetAnnotPr* m_pWidgetPr;
|
||||
};
|
||||
|
||||
class GRAPHICS_DECL CAnnotFieldDelete : public IAdvancedCommand
|
||||
|
||||
@ -936,7 +936,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF
|
||||
rec["ID"].push(readStringFunc.call(reader));
|
||||
rec["ID"].push(readStringFunc.call(reader));
|
||||
}
|
||||
rec["V"] = flags & (1 << 23);
|
||||
rec["V"] = flags & (1 << 23) ? true : false;
|
||||
if (flags & (1 << 24))
|
||||
{
|
||||
if (isRead)
|
||||
@ -1085,6 +1085,48 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF
|
||||
for (let i = 0; i < n; ++i)
|
||||
rec["QuadPoints"].push(readDoubleFunc.call(reader));
|
||||
}
|
||||
// Rect and RD differenses
|
||||
if (flags & (1 << 4))
|
||||
{
|
||||
rec["RD"] = [];
|
||||
for (let i = 0; i < 4; ++i)
|
||||
rec["RD"].push(readDoubleFunc.call(reader));
|
||||
}
|
||||
}
|
||||
// Screen
|
||||
else if (rec["type"] == 20)
|
||||
{
|
||||
flags = reader.readInt();
|
||||
if (flags & (1 << 0))
|
||||
rec["T"] = readStringFunc.call(reader);
|
||||
if (flags & (1 << 1))
|
||||
{
|
||||
let n = reader.readInt();
|
||||
rec["BC"] = [];
|
||||
for (let i = 0; i < n; ++i)
|
||||
rec["BC"].push(readDouble2Func.call(reader));
|
||||
}
|
||||
if (flags & (1 << 2))
|
||||
rec["rotate"] = reader.readInt();
|
||||
if (flags & (1 << 3))
|
||||
{
|
||||
let n = reader.readInt();
|
||||
rec["BG"] = [];
|
||||
for (let i = 0; i < n; ++i)
|
||||
rec["BG"].push(readDouble2Func.call(reader));
|
||||
}
|
||||
if (flags & (1 << 4))
|
||||
{
|
||||
let nAction = reader.readInt();
|
||||
if (nAction > 0)
|
||||
rec["AA"] = {};
|
||||
for (let i = 0; i < nAction; ++i)
|
||||
{
|
||||
let AAType = readStringFunc.call(reader);
|
||||
rec["AA"][AAType] = {};
|
||||
readAction(reader, rec["AA"][AAType], readDoubleFunc, readStringFunc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "../../../../raster/BgraFrame.h"
|
||||
#include "../../../../raster/ImageFileFormatChecker.h"
|
||||
#include "../../../../../raster/BgraFrame.h"
|
||||
#include "../../../../../raster/ImageFileFormatChecker.h"
|
||||
#include "../../../../../common/File.h"
|
||||
#include "../../../../../common/StringBuilder.h"
|
||||
#include "drawingfile.cpp"
|
||||
@ -958,7 +958,7 @@ void ReadInteractiveFormsFonts(CDrawingFile* pGrFile, int nType)
|
||||
if (pFont)
|
||||
free(pFont);
|
||||
|
||||
if (false)
|
||||
if (true)
|
||||
continue;
|
||||
|
||||
pFont = GetGIDByUnicode(pGrFile, (char*)sFontName.c_str());
|
||||
@ -2228,6 +2228,79 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
std::cout << ", ";
|
||||
}
|
||||
if (nFlags & (1 << 4))
|
||||
{
|
||||
std::cout << "RD";
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << " " << (double)nPathLength / 100.0;
|
||||
}
|
||||
std::cout << ", ";
|
||||
}
|
||||
}
|
||||
else if (sType == "Screen")
|
||||
{
|
||||
nFlags = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
if (nFlags & (1 << 0))
|
||||
{
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << "T " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
|
||||
i += nPathLength;
|
||||
}
|
||||
if (nFlags & (1 << 1))
|
||||
{
|
||||
int nBCLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << "BC ";
|
||||
|
||||
for (int j = 0; j < nBCLength; ++j)
|
||||
{
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << (double)nPathLength / 10000.0 << " ";
|
||||
}
|
||||
std::cout << ", ";
|
||||
}
|
||||
if (nFlags & (1 << 2))
|
||||
{
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << "R " << nPathLength << ", ";
|
||||
}
|
||||
if (nFlags & (1 << 3))
|
||||
{
|
||||
int nBCLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << "BG ";
|
||||
|
||||
for (int j = 0; j < nBCLength; ++j)
|
||||
{
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << (double)nPathLength / 10000.0 << " ";
|
||||
}
|
||||
std::cout << ", ";
|
||||
}
|
||||
if (nFlags & (1 << 4))
|
||||
{
|
||||
int nActLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
for (int j = 0; j < nActLength; ++j)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << std::to_string(j) << " Action " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
|
||||
i += nPathLength;
|
||||
|
||||
ReadAction(pAnnots, i);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl << "]" << std::endl;
|
||||
|
||||
@ -863,17 +863,12 @@ namespace MetaFile
|
||||
void PathClip(const CPath& oPath, int nClipMode, TXForm *pTransform = NULL)
|
||||
{
|
||||
double dM11, dM12, dM21, dM22, dX, dY;
|
||||
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
|
||||
|
||||
if (NULL != pTransform)
|
||||
SetTransform(pTransform->M11, pTransform->M12,
|
||||
pTransform->M21, pTransform->M22,
|
||||
pTransform->Dx - m_pFile->GetDCBounds().Left,
|
||||
pTransform->Dy - m_pFile->GetDCBounds().Top);
|
||||
else
|
||||
SetTransform(dM11, dM12, dM21, dM22,
|
||||
dX - m_pFile->GetDCBounds().Left,
|
||||
dY - m_pFile->GetDCBounds().Top);
|
||||
{
|
||||
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
|
||||
SetTransform(pTransform->M11, pTransform->M12, pTransform->M21, pTransform->M22, pTransform->Dx, pTransform->Dy);
|
||||
}
|
||||
|
||||
oPath.DrawOn(this, false, false, nClipMode);
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ namespace MetaFile
|
||||
|
||||
void CEmfInterpretatorRender::ChangeConditional()
|
||||
{
|
||||
if (NULL != m_pMetaFileRenderer)
|
||||
m_pMetaFileRenderer->ChangeConditional();
|
||||
if (NULL != m_pMetaFileRenderer)
|
||||
m_pMetaFileRenderer->ChangeConditional();
|
||||
}
|
||||
|
||||
void CEmfInterpretatorRender::Begin()
|
||||
|
||||
@ -1264,7 +1264,11 @@ namespace MetaFile
|
||||
|
||||
if (NULL != m_pPath)
|
||||
{
|
||||
m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, m_pDC->GetFinalTransform(GM_ADVANCED));
|
||||
TEmfXForm oTransform{m_pDC->GetFinalTransform(GM_ADVANCED)};
|
||||
oTransform.Dx -= GetDCBounds().Left;
|
||||
oTransform.Dy -= GetDCBounds().Top;
|
||||
|
||||
m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, oTransform);
|
||||
RELEASEOBJECT(m_pPath);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
@ -3284,6 +3284,10 @@ namespace MetaFile
|
||||
void CEmfPlusParser::Read_EMFPLUS_SETCLIPRECT(unsigned short unShFlags)
|
||||
{
|
||||
short shCM = ExpressValue(unShFlags, 8, 11);
|
||||
|
||||
if (0 == shCM)
|
||||
shCM = RGN_COPY;
|
||||
|
||||
TEmfPlusRectF oRect;
|
||||
|
||||
m_oStream >> oRect;
|
||||
|
||||
@ -632,18 +632,8 @@ namespace MetaFile
|
||||
if (wsPath.empty())
|
||||
return;
|
||||
|
||||
const std::wstring wsClipId = L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
|
||||
std::wstring wsValue = L"<path d=\"" + wsPath + L"\"";
|
||||
|
||||
const int nOffsetLeft{-m_pParser->GetDCBounds().Left};
|
||||
const int nOffsetTop {-m_pParser->GetDCBounds().Top};
|
||||
|
||||
if (0 != nOffsetLeft || 0 != nOffsetTop)
|
||||
wsValue += L" transform=\"translate(" + std::to_wstring(nOffsetLeft) + L',' + std::to_wstring(nOffsetTop) + L")\"";
|
||||
|
||||
wsValue += L"/>";
|
||||
|
||||
m_oClip.AddClipValue(wsClipId, wsValue, nClipMode);
|
||||
m_oClip.AddClipValue(L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0),
|
||||
L"<path d=\"" + wsPath + L"\"/>", nClipMode);
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::AddStroke(NodeAttributes &arAttributes) const
|
||||
|
||||
@ -985,6 +985,8 @@ bool CPictFile::DecodeData()
|
||||
m_oImgData.m_pPixelData = (BYTE*)malloc(4 * m_oImgData.m_nHeight * m_oImgData.m_nWidth);
|
||||
if (m_oFrame.get_Data())
|
||||
memcpy(m_oImgData.m_pPixelData, m_oFrame.get_Data(), 4 * m_oImgData.m_nHeight * m_oImgData.m_nWidth);
|
||||
else
|
||||
memset(m_oImgData.m_pPixelData, 255, m_oImgData.m_nWidth * m_oImgData.m_nHeight * 4);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1717,6 +1719,12 @@ void CPictFile::InitializeRenderer()
|
||||
return;
|
||||
|
||||
m_pFrameData = new BYTE[4 * m_oImgData.m_nWidth * m_oImgData.m_nHeight];
|
||||
unsigned int back = 0xffffff;
|
||||
unsigned int *pData32 = (unsigned int*)m_pFrameData;
|
||||
unsigned int *pData32End = pData32 + m_oImgData.m_nWidth * m_oImgData.m_nHeight;
|
||||
while (pData32 < pData32End)
|
||||
*pData32++ = back;
|
||||
|
||||
m_oFrame.put_Data(m_pFrameData);
|
||||
m_oFrame.put_Width(m_oImgData.m_nWidth);
|
||||
m_oFrame.put_Height(m_oImgData.m_nHeight);
|
||||
|
||||
@ -116,6 +116,7 @@ namespace XmlUtils
|
||||
void GetTextWithHHHH(bool bPreserve, wchar_t*& sBuffer, long& nSize, long& nLen);
|
||||
std::wstring GetTextWithHHHH(bool bPreserve);
|
||||
|
||||
std::string GetOuterXmlA();
|
||||
std::wstring GetOuterXml();
|
||||
std::wstring GetInnerXml();
|
||||
|
||||
|
||||
@ -206,8 +206,11 @@ namespace XmlUtils
|
||||
std::wstring CXmlLiteReader::GetTextWithHHHH(bool bPreserve)
|
||||
{
|
||||
return m_pInternal->GetTextWithHHHH(bPreserve);
|
||||
}
|
||||
|
||||
}
|
||||
std::string CXmlLiteReader::GetOuterXmlA()
|
||||
{
|
||||
return m_pInternal->GetOuterXmlA();
|
||||
}
|
||||
std::wstring CXmlLiteReader::GetOuterXml()
|
||||
{
|
||||
return m_pInternal->GetOuterXml();
|
||||
|
||||
@ -635,6 +635,10 @@ namespace XmlUtils
|
||||
GetTextWithHHHH(bPreserve, pUnicodes, nSize, nLen);
|
||||
return std::wstring(pUnicodes, nLen);
|
||||
}
|
||||
inline std::string GetOuterXmlA()
|
||||
{
|
||||
return GetXmlA(false);
|
||||
}
|
||||
inline std::wstring GetOuterXml()
|
||||
{
|
||||
return GetXml(false);
|
||||
@ -700,6 +704,64 @@ namespace XmlUtils
|
||||
}
|
||||
|
||||
private:
|
||||
inline std::string GetXmlA(bool bInner)
|
||||
{
|
||||
if (!IsValid())
|
||||
return "";
|
||||
|
||||
NSStringUtils::CStringBuilderA oResult;
|
||||
if (false == bInner)
|
||||
WriteElement(oResult);
|
||||
|
||||
int nDepth = GetDepth();
|
||||
if (0 == xmlTextReaderIsEmptyElement(reader))
|
||||
{
|
||||
XmlNodeType eNodeType = XmlNodeType_None;
|
||||
|
||||
int nCurDepth = -1;
|
||||
while (true)
|
||||
{
|
||||
if (1 != xmlTextReaderRead(reader))
|
||||
break;
|
||||
|
||||
int nTempType = xmlTextReaderNodeType(reader);
|
||||
if (-1 == nTempType)
|
||||
break;
|
||||
eNodeType = (XmlNodeType)nTempType;
|
||||
|
||||
nCurDepth = GetDepth();
|
||||
if (eNodeType == XmlNodeType_Text ||
|
||||
eNodeType == XmlNodeType_Whitespace ||
|
||||
eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE ||
|
||||
eNodeType == XmlNodeType_CDATA)
|
||||
{
|
||||
oResult.WriteString(GetTextA().c_str());
|
||||
}
|
||||
else if (eNodeType == XmlNodeType_Element)
|
||||
{
|
||||
WriteElement(oResult);
|
||||
}
|
||||
else if (eNodeType == XmlNodeType_EndElement)
|
||||
{
|
||||
if (false == bInner || nCurDepth != nDepth)
|
||||
{
|
||||
oResult.AddChar2Safe(char('<'), char('/'));
|
||||
oResult.WriteString(GetNameA().c_str());
|
||||
oResult.AddCharSafe(char('>'));
|
||||
}
|
||||
}
|
||||
|
||||
nCurDepth = GetDepth();
|
||||
if (nCurDepth < nDepth)
|
||||
break;
|
||||
|
||||
if (XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return oResult.GetData();
|
||||
}
|
||||
inline std::wstring GetXml(bool bInner)
|
||||
{
|
||||
if (!IsValid())
|
||||
@ -781,6 +843,33 @@ namespace XmlUtils
|
||||
else
|
||||
oResult.AddCharSafe(wchar_t('>'));
|
||||
}
|
||||
void WriteElement(NSStringUtils::CStringBuilderA& oResult)
|
||||
{
|
||||
oResult.AddCharSafe((char)'<');
|
||||
oResult.WriteString(GetNameA().c_str());
|
||||
if (GetAttributesCount() > 0)
|
||||
{
|
||||
MoveToFirstAttribute();
|
||||
std::wstring sName = GetName();
|
||||
while (!sName.empty())
|
||||
{
|
||||
oResult.AddCharSafe(char(' '));
|
||||
oResult.WriteString(GetNameA().c_str());
|
||||
oResult.AddChar2Safe(char('='), char('\"'));
|
||||
oResult.WriteString(GetTextA().c_str());
|
||||
oResult.AddCharSafe(char('\"'));
|
||||
|
||||
if (!MoveToNextAttribute())
|
||||
break;
|
||||
sName = GetName();
|
||||
}
|
||||
MoveToElement();
|
||||
}
|
||||
if (IsEmptyNode())
|
||||
oResult.AddChar2Safe(char('/'), char('>'));
|
||||
else
|
||||
oResult.AddCharSafe(char('>'));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -726,7 +726,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, int nRas
|
||||
GP<DjVuImage> pPage = m_pDoc->get_page(nPageIndex);
|
||||
//pPage->wait_for_complete_decode();
|
||||
pPage->set_rotate(0);
|
||||
return ConvertToPixels(pPage, nRasterW, nRasterH, bIsFlip);
|
||||
return ConvertToPixels(pPage, nRasterW, nRasterH, bIsFlip, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -734,11 +734,11 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, int nRas
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, int nImageW, int nImageH, bool bFlip)
|
||||
unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, int nImageW, int nImageH, bool bFlip, bool bIsSwapRGB)
|
||||
{
|
||||
BYTE* pBufferDst = NULL;
|
||||
|
||||
auto processPixmap = [&](GP<GPixmap> pImage, bool bFlip = false)
|
||||
auto processPixmap = [&](GP<GPixmap> pImage, bool bFlip = false, bool bIsSwapRGB = false)
|
||||
{
|
||||
pBufferDst = new BYTE[4 * nImageW * nImageH];
|
||||
|
||||
@ -749,7 +749,10 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
|
||||
GPixel* pLine = pImage->operator[](nRow);
|
||||
for (int i = 0; i < nImageW; ++i)
|
||||
{
|
||||
*pBuffer++ = 0xFF000000 | pLine->r << 16 | pLine->g << 8 | pLine->b;
|
||||
if (bIsSwapRGB)
|
||||
*pBuffer++ = 0xFF000000 | pLine->b << 16 | pLine->g << 8 | pLine->r;
|
||||
else
|
||||
*pBuffer++ = 0xFF000000 | pLine->r << 16 | pLine->g << 8 | pLine->b;
|
||||
++pLine;
|
||||
}
|
||||
}
|
||||
@ -790,7 +793,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
|
||||
if (pPage->is_legal_photo() || pPage->is_legal_compound())
|
||||
{
|
||||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||||
processPixmap(pImage, bFlip);
|
||||
processPixmap(pImage, bFlip, bIsSwapRGB);
|
||||
}
|
||||
else if (pPage->is_legal_bilevel())
|
||||
{
|
||||
@ -802,7 +805,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
|
||||
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
|
||||
if (pImage)
|
||||
{
|
||||
processPixmap(pImage, bFlip);
|
||||
processPixmap(pImage, bFlip, bIsSwapRGB);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -83,7 +83,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
unsigned char* ConvertToPixels(GP<DjVuImage>& pPage, int nRasterW, int nRasterH, bool bIsFlip = false);
|
||||
unsigned char* ConvertToPixels(GP<DjVuImage>& pPage, int nRasterW, int nRasterH, bool bIsFlip = false, bool bIsSwapRGB = false);
|
||||
|
||||
void CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
|
||||
void CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
|
||||
|
||||
@ -93,6 +93,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDst,
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = false;
|
||||
m_pInternal->m_bIsSupportShapeCommands = false;
|
||||
m_pInternal->m_oDocument.m_bIsRecord = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
|
||||
|
||||
if (bIsOutCompress)
|
||||
m_pInternal->m_oDocument.m_strTempDirectory = NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory);
|
||||
@ -130,6 +131,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz
|
||||
m_pInternal->m_oDocument.Init(false);
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
|
||||
m_pInternal->m_bIsSupportShapeCommands = false;
|
||||
m_pInternal->m_oDocument.m_bIsRecord = false;
|
||||
|
||||
@ -147,6 +149,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile,
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bCollectMetaInfo = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
|
||||
m_pInternal->m_bIsSupportShapeCommands = true;
|
||||
m_pInternal->m_oDocument.m_bIsRecord = false;
|
||||
|
||||
@ -165,6 +168,7 @@ NSWasm::CData CDocxRenderer::ScanPageBin(IOfficeDrawingFile* pFile, size_t nPage
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bCollectMetaInfo = true;
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
|
||||
m_pInternal->m_oDocument.m_bIsRecord = false;
|
||||
m_pInternal->m_bIsSupportShapeCommands = true;
|
||||
m_pInternal->m_oDocument.m_oFontStyleManager.Clear();
|
||||
|
||||
@ -195,12 +195,14 @@ namespace NSDocxRenderer
|
||||
|
||||
if (!m_arShapes.empty())
|
||||
{
|
||||
auto& last_shape = m_arShapes.back();
|
||||
if (last_shape->IsEqual(top, bot, left, right) && rotation == last_shape->m_dRotation && lType != m_lLastType && m_lLastType != 0)
|
||||
auto& last_shape = m_arShapes.back();
|
||||
bool is_type_diff = lType == c_nStroke && (m_lLastType == c_nWindingFillMode || m_lLastType == c_nEvenOddFillMode);
|
||||
is_type_diff = is_type_diff || (m_lLastType == c_nStroke && (lType == c_nWindingFillMode || m_lLastType == c_nEvenOddFillMode));
|
||||
if (last_shape->IsEqual(top, bot, left, right) && rotation == last_shape->m_dRotation && is_type_diff && m_lLastType != 0)
|
||||
{
|
||||
set_fill_mode(last_shape);
|
||||
// Reset stroke/fill logic
|
||||
m_lLastType = 0;
|
||||
if (pInfo) DrawImage(last_shape, pInfo, image_vector);
|
||||
m_lLastType = 0; // reset stroke/fill logic
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -341,10 +343,7 @@ namespace NSDocxRenderer
|
||||
|
||||
double top = baseline - _h;
|
||||
double left = dTextX;
|
||||
double right = dTextR;
|
||||
|
||||
if (left == right) // XPS
|
||||
right = left + _w;
|
||||
double right = left + _w;
|
||||
|
||||
// use forced fold option
|
||||
const auto& oParams = m_oManagers.pFontManager->GetFontSelectParams();
|
||||
@ -517,7 +516,7 @@ namespace NSDocxRenderer
|
||||
cont->CalculateSpace() * c_dSPACE_WIDTH_COEF;
|
||||
|
||||
if (curr_line && fabs(curr_line->m_dBot - cont->m_dBot) <= c_dTHE_SAME_STRING_Y_PRECISION_MM &&
|
||||
fabs(curr_line->m_dRight - cont->m_dLeft) <= 3 * space_width)
|
||||
fabs(curr_line->m_dRight - cont->m_dLeft) <= 4 * space_width)
|
||||
{
|
||||
curr_line->AddCont(cont);
|
||||
continue;
|
||||
@ -581,7 +580,7 @@ namespace NSDocxRenderer
|
||||
shape_ref_ptr_t val = m_arShapes[i];
|
||||
shape_ref_ptr_t next_val = m_arShapes[i + 1];
|
||||
|
||||
if (!val.get() || ! next_val.get())
|
||||
if (!val.get() || !next_val.get() || next_val.get()->m_nOrder - val.get()->m_nOrder != 1)
|
||||
continue;
|
||||
|
||||
next_val.get()->TryMergeShape(val.get());
|
||||
@ -1410,14 +1409,10 @@ namespace NSDocxRenderer
|
||||
}
|
||||
bool CPage::IsTextLineTrough(base_item_ptr_t pFirst) const noexcept
|
||||
{
|
||||
const auto width = pFirst->m_dRight - pFirst->m_dLeft;
|
||||
const auto center = pFirst->m_dLeft + width / 2;
|
||||
|
||||
for (const auto& text_line : m_arShapes)
|
||||
if (text_line && text_line->m_eType == CShape::eShapeType::stTextBox && text_line->m_dBot > pFirst->m_dTop &&
|
||||
text_line->m_dBot < pFirst->m_dBot &&
|
||||
text_line->m_dLeft <= center &&
|
||||
text_line->m_dRight >= center)
|
||||
text_line->m_dBot < pFirst->m_dBot && !(
|
||||
text_line->m_dRight < pFirst->m_dLeft || text_line->m_dLeft > pFirst->m_dRight))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -1666,7 +1661,11 @@ namespace NSDocxRenderer
|
||||
paragraph->m_dRightBorder = m_dWidth - paragraph->m_dRight;
|
||||
paragraph->m_dLeftBorder = min_left;
|
||||
|
||||
paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arTextLines.size();
|
||||
if (paragraph->m_arTextLines.size() == 1)
|
||||
paragraph->m_dLineHeight = paragraph->m_dHeight;
|
||||
else
|
||||
paragraph->m_dLineHeight = (paragraph->m_dBot - firstLine->m_dBotWithMaxDescent) / (paragraph->m_arTextLines.size() - 1);
|
||||
|
||||
paragraph->m_bIsNeedFirstLineIndent = false;
|
||||
paragraph->m_dFirstLine = 0;
|
||||
paragraph->m_wsStyleId = m_oManagers.pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph);
|
||||
@ -1674,20 +1673,22 @@ namespace NSDocxRenderer
|
||||
paragraph->MergeLines();
|
||||
|
||||
// Correct first line position
|
||||
double firstLine_height = firstLine->m_dBotWithMaxDescent - firstLine->m_dTopWithMaxAscent;
|
||||
if (paragraph->m_dLineHeight > firstLine_height)
|
||||
if (m_bFirstParagraphLineCorrection)
|
||||
{
|
||||
double offset = paragraph->m_dLineHeight - firstLine_height;
|
||||
paragraph->m_dTop -= offset;
|
||||
paragraph->m_dBot -= offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
double ascent = firstLine->m_dBot - firstLine->m_dTopWithMaxAscent;
|
||||
double newAscent = ascent * paragraph->m_dLineHeight / firstLine_height;
|
||||
double offset = ascent - newAscent;
|
||||
paragraph->m_dTop += offset;
|
||||
paragraph->m_dBot += offset;
|
||||
double firstLine_height = firstLine->m_dBotWithMaxDescent - firstLine->m_dTopWithMaxAscent;
|
||||
if (paragraph->m_dLineHeight > firstLine_height)
|
||||
{
|
||||
double offset = paragraph->m_dLineHeight - firstLine_height;
|
||||
paragraph->m_dTop -= offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
double ascent = firstLine->m_dBot - firstLine->m_dTopWithMaxAscent;
|
||||
double newAscent = ascent * paragraph->m_dLineHeight / firstLine_height;
|
||||
double offset = ascent - newAscent;
|
||||
paragraph->m_dTop += offset;
|
||||
}
|
||||
paragraph->m_dHeight = paragraph->m_dBot - paragraph->m_dTop;
|
||||
}
|
||||
|
||||
// setting TextAlignmentType
|
||||
@ -1935,6 +1936,9 @@ namespace NSDocxRenderer
|
||||
|
||||
double curr_max_right = text_lines[0]->m_dRight;
|
||||
double curr_min_left = text_lines[0]->m_dLeft;
|
||||
|
||||
double line_with_first_right_min = std::numeric_limits<double>::max();
|
||||
double line_with_first_left_max = std::numeric_limits<double>::lowest();
|
||||
for (size_t index = 0; index < ar_positions.size() - 1; ++index)
|
||||
{
|
||||
Position position = ar_positions[index];
|
||||
@ -1945,6 +1949,10 @@ namespace NSDocxRenderer
|
||||
{
|
||||
curr_max_right = line_bot->m_dRight;
|
||||
curr_min_left = line_bot->m_dLeft;
|
||||
|
||||
line_with_first_right_min = std::numeric_limits<double>::max();
|
||||
line_with_first_left_max = std::numeric_limits<double>::lowest();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1952,15 +1960,18 @@ namespace NSDocxRenderer
|
||||
double line_with_first_right = line_top->m_dRight + line_bot->m_dFirstWordWidth;
|
||||
double line_with_first_left = line_top->m_dLeft - line_bot->m_dFirstWordWidth;
|
||||
|
||||
line_with_first_right_min = std::min(line_with_first_right_min, line_with_first_right);
|
||||
line_with_first_left_max = std::max(line_with_first_left_max, line_with_first_left);
|
||||
|
||||
curr_max_right = std::max(curr_max_right, line_bot->m_dRight);
|
||||
curr_min_left = std::min(curr_min_left, line_bot->m_dLeft);
|
||||
|
||||
double diff = 0;
|
||||
|
||||
if (position.right && !position.left)
|
||||
diff = line_with_first_left - curr_min_left;
|
||||
diff = line_with_first_left_max - curr_min_left;
|
||||
else if (position.left || ar_indents[index] || position.center)
|
||||
diff = curr_max_right - line_with_first_right;
|
||||
diff = curr_max_right - line_with_first_right_min;
|
||||
|
||||
if (diff <= 0)
|
||||
continue;
|
||||
@ -1969,6 +1980,8 @@ namespace NSDocxRenderer
|
||||
ar_delims[index] = true;
|
||||
curr_max_right = line_bot->m_dRight;
|
||||
curr_min_left = line_bot->m_dLeft;
|
||||
line_with_first_right_min = std::numeric_limits<double>::max();
|
||||
line_with_first_left_max = std::numeric_limits<double>::lowest();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2717,6 +2730,20 @@ namespace NSDocxRenderer
|
||||
pShape->m_dImageTop = imageVector.GetTop();
|
||||
pShape->m_dImageLeft = imageVector.GetLeft();
|
||||
pShape->m_dImageRight = imageVector.GetRight();
|
||||
|
||||
// for reflection along the x-axis
|
||||
if (fabs(fabs(pShape->m_dRotation) - 180.0) < 0.01 && m_oTransform.sx() > 0.0)
|
||||
{
|
||||
std::swap(pShape->m_dImageBot, pShape->m_dImageTop);
|
||||
pShape->m_dRotation = 0.0;
|
||||
}
|
||||
|
||||
// for reflection along the y-axis
|
||||
if (fabs(fabs(pShape->m_dRotation) - 180.0) < 0.01 && m_oTransform.sy() > 0.0)
|
||||
{
|
||||
std::swap(pShape->m_dImageLeft, pShape->m_dImageRight);
|
||||
pShape->m_dRotation = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void CPage::DrawGradient(shape_ptr_t pShape)
|
||||
|
||||
@ -50,6 +50,7 @@ namespace NSDocxRenderer
|
||||
bool m_bIsBuildTables {false};
|
||||
bool m_bIsLuminosityShapesFiled{false};
|
||||
bool m_bFontSubstitution {false};
|
||||
bool m_bFirstParagraphLineCorrection{false};
|
||||
|
||||
CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers);
|
||||
~CPage();
|
||||
|
||||
@ -142,7 +142,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
|
||||
*/
|
||||
|
||||
CHtmlFile2 oFile;
|
||||
CHtmlParams oFileParams;
|
||||
HTML::THTMLParameters oFileParams;
|
||||
|
||||
oFileParams.SetAuthors (m_oBookInfo.GetCreators());
|
||||
oFileParams.SetGenres (m_oBookInfo.GetSubjects());
|
||||
@ -155,7 +155,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
|
||||
|
||||
std::wstring sDocxFileTempDir = m_sTempDir + L"/tmp";
|
||||
NSDirectory::CreateDirectory(sDocxFileTempDir);
|
||||
oFile.SetTmpDirectory(sDocxFileTempDir);
|
||||
oFile.SetTempDirectory(sDocxFileTempDir);
|
||||
oFile.SetCoreDirectory(NSFile::GetDirectoryName(sContent));
|
||||
|
||||
std::vector<std::wstring> arFiles;
|
||||
@ -182,7 +182,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
|
||||
sOutputDir = sOutputFile;
|
||||
|
||||
NSDirectory::CreateDirectory(sOutputDir);
|
||||
HRESULT hRes = oFile.OpenBatchHtml(arFiles, sOutputDir, &oFileParams);
|
||||
HRESULT hRes = oFile.ConvertHTML2OOXML(arFiles, sOutputDir, &oFileParams);
|
||||
if (bIsOutCompress && S_OK == hRes)
|
||||
hRes = oOfficeUtils.CompressFileOrDirectory(sOutputDir, sOutputFile);
|
||||
|
||||
|
||||
@ -2170,7 +2170,7 @@ HRESULT CFb2File::FromHtml(const std::wstring& sHtmlFile, const std::wstring& sD
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
|
||||
//XmlUtils::CXmlLiteReader oIndexHtml;
|
||||
std::wstring xhtml = htmlToXhtml(sContent, bNeedConvert);
|
||||
std::wstring xhtml = HTML::htmlToXhtml(sContent, bNeedConvert);
|
||||
|
||||
if (!m_internal->m_oLightReader.FromString(xhtml))
|
||||
return S_FALSE;
|
||||
|
||||
64
HtmlFile2/Common.h
Normal file
64
HtmlFile2/Common.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <string>
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
|
||||
|
||||
using XmlString = NSStringUtils::CStringBuilder;
|
||||
|
||||
inline void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2)
|
||||
{
|
||||
size_t pos = s.find(s1);
|
||||
size_t l = s2.length();
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
if (!(s1 == L"&" && s2 == L"&" && s.length() > pos + 4 && s[pos] == L'&' && s[pos + 1] == L'a' && s[pos + 2] == L'm' && s[pos + 3] == L'p' && s[pos + 4] == L';'))
|
||||
s.replace(pos, s1.length(), s2);
|
||||
pos = s.find(s1, pos + l);
|
||||
}
|
||||
}
|
||||
|
||||
inline std::wstring EncodeXmlString(const std::wstring& s)
|
||||
{
|
||||
std::wstring sRes = s;
|
||||
|
||||
replace_all(sRes, L"&", L"&");
|
||||
replace_all(sRes, L"<", L"<");
|
||||
replace_all(sRes, L">", L">");
|
||||
replace_all(sRes, L"\"", L""");
|
||||
replace_all(sRes, L"\'", L"'");
|
||||
replace_all(sRes, L"\n", L"
");
|
||||
replace_all(sRes, L"\r", L"
");
|
||||
replace_all(sRes, L"\t", L"	");
|
||||
|
||||
return sRes;
|
||||
}
|
||||
|
||||
inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder)
|
||||
{
|
||||
if (oSrcStringBuilder.GetCurSize() < MAX_STRING_BLOCK_SIZE)
|
||||
{
|
||||
oDstStringBuilder.Write(oSrcStringBuilder);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t ulSize = oSrcStringBuilder.GetCurSize();
|
||||
size_t ulCurrentBlockSize = 0, ulPosition = 0;
|
||||
|
||||
while (ulSize > 0)
|
||||
{
|
||||
ulCurrentBlockSize = std::min(ulSize, MAX_STRING_BLOCK_SIZE);
|
||||
oDstStringBuilder.WriteString(oSrcStringBuilder.GetSubData(ulPosition, ulCurrentBlockSize));
|
||||
|
||||
ulSize -= ulCurrentBlockSize;
|
||||
ulPosition += ulCurrentBlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMON_H
|
||||
69
HtmlFile2/HTMLParameters.h
Normal file
69
HtmlFile2/HTMLParameters.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef HTMLPARAMETERS_H
|
||||
#define HTMLPARAMETERS_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
struct THTMLParameters
|
||||
{
|
||||
std::wstring m_sGenres; // Жанры
|
||||
std::wstring m_sAuthors; // Авторы
|
||||
std::wstring m_sBookTitle; // Название
|
||||
std::wstring m_sDate; // Дата
|
||||
std::wstring m_sDescription; // описание
|
||||
std::wstring m_sLanguage; // Язык
|
||||
bool m_bNeedPageBreakBefore; // Новый html с новой страницы
|
||||
std::wstring m_sdocDefaults; // Стиль docDefaults
|
||||
std::wstring m_sNormal; // Стиль normal
|
||||
|
||||
THTMLParameters() : m_bNeedPageBreakBefore(false) {}
|
||||
|
||||
void SetNormal(const std::wstring& sStyle)
|
||||
{
|
||||
m_sNormal = sStyle;
|
||||
}
|
||||
|
||||
void SetDocDefaults(const std::wstring& sStyle)
|
||||
{
|
||||
m_sdocDefaults = sStyle;
|
||||
}
|
||||
|
||||
void SetPageBreakBefore(bool bNeed)
|
||||
{
|
||||
m_bNeedPageBreakBefore = bNeed;
|
||||
}
|
||||
|
||||
void SetDate(const std::wstring& sDate)
|
||||
{
|
||||
m_sDate = sDate;
|
||||
}
|
||||
|
||||
void SetDescription(const std::wstring& sDescription)
|
||||
{
|
||||
m_sDescription = sDescription;
|
||||
}
|
||||
|
||||
void SetGenres(const std::wstring& sGenres)
|
||||
{
|
||||
m_sGenres = sGenres;
|
||||
}
|
||||
|
||||
void SetAuthors(const std::wstring& sAuthors)
|
||||
{
|
||||
m_sAuthors = sAuthors;
|
||||
}
|
||||
|
||||
void SetTitle(const std::wstring& sTitle)
|
||||
{
|
||||
m_sBookTitle = sTitle;
|
||||
}
|
||||
|
||||
void SetLanguage(const std::wstring& sLanguage)
|
||||
{
|
||||
m_sLanguage = sLanguage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HTMLPARAMETERS_H
|
||||
1533
HtmlFile2/HTMLReader.cpp
Normal file
1533
HtmlFile2/HTMLReader.cpp
Normal file
File diff suppressed because it is too large
Load Diff
93
HtmlFile2/HTMLReader.h
Normal file
93
HtmlFile2/HTMLReader.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef HTMLREADER_H
|
||||
#define HTMLREADER_H
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
|
||||
#include "../DesktopEditor/xml/include/xmlutils.h"
|
||||
|
||||
#include "HTMLParameters.h"
|
||||
#include "MarkdownParameters.h"
|
||||
|
||||
#include "Writers/IWriter.h"
|
||||
#include "Tags/HTMLTags.h"
|
||||
#include "Table.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
class CHTMLReader
|
||||
{
|
||||
XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
|
||||
NSCSS::CCssCalculator m_oCSSCalculator; // Css калькулятор
|
||||
|
||||
bool m_bIsTempDirOwner;
|
||||
std::wstring m_wsTempDirectory; // Temp папка
|
||||
std::wstring m_wsSrcDirectory; // Директория источника
|
||||
std::wstring m_wsDstDirectory; // Директория назначения
|
||||
std::wstring m_wsBaseDirectory; // Полный базовый адрес
|
||||
std::wstring m_wsCoreDirectory; // Путь до корневого файла (используется для работы с Epub)
|
||||
|
||||
IWriter *m_pWriter;
|
||||
|
||||
std::unordered_map<UINT, std::shared_ptr<ITag>> m_mTags;
|
||||
public:
|
||||
CHTMLReader();
|
||||
~CHTMLReader();
|
||||
|
||||
void SetTempDirectory(const std::wstring& wsPath);
|
||||
void SetCoreDirectory(const std::wstring& wsPath);
|
||||
|
||||
HRESULT ConvertHTML2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
|
||||
HRESULT ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
|
||||
|
||||
HRESULT ConvertHTML2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
|
||||
HRESULT ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
|
||||
|
||||
HRESULT ConvertMHT2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
|
||||
HRESULT ConvertMHT2Markdown (const std::wstring& wsPath, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
|
||||
|
||||
HRESULT ConvertMHT2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
|
||||
HRESULT ConvertMHT2Markdown (const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
|
||||
|
||||
NSCSS::CCssCalculator* GetCSSCalculator();
|
||||
private:
|
||||
void Clear();
|
||||
void InitOOXMLTags(THTMLParameters* pParametrs = nullptr);
|
||||
void InitMDTags(TMarkdownParameters* pParametrs = nullptr);
|
||||
|
||||
bool IsHTML();
|
||||
|
||||
typedef std::function<bool(const std::wstring&, XmlUtils::CXmlLiteReader&)> Convert_Func;
|
||||
|
||||
HRESULT InitAndConvert2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, Convert_Func Convertation, THTMLParameters* pParameters = nullptr);
|
||||
HRESULT InitAndConvert2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, Convert_Func Convertation, TMarkdownParameters* pParameters = nullptr);
|
||||
|
||||
bool Convert(const std::wstring& wsPath, Convert_Func Convertation);
|
||||
|
||||
void ReadStyle();
|
||||
void ReadStyle2();
|
||||
void ReadStyleFromNetwork();
|
||||
|
||||
void ReadDocument();
|
||||
void ReadHead();
|
||||
void ReadBody();
|
||||
|
||||
bool ReadStream(std::vector<NSCSS::CNode>& arSelectors, bool bInsertEmptyP = false);
|
||||
bool ReadInside(std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool ReadText(std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool ReadSVG(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
bool ReadEmptyTag(UINT unTag, const std::vector<NSCSS::CNode>& arSelectors);
|
||||
bool ReadDefaultTag(UINT unTag, std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool ReadTable(std::vector<NSCSS::CNode>& arSelectors);
|
||||
void ReadTableCaption(CStorageTable& oTable, std::vector<NSCSS::CNode>& arSelectors);
|
||||
void ReadTableRows(CStorageTable& oTable, std::vector<NSCSS::CNode>& arSelectors, ERowParseMode eMode);
|
||||
void ReadTableColspan(CStorageTable& oTable);
|
||||
|
||||
void GetSubClass(std::vector<NSCSS::CNode>& arSelectors);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HTMLREADER_H
|
||||
@ -13,6 +13,7 @@ DEFINES += CSSCALCULATOR_LIBRARY_STATIC
|
||||
DEFINES += CSS_CALCULATOR_WITH_XHTML
|
||||
DEFINES += DISABLE_RUBY_SUPPORT
|
||||
DEFINES += MDCONVERTER_DECL_EXPORT
|
||||
DEFINES += HTML_NORMALIZER_DECL_EXPORT
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/..
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
@ -31,8 +32,25 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri)
|
||||
|
||||
ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network)
|
||||
|
||||
SOURCES += htmlfile2.cpp
|
||||
SOURCES += htmlfile2.cpp \
|
||||
./Writers/OOXMLWriter.cpp \
|
||||
HTMLReader.cpp \
|
||||
Tags/MDTags.cpp \
|
||||
Writers/MDWriter.cpp \
|
||||
Table.cpp \
|
||||
Tags/OOXMLTags.cpp
|
||||
|
||||
HEADERS += htmlfile2.h \
|
||||
./src/StringFinder.h \
|
||||
./src/Languages.h
|
||||
./src/Languages.h \
|
||||
Common.h \
|
||||
./Writers/OOXMLWriter.h \
|
||||
./Writers/IWriter.h \
|
||||
HTMLParameters.h \
|
||||
HTMLReader.h \
|
||||
./Tags/HTMLTags.h \
|
||||
MarkdownParameters.h \
|
||||
Tags/MDTags.h \
|
||||
Writers/MDWriter.h \
|
||||
Table.h \
|
||||
Tags/OOXMLTags.h
|
||||
|
||||
14
HtmlFile2/MarkdownParameters.h
Normal file
14
HtmlFile2/MarkdownParameters.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef MARKDOWNPARAMETERS_H
|
||||
#define MARKDOWNPARAMETERS_H
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
struct TMarkdownParameters
|
||||
{
|
||||
bool m_bUseAlternativeHTMLTags = false; //Использовать html теги там, где нет стандартной реализации в md(например для подчеркиваний)
|
||||
wchar_t m_wchUnorderedList = L'-'; // Возможные варианты в md: -, +, *
|
||||
wchar_t m_wchOrderedList = L'.'; // Возможные варианты в md: ., )
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MARKDOWNPARAMETERS_H
|
||||
715
HtmlFile2/Table.cpp
Normal file
715
HtmlFile2/Table.cpp
Normal file
@ -0,0 +1,715 @@
|
||||
#include "Table.h"
|
||||
|
||||
#include "Common.h"
|
||||
#include "src/StringFinder.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
|
||||
|
||||
#define RELEASE_VECTOR_PTR(vector_object, object_type) \
|
||||
for (object_type* pElement : vector_object) \
|
||||
RELEASEOBJECT(pElement)
|
||||
|
||||
#define FIRST_ELEMENT 0x00000001
|
||||
#define LAST_ELEMENT 0x00000002
|
||||
#define MID_ELEMENT 0x00000004
|
||||
|
||||
#define PARSE_MODE_HEADER 0x00000100
|
||||
#define PARSE_MODE_BODY 0x00000200
|
||||
#define PARSE_MODE_FOOTHER 0x00000400
|
||||
|
||||
#define COL_POSITION_MASK 0x0000000F
|
||||
#define ROW_POSITION_MASK 0x000000F0
|
||||
#define PARSE_MODE_MASK 0x00000F00
|
||||
|
||||
#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips
|
||||
#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips
|
||||
|
||||
TTableRowStyle::TTableRowStyle()
|
||||
: m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false)
|
||||
{}
|
||||
|
||||
bool TTableRowStyle::Empty() const
|
||||
{
|
||||
return 0 == m_unMaxHeight && false == m_bIsHeader;
|
||||
}
|
||||
|
||||
TTableCellStyle::TTableCellStyle()
|
||||
{}
|
||||
|
||||
bool TTableCellStyle::Empty()
|
||||
{
|
||||
return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty();
|
||||
}
|
||||
|
||||
void TTableCellStyle::Copy(const TTableCellStyle* pTableCellStyle)
|
||||
{
|
||||
if (NULL == pTableCellStyle)
|
||||
return;
|
||||
|
||||
m_oWidth = pTableCellStyle->m_oWidth;
|
||||
m_oHeight = pTableCellStyle->m_oHeight;
|
||||
m_oBorder = pTableCellStyle->m_oBorder;
|
||||
m_oPadding = pTableCellStyle->m_oPadding;
|
||||
m_oBackground = pTableCellStyle->m_oBackground;
|
||||
|
||||
m_wsHAlign = pTableCellStyle->m_wsHAlign;
|
||||
m_wsVAlign = pTableCellStyle->m_wsVAlign;
|
||||
}
|
||||
|
||||
TTableCellStyle& TTableCellStyle::operator+=(const TTableCellStyle* pCellStyle)
|
||||
{
|
||||
if (NULL == pCellStyle)
|
||||
return *this;
|
||||
|
||||
m_oWidth += pCellStyle->m_oWidth;
|
||||
m_oHeight += pCellStyle->m_oHeight;
|
||||
m_oBorder += pCellStyle->m_oBorder;
|
||||
m_oPadding += pCellStyle->m_oPadding;
|
||||
m_oBackground += pCellStyle->m_oBackground;
|
||||
|
||||
if (m_wsHAlign.empty())
|
||||
m_wsHAlign = pCellStyle->m_wsHAlign;
|
||||
|
||||
if (m_wsVAlign.empty())
|
||||
m_wsVAlign = pCellStyle->m_wsVAlign;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
CStorageTableCell::CStorageTableCell()
|
||||
: m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_oData(30)
|
||||
{}
|
||||
|
||||
CStorageTableCell::CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty)
|
||||
: m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged),
|
||||
m_bIsEmpty(bIsEmpty)
|
||||
{}
|
||||
|
||||
CStorageTableCell::CStorageTableCell(CStorageTableCell& oCell)
|
||||
: m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged),
|
||||
m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles)
|
||||
{
|
||||
WriteToStringBuilder(oCell.m_oData, m_oData);
|
||||
}
|
||||
|
||||
bool CStorageTableCell::Empty() const
|
||||
{
|
||||
return m_bIsEmpty;
|
||||
}
|
||||
|
||||
bool CStorageTableCell::Merged() const
|
||||
{
|
||||
return m_bIsMerged;
|
||||
}
|
||||
|
||||
CStorageTableCell* CStorageTableCell::Copy()
|
||||
{
|
||||
return new CStorageTableCell(*this);
|
||||
}
|
||||
|
||||
CStorageTableCell* CStorageTableCell::CreateEmpty(UINT unColspan, bool m_bIsMerged, const TTableCellStyle* pStyle)
|
||||
{
|
||||
CStorageTableCell *pCell = new CStorageTableCell(unColspan, 1, m_bIsMerged, true);
|
||||
|
||||
pCell->m_oStyles.Copy(pStyle);
|
||||
|
||||
return pCell;
|
||||
}
|
||||
|
||||
CStorageTableCell* CStorageTableCell::CreateEmpty(const TTableCellStyle* pStyle)
|
||||
{
|
||||
CStorageTableCell *pCell = new CStorageTableCell(1, 1, false, true);
|
||||
|
||||
pCell->m_oStyles.Copy(pStyle);
|
||||
|
||||
return pCell;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetColspan(UINT unColspan, UINT unCurrentIndex)
|
||||
{
|
||||
if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex)
|
||||
m_unColspan = std::min(MAXCOLUMNSINTABLE - 1 - unCurrentIndex, unColspan);
|
||||
else
|
||||
m_unColspan = 1;
|
||||
}
|
||||
|
||||
UINT CStorageTableCell::GetColspan() const
|
||||
{
|
||||
return m_unColspan;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetRowspan(UINT unRowspan)
|
||||
{
|
||||
m_unRowSpan = unRowspan;
|
||||
}
|
||||
|
||||
UINT CStorageTableCell::GetRowspan() const
|
||||
{
|
||||
return m_unRowSpan;
|
||||
}
|
||||
|
||||
NSStringUtils::CStringBuilder* CStorageTableCell::GetData()
|
||||
{
|
||||
return &m_oData;
|
||||
}
|
||||
|
||||
const TTableCellStyle* CStorageTableCell::GetStyles() const
|
||||
{
|
||||
return &m_oStyles;
|
||||
}
|
||||
|
||||
TTableCellStyle* CStorageTableCell::GetStyles()
|
||||
{
|
||||
return &m_oStyles;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
|
||||
{
|
||||
m_oStyles.m_oWidth = oWidth;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetHeight(const NSCSS::NSProperties::CDigit& oHeight)
|
||||
{
|
||||
m_oStyles.m_oHeight = oHeight;
|
||||
}
|
||||
|
||||
UINT CStorageTableCell::GetWidth() const
|
||||
{
|
||||
return m_oStyles.m_oWidth.ToInt(NSCSS::Twips, DEFAULT_PAGE_WIDTH);
|
||||
}
|
||||
|
||||
UINT CStorageTableCell::GetHeight() const
|
||||
{
|
||||
return m_oStyles.m_oHeight.ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT);
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
|
||||
{
|
||||
m_oStyles.m_oBorder = oBorder;
|
||||
}
|
||||
|
||||
void CStorageTableCell::ClearTopBorder()
|
||||
{
|
||||
m_oStyles.m_oBorder.SetTopSide(L"none", 0, true);
|
||||
}
|
||||
|
||||
void CStorageTableCell::ClearLeftBorder()
|
||||
{
|
||||
m_oStyles.m_oBorder.SetLeftSide(L"none", 0, true);
|
||||
}
|
||||
|
||||
void CStorageTableCell::ClearBottomBorder()
|
||||
{
|
||||
m_oStyles.m_oBorder.SetBottomSide(L"none", 0, true);
|
||||
}
|
||||
|
||||
void CStorageTableCell::ClearRightBorder()
|
||||
{
|
||||
m_oStyles.m_oBorder.SetRightSide(L"none", 0, true);
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
|
||||
{
|
||||
m_oStyles.m_oPadding = oPadding;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetHAlign(const std::wstring& wsAlign)
|
||||
{
|
||||
m_oStyles.m_wsHAlign = wsAlign;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetVAlign(const std::wstring& wsAlign)
|
||||
{
|
||||
m_oStyles.m_wsVAlign = wsAlign;
|
||||
}
|
||||
|
||||
void CStorageTableCell::SetBackground(const NSCSS::NSProperties::CColor& oColor)
|
||||
{
|
||||
m_oStyles.m_oBackground = oColor;
|
||||
}
|
||||
|
||||
CStorageTableRow::CStorageTableRow()
|
||||
{}
|
||||
|
||||
CStorageTableRow::~CStorageTableRow()
|
||||
{
|
||||
for (CStorageTableCell* pCell : m_arCells)
|
||||
RELEASEOBJECT(pCell);
|
||||
}
|
||||
|
||||
void CStorageTableRow::AddCell(CStorageTableCell* pCell)
|
||||
{
|
||||
InsertCell(pCell, -1);
|
||||
}
|
||||
|
||||
void CStorageTableRow::InsertCell(CStorageTableCell* pCell, int nPosition)
|
||||
{
|
||||
if (NULL == pCell)
|
||||
return;
|
||||
|
||||
if (nPosition < 0)
|
||||
{
|
||||
std::vector<CStorageTableCell*>::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CStorageTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); });
|
||||
|
||||
if (m_arCells.end() != itFoundEmpty)
|
||||
{
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
delete *itFoundEmpty;
|
||||
*itFoundEmpty = pCell;
|
||||
|
||||
if (1 != pCell->GetColspan())
|
||||
{
|
||||
++itFoundEmpty;
|
||||
UINT unColspan = pCell->GetColspan() - 1;
|
||||
|
||||
while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0)
|
||||
{
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
--unColspan;
|
||||
delete (*itFoundEmpty);
|
||||
itFoundEmpty = m_arCells.erase(itFoundEmpty);
|
||||
}
|
||||
|
||||
if (unColspan != 0)
|
||||
pCell->SetColspan(pCell->GetColspan() - unColspan, MAXCOLUMNSINTABLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_arCells.push_back(pCell);
|
||||
}
|
||||
else if (nPosition >= m_arCells.size())
|
||||
{
|
||||
const UINT unMissingCount = nPosition - m_arCells.size();
|
||||
|
||||
for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex)
|
||||
m_arCells.push_back(CStorageTableCell::CreateEmpty());
|
||||
|
||||
m_oStyles.m_unMaxIndex += unMissingCount;
|
||||
|
||||
m_arCells.push_back(pCell);
|
||||
}
|
||||
else if (m_arCells[nPosition]->Empty())
|
||||
{
|
||||
delete m_arCells[nPosition];
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
m_arCells[nPosition] = pCell;
|
||||
|
||||
if (1 != pCell->GetColspan())
|
||||
{
|
||||
++nPosition;
|
||||
UINT unDeleteCount = pCell->GetColspan() - 1;
|
||||
while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0)
|
||||
{
|
||||
delete m_arCells[nPosition];
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
m_arCells.erase(m_arCells.begin() + nPosition);
|
||||
--unDeleteCount;
|
||||
}
|
||||
|
||||
if (0 != unDeleteCount)
|
||||
pCell->SetColspan(pCell->GetColspan() - unDeleteCount, MAXCOLUMNSINTABLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_arCells.insert(m_arCells.begin() + nPosition, pCell);
|
||||
|
||||
m_oStyles.m_unMaxIndex += pCell->GetColspan();
|
||||
|
||||
if (1 == pCell->GetColspan() && 1 == pCell->GetRowspan())
|
||||
m_oStyles.m_unMaxHeight = std::max(m_oStyles.m_unMaxHeight, pCell->GetHeight());
|
||||
}
|
||||
|
||||
UINT CStorageTableRow::GetIndex() const
|
||||
{
|
||||
return m_oStyles.m_unMaxIndex;
|
||||
}
|
||||
|
||||
UINT CStorageTableRow::GetCount() const
|
||||
{
|
||||
return m_arCells.size();
|
||||
}
|
||||
|
||||
CStorageTableCell* CStorageTableRow::operator[](UINT unIndex)
|
||||
{
|
||||
if (unIndex >= m_arCells.size())
|
||||
return NULL;
|
||||
|
||||
return m_arCells[unIndex];
|
||||
}
|
||||
|
||||
bool CStorageTableRow::Empty() const
|
||||
{
|
||||
return m_arCells.empty();
|
||||
}
|
||||
|
||||
const TTableRowStyle& CStorageTableRow::GetStyles() const
|
||||
{
|
||||
return m_oStyles;
|
||||
}
|
||||
|
||||
const std::vector<CStorageTableCell*>& CStorageTableRow::GetCells() const
|
||||
{
|
||||
return m_arCells;
|
||||
}
|
||||
|
||||
CTableCol::CTableCol(UINT unSpan)
|
||||
: m_unSpan(unSpan)
|
||||
{}
|
||||
|
||||
CTableCol::CTableCol(const NSCSS::CNode& oTableColNode)
|
||||
: m_unSpan(1)
|
||||
{
|
||||
m_unSpan = NSStringFinder::ToInt(oTableColNode.GetAttributeValue(L"span"));
|
||||
}
|
||||
|
||||
UINT CTableCol::GetSpan() const
|
||||
{
|
||||
return m_unSpan;
|
||||
}
|
||||
|
||||
TTableCellStyle* CTableCol::GetStyle()
|
||||
{
|
||||
return &m_oStyle;
|
||||
}
|
||||
|
||||
const TTableCellStyle* CTableCol::GetStyle() const
|
||||
{
|
||||
return &m_oStyle;
|
||||
}
|
||||
|
||||
CTableColgroup::CTableColgroup(NSCSS::CNode& oTableColgroupNode)
|
||||
: m_unWidth(0)
|
||||
{
|
||||
m_unWidth = NSStringFinder::ToInt(oTableColgroupNode.GetAttributeValue(L"width"), 0);
|
||||
}
|
||||
|
||||
CTableColgroup::~CTableColgroup()
|
||||
{
|
||||
RELEASE_VECTOR_PTR(m_arCols, CTableCol)
|
||||
}
|
||||
|
||||
bool CTableColgroup::Empty() const
|
||||
{
|
||||
return m_arCols.empty();
|
||||
}
|
||||
|
||||
void CTableColgroup::AddCol(CTableCol* pCol)
|
||||
{
|
||||
if (NULL != pCol)
|
||||
m_arCols.push_back(pCol);
|
||||
}
|
||||
|
||||
const std::vector<CTableCol*>& CTableColgroup::GetCols() const
|
||||
{
|
||||
return m_arCols;
|
||||
}
|
||||
|
||||
TTableStyles::TTableStyles()
|
||||
: m_nCellSpacing(-1), m_enRules(None)
|
||||
{}
|
||||
|
||||
bool TTableStyles::Empty() const
|
||||
{
|
||||
return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && m_wsAlign.empty();
|
||||
}
|
||||
|
||||
CStorageTable::CStorageTable()
|
||||
: m_unMaxColumns(0)
|
||||
{}
|
||||
|
||||
CStorageTable::~CStorageTable()
|
||||
{
|
||||
for (std::vector<CStorageTableRow*>& arHeaders : m_arHeaders)
|
||||
RELEASE_VECTOR_PTR(arHeaders, CStorageTableRow)
|
||||
|
||||
RELEASE_VECTOR_PTR(m_arFoother, CStorageTableRow)
|
||||
RELEASE_VECTOR_PTR(m_arRows, CStorageTableRow)
|
||||
RELEASE_VECTOR_PTR(m_arColgroups, CTableColgroup)
|
||||
}
|
||||
|
||||
CStorageTableRow* CStorageTable::operator[](UINT unIndex)
|
||||
{
|
||||
if (unIndex < m_arRows.size())
|
||||
return m_arRows[unIndex];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CStorageTable::Empty() const
|
||||
{
|
||||
return m_arHeaders.empty() && m_arRows.empty() && m_arFoother.empty();
|
||||
}
|
||||
|
||||
bool CStorageTable::HaveCaption()
|
||||
{
|
||||
return 0 != m_oCaption.GetCurSize();
|
||||
}
|
||||
|
||||
bool CStorageTable::HaveColgroups() const
|
||||
{
|
||||
return !m_arColgroups.empty();
|
||||
}
|
||||
|
||||
bool CStorageTable::HaveHeader() const
|
||||
{
|
||||
return !m_arHeaders.empty();
|
||||
}
|
||||
|
||||
UINT CStorageTable::GetRowCount() const
|
||||
{
|
||||
return m_arRows.size();
|
||||
}
|
||||
|
||||
const TTableStyles& CStorageTable::GetTableStyles() const
|
||||
{
|
||||
return m_oStyles;
|
||||
}
|
||||
|
||||
const TTableCellStyle* CStorageTable::GetColStyle(UINT unColumnNumber) const
|
||||
{
|
||||
if (m_arColgroups.empty())
|
||||
return NULL;
|
||||
|
||||
UINT unCurrentNumber = 0;
|
||||
|
||||
for (const CTableColgroup* pColgroup : m_arColgroups)
|
||||
{
|
||||
for (const CTableCol* pCol : pColgroup->GetCols())
|
||||
{
|
||||
unCurrentNumber += pCol->GetSpan();
|
||||
|
||||
if (unCurrentNumber >= unColumnNumber)
|
||||
return pCol->GetStyle();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CStorageTable::AddRows(std::vector<CStorageTableRow*>& arRows, ERowParseMode eParseMode)
|
||||
{
|
||||
if (arRows.empty())
|
||||
return;
|
||||
|
||||
if (ERowParseMode::Foother == eParseMode && !m_arFoother.empty())
|
||||
eParseMode = ERowParseMode::Header;
|
||||
|
||||
if (ERowParseMode::Header == eParseMode)
|
||||
m_arHeaders.push_back({});
|
||||
|
||||
for (CStorageTableRow* pRow : arRows)
|
||||
AddRow(pRow, eParseMode);
|
||||
}
|
||||
|
||||
void CStorageTable::AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode)
|
||||
{
|
||||
if (NULL == pRow)
|
||||
return;
|
||||
|
||||
for (UINT unIndex = 0; unIndex < pRow->GetCount(); ++unIndex)
|
||||
{
|
||||
if (unIndex >= m_arMinColspan.size())
|
||||
m_arMinColspan.push_back((*pRow)[unIndex]->GetColspan());
|
||||
else if ((*pRow)[unIndex]->GetColspan() < m_arMinColspan[unIndex])
|
||||
m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan();
|
||||
}
|
||||
|
||||
switch (eParseMode)
|
||||
{
|
||||
default:
|
||||
case ERowParseMode::Body:
|
||||
{
|
||||
m_arRows.push_back(pRow);
|
||||
break;
|
||||
}
|
||||
case ERowParseMode::Header:
|
||||
{
|
||||
if (m_arHeaders.empty())
|
||||
m_arHeaders.push_back({});
|
||||
|
||||
m_arHeaders.back().push_back(pRow);
|
||||
break;
|
||||
}
|
||||
case ERowParseMode::Foother:
|
||||
{
|
||||
m_arFoother.push_back(pRow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSStringUtils::CStringBuilder* CStorageTable::GetCaptionData()
|
||||
{
|
||||
return &m_oCaption;
|
||||
}
|
||||
|
||||
void CStorageTable::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
|
||||
{
|
||||
m_oStyles.m_oPadding = oPadding;
|
||||
}
|
||||
|
||||
const NSCSS::NSProperties::CIndent& CStorageTable::GetPadding() const
|
||||
{
|
||||
return m_oStyles.m_oPadding;
|
||||
}
|
||||
|
||||
void CStorageTable::SetMargin(const NSCSS::NSProperties::CIndent& oMargin)
|
||||
{
|
||||
m_oStyles.m_oMargin = oMargin;
|
||||
}
|
||||
|
||||
void CStorageTable::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
|
||||
{
|
||||
m_oStyles.m_oBorder = oBorder;
|
||||
}
|
||||
|
||||
void CStorageTable::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
|
||||
{
|
||||
m_oStyles.m_oWidth = oWidth;
|
||||
}
|
||||
|
||||
void CStorageTable::SetCellSpacing(int nCellSpacing)
|
||||
{
|
||||
m_oStyles.m_nCellSpacing = nCellSpacing;
|
||||
}
|
||||
|
||||
void CStorageTable::SetAlign(const std::wstring& wsValue)
|
||||
{
|
||||
m_oStyles.m_wsAlign = wsValue;
|
||||
}
|
||||
|
||||
void CStorageTable::SetRules(const std::wstring& wsValue)
|
||||
{
|
||||
if (wsValue.empty())
|
||||
return;
|
||||
|
||||
if (NSStringFinder::Equals(wsValue, L"all"))
|
||||
m_oStyles.m_enRules = TTableStyles::ETableRules::All;
|
||||
else if (NSStringFinder::Equals(wsValue, L"groups"))
|
||||
m_oStyles.m_enRules = TTableStyles::ETableRules::Groups;
|
||||
else if (NSStringFinder::Equals(wsValue, L"cols"))
|
||||
m_oStyles.m_enRules = TTableStyles::ETableRules::Cols;
|
||||
else if (NSStringFinder::Equals(wsValue, L"none"))
|
||||
m_oStyles.m_enRules = TTableStyles::ETableRules::None;
|
||||
else if (NSStringFinder::Equals(wsValue, L"rows"))
|
||||
m_oStyles.m_enRules = TTableStyles::ETableRules::Rows;
|
||||
}
|
||||
|
||||
void CStorageTable::AddColgroup(CTableColgroup* pElement)
|
||||
{
|
||||
if (NULL != pElement)
|
||||
m_arColgroups.push_back(pElement);
|
||||
}
|
||||
|
||||
void CStorageTable::RecalculateMaxColumns()
|
||||
{
|
||||
for (const std::vector<CStorageTableRow*>& arHeaders : m_arHeaders)
|
||||
for (const CStorageTableRow* pHeader : arHeaders)
|
||||
m_unMaxColumns = std::max(m_unMaxColumns, pHeader->GetIndex());
|
||||
|
||||
for (const CStorageTableRow* pRow : m_arRows)
|
||||
m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex());
|
||||
|
||||
for (const CStorageTableRow* pFoother : m_arFoother)
|
||||
m_unMaxColumns = std::max(m_unMaxColumns, pFoother->GetIndex());
|
||||
}
|
||||
|
||||
void CStorageTable::Shorten()
|
||||
{
|
||||
UINT unIndex = 0;
|
||||
CStorageTableCell* pCell = NULL;
|
||||
|
||||
UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка
|
||||
|
||||
for (const CStorageTableRow* pRow : m_arRows)
|
||||
{
|
||||
if (1 < pRow->GetCount())
|
||||
unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
|
||||
}
|
||||
|
||||
while (unIndex < m_arMinColspan.size())
|
||||
{
|
||||
for (CStorageTableRow* pRow : m_arRows)
|
||||
{
|
||||
if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex)
|
||||
{
|
||||
pCell = (*pRow)[unIndex];
|
||||
|
||||
if (NULL == pCell)
|
||||
continue;
|
||||
|
||||
pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (1 == m_arMinColspan[unIndex])
|
||||
break;
|
||||
|
||||
pCell = (*pRow)[unIndex];
|
||||
|
||||
if (NULL == pCell)
|
||||
continue;
|
||||
|
||||
if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex])
|
||||
{
|
||||
pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1)
|
||||
(*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE);
|
||||
else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex])
|
||||
(*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
|
||||
}
|
||||
|
||||
++unIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void CStorageTable::CompleteTable()
|
||||
{
|
||||
UINT unMaxIndex = 0;
|
||||
|
||||
for (CStorageTableRow* pRow : m_arRows)
|
||||
unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
|
||||
|
||||
for (CStorageTableRow* pRow : m_arRows)
|
||||
{
|
||||
if (NULL == pRow || 0 == pRow->GetCount())
|
||||
continue;
|
||||
|
||||
for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex)
|
||||
pRow->InsertCell(CStorageTableCell::CreateEmpty(), unIndex);
|
||||
}
|
||||
|
||||
RecalculateMaxColumns();
|
||||
}
|
||||
|
||||
const std::vector<std::vector<CStorageTableRow*>>& CStorageTable::GetHeaders() const
|
||||
{
|
||||
return m_arHeaders;
|
||||
}
|
||||
|
||||
const std::vector<CStorageTableRow*>& CStorageTable::GetFoothers() const
|
||||
{
|
||||
return m_arFoother;
|
||||
}
|
||||
|
||||
const std::vector<CStorageTableRow*>& CStorageTable::GetRows() const
|
||||
{
|
||||
return m_arRows;
|
||||
}
|
||||
|
||||
const std::vector<CTableColgroup*> CStorageTable::GetColgroups() const
|
||||
{
|
||||
return m_arColgroups;
|
||||
}
|
||||
|
||||
UINT CStorageTable::GetMaxColumns() const
|
||||
{
|
||||
return m_unMaxColumns;
|
||||
}
|
||||
|
||||
}
|
||||
255
HtmlFile2/Table.h
Normal file
255
HtmlFile2/Table.h
Normal file
@ -0,0 +1,255 @@
|
||||
#ifndef TABLE_H
|
||||
#define TABLE_H
|
||||
|
||||
#include "../DesktopEditor/common/StringBuilder.h"
|
||||
#include "../Common/3dParty/html/css/src/StyleProperties.h"
|
||||
#include "../Common/3dParty/html/css/src/CNode.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
#define MAXCOLUMNSINTABLE 63
|
||||
#define MAXROWSINTABLE 32767
|
||||
|
||||
enum class ERowParseMode
|
||||
{
|
||||
Header,
|
||||
Body,
|
||||
Foother
|
||||
};
|
||||
|
||||
enum class ERowPosition
|
||||
{
|
||||
First,
|
||||
Middle,
|
||||
Last
|
||||
};
|
||||
|
||||
struct TTableRowStyle
|
||||
{
|
||||
UINT m_unMaxIndex;
|
||||
UINT m_unMaxHeight;
|
||||
bool m_bIsHeader;
|
||||
|
||||
TTableRowStyle();
|
||||
|
||||
bool Empty() const;
|
||||
};
|
||||
|
||||
struct TTableCellStyle
|
||||
{
|
||||
NSCSS::NSProperties::CDigit m_oWidth;
|
||||
NSCSS::NSProperties::CDigit m_oHeight;
|
||||
NSCSS::NSProperties::CBorder m_oBorder;
|
||||
NSCSS::NSProperties::CIndent m_oPadding;
|
||||
NSCSS::NSProperties::CColor m_oBackground;
|
||||
|
||||
std::wstring m_wsHAlign;
|
||||
std::wstring m_wsVAlign;
|
||||
|
||||
TTableCellStyle();
|
||||
|
||||
bool Empty();
|
||||
void Copy(const TTableCellStyle* pTableCellStyle);
|
||||
|
||||
TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle);
|
||||
};
|
||||
|
||||
class CStorageTable;
|
||||
|
||||
class CStorageTableCell
|
||||
{
|
||||
public:
|
||||
CStorageTableCell();
|
||||
CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty);
|
||||
CStorageTableCell(CStorageTableCell& oCell);
|
||||
|
||||
bool Empty() const;
|
||||
bool Merged() const;
|
||||
|
||||
CStorageTableCell* Copy();
|
||||
|
||||
static CStorageTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL);
|
||||
static CStorageTableCell* CreateEmpty(const TTableCellStyle* pStyle);
|
||||
|
||||
void SetColspan(UINT unColspan, UINT unCurrentIndex);
|
||||
UINT GetColspan() const;
|
||||
|
||||
void SetRowspan(UINT unRowspan);
|
||||
UINT GetRowspan() const;
|
||||
|
||||
NSStringUtils::CStringBuilder* GetData();
|
||||
|
||||
const TTableCellStyle* GetStyles() const;
|
||||
TTableCellStyle* GetStyles();
|
||||
|
||||
void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
|
||||
void SetHeight(const NSCSS::NSProperties::CDigit& oHeight);
|
||||
|
||||
UINT GetWidth() const;
|
||||
UINT GetHeight() const;
|
||||
|
||||
void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
|
||||
|
||||
void ClearTopBorder();
|
||||
void ClearLeftBorder();
|
||||
void ClearBottomBorder();
|
||||
void ClearRightBorder();
|
||||
|
||||
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
|
||||
void SetHAlign(const std::wstring& wsAlign);
|
||||
void SetVAlign(const std::wstring& wsAlign);
|
||||
void SetBackground(const NSCSS::NSProperties::CColor& oColor);
|
||||
private:
|
||||
UINT m_unColspan;
|
||||
UINT m_unRowSpan;
|
||||
|
||||
bool m_bIsMerged;
|
||||
bool m_bIsEmpty;
|
||||
|
||||
TTableCellStyle m_oStyles;
|
||||
NSStringUtils::CStringBuilder m_oData;
|
||||
};
|
||||
|
||||
class CStorageTableRow
|
||||
{
|
||||
public:
|
||||
CStorageTableRow();
|
||||
~CStorageTableRow();
|
||||
|
||||
void AddCell(CStorageTableCell* pCell);
|
||||
void InsertCell(CStorageTableCell *pCell, int nPosition);
|
||||
|
||||
UINT GetIndex() const;
|
||||
UINT GetCount() const;
|
||||
|
||||
CStorageTableCell* operator[](UINT unIndex);
|
||||
|
||||
bool Empty() const;
|
||||
const TTableRowStyle& GetStyles() const;
|
||||
const std::vector<CStorageTableCell*>& GetCells() const;
|
||||
private:
|
||||
TTableRowStyle m_oStyles;
|
||||
std::vector<CStorageTableCell*> m_arCells;
|
||||
};
|
||||
|
||||
class CTableCol
|
||||
{
|
||||
public:
|
||||
CTableCol(UINT unSpan);
|
||||
CTableCol(const NSCSS::CNode& oTableColNode);
|
||||
|
||||
UINT GetSpan() const;
|
||||
TTableCellStyle* GetStyle();
|
||||
const TTableCellStyle* GetStyle() const;
|
||||
private:
|
||||
UINT m_unSpan;
|
||||
TTableCellStyle m_oStyle;
|
||||
};
|
||||
|
||||
class CTableColgroup
|
||||
{
|
||||
public:
|
||||
CTableColgroup(NSCSS::CNode& oTableColgroupNode);
|
||||
~CTableColgroup();
|
||||
|
||||
bool Empty() const;
|
||||
|
||||
void AddCol(CTableCol* pCol);
|
||||
|
||||
const std::vector<CTableCol*>& GetCols() const;
|
||||
private:
|
||||
std::vector<CTableCol*> m_arCols;
|
||||
UINT m_unWidth;
|
||||
};
|
||||
|
||||
//Необходимые стили таблицы
|
||||
struct TTableStyles
|
||||
{
|
||||
NSCSS::NSProperties::CIndent m_oPadding;
|
||||
NSCSS::NSProperties::CIndent m_oMargin;
|
||||
NSCSS::NSProperties::CBorder m_oBorder;
|
||||
NSCSS::NSProperties::CDigit m_oWidth;
|
||||
|
||||
int m_nCellSpacing;
|
||||
|
||||
std::wstring m_wsAlign;
|
||||
|
||||
enum ETableRules
|
||||
{
|
||||
All,
|
||||
Groups,
|
||||
Cols,
|
||||
None,
|
||||
Rows
|
||||
} m_enRules;
|
||||
|
||||
TTableStyles();
|
||||
|
||||
bool Empty() const;
|
||||
};
|
||||
|
||||
class CStorageTable
|
||||
{
|
||||
public:
|
||||
CStorageTable();
|
||||
~CStorageTable();
|
||||
|
||||
CStorageTableRow* operator[](UINT unIndex);
|
||||
|
||||
bool Empty() const;
|
||||
bool HaveCaption();
|
||||
bool HaveColgroups() const;
|
||||
bool HaveHeader() const;
|
||||
UINT GetRowCount() const;
|
||||
const TTableStyles& GetTableStyles() const;
|
||||
const TTableCellStyle* GetColStyle(UINT unColumnNumber) const;
|
||||
|
||||
void AddRows(std::vector<CStorageTableRow*>& m_arRows, ERowParseMode eParseMode = ERowParseMode::Body);
|
||||
void AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::Body);
|
||||
|
||||
NSStringUtils::CStringBuilder* GetCaptionData();
|
||||
|
||||
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
|
||||
const NSCSS::NSProperties::CIndent& GetPadding() const;
|
||||
|
||||
void SetMargin(const NSCSS::NSProperties::CIndent& oMargin);
|
||||
void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
|
||||
|
||||
void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
|
||||
void SetCellSpacing(int nCellSpacing);
|
||||
void SetAlign(const std::wstring& wsValue);
|
||||
void SetRules(const std::wstring& wsValue);
|
||||
|
||||
void AddColgroup(CTableColgroup* pElement);
|
||||
|
||||
void RecalculateMaxColumns();
|
||||
void Shorten();
|
||||
void CompleteTable();
|
||||
|
||||
//TODO:: переделать на const std::vector<const T*> Get...() const;
|
||||
const std::vector<std::vector<CStorageTableRow*>>& GetHeaders() const;
|
||||
const std::vector<CStorageTableRow*>& GetFoothers() const;
|
||||
const std::vector<CStorageTableRow*>& GetRows() const;
|
||||
const std::vector<CTableColgroup*> GetColgroups() const;
|
||||
|
||||
UINT GetMaxColumns() const;
|
||||
private:
|
||||
std::vector<std::vector<CStorageTableRow*>> m_arHeaders;
|
||||
std::vector<CStorageTableRow*> m_arFoother;
|
||||
std::vector<CStorageTableRow*> m_arRows;
|
||||
|
||||
std::vector<UINT> m_arMinColspan;
|
||||
|
||||
NSStringUtils::CStringBuilder m_oCaption;
|
||||
|
||||
std::vector<CTableColgroup*> m_arColgroups;
|
||||
|
||||
TTableStyles m_oStyles;
|
||||
|
||||
UINT m_unMaxColumns;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TABLE_H
|
||||
90
HtmlFile2/Tags/HTMLTags.h
Normal file
90
HtmlFile2/Tags/HTMLTags.h
Normal file
@ -0,0 +1,90 @@
|
||||
#ifndef HTMLTAGS_H
|
||||
#define HTMLTAGS_H
|
||||
|
||||
#include "../Common/3dParty/html/css/src/CNode.h"
|
||||
#include <boost/any.hpp>
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
class ITag
|
||||
{
|
||||
public:
|
||||
virtual ~ITag() = default;
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) = 0;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
|
||||
};
|
||||
|
||||
class CEmptyTag : public ITag
|
||||
{
|
||||
public:
|
||||
virtual ~CEmptyTag() = default;
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any())
|
||||
{
|
||||
return true;
|
||||
};
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) {};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class CTag : public ITag
|
||||
{
|
||||
protected:
|
||||
T* m_pWriter;
|
||||
public:
|
||||
CTag(T* pWriter)
|
||||
: m_pWriter(pWriter)
|
||||
{}
|
||||
virtual ~CTag() = default;
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) = 0;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
|
||||
|
||||
bool ValidWriter() const
|
||||
{
|
||||
return nullptr != m_pWriter;
|
||||
}
|
||||
};
|
||||
|
||||
#define CREATE_TAG(tag_name)\
|
||||
template<class T>\
|
||||
class tag_name : public CTag<T>\
|
||||
{\
|
||||
public:\
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) = 0;\
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;\
|
||||
}
|
||||
|
||||
CREATE_TAG(CAnchor);
|
||||
CREATE_TAG(CAbbr);
|
||||
CREATE_TAG(CBold);
|
||||
CREATE_TAG(CBidirectional);
|
||||
CREATE_TAG(CBreak);
|
||||
CREATE_TAG(CCenter);
|
||||
CREATE_TAG(CItalic);
|
||||
CREATE_TAG(CKbd);
|
||||
CREATE_TAG(CStrike);
|
||||
CREATE_TAG(CUnderline);
|
||||
CREATE_TAG(CMark);
|
||||
CREATE_TAG(CQuotation);
|
||||
CREATE_TAG(CSup);
|
||||
CREATE_TAG(CSpan);
|
||||
CREATE_TAG(CDD);
|
||||
CREATE_TAG(CPreformatted);
|
||||
CREATE_TAG(CHeader);
|
||||
CREATE_TAG(CDivision);
|
||||
CREATE_TAG(CImage);
|
||||
CREATE_TAG(CFont);
|
||||
CREATE_TAG(CInput);
|
||||
CREATE_TAG(CBaseFont);
|
||||
CREATE_TAG(CBlockquote);
|
||||
CREATE_TAG(CHorizontalRule);
|
||||
CREATE_TAG(CList);
|
||||
CREATE_TAG(CListElement);
|
||||
CREATE_TAG(CCaption);
|
||||
CREATE_TAG(CTable);
|
||||
CREATE_TAG(CTableRow);
|
||||
CREATE_TAG(CTableCell);
|
||||
CREATE_TAG(CCode);
|
||||
CREATE_TAG(CHTML);
|
||||
|
||||
}
|
||||
#endif // HTMLTAGS_H
|
||||
520
HtmlFile2/Tags/MDTags.cpp
Normal file
520
HtmlFile2/Tags/MDTags.cpp
Normal file
@ -0,0 +1,520 @@
|
||||
#include "MDTags.h"
|
||||
|
||||
#include "../src/StringFinder.h"
|
||||
#include "../Table.h"
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
CAnchor<CMDWriter>::CAnchor(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CAnchor<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteString(L"[");
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAnchor<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteString(L"]");
|
||||
|
||||
std::wstring wsHref, wsTitle;
|
||||
|
||||
arSelectors.back().GetAttributeValue(L"href", wsHref);
|
||||
arSelectors.back().GetAttributeValue(L"title", wsTitle);
|
||||
|
||||
m_pWriter->WriteString(L'(' + wsHref);
|
||||
|
||||
if (!wsTitle.empty())
|
||||
m_pWriter->WriteString(L" \"" + wsTitle + L'"');
|
||||
|
||||
m_pWriter->WriteString(L")");
|
||||
}
|
||||
|
||||
CBold<CMDWriter>::CBold(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CBold<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
if (m_pWriter->IsBold())
|
||||
return true;
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"**");
|
||||
m_pWriter->EnteredBold();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBold<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter() || !m_pWriter->IsBold())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteCloseSpecialString(L"**");
|
||||
m_pWriter->OutBold();
|
||||
}
|
||||
|
||||
CBreak<CMDWriter>::CBreak(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CBreak<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteBreakLine();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBreak<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
CItalic<CMDWriter>::CItalic(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CItalic<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
if (m_pWriter->IsItalic())
|
||||
return true;
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"*");
|
||||
m_pWriter->EnteredItalic();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CItalic<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter() || !m_pWriter->IsItalic())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteCloseSpecialString(L"*");
|
||||
m_pWriter->OutItalic();
|
||||
}
|
||||
|
||||
CStrike<CMDWriter>::CStrike(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CStrike<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
if (m_pWriter->IsStrike())
|
||||
return true;
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"~~");
|
||||
m_pWriter->EnteredStrike();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CStrike<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter() || !m_pWriter->IsStrike())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteCloseSpecialString(L"~~");
|
||||
m_pWriter->OutStrike();
|
||||
}
|
||||
|
||||
CQuotation<CMDWriter>::CQuotation(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CQuotation<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CQuotation<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
CPreformatted<CMDWriter>::CPreformatted(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CPreformatted<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"```");
|
||||
m_pWriter->EnteredPreformatted();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPreformatted<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
bool bNeedBreakLine{false};
|
||||
|
||||
for (std::vector<NSCSS::CNode>::const_reverse_iterator itElement{arSelectors.crbegin()}; itElement < arSelectors.crend(); ++itElement)
|
||||
{
|
||||
if (L"pre" == itElement->m_wsName)
|
||||
{
|
||||
bNeedBreakLine = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bNeedBreakLine && !m_pWriter->InTable())
|
||||
m_pWriter->WriteBreakLine();
|
||||
|
||||
m_pWriter->WriteCloseSpecialString(L"```");
|
||||
m_pWriter->OutPreformatted();
|
||||
|
||||
if (bNeedBreakLine && !m_pWriter->InTable())
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
}
|
||||
|
||||
CHeader<CMDWriter>::CHeader(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CHeader<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
switch(arSelectors.back().m_wsName[1])
|
||||
{
|
||||
case L'1' : m_pWriter->WriteString(L"# ", true); break;
|
||||
case L'2' : m_pWriter->WriteString(L"## ", true); break;
|
||||
case L'3' : m_pWriter->WriteString(L"### ", true); break;
|
||||
case L'4' : m_pWriter->WriteString(L"#### ", true); break;
|
||||
case L'5' : m_pWriter->WriteString(L"##### ", true); break;
|
||||
case L'6' : m_pWriter->WriteString(L"###### ", true); break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHeader<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
}
|
||||
|
||||
CImage<CMDWriter>::CImage(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CImage<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
std::wstring wsAlt, wsSrc, wsTitle;
|
||||
|
||||
if (!arSelectors.back().GetAttributeValue(L"src", wsSrc) &&
|
||||
!arSelectors.back().GetAttributeValue(L"alt", wsAlt))
|
||||
return false;
|
||||
|
||||
arSelectors.back().GetAttributeValue(L"title", wsTitle);
|
||||
|
||||
m_pWriter->WriteString(L";
|
||||
|
||||
if (!wsTitle.empty())
|
||||
m_pWriter->WriteString(L" \"" + wsTitle + L'"');
|
||||
|
||||
m_pWriter->WriteString(L")");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CImage<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteBreakLine();
|
||||
}
|
||||
|
||||
CHorizontalRule<CMDWriter>::CHorizontalRule(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CHorizontalRule<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
m_pWriter->WriteString(L"---");
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CHorizontalRule<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
CBlockquote<CMDWriter>::CBlockquote(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CBlockquote<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_pWriter->EnteredBlockquote();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBlockquote<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->OutBlockquote();
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
}
|
||||
|
||||
CTable<CMDWriter>::CTable(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CTable<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter() /*|| m_pWriter->InTable()*/) //В MD не поддерживаются вложенные таблицы (пока разруливаем в парсере)
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_pWriter->EnteredTable();
|
||||
|
||||
if (m_pWriter->InCode())
|
||||
{
|
||||
if (!m_pWriter->InPreformatted())
|
||||
m_pWriter->WriteCloseSpecialString(L"`");
|
||||
|
||||
m_pWriter->OutCode();
|
||||
}
|
||||
|
||||
if (m_pWriter->InPreformatted())
|
||||
{
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_pWriter->WriteCloseSpecialString(L"```");
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
m_pWriter->OutPreformatted();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTable<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->OutTable();
|
||||
m_pWriter->WriteBreakLine();
|
||||
}
|
||||
|
||||
CTableRow<CMDWriter>::CTableRow(CMDWriter* pWriter)
|
||||
: CTag(pWriter), m_unLastRowType(static_cast<UINT>(ERowParseMode::Foother))
|
||||
{}
|
||||
|
||||
bool CTableRow<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
using DataForRow = boost::tuple<const TTableRowStyle*, const CStorageTable&, ERowParseMode, ERowPosition>;
|
||||
|
||||
if (!ValidWriter() || oExtraData.empty() || typeid(DataForRow) != oExtraData.type())
|
||||
return false;
|
||||
|
||||
m_pWriter->EnteredTable();
|
||||
|
||||
const DataForRow& oDataForRow(boost::any_cast<DataForRow>(oExtraData));
|
||||
const CStorageTable& oStorageTable{boost::get<1>(oDataForRow)};
|
||||
|
||||
if (nullptr == boost::get<0>(oDataForRow) && ERowParseMode::Header == boost::get<2>(oDataForRow))
|
||||
{
|
||||
for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
|
||||
m_pWriter->WriteOpenSpecialString(L"| ");
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"|");
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_unLastRowType = static_cast<UINT>(ERowParseMode::Header);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_unLastRowType == static_cast<UINT>(ERowParseMode::Header))
|
||||
{
|
||||
for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
|
||||
m_pWriter->WriteString(L"|-");
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"|");
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
}
|
||||
|
||||
m_pWriter->WriteOpenSpecialString(L"| ");
|
||||
m_unLastRowType = static_cast<UINT>(boost::get<2>(oDataForRow));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTableRow<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
}
|
||||
|
||||
CTableCell<CMDWriter>::CTableCell(CMDWriter* pWriter)
|
||||
: CTag(pWriter), m_unNeedEmptyCells(0)
|
||||
{}
|
||||
|
||||
bool CTableCell<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
using DataForCell = boost::tuple<const CStorageTableCell&, const CStorageTable&, UINT, ERowParseMode, ERowPosition>;
|
||||
|
||||
if (!ValidWriter() || oExtraData.empty() || typeid(DataForCell) != oExtraData.type())
|
||||
return false;
|
||||
|
||||
const DataForCell& oDataForCell{boost::any_cast<const DataForCell>(oExtraData)};
|
||||
|
||||
m_unNeedEmptyCells = boost::get<0>(oDataForCell).GetColspan() - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CTableCell<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
for (UINT unIndex = 0; unIndex < m_unNeedEmptyCells; ++unIndex)
|
||||
m_pWriter->WriteOpenSpecialString(L" |");
|
||||
|
||||
m_unNeedEmptyCells = 0;
|
||||
m_pWriter->WriteOpenSpecialString(L" | ");
|
||||
}
|
||||
|
||||
CList<CMDWriter>::CList(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CList<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->WriteBreakLine();
|
||||
m_pWriter->EnteredList(L"ol" == arSelectors.back().m_wsName);
|
||||
|
||||
if (!m_pWriter->InOrederedList())
|
||||
return true;
|
||||
|
||||
std::wstring wsIndex;
|
||||
|
||||
if (arSelectors.back().GetAttributeValue(L"start", wsIndex))
|
||||
m_pWriter->SetIndexOrderedList(NSStringFinder::ToInt(wsIndex, 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CList<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
m_pWriter->OutList();
|
||||
}
|
||||
|
||||
CListElement<CMDWriter>::CListElement(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CListElement<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
if (0 != m_pWriter->GetLevelList())
|
||||
{
|
||||
for (UINT unLevelList = 0; unLevelList < m_pWriter->GetLevelList() - 1; ++unLevelList)
|
||||
m_pWriter->WriteString(L" ");
|
||||
}
|
||||
|
||||
if (m_pWriter->InOrederedList())
|
||||
{
|
||||
m_pWriter->WriteString(std::to_wstring(m_pWriter->GetIndexOrderedList()) + m_pWriter->GetParametrs().m_wchOrderedList + L' ');
|
||||
m_pWriter->IncreaseIndexOrderedList();
|
||||
}
|
||||
else
|
||||
m_pWriter->WriteString({m_pWriter->GetParametrs().m_wchUnorderedList, L' '});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CListElement<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{}
|
||||
|
||||
CCode<CMDWriter>::CCode(CMDWriter* pWriter)
|
||||
: CTag(pWriter)
|
||||
{}
|
||||
|
||||
bool CCode<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return false;
|
||||
|
||||
m_pWriter->EnteredCode();
|
||||
|
||||
if (m_pWriter->InPreformatted())
|
||||
{
|
||||
if (!arSelectors.back().m_wsClass.empty() && arSelectors.back().m_wsClass.size() >= 9 &&
|
||||
0 == arSelectors.back().m_wsClass.compare(0, 9, L"language-"))
|
||||
m_pWriter->WriteString(arSelectors.back().m_wsClass.substr(9, arSelectors.back().m_wsClass.size() - 9));
|
||||
m_pWriter->WriteBreakLine(false);
|
||||
}
|
||||
else
|
||||
m_pWriter->WriteOpenSpecialString(L"`");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCode<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
if (!ValidWriter())
|
||||
return;
|
||||
|
||||
if (!m_pWriter->InPreformatted())
|
||||
m_pWriter->WriteCloseSpecialString(L"`");
|
||||
|
||||
m_pWriter->OutCode();
|
||||
}
|
||||
}
|
||||
165
HtmlFile2/Tags/MDTags.h
Normal file
165
HtmlFile2/Tags/MDTags.h
Normal file
@ -0,0 +1,165 @@
|
||||
#ifndef MDTAGS_H
|
||||
#define MDTAGS_H
|
||||
|
||||
#include "HTMLTags.h"
|
||||
#include "../Writers/MDWriter.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
template<>
|
||||
class CAnchor<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CAnchor(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBold<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CBold(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBreak<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CBreak(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CItalic<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CItalic(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CStrike<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CStrike(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CQuotation<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CQuotation(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CPreformatted<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CPreformatted(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CHeader<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CHeader(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CImage<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CImage(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CHorizontalRule<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CHorizontalRule(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBlockquote<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CBlockquote(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTable<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CTable(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTableRow<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
UINT m_unLastRowType;
|
||||
public:
|
||||
CTableRow(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTableCell<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
UINT m_unNeedEmptyCells;
|
||||
public:
|
||||
CTableCell(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CList<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CList(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CListElement<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CListElement(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CCode<CMDWriter> : public CTag<CMDWriter>
|
||||
{
|
||||
public:
|
||||
CCode(CMDWriter* pWriter);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MDTAGS_H
|
||||
1492
HtmlFile2/Tags/OOXMLTags.cpp
Normal file
1492
HtmlFile2/Tags/OOXMLTags.cpp
Normal file
File diff suppressed because it is too large
Load Diff
167
HtmlFile2/Tags/OOXMLTags.h
Normal file
167
HtmlFile2/Tags/OOXMLTags.h
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef OOXMLTAGS_H
|
||||
#define OOXMLTAGS_H
|
||||
|
||||
#include "HTMLTags.h"
|
||||
#include "../Writers/OOXMLWriter.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
template<>
|
||||
class CAnchor<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CAnchor(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CAbbr<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CAbbr(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBreak<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CBreak(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CDivision<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
std::stack<UINT> m_arFootnoteIDs;
|
||||
public:
|
||||
CDivision(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CImage<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
std::vector<std::wstring> m_arrImages;
|
||||
public:
|
||||
CImage(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CFont<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CFont(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CInput<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CInput(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBaseFont<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CBaseFont(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CBlockquote<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
std::map<std::wstring, UINT> m_mDivs;
|
||||
public:
|
||||
CBlockquote(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CHorizontalRule<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
UINT m_unShapeId;
|
||||
public:
|
||||
CHorizontalRule(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CList<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CList(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CListElement<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CListElement(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CCaption<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CCaption(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTable<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CTable(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTableRow<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CTableRow(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CTableCell<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CTableCell(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
|
||||
template<>
|
||||
class CHTML<COOXMLWriter> : public CTag<COOXMLWriter>
|
||||
{
|
||||
public:
|
||||
CHTML(COOXMLWriter* pInterpretator);
|
||||
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
|
||||
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OOXMLTAGS_H
|
||||
37
HtmlFile2/Writers/IWriter.h
Normal file
37
HtmlFile2/Writers/IWriter.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef IWRITER_H
|
||||
#define IWRITER_H
|
||||
|
||||
#include "../../Common/3dParty/html/css/src/CNode.h"
|
||||
#include "../Common.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
class IWriter
|
||||
{
|
||||
public:
|
||||
IWriter() = default;
|
||||
virtual ~IWriter() = default;
|
||||
|
||||
virtual void Begin(const std::wstring& wsDst) = 0;
|
||||
virtual void End(const std::wstring& wsDst) = 0;
|
||||
|
||||
virtual bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) = 0;
|
||||
|
||||
virtual void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) = 0;
|
||||
|
||||
virtual void PageBreak() = 0;
|
||||
|
||||
virtual void BeginBlock() = 0;
|
||||
virtual void EndBlock(bool bAddBlock) = 0;
|
||||
|
||||
virtual void SetDataOutput(XmlString* pOutputData) = 0; // Задаем место вывода для интерпретатора
|
||||
virtual void RevertDataOutput() = 0; // Возвращаем место вывода к исходному
|
||||
|
||||
virtual XmlString* GetCurrentDocument() const = 0;
|
||||
|
||||
//TODO:: перенести разруливание вложенных таблиц в конвертацию после изменения принципа работы с таблицами
|
||||
virtual bool SupportNestedTables() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // IWRITER_H
|
||||
408
HtmlFile2/Writers/MDWriter.cpp
Normal file
408
HtmlFile2/Writers/MDWriter.cpp
Normal file
@ -0,0 +1,408 @@
|
||||
#include "MDWriter.h"
|
||||
|
||||
#include <cwctype>
|
||||
|
||||
#include "../../DesktopEditor/common/File.h"
|
||||
#include "../../Common/3dParty/html/css/src/CCompiledStyle.h"
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
CMDWriter::CMDWriter(const TMarkdownParameters& oMDParametrs)
|
||||
: m_oMDParametrs(oMDParametrs)
|
||||
{
|
||||
m_arStates.push(TState{});
|
||||
m_arStates.top().m_pCurrentDocument = &m_oDocument;
|
||||
}
|
||||
|
||||
void CMDWriter::Begin(const std::wstring& wsDst)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CMDWriter::End(const std::wstring& wsDst)
|
||||
{
|
||||
NSFile::CFileBinary oDocument;
|
||||
|
||||
if (!oDocument.CreateFileW(wsDst))
|
||||
return;
|
||||
|
||||
oDocument.WriteStringUTF8(m_oDocument.GetData());
|
||||
oDocument.CloseFile();
|
||||
}
|
||||
|
||||
inline void ReplaceSpaces(std::wstring& wsValue)
|
||||
{
|
||||
// boost::wregex oRegex(L"\\s+");
|
||||
// wsValue = boost::regex_replace(wsValue, oRegex, L" ");
|
||||
|
||||
std::wstring::const_iterator itBegin = std::find_if(wsValue.cbegin(), wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
|
||||
std::wstring::const_iterator itEnd;
|
||||
|
||||
while (wsValue.cend() != itBegin)
|
||||
{
|
||||
itEnd = std::find_if(itBegin, wsValue.cend(), [](wchar_t wchValue){ return !std::iswspace(wchValue) || 0xa0 == wchValue; });
|
||||
|
||||
wsValue.replace(itBegin, itEnd, L" ");
|
||||
|
||||
itBegin = std::find_if(itBegin + 1, wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
|
||||
}
|
||||
}
|
||||
|
||||
bool CMDWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors)
|
||||
{
|
||||
bool bPreformatted{InPreformatted()};
|
||||
|
||||
const NSCSS::CCompiledStyle* pCompiledStyle{arSelectors.back().m_pCompiledStyle};
|
||||
|
||||
if (!bPreformatted && nullptr != pCompiledStyle)
|
||||
{
|
||||
// TODO::поведение должно быть немного разное (реализовать)
|
||||
switch(pCompiledStyle->m_oDisplay.GetWhiteSpace().ToInt())
|
||||
{
|
||||
case NSCSS::NSProperties::EWhiteSpace::Pre:
|
||||
case NSCSS::NSProperties::EWhiteSpace::Pre_Wrap:
|
||||
case NSCSS::NSProperties::EWhiteSpace::Pre_Line:
|
||||
bPreformatted = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bPreformatted && wsText.end() == std::find_if_not(wsText.begin(), wsText.end(), [](wchar_t wchChar){ return iswspace(wchChar) && 0xa0 != wchChar;}))
|
||||
return false;
|
||||
|
||||
if (bPreformatted && !m_arStates.top().m_bEmptyLine && !m_arStates.top().m_bInTable)
|
||||
{
|
||||
for (std::vector<NSCSS::CNode>::const_reverse_iterator itElement{arSelectors.crbegin()}; itElement < arSelectors.crend(); ++itElement)
|
||||
{
|
||||
if (L"pre" == itElement->m_wsName)
|
||||
{
|
||||
GetCurrentDocument()->AddCharSafe(L'\n');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Пока корректно работает только для текста (необходимо проверить и с другими нодами)
|
||||
if (m_arStates.top().m_bEmptyLine)
|
||||
{
|
||||
for (UINT unIndex = 0; unIndex < GetLevelBlockquote(); ++unIndex)
|
||||
WriteString(L"> ", true);
|
||||
}
|
||||
|
||||
if (!bPreformatted && !InCode())
|
||||
ReplaceSpaces(wsText);
|
||||
|
||||
bool bNeedBold{false}, bNeedItalic{false}, bNeedStrike{false};
|
||||
|
||||
if (nullptr != pCompiledStyle)
|
||||
{
|
||||
if (!IsBold() && pCompiledStyle->m_oFont.Bold())
|
||||
bNeedBold = true;
|
||||
|
||||
if (!IsItalic() && pCompiledStyle->m_oFont.Italic())
|
||||
bNeedItalic = true;
|
||||
|
||||
if (!IsStrike() && pCompiledStyle->m_oText.LineThrough())
|
||||
bNeedStrike = true;
|
||||
}
|
||||
|
||||
if (bNeedBold)
|
||||
WriteString(L"**");
|
||||
|
||||
if (bNeedItalic)
|
||||
WriteString(L"*");
|
||||
|
||||
if (bNeedStrike)
|
||||
WriteString(L"~~");
|
||||
|
||||
ApplyAlternativeTags(pCompiledStyle);
|
||||
WriteString(wsText);
|
||||
ApplyAlternativeTags(pCompiledStyle, true);
|
||||
|
||||
if (bNeedBold)
|
||||
WriteString(L"**");
|
||||
|
||||
if (bNeedItalic)
|
||||
WriteString(L"*");
|
||||
|
||||
if (bNeedStrike)
|
||||
WriteString(L"~~");
|
||||
|
||||
if (L'\n' == wsText.back())
|
||||
m_arStates.top().m_bNeedBreakLine = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMDWriter::WriteEmptyParagraph(bool bVahish, bool bInP)
|
||||
{}
|
||||
|
||||
void CMDWriter::PageBreak()
|
||||
{}
|
||||
|
||||
void CMDWriter::BeginBlock()
|
||||
{
|
||||
if (!m_arStates.top().m_bInList)
|
||||
WriteBreakLine();
|
||||
}
|
||||
|
||||
void CMDWriter::EndBlock(bool bAddBlock)
|
||||
{
|
||||
if (!m_arStates.top().m_bInTable)
|
||||
WriteBreakLine();
|
||||
}
|
||||
|
||||
void CMDWriter::SetDataOutput(XmlString* pOutputData)
|
||||
{
|
||||
SaveState();
|
||||
m_arStates.top().m_pCurrentDocument = pOutputData;
|
||||
}
|
||||
|
||||
void CMDWriter::RevertDataOutput()
|
||||
{
|
||||
RollBackState();
|
||||
}
|
||||
|
||||
TMarkdownParameters CMDWriter::GetParametrs() const
|
||||
{
|
||||
return m_oMDParametrs;
|
||||
}
|
||||
|
||||
void CMDWriter::WriteString(const std::wstring& wsString, bool bSpecialString)
|
||||
{
|
||||
GetCurrentDocument()->WriteString(wsString);
|
||||
|
||||
if (m_arStates.top().m_bEmptyLine)
|
||||
m_arStates.top().m_bEmptyLine = wsString.empty();
|
||||
|
||||
if (!bSpecialString)
|
||||
m_arStates.top().m_bNeedBreakLine = true;
|
||||
}
|
||||
|
||||
void CMDWriter::WriteOpenSpecialString(const std::wstring& wsString)
|
||||
{
|
||||
if (m_arStates.top().m_wsLastSpecialString == wsString)
|
||||
GetCurrentDocument()->WriteString(L" ");
|
||||
|
||||
m_arStates.top().m_wsLastSpecialString.clear();
|
||||
|
||||
WriteString(wsString, true);
|
||||
}
|
||||
|
||||
void CMDWriter::WriteCloseSpecialString(const std::wstring& wsString)
|
||||
{
|
||||
m_arStates.top().m_wsLastSpecialString = wsString;
|
||||
|
||||
WriteString(wsString, true);
|
||||
}
|
||||
|
||||
XmlString* CMDWriter::GetCurrentDocument() const
|
||||
{
|
||||
return m_arStates.top().m_pCurrentDocument;
|
||||
}
|
||||
|
||||
bool CMDWriter::SupportNestedTables() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMDWriter::WriteBreakLine(bool bNeedChecked)
|
||||
{
|
||||
if (bNeedChecked && !m_arStates.top().m_bNeedBreakLine)
|
||||
return;
|
||||
|
||||
if (m_arStates.top().m_bInTable && bNeedChecked)
|
||||
{
|
||||
if (m_oMDParametrs.m_bUseAlternativeHTMLTags)
|
||||
WriteString(L"</br>");
|
||||
|
||||
m_arStates.top().m_bNeedBreakLine = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_arStates.top().m_bEmptyLine)
|
||||
{
|
||||
for (UINT unIndex = 0; unIndex < GetLevelBlockquote(); ++unIndex)
|
||||
WriteString(L"> ", true);
|
||||
}
|
||||
|
||||
GetCurrentDocument()->WriteString(L" \n");
|
||||
|
||||
m_arStates.top().m_bEmptyLine = true;
|
||||
m_arStates.top().m_bNeedBreakLine = false;
|
||||
m_arStates.top().m_wsLastSpecialString.clear();
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredBold()
|
||||
{
|
||||
m_arStates.top().m_bBold = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutBold()
|
||||
{
|
||||
m_arStates.top().m_bBold = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::IsBold()
|
||||
{
|
||||
return m_arStates.top().m_bBold;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredItalic()
|
||||
{
|
||||
m_arStates.top().m_bItalic = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutItalic()
|
||||
{
|
||||
m_arStates.top().m_bItalic = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::IsItalic()
|
||||
{
|
||||
return m_arStates.top().m_bItalic;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredStrike()
|
||||
{
|
||||
m_arStates.top().m_bStrike = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutStrike()
|
||||
{
|
||||
m_arStates.top().m_bStrike = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::IsStrike()
|
||||
{
|
||||
return m_arStates.top().m_bStrike;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredBlockquote()
|
||||
{
|
||||
m_arStates.top().m_unLevelBlockquote++;
|
||||
}
|
||||
|
||||
void CMDWriter::OutBlockquote()
|
||||
{
|
||||
if (m_arStates.top().m_unLevelBlockquote > 0)
|
||||
m_arStates.top().m_unLevelBlockquote--;
|
||||
}
|
||||
|
||||
UINT CMDWriter::GetLevelBlockquote()
|
||||
{
|
||||
return m_arStates.top().m_unLevelBlockquote;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredTable()
|
||||
{
|
||||
m_arStates.top().m_bInTable = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutTable()
|
||||
{
|
||||
m_arStates.top().m_bInTable = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::InTable() const
|
||||
{
|
||||
return m_arStates.top().m_bInTable;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredPreformatted()
|
||||
{
|
||||
m_arStates.top().m_bInPreformatted = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutPreformatted()
|
||||
{
|
||||
m_arStates.top().m_bInPreformatted = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::InPreformatted() const
|
||||
{
|
||||
return m_arStates.top().m_bInPreformatted;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredCode()
|
||||
{
|
||||
m_arStates.top().m_bInCode = true;
|
||||
}
|
||||
|
||||
void CMDWriter::OutCode()
|
||||
{
|
||||
m_arStates.top().m_bInCode = false;
|
||||
}
|
||||
|
||||
bool CMDWriter::InCode() const
|
||||
{
|
||||
return m_arStates.top().m_bInCode;
|
||||
}
|
||||
|
||||
void CMDWriter::EnteredList(bool bOrderedList)
|
||||
{
|
||||
SaveState();
|
||||
m_arStates.top().m_bInList = true;
|
||||
m_arStates.top().m_bIsOrederedList = bOrderedList;
|
||||
m_arStates.top().m_unLevelList++;
|
||||
}
|
||||
|
||||
void CMDWriter::OutList()
|
||||
{
|
||||
RollBackState();
|
||||
}
|
||||
|
||||
void CMDWriter::SetIndexOrderedList(UINT unIndex)
|
||||
{
|
||||
m_arStates.top().m_unIndexListElement = unIndex;
|
||||
}
|
||||
|
||||
void CMDWriter::IncreaseIndexOrderedList()
|
||||
{
|
||||
m_arStates.top().m_unIndexListElement++;
|
||||
}
|
||||
|
||||
bool CMDWriter::InOrederedList() const
|
||||
{
|
||||
return m_arStates.top().m_bIsOrederedList;
|
||||
}
|
||||
|
||||
UINT CMDWriter::GetIndexOrderedList() const
|
||||
{
|
||||
return m_arStates.top().m_unIndexListElement;
|
||||
}
|
||||
|
||||
UINT CMDWriter::GetLevelList() const
|
||||
{
|
||||
return m_arStates.top().m_unLevelList;
|
||||
}
|
||||
|
||||
void CMDWriter::SaveState()
|
||||
{
|
||||
m_arStates.push(m_arStates.top());
|
||||
}
|
||||
|
||||
void CMDWriter::RollBackState()
|
||||
{
|
||||
if (m_arStates.size() > 1)
|
||||
m_arStates.pop();
|
||||
}
|
||||
|
||||
void CMDWriter::ApplyAlternativeTags(const NSCSS::CCompiledStyle* pCompiledStyle, bool bIsCloseTag)
|
||||
{
|
||||
if (nullptr == pCompiledStyle || !m_oMDParametrs.m_bUseAlternativeHTMLTags)
|
||||
return;
|
||||
|
||||
if (pCompiledStyle->m_oText.Underline())
|
||||
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</u>" : L"<u>");
|
||||
|
||||
if (L"top" == pCompiledStyle->m_oDisplay.GetVAlign().ToWString())
|
||||
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</sup>" : L"<sup>");
|
||||
else if (L"bottom" == pCompiledStyle->m_oDisplay.GetVAlign().ToWString())
|
||||
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</sub>" : L"<sub>");
|
||||
|
||||
if (L"FFFF00" == pCompiledStyle->m_oBackground.GetColor().ToHEX())
|
||||
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</mark>" : L"<mark>");
|
||||
}
|
||||
}
|
||||
119
HtmlFile2/Writers/MDWriter.h
Normal file
119
HtmlFile2/Writers/MDWriter.h
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef MDWRITER_H
|
||||
#define MDWRITER_H
|
||||
|
||||
#include "IWriter.h"
|
||||
#include "../MarkdownParameters.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
class CMDWriter : public IWriter
|
||||
{
|
||||
XmlString m_oDocument;
|
||||
|
||||
struct TState
|
||||
{
|
||||
XmlString *m_pCurrentDocument{nullptr};
|
||||
|
||||
bool m_bNeedBreakLine{false};
|
||||
bool m_bEmptyLine{true};
|
||||
|
||||
UINT m_unLevelBlockquote{0};
|
||||
|
||||
bool m_bBold{false};
|
||||
bool m_bItalic{false};
|
||||
bool m_bStrike{false};
|
||||
|
||||
bool m_bInTable{false};
|
||||
bool m_bInPreformatted{false};
|
||||
bool m_bInCode{false};
|
||||
|
||||
bool m_bInList{false};
|
||||
bool m_bIsOrederedList{false};
|
||||
UINT m_unLevelList{0};
|
||||
UINT m_unIndexListElement{1};
|
||||
|
||||
std::wstring m_wsLastSpecialString;
|
||||
};
|
||||
|
||||
std::stack<TState> m_arStates;
|
||||
TMarkdownParameters m_oMDParametrs;
|
||||
public:
|
||||
CMDWriter(const TMarkdownParameters& oMDParametrs);
|
||||
|
||||
void Begin(const std::wstring& wsDst) override;
|
||||
void End(const std::wstring& wsDst) override;
|
||||
|
||||
bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
|
||||
void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) override;
|
||||
|
||||
void PageBreak() override;
|
||||
|
||||
void BeginBlock() override;
|
||||
void EndBlock(bool bAddBlock) override;
|
||||
|
||||
void SetDataOutput(XmlString* pOutputData) override;
|
||||
void RevertDataOutput() override;
|
||||
|
||||
TMarkdownParameters GetParametrs() const;
|
||||
|
||||
void WriteString(const std::wstring& wsString, bool bSpecialString = false);
|
||||
void WriteOpenSpecialString(const std::wstring& wsString);
|
||||
void WriteCloseSpecialString(const std::wstring& wsString);
|
||||
|
||||
XmlString* GetCurrentDocument() const override;
|
||||
|
||||
bool SupportNestedTables() const override;
|
||||
|
||||
void WriteBreakLine(bool bNeedChecked = true);
|
||||
|
||||
void EnteredBold();
|
||||
void OutBold();
|
||||
bool IsBold();
|
||||
|
||||
void EnteredItalic();
|
||||
void OutItalic();
|
||||
bool IsItalic();
|
||||
|
||||
void EnteredStrike();
|
||||
void OutStrike();
|
||||
bool IsStrike();
|
||||
|
||||
void EnteredBlockquote();
|
||||
void OutBlockquote();
|
||||
UINT GetLevelBlockquote();
|
||||
|
||||
void EnteredTable();
|
||||
void OutTable();
|
||||
bool InTable() const;
|
||||
|
||||
void EnteredPreformatted();
|
||||
void OutPreformatted();
|
||||
bool InPreformatted() const;
|
||||
|
||||
void EnteredCode();
|
||||
void OutCode();
|
||||
bool InCode() const;
|
||||
|
||||
void EnteredList(bool bOrderedList);
|
||||
void OutList();
|
||||
void SetIndexOrderedList(UINT unIndex);
|
||||
void IncreaseIndexOrderedList();
|
||||
|
||||
bool InOrederedList() const;
|
||||
UINT GetIndexOrderedList() const;
|
||||
UINT GetLevelList() const;
|
||||
|
||||
void SetLinePrefix(const std::wstring& wsPrefix);
|
||||
void ClearLinePrefix();
|
||||
private:
|
||||
void SaveState();
|
||||
void RollBackState();
|
||||
|
||||
void ApplyAlternativeTags(const NSCSS::CCompiledStyle* pCompiledStyle, bool bIsCloseTag = false);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MDWRITER_H
|
||||
1494
HtmlFile2/Writers/OOXMLWriter.cpp
Normal file
1494
HtmlFile2/Writers/OOXMLWriter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
216
HtmlFile2/Writers/OOXMLWriter.h
Normal file
216
HtmlFile2/Writers/OOXMLWriter.h
Normal file
@ -0,0 +1,216 @@
|
||||
#ifndef OOXMLWRITER_H
|
||||
#define OOXMLWRITER_H
|
||||
|
||||
#include "../../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h"
|
||||
#include "../../Common/3dParty/html/css/src/CCssCalculator.h"
|
||||
#include "../HTMLParameters.h"
|
||||
#include "IWriter.h"
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace NSFonts { class IApplicationFonts; }
|
||||
|
||||
namespace HTML
|
||||
{
|
||||
struct TImageData
|
||||
{
|
||||
UINT m_unWidth;
|
||||
UINT m_unHeight;
|
||||
|
||||
int m_nHSpace;
|
||||
int m_nVSpace;
|
||||
|
||||
std::wstring m_wsAlign;
|
||||
|
||||
TImageData()
|
||||
: m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left")
|
||||
{}
|
||||
|
||||
bool ZeroSize() const
|
||||
{
|
||||
return 0 == m_unWidth || 0 == m_unHeight;
|
||||
}
|
||||
|
||||
bool ZeroSpaces() const
|
||||
{
|
||||
return 0 == m_nHSpace && 0 == m_nVSpace;
|
||||
}
|
||||
};
|
||||
|
||||
class COOXMLWriter : public IWriter
|
||||
{
|
||||
const std::wstring *m_pDstPath; // Директория назначения
|
||||
const std::wstring *m_pTempDir; // Temp папка
|
||||
const std::wstring *m_pSrcPath; // Директория источника
|
||||
const std::wstring *m_pBasePath; // Полный базовый адрес
|
||||
const std::wstring *m_pCorePath; // Путь до корневого файла (используется для работы с Epub)
|
||||
|
||||
XmlString m_oStylesXml; // styles.xml
|
||||
XmlString m_oDocXmlRels; // document.xml.rels
|
||||
XmlString m_oNoteXmlRels; // footnotes.xml.rels
|
||||
XmlString m_oDocXml; // document.xml
|
||||
XmlString m_oNoteXml; // footnotes.xml
|
||||
XmlString m_oNumberXml; // numbering.xml
|
||||
XmlString m_oWebSettings; // webSettings.xml
|
||||
|
||||
NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль
|
||||
NSCSS::NSProperties::CPage m_oPageData; // Стили страницы
|
||||
|
||||
NSCSS::CCssCalculator *m_pStylesCalculator;
|
||||
THTMLParameters *m_pHTMLParameters;
|
||||
|
||||
struct TState
|
||||
{
|
||||
bool m_bInP; // <w:p> открыт?
|
||||
bool m_bInR; // <w:r> открыт?
|
||||
bool m_bInT; // <w:t> открыт?
|
||||
bool m_bWasPStyle; // <w:pStyle> записан?
|
||||
bool m_bWasSpace; // Был пробел?
|
||||
|
||||
bool m_bInHyperlink; // <w:hyperlink> открыт?
|
||||
std::wstring m_wsTooltip;
|
||||
std::wstring m_wsHref;
|
||||
std::wstring m_wsFootnote;
|
||||
bool m_bIsFootnote;
|
||||
bool m_bISCrossHyperlink;
|
||||
|
||||
XmlString *m_pCurrentDocument; //Текущее место записи
|
||||
bool m_bRemoveCurrentDocument;
|
||||
|
||||
TState(XmlString *pCurrentDocument)
|
||||
: m_bInP(false), m_bInR(false), m_bInT(false),
|
||||
m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false),
|
||||
m_bIsFootnote(false), m_bISCrossHyperlink(false),
|
||||
m_pCurrentDocument(pCurrentDocument), m_bRemoveCurrentDocument(false)
|
||||
{}
|
||||
|
||||
~TState()
|
||||
{
|
||||
if (m_bRemoveCurrentDocument && nullptr != m_pCurrentDocument)
|
||||
delete m_pCurrentDocument;
|
||||
}
|
||||
|
||||
void CreateNewCurrentDocument()
|
||||
{
|
||||
m_pCurrentDocument = new XmlString();
|
||||
m_bRemoveCurrentDocument = true;
|
||||
}
|
||||
};
|
||||
|
||||
std::stack<TState> m_arStates;
|
||||
|
||||
int m_nFootnoteId; // ID сноски
|
||||
int m_nHyperlinkId; // ID ссылки
|
||||
int m_nListId; // ID списка
|
||||
int m_nElementId; // ID остальные элементы
|
||||
|
||||
bool m_bBanUpdatePageData; // Запретить обновление данных о странице?
|
||||
|
||||
std::stack<std::wstring> m_arDivId;
|
||||
bool m_bWasDivs;
|
||||
|
||||
std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски
|
||||
std::map<std::wstring, UINT> m_mBookmarks; // Закладки
|
||||
using anchors_map = std::map<std::wstring, std::wstring>;
|
||||
anchors_map m_mAnchors; // Map якорей с индивидуальными id
|
||||
|
||||
NSFonts::IApplicationFonts* m_pFonts; // Необходимо для оптимизации работы со шрифтами
|
||||
public:
|
||||
COOXMLWriter(THTMLParameters* pHTMLParameters = nullptr, NSCSS::CCssCalculator* pCSSCalculator = nullptr);
|
||||
|
||||
void SetSrcDirectory (const std::wstring& wsPath);
|
||||
void SetDstDirectory (const std::wstring& wsPath);
|
||||
void SetTempDirectory(const std::wstring& wsPath);
|
||||
void SetBaseDirectory(const std::wstring& wsPath);
|
||||
void SetCoreDirectory(const std::wstring& wsPath);
|
||||
|
||||
void Begin(const std::wstring& wsDst) override;
|
||||
void End(const std::wstring& wsDst) override;
|
||||
|
||||
bool OpenP();
|
||||
bool OpenR();
|
||||
bool OpenT();
|
||||
void OpenHyperlink();
|
||||
|
||||
void CloseP();
|
||||
void CloseR();
|
||||
void CloseT();
|
||||
void CloseHyperlink();
|
||||
|
||||
void PageBreak() override;
|
||||
|
||||
void BeginBlock() override;
|
||||
void EndBlock(bool bAddBlock) override;
|
||||
|
||||
void SetDataOutput(XmlString* pOutputData) override;
|
||||
void RevertDataOutput() override;
|
||||
|
||||
void SaveState();
|
||||
void RollBackState();
|
||||
|
||||
void SetCurrentDocument(XmlString* pNewDocument);
|
||||
|
||||
void Break(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
void SetHyperlinkData(const std::wstring& wsRef, const std::wstring& wsTooltip, bool bIsCross, const std::wstring& wsFootnote, bool bIsFootnote);
|
||||
void ClearHyperlinkData();
|
||||
|
||||
void OpenCrossHyperlink(const std::wstring& wsRef);
|
||||
void OpenExternalHyperlink(const std::wstring& wsRef, const std::wstring& wsTooltip);
|
||||
void CloseCrossHyperlink(const std::vector<NSCSS::CNode>& arSelectors, std::wstring wsFootnote, const std::wstring& wsRef);
|
||||
void CloseExternalHyperlink();
|
||||
|
||||
std::wstring WritePPr(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
std::wstring WriteRPr(XmlString& oXml, const std::vector<NSCSS::CNode>& arSelectors);
|
||||
|
||||
bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) override;
|
||||
void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) override;
|
||||
void WriteSpace();
|
||||
|
||||
void WriteEmptyBookmark(const std::wstring& wsId);
|
||||
std::wstring AddLiteBookmark();
|
||||
std::wstring WriteBookmark(const std::wstring& wsId);
|
||||
std::wstring AddAnchor(const std::wstring& wsAnchorValue);
|
||||
|
||||
void WriteImage(const TImageData& oImageData, const std::wstring& wsId);
|
||||
void WriteAlternativeImage(const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData);
|
||||
void WriteEmptyImage(int nWidth, int nHeight, const std::wstring& wsName = L"", const std::wstring& wsDescr = L"");
|
||||
void WriteImageRels(const std::wstring& wsImageId, const std::wstring& wsImageName);
|
||||
|
||||
std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle);
|
||||
|
||||
void UpdatePageStyle(const std::vector<NSCSS::CNode>& arSelectors);
|
||||
void SetBaseFont(const std::wstring& wsFontStyles);
|
||||
void SetDivId(const std::wstring& wsDivId);
|
||||
void RollBackDivId();
|
||||
|
||||
void IncreaseListId();
|
||||
int GetListId() const;
|
||||
|
||||
std::wstring FindFootnote(const std::wstring& wsId);
|
||||
void OpenFootnote(const std::wstring& wsFootnoteID);
|
||||
void CloseFootnote();
|
||||
|
||||
XmlString& GetStylesXml();
|
||||
XmlString& GetDocRelsXml();
|
||||
XmlString& GetNotesRelsXml();
|
||||
XmlString& GetDocumentXml();
|
||||
XmlString& GetNotesXml();
|
||||
XmlString& GetNumberingXml();
|
||||
XmlString& GetWebSettingsXml();
|
||||
XmlString* GetCurrentDocument() const override;
|
||||
|
||||
bool SupportNestedTables() const override;
|
||||
|
||||
const NSCSS::NSProperties::CPage* GetPageData() const;
|
||||
NSFonts::IApplicationFonts* GetFonts();
|
||||
|
||||
std::wstring GetMediaDir() const;
|
||||
std::wstring GetTempDir() const;
|
||||
std::wstring GetSrcPath() const;
|
||||
std::wstring GetBasePath() const;
|
||||
std::wstring GetCorePath() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OOXMLWRITER_H
|
||||
@ -5,9 +5,11 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "../Common/3dParty/html/htmltoxhtml.h"
|
||||
#include "htmlfile2.h"
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
#include "../Common/3dParty/html/htmltoxhtml.h".
|
||||
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
|
||||
#include "../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h"
|
||||
#include "../Common/Network/FileTransporter/include/FileTransporter.h"
|
||||
@ -23,7 +25,6 @@
|
||||
#include "../DesktopEditor/raster/BgraFrame.h"
|
||||
#include "../DesktopEditor/graphics/pro/Graphics.h"
|
||||
|
||||
#include "htmlfile2.h"
|
||||
#include "src/Languages.h"
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
@ -267,7 +268,7 @@ struct CTextSettings
|
||||
bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк)
|
||||
bool bQ; // Цитата
|
||||
bool bAddSpaces; // Добавлять пробелы перед текстом?
|
||||
bool bMergeText; // Объединять подяр идущий текст в 1?
|
||||
bool bMergeText; // Объединять подряд идущий текст в 1?
|
||||
int nLi; // Уровень списка
|
||||
bool bNumberingLi; // Является ли список нумерованным
|
||||
|
||||
@ -2488,16 +2489,6 @@ private:
|
||||
sSelectors.push_back(NSCSS::CNode(L"html", L"", L""));
|
||||
|
||||
GetSubClass(&m_oDocXml, sSelectors);
|
||||
/*
|
||||
std::wstring sCrossId = std::to_wstring(m_nCrossId++);
|
||||
m_oDocXml.WriteString(L"<w:bookmarkStart w:id=\"");
|
||||
m_oDocXml.WriteString(sCrossId);
|
||||
m_oDocXml.WriteString(L"\" w:name=\"");
|
||||
m_oDocXml.WriteString(sFileName);
|
||||
m_oDocXml.WriteString(L"\"/><w:bookmarkEnd w:id=\"");
|
||||
m_oDocXml.WriteString(sCrossId);
|
||||
m_oDocXml.WriteString(L"\"/>");
|
||||
*/
|
||||
|
||||
if (!sSelectors.back().m_mAttributes.empty())
|
||||
{
|
||||
@ -2573,7 +2564,7 @@ private:
|
||||
|
||||
NSStringUtils::CStringBuilder oPPr;
|
||||
|
||||
const std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);
|
||||
wrP(&oPPr, arSelectors, oTS);
|
||||
|
||||
WriteToStringBuilder(oPPr, *pXml);
|
||||
|
||||
@ -2590,9 +2581,6 @@ private:
|
||||
sRStyle = wrRPr(&oRPr, arSelectors, oTS);
|
||||
|
||||
WriteToStringBuilder(oRPr, *pXml);
|
||||
|
||||
if (oTS.bQ)
|
||||
pXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t>");
|
||||
}
|
||||
|
||||
if (oTS.bQ)
|
||||
@ -2608,10 +2596,7 @@ private:
|
||||
while (std::wstring::npos != unBegin)
|
||||
{
|
||||
if (OpenR(pXml))
|
||||
{
|
||||
pXml->WriteString(L"<w:test/>");
|
||||
WriteToStringBuilder(oRPr, *pXml);
|
||||
}
|
||||
|
||||
OpenT(pXml);
|
||||
if (unEnd == std::wstring::npos)
|
||||
@ -2684,11 +2669,13 @@ private:
|
||||
wrP(pXml, arSelectors, oTS);
|
||||
const std::wstring wsName{L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1)};
|
||||
m_mBookmarks.insert(std::make_pair(wsName, m_mBookmarks.size() + 1));
|
||||
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + wsName + L"\" \\o \"");
|
||||
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + wsName + L"\" \\o \"");
|
||||
pXml->WriteEncodeXmlString(wsNote);
|
||||
pXml->WriteString(L"\"</w:instrText></w:r>");
|
||||
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>");
|
||||
|
||||
const bool bResult = readStream(pXml, arSelectors, oTS);
|
||||
|
||||
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>");
|
||||
wsNote.clear();
|
||||
|
||||
@ -2701,7 +2688,7 @@ private:
|
||||
return false;
|
||||
|
||||
CTextSettings oTSR(oTS);
|
||||
oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
|
||||
// oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
|
||||
|
||||
return readStream(pXml, arSelectors, oTSR);
|
||||
}
|
||||
@ -3843,7 +3830,7 @@ private:
|
||||
CTextSettings oNewSettings{oTS};
|
||||
|
||||
const std::wstring wsHighlight{sSelectors.back().m_pCompiledStyle->m_oBackground.GetColor()
|
||||
.EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
|
||||
.EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
|
||||
{{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
|
||||
{{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
|
||||
{{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"},
|
||||
@ -4094,71 +4081,7 @@ private:
|
||||
if(m_oLightReader.IsEmptyNode())
|
||||
return false;
|
||||
|
||||
CloseP(oXml, arSelectors);
|
||||
|
||||
CTextSettings oTSLi(oTS);
|
||||
|
||||
++oTSLi.nLi;
|
||||
|
||||
//Нумерованный список
|
||||
if (L"ol" == arSelectors.back().m_wsName)
|
||||
{
|
||||
int nStart = 1;
|
||||
while(m_oLightReader.MoveToNextAttribute())
|
||||
if(m_oLightReader.GetName() == L"start")
|
||||
nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
|
||||
m_oLightReader.MoveToElement();
|
||||
|
||||
oTSLi.bNumberingLi = true;
|
||||
|
||||
const std::wstring wsStart(std::to_wstring(nStart));
|
||||
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"");
|
||||
m_oNumberXml.WriteString(std::to_wstring(m_nNumberingId++));
|
||||
m_oNumberXml.WriteString(L"\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"709\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%2.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1429\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%3.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"2149\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%4.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2869\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3589\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%6.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"4309\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%7.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5029\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%8.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5749\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"");
|
||||
m_oNumberXml.WriteString(wsStart);
|
||||
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%9.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"6469\" w:hanging=\"180\"/></w:pPr></w:lvl></w:abstractNum>");
|
||||
}
|
||||
else
|
||||
oTSLi.bNumberingLi = false;
|
||||
|
||||
CTextSettings oTSList{oTSLi};
|
||||
|
||||
oTSList.oAdditionalStyle.m_oMargin.SetTop (100, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
oTSList.oAdditionalStyle.m_oMargin.SetBottom(100, NSCSS::UnitMeasure::Twips, 0, true);
|
||||
|
||||
int nDeath = m_oLightReader.GetDepth();
|
||||
while(m_oLightReader.ReadNextSiblingNode2(nDeath))
|
||||
{
|
||||
const std::wstring wsName = m_oLightReader.GetName();
|
||||
|
||||
if (L"li" == wsName)
|
||||
ReadListElement(oXml, arSelectors, oTSList);
|
||||
else
|
||||
{
|
||||
CloseP(oXml, arSelectors);
|
||||
readInside(oXml, arSelectors, oTSLi, wsName);
|
||||
}
|
||||
}
|
||||
|
||||
CloseP(oXml, arSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, CTextSettings& oTS, bool bType)
|
||||
@ -5081,17 +5004,29 @@ private:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#else
|
||||
#include "HTMLReader.h"
|
||||
#endif
|
||||
|
||||
CHtmlFile2::CHtmlFile2()
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal = new CHtmlFile2_Private();
|
||||
#else
|
||||
m_pReader = new HTML::CHTMLReader();
|
||||
#endif
|
||||
}
|
||||
|
||||
CHtmlFile2::~CHtmlFile2()
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
RELEASEOBJECT(m_internal);
|
||||
#else
|
||||
RELEASEOBJECT(m_pReader);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
bool CHtmlFile2::IsHtmlFile(const std::wstring& sFile)
|
||||
{
|
||||
// Конвертируем в xhtml
|
||||
@ -5109,47 +5044,77 @@ bool CHtmlFile2::IsMhtFile(const std::wstring& sFile)
|
||||
// Читаем html
|
||||
return m_internal->isHtml();
|
||||
}
|
||||
#endif
|
||||
|
||||
void CHtmlFile2::SetTmpDirectory(const std::wstring& sFolder)
|
||||
void CHtmlFile2::SetTempDirectory(const std::wstring& wsFolder)
|
||||
{
|
||||
m_internal->m_sTmp = NSSystemPath::NormalizePath(sFolder);
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sTmp = NSSystemPath::NormalizePath(wsFolder);
|
||||
#else
|
||||
m_pReader->SetTempDirectory(wsFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CHtmlFile2::SetCoreDirectory(const std::wstring& wsFolder)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sCore = NSSystemPath::NormalizePath(wsFolder);
|
||||
#else
|
||||
m_pReader->SetCoreDirectory(wsFolder);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
HRESULT CHtmlFile2::ConvertHTML2OOXML(const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
|
||||
{
|
||||
#ifndef USE_OLD_HTML_CONVERTER
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertHTML2OOXML(wsPath, wsDirectory, pParametrs);
|
||||
#else
|
||||
if(!m_internal->m_oLightReader.IsValid())
|
||||
if(!IsHtmlFile(sSrc))
|
||||
return S_FALSE;
|
||||
|
||||
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sSrc);
|
||||
m_internal->m_sDst = sDst;
|
||||
m_internal->CreateDocxEmpty(oParams);
|
||||
m_internal->CreateDocxEmpty(pParametrs);
|
||||
m_internal->readStyle();
|
||||
|
||||
// Переходим в начало
|
||||
if(!m_internal->m_oLightReader.MoveToStart())
|
||||
return S_FALSE;
|
||||
|
||||
if(oParams && oParams->m_bNeedPageBreakBefore)
|
||||
if(pParametrs && pParametrs->m_bNeedPageBreakBefore)
|
||||
m_internal->PageBreakBefore();
|
||||
|
||||
m_internal->readSrc();
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
HRESULT CHtmlFile2::ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
return S_FALSE;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertHTML2Markdown(wsPath, wsFinalFile, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::ConvertMHT2OOXML(const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
if(!m_internal->m_oLightReader.IsValid())
|
||||
if(!IsMhtFile(sSrc))
|
||||
if(!IsMhtFile(wsPath))
|
||||
return S_FALSE;
|
||||
|
||||
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sSrc);
|
||||
m_internal->m_sDst = sDst;
|
||||
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(wsPath);
|
||||
m_internal->m_sDst = sDirectory;
|
||||
m_internal->CreateDocxEmpty(oParams);
|
||||
m_internal->readStyle();
|
||||
|
||||
@ -5162,19 +5127,38 @@ HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst,
|
||||
m_internal->readSrc();
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertMHT2OOXML(wsPath, wsDirectory, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
|
||||
HRESULT CHtmlFile2::ConvertMHT2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
|
||||
{
|
||||
m_internal->m_sDst = sDst;
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
return S_FALSE;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertMHT2Markdown(wsPath, wsFinalFile, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::ConvertHTML2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
m_internal->m_sDst = wsDirectory;
|
||||
m_internal->CreateDocxEmpty(oParams);
|
||||
bool bFirst = true;
|
||||
|
||||
for(const std::wstring& sS : sSrc)
|
||||
for(const std::wstring& sS : arPaths)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifdef _DEBUG
|
||||
std::wcout << NSFile::GetFileName(sS) << std::endl;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sS);
|
||||
if(!IsHtmlFile(sS))
|
||||
@ -5202,8 +5186,51 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const s
|
||||
|
||||
m_internal->write();
|
||||
return S_OK;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertHTML2OOXML(arPaths, wsDirectory, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
return S_FALSE;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertHTML2Markdown(arPaths, wsFinalFile, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::ConvertMHT2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
return S_FALSE;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertMHT2OOXML(arPaths, wsDirectory, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT CHtmlFile2::ConvertMHT2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
|
||||
{
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
return S_FALSE;
|
||||
#else
|
||||
if (nullptr == m_pReader)
|
||||
return S_FALSE;
|
||||
|
||||
return m_pReader->ConvertMHT2Markdown(arPaths, wsFinalFile, pParametrs);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
std::wstring CTableRow::ConvertToOOXML(const CTable& oTable, int nInstruction)
|
||||
{
|
||||
if (m_arCells.empty())
|
||||
@ -5359,3 +5386,4 @@ std::wstring CTableCell::ConvertToOOXML(const CTable& oTable, UINT unColumnNumbe
|
||||
|
||||
return oCell.GetData();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
#include <vector>
|
||||
#include "../DesktopEditor/common/Types.h"
|
||||
|
||||
#include "HTMLParameters.h"
|
||||
#include "MarkdownParameters.h"
|
||||
|
||||
#ifndef HTMLFILE2_USE_DYNAMIC_LIBRARY
|
||||
#define HTMLFILE2_DECL_EXPORT
|
||||
#else
|
||||
@ -12,82 +15,43 @@
|
||||
#define HTMLFILE2_DECL_EXPORT Q_DECL_EXPORT
|
||||
#endif
|
||||
|
||||
struct CHtmlParams
|
||||
{
|
||||
std::wstring m_sGenres; // Жанры
|
||||
std::wstring m_sAuthors; // Авторы
|
||||
std::wstring m_sBookTitle; // Название
|
||||
std::wstring m_sDate; // Дата
|
||||
std::wstring m_sDescription; // описание
|
||||
std::wstring m_sLanguage; // Язык
|
||||
bool m_bNeedPageBreakBefore; // Новый html с новой страницы
|
||||
std::wstring m_sdocDefaults; // Стиль docDefaults
|
||||
std::wstring m_sNormal; // Стиль normal
|
||||
|
||||
CHtmlParams() : m_bNeedPageBreakBefore(false) {}
|
||||
|
||||
void SetNormal(const std::wstring& sStyle)
|
||||
{
|
||||
m_sNormal = sStyle;
|
||||
}
|
||||
|
||||
void SetDocDefaults(const std::wstring& sStyle)
|
||||
{
|
||||
m_sdocDefaults = sStyle;
|
||||
}
|
||||
|
||||
void SetPageBreakBefore(bool bNeed)
|
||||
{
|
||||
m_bNeedPageBreakBefore = bNeed;
|
||||
}
|
||||
|
||||
void SetDate(const std::wstring& sDate)
|
||||
{
|
||||
m_sDate = sDate;
|
||||
}
|
||||
|
||||
void SetDescription(const std::wstring& sDescription)
|
||||
{
|
||||
m_sDescription = sDescription;
|
||||
}
|
||||
|
||||
void SetGenres(const std::wstring& sGenres)
|
||||
{
|
||||
m_sGenres = sGenres;
|
||||
}
|
||||
|
||||
void SetAuthors(const std::wstring& sAuthors)
|
||||
{
|
||||
m_sAuthors = sAuthors;
|
||||
}
|
||||
|
||||
void SetTitle(const std::wstring& sTitle)
|
||||
{
|
||||
m_sBookTitle = sTitle;
|
||||
}
|
||||
|
||||
void SetLanguage(const std::wstring& sLanguage)
|
||||
{
|
||||
m_sLanguage = sLanguage;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
class CHtmlFile2_Private;
|
||||
#else
|
||||
namespace HTML { class CHTMLReader; }
|
||||
#endif
|
||||
|
||||
class HTMLFILE2_DECL_EXPORT CHtmlFile2
|
||||
{
|
||||
private:
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
CHtmlFile2_Private* m_internal;
|
||||
#else
|
||||
HTML::CHTMLReader* m_pReader;
|
||||
#endif
|
||||
public:
|
||||
CHtmlFile2();
|
||||
~CHtmlFile2();
|
||||
|
||||
bool IsHtmlFile(const std::wstring& sFile);
|
||||
bool IsMhtFile (const std::wstring& sFile);
|
||||
void SetTmpDirectory(const std::wstring& sFolder);
|
||||
#ifdef USE_OLD_HTML_CONVERTER
|
||||
bool IsHtmlFile(const std::wstring& wsFile);
|
||||
bool IsMhtFile (const std::wstring& wsFile);
|
||||
#endif
|
||||
|
||||
void SetTempDirectory(const std::wstring& wsFolder);
|
||||
void SetCoreDirectory(const std::wstring& wsFolder);
|
||||
HRESULT OpenHtml(const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
|
||||
HRESULT OpenMht (const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
|
||||
HRESULT OpenBatchHtml(const std::vector<std::wstring>& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
|
||||
|
||||
HRESULT ConvertHTML2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
|
||||
HRESULT ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
|
||||
|
||||
HRESULT ConvertMHT2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
|
||||
HRESULT ConvertMHT2Markdown (const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
|
||||
|
||||
HRESULT ConvertHTML2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
|
||||
HRESULT ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
|
||||
|
||||
HRESULT ConvertMHT2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
|
||||
HRESULT ConvertMHT2Markdown (const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
|
||||
};
|
||||
|
||||
#endif // _HTMLFILE2_HTMLFILE2_H
|
||||
|
||||
@ -60,23 +60,23 @@ namespace NSStringFinder
|
||||
return sValue;
|
||||
}
|
||||
|
||||
std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition)
|
||||
inline std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition)
|
||||
{
|
||||
return FindPropertyTemplate<char>(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition);
|
||||
}
|
||||
|
||||
std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition)
|
||||
inline std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition)
|
||||
{
|
||||
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition);
|
||||
}
|
||||
|
||||
std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0)
|
||||
inline std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0)
|
||||
{
|
||||
size_t unEndPosition = 0;
|
||||
return FindPropertyTemplate<char>(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition);
|
||||
}
|
||||
|
||||
std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0)
|
||||
inline std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0)
|
||||
{
|
||||
size_t unEndPosition = 0;
|
||||
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition);
|
||||
@ -130,12 +130,12 @@ namespace NSStringFinder
|
||||
return oData;
|
||||
}
|
||||
|
||||
TFoundedData<char> FindProperty(const std::string& sString, const std::string& sProperty, const std::vector<std::string>& arDelimiters, const std::vector<std::string>& arEndings, const size_t& unStarting = 0)
|
||||
inline TFoundedData<char> FindProperty(const std::string& sString, const std::string& sProperty, const std::vector<std::string>& arDelimiters, const std::vector<std::string>& arEndings, const size_t& unStarting = 0)
|
||||
{
|
||||
return FindPropertyTemplate<char>(sString, sProperty, arDelimiters, arEndings, unStarting);
|
||||
}
|
||||
|
||||
TFoundedData<wchar_t> FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector<std::wstring>& arDelimiters, const std::vector<std::wstring>& arEndings, const size_t& unStarting = 0)
|
||||
inline TFoundedData<wchar_t> FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector<std::wstring>& arDelimiters, const std::vector<std::wstring>& arEndings, const size_t& unStarting = 0)
|
||||
{
|
||||
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, arDelimiters, arEndings, unStarting);
|
||||
}
|
||||
@ -154,12 +154,12 @@ namespace NSStringFinder
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0)
|
||||
inline bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0)
|
||||
{
|
||||
return RemoveEmptyTagTemplate<char>(sValue, sTagName, unStart);
|
||||
}
|
||||
|
||||
bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0)
|
||||
inline bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0)
|
||||
{
|
||||
return RemoveEmptyTagTemplate<wchar_t>(sValue, sTagName, unStart);
|
||||
}
|
||||
@ -223,7 +223,7 @@ namespace NSStringFinder
|
||||
return !boost::algorithm::ifind_first(sString, sValue).empty();
|
||||
}
|
||||
|
||||
int ToInt(const std::wstring& oValue, int nMinValue = 0)
|
||||
inline int ToInt(const std::wstring& oValue, int nMinValue = 0)
|
||||
{
|
||||
boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))");
|
||||
|
||||
@ -237,7 +237,7 @@ namespace NSStringFinder
|
||||
return std::max(nMinValue, nValue);
|
||||
}
|
||||
|
||||
int ToDouble(const std::wstring& oValue, double dMinValue = 0.)
|
||||
inline int ToDouble(const std::wstring& oValue, double dMinValue = 0.)
|
||||
{
|
||||
boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))");
|
||||
|
||||
|
||||
@ -6,6 +6,13 @@
|
||||
#include "../../DesktopEditor/common/Directory.h"
|
||||
#include "../../OfficeUtils/src/OfficeUtils.h"
|
||||
|
||||
#include "../../Common/3dParty/md/md2html.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
void getDirectories(const std::wstring& sDirectory, std::vector<std::wstring>& arrDirectory)
|
||||
{
|
||||
arrDirectory.push_back(sDirectory);
|
||||
@ -15,6 +22,15 @@ void getDirectories(const std::wstring& sDirectory, std::vector<std::wstring>& a
|
||||
|
||||
int main()
|
||||
{
|
||||
// if (Md::ConvertMdFileToHtml(L"C:\\ONLYOFFICE\\Files\\md\\Bugs\\74626\\file-1.md",
|
||||
// L"C:\\ONLYOFFICE\\Files\\md\\Bugs\\74626\\file-1.html"))
|
||||
// std::wcout << L"Good" << std::endl;
|
||||
// else
|
||||
// std::wcout << L"Bad" << std::endl;
|
||||
|
||||
// return 0;
|
||||
|
||||
|
||||
bool bBatchMode = false;
|
||||
bool bMhtMode = false;
|
||||
if(bBatchMode)
|
||||
@ -97,7 +113,7 @@ int main()
|
||||
oParams.SetDescription(L"Description");
|
||||
|
||||
// Файл, который открываем
|
||||
std::wstring sFile = NSFile::GetProcessDirectory() + L"/test.html";
|
||||
std::wstring sFile = L"C:\\ONLYOFFICE\\Files\\html\\test_tag_a_1.html";
|
||||
CHtmlFile2 oFile;
|
||||
oFile.SetTmpDirectory(sOutputDirectory);
|
||||
nResConvert = (bMhtMode ? oFile.OpenMht(sFile, sOutputDirectory, &oParams) : oFile.OpenHtml(sFile, sOutputDirectory, &oParams));
|
||||
|
||||
@ -339,7 +339,6 @@ namespace DocFileFormat
|
||||
if ((chpxs != NULL) && (chpxFcs != NULL) && !chpxFcs->empty())//? второе
|
||||
{
|
||||
size_t i = 0;
|
||||
bool changechpx = false;
|
||||
|
||||
// write a runs for each CHPX
|
||||
for (size_t it = 0; it < chpxs->size(); ++it)
|
||||
@ -348,15 +347,6 @@ namespace DocFileFormat
|
||||
|
||||
int fcChpxStart = ((chpxFcs) && (i < chpxFcs->size())) ? chpxFcs->at(i) : fc;
|
||||
int fcChpxEnd = fcEnd;
|
||||
if (i > 0)
|
||||
{
|
||||
int previous = chpxFcs->at(i-1);
|
||||
if ((fcChpxStart != fc) && (previous > fcChpxStart))
|
||||
{
|
||||
fcChpxStart = previous;
|
||||
changechpx = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((chpxFcs) && ( i < chpxFcs->size() - 1))
|
||||
fcChpxEnd = chpxFcs->at(i + 1);
|
||||
@ -442,13 +432,7 @@ namespace DocFileFormat
|
||||
}
|
||||
else
|
||||
{
|
||||
if (changechpx == true)
|
||||
{
|
||||
size_t a = it - 1;
|
||||
cp = writeRun(chpxChars, chpxs->at(a), cp);
|
||||
}
|
||||
else
|
||||
cp = writeRun(chpxChars, chpxs->at(it), cp);
|
||||
cp = writeRun(chpxChars, chpxs->at(it), cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ namespace DocFileFormat
|
||||
{
|
||||
ShapeConcentricFill = true;
|
||||
Joins = round;
|
||||
Path = L"wr-21600,,21600,43200,,,21600,21600nfewr-21600,,21600,43200,,,21600,21600l,21600nsxe";
|
||||
Path = L"wr-21600,,21600,43200,,,21600,21600nfe";
|
||||
|
||||
Formulas.push_back( L"val #2");
|
||||
Formulas.push_back( L"val #3");
|
||||
|
||||
@ -312,7 +312,7 @@ void CFRecord::appendRawData(const char* raw_data, const size_t size)
|
||||
|
||||
void CFRecord::appendRawDataToStatic(const unsigned char *raw_data, const size_t size)
|
||||
{
|
||||
if(MAX_RECORD_SIZE - rdPtr > size)
|
||||
if(MAX_RECORD_SIZE - rdPtr >= size)
|
||||
{
|
||||
memcpy(&intData[rdPtr], raw_data, size);
|
||||
rdPtr += size;
|
||||
@ -483,7 +483,7 @@ void CFRecord::resetPointerToBegin()
|
||||
rdPtr = 0;
|
||||
}
|
||||
|
||||
void CFRecord::save(NSBinPptxRW::CXlsbBinaryWriter& writer)
|
||||
void CFRecord::save(NSBinPptxRW::CXlsyBinaryWriter& writer)
|
||||
{
|
||||
writer.XlsbStartRecord(type_id_, rdPtr);
|
||||
writer.WriteBYTEArray((BYTE*)&intData[0], rdPtr);
|
||||
|
||||
@ -90,7 +90,7 @@ public:
|
||||
void resetPointerToBegin();
|
||||
|
||||
//save record to stream
|
||||
void save(NSBinPptxRW::CXlsbBinaryWriter& writer);
|
||||
void save(NSBinPptxRW::CXlsyBinaryWriter& writer);
|
||||
void save(CFStreamPtr& writer);
|
||||
|
||||
template<class T>
|
||||
|
||||
@ -93,7 +93,7 @@ const size_t CFStreamCacheWriter::writeToStream(const size_t num_of_records_min_
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
BinaryStreamCacheWriter::BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream, GlobalWorkbookInfoPtr global_info)
|
||||
BinaryStreamCacheWriter::BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream, GlobalWorkbookInfoPtr global_info)
|
||||
: StreamCacheWriter(global_info), binaryStream_(binaryStream)
|
||||
{
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ protected:
|
||||
class CFStreamCacheWriter : public StreamCacheWriter
|
||||
{
|
||||
public:
|
||||
CFStreamCacheWriter(CFStreamPtr stream, const GlobalWorkbookInfoPtr global_info);
|
||||
CFStreamCacheWriter(CFStreamPtr stream, const GlobalWorkbookInfoPtr global_info);
|
||||
~CFStreamCacheWriter();
|
||||
|
||||
// Return the next new CFRecord
|
||||
@ -92,13 +92,13 @@ private:
|
||||
class BinaryStreamCacheWriter : public StreamCacheWriter
|
||||
{
|
||||
public:
|
||||
BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream, const GlobalWorkbookInfoPtr global_info);
|
||||
BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream, const GlobalWorkbookInfoPtr global_info);
|
||||
~BinaryStreamCacheWriter();
|
||||
const size_t GetRecordPosition()override{return 0;}
|
||||
private:
|
||||
const size_t writeToStream(const size_t num_of_records_min_necessary) override;
|
||||
|
||||
boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream_;
|
||||
boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream_;
|
||||
};
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -66,7 +66,7 @@ public:
|
||||
bool fInvertNeg = false;
|
||||
|
||||
IcvChart icvFore = 0x004D;
|
||||
IcvChart icvBack = 0x0009;
|
||||
IcvChart icvBack = 0x004D;
|
||||
};
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -372,6 +372,7 @@ void CF12::writeFields(CFRecord& record)
|
||||
else if (dxfObj.m_oNumFmt->m_oFormatCode.IsInit())
|
||||
{
|
||||
dxf.dxfn->fIfmtUser = true;
|
||||
dxf.dxfn->ifmtNinch = false;
|
||||
dxf.dxfn->dxfnum.user_defined.fmt = dxfObj.m_oNumFmt->m_oFormatCode.get();
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public:
|
||||
|
||||
//-----------------------------
|
||||
_INT16 catCross = 0;
|
||||
_INT16 catLabel = 0;
|
||||
_INT16 catLabel = 1;
|
||||
_INT16 catMark = 0;
|
||||
|
||||
bool fBetween = false;
|
||||
|
||||
@ -174,9 +174,17 @@ void Dv::writeFields(CFRecord& record)
|
||||
if (record.getGlobalWorkbookInfo()->Version < 0x0800)
|
||||
{
|
||||
XLUnicodeString PromptTitle_(PromptTitle);
|
||||
if(PromptTitle.empty())
|
||||
PromptTitle_ = std::wstring (1, L'\0');
|
||||
XLUnicodeString ErrorTitle_(ErrorTitle);
|
||||
if(ErrorTitle.empty())
|
||||
ErrorTitle_ = std::wstring (1, L'\0');
|
||||
XLUnicodeString Prompt_(Prompt);
|
||||
if(Prompt.empty())
|
||||
Prompt_ = std::wstring (1, L'\0');
|
||||
XLUnicodeString Error_(Error);
|
||||
if(Error.empty())
|
||||
Error_ = std::wstring (1, L'\0');
|
||||
|
||||
record << PromptTitle_ << ErrorTitle_ << Prompt_ << Error_;
|
||||
}
|
||||
|
||||
@ -37,6 +37,9 @@
|
||||
#include "../Biff_structures/ODRAW/OfficeArtFSPGR.h"
|
||||
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
|
||||
#include "../Biff_structures/ODRAW/OfficeArtFOPT.h"
|
||||
#include "../Biff_structures/ODRAW/OfficeArtClientAnchorChart.h"
|
||||
#include "../Biff_structures/ODRAW/OfficeArtClientAnchorSheet.h"
|
||||
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
|
||||
|
||||
namespace XLS
|
||||
{
|
||||
@ -134,81 +137,124 @@ const bool MsoDrawing::isEndingRecord(CFRecord& record)
|
||||
return ODRAW::OfficeArtDgContainer::CheckIfContainerSizeOK(record);
|
||||
}
|
||||
|
||||
void MsoDrawing::prepareComment(const unsigned int CommentId)
|
||||
void MsoDrawing::prepareDrawing(const DrawingType Type, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
|
||||
const unsigned int row2, const unsigned int col2, const unsigned int param)
|
||||
{
|
||||
|
||||
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
|
||||
|
||||
if(rgChildRec.first)
|
||||
{
|
||||
auto ShapeGroup = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
auto groupFsp = new ODRAW::OfficeArtFSP;
|
||||
ShapeGroup->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(groupFsp);
|
||||
groupFsp->shape_id = 0;
|
||||
groupFsp->fGroup = true;
|
||||
groupFsp->fPatriarch = true;
|
||||
groupFsp->spid = CommentId;
|
||||
auto fdgPtr = new ODRAW::OfficeArtFDG;
|
||||
fdgPtr->rh_own.recInstance = DrawingtId;
|
||||
fdgPtr->spidCur = DrawingtId;
|
||||
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
|
||||
|
||||
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
|
||||
ShapeGroup->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
|
||||
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
|
||||
|
||||
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(ShapeGroup));
|
||||
{
|
||||
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
|
||||
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
|
||||
groupFSPGR->xLeft = col1;
|
||||
groupFSPGR->xRight = col2;
|
||||
groupFSPGR->yTop = row1;
|
||||
groupFSPGR->yBottom = row2;
|
||||
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
|
||||
|
||||
auto fsprPtr = new ODRAW::OfficeArtFSP;
|
||||
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
|
||||
fsprPtr->shape_id = 0;
|
||||
fsprPtr->spid = DrawingtId;
|
||||
fsprPtr->fGroup = true;
|
||||
fsprPtr->fPatriarch = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto TextboxContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
|
||||
|
||||
auto fdgPtr = new ODRAW::OfficeArtFDG;
|
||||
fdgPtr->rh_own.recInstance = CommentId;
|
||||
fdgPtr->csp = 2;
|
||||
fdgPtr->spidCur = CommentId+1;
|
||||
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
|
||||
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(TextboxContainer));
|
||||
|
||||
auto fsprPtr = new ODRAW::OfficeArtFSP;
|
||||
TextboxContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
|
||||
fsprPtr->shape_id = 0xCA;
|
||||
fsprPtr->spid = CommentId+1;
|
||||
fsprPtr->fHaveAnchor = true;
|
||||
fsprPtr->fHaveSpt = true;
|
||||
|
||||
|
||||
{
|
||||
//todo add mandatory optrions writing
|
||||
//auto textboxOpt = new ODRAW::OfficeArtFOPT;
|
||||
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
|
||||
if(rgChildRec.first && rgChildRec.m_OfficeArtSpgrContainer != nullptr)
|
||||
{
|
||||
auto spgrContainer = static_cast<ODRAW::OfficeArtSpgrContainer*>(rgChildRec.m_OfficeArtSpgrContainer.get());
|
||||
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
|
||||
}
|
||||
else
|
||||
rgChildRec.m_OfficeArtSpContainer.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
|
||||
|
||||
auto fsprPtr = new ODRAW::OfficeArtFSP;
|
||||
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
|
||||
if(Type == DrawingType::comment)
|
||||
fsprPtr->shape_id = 0xCA;
|
||||
else
|
||||
fsprPtr->shape_id = 1;
|
||||
fsprPtr->spid = DrawingtId+1;
|
||||
fsprPtr->fHaveMaster = true;
|
||||
auto clientAnchor = new ODRAW::OfficeArtClientAnchorSheet;
|
||||
clientAnchor->colL = col1;
|
||||
clientAnchor->colR = col2;
|
||||
clientAnchor->rwT = row1;
|
||||
clientAnchor->rwB = row2;
|
||||
SpContainer->m_OfficeArtAnchor = ODRAW::OfficeArtRecordPtr(clientAnchor);
|
||||
auto clientData = new ODRAW::OfficeArtClientData;
|
||||
SpContainer->m_oOfficeArtClientData = ODRAW::OfficeArtRecordPtr(clientData);
|
||||
if(Type == DrawingType::comment)
|
||||
{
|
||||
auto commentOptions = new ODRAW::OfficeArtFOPT;
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x0080;
|
||||
txId->op = DrawingtId;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x008B;
|
||||
txId->op = 2;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x00BF;
|
||||
txId->op = 0x00080008;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x0158;
|
||||
txId->op = 0x0000;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x0181;
|
||||
txId->op = 0x08000050;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
{
|
||||
auto txId = new ODRAW::OfficeArtFOPTE;
|
||||
txId->opid = 0x03BF;
|
||||
txId->op = 0x00020002;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
|
||||
}
|
||||
|
||||
commentOptions->fopt.options_count += 6;
|
||||
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
|
||||
SpContainer->extraSize += 8;
|
||||
}
|
||||
else if(Type == DrawingType::pic)
|
||||
{
|
||||
auto commentOptions = new ODRAW::OfficeArtFOPT;
|
||||
{
|
||||
auto PicOp = new ODRAW::OfficeArtFOPTE;//pib
|
||||
PicOp->opid = 0x0104;
|
||||
PicOp->fComplex = false;
|
||||
PicOp->fBid = true;
|
||||
PicOp->op = param;
|
||||
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(PicOp));
|
||||
}
|
||||
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
|
||||
commentOptions->fopt.options_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MsoDrawing::prepareChart(const unsigned int chartId, const unsigned int xPos, const unsigned int xOffset,
|
||||
const unsigned int yPos, const unsigned int yOffset)
|
||||
{
|
||||
|
||||
auto fdgPtr = new ODRAW::OfficeArtFDG;
|
||||
fdgPtr->rh_own.recInstance = chartId;
|
||||
fdgPtr->csp = 1;
|
||||
fdgPtr->spidCur = chartId;
|
||||
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
|
||||
|
||||
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Chart);
|
||||
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
|
||||
|
||||
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Chart);
|
||||
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
|
||||
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
|
||||
groupFSPGR->xLeft = xPos;
|
||||
groupFSPGR->xRight = xOffset;
|
||||
groupFSPGR->yTop = yPos;
|
||||
groupFSPGR->yBottom = yOffset;
|
||||
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
|
||||
|
||||
auto fsprPtr = new ODRAW::OfficeArtFSP;
|
||||
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
|
||||
fsprPtr->shape_id = 0;
|
||||
fsprPtr->spid = chartId;
|
||||
fsprPtr->fGroup = true;
|
||||
fsprPtr->fPatriarch = true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
|
||||
@ -60,18 +60,22 @@ public:
|
||||
virtual const bool isStartingRecord (CFRecord& record);
|
||||
virtual const bool isEndingRecord (CFRecord& record);
|
||||
virtual void useContinueRecords (CFRecord& record);
|
||||
|
||||
void prepareComment (const unsigned int CommentId);
|
||||
void prepareChart (const unsigned int chartId, const unsigned int xPos, const unsigned int xOffset,
|
||||
const unsigned int yPos, const unsigned int yOffset );
|
||||
|
||||
//-----------------------------
|
||||
ODRAW::OfficeArtDgContainer rgChildRec;
|
||||
|
||||
bool isReading;
|
||||
|
||||
enum DrawingType
|
||||
{
|
||||
chart,
|
||||
comment,
|
||||
pic
|
||||
};
|
||||
DrawingType xlsDrawingType;
|
||||
void prepareDrawing(const DrawingType DrawingType, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
|
||||
const unsigned int row2, const unsigned int col2, const unsigned int param = 1);
|
||||
};
|
||||
|
||||
|
||||
typedef boost::shared_ptr<MsoDrawing> MsoDrawingPtr;
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -31,6 +31,9 @@
|
||||
*/
|
||||
|
||||
#include "MsoDrawingGroup.h"
|
||||
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
|
||||
#include "../Biff_structures/ODRAW/OfficeArtFDGGBlock.h"
|
||||
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
|
||||
|
||||
namespace XLS
|
||||
{
|
||||
@ -64,5 +67,57 @@ void MsoDrawingGroup::readFields(CFRecord& record)
|
||||
record >> rgChildRec;
|
||||
}
|
||||
|
||||
void MsoDrawingGroup::writeFields(CFRecord& record)
|
||||
{
|
||||
rgChildRec.save(record);
|
||||
}
|
||||
|
||||
void MsoDrawingGroup::prepareChart(unsigned int count)
|
||||
{
|
||||
if(!drawingCount)
|
||||
return;
|
||||
auto fdggblock = new ODRAW::OfficeArtFDGGBlock;
|
||||
rgChildRec.m_OfficeArtFDGGBlock = ODRAW::OfficeArtRecordPtr(fdggblock);
|
||||
fdggblock->cdgSaved = count;
|
||||
fdggblock->cspSaved = count;
|
||||
for(auto i = 0; i < count; i++)
|
||||
{
|
||||
ODRAW::OfficeArtIDCL idcl;
|
||||
idcl.cspidCur = i;
|
||||
idcl.dgid = i;
|
||||
fdggblock->Rgidcl.push_back(idcl);
|
||||
}
|
||||
}
|
||||
|
||||
int MsoDrawingGroup::AddPict(const std::wstring& picPath)
|
||||
{
|
||||
int pictNum = -1;
|
||||
ODRAW::OfficeArtBStoreContainer *bstore;
|
||||
if(rgChildRec.m_OfficeArtBStoreContainer == nullptr)
|
||||
{
|
||||
bstore = new ODRAW::OfficeArtBStoreContainer;
|
||||
rgChildRec.m_OfficeArtBStoreContainer = ODRAW::OfficeArtRecordPtr(bstore);
|
||||
}
|
||||
else
|
||||
bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(rgChildRec.m_OfficeArtBStoreContainer.get());
|
||||
if(!drawingNames.IsInit())
|
||||
drawingNames.Init();
|
||||
if(drawingNames->find(picPath) == drawingNames->end())
|
||||
{
|
||||
auto fileBlock = new ODRAW::OfficeArtBStoreContainerFileBlock;
|
||||
bstore->rgfb.push_back(fileBlock);
|
||||
|
||||
pictNum = bstore->rgfb.size();
|
||||
drawingNames->emplace(picPath, pictNum);
|
||||
|
||||
DWORD fileSize = 0;
|
||||
auto result = NSFile::CFileBinary::ReadAllBytes(picPath, (BYTE**)&fileBlock->pict_data, fileSize);
|
||||
fileBlock->pict_size = fileSize;
|
||||
}
|
||||
else
|
||||
pictNum = drawingNames->find(picPath)->second;
|
||||
return pictNum;
|
||||
}
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
#include "BiffRecordContinued.h"
|
||||
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
|
||||
#include "../../../../../OOXML/Base/Nullable.h"
|
||||
|
||||
namespace XLS
|
||||
{
|
||||
@ -44,15 +45,21 @@ class MsoDrawingGroup: public BiffRecordContinued
|
||||
BIFF_RECORD_DEFINE_TYPE_INFO(MsoDrawingGroup)
|
||||
BASE_OBJECT_DEFINE_CLASS_NAME(MsoDrawingGroup)
|
||||
public:
|
||||
MsoDrawingGroup(const bool is_inside_chart_sheet);
|
||||
MsoDrawingGroup(const bool is_inside_chart_sheet = false);
|
||||
~MsoDrawingGroup();
|
||||
|
||||
BaseObjectPtr clone();
|
||||
|
||||
|
||||
void readFields(CFRecord& record);
|
||||
void writeFields(CFRecord& record);
|
||||
|
||||
void prepareChart(unsigned int count);
|
||||
int AddPict(const std::wstring& pictPath);
|
||||
|
||||
ODRAW::OfficeArtDggContainer rgChildRec;
|
||||
unsigned int drawingCount = 0;
|
||||
nullable<std::map<std::wstring, unsigned int>> drawingNames;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -56,10 +56,10 @@ public:
|
||||
|
||||
//-----------------------------
|
||||
bool fManSerAlloc = false;
|
||||
bool fManPlotArea = false;
|
||||
bool fManPlotArea = true;
|
||||
bool fPlotVisOnly = true;
|
||||
bool fNotSizeWith = false;
|
||||
bool fAlwaysAutoPlotArea = false;
|
||||
bool fAlwaysAutoPlotArea = true;
|
||||
unsigned char mdBlank = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -60,10 +60,10 @@ public:
|
||||
unsigned char tktMajor = 0;
|
||||
unsigned char tktMinor = 0;
|
||||
unsigned char tlt = 0;
|
||||
unsigned char wBkgMode = 0;
|
||||
unsigned char wBkgMode = 1;
|
||||
LongRGB rgb;
|
||||
|
||||
bool fAutoCo = false;
|
||||
bool fAutoCo = true;
|
||||
bool fAutoMode = false;
|
||||
unsigned char rot = 0;
|
||||
bool fAutoRot = false;
|
||||
|
||||
@ -52,7 +52,7 @@ public:
|
||||
virtual void load(CFRecord& record);
|
||||
virtual void save(CFRecord& record);
|
||||
|
||||
bool fAutoPict = false;
|
||||
bool fAutoPict = true;
|
||||
bool fDde = false;
|
||||
bool fPrintCalc = false;
|
||||
bool fIcon = false;
|
||||
|
||||
@ -80,6 +80,23 @@ void OfficeArtBStoreContainer::loadFields(XLS::CFRecord& record)
|
||||
}
|
||||
}
|
||||
|
||||
void OfficeArtBStoreContainer::save(XLS::CFRecord& record)
|
||||
{
|
||||
rh_own.recVer = 0xF;
|
||||
rh_own.recInstance = rgfb.size();
|
||||
rh_own.recType = 0xF001;
|
||||
for(auto i : rgfb)
|
||||
{
|
||||
rh_own.recLen += 44; //OfficeArtFBSE
|
||||
if(!i->nameData.empty())
|
||||
rh_own.recLen += i->nameData.size()+1;
|
||||
rh_own.recLen += 25; //blipHeader
|
||||
rh_own.recLen += i->pict_size;
|
||||
}
|
||||
record << rh_own;
|
||||
|
||||
}
|
||||
|
||||
const unsigned short OfficeArtBStoreContainer::GetInstanceToStore()
|
||||
{
|
||||
return rgfb.size();
|
||||
|
||||
@ -61,6 +61,7 @@ public:
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainer;
|
||||
|
||||
virtual void loadFields(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
// overriden
|
||||
const unsigned short GetInstanceToStore();
|
||||
|
||||
@ -269,4 +269,71 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record)
|
||||
}
|
||||
|
||||
|
||||
const void WriteMD4Digest(std::wstring UidStr, XLS::CFRecord& record)
|
||||
{
|
||||
if(UidStr.size() < 16 )
|
||||
UidStr = L"0000000000000000";
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
unsigned char hex_data = UidStr.at(i);
|
||||
record << hex_data;
|
||||
}
|
||||
}
|
||||
|
||||
void OfficeArtBStoreContainerFileBlock::save(XLS::CFRecord& record)
|
||||
{
|
||||
//fbse
|
||||
{
|
||||
OfficeArtRecordHeader FbseHeader;
|
||||
FbseHeader.recVer = 2;
|
||||
FbseHeader.recInstance = 5;
|
||||
FbseHeader.recType = 0xF007;
|
||||
FbseHeader.recLen = pict_size + 36 + 25;
|
||||
if(!nameData.empty())
|
||||
FbseHeader.recLen += nameData.size()+1;
|
||||
record << FbseHeader;
|
||||
BYTE btOs = FbseHeader.recInstance;
|
||||
record << btOs << btOs;
|
||||
WriteMD4Digest(rgbUid1, record);
|
||||
unsigned short tag = 0xFF;
|
||||
record << tag;
|
||||
unsigned int Size = pict_size + 17 + 8;
|
||||
record << Size;
|
||||
unsigned int Cref = 1;
|
||||
record << Cref;
|
||||
unsigned int foDelay = 0;
|
||||
record << foDelay;
|
||||
record.reserveNunBytes(1);
|
||||
BYTE cbName = 0;
|
||||
if(!nameData.empty())
|
||||
cbName = nameData.size()+1;
|
||||
record << cbName;
|
||||
|
||||
record.reserveNunBytes(2);
|
||||
if(cbName)
|
||||
{
|
||||
for(auto i : nameData)
|
||||
{
|
||||
record << i;
|
||||
}
|
||||
BYTE terminal = L'\0';
|
||||
record << terminal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OfficeArtRecordHeader rc_header;
|
||||
rc_header.recVer = 0;
|
||||
rc_header.recInstance = 0x46A;
|
||||
rc_header.recType = 0xF01D;
|
||||
rc_header.recLen = pict_size + 17;
|
||||
record << rc_header;
|
||||
record.reserveNunBytes(16);
|
||||
BYTE tag = 0xFF;
|
||||
record << tag;
|
||||
|
||||
//record.appendRawDataToStatic((BYTE*)pict_data, pict_size);
|
||||
}
|
||||
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -71,6 +71,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void load(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainerFileBlock;
|
||||
@ -86,6 +87,7 @@ public:
|
||||
size_t recType;
|
||||
std::wstring rgbUid1;
|
||||
std::wstring rgbUid2;
|
||||
std::wstring nameData;
|
||||
bool result;
|
||||
|
||||
const std::wstring ReadMD4Digest(XLS::CFRecord& record)
|
||||
|
||||
@ -56,5 +56,17 @@ void OfficeArtClientAnchorChart::loadFields(XLS::CFRecord& record)
|
||||
|
||||
}
|
||||
|
||||
void OfficeArtClientAnchorChart::save(XLS::CFRecord& record)
|
||||
{
|
||||
rh_own.recVer = 0;
|
||||
rh_own.recType = 0xF010;
|
||||
rh_own.recLen = 0x00000012;
|
||||
record << rh_own;
|
||||
unsigned short flags = 3;
|
||||
|
||||
record << flags << lx1 << ly1 << lx2 << ly2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -52,14 +52,15 @@ public:
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtClientAnchorChart;
|
||||
|
||||
virtual void loadFields(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
// bool fMove; // This attribute is ignored for chart sheets
|
||||
bool fSize;
|
||||
|
||||
int lx1;
|
||||
int ly1;
|
||||
int lx2;
|
||||
int ly2;
|
||||
int lx1 = 0;
|
||||
int ly1 = 0;
|
||||
int lx2 = 0;
|
||||
int ly2 = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<OfficeArtClientAnchorChart> OfficeArtClientAnchorChartPtr;
|
||||
|
||||
@ -70,6 +70,18 @@ void OfficeArtClientAnchorSheet::loadFields(XLS::CFRecord& record)
|
||||
record >> colL >> dxL >> rwT >> dyT >> colR >> dxR >> rwB >> dyB;
|
||||
}
|
||||
|
||||
void OfficeArtClientAnchorSheet::save(XLS::CFRecord& record)
|
||||
{
|
||||
rh_own.recVer = 0;
|
||||
rh_own.recType = 0xF010;
|
||||
rh_own.recLen = 0x00000012;
|
||||
record << rh_own;
|
||||
|
||||
unsigned short flags = 0;
|
||||
SETBIT(flags, 0, fMove)
|
||||
SETBIT(flags, 1, fSize)
|
||||
record << flags << colL << dxL << rwT << dyT << colR << dxR << rwB << dyB;
|
||||
}
|
||||
void OfficeArtClientAnchorSheet::calculate()
|
||||
{
|
||||
global_info->GetDigitFontSizePixels();
|
||||
|
||||
@ -53,18 +53,19 @@ public:
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtClientAnchorSheet;
|
||||
|
||||
virtual void loadFields(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
bool fMove;
|
||||
bool fSize;
|
||||
bool fMove = true;
|
||||
bool fSize = true;
|
||||
|
||||
XLS::Col256U colL;
|
||||
short dxL;
|
||||
XLS::RwU rwT;
|
||||
short dyT;
|
||||
XLS::Col256U colR;
|
||||
short dxR;
|
||||
XLS::RwU rwB;
|
||||
short dyB;
|
||||
XLS::Col256U colL = 0;
|
||||
short dxL = 0;
|
||||
XLS::RwU rwT = 0;
|
||||
short dyT = 0;
|
||||
XLS::Col256U colR = 0;
|
||||
short dxR = 0;
|
||||
XLS::RwU rwB = 0;
|
||||
short dyB = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
XLS::GlobalWorkbookInfoPtr global_info;
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
*/
|
||||
|
||||
#include "OfficeArtDgContainer.h"
|
||||
#include "SimpleOfficeArtContainers.h"
|
||||
|
||||
namespace ODRAW
|
||||
{
|
||||
@ -147,29 +148,39 @@ void OfficeArtDgContainer::loadFields(XLS::CFRecord& record)
|
||||
|
||||
void OfficeArtDgContainer::save(XLS::CFRecord& record)
|
||||
{
|
||||
rh_own.recVer = 0xF;
|
||||
rh_own.recInstance = 0;
|
||||
rh_own.recType = 0xF002;
|
||||
record << rh_own;
|
||||
auto sizePos = record.getRdPtr();
|
||||
if(m_OfficeArtFDG != nullptr)
|
||||
m_OfficeArtFDG->save(record);
|
||||
if(m_OfficeArtFRITContainer != nullptr)
|
||||
m_OfficeArtFRITContainer->save(record);
|
||||
if(m_OfficeArtSpgrContainer != nullptr)
|
||||
m_OfficeArtSpgrContainer->save(record);
|
||||
auto sizePos = 0;
|
||||
if(first)
|
||||
{
|
||||
rh_own.recVer = 0xF;
|
||||
rh_own.recInstance = 0;
|
||||
rh_own.recType = 0xF002;
|
||||
record << rh_own;
|
||||
sizePos = record.getRdPtr();
|
||||
if(m_OfficeArtFDG != nullptr)
|
||||
m_OfficeArtFDG->save(record);
|
||||
if(m_OfficeArtFRITContainer != nullptr)
|
||||
m_OfficeArtFRITContainer->save(record);
|
||||
if(m_OfficeArtSpgrContainer != nullptr)
|
||||
{
|
||||
auto castedContainer = static_cast<OfficeArtSpgrContainer*>(m_OfficeArtSpgrContainer.get());
|
||||
castedContainer->rh_own.recLen += totalSize;
|
||||
m_OfficeArtSpgrContainer->save(record);
|
||||
}
|
||||
}
|
||||
for(auto i : m_OfficeArtSpContainer)
|
||||
if(i != nullptr)
|
||||
i->save(record);
|
||||
if(m_OfficeArtSpgrContainerFileBlock != nullptr)
|
||||
m_OfficeArtSpgrContainerFileBlock->save(record);
|
||||
|
||||
//calculating size
|
||||
rh_own.recLen = record.getRdPtr() - sizePos;
|
||||
record.RollRdPtrBack(rh_own.recLen + 4);
|
||||
auto recLen = rh_own.recLen;
|
||||
record << recLen;
|
||||
record.skipNunBytes(rh_own.recLen);
|
||||
if(first)
|
||||
{
|
||||
//calculating size
|
||||
rh_own.recLen = record.getRdPtr() - sizePos;
|
||||
record.RollRdPtrBack(rh_own.recLen + 4);
|
||||
auto recLen = rh_own.recLen + totalSize;
|
||||
record << recLen;
|
||||
record.skipNunBytes(rh_own.recLen);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ODRAW
|
||||
|
||||
@ -62,6 +62,8 @@ public:
|
||||
OfficeArtRecordPtr m_OfficeArtSpgrContainer;
|
||||
std::vector<OfficeArtRecordPtr> m_OfficeArtSpContainer;
|
||||
OfficeArtRecordPtr m_OfficeArtSpgrContainerFileBlock;
|
||||
bool first = true;
|
||||
unsigned int totalSize = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<OfficeArtDgContainer> OfficeArtDgContainerPtr;
|
||||
|
||||
@ -61,4 +61,17 @@ void OfficeArtFDGGBlock::loadFields(XLS::CFRecord& record)
|
||||
}
|
||||
}
|
||||
|
||||
void OfficeArtFDGGBlock::save(XLS::CFRecord& record)
|
||||
{
|
||||
rh_own.recVer = 0;
|
||||
rh_own.recInstance = 0;
|
||||
rh_own.recType = 0xF006;
|
||||
rh_own.recLen = 0x10 + Rgidcl.size()*8;
|
||||
record << rh_own;
|
||||
_UINT32 cidcl = Rgidcl.size()+1;
|
||||
record << spidMax << cidcl << cspSaved << cdgSaved;
|
||||
for(auto i : Rgidcl)
|
||||
i.save(record);
|
||||
}
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -53,10 +53,11 @@ public:
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtFDGGBlock;
|
||||
|
||||
virtual void loadFields(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
_UINT32 spidMax;
|
||||
_UINT32 cspSaved;
|
||||
_UINT32 cdgSaved;
|
||||
_UINT32 spidMax = 0x02FFD7FF;
|
||||
_UINT32 cspSaved = 1;
|
||||
_UINT32 cdgSaved = 0;
|
||||
|
||||
std::vector<OfficeArtIDCL> Rgidcl;
|
||||
};
|
||||
|
||||
@ -76,10 +76,10 @@ public:
|
||||
virtual void ReadComplexData(XLS::CFRecord& record);
|
||||
virtual void ReadComplexData(IBinaryReader* reader);
|
||||
|
||||
unsigned short opid;
|
||||
bool fBid;
|
||||
bool fComplex;
|
||||
_INT32 op;
|
||||
unsigned short opid = 0;
|
||||
bool fBid = false;
|
||||
bool fComplex = false;
|
||||
_INT32 op = 0;
|
||||
};
|
||||
|
||||
class FillColor : public OfficeArtFOPTE
|
||||
@ -1068,50 +1068,47 @@ public:
|
||||
{
|
||||
case ODRAW::rtLineTo:
|
||||
{
|
||||
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; ++j)
|
||||
{
|
||||
if (valuePointer + 1 > m_arPoints.size())
|
||||
{
|
||||
break;
|
||||
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; j++)
|
||||
{
|
||||
if (valuePointer + 1 > m_arPoints.size())
|
||||
{
|
||||
break;
|
||||
|
||||
strVmlPath += L"l";
|
||||
strVmlPath += std::to_wstring(m_arPoints[0].x);
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[0].y);
|
||||
strVmlPath += L"l";
|
||||
strVmlPath += std::to_wstring(m_arPoints[0].x);
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[0].y);
|
||||
|
||||
++valuePointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
strVmlPath += L"l";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
|
||||
++valuePointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
strVmlPath += L"l";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
|
||||
|
||||
++valuePointer;
|
||||
}
|
||||
}
|
||||
++valuePointer;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case ODRAW::rtCurveTo:
|
||||
{
|
||||
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; ++j)
|
||||
{
|
||||
if (valuePointer + 3 > m_arPoints.size())
|
||||
break;
|
||||
strVmlPath += L"c";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].y );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].y );
|
||||
valuePointer += 3;
|
||||
}
|
||||
if (valuePointer + 3 > m_arPoints.size())
|
||||
break;
|
||||
strVmlPath += L"c";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].y );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].x );
|
||||
strVmlPath += L",";
|
||||
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].y );
|
||||
valuePointer += 3;
|
||||
}break;
|
||||
case ODRAW::rtMoveTo:
|
||||
{
|
||||
@ -1126,6 +1123,16 @@ public:
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ODRAW::rtNoFill:
|
||||
{
|
||||
strVmlPath += L"nf";
|
||||
}
|
||||
break;
|
||||
case ODRAW::rtNoStroke:
|
||||
{
|
||||
strVmlPath += L"ns";
|
||||
}
|
||||
break;
|
||||
case ODRAW::rtClose:
|
||||
{
|
||||
strVmlPath += L"x";
|
||||
|
||||
@ -46,5 +46,10 @@ void OfficeArtIDCL::load(XLS::CFRecord& record)
|
||||
record >> dgid >> cspidCur;
|
||||
}
|
||||
|
||||
void OfficeArtIDCL::save(XLS::CFRecord& record)
|
||||
{
|
||||
record << dgid << cspidCur;
|
||||
}
|
||||
|
||||
|
||||
} // namespace XLS
|
||||
|
||||
@ -50,10 +50,11 @@ public:
|
||||
static const XLS::ElementType type = XLS::typeOfficeArtIDCL;
|
||||
|
||||
virtual void load(XLS::CFRecord& record);
|
||||
virtual void save(XLS::CFRecord& record);
|
||||
|
||||
|
||||
_UINT32 dgid;
|
||||
_UINT32 cspidCur;
|
||||
_UINT32 dgid = 0;
|
||||
_UINT32 cspidCur = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<OfficeArtIDCL> OfficeArtIDCLPtr;
|
||||
|
||||
@ -69,7 +69,7 @@ public:
|
||||
std::vector<OfficeArtFOPTEPtr> Transform_props;
|
||||
std::vector<OfficeArtFOPTEPtr> Other_props;
|
||||
|
||||
unsigned short options_count;
|
||||
unsigned short options_count = 0;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<OfficeArtRGFOPTE> OfficeArtRGFOPTEPtr;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user