mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Compare commits
197 Commits
v8.3.0.59
...
fix/boolea
| Author | SHA1 | Date | |
|---|---|---|---|
| ce1763501b | |||
| 896427db83 | |||
| 2f4b7442c7 | |||
| 45da53e9ae | |||
| a33743cff2 | |||
| a83e19cbdf | |||
| 8a991ae24a | |||
| 6caca87b64 | |||
| 9ab884ae24 | |||
| e493d976e3 | |||
| d75e7342cf | |||
| ddd750be9c | |||
| 79a4434583 | |||
| 44ff2aff3c | |||
| 2f4b3e41b3 | |||
| fe208f5243 | |||
| e41c1d9703 | |||
| 5c5f98a6e3 | |||
| f9dd82ad47 | |||
| 084c8f4b94 | |||
| bf15325a9e | |||
| 1b50b3a53a | |||
| 70b40c46d2 | |||
| 23798f3c96 | |||
| 1e8d22080d | |||
| 90bcd47fb7 | |||
| c1adf0b30c | |||
| 81a4d9ccd0 | |||
| a97014c173 | |||
| b3951d083a | |||
| 7d78b37540 | |||
| ff162d451e | |||
| 5dc6402006 | |||
| fae17d9bfc | |||
| 931f4edae4 | |||
| 3609cf1237 | |||
| cc8fa641aa | |||
| 3b9a865d77 | |||
| f3b0a992bd | |||
| 74f3e7f279 | |||
| d195aa4a79 | |||
| 4a384edf08 | |||
| 30f96cbc6c | |||
| 007362d8be | |||
| f4aac048ea | |||
| f815fec8ed | |||
| 4ec217226d | |||
| 3cef41e876 | |||
| 20bff1d6fe | |||
| 8da1a109de | |||
| 704cef604e | |||
| 3c850e2086 | |||
| ab660cb8a3 | |||
| af4343b1d8 | |||
| 7e4fe558f4 | |||
| f942e56361 | |||
| 8b85f6987f | |||
| cbe412d3c7 | |||
| d3d9c8df94 | |||
| 01b582c4b9 | |||
| 4568144a22 | |||
| cc4df3726a | |||
| 696610862a | |||
| da6a5e9e98 | |||
| d395e63b80 | |||
| 0350675df6 | |||
| aead2e9fb8 | |||
| d12bad7bd1 | |||
| da2284fff6 | |||
| 1382aa0b3d | |||
| 8ba5df60d9 | |||
| 5299872b17 | |||
| e1757dd5d1 | |||
| b5c5a5f1ed | |||
| 6979e17c3d | |||
| c43fb92860 | |||
| 63887c95b6 | |||
| d3d4e86925 | |||
| f6383571eb | |||
| a6f6a67aed | |||
| f9543ef9de | |||
| bb58be4f18 | |||
| 40efe7dabc | |||
| 80b7caaf7a | |||
| 08e3dfb061 | |||
| 3a9d91b291 | |||
| 45b26554b2 | |||
| 09c4df8e05 | |||
| 85533a6553 | |||
| 65898a94ad | |||
| 86009ff6fa | |||
| b91dfb075e | |||
| f057a16bc1 | |||
| bd76adc97f | |||
| 27b5dbf15e | |||
| 58a7c7cd9d | |||
| 18fa4639b0 | |||
| 389e5314df | |||
| 42636a8ab1 | |||
| a3c87e7119 | |||
| 2115371c0c | |||
| bd95478d77 | |||
| 965680de23 | |||
| ad44ddf682 | |||
| 06386d5458 | |||
| ffda83848d | |||
| 55dc0b789f | |||
| 53e3f8c561 | |||
| 731a7addee | |||
| 36b82c1ef9 | |||
| 229a8f9dad | |||
| 5f5d74df92 | |||
| 66ea88bf14 | |||
| 3953044063 | |||
| 9a4a1546cb | |||
| 4085ee5002 | |||
| f6ef582658 | |||
| 7b62295149 | |||
| 421dcd780d | |||
| b9e7a3143c | |||
| 6026841c00 | |||
| 1e6d0a9f25 | |||
| adad3a05ba | |||
| 99fa27e693 | |||
| 6b66c8fb50 | |||
| 9faa7fb69d | |||
| 84042360ab | |||
| 8a8a6e78eb | |||
| 8bd655dd17 | |||
| 34ecf84835 | |||
| 4cf79c985d | |||
| 18e359c1a6 | |||
| dc777f43d9 | |||
| 8cd7ca9731 | |||
| 8f91c47178 | |||
| fdac954df5 | |||
| 70c98eb9f3 | |||
| 024efd2e35 | |||
| da252bfa5e | |||
| c9ce68eab3 | |||
| 3af549a158 | |||
| 34627ff1c5 | |||
| 0c2b49af11 | |||
| 4324ea847c | |||
| df76ff3778 | |||
| 172bb09305 | |||
| aa0ba83d32 | |||
| fb934ef527 | |||
| a2b817bbc2 | |||
| ecd80408e2 | |||
| b78e2cb33c | |||
| f0c52d2e81 | |||
| 23ac269339 | |||
| 8239d6f51d | |||
| 3adf336384 | |||
| 8e1810697f | |||
| 7c2105b613 | |||
| 2027defafb | |||
| 2ea586ec6f | |||
| a6940c42ac | |||
| 6ed1cb60d6 | |||
| 2c9e58280b | |||
| f18b50cd4f | |||
| aa2af5d280 | |||
| dde69ba65f | |||
| f51b58c927 | |||
| 43f1ac0596 | |||
| 02bd5c4b0b | |||
| 6c79ab37fa | |||
| fdcb2cf7ba | |||
| 07bf7a44aa | |||
| a2bfbd8368 | |||
| 25553904df | |||
| 954ef08975 | |||
| 00abbab370 | |||
| 91eb74773b | |||
| 5b8d2660aa | |||
| 36b0cc524e | |||
| 5f2d7b2f5a | |||
| 02aeaa6a64 | |||
| 48d86cb7ce | |||
| 9991cc8c03 | |||
| 36a3b693d5 | |||
| d58424d089 | |||
| fe2ca8c566 | |||
| 20d2ff7954 | |||
| b125c19d02 | |||
| 2f2d11a5f6 | |||
| de4897fdef | |||
| f9952d0f94 | |||
| d7b435a446 | |||
| 168dc1ddb8 | |||
| 8918b7fae0 | |||
| 925ffa09e2 | |||
| 10ff332f4d | |||
| ce0f8251d3 | |||
| 42466cf648 |
@ -25,7 +25,7 @@ namespace NSCSS
|
||||
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_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform){}
|
||||
|
||||
CCompiledStyle::~CCompiledStyle()
|
||||
{
|
||||
@ -44,6 +44,7 @@ namespace NSCSS
|
||||
m_oPadding += oElement.m_oPadding;
|
||||
m_oText += oElement.m_oText;
|
||||
m_oDisplay += oElement.m_oDisplay;
|
||||
m_oTransform += oElement.m_oTransform;
|
||||
|
||||
if (!oElement.m_sId.empty())
|
||||
m_sId += L'+' + oElement.m_sId;
|
||||
@ -66,6 +67,7 @@ namespace NSCSS
|
||||
m_oPadding = oElement.m_oPadding;
|
||||
m_oText = oElement.m_oText;
|
||||
m_oDisplay = oElement.m_oDisplay;
|
||||
m_oTransform = oElement.m_oTransform;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -78,7 +80,8 @@ namespace NSCSS
|
||||
m_oMargin == oStyle.m_oMargin &&
|
||||
m_oPadding == oStyle.m_oPadding &&
|
||||
m_oText == oStyle.m_oText &&
|
||||
m_oDisplay == oStyle.m_oDisplay;
|
||||
m_oDisplay == oStyle.m_oDisplay &&
|
||||
m_oTransform == oStyle.m_oTransform;
|
||||
}
|
||||
|
||||
void CCompiledStyle::StyleEquation(CCompiledStyle &oFirstStyle, CCompiledStyle &oSecondStyle)
|
||||
@ -90,6 +93,7 @@ namespace NSCSS
|
||||
NSProperties::CText ::Equation(oFirstStyle.m_oText, oSecondStyle.m_oText);
|
||||
NSProperties::CBorder ::Equation(oFirstStyle.m_oBorder, oSecondStyle.m_oBorder);
|
||||
NSProperties::CDisplay ::Equation(oFirstStyle.m_oDisplay, oSecondStyle.m_oDisplay);
|
||||
NSProperties::CTransform ::Equation(oFirstStyle.m_oTransform, oSecondStyle.m_oTransform);
|
||||
}
|
||||
|
||||
void CCompiledStyle::SetDpi(const unsigned short &uiDpi)
|
||||
@ -431,6 +435,12 @@ namespace NSCSS
|
||||
m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode);
|
||||
break;
|
||||
}
|
||||
//TRANSFORM
|
||||
CASE(L"transform"):
|
||||
{
|
||||
m_oTransform.SetMatrix(pPropertie.second, unLevel, bHardMode);
|
||||
break;
|
||||
}
|
||||
default: AddOtherStyle(pPropertie, unLevel, bHardMode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,11 +31,12 @@ namespace NSCSS
|
||||
NSProperties::CText m_oText;
|
||||
NSProperties::CBorder m_oBorder;
|
||||
NSProperties::CDisplay m_oDisplay;
|
||||
NSProperties::CTransform m_oTransform;
|
||||
|
||||
CCompiledStyle();
|
||||
CCompiledStyle(const CCompiledStyle& oStyle);
|
||||
|
||||
~CCompiledStyle();
|
||||
virtual ~CCompiledStyle();
|
||||
|
||||
void SetDpi(const unsigned short& uiDpi);
|
||||
void SetUnitMeasure(const UnitMeasure& enUnitMeasure);
|
||||
|
||||
@ -63,6 +63,26 @@ namespace NSCSS
|
||||
return m_pInternal->GetDpi();
|
||||
}
|
||||
|
||||
void CCssCalculator::ClearPageData()
|
||||
{
|
||||
m_pInternal->ClearPageData();
|
||||
}
|
||||
|
||||
void CCssCalculator::ClearEmbeddedStyles()
|
||||
{
|
||||
m_pInternal->ClearEmbeddedStyles();
|
||||
}
|
||||
|
||||
void CCssCalculator::ClearAllowedStyleFiles()
|
||||
{
|
||||
m_pInternal->ClearAllowedStyleFiles();
|
||||
}
|
||||
|
||||
void CCssCalculator::ClearStylesFromFile(const std::wstring& wsFilePath)
|
||||
{
|
||||
m_pInternal->ClearStylesFromFile(wsFilePath);
|
||||
}
|
||||
|
||||
void CCssCalculator::Clear()
|
||||
{
|
||||
m_pInternal->Clear();
|
||||
|
||||
@ -35,6 +35,10 @@ namespace NSCSS
|
||||
std::wstring GetEncoding() const;
|
||||
unsigned short int GetDpi() const;
|
||||
|
||||
void ClearPageData();
|
||||
void ClearEmbeddedStyles();
|
||||
void ClearAllowedStyleFiles();
|
||||
void ClearStylesFromFile(const std::wstring& wsFilePath);
|
||||
void Clear();
|
||||
};
|
||||
}
|
||||
|
||||
@ -5,12 +5,9 @@
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
|
||||
#include "../../katana-parser/src/selector.h"
|
||||
#include "../../../../../UnicodeConverter/UnicodeConverter.h"
|
||||
#include "ConstValues.h"
|
||||
#include "../../../../../DesktopEditor/common/File.h"
|
||||
#include "StaticFunctions.h"
|
||||
|
||||
@ -41,58 +38,120 @@ bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vect
|
||||
|
||||
namespace NSCSS
|
||||
{
|
||||
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
|
||||
CStyleStorage::CStyleStorage()
|
||||
{}
|
||||
|
||||
CCssCalculator_Private::~CCssCalculator_Private()
|
||||
CStyleStorage::~CStyleStorage()
|
||||
{
|
||||
m_arFiles.clear();
|
||||
|
||||
for (std::map<std::wstring, CElement*>::iterator oIter = m_mData.begin(); oIter != m_mData.end(); ++oIter)
|
||||
if (oIter->second != NULL)
|
||||
delete oIter->second;
|
||||
|
||||
m_mData.clear();
|
||||
Clear();
|
||||
}
|
||||
|
||||
inline void CCssCalculator_Private::GetOutputData(KatanaOutput *oOutput)
|
||||
void CStyleStorage::Clear()
|
||||
{
|
||||
if ( NULL == oOutput )
|
||||
return;
|
||||
for (TStyleFileData* pStyleFileData : m_arStyleFiles)
|
||||
{
|
||||
if (nullptr == pStyleFileData)
|
||||
continue;
|
||||
|
||||
switch (oOutput->mode) {
|
||||
case KatanaParserModeStylesheet:
|
||||
GetStylesheet(oOutput->stylesheet);
|
||||
break;
|
||||
case KatanaParserModeRule:
|
||||
GetRule(oOutput->rule);
|
||||
break;
|
||||
case KatanaParserModeKeyframeRule:
|
||||
case KatanaParserModeKeyframeKeyList:
|
||||
case KatanaParserModeMediaList:
|
||||
case KatanaParserModeValue:
|
||||
case KatanaParserModeSelector:
|
||||
case KatanaParserModeDeclarationList:
|
||||
break;
|
||||
for (std::map<std::wstring, CElement*>::iterator oIter = pStyleFileData->m_mStyleData.begin(); oIter != pStyleFileData->m_mStyleData.end(); ++oIter)
|
||||
if (oIter->second != nullptr)
|
||||
delete oIter->second;
|
||||
|
||||
delete pStyleFileData;
|
||||
}
|
||||
|
||||
m_arStyleFiles.clear();
|
||||
m_arEmptyStyleFiles.clear();
|
||||
|
||||
ClearEmbeddedStyles();
|
||||
ClearAllowedStyleFiles();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
ClearPageData();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CStyleStorage::AddStyles(const std::string& sStyle)
|
||||
{
|
||||
if (sStyle.empty())
|
||||
return;
|
||||
|
||||
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
|
||||
this->GetOutputData(output, m_mEmbeddedStyleData);
|
||||
katana_destroy_output(output);
|
||||
}
|
||||
|
||||
void CStyleStorage::AddStyles(const std::wstring& wsStyle)
|
||||
{
|
||||
if (wsStyle.empty())
|
||||
return;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
|
||||
std::wsmatch oMatch;
|
||||
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
|
||||
|
||||
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
|
||||
{
|
||||
AddPageData(oMatch[1].str(), oMatch[2].str());
|
||||
oSearchStart = oMatch.suffix().first;
|
||||
}
|
||||
#endif
|
||||
|
||||
AddStyles(U_TO_UTF8(wsStyle));
|
||||
}
|
||||
|
||||
void CStyleStorage::AddStylesFromFile(const std::wstring& wsFileName)
|
||||
{
|
||||
std::set<std::wstring>::const_iterator itEmptyFileFound = m_arEmptyStyleFiles.find(wsFileName);
|
||||
|
||||
if (m_arEmptyStyleFiles.cend() != itEmptyFileFound)
|
||||
return;
|
||||
|
||||
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
|
||||
[wsFileName](const TStyleFileData* pStyleFileData)
|
||||
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
|
||||
|
||||
m_arAllowedStyleFiles.insert(wsFileName);
|
||||
|
||||
if (m_arStyleFiles.cend() != itFound)
|
||||
return;
|
||||
|
||||
TStyleFileData *pStyleFileData = new TStyleFileData();
|
||||
|
||||
pStyleFileData->m_wsStyleFilepath = wsFileName;
|
||||
|
||||
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName), pStyleFileData->m_mStyleData);
|
||||
|
||||
if (!pStyleFileData->m_mStyleData.empty())
|
||||
m_arStyleFiles.push_back(pStyleFileData);
|
||||
else
|
||||
{
|
||||
m_arEmptyStyleFiles.insert(wsFileName);
|
||||
delete pStyleFileData;
|
||||
}
|
||||
}
|
||||
|
||||
void CStyleStorage::ClearStylesFromFile(const std::wstring& wsFileName)
|
||||
{
|
||||
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
|
||||
[wsFileName](const TStyleFileData* pStyleFileData)
|
||||
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
|
||||
|
||||
if (m_arStyleFiles.cend() != itFound)
|
||||
{
|
||||
m_arStyleFiles.erase(itFound);
|
||||
delete *itFound;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
|
||||
void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles)
|
||||
{
|
||||
if (m_arPageDatas.empty())
|
||||
return {};
|
||||
|
||||
for (const TPageData& oPageData : m_arPageDatas)
|
||||
{
|
||||
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
|
||||
return oPageData.m_mData;
|
||||
}
|
||||
|
||||
return {};
|
||||
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
|
||||
|
||||
void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode)
|
||||
{
|
||||
for (const std::pair<std::wstring, std::wstring> &oData : mData)
|
||||
{
|
||||
@ -107,149 +166,84 @@ namespace NSCSS
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
|
||||
std::map<std::wstring, std::wstring> CStyleStorage::GetPageData(const std::wstring& wsPageName)
|
||||
{
|
||||
std::vector<std::wstring> arNodes;
|
||||
|
||||
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
|
||||
{
|
||||
if (!oNode->m_wsName.empty())
|
||||
arNodes.push_back(oNode->m_wsName);
|
||||
|
||||
if (!oNode->m_wsClass.empty())
|
||||
{
|
||||
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
|
||||
{
|
||||
std::vector<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' ';}));
|
||||
}
|
||||
else
|
||||
arNodes.push_back(L'.' + oNode->m_wsClass);
|
||||
}
|
||||
|
||||
if (!oNode->m_wsId.empty())
|
||||
arNodes.push_back(L'#' + oNode->m_wsId);
|
||||
}
|
||||
|
||||
return arNodes;
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
|
||||
{
|
||||
if (arNextNodes.empty())
|
||||
return;
|
||||
|
||||
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
|
||||
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
|
||||
|
||||
if (!arTempPrev.empty())
|
||||
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
|
||||
|
||||
if (!arTempKins.empty())
|
||||
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
|
||||
}
|
||||
|
||||
std::vector<CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
|
||||
{
|
||||
if (arNodes.empty())
|
||||
if (m_arPageDatas.empty())
|
||||
return {};
|
||||
|
||||
std::vector<CElement*> arFindedElements;
|
||||
|
||||
std::wstring wsName, wsId;
|
||||
std::vector<std::wstring> arClasses;
|
||||
|
||||
if (!arNodes.empty() && arNodes.back()[0] == L'#')
|
||||
for (const TPageData& oPageData : m_arPageDatas)
|
||||
{
|
||||
wsId = arNodes.back();
|
||||
arNodes.pop_back();
|
||||
arNextNodes.push_back(wsId);
|
||||
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
|
||||
return oPageData.m_mData;
|
||||
}
|
||||
|
||||
if (!arNodes.empty() && arNodes.back()[0] == L'.')
|
||||
{
|
||||
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
|
||||
arNextNodes.push_back(arNodes.back());
|
||||
arNodes.pop_back();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!arNodes.empty())
|
||||
{
|
||||
wsName = arNodes.back();
|
||||
arNodes.pop_back();
|
||||
arNextNodes.push_back(wsName);
|
||||
}
|
||||
|
||||
const std::map<std::wstring, CElement*>::const_iterator oFindName = m_mData.find(wsName);
|
||||
std::map<std::wstring, CElement*>::const_iterator oFindId;
|
||||
|
||||
if (!wsId.empty())
|
||||
{
|
||||
oFindId = m_mData.find(wsId);
|
||||
|
||||
if (m_mData.cend() != oFindId)
|
||||
{
|
||||
if (!oFindId->second->Empty())
|
||||
arFindedElements.push_back(oFindId->second);
|
||||
|
||||
FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!arClasses.empty())
|
||||
{
|
||||
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
|
||||
{
|
||||
const std::map<std::wstring, CElement*>::const_iterator oFindClass = m_mData.find(*iClass);
|
||||
if (oFindClass != m_mData.cend())
|
||||
{
|
||||
if (!oFindClass->second->Empty())
|
||||
arFindedElements.push_back(oFindClass->second);
|
||||
|
||||
FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oFindName != m_mData.cend())
|
||||
{
|
||||
if (!oFindName->second->Empty())
|
||||
arFindedElements.push_back(oFindName->second);
|
||||
|
||||
FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses);
|
||||
}
|
||||
|
||||
if (arFindedElements.size() > 1)
|
||||
{
|
||||
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
|
||||
[](CElement* oFirstElement, CElement* oSecondElement)
|
||||
{
|
||||
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
|
||||
});
|
||||
}
|
||||
|
||||
return arFindedElements;
|
||||
void CStyleStorage::ClearPageData()
|
||||
{
|
||||
m_arPageDatas.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles)
|
||||
const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector)
|
||||
{
|
||||
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
|
||||
if (wsSelector.empty())
|
||||
return nullptr;
|
||||
|
||||
const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mEmbeddedStyleData);
|
||||
|
||||
if (nullptr != pFoundElement)
|
||||
return pFoundElement;
|
||||
|
||||
for (std::vector<TStyleFileData*>::const_reverse_iterator itIter = m_arStyleFiles.crbegin(); itIter < m_arStyleFiles.crend(); ++itIter)
|
||||
{
|
||||
if (m_arAllowedStyleFiles.cend() == std::find(m_arAllowedStyleFiles.cbegin(), m_arAllowedStyleFiles.cend(), (*itIter)->m_wsStyleFilepath))
|
||||
continue;
|
||||
|
||||
pFoundElement = FindSelectorFromStyleData(wsSelector, (*itIter)->m_mStyleData);
|
||||
|
||||
if (nullptr != pFoundElement)
|
||||
return pFoundElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet)
|
||||
|
||||
void CStyleStorage::AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
if (sStyle.empty())
|
||||
return;
|
||||
|
||||
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
|
||||
this->GetOutputData(output, mStyleData);
|
||||
katana_destroy_output(output);
|
||||
}
|
||||
|
||||
void CStyleStorage::ClearEmbeddedStyles()
|
||||
{
|
||||
for (std::map<std::wstring, CElement*>::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter)
|
||||
if (oIter->second != nullptr)
|
||||
delete oIter->second;
|
||||
|
||||
m_mEmbeddedStyleData.clear();
|
||||
}
|
||||
|
||||
void CStyleStorage::ClearAllowedStyleFiles()
|
||||
{
|
||||
m_arAllowedStyleFiles.clear();
|
||||
}
|
||||
|
||||
void CStyleStorage::GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
for (size_t i = 0; i < oStylesheet->imports.length; ++i)
|
||||
GetRule((KatanaRule*)oStylesheet->imports.data[i]);
|
||||
GetRule((KatanaRule*)oStylesheet->imports.data[i], mStyleData);
|
||||
|
||||
for (size_t i = 0; i < oStylesheet->rules.length; ++i)
|
||||
GetRule((KatanaRule*)oStylesheet->rules.data[i]);
|
||||
GetRule((KatanaRule*)oStylesheet->rules.data[i], mStyleData);
|
||||
}
|
||||
|
||||
inline void CCssCalculator_Private::GetRule(const KatanaRule *oRule)
|
||||
void CStyleStorage::GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
if ( NULL == oRule )
|
||||
return;
|
||||
@ -257,7 +251,7 @@ namespace NSCSS
|
||||
switch (oRule->type) {
|
||||
case KatanaRuleStyle:
|
||||
{
|
||||
GetStyleRule((KatanaStyleRule*)oRule);
|
||||
GetStyleRule((KatanaStyleRule*)oRule, mStyleData);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -265,7 +259,7 @@ namespace NSCSS
|
||||
}
|
||||
}
|
||||
|
||||
inline void CCssCalculator_Private::GetStyleRule(const KatanaStyleRule *oRule)
|
||||
void CStyleStorage::GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
if (oRule->declarations->length == 0)
|
||||
return;
|
||||
@ -281,7 +275,7 @@ namespace NSCSS
|
||||
|
||||
for (std::vector<std::wstring>::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord)
|
||||
{
|
||||
const size_t posPoint = oWord->find(L'.');
|
||||
const size_t posPoint = oWord->find(L'.');
|
||||
const size_t posLattice = oWord->find(L'#');
|
||||
|
||||
const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord;
|
||||
@ -297,8 +291,8 @@ namespace NSCSS
|
||||
{
|
||||
if (NULL == oFirstElement && bCreateFirst)
|
||||
{
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindId = m_mData.find(sId);
|
||||
if (oFindId != m_mData.end())
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindId = mStyleData.find(sId);
|
||||
if (oFindId != mStyleData.end())
|
||||
{
|
||||
oIdElement = oFindId->second;
|
||||
bCreateFirst = false;
|
||||
@ -326,8 +320,8 @@ namespace NSCSS
|
||||
{
|
||||
if (NULL == oFirstElement && bCreateFirst)
|
||||
{
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = m_mData.find(sClass);
|
||||
if (oFindClass != m_mData.end())
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = mStyleData.find(sClass);
|
||||
if (oFindClass != mStyleData.end())
|
||||
{
|
||||
oClassElement = oFindClass->second;
|
||||
bCreateFirst = false;
|
||||
@ -359,8 +353,8 @@ namespace NSCSS
|
||||
{
|
||||
if (NULL == oFirstElement && bCreateFirst)
|
||||
{
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindName = m_mData.find(sName);
|
||||
if (oFindName != m_mData.end())
|
||||
const std::map<std::wstring, CElement*>::const_iterator& oFindName = mStyleData.find(sName);
|
||||
if (oFindName != mStyleData.end())
|
||||
{
|
||||
oNameElement = oFindName->second;
|
||||
bCreateFirst = false;
|
||||
@ -392,11 +386,16 @@ namespace NSCSS
|
||||
oLastElement->AddProperties(mStyle);
|
||||
|
||||
if (NULL != oFirstElement)
|
||||
m_mData[oFirstElement->GetSelector()] = oFirstElement;
|
||||
mStyleData[oFirstElement->GetSelector()] = oFirstElement;
|
||||
}
|
||||
}
|
||||
|
||||
inline std::vector<std::wstring> CCssCalculator_Private::GetSelectorList(const KatanaArray* oSelectors) const
|
||||
std::wstring CStyleStorage::GetValueList(const KatanaArray* oValues)
|
||||
{
|
||||
return StringifyValueList(oValues);
|
||||
}
|
||||
|
||||
std::vector<std::wstring> CStyleStorage::GetSelectorList(const KatanaArray* oSelectors) const
|
||||
{
|
||||
if (oSelectors->length == 0)
|
||||
return std::vector<std::wstring>();
|
||||
@ -409,7 +408,7 @@ namespace NSCSS
|
||||
return arSelectors;
|
||||
}
|
||||
|
||||
inline std::wstring CCssCalculator_Private::GetSelector(const KatanaSelector *oSelector) const
|
||||
std::wstring CStyleStorage::GetSelector(const KatanaSelector* oSelector) const
|
||||
{
|
||||
KatanaParser oParser;
|
||||
oParser.options = &kKatanaDefaultOptions;
|
||||
@ -428,7 +427,7 @@ namespace NSCSS
|
||||
return wsText;
|
||||
}
|
||||
|
||||
inline std::map<std::wstring, std::wstring> CCssCalculator_Private::GetDeclarationList(const KatanaArray* oDeclarations) const
|
||||
std::map<std::wstring, std::wstring> CStyleStorage::GetDeclarationList(const KatanaArray* oDeclarations) const
|
||||
{
|
||||
if(oDeclarations->length == 0)
|
||||
return std::map<std::wstring, std::wstring>();
|
||||
@ -441,7 +440,7 @@ namespace NSCSS
|
||||
return arDeclarations;
|
||||
}
|
||||
|
||||
inline std::pair<std::wstring, std::wstring> CCssCalculator_Private::GetDeclaration(const KatanaDeclaration* oDecl) const
|
||||
std::pair<std::wstring, std::wstring> CStyleStorage::GetDeclaration(const KatanaDeclaration* oDecl) const
|
||||
{
|
||||
std::wstring sValueList = StringifyValueList(oDecl->values);
|
||||
|
||||
@ -451,9 +450,184 @@ namespace NSCSS
|
||||
return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList);
|
||||
}
|
||||
|
||||
inline std::wstring CCssCalculator_Private::GetValueList(const KatanaArray *oValues)
|
||||
void CStyleStorage::GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
return StringifyValueList(oValues);
|
||||
if ( NULL == oOutput )
|
||||
return;
|
||||
|
||||
switch (oOutput->mode) {
|
||||
case KatanaParserModeStylesheet:
|
||||
GetStylesheet(oOutput->stylesheet, mStyleData);
|
||||
break;
|
||||
case KatanaParserModeRule:
|
||||
GetRule(oOutput->rule, mStyleData);
|
||||
break;
|
||||
case KatanaParserModeKeyframeRule:
|
||||
case KatanaParserModeKeyframeKeyList:
|
||||
case KatanaParserModeMediaList:
|
||||
case KatanaParserModeValue:
|
||||
case KatanaParserModeSelector:
|
||||
case KatanaParserModeDeclarationList:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData)
|
||||
{
|
||||
std::map<std::wstring, CElement*>::const_iterator itFound = mStyleData.find(wsSelector);
|
||||
|
||||
if (mStyleData.cend() != itFound)
|
||||
return itFound->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
|
||||
|
||||
CCssCalculator_Private::~CCssCalculator_Private()
|
||||
{}
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
|
||||
{
|
||||
//TODO:: пересмотреть данный метод
|
||||
m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode);
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
|
||||
{
|
||||
return m_oStyleStorage.GetPageData(wsPageName);
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::ClearPageData()
|
||||
{
|
||||
m_oStyleStorage.ClearPageData();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
|
||||
{
|
||||
std::vector<std::wstring> arNodes;
|
||||
|
||||
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
|
||||
{
|
||||
if (!oNode->m_wsName.empty())
|
||||
arNodes.push_back(oNode->m_wsName);
|
||||
|
||||
if (!oNode->m_wsClass.empty())
|
||||
{
|
||||
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
|
||||
{
|
||||
std::vector<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' ';}));
|
||||
}
|
||||
else
|
||||
arNodes.push_back(L'.' + oNode->m_wsClass);
|
||||
}
|
||||
|
||||
if (!oNode->m_wsId.empty())
|
||||
arNodes.push_back(L'#' + oNode->m_wsId);
|
||||
}
|
||||
|
||||
return arNodes;
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
|
||||
{
|
||||
if (arNextNodes.empty())
|
||||
return;
|
||||
|
||||
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
|
||||
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
|
||||
|
||||
if (!arTempPrev.empty())
|
||||
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
|
||||
|
||||
if (!arTempKins.empty())
|
||||
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
|
||||
}
|
||||
|
||||
std::vector<const CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
|
||||
{
|
||||
if (arNodes.empty())
|
||||
return {};
|
||||
|
||||
std::vector<const CElement*> arFindedElements;
|
||||
|
||||
std::wstring wsName, wsId;
|
||||
std::vector<std::wstring> arClasses;
|
||||
|
||||
if (!arNodes.empty() && arNodes.back()[0] == L'#')
|
||||
{
|
||||
wsId = arNodes.back();
|
||||
arNodes.pop_back();
|
||||
arNextNodes.push_back(wsId);
|
||||
}
|
||||
|
||||
if (!arNodes.empty() && arNodes.back()[0] == L'.')
|
||||
{
|
||||
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
|
||||
arNextNodes.push_back(arNodes.back());
|
||||
arNodes.pop_back();
|
||||
}
|
||||
|
||||
if (!arNodes.empty())
|
||||
{
|
||||
wsName = arNodes.back();
|
||||
arNodes.pop_back();
|
||||
arNextNodes.push_back(wsName);
|
||||
}
|
||||
|
||||
if (!wsId.empty())
|
||||
{
|
||||
const CElement* pFoundId = m_oStyleStorage.FindElement(wsId);
|
||||
|
||||
if(nullptr != pFoundId)
|
||||
{
|
||||
if (!pFoundId->Empty())
|
||||
arFindedElements.push_back(pFoundId);
|
||||
|
||||
FindPrevAndKindElements(pFoundId, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!arClasses.empty())
|
||||
{
|
||||
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
|
||||
{
|
||||
const CElement* pFoundClass = m_oStyleStorage.FindElement(*iClass);
|
||||
|
||||
if (nullptr != pFoundClass)
|
||||
{
|
||||
if (!pFoundClass->Empty())
|
||||
arFindedElements.push_back(pFoundClass);
|
||||
|
||||
FindPrevAndKindElements(pFoundClass, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CElement* pFoundName = m_oStyleStorage.FindElement(wsName);
|
||||
|
||||
if (nullptr != pFoundName)
|
||||
{
|
||||
if (!pFoundName->Empty())
|
||||
arFindedElements.push_back(pFoundName);
|
||||
|
||||
FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses);
|
||||
}
|
||||
|
||||
if (arFindedElements.size() > 1)
|
||||
{
|
||||
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
|
||||
[](const CElement* oFirstElement, const CElement* oSecondElement)
|
||||
{ return oFirstElement->GetWeight() > oSecondElement->GetWeight(); });
|
||||
}
|
||||
|
||||
return arFindedElements;
|
||||
}
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
@ -566,42 +740,20 @@ namespace NSCSS
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
void CCssCalculator_Private::AddStyles(const std::string &sStyle)
|
||||
{
|
||||
if (sStyle.empty())
|
||||
return;
|
||||
|
||||
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
|
||||
this->GetOutputData(output);
|
||||
katana_destroy_output(output);
|
||||
void CCssCalculator_Private::AddStyles(const std::string& sStyle)
|
||||
{
|
||||
m_oStyleStorage.AddStyles(sStyle);
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::AddStyles(const std::wstring &wsStyle)
|
||||
void CCssCalculator_Private::AddStyles(const std::wstring& wsStyle)
|
||||
{
|
||||
if (wsStyle.empty())
|
||||
return;
|
||||
|
||||
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
|
||||
std::wsmatch oMatch;
|
||||
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
|
||||
|
||||
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
|
||||
{
|
||||
AddPageData(oMatch[1].str(), oMatch[2].str());
|
||||
oSearchStart = oMatch.suffix().first;
|
||||
}
|
||||
|
||||
AddStyles(U_TO_UTF8(wsStyle));
|
||||
m_oStyleStorage.AddStyles(wsStyle);
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::AddStylesFromFile(const std::wstring& wsFileName)
|
||||
{
|
||||
if (std::find(m_arFiles.begin(), m_arFiles.end(), wsFileName) != m_arFiles.end())
|
||||
return;
|
||||
|
||||
m_arFiles.push_back(wsFileName);
|
||||
|
||||
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName));
|
||||
m_oStyleStorage.AddStylesFromFile(wsFileName);
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::SetDpi(unsigned short int nValue)
|
||||
@ -614,9 +766,23 @@ namespace NSCSS
|
||||
return m_nDpi;
|
||||
}
|
||||
|
||||
const std::map<std::wstring, CElement *> *CCssCalculator_Private::GetData() const
|
||||
void CCssCalculator_Private::ClearEmbeddedStyles()
|
||||
{
|
||||
return &m_mData;
|
||||
m_oStyleStorage.ClearEmbeddedStyles();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
m_mUsedStyles.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::ClearAllowedStyleFiles()
|
||||
{
|
||||
m_oStyleStorage.ClearAllowedStyleFiles();
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath)
|
||||
{
|
||||
m_oStyleStorage.ClearStylesFromFile(wsFilePath);
|
||||
}
|
||||
|
||||
std::wstring CCssCalculator_Private::GetEncoding() const
|
||||
@ -629,10 +795,21 @@ namespace NSCSS
|
||||
m_sEncoding = L"UTF-8";
|
||||
m_nDpi = 96;
|
||||
|
||||
m_mData.clear();
|
||||
m_arFiles.clear();
|
||||
m_oStyleStorage.Clear();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
m_mUsedStyles.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsTableElement(const std::wstring& wsNameTag)
|
||||
{
|
||||
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
|
||||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
|
||||
L"th" == wsNameTag;
|
||||
}
|
||||
}
|
||||
|
||||
inline static std::wstring StringifyValueList(const KatanaArray* oValues)
|
||||
{
|
||||
if (NULL == oValues)
|
||||
@ -733,11 +910,4 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue)
|
||||
return str;
|
||||
}
|
||||
|
||||
inline static bool IsTableElement(const std::wstring& wsNameTag)
|
||||
{
|
||||
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
|
||||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
|
||||
L"th" == wsNameTag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,11 +3,9 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include "CElement.h"
|
||||
#include "ConstValues.h"
|
||||
#include "CUnitMeasureConverter.h"
|
||||
#include "StyleProperties.h"
|
||||
#include "../../katana-parser/src/katana.h"
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
@ -16,15 +14,43 @@
|
||||
|
||||
namespace NSCSS
|
||||
{
|
||||
class CCssCalculator_Private
|
||||
class CStyleStorage
|
||||
{
|
||||
unsigned short int m_nDpi;
|
||||
unsigned short int m_nCountNodes;
|
||||
public:
|
||||
CStyleStorage();
|
||||
~CStyleStorage();
|
||||
|
||||
std::list<std::wstring> m_arFiles;
|
||||
void Clear();
|
||||
|
||||
std::map<std::wstring, CElement*> m_mData;
|
||||
void AddStyles(const std::string& sStyle);
|
||||
void AddStyles(const std::wstring& wsStyle);
|
||||
void AddStylesFromFile(const std::wstring& wsFileName);
|
||||
|
||||
void ClearEmbeddedStyles();
|
||||
void ClearAllowedStyleFiles();
|
||||
void ClearStylesFromFile(const std::wstring& wsFileName);
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
|
||||
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
|
||||
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
|
||||
void ClearPageData();
|
||||
#endif
|
||||
|
||||
const CElement* FindElement(const std::wstring& wsSelector);
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
std::wstring m_wsStyleFilepath;
|
||||
std::map<std::wstring, CElement*> m_mStyleData;
|
||||
} TStyleFileData;
|
||||
|
||||
std::set<std::wstring> m_arEmptyStyleFiles;
|
||||
std::set<std::wstring> m_arAllowedStyleFiles;
|
||||
std::vector<TStyleFileData*> m_arStyleFiles;
|
||||
std::map<std::wstring, CElement*> m_mEmbeddedStyleData;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
typedef struct
|
||||
{
|
||||
std::vector<std::wstring> m_wsNames;
|
||||
@ -32,27 +58,14 @@ namespace NSCSS
|
||||
} TPageData;
|
||||
|
||||
std::vector<TPageData> m_arPageDatas;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
|
||||
|
||||
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
|
||||
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
|
||||
|
||||
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
|
||||
|
||||
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
|
||||
std::vector<CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
|
||||
#endif
|
||||
private:
|
||||
void AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData);
|
||||
|
||||
std::wstring m_sEncoding;
|
||||
void GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData);
|
||||
void GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
|
||||
|
||||
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
|
||||
|
||||
void GetStylesheet(const KatanaStylesheet* oStylesheet);
|
||||
void GetRule(const KatanaRule* oRule);
|
||||
|
||||
void GetStyleRule(const KatanaStyleRule* oRule);
|
||||
void GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
|
||||
|
||||
std::wstring GetValueList(const KatanaArray* oValues);
|
||||
|
||||
@ -62,8 +75,28 @@ namespace NSCSS
|
||||
std::map<std::wstring, std::wstring> GetDeclarationList(const KatanaArray* oDeclarations) const;
|
||||
std::pair<std::wstring, std::wstring> GetDeclaration(const KatanaDeclaration* oDecl) const;
|
||||
|
||||
void GetOutputData(KatanaOutput* oOutput);
|
||||
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
|
||||
|
||||
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData);
|
||||
};
|
||||
|
||||
class CCssCalculator_Private
|
||||
{
|
||||
unsigned short int m_nDpi;
|
||||
unsigned short int m_nCountNodes;
|
||||
|
||||
CStyleStorage m_oStyleStorage;
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
|
||||
|
||||
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
|
||||
std::map<std::wstring, std::wstring> GetPageData(const std::wstring &wsPageName);
|
||||
#endif
|
||||
|
||||
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
|
||||
|
||||
std::wstring m_sEncoding;
|
||||
public:
|
||||
CCssCalculator_Private();
|
||||
~CCssCalculator_Private();
|
||||
@ -74,8 +107,13 @@ namespace NSCSS
|
||||
|
||||
std::wstring CalculateStyleId(const CNode& oNode);
|
||||
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector<CNode> &arSelectors);
|
||||
|
||||
void ClearPageData();
|
||||
#endif
|
||||
|
||||
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
|
||||
std::vector<const CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
|
||||
|
||||
void AddStyles(const std::string& sStyle);
|
||||
void AddStyles(const std::wstring& wsStyle);
|
||||
void AddStylesFromFile(const std::wstring& wsFileName);
|
||||
@ -85,10 +123,12 @@ namespace NSCSS
|
||||
std::wstring GetEncoding() const;
|
||||
unsigned short int GetDpi() const;
|
||||
|
||||
const std::map<std::wstring, CElement*>* GetData() const;
|
||||
|
||||
void ClearEmbeddedStyles();
|
||||
void ClearAllowedStyleFiles();
|
||||
void ClearStylesFromFile(const std::wstring& wsFilePath);
|
||||
void Clear();
|
||||
|
||||
};
|
||||
|
||||
inline bool IsTableElement(const std::wstring& wsNameTag);
|
||||
}
|
||||
#endif // CCSSCALCULATOR_PRIVATE_H
|
||||
|
||||
@ -40,6 +40,7 @@ namespace NSCSS
|
||||
{
|
||||
m_sSelector = sSelector;
|
||||
m_sFullSelector = m_sSelector;
|
||||
UpdateWeight();
|
||||
}
|
||||
|
||||
void NSCSS::CElement::AddPropertie(const std::wstring &sName, const std::wstring& sValue)
|
||||
@ -67,6 +68,7 @@ namespace NSCSS
|
||||
|
||||
m_arPrevElements.push_back(oPrevElement);
|
||||
oPrevElement->m_sFullSelector += L' ' + m_sFullSelector;
|
||||
UpdateWeight();
|
||||
}
|
||||
|
||||
void CElement::AddKinElement(CElement *oKinElement)
|
||||
@ -76,6 +78,7 @@ namespace NSCSS
|
||||
|
||||
m_arKinElements.push_back(oKinElement);
|
||||
oKinElement->m_sFullSelector += m_sFullSelector;
|
||||
oKinElement->UpdateWeight();
|
||||
}
|
||||
|
||||
std::map<std::wstring, std::wstring> CElement::GetStyle() const
|
||||
@ -230,11 +233,14 @@ namespace NSCSS
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<unsigned short> CElement::GetWeight()
|
||||
void CElement::UpdateWeight()
|
||||
{
|
||||
if (m_arWeight.empty())
|
||||
m_arWeight = NS_STATIC_FUNCTIONS::GetWeightSelector(m_sFullSelector);
|
||||
}
|
||||
|
||||
std::vector<unsigned short> CElement::GetWeight() const
|
||||
{
|
||||
return m_arWeight;
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,8 @@ namespace NSCSS
|
||||
|
||||
CElement *FindPrevElement(const std::wstring& sSelector) const;
|
||||
|
||||
std::vector<unsigned short int> GetWeight();
|
||||
void UpdateWeight();
|
||||
std::vector<unsigned short int> GetWeight() const;
|
||||
void IncreasedWeight();
|
||||
};
|
||||
}
|
||||
|
||||
@ -48,7 +48,6 @@ namespace NS_STATIC_FUNCTIONS
|
||||
if (sEncoding.empty())
|
||||
sEncoding = "utf-8";
|
||||
|
||||
|
||||
if (!sEncoding.empty() && sEncoding != "utf-8" && sEncoding != "UTF-8")
|
||||
{
|
||||
NSUnicodeConverter::CUnicodeConverter oConverter;
|
||||
|
||||
@ -917,6 +917,25 @@ namespace NSCSS
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring CColor::ToHEX() const
|
||||
{
|
||||
switch(m_enType)
|
||||
{
|
||||
case ColorRGB:
|
||||
{
|
||||
TRGB* pRGB = static_cast<TRGB*>(m_oValue);
|
||||
return ConvertRGBtoHEX(*pRGB);
|
||||
}
|
||||
case ColorHEX:
|
||||
{
|
||||
std::wstring *pValue = static_cast<std::wstring*>(m_oValue);
|
||||
return *pValue;
|
||||
}
|
||||
default:
|
||||
return std::wstring();
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring CColor::EquateToColor(const std::vector<std::pair<TRGB, std::wstring>> &arColors) const
|
||||
{
|
||||
if (arColors.empty())
|
||||
|
||||
@ -242,6 +242,7 @@ namespace NSCSS
|
||||
int ToInt() const override;
|
||||
double ToDouble() const override;
|
||||
std::wstring ToWString() const override;
|
||||
std::wstring ToHEX() const;
|
||||
std::wstring EquateToColor(const std::vector<std::pair<TRGB, std::wstring>>& arColors) const;
|
||||
TRGB ToRGB() const;
|
||||
|
||||
|
||||
@ -316,7 +316,7 @@ namespace NSCSS
|
||||
|
||||
std::wstring wsTextAlign{oStyle.m_oText.GetAlign().ToWString()};
|
||||
|
||||
if (wsTextAlign.empty() && bInTable)
|
||||
if (wsTextAlign.empty())
|
||||
wsTextAlign = oStyle.m_oDisplay.GetHAlign().ToWString();
|
||||
|
||||
oXmlElement.AddPropertiesInP(PProperties::P_Jc, wsTextAlign);
|
||||
@ -485,7 +485,7 @@ namespace NSCSS
|
||||
return;
|
||||
|
||||
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. + 0.5))); // Значения шрифта увеличивает на 2
|
||||
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
|
||||
|
||||
if (oStyle.m_oText.GetDecoration().m_oLine.Underline())
|
||||
oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single");
|
||||
|
||||
@ -38,6 +38,9 @@
|
||||
#include "../xml/include/xmlutils.h"
|
||||
#include "../fontengine/TextHyphen.h"
|
||||
|
||||
#define VALUE_TO_STRING(x) #x
|
||||
#define VALUE(x) VALUE_TO_STRING(x)
|
||||
|
||||
namespace NSDoctRenderer
|
||||
{
|
||||
class CAdditionalData
|
||||
@ -203,28 +206,14 @@ namespace NSDoctRenderer
|
||||
|
||||
char* GetVersion()
|
||||
{
|
||||
std::wstring sFile = m_strSdkPath + L"/word/sdk-all-min.js";
|
||||
std::string sVersion = VALUE(INTVER);
|
||||
|
||||
std::string sData;
|
||||
if (!NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sData))
|
||||
return NULL;
|
||||
|
||||
std::string::size_type startPos = sData.find("Version:");
|
||||
if (std::string::npos == startPos)
|
||||
return NULL;
|
||||
|
||||
startPos += 8;
|
||||
|
||||
std::string::size_type endPos = sData.find(')', startPos);
|
||||
if (std::string::npos == endPos)
|
||||
return NULL;
|
||||
|
||||
size_t sSrcLen = endPos - startPos + 1;
|
||||
size_t sSrcLen = sVersion.size();
|
||||
if (sSrcLen == 0)
|
||||
return NULL;
|
||||
|
||||
char* sRet = new char[sSrcLen + 1];
|
||||
memcpy(sRet, sData.c_str() + startPos, sSrcLen);
|
||||
memcpy(sRet, sVersion.c_str(), sSrcLen);
|
||||
sRet[sSrcLen] = '\0';
|
||||
return sRet;
|
||||
}
|
||||
|
||||
@ -240,6 +240,14 @@ bool CV8RealTimeWorker::InitVariables()
|
||||
if (try_catch->Check())
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_sJSCodeStart.empty())
|
||||
{
|
||||
m_context->runScript(m_sJSCodeStart, try_catch);
|
||||
if (try_catch->Check())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -422,6 +422,7 @@ public:
|
||||
int m_nFileType;
|
||||
std::string m_sUtf8ArgumentJSON;
|
||||
std::string m_sGlobalVariable;
|
||||
std::string m_sJSCodeStart;
|
||||
|
||||
CJSContextData m_oContextData;
|
||||
|
||||
@ -455,7 +456,8 @@ namespace NSDoctRenderer
|
||||
std::wstring m_sTmpFolder;
|
||||
std::wstring m_sFileDir;
|
||||
int m_nFileType;
|
||||
bool m_bJavascriptBeforeEditor;
|
||||
|
||||
std::wstring m_sCommandsBeforeContextCreated;
|
||||
|
||||
std::wstring m_sX2tPath;
|
||||
|
||||
@ -478,7 +480,7 @@ namespace NSDoctRenderer
|
||||
public:
|
||||
CDocBuilder_Private() : CDoctRendererConfig(), m_sTmpFolder(NSFile::CFileBinary::GetTempPath()), m_nFileType(-1),
|
||||
m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsServerSafeVersion(false),
|
||||
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_bJavascriptBeforeEditor(false)
|
||||
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_sCommandsBeforeContextCreated(L"")
|
||||
{
|
||||
}
|
||||
|
||||
@ -639,9 +641,6 @@ namespace NSDoctRenderer
|
||||
NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
|
||||
}
|
||||
|
||||
if (m_bJavascriptBeforeEditor)
|
||||
CheckWorkerAfterOpen();
|
||||
|
||||
return bRet;
|
||||
#else
|
||||
std::wstring sPath = m_sX2tPath + L"/empty/new.";
|
||||
@ -930,11 +929,7 @@ namespace NSDoctRenderer
|
||||
LOGGER_SPEED_LAP("open_convert");
|
||||
|
||||
if (0 == nReturnCode)
|
||||
{
|
||||
if (m_bJavascriptBeforeEditor)
|
||||
CheckWorkerAfterOpen();
|
||||
return 0;
|
||||
}
|
||||
|
||||
NSDirectory::DeleteDirectory(m_sFileDir);
|
||||
m_sFileDir = L"";
|
||||
@ -1220,36 +1215,27 @@ namespace NSDoctRenderer
|
||||
{
|
||||
if (NULL == m_pWorker)
|
||||
{
|
||||
m_pWorker = new CV8RealTimeWorker(m_pParent, GetEditorType(), this);
|
||||
NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType();
|
||||
if (NSDoctRenderer::DoctRendererEditorType::INVALID == editorType)
|
||||
return false;
|
||||
|
||||
m_pWorker = new CV8RealTimeWorker(m_pParent, editorType, this);
|
||||
m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON;
|
||||
m_pWorker->m_sGlobalVariable = m_sGlobalVariable;
|
||||
m_pWorker->m_sJSCodeStart = U_TO_UTF8(m_sCommandsBeforeContextCreated);
|
||||
m_sCommandsBeforeContextCreated = L"";
|
||||
|
||||
return CheckWorkerAfterOpen();
|
||||
m_pWorker->m_nFileType = m_nFileType;
|
||||
|
||||
CV8Params oParams;
|
||||
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
|
||||
oParams.DocumentDirectory = m_sFileDir;
|
||||
|
||||
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, editorType, this, &oParams);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckWorkerAfterOpen()
|
||||
{
|
||||
if (!m_pWorker)
|
||||
return false;
|
||||
|
||||
m_pWorker->m_nFileType = m_nFileType;
|
||||
if (-1 == m_nFileType)
|
||||
{
|
||||
m_bJavascriptBeforeEditor = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bJavascriptBeforeEditor = false;
|
||||
|
||||
CV8Params oParams;
|
||||
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
|
||||
oParams.DocumentDirectory = m_sFileDir;
|
||||
|
||||
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetEditorType(), this, &oParams);
|
||||
}
|
||||
|
||||
int SaveFile(const std::wstring& ext, const std::wstring& path, const wchar_t* params = NULL)
|
||||
{
|
||||
int nType = GetFormatByTexExtention(ext);
|
||||
@ -1261,21 +1247,26 @@ namespace NSDoctRenderer
|
||||
if (command.length() < 7 && !retValue) // minimum command (!!!)
|
||||
return true;
|
||||
|
||||
if (m_nFileType == -1)
|
||||
{
|
||||
m_sCommandsBeforeContextCreated += command;
|
||||
return true;
|
||||
}
|
||||
|
||||
Init();
|
||||
|
||||
bool bRes = CheckWorker();
|
||||
if (CheckWorker())
|
||||
return m_pWorker->ExecuteCommand(command, retValue);
|
||||
|
||||
if (!bRes && m_pWorker && m_bJavascriptBeforeEditor)
|
||||
m_pWorker->InitVariables();
|
||||
|
||||
return m_pWorker->ExecuteCommand(command, retValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
CDocBuilderContext GetContext(bool enterContext)
|
||||
{
|
||||
CDocBuilderContext ctx;
|
||||
|
||||
CheckWorker();
|
||||
if (!CheckWorker())
|
||||
return ctx;
|
||||
|
||||
ctx.m_internal->m_context = m_pWorker->m_context;
|
||||
ctx.m_internal->m_context_data = &m_pWorker->m_oContextData;
|
||||
|
||||
@ -6,16 +6,16 @@ namespace NSDoctRenderer
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void AppendScript(NSStringUtils::CStringBuilderA* builder, const std::wstring& path)
|
||||
bool AppendScript(NSStringUtils::CStringBuilderA* builder, const std::wstring& path, const std::string& header = "", const std::string& footer = "")
|
||||
{
|
||||
NSFile::CFileBinary oFile;
|
||||
|
||||
if (!oFile.OpenFile(path))
|
||||
return;
|
||||
return false;
|
||||
|
||||
int size = (int)oFile.GetFileSize();
|
||||
if (size < 3)
|
||||
return;
|
||||
return false;
|
||||
|
||||
BYTE* pData = new BYTE[size];
|
||||
DWORD dwReadSize = 0;
|
||||
@ -26,9 +26,18 @@ namespace NSDoctRenderer
|
||||
if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF)
|
||||
nOffset = 3;
|
||||
|
||||
if (!header.empty())
|
||||
builder->WriteString(header);
|
||||
|
||||
builder->WriteString((char*)(pData + nOffset), size - nOffset);
|
||||
|
||||
if (!footer.empty())
|
||||
builder->WriteString(footer);
|
||||
|
||||
builder->WriteString("\n\n");
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RunScript(JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, const std::wstring& path)
|
||||
@ -114,6 +123,7 @@ namespace NSDoctRenderer
|
||||
AppendScript(builder, sFontsPath);
|
||||
AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all.js");
|
||||
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/engine/drawingfile_native.js");
|
||||
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/annotations/stamps.json", "window[\"native_pdf_stamps\"]=", ";");
|
||||
sCachePath = config->m_strSdkPath + L"/pdf/sdk-all";
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "DrawingFileEmbed.h"
|
||||
#include "../drawingfile.h"
|
||||
#include "../../raster/BgraFrame.h"
|
||||
|
||||
JSSmart<CJSValue> WasmMemoryToJS(BYTE* pWasmData)
|
||||
{
|
||||
|
||||
@ -160,16 +160,30 @@ void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage)
|
||||
|
||||
JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm)
|
||||
{
|
||||
NSNativeControl::CNativeControl* pControl = NULL;
|
||||
if (!Native->isNull())
|
||||
{
|
||||
pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject();
|
||||
JSSmart<CJSObject> pNativeObject = Native->toObject();
|
||||
CJSEmbedObject* pNativeEmbedObject = pNativeObject->getNative();
|
||||
|
||||
if (m_pInternal->m_pAppImage)
|
||||
delete m_pInternal->m_pAppImage;
|
||||
m_pInternal->m_pAppImage = new CGraphicsAppImage();
|
||||
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
|
||||
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
|
||||
|
||||
if (pNativeEmbedObject)
|
||||
{
|
||||
NSNativeControl::CNativeControl* pControl = (NSNativeControl::CNativeControl*)pNativeEmbedObject->getObject();
|
||||
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
|
||||
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
|
||||
}
|
||||
else
|
||||
{
|
||||
JSSmart<CJSValue> checkResources = pNativeObject->get("isResourcesObject");
|
||||
if (checkResources->isBool() && true == checkResources->toBool())
|
||||
{
|
||||
m_pInternal->m_pAppImage->SetFontsDirectory(pNativeObject->get("fontsDirectory")->toStringW());
|
||||
m_pInternal->m_pAppImage->SetImagesDirectory(pNativeObject->get("imagesDirectory")->toStringW());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble());
|
||||
|
||||
@ -258,3 +258,64 @@ JSSmart<CJSValue> CZipEmbed::getImageType(JSSmart<CJSValue> typedArray)
|
||||
oBuffer.Free();
|
||||
return CJSContext::createInt(bIsImageFile ? oChecker.eFileType : 0);
|
||||
}
|
||||
|
||||
JSSmart<CJSValue> CZipEmbed::getImageBuffer(JSSmart<CJSValue> filePath)
|
||||
{
|
||||
if (!m_pFolder || !filePath->isString())
|
||||
return CJSContext::createNull();
|
||||
|
||||
std::wstring sFilePath = filePath->toStringW();
|
||||
IFolder::CBuffer* pBuffer;
|
||||
if (!m_pFolder->read(sFilePath, pBuffer))
|
||||
return CJSContext::createNull();
|
||||
|
||||
size_t nBufferSize = (size_t)pBuffer->Size;
|
||||
|
||||
CImageFileFormatChecker oChecker;
|
||||
bool bIsImageFile = oChecker.isImageFile(pBuffer->Buffer, (DWORD)pBuffer->Size);
|
||||
|
||||
if (!bIsImageFile)
|
||||
{
|
||||
RELEASEOBJECT(pBuffer);
|
||||
return CJSContext::createNull();
|
||||
}
|
||||
|
||||
bool bIsNeedConvertMetfileToSvg = false;
|
||||
|
||||
// Make as wasm module
|
||||
if (oChecker.eFileType == _CXIMAGE_FORMAT_WMF || oChecker.eFileType == _CXIMAGE_FORMAT_EMF)
|
||||
oChecker.eFileType = _CXIMAGE_FORMAT_SVG;
|
||||
else
|
||||
bIsNeedConvertMetfileToSvg = false;
|
||||
|
||||
if (!bIsNeedConvertMetfileToSvg)
|
||||
{
|
||||
BYTE* pMemory = NSJSBase::NSAllocator::Alloc(nBufferSize);
|
||||
memcpy(pMemory, pBuffer->Buffer, nBufferSize);
|
||||
RELEASEOBJECT(pBuffer);
|
||||
|
||||
JSSmart<CJSObject> retObject = CJSContext::createObject();
|
||||
retObject->set("type", CJSContext::createInt(oChecker.eFileType));
|
||||
retObject->set("data", NSJSBase::CJSContext::createUint8Array(pMemory, (int)nBufferSize, false));
|
||||
return retObject->toValue();
|
||||
}
|
||||
|
||||
#ifndef GRAPHICS_DISABLE_METAFILE
|
||||
MetaFile::IMetaFile* pMetaFile = MetaFile::Create(NULL);
|
||||
pMetaFile->LoadFromBuffer(pBuffer->Buffer, (unsigned int)pBuffer->Size);
|
||||
std::wstring wsSvg = pMetaFile->ConvertToSvg();
|
||||
std::string sSvg = U_TO_UTF8(wsSvg);
|
||||
pMetaFile->Release();
|
||||
RELEASEOBJECT(pBuffer);
|
||||
|
||||
BYTE* pData = NSAllocator::Alloc(sSvg.length());
|
||||
memcpy(pData, sSvg.c_str(), sSvg.length());
|
||||
|
||||
JSSmart<CJSObject> retObject = CJSContext::createObject();
|
||||
retObject->set("type", CJSContext::createInt(24));
|
||||
retObject->set("data", NSJSBase::CJSContext::createUint8Array(pData, sSvg.length(), false));
|
||||
return retObject->toValue();
|
||||
#else
|
||||
return CJSContext::createNull();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ public:
|
||||
JSSmart<CJSValue> encodeImageData(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> w, JSSmart<CJSValue> h, JSSmart<CJSValue> stride, JSSmart<CJSValue> format, JSSmart<CJSValue> isRgba);
|
||||
JSSmart<CJSValue> encodeImage(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> format);
|
||||
JSSmart<CJSValue> getImageType(JSSmart<CJSValue> typedArray);
|
||||
JSSmart<CJSValue> getImageBuffer(JSSmart<CJSValue> path);
|
||||
|
||||
DECLARE_EMBED_METHODS
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
-(JSValue*) encodeImageData : (JSValue*)typedArray : (JSValue*)w : (JSValue*)h : (JSValue*)stride : (JSValue*)format : (JSValue*)isRgba;
|
||||
-(JSValue*) encodeImage : (JSValue*)typedArray : (JSValue*)format;
|
||||
-(JSValue*) getImageType : (JSValue*)typedArray;
|
||||
-(JSValue*) getImageBuffer : (JSValue*)path;
|
||||
@end
|
||||
|
||||
@interface CJSCZipEmbed : NSObject<IJSCZipEmbed, JSEmbedObjectProtocol>
|
||||
@ -41,6 +42,7 @@ FUNCTION_WRAPPER_JS_2(decodeImage, decodeImage)
|
||||
FUNCTION_WRAPPER_JS_6(encodeImageData, encodeImageData)
|
||||
FUNCTION_WRAPPER_JS_2(encodeImage, encodeImage)
|
||||
FUNCTION_WRAPPER_JS_1(getImageType, getImageType)
|
||||
FUNCTION_WRAPPER_JS_1(getImageBuffer, getImageBuffer)
|
||||
@end
|
||||
|
||||
class CZipEmbedAdapter : public CJSEmbedObjectAdapterJSC
|
||||
|
||||
@ -20,6 +20,7 @@ namespace NSZipEmbed
|
||||
FUNCTION_WRAPPER_V8_6(_encodeImageData, encodeImageData)
|
||||
FUNCTION_WRAPPER_V8_2(_encodeImage, encodeImage)
|
||||
FUNCTION_WRAPPER_V8_1(_getImageType, getImageType)
|
||||
FUNCTION_WRAPPER_V8_1(_getImageBuffer, getImageBuffer)
|
||||
|
||||
v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate)
|
||||
{
|
||||
@ -39,6 +40,7 @@ namespace NSZipEmbed
|
||||
NSV8Objects::Template_Set(result, "encodeImageData", _encodeImageData);
|
||||
NSV8Objects::Template_Set(result, "encodeImage", _encodeImage);
|
||||
NSV8Objects::Template_Set(result, "getImageType", _getImageType);
|
||||
NSV8Objects::Template_Set(result, "getImageBuffer", _getImageBuffer);
|
||||
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
|
||||
@ -374,7 +374,7 @@ namespace NSJSBase
|
||||
|
||||
JSSmart<CJSContext> CJSContext::GetCurrent()
|
||||
{
|
||||
CJSContext* ret = new CJSContext();
|
||||
CJSContext* ret = new CJSContext(false);
|
||||
ret->m_internal->context = NSJSBase::CJSContextPrivate::GetCurrentContext();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -356,6 +356,8 @@ public:
|
||||
|
||||
virtual void Check(const int& nCode, const unsigned int& nIndex)
|
||||
{
|
||||
if (nCode > m_nMaxSymbols)
|
||||
return;
|
||||
if (nCode > m_nMax)
|
||||
m_nMax = nCode;
|
||||
if (nCode < m_nMin)
|
||||
@ -794,6 +796,8 @@ public:
|
||||
std::wstring sNameCorrect = pPair->second.m_sName;
|
||||
NSStringUtils::string_replace(sNameCorrect, L"\\", L"\\\\");
|
||||
NSStringUtils::string_replace(sNameCorrect, L"\"", L"\\\"");
|
||||
NSStringUtils::string_replace(sNameCorrect, L"\n", L"");
|
||||
NSStringUtils::string_replace(sNameCorrect, L"\r", L"");
|
||||
oWriterJS += sNameCorrect;
|
||||
|
||||
oWriterJS.AddSize(120);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
@ -531,6 +531,45 @@ ZLib.prototype.getImageAsSvg = function(path)
|
||||
|
||||
return string;
|
||||
};
|
||||
/**
|
||||
* Get image file raw data. this memory was copied and detach from archive.
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
ZLib.prototype.getImageBuffer = function(path)
|
||||
{
|
||||
let result = {
|
||||
type : 0,
|
||||
data : null
|
||||
};
|
||||
result.type = this.getImageType(path);
|
||||
if (result.type === 0)
|
||||
return null;
|
||||
|
||||
let fileData = this.getFile(path);
|
||||
result.data = new Uint8Array(fileData.length);
|
||||
result.data.set(fileData);
|
||||
|
||||
if (result.type != 10 &&
|
||||
result.type != 21)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.type = 24;
|
||||
// Source was saved as result.data for using original image in native convertations.
|
||||
// But for js we need svg for metafiles.
|
||||
|
||||
let encodedData = Module["_Raster_Encode"](this.files[path].p + 4, fileData.length, 24);
|
||||
let encodedSize = Module["_Raster_GetEncodedSize"](encodedData);
|
||||
let encodedBuffer = Module["_Raster_GetEncodedBuffer"](encodedData);
|
||||
|
||||
let fileDataEnc = new Uint8Array(Module["HEAP8"].buffer, encodedBuffer, encodedSize);
|
||||
result.dataBlob = new Uint8Array(fileDataEnc.length);
|
||||
result.dataBlob.set(fileDataEnc);
|
||||
|
||||
Module["_Raster_DestroyEncodedData"](encodedData);
|
||||
return result;
|
||||
};
|
||||
/**
|
||||
* Get image blob for browser
|
||||
* @returns {Blob}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
@ -35,7 +35,7 @@
|
||||
window['AscFonts'] = window['AscFonts'] || {};
|
||||
var AscFonts = window['AscFonts'];
|
||||
|
||||
var g_native_engine = CreateEmbedObject("CTextMeasurerEmbed");
|
||||
var g_native_engine = null;
|
||||
|
||||
function CReturnObject()
|
||||
{
|
||||
@ -236,4 +236,6 @@ AscFonts.Hyphen_Word = function(lang, word)
|
||||
AscFonts.onLoadModule();
|
||||
AscFonts.onLoadModule();
|
||||
|
||||
window["InitNativeTextMeasurer"] = function() { g_native_engine = CreateEmbedObject("CTextMeasurerEmbed"); };
|
||||
|
||||
})(window, undefined);
|
||||
|
||||
@ -100,6 +100,7 @@
|
||||
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
|
||||
"GRAPHICS_NO_USE_DYNAMIC_LIBRARY",
|
||||
"HYPHEN_ENGINE_DISABLE_FILESYSTEM",
|
||||
"METAFILE_DISABLE_FILESYSTEM",
|
||||
|
||||
"HAVE_UNISTD_H", "HAVE_FCNTL_H", "_ARM_ALIGN_",
|
||||
"METAFILE_SUPPORT_WMF_EMF",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
@ -761,6 +761,14 @@ function onLoadFontsModule(window, undefined)
|
||||
{
|
||||
return this.engine["getImageBlob"](path);
|
||||
};
|
||||
/**
|
||||
* Get image file raw data. this memory was copied and detach from archive.
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
ZLib.prototype.getImageBuffer = function(path)
|
||||
{
|
||||
return this.engine["getImageBuffer"](path);
|
||||
};
|
||||
/**
|
||||
* Get all file paths in archive
|
||||
* @returns {Array}
|
||||
@ -772,10 +780,84 @@ function onLoadFontsModule(window, undefined)
|
||||
|
||||
AscCommon.ZLib = ZLib;
|
||||
|
||||
function ZlibImageBlobs()
|
||||
{
|
||||
this.url2BlobUrl = {};
|
||||
this.blobUrl2Data = {};
|
||||
this.url2Base64 = {};
|
||||
|
||||
this.nativeBlobCounter = 1;
|
||||
}
|
||||
ZlibImageBlobs.prototype.getBlobUrl = function(path, zip)
|
||||
{
|
||||
if (this.url2BlobUrl[path])
|
||||
return this.url2BlobUrl[path];
|
||||
|
||||
let result = zip.getImageBuffer(path);
|
||||
if (result == null)
|
||||
return "";
|
||||
|
||||
let blobUrl = "";
|
||||
let blobType = AscCommon.openXml.GetMimeType((24 !== result["type"]) ? AscCommon.GetFileExtension(path) : "svg");
|
||||
|
||||
if (window["NATIVE_EDITOR_ENJINE"])
|
||||
{
|
||||
blobUrl = "blob:internal-image" + this.nativeBlobCounter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
let blob = new Blob([result["dataBlob"] ? result["dataBlob"] : result["data"]], {type: blobType});
|
||||
blobUrl = window.URL.createObjectURL(blob);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
blobUrl = "error";
|
||||
AscCommon.consoleLog("ERROR: Image blob was not loaded");
|
||||
}
|
||||
}
|
||||
|
||||
this.blobUrl2Data[blobUrl] = result;
|
||||
this.url2BlobUrl[path] = blobUrl;
|
||||
return blobUrl;
|
||||
};
|
||||
ZlibImageBlobs.prototype.getImageBase64 = function(url)
|
||||
{
|
||||
if (this.url2Base64[url])
|
||||
return this.url2Base64[url];
|
||||
|
||||
let obj = this.blobUrl2Data[url];
|
||||
if (!obj)
|
||||
return url;
|
||||
|
||||
let header = "";
|
||||
switch (obj.type)
|
||||
{
|
||||
case 3:
|
||||
header = "data:image/jpeg;base64,";
|
||||
break;
|
||||
case 24:
|
||||
header = "data:image/svg+xml;base64,";
|
||||
break;
|
||||
case 4:
|
||||
default:
|
||||
header = "data:image/png;base64,";
|
||||
}
|
||||
|
||||
this.url2Base64[url] = header + AscCommon.Base64.encode(obj.data);
|
||||
return this.url2Base64[url];
|
||||
};
|
||||
|
||||
window["AscCommon"].g_oDocumentBlobUrls = new ZlibImageBlobs();
|
||||
|
||||
if (AscCommon["CZLibEngineJS"])
|
||||
AscCommon["CZLibEngineJS"].prototype["isModuleInit"] = true;
|
||||
|
||||
window.nativeZlibEngine = new ZLib();
|
||||
if (window["NATIVE_EDITOR_ENJINE"])
|
||||
window["InitNativeZLib"] = function() { window.nativeZlibEngine = new ZLib(); };
|
||||
else
|
||||
window.nativeZlibEngine = new ZLib();
|
||||
|
||||
function Hyphenation()
|
||||
{
|
||||
|
||||
@ -730,14 +730,14 @@ bool Location::IsTouching() noexcept
|
||||
PointD pt;
|
||||
bool straight = C.IsStraight() && Inters->C.IsStraight();
|
||||
|
||||
return !straight || !intersect({C.Segment1.P.X,
|
||||
C.Segment1.P.Y,
|
||||
C.Segment2.P.X,
|
||||
C.Segment2.P.Y,
|
||||
Inters->C.Segment1.P.X,
|
||||
Inters->C.Segment1.P.Y,
|
||||
Inters->C.Segment2.P.X,
|
||||
Inters->C.Segment2.P.Y}, pt);
|
||||
return !straight || !intersect(C.Segment1.P.X,
|
||||
C.Segment1.P.Y,
|
||||
C.Segment2.P.X,
|
||||
C.Segment2.P.Y,
|
||||
Inters->C.Segment1.P.X,
|
||||
Inters->C.Segment1.P.Y,
|
||||
Inters->C.Segment2.P.X,
|
||||
Inters->C.Segment2.P.Y, pt);
|
||||
}
|
||||
|
||||
CBooleanOperations::CBooleanOperations(const CGraphicsPath& path1,
|
||||
@ -943,7 +943,7 @@ void CBooleanOperations::TraceAllOverlap()
|
||||
{
|
||||
int touchCount = 0;
|
||||
for (const auto& c : OriginCurves2)
|
||||
count1 += CheckInters(MIN_POINT, s, c, touchCount);
|
||||
count1 += CheckInters(s, c, touchCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -954,7 +954,7 @@ void CBooleanOperations::TraceAllOverlap()
|
||||
{
|
||||
int touchCount = 0;
|
||||
for (const auto& c : OriginCurves1)
|
||||
count2 += CheckInters(MIN_POINT, s, c, touchCount);
|
||||
count2 += CheckInters(s, c, touchCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1255,20 +1255,26 @@ void CBooleanOperations::SetVisited(const Segment& segment)
|
||||
|
||||
std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
||||
{
|
||||
int length1 = static_cast<int>(Curves1.size()),
|
||||
length2 = static_cast<int>(Curves2.size());
|
||||
std::vector<std::vector<double>> allBounds, bounds2;
|
||||
allBounds.reserve(length1 + length2);
|
||||
bounds2.reserve(length2);
|
||||
for (const auto& c : Curves1)
|
||||
allBounds.push_back(c.GetBound());
|
||||
allBounds.emplace_back(c.GetBound());
|
||||
for (const auto& c : Curves2)
|
||||
bounds2.push_back(c.GetBound());
|
||||
bounds2.emplace_back(c.GetBound());
|
||||
|
||||
bool self = allBounds == bounds2;
|
||||
|
||||
if (!self)
|
||||
for (auto it = bounds2.begin(); it != bounds2.end(); ++it)
|
||||
allBounds.push_back(*it);
|
||||
{
|
||||
allBounds.resize(length1 + length2);
|
||||
for (size_t i = 0; i < length2; i++)
|
||||
allBounds[i + length1] = std::move(bounds2[i]);
|
||||
}
|
||||
|
||||
int allLength = static_cast<int>(allBounds.size()),
|
||||
length1 = static_cast<int>(Curves1.size());
|
||||
int allLength = static_cast<int>(allBounds.size());
|
||||
|
||||
std::vector<int> allIdicesByPri1(allLength);
|
||||
for (int i = 0; i < allLength; i++)
|
||||
@ -1502,8 +1508,8 @@ void CBooleanOperations::LinkIntersection(std::shared_ptr<Location> from,
|
||||
void CBooleanOperations::AddLineIntersection(const Curve& curve1, const Curve& curve2)
|
||||
{
|
||||
PointD pt;
|
||||
if (intersect({curve1.Segment1.P.X, curve1.Segment1.P.Y, curve1.Segment2.P.X, curve1.Segment2.P.Y,
|
||||
curve2.Segment1.P.X, curve2.Segment1.P.Y, curve2.Segment2.P.X, curve2.Segment2.P.Y}, pt))
|
||||
if (intersect(curve1.Segment1.P.X, curve1.Segment1.P.Y, curve1.Segment2.P.X, curve1.Segment2.P.Y,
|
||||
curve2.Segment1.P.X, curve2.Segment1.P.Y, curve2.Segment2.P.X, curve2.Segment2.P.Y, pt))
|
||||
AddLocation(curve1, curve2, curve1.GetTimeOf(pt), curve2.GetTimeOf(pt));
|
||||
}
|
||||
|
||||
@ -1626,10 +1632,10 @@ int CBooleanOperations::AddCurveIntersection(const Curve& curve1, const Curve& c
|
||||
return calls;
|
||||
}
|
||||
|
||||
int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const
|
||||
int CBooleanOperations::CheckInters(const Segment& segment, const Curve& curve, int& touchCount) const
|
||||
{
|
||||
PointD pt{};
|
||||
if (intersect({point.X, point.Y, segment.P.X, segment.P.Y, curve.Segment1.P.X, curve.Segment1.P.Y, curve.Segment2.P.X, curve.Segment2.P.Y}, pt))
|
||||
if (intersect(MIN_POINT.X, MIN_POINT.Y, segment.P.X, segment.P.Y, curve.Segment1.P.X, curve.Segment1.P.Y, curve.Segment2.P.X, curve.Segment2.P.Y, pt))
|
||||
{
|
||||
if (getDistance(segment.P, pt) <= GEOMETRIC_EPSILON) return (touchCount + 1) % 2;
|
||||
if (getDistance(curve.Segment1.P, pt) <= GEOMETRIC_EPSILON || getDistance(curve.Segment2.P, pt) <= GEOMETRIC_EPSILON)
|
||||
@ -1642,8 +1648,8 @@ int CBooleanOperations::CheckInters(const PointD& point, const Segment& segment,
|
||||
}
|
||||
if (!curve.IsStraight())
|
||||
{
|
||||
std::vector<double> roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, point.X - segment.P.X, point.Y - segment.P.Y);
|
||||
Curve line(segment, Segment(point));
|
||||
std::vector<double> roots = curve.GetCurveLineIntersection(segment.P.X,segment.P.Y, MIN_POINT.X - segment.P.X, MIN_POINT.Y - segment.P.Y);
|
||||
Curve line(segment, Segment(MIN_POINT));
|
||||
|
||||
int count = 0;
|
||||
for (const auto& r : roots)
|
||||
@ -1672,7 +1678,7 @@ void CBooleanOperations::SetWinding()
|
||||
int count = 0,
|
||||
touchCount = 0;
|
||||
for (const auto& c : OriginCurves2)
|
||||
count += CheckInters(MIN_POINT, s1, c, touchCount);
|
||||
count += CheckInters(s1, c, touchCount);
|
||||
|
||||
for (auto& s : Segments1)
|
||||
s.Winding = count % 2;
|
||||
@ -1680,7 +1686,7 @@ void CBooleanOperations::SetWinding()
|
||||
count = 0;
|
||||
touchCount = 0;
|
||||
for (const auto& c : OriginCurves1)
|
||||
count += CheckInters(MIN_POINT, s2, c, touchCount);
|
||||
count += CheckInters(s2, c, touchCount);
|
||||
|
||||
for (auto& s : Segments2)
|
||||
s.Winding = count % 2;
|
||||
@ -1698,7 +1704,7 @@ void CBooleanOperations::SetWinding()
|
||||
int count = 0,
|
||||
touchCount = 0;
|
||||
for (const auto& c : (s.Id == 1 ? OriginCurves2 : OriginCurves1))
|
||||
count += CheckInters(MIN_POINT, s, c, touchCount);
|
||||
count += CheckInters(s, c, touchCount);
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
@ -140,7 +140,7 @@ namespace Aggplus
|
||||
void AddCurveLineIntersection(const Curve& curve1, const Curve& curve2, bool flip);
|
||||
int AddCurveIntersection(const Curve& curve1, const Curve& curve2, const Curve& startCurve1, const Curve& startCurve2, bool flip,
|
||||
int recursion = 0, int calls = 0, double tMin = 0.0, double tMax = 1.0, double uMin = 0.0, double uMax = 1.0);
|
||||
int CheckInters(const PointD& point, const Segment& segment, const Curve& curve, int& touchCount) const;
|
||||
int CheckInters(const Segment& segment, const Curve& curve, int& touchCount) const;
|
||||
void SetWinding();
|
||||
|
||||
// Location
|
||||
|
||||
@ -837,12 +837,13 @@ namespace Aggplus
|
||||
{
|
||||
std::vector<PointD> points;
|
||||
unsigned length = m_internal->m_agg_ps.total_vertices();
|
||||
points.resize(count);
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
double x,y;
|
||||
if (idx + i > length) break;
|
||||
this->m_internal->m_agg_ps.vertex(idx + i, &x, &y);
|
||||
points.push_back(PointD(x, y));
|
||||
points[i] = PointD(x, y);
|
||||
}
|
||||
|
||||
return points;
|
||||
@ -885,37 +886,37 @@ namespace Aggplus
|
||||
{
|
||||
std::vector<CGraphicsPath> result;
|
||||
|
||||
CGraphicsPath subPath;
|
||||
bool close = true;
|
||||
CGraphicsPath sub_path;
|
||||
for (unsigned i = 0; i < m_internal->m_agg_ps.total_vertices(); i++)
|
||||
{
|
||||
if (IsMovePoint(i))
|
||||
{
|
||||
if (!close)
|
||||
{
|
||||
PointD firstPoint = subPath.GetPoints(0, 1)[0];
|
||||
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
|
||||
double x, y;
|
||||
subPath.GetLastPoint(x, y);
|
||||
sub_path.GetLastPoint(x, y);
|
||||
if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) ||
|
||||
subPath.GetPointCount() == 1)
|
||||
sub_path.GetPointCount() == 1)
|
||||
{
|
||||
if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1)
|
||||
subPath.LineTo(firstPoint.X, firstPoint.Y);
|
||||
subPath.CloseFigure();
|
||||
if (!firstPoint.Equals(PointD(x, y)) || sub_path.GetPointCount() == 1)
|
||||
sub_path.LineTo(firstPoint.X, firstPoint.Y);
|
||||
sub_path.CloseFigure();
|
||||
}
|
||||
|
||||
result.push_back(subPath);
|
||||
subPath.Reset();
|
||||
result.push_back(sub_path);
|
||||
sub_path.Reset();
|
||||
}
|
||||
subPath.StartFigure();
|
||||
sub_path.StartFigure();
|
||||
PointD point = GetPoints(i, 1)[0];
|
||||
subPath.MoveTo(point.X, point.Y);
|
||||
sub_path.MoveTo(point.X, point.Y);
|
||||
close = false;
|
||||
}
|
||||
else if (IsCurvePoint(i))
|
||||
{
|
||||
std::vector<PointD> points = GetPoints(i, 3);
|
||||
subPath.CurveTo(points[0].X, points[0].Y,
|
||||
sub_path.CurveTo(points[0].X, points[0].Y,
|
||||
points[1].X, points[1].Y,
|
||||
points[2].X, points[2].Y);
|
||||
i += 2;
|
||||
@ -923,40 +924,40 @@ namespace Aggplus
|
||||
else if (IsLinePoint(i))
|
||||
{
|
||||
PointD point = GetPoints(i, 1)[0];
|
||||
subPath.LineTo(point.X, point.Y);
|
||||
sub_path.LineTo(point.X, point.Y);
|
||||
}
|
||||
else if (IsClosePoint(i))
|
||||
{
|
||||
PointD firstPoint = subPath.GetPoints(0, 1)[0];
|
||||
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
|
||||
double x, y;
|
||||
subPath.GetLastPoint(x, y);
|
||||
sub_path.GetLastPoint(x, y);
|
||||
|
||||
if (!firstPoint.Equals(PointD(x, y)) || subPath.GetPointCount() == 1)
|
||||
subPath.LineTo(firstPoint.X, firstPoint.Y);
|
||||
if (!firstPoint.Equals(PointD(x, y)) || sub_path.GetPointCount() == 1)
|
||||
sub_path.LineTo(firstPoint.X, firstPoint.Y);
|
||||
|
||||
subPath.CloseFigure();
|
||||
result.push_back(subPath);
|
||||
subPath.Reset();
|
||||
sub_path.CloseFigure();
|
||||
result.push_back(sub_path);
|
||||
sub_path.Reset();
|
||||
close = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!close)
|
||||
{
|
||||
PointD firstPoint = subPath.GetPoints(0, 1)[0];
|
||||
PointD firstPoint = sub_path.GetPoints(0, 1)[0];
|
||||
double x, y;
|
||||
subPath.GetLastPoint(x, y);
|
||||
sub_path.GetLastPoint(x, y);
|
||||
|
||||
if ((abs(firstPoint.X - x) <= 1e-2 && abs(firstPoint.Y - y) <= 1e-2) ||
|
||||
subPath.GetPointCount() == 1)
|
||||
sub_path.GetPointCount() == 1)
|
||||
{
|
||||
if (!firstPoint.Equals(PointD(x, y)) ||
|
||||
subPath.GetPointCount() == 1)
|
||||
subPath.LineTo(firstPoint.X, firstPoint.Y);
|
||||
subPath.CloseFigure();
|
||||
sub_path.GetPointCount() == 1)
|
||||
sub_path.LineTo(firstPoint.X, firstPoint.Y);
|
||||
sub_path.CloseFigure();
|
||||
}
|
||||
|
||||
result.push_back(subPath);
|
||||
result.push_back(sub_path);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@ -153,13 +153,6 @@ IMetafileToRenderter::IMetafileToRenderter(IRenderer* pRenderer)
|
||||
}
|
||||
IMetafileToRenderter::~IMetafileToRenderter()
|
||||
{
|
||||
for (std::vector<std::wstring>::iterator i = m_arTempFiles.begin(); i != m_arTempFiles.end(); i++)
|
||||
{
|
||||
std::wstring sPath = *i;
|
||||
if (NSFile::CFileBinary::Exists(sPath))
|
||||
NSFile::CFileBinary::Remove(sPath);
|
||||
}
|
||||
|
||||
if (m_pPicker)
|
||||
{
|
||||
CMetafileFontPicker* pPicker = (CMetafileFontPicker*)m_pPicker;
|
||||
@ -234,8 +227,6 @@ std::wstring IMetafileToRenderter::GetImagePath(const std::wstring& sPath)
|
||||
oFrame.put_Data(NULL);
|
||||
sImagePath = sTempFile;
|
||||
}
|
||||
|
||||
m_arTempFiles.push_back(sTempFile);
|
||||
}
|
||||
|
||||
RELEASEARRAYOBJECTS(pImageBuffer);
|
||||
|
||||
@ -49,7 +49,6 @@ public:
|
||||
|
||||
protected:
|
||||
std::wstring m_sTempDir;
|
||||
std::vector<std::wstring> m_arTempFiles;
|
||||
|
||||
std::wstring m_sThemesDir;
|
||||
std::wstring m_sMediaDir;
|
||||
|
||||
@ -151,27 +151,28 @@ inline double integrate(const double& ax, const double& bx, const double& cx, co
|
||||
return A * sum;
|
||||
}
|
||||
|
||||
inline bool intersect(std::vector<double> v, Aggplus::PointD& res)
|
||||
inline bool intersect(double v0, double v1, double v2, double v3, double v4,
|
||||
double v5, double v6, double v7, Aggplus::PointD& res)
|
||||
{
|
||||
v[2] -= v[0];
|
||||
v[3] -= v[1];
|
||||
v[6] -= v[4];
|
||||
v[7] -= v[5];
|
||||
v2 -= v0;
|
||||
v3 -= v1;
|
||||
v6 -= v4;
|
||||
v7 -= v5;
|
||||
|
||||
double cross = v[2] * v[7] - v[3] * v[6];
|
||||
double cross = v2 * v7 - v3 * v6;
|
||||
if (!isMachineZero(cross))
|
||||
{
|
||||
double dx = v[0] - v[4],
|
||||
dy = v[1] - v[5],
|
||||
u1 = (v[6] * dy - v[7] * dx) / cross,
|
||||
u2 = (v[2] * dy - v[3] * dx) / cross,
|
||||
double dx = v0 - v4,
|
||||
dy = v1 - v5,
|
||||
u1 = (v6 * dy - v7 * dx) / cross,
|
||||
u2 = (v2 * dy - v3 * dx) / cross,
|
||||
uMin = -EPSILON,
|
||||
uMax = 1 + EPSILON;
|
||||
|
||||
if (uMin < u1 && u1 < uMax && uMin < u2 && u2 < uMax)
|
||||
{
|
||||
u1 = u1 <= 0 ? 0 : u1 >= 1 ? 1 : u1;
|
||||
res = Aggplus::PointD(v[0] + u1 * v[2], v[1] + u1 * v[3]);
|
||||
res = Aggplus::PointD(v0 + u1 * v2, v1 + u1 * v3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -223,7 +223,7 @@
|
||||
},
|
||||
{
|
||||
"folder": "../../../../DocxRenderer/src/logic/elements",
|
||||
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp"]
|
||||
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "../../../common",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
|
||||
@ -147,6 +147,10 @@ namespace MetaFile
|
||||
if (BI_JPEG != unCompression || BI_PNG != unCompression)
|
||||
return false;
|
||||
|
||||
#ifdef METAFILE_DISABLE_FILESYSTEM
|
||||
return false;
|
||||
#endif
|
||||
|
||||
std::wstring wsTempFileName = GetTempFilename();
|
||||
if (wsTempFileName.empty())
|
||||
return false;
|
||||
|
||||
@ -1512,26 +1512,5 @@ namespace MetaFile
|
||||
|
||||
std::swap(oFirstClip, oSecondClip);
|
||||
}
|
||||
|
||||
TRectD CEmfInterpretatorSvg::TranslateRect(const TRectL &oRect) const
|
||||
{
|
||||
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
|
||||
|
||||
if (oNewRect.Right < oNewRect.Left)
|
||||
{
|
||||
double dTempValue = oNewRect.Left;
|
||||
oNewRect.Left = oNewRect.Right;
|
||||
oNewRect.Right = dTempValue;
|
||||
}
|
||||
|
||||
if (oNewRect.Bottom < oNewRect.Top)
|
||||
{
|
||||
double dTempValue = oNewRect.Top;
|
||||
oNewRect.Top = oNewRect.Bottom;
|
||||
oNewRect.Bottom = dTempValue;
|
||||
}
|
||||
|
||||
return oNewRect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -227,8 +227,6 @@ namespace MetaFile
|
||||
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
|
||||
|
||||
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);
|
||||
|
||||
TRectD TranslateRect(const TRectL &oRect) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -664,6 +664,9 @@ namespace MetaFile
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
|
||||
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
|
||||
|
||||
pEmfPlusBrush->oColor = pEmfPlusBrush->arGradientColors[unPositionCount - 1].first;
|
||||
pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors[0].first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -560,16 +560,18 @@ namespace MetaFile
|
||||
|
||||
void CInterpretatorSvgBase::IntersectClip(const TRectD &oClip)
|
||||
{
|
||||
double dLeft = oClip.Left;
|
||||
double dTop = oClip.Top;
|
||||
double dRight = oClip.Right;
|
||||
double dBottom = oClip.Bottom;
|
||||
TRectD oUpdatedClip{oClip};
|
||||
|
||||
m_pParser->GetTransform().Apply(dLeft, dTop);
|
||||
m_pParser->GetTransform().Apply(dRight, dBottom);
|
||||
NormalizeRect(oUpdatedClip);
|
||||
|
||||
m_pParser->GetTransform().Apply(oUpdatedClip.Left, oUpdatedClip.Top);
|
||||
m_pParser->GetTransform().Apply(oUpdatedClip.Right, oUpdatedClip.Bottom);
|
||||
|
||||
const std::wstring wsId = L"INTERSECTCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
|
||||
const std::wstring wsValue = L"<rect x=\"" + ConvertToWString(dLeft, 0) + L"\" y=\"" + ConvertToWString(dTop, 0) + L"\" width=\"" + ConvertToWString(dRight - dLeft, 0) + L"\" height=\"" + ConvertToWString(dBottom - dTop, 0) + L"\"/>";
|
||||
const std::wstring wsValue = L"<rect x=\"" + ConvertToWString(oUpdatedClip.Left, 0) +
|
||||
L"\" y=\"" + ConvertToWString(oUpdatedClip.Top, 0) +
|
||||
L"\" width=\"" + ConvertToWString(oUpdatedClip.Right - oUpdatedClip.Left, 0) +
|
||||
L"\" height=\"" + ConvertToWString(oUpdatedClip.Bottom - oUpdatedClip.Top, 0) + L"\"/>";
|
||||
|
||||
m_oClip.AddClipValue(wsId, wsValue);
|
||||
}
|
||||
@ -577,28 +579,24 @@ namespace MetaFile
|
||||
void CInterpretatorSvgBase::ExcludeClip(const TRectD &oClip, const TRectD &oBB)
|
||||
{
|
||||
const TXForm &oTransform{m_pParser->GetTransform()};
|
||||
|
||||
double dClipLeft = oClip.Left;
|
||||
double dClipTop = oClip.Top;
|
||||
double dClipRight = oClip.Right;
|
||||
double dClipBottom = oClip.Bottom;
|
||||
|
||||
oTransform.Apply(dClipLeft, dClipTop);
|
||||
oTransform.Apply(dClipRight, dClipBottom);
|
||||
TRectD oUpdatedClip{oClip};
|
||||
NormalizeRect(oUpdatedClip);
|
||||
|
||||
double dBBLeft = oBB.Left;
|
||||
double dBBTop = oBB.Top;
|
||||
double dBBRight = oBB.Right;
|
||||
double dBBBottom = oBB.Bottom;
|
||||
oTransform.Apply(oUpdatedClip.Left, oUpdatedClip.Top);
|
||||
oTransform.Apply(oUpdatedClip.Right, oUpdatedClip.Bottom);
|
||||
|
||||
oTransform.Apply(dBBLeft, dBBTop);
|
||||
oTransform.Apply(dBBRight, dBBBottom);
|
||||
TRectD oBBRect{oBB};
|
||||
NormalizeRect(oBBRect);
|
||||
|
||||
oTransform.Apply(oBBRect.Left, oBBRect.Top);
|
||||
oTransform.Apply(oBBRect.Right, oBBRect.Bottom);
|
||||
|
||||
const std::wstring wsId = L"EXCLUDECLIP_" + ConvertToWString(++m_unNumberDefs, 0);
|
||||
const std::wstring wsValue = L"<path d=\"M" + ConvertToWString(dBBLeft) + L' ' + ConvertToWString(dBBTop) + L", L" + ConvertToWString(dBBRight) + L' ' + ConvertToWString(dBBTop) + L", " +
|
||||
ConvertToWString(dBBRight) + L' ' + ConvertToWString(dBBBottom) + L", " + ConvertToWString(dBBLeft ) + L' ' + ConvertToWString(dBBBottom) + L", M" +
|
||||
ConvertToWString(dClipLeft) + L' ' + ConvertToWString(dClipTop) + L", L" + ConvertToWString(dClipRight) + L' ' + ConvertToWString(dClipTop) + L", " +
|
||||
ConvertToWString(dClipRight) + L' ' + ConvertToWString(dClipBottom) + L", " + ConvertToWString(dClipLeft) + L' ' + ConvertToWString(dClipLeft ) + L"\" clip-rule=\"evenodd\"/>";
|
||||
const std::wstring wsValue = L"<path d=\"M" + ConvertToWString(oBBRect.Left) + L' ' + ConvertToWString(oBBRect.Top) + L", L" + ConvertToWString(oBBRect.Right) + L' ' + ConvertToWString(oBBRect.Top) + L", " +
|
||||
ConvertToWString(oBBRect.Right) + L' ' + ConvertToWString(oBBRect.Bottom) + L", " + ConvertToWString(oBBRect.Left) + L' ' + ConvertToWString(oBBRect.Bottom) + L", Z M" +
|
||||
ConvertToWString(oUpdatedClip.Left) + L' ' + ConvertToWString(oUpdatedClip.Top) + L", L" + ConvertToWString(oUpdatedClip.Right) + L' ' + ConvertToWString(oUpdatedClip.Top) + L", " +
|
||||
ConvertToWString(oUpdatedClip.Right) + L' ' + ConvertToWString(oUpdatedClip.Bottom) + L", " + ConvertToWString(oUpdatedClip.Left) + L' ' + ConvertToWString(oUpdatedClip.Bottom) + L" Z\" clip-rule=\"evenodd\"/>";
|
||||
|
||||
m_oClip.AddClipValue(wsId, wsValue);
|
||||
}
|
||||
@ -2080,4 +2078,21 @@ namespace MetaFile
|
||||
return CalculateColor(unColor, chAlpha);
|
||||
}
|
||||
|
||||
void NormalizeRect(TRectD& oRect)
|
||||
{
|
||||
if (oRect.Right < oRect.Left)
|
||||
std::swap(oRect.Right, oRect.Left);
|
||||
|
||||
if (oRect.Bottom < oRect.Top)
|
||||
std::swap(oRect.Bottom, oRect.Top);
|
||||
}
|
||||
|
||||
TRectD TranslateRect(const TRectL& oRect)
|
||||
{
|
||||
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
|
||||
|
||||
NormalizeRect(oNewRect);
|
||||
|
||||
return oNewRect;
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +161,8 @@ namespace MetaFile
|
||||
std::wstring CalculateColor(unsigned int unColor);
|
||||
std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha);
|
||||
std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha);
|
||||
void NormalizeRect(TRectD& oRect);
|
||||
TRectD TranslateRect(const TRectL &oRect);
|
||||
}
|
||||
|
||||
#endif // CINTERPRETATORSVGBASE_H
|
||||
|
||||
@ -346,12 +346,7 @@ namespace MetaFile
|
||||
|
||||
void CWmfInterpretatorSvg::HANDLE_META_RECTANGLE(short shB, short shR, short shT, short shL)
|
||||
{
|
||||
TRectD oNewRect;
|
||||
|
||||
oNewRect.Left = shL;
|
||||
oNewRect.Top = shT;
|
||||
oNewRect.Right = shR;
|
||||
oNewRect.Bottom = shB;
|
||||
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
@ -369,12 +364,7 @@ namespace MetaFile
|
||||
|
||||
void CWmfInterpretatorSvg::HANDLE_META_ROUNDRECT(short shH, short shW, short shB, short shR, short shT, short shL)
|
||||
{
|
||||
TRectD oNewRect;
|
||||
|
||||
oNewRect.Left = shL;
|
||||
oNewRect.Top = shT;
|
||||
oNewRect.Right = shR;
|
||||
oNewRect.Bottom = shB;
|
||||
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
|
||||
@ -29,139 +29,22 @@ namespace SVG
|
||||
if (NULL == pSvgObject)
|
||||
return;
|
||||
|
||||
const std::map<std::wstring, NSCSS::CElement *> *pData = m_pInternal->GetData();
|
||||
const std::vector<NSCSS::CNode> arSelectors = pSvgObject->GetFullPath();
|
||||
|
||||
if ((NULL == pData || pData->empty()) && arSelectors.empty())
|
||||
return;
|
||||
|
||||
std::vector<std::wstring> arWords;
|
||||
arWords.reserve(arSelectors.size() * 2);
|
||||
|
||||
std::vector<std::wstring> arNextNodes;
|
||||
arNextNodes.reserve(arSelectors.size() * 2);
|
||||
|
||||
for (std::vector<NSCSS::CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
|
||||
{
|
||||
arWords.push_back(oNode->m_wsName);
|
||||
|
||||
if (!oNode->m_wsClass.empty())
|
||||
{
|
||||
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
|
||||
{
|
||||
std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
|
||||
|
||||
if (arClasses.size() > 1)
|
||||
arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin());
|
||||
|
||||
arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
|
||||
[](std::wstring sRes, const std::wstring& sClass)
|
||||
{return sRes += L'.' + sClass + L' ';}));
|
||||
}
|
||||
else
|
||||
arWords.push_back(L'.' + oNode->m_wsClass);
|
||||
}
|
||||
if (!oNode->m_wsId.empty())
|
||||
arWords.push_back(L'#' + oNode->m_wsId);
|
||||
}
|
||||
|
||||
std::vector<NSCSS::CElement*> arElements;
|
||||
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors);
|
||||
std::vector<std::wstring> arPrevNodes;
|
||||
|
||||
for (size_t i = 0; i < arSelectors.size(); ++i)
|
||||
{
|
||||
std::wstring sName, sId;
|
||||
std::vector<std::wstring> arClasses;
|
||||
|
||||
if (arWords.back()[0] == L'#')
|
||||
{
|
||||
sId = arWords.back();
|
||||
arWords.pop_back();
|
||||
arNextNodes.push_back(sId);
|
||||
}
|
||||
|
||||
if (arWords.back()[0] == L'.')
|
||||
{
|
||||
arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" ");
|
||||
arNextNodes.push_back(arWords.back());
|
||||
arWords.pop_back();
|
||||
}
|
||||
|
||||
sName = arWords.back();
|
||||
arWords.pop_back();
|
||||
arNextNodes.push_back(sName);
|
||||
|
||||
const std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindName = pData->find(sName);
|
||||
std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindId;
|
||||
std::vector<NSCSS::CElement*> arFindElements;
|
||||
|
||||
if (!sId.empty())
|
||||
{
|
||||
oFindId = pData->find(sId);
|
||||
|
||||
if (oFindId != std::end(*pData))
|
||||
{
|
||||
if (!oFindId->second->Empty())
|
||||
arFindElements.push_back(oFindId->second);
|
||||
|
||||
const std::vector<NSCSS::CElement*> arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend());
|
||||
|
||||
if (!arTempPrev.empty())
|
||||
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
|
||||
}
|
||||
}
|
||||
|
||||
if (!arClasses.empty())
|
||||
{
|
||||
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
|
||||
{
|
||||
const std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindClass = pData->find(*iClass);
|
||||
if (oFindClass != std::end(*pData))
|
||||
{
|
||||
if (!oFindClass->second->Empty())
|
||||
arFindElements.push_back(oFindClass->second);
|
||||
|
||||
const std::vector<NSCSS::CElement*> arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend());
|
||||
const std::vector<NSCSS::CElement*> arTempKins = oFindClass->second->GetNextOfKin(sName);
|
||||
|
||||
if (!arTempPrev.empty())
|
||||
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
|
||||
|
||||
if (!arTempKins.empty())
|
||||
arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oFindName != std::end(*pData))
|
||||
{
|
||||
if (!oFindName->second->Empty())
|
||||
arFindElements.push_back(oFindName->second);
|
||||
|
||||
const std::vector<NSCSS::CElement*> arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend());
|
||||
const std::vector<NSCSS::CElement*> arTempKins = oFindName->second->GetNextOfKin(sName, arClasses);
|
||||
|
||||
if (!arTempPrev.empty())
|
||||
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
|
||||
|
||||
if (!arTempKins.empty())
|
||||
arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end());
|
||||
}
|
||||
|
||||
|
||||
if (arFindElements.size() > 1)
|
||||
{
|
||||
std::sort(arFindElements.rbegin(), arFindElements.rend(),
|
||||
[](NSCSS::CElement* oFirstElement, NSCSS::CElement* oSecondElement)
|
||||
{
|
||||
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
|
||||
});
|
||||
}
|
||||
|
||||
pSvgObject->SetData(arSelectors[i].m_mAttributes, i + 1);
|
||||
pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
|
||||
for (const NSCSS::CElement* oElement : arFindElements)
|
||||
for (const NSCSS::CElement* oElement : m_pInternal->FindElements(arNodes, arPrevNodes))
|
||||
pSvgObject->SetData(oElement->GetStyle(), i + 1);
|
||||
|
||||
if (!arSelectors[i].m_wsStyle.empty())
|
||||
pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -442,14 +442,14 @@ namespace SVG
|
||||
|
||||
if (!Equals(0., dFontHeight) && dFontHeight < MIN_FONT_SIZE)
|
||||
{
|
||||
dXScale *= dFontHeight / MIN_FONT_SIZE;
|
||||
dYScale *= dFontHeight / MIN_FONT_SIZE;
|
||||
dXScale *= MIN_FONT_SIZE / dFontHeight;
|
||||
dYScale *= MIN_FONT_SIZE / dFontHeight;
|
||||
dFontHeight = MIN_FONT_SIZE;
|
||||
}
|
||||
else if (!Equals(0., dFontHeight) && dFontHeight > MAX_FONT_SIZE)
|
||||
{
|
||||
dXScale *= MAX_FONT_SIZE / dFontHeight;
|
||||
dYScale *= MAX_FONT_SIZE / dFontHeight;
|
||||
dXScale *= dFontHeight / MAX_FONT_SIZE;
|
||||
dYScale *= dFontHeight / MAX_FONT_SIZE;
|
||||
dFontHeight = MAX_FONT_SIZE;
|
||||
}
|
||||
|
||||
|
||||
@ -45,21 +45,23 @@ namespace SVG
|
||||
|
||||
const CRenderedObject *pFoundObj = dynamic_cast<CRenderedObject*>(pFile->GetMarkedObject(m_wsHref));
|
||||
|
||||
if (NULL != pFoundObj)
|
||||
bool bResult = false;
|
||||
|
||||
if (NULL != pFoundObj && this != pFoundObj)
|
||||
{
|
||||
if (NULL != pOtherStyles)
|
||||
{
|
||||
TSvgStyles oNewStyles(m_oStyles);
|
||||
oNewStyles += *pOtherStyles;
|
||||
pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this);
|
||||
bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this);
|
||||
}
|
||||
else
|
||||
pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this);
|
||||
bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this);
|
||||
}
|
||||
|
||||
EndPath(pRenderer, pFile, oOldTransform);
|
||||
|
||||
return true;
|
||||
return bResult;
|
||||
}
|
||||
|
||||
TBounds CUse::GetBounds() const
|
||||
|
||||
@ -126,20 +126,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz
|
||||
|
||||
DrawPage(pFile, nPage);
|
||||
|
||||
std::vector<std::wstring> xml_shapes;
|
||||
for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes)
|
||||
{
|
||||
if (!shape) continue;
|
||||
auto writer = new NSStringUtils::CStringBuilder();
|
||||
shape->ToXml(*writer);
|
||||
xml_shapes.push_back(writer->GetData());
|
||||
delete writer;
|
||||
}
|
||||
|
||||
std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml;
|
||||
if (!arComleteObjects.empty())
|
||||
xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end());
|
||||
|
||||
auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapes();
|
||||
m_pInternal->m_oDocument.Clear();
|
||||
return xml_shapes;
|
||||
}
|
||||
@ -154,23 +141,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile,
|
||||
|
||||
DrawPage(pFile, nPage);
|
||||
|
||||
// for drawingml is no tag behind-doc - so we need to reorder shapes
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.ReorderShapesForPptx();
|
||||
|
||||
std::vector<std::wstring> xml_shapes;
|
||||
for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes)
|
||||
{
|
||||
if (!shape) continue;
|
||||
auto writer = new NSStringUtils::CStringBuilder();
|
||||
shape->ToXmlPptx(*writer);
|
||||
xml_shapes.push_back(writer->GetData());
|
||||
delete writer;
|
||||
}
|
||||
|
||||
std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml;
|
||||
if (!arComleteObjects.empty())
|
||||
xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end());
|
||||
|
||||
auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapesPptx();
|
||||
m_pInternal->m_oDocument.Clear();
|
||||
return xml_shapes;
|
||||
}
|
||||
@ -241,7 +212,7 @@ HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
|
||||
std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\"";
|
||||
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
|
||||
}
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml.push_back(UTF8_TO_U(sUtf8Shape));
|
||||
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
|
||||
return S_OK;
|
||||
}
|
||||
case IAdvancedCommand::AdvancedCommandType::ShapeEnd:
|
||||
|
||||
@ -32,6 +32,7 @@ HEADERS += \
|
||||
src/logic/elements/ContText.h \
|
||||
src/logic/elements/Paragraph.h \
|
||||
src/logic/elements/Shape.h \
|
||||
src/logic/elements/Table.h \
|
||||
src/logic/elements/TextLine.h \
|
||||
src/logic/managers/ExternalImageStorage.h \
|
||||
src/logic/managers/FontStyleManager.h \
|
||||
@ -56,6 +57,7 @@ SOURCES += \
|
||||
src/logic/elements/ContText.cpp \
|
||||
src/logic/elements/Paragraph.cpp \
|
||||
src/logic/elements/Shape.cpp \
|
||||
src/logic/elements/Table.cpp \
|
||||
src/logic/elements/TextLine.cpp \
|
||||
src/logic/managers/FontManager.cpp \
|
||||
src/logic/managers/FontStyleManager.cpp \
|
||||
|
||||
@ -1,126 +0,0 @@
|
||||
#include "BaseItem.h"
|
||||
#include "../resources/Constants.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc)
|
||||
{
|
||||
if (this == &oSrc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_eType = oSrc.m_eType;
|
||||
m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse;
|
||||
|
||||
m_dLeft = oSrc.m_dLeft;
|
||||
m_dTop = oSrc.m_dTop;
|
||||
m_dWidth = oSrc.m_dWidth;
|
||||
m_dHeight = oSrc.m_dHeight;
|
||||
m_dBaselinePos = oSrc.m_dBaselinePos;
|
||||
m_dRight = oSrc.m_dRight;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CBaseItem::IsBigger(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dLeft > oSrc->m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc)
|
||||
{
|
||||
return (m_dLeft >= oSrc->m_dLeft) ? true : false;
|
||||
}
|
||||
|
||||
eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc)
|
||||
{
|
||||
if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos)
|
||||
{
|
||||
return eVerticalCrossingType::vctCurrentInsideNext;
|
||||
}
|
||||
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos)
|
||||
{
|
||||
return eVerticalCrossingType::vctCurrentOutsideNext;
|
||||
}
|
||||
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop)
|
||||
{
|
||||
return eVerticalCrossingType::vctCurrentAboveNext;
|
||||
}
|
||||
else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos)
|
||||
{
|
||||
return eVerticalCrossingType::vctCurrentBelowNext;
|
||||
}
|
||||
else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos &&
|
||||
m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight)
|
||||
{
|
||||
return eVerticalCrossingType::vctDublicate;
|
||||
}
|
||||
else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
return eVerticalCrossingType::vctTopBordersMatch;
|
||||
}
|
||||
else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
return eVerticalCrossingType::vctBottomBordersMatch;
|
||||
}
|
||||
else if (m_dBaselinePos < oSrc->m_dTop)
|
||||
{
|
||||
return eVerticalCrossingType::vctNoCrossingCurrentAboveNext;
|
||||
}
|
||||
else if (m_dTop > oSrc->m_dBaselinePos)
|
||||
{
|
||||
return eVerticalCrossingType::vctNoCrossingCurrentBelowNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
return eVerticalCrossingType::vctUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc)
|
||||
{
|
||||
if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight)
|
||||
{
|
||||
return eHorizontalCrossingType::hctCurrentInsideNext;
|
||||
}
|
||||
else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight)
|
||||
{
|
||||
return eHorizontalCrossingType::hctCurrentOutsideNext;
|
||||
}
|
||||
else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight > oSrc->m_dLeft)
|
||||
{
|
||||
return eHorizontalCrossingType::hctCurrentLeftOfNext;
|
||||
}
|
||||
else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft < oSrc->m_dRight)
|
||||
{
|
||||
return eHorizontalCrossingType::hctCurrentRightOfNext;
|
||||
}
|
||||
else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight &&
|
||||
m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos)
|
||||
{
|
||||
return eHorizontalCrossingType::hctDublicate;
|
||||
}
|
||||
else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
return eHorizontalCrossingType::hctLeftBordersMatch;
|
||||
}
|
||||
else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
|
||||
{
|
||||
return eHorizontalCrossingType::hctRightBordersMatch;
|
||||
}
|
||||
else if (m_dRight < oSrc->m_dLeft)
|
||||
{
|
||||
return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext;
|
||||
}
|
||||
else if (m_dLeft > oSrc->m_dRight)
|
||||
{
|
||||
return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
return eHorizontalCrossingType::hctUnknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "elements/Paragraph.h"
|
||||
#include "elements/Table.h"
|
||||
#include "elements/Shape.h"
|
||||
#include "managers/ImageManager.h"
|
||||
#include "managers/FontStyleManager.h"
|
||||
@ -18,47 +19,34 @@ namespace NSDocxRenderer
|
||||
CManagers(const CManagers& other) = default;
|
||||
~CManagers() = default;
|
||||
|
||||
CImageManager* pImageManager;
|
||||
CFontStyleManager* pFontStyleManager;
|
||||
CParagraphStyleManager* pParagraphStyleManager;
|
||||
CFontManager* pFontManager;
|
||||
CFontSelector* pFontSelector;
|
||||
CImageManager* pImageManager;
|
||||
CFontStyleManager* pFontStyleManager;
|
||||
CParagraphStyleManager* pParagraphStyleManager;
|
||||
CFontManager* pFontManager;
|
||||
CFontSelector* pFontSelector;
|
||||
};
|
||||
|
||||
double m_dWidth {0.0};
|
||||
double m_dHeight {0.0};
|
||||
double m_dHeight{0.0};
|
||||
|
||||
LONG m_lCurrentCommand{0};
|
||||
LONG m_lClipMode{0};
|
||||
LONG m_lClipMode {0};
|
||||
|
||||
TextAssociationType m_eTextAssociationType{TextAssociationType::tatPlainParagraph};
|
||||
TextAssociationType m_eTextAssociationType{TextAssociationType::tatPlainParagraph};
|
||||
NSFonts::IApplicationFonts* m_pAppFonts{nullptr};
|
||||
|
||||
NSStructures::CFont m_oFont;
|
||||
NSStructures::CPen m_oPen;
|
||||
NSStructures::CBrush m_oBrush;
|
||||
NSStructures::CShadow m_oShadow;
|
||||
NSStructures::CEdgeText m_oEdgeText;
|
||||
|
||||
Aggplus::CMatrix m_oTransform;
|
||||
CManagers m_oManagers;
|
||||
|
||||
CVectorGraphics m_oCurrVectorGraphics, m_oClipVectorGraphics;
|
||||
CContTextBuilder m_oContBuilder;
|
||||
|
||||
std::vector<std::shared_ptr<CContText>> m_arConts;
|
||||
std::vector<std::shared_ptr<CTextLine>> m_arTextLines;
|
||||
std::vector<std::shared_ptr<CContText>> m_arDiacriticalSymbols;
|
||||
std::vector<std::shared_ptr<CShape>> m_arShapes;
|
||||
|
||||
std::vector<std::wstring> m_arCompleteObjectsXml;
|
||||
std::vector<std::shared_ptr<CBaseItem>> m_arOutputObjects;
|
||||
NSStructures::CFont m_oFont{};
|
||||
NSStructures::CPen m_oPen{};
|
||||
NSStructures::CBrush m_oBrush{};
|
||||
NSStructures::CShadow m_oShadow{};
|
||||
NSStructures::CEdgeText m_oEdgeText{};
|
||||
Aggplus::CMatrix m_oTransform{};
|
||||
|
||||
bool m_bIsDeleteTextClipPage{true};
|
||||
bool m_bIsRecalcFontSize {true};
|
||||
bool m_bIsGradient {false};
|
||||
bool m_bUseDefaultFont {false};
|
||||
bool m_bWriteStyleRaw {false};
|
||||
bool m_bIsBuildTables {false};
|
||||
|
||||
CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers);
|
||||
~CPage();
|
||||
@ -67,7 +55,6 @@ namespace NSDocxRenderer
|
||||
void EndCommand(DWORD lType);
|
||||
|
||||
void Clear();
|
||||
void DeleteTextClipPage();
|
||||
|
||||
void WriteImage(const std::shared_ptr<CImageInfo> pInfo, double& fX, double& fY, double& fWidth, double& fHeight);
|
||||
|
||||
@ -77,8 +64,8 @@ namespace NSDocxRenderer
|
||||
void PathStart();
|
||||
void PathEnd();
|
||||
void PathClose();
|
||||
|
||||
void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo);
|
||||
|
||||
void AddText(
|
||||
const PUINT pUnicodes,
|
||||
const PUINT pGids,
|
||||
@ -91,50 +78,134 @@ namespace NSDocxRenderer
|
||||
|
||||
void Analyze();
|
||||
void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage);
|
||||
void ReorderShapesForPptx();
|
||||
|
||||
std::vector<std::wstring> GetXmlShapes();
|
||||
std::vector<std::wstring> GetXmlShapesPptx();
|
||||
void AddCompleteXml(const std::wstring oXml);
|
||||
|
||||
private:
|
||||
void BuildDiacriticalSymbols();
|
||||
void BuildTextLines();
|
||||
using shape_ptr_t = std::shared_ptr<CShape>;
|
||||
using cont_ptr_t = std::shared_ptr<CContText>;
|
||||
using line_ptr_t = std::shared_ptr<CTextLine>;
|
||||
using item_ptr_t = std::shared_ptr<CBaseItem>;
|
||||
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
|
||||
using table_ptr_t = std::shared_ptr<CTable>;
|
||||
|
||||
// returns std::vector of conts with diac. symbols and remove it from m_arConts
|
||||
std::vector<cont_ptr_t> MoveDiacriticalSymbols();
|
||||
|
||||
// returns std::vector of text lines builded from m_arConts
|
||||
std::vector<line_ptr_t> BuildTextLines();
|
||||
|
||||
// returns std::vector of paragraphs builded from m_arTextLines
|
||||
std::vector<paragraph_ptr_t> BuildParagraphs();
|
||||
|
||||
// returns std::vector of tables builded from shapes and paragraphes
|
||||
std::vector<table_ptr_t> BuildTables();
|
||||
|
||||
// returns std::vector of cells for tables
|
||||
std::vector<CTable::cell_ptr_t> BuildCells();
|
||||
|
||||
// returns std::vector of rows for tables
|
||||
std::vector<CTable::row_ptr_t> BuildRows(std::vector<CTable::cell_ptr_t>& arCells);
|
||||
|
||||
// returns std::vector of base items builded from m_arParagraphs
|
||||
std::vector<item_ptr_t> BuildOutputObjects();
|
||||
|
||||
// analyze shapes (set lines type)
|
||||
void AnalyzeShapes();
|
||||
|
||||
// analyze type of lines (double, wave, etc.)
|
||||
void AnalyzeLinesType();
|
||||
|
||||
// analyze m_arTextLines and add effects, adds diac, super-sub scripts etc.
|
||||
void AnalyzeTextLines();
|
||||
void SplitLines();
|
||||
void CalcSelected();
|
||||
void BuildParagraphes();
|
||||
|
||||
std::vector<std::vector<std::shared_ptr<CTextLine>>> GetLinesByGroups();
|
||||
// analyze drop caps (creates shapes)
|
||||
void AnalyzeDropCaps();
|
||||
|
||||
void MergeShapes();
|
||||
void CalcShapesRotation();
|
||||
// analyze conts in text lines
|
||||
void AnalyzeConts();
|
||||
|
||||
// strikeouts, underlines, highlights, outline
|
||||
void AnalyzeEffects();
|
||||
|
||||
bool IsLineCrossingText(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
|
||||
bool IsLineBelowText(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
|
||||
bool IsHighlight(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
|
||||
bool IsOutline(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
|
||||
|
||||
void AnalyzeDropCaps();
|
||||
void AnalyzeConts();
|
||||
// adds diacritical symbols in conts
|
||||
void AddDiacriticalSymbols();
|
||||
void MergeLinesByVertAlignType();
|
||||
|
||||
void AnalyzeShapes();
|
||||
void DetermineLinesType();
|
||||
// super-sub scripts line merge
|
||||
void MergeTextLinesByVatType();
|
||||
|
||||
// remove out of bounds text lines
|
||||
void DeleteTextClipPage();
|
||||
|
||||
// merging conts in text lines
|
||||
void MergeConts();
|
||||
|
||||
// get horizontal and vertical lines from shapes
|
||||
void GetHorVerLines();
|
||||
|
||||
// set dominant shapes
|
||||
void DetermineDominantGraphics();
|
||||
|
||||
bool IsShapeBorderBetweenVertical(std::shared_ptr<CTextLine> pFirst, std::shared_ptr<CTextLine> pSecond) const noexcept;
|
||||
bool IsShapeBorderBetweenHorizontal(std::shared_ptr<CTextLine> pFirst, std::shared_ptr<CTextLine> pSecond) const noexcept;
|
||||
bool IsShapeBorderTrough(std::shared_ptr<CContText> pItem, double& dXCrossing, double& dYCrossing) const noexcept;
|
||||
// split lines by graphics
|
||||
void SplitLines();
|
||||
|
||||
std::shared_ptr<CShape> CreateSingleLineShape(std::shared_ptr<CTextLine>& pLine);
|
||||
std::shared_ptr<CShape> CreateSingleParagraphShape(std::shared_ptr<CParagraph>& pParagraph);
|
||||
// creates shapes from overlapping text lines
|
||||
void AnalyzeOverlapLines();
|
||||
|
||||
// конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter);
|
||||
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter);
|
||||
// calc selected sizes of conts
|
||||
void CalcSelected();
|
||||
|
||||
// merge shapes with each other
|
||||
void MergeShapes();
|
||||
|
||||
// calc true shapes rotation for ooxml format
|
||||
void CalcShapesRotation();
|
||||
|
||||
// for drawingml is no tag behind-doc - so we need to reorder shapes
|
||||
void ReorderShapesForPptx();
|
||||
|
||||
// get lines by groups by X
|
||||
std::vector<std::vector<line_ptr_t>> GetLinesByGroups();
|
||||
|
||||
bool IsLineCrossingText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
|
||||
bool IsLineBelowText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
|
||||
bool IsHighlight(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
|
||||
bool IsOutline(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
|
||||
|
||||
bool IsVerticalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
|
||||
bool IsHorizontalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
|
||||
|
||||
bool IsVerticalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
|
||||
bool IsHorizontalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
|
||||
|
||||
bool IsVerticalLineTrough(item_ptr_t pFirst) const noexcept;
|
||||
bool IsHorizontalLineTrough(item_ptr_t pFirst) const noexcept;
|
||||
|
||||
void ToXml(NSStringUtils::CStringBuilder& oWriter) const noexcept;
|
||||
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) const noexcept;
|
||||
|
||||
static shape_ptr_t CreateSingleLineShape(line_ptr_t& pLine);
|
||||
static shape_ptr_t CreateSingleParagraphShape(paragraph_ptr_t& pParagraph);
|
||||
|
||||
CManagers m_oManagers;
|
||||
|
||||
CVectorGraphics m_oCurrVectorGraphics;
|
||||
CVectorGraphics m_oClipVectorGraphics;
|
||||
|
||||
CContTextBuilder m_oContBuilder;
|
||||
CHorVerLinesCollector m_oHorVerLinesCollector;
|
||||
|
||||
std::vector<cont_ptr_t> m_arConts;
|
||||
std::vector<line_ptr_t> m_arTextLines;
|
||||
std::vector<cont_ptr_t> m_arDiacriticalSymbols;
|
||||
std::vector<shape_ptr_t> m_arShapes;
|
||||
std::vector<paragraph_ptr_t> m_arParagraphs;
|
||||
std::vector<table_ptr_t> m_arTables;
|
||||
|
||||
std::vector<item_ptr_t> m_arOutputObjects;
|
||||
std::vector<std::wstring> m_arCompleteObjectsXml;
|
||||
|
||||
size_t m_nShapeOrder = 0;
|
||||
};
|
||||
|
||||
@ -1,6 +1,4 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "../../../../DesktopEditor/common/StringBuilder.h"
|
||||
|
||||
|
||||
@ -6,18 +6,6 @@
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
bool IsTextOnlySpaces(const NSStringUtils::CStringUTF32& oText)
|
||||
{
|
||||
bool only_spaces = true;
|
||||
for (size_t j = 0; j < oText.length(); ++j)
|
||||
if (!CContText::IsUnicodeSpace(oText.at(j)))
|
||||
{
|
||||
only_spaces = false;
|
||||
break;
|
||||
}
|
||||
return only_spaces;
|
||||
}
|
||||
|
||||
CSelectedSizes::CSelectedSizes(const CSelectedSizes& oSelectedSizes)
|
||||
{
|
||||
*this = oSelectedSizes;
|
||||
@ -108,8 +96,13 @@ namespace NSDocxRenderer
|
||||
double dBoxWidth;
|
||||
double dBoxHeight;
|
||||
|
||||
m_pManager->SetStringGid(0);
|
||||
m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition);
|
||||
if (m_oText.ToStdWString() == L" ")
|
||||
dBoxWidth = m_pManager->GetSpaceWidthMM();
|
||||
else
|
||||
{
|
||||
m_pManager->SetStringGid(0);
|
||||
m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition);
|
||||
}
|
||||
|
||||
m_oSelectedSizes.dWidth = dBoxWidth;
|
||||
m_oSelectedSizes.dHeight = dBoxHeight;
|
||||
@ -544,7 +537,19 @@ namespace NSDocxRenderer
|
||||
|
||||
bool CContText::IsOnlySpaces() const
|
||||
{
|
||||
return IsTextOnlySpaces(m_oText);
|
||||
bool only_spaces = true;
|
||||
for (size_t j = 0; j < m_oText.length(); ++j)
|
||||
if (!CContText::IsUnicodeSpace(m_oText.at(j)))
|
||||
{
|
||||
only_spaces = false;
|
||||
break;
|
||||
}
|
||||
return only_spaces;
|
||||
}
|
||||
bool CContText::IsDiacritical() const noexcept
|
||||
{
|
||||
const auto& text = GetText();
|
||||
return text.length() == 1 && CContText::IsUnicodeDiacriticalMark(text.at(0));
|
||||
}
|
||||
|
||||
void CContText::AddTextBack(const NSStringUtils::CStringUTF32& oText, const std::vector<double>& arSymWidths)
|
||||
@ -831,7 +836,14 @@ namespace NSDocxRenderer
|
||||
|
||||
return is_bullet || is_another;
|
||||
}
|
||||
|
||||
bool CContText::IsUnicodeEnumEnd(uint32_t cSym)
|
||||
{
|
||||
return cSym == 0x29 || cSym == 0x2e;
|
||||
}
|
||||
bool CContText::IsUnicodeNumber(uint32_t cSym)
|
||||
{
|
||||
return cSym >= 0x30 && cSym <= 0x39;
|
||||
}
|
||||
bool CContText::IsUnicodeSpace(uint32_t cSym)
|
||||
{
|
||||
return (0x20 == cSym || 0xA0 == cSym || 0x2003 == cSym);
|
||||
|
||||
@ -117,6 +117,7 @@ namespace NSDocxRenderer
|
||||
bool IsDuplicate(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) const noexcept;
|
||||
|
||||
bool IsOnlySpaces() const;
|
||||
bool IsDiacritical() const noexcept;
|
||||
double CalculateSpace() const noexcept;
|
||||
|
||||
// check font effect and delete not needed cont
|
||||
@ -135,6 +136,8 @@ namespace NSDocxRenderer
|
||||
|
||||
static bool IsUnicodeRtl(uint32_t cSym);
|
||||
static bool IsUnicodeBullet(uint32_t cSym);
|
||||
static bool IsUnicodeEnumEnd(uint32_t cSym);
|
||||
static bool IsUnicodeNumber(uint32_t cSym);
|
||||
static bool IsUnicodeSpace(uint32_t c);
|
||||
static bool IsUnicodeSymbol(uint32_t symbol);
|
||||
static bool IsUnicodeDiacriticalMark(uint32_t symbol);
|
||||
@ -154,7 +157,7 @@ namespace NSDocxRenderer
|
||||
CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector);
|
||||
~CContTextBuilder() = default;
|
||||
|
||||
// after call CContTextBuilder is empty.
|
||||
// after call CContTextBuilder is empty
|
||||
std::vector<cont_ptr_t> GetConts();
|
||||
void AddUnicode(
|
||||
double dTop,
|
||||
|
||||
@ -9,6 +9,15 @@ namespace NSDocxRenderer
|
||||
{
|
||||
UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight;
|
||||
|
||||
unsigned int ClampUIntSign(const double& value)
|
||||
{
|
||||
if (value < 0)
|
||||
return 0;
|
||||
if (value > 0x7FFFFFFF)
|
||||
return 0x7FFFFFFF;
|
||||
return (unsigned int)value;
|
||||
}
|
||||
|
||||
CShape::CShape()
|
||||
{
|
||||
m_nRelativeHeight = m_gRelativeHeight;
|
||||
@ -234,69 +243,49 @@ namespace NSDocxRenderer
|
||||
|
||||
void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) noexcept
|
||||
{
|
||||
//note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста.
|
||||
if ((m_bIsNoStroke && m_bIsNoFill) ||
|
||||
(m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor))
|
||||
{
|
||||
if ((m_bIsNoStroke && m_bIsNoFill) || (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor))
|
||||
m_eGraphicsType = eGraphicsType::gtNoGraphics;
|
||||
}
|
||||
else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtRectangle;
|
||||
|
||||
if (dHeight < 0.7)
|
||||
{
|
||||
if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman
|
||||
{
|
||||
if (dWidth > 2.0) // длинное тире - 2.8mm у times new roman
|
||||
m_eSimpleLineType = eSimpleLineType::sltHLongDash;
|
||||
}
|
||||
else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash
|
||||
{
|
||||
else if (dWidth > 0.7) // минимальное тире - 0.75mm у dotDotDash
|
||||
m_eSimpleLineType = eSimpleLineType::sltHDash;
|
||||
}
|
||||
else //максимальная точка - 0.5mm
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltHDot;
|
||||
}
|
||||
else
|
||||
m_eSimpleLineType = eSimpleLineType::sltHDot; // максимальная точка - 0.5mm
|
||||
}
|
||||
else if (dWidth < 0.7)
|
||||
{
|
||||
if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman
|
||||
{
|
||||
if (dHeight > 2.0) // длинное тире - 2.8mm у times new roman
|
||||
m_eSimpleLineType = eSimpleLineType::sltVLongDash;
|
||||
}
|
||||
else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash
|
||||
{
|
||||
else if (dHeight > 0.7) // минимальное тире - 0.75mm у dotDotDash
|
||||
m_eSimpleLineType = eSimpleLineType::sltVDash;
|
||||
}
|
||||
else //максимальна точка - 0.5mm
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltVDot;
|
||||
}
|
||||
else
|
||||
m_eSimpleLineType = eSimpleLineType::sltVDot; // максимальна точка - 0.5mm
|
||||
}
|
||||
}
|
||||
else if (nCurves > 0 && nPeacks <= 1) //1 move
|
||||
else if (nCurves > 0 && nPeacks <= 1) // 1 move
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtCurve;
|
||||
if (dHeight < dWidth)
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltHWave;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eSimpleLineType = eSimpleLineType::sltVWave;
|
||||
}
|
||||
}
|
||||
else if (nCurves > 0 && nPeacks > 1)
|
||||
{
|
||||
m_eGraphicsType = eGraphicsType::gtComplicatedFigure;
|
||||
}
|
||||
}
|
||||
|
||||
bool CShape::IsItFitLine() const noexcept
|
||||
{
|
||||
return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) ||
|
||||
(m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave);
|
||||
return (m_eGraphicsType == eGraphicsType::gtRectangle && (
|
||||
m_eSimpleLineType == eSimpleLineType::sltHDot ||
|
||||
m_eSimpleLineType == eSimpleLineType::sltHDash ||
|
||||
m_eSimpleLineType == eSimpleLineType::sltHLongDash)) ||
|
||||
(m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave);
|
||||
}
|
||||
|
||||
bool CShape::IsCorrelated(std::shared_ptr<const CShape> pShape) const noexcept
|
||||
@ -323,7 +312,7 @@ namespace NSDocxRenderer
|
||||
|
||||
void CShape::CheckLineType(std::shared_ptr<CShape>& pFirstShape)
|
||||
{
|
||||
if(!pFirstShape)
|
||||
if (!pFirstShape)
|
||||
return;
|
||||
|
||||
if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
|
||||
@ -338,103 +327,68 @@ namespace NSDocxRenderer
|
||||
return;
|
||||
|
||||
if (!pFirstShape->IsItFitLine() || !pSecondShape->IsItFitLine() || !pFirstShape->IsCorrelated(pSecondShape) ||
|
||||
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) // линия должна быть одного размера по высоте
|
||||
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM)
|
||||
{
|
||||
return; // линия должна быть одного размера по высоте
|
||||
}
|
||||
|
||||
auto set_line_type = [] (std::shared_ptr<CShape>& master, std::shared_ptr<CShape>& slave, eLineType type) {
|
||||
master->m_eLineType = type;
|
||||
master->RecalcWithNewItem(slave.get());
|
||||
master->m_oVector.Join(std::move(slave->m_oVector));
|
||||
slave = nullptr;
|
||||
};
|
||||
|
||||
// проверка на двойную линию
|
||||
if (pFirstShape->m_eLineType == eLineType::ltDouble)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble);
|
||||
else
|
||||
set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble);
|
||||
|
||||
return;
|
||||
}
|
||||
if (pFirstShape->m_eLineType == eLineType::ltWavyDouble)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble);
|
||||
else
|
||||
set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// проверка на двойную линию
|
||||
if (pFirstShape->m_eLineType == eLineType::ltDouble || pFirstShape->m_eLineType == eLineType::ltWavyDouble)
|
||||
{
|
||||
if (pFirstShape->m_eLineType == eLineType::ltDouble)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
{
|
||||
pFirstShape->m_eLineType = eLineType::ltDouble;
|
||||
pFirstShape->RecalcWithNewItem(pSecondShape.get());
|
||||
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
|
||||
pSecondShape = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSecondShape->m_eLineType = eLineType::ltDouble;
|
||||
pSecondShape->RecalcWithNewItem(pFirstShape.get());
|
||||
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
|
||||
pFirstShape = nullptr;
|
||||
}
|
||||
}
|
||||
else if (pFirstShape->m_eLineType == eLineType::ltWavyDouble)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
{
|
||||
pFirstShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
pFirstShape->RecalcWithNewItem(pSecondShape.get());
|
||||
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
|
||||
pSecondShape = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSecondShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
pSecondShape->RecalcWithNewItem(pFirstShape.get());
|
||||
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
|
||||
pFirstShape = nullptr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 &&
|
||||
fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
|
||||
fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM)
|
||||
{
|
||||
//Условие первого определения
|
||||
// условие первого определения
|
||||
if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
{
|
||||
pFirstShape->m_eLineType = eLineType::ltDouble;
|
||||
pFirstShape->RecalcWithNewItem(pSecondShape.get());
|
||||
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
|
||||
pSecondShape = nullptr;
|
||||
}
|
||||
set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble);
|
||||
else
|
||||
{
|
||||
pSecondShape->m_eLineType = eLineType::ltDouble;
|
||||
pSecondShape->RecalcWithNewItem(pFirstShape.get());
|
||||
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
|
||||
pFirstShape = nullptr;
|
||||
}
|
||||
set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble);
|
||||
}
|
||||
else if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave)
|
||||
{
|
||||
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
|
||||
{
|
||||
pFirstShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
pFirstShape->RecalcWithNewItem(pSecondShape.get());
|
||||
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
|
||||
pSecondShape = nullptr;
|
||||
}
|
||||
set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble);
|
||||
else
|
||||
{
|
||||
pSecondShape->m_eLineType = eLineType::ltWavyDouble;
|
||||
pSecondShape->RecalcWithNewItem(pFirstShape.get());
|
||||
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
|
||||
pFirstShape = nullptr;
|
||||
}
|
||||
set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM)
|
||||
{
|
||||
// все должно быть на одной линии
|
||||
return;
|
||||
}
|
||||
return; // все должно быть на одной линии
|
||||
|
||||
// теперь считаем, что графика находится на одной линии
|
||||
if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5)
|
||||
// расстояние между объектами на одной линии должно быть небольшим
|
||||
if (fabs(pFirstShape->m_dLeft + pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5)
|
||||
{
|
||||
// расстояние между объектами на одной линии должно быть небольшим
|
||||
if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
|
||||
pFirstShape->m_eLineType =pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle;
|
||||
pFirstShape->m_eLineType = pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle;
|
||||
|
||||
else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave)
|
||||
pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave;
|
||||
@ -924,6 +878,27 @@ namespace NSDocxRenderer
|
||||
}
|
||||
|
||||
oWriter.WriteString(L"</a:solidFill>");
|
||||
if (m_oPen.DashStyle == Aggplus::DashStyleCustom)
|
||||
{
|
||||
// dash pattern
|
||||
std::vector<double> dash_pattern(m_oPen.Count);
|
||||
long count = m_oPen.Count;
|
||||
m_oPen.GetDashPattern(dash_pattern.data(), count);
|
||||
|
||||
oWriter.WriteString(L"<a:custDash>");
|
||||
for (size_t i = 0; i < count; i+= 2)
|
||||
{
|
||||
double to_percentage = 100.0 * 1000.0 / m_oPen.Size;
|
||||
oWriter.WriteString(L"<a:ds d=\"");
|
||||
oWriter.AddUInt(ClampUIntSign(dash_pattern[i] * to_percentage));
|
||||
oWriter.WriteString(L"\" ");
|
||||
oWriter.WriteString(L"sp=\"");
|
||||
oWriter.AddUInt(ClampUIntSign(dash_pattern[i + 1] * to_percentage));
|
||||
oWriter.WriteString(L"\" />");
|
||||
}
|
||||
oWriter.WriteString(L"</a:custDash>");
|
||||
}
|
||||
// Aggplus::DashStyleSolid
|
||||
oWriter.WriteString(L"</a:ln>");
|
||||
}
|
||||
}
|
||||
@ -1072,6 +1047,4 @@ namespace NSDocxRenderer
|
||||
}
|
||||
oWriter.WriteString(L"</p:sp>");
|
||||
}
|
||||
|
||||
|
||||
}; // namespace NSDocxRenderer
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "../../../../DesktopEditor/graphics/structures.h"
|
||||
|
||||
#include "../../resources/ImageInfo.h"
|
||||
@ -62,7 +65,6 @@ namespace NSDocxRenderer
|
||||
|
||||
std::vector<std::shared_ptr<CBaseItem>> m_arOutputObjects;
|
||||
|
||||
|
||||
public:
|
||||
CShape();
|
||||
CShape(std::shared_ptr<CImageInfo> pInfo, const std::wstring& strDstMedia);
|
||||
|
||||
127
DocxRenderer/src/logic/elements/Table.cpp
Normal file
127
DocxRenderer/src/logic/elements/Table.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
#include "Table.h"
|
||||
|
||||
#include "../../resources/SingletonTemplate.h"
|
||||
#include "../../resources/utils.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
void CTable::CCell::Clear()
|
||||
{
|
||||
m_arParagraphs.clear();
|
||||
}
|
||||
void CTable::CCell::ToXml(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
oWriter.WriteString(L"<w:tc>");
|
||||
oWriter.WriteString(L"<w:tcPr>");
|
||||
oWriter.WriteString(L"<w:tcW w:w=\"");
|
||||
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"w:type=\"dxa\"/>");
|
||||
|
||||
oWriter.WriteString(L"<w:tcBorders>");
|
||||
|
||||
auto write_border = [&oWriter] (const CBorder& border, const std::wstring& prefix) {
|
||||
oWriter.WriteString(L"<w:");
|
||||
oWriter.WriteString(prefix);
|
||||
oWriter.WriteString(L" w:val=");
|
||||
oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(border.lineType));
|
||||
oWriter.WriteString(L" w:sz=\"");
|
||||
oWriter.AddUInt(static_cast<unsigned int>(border.dWidth * c_dMMToPt / 8));
|
||||
oWriter.WriteString(L"\" w:space=\"");
|
||||
oWriter.AddUInt(static_cast<unsigned int>(border.dSpacing * c_dMMToPt));
|
||||
oWriter.WriteString(L"\" w:color=\"");
|
||||
oWriter.WriteHexInt3(ConvertColorBGRToRGB(border.lColor));
|
||||
oWriter.WriteString(L"\" />");
|
||||
};
|
||||
|
||||
write_border(m_oBorderTop, L"top");
|
||||
write_border(m_oBorderBot, L"bot");
|
||||
write_border(m_oBorderLeft, L"left");
|
||||
write_border(m_oBorderRight, L"right");
|
||||
|
||||
oWriter.WriteString(L"</w:tcBorders>");
|
||||
oWriter.WriteString(L"</w:tcPr>");
|
||||
|
||||
for (const auto& p : m_arParagraphs)
|
||||
p->ToXml(oWriter);
|
||||
|
||||
oWriter.WriteString(L"</w:tc>");
|
||||
}
|
||||
void CTable::CCell::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
|
||||
}
|
||||
void CTable::CCell::AddParagraph(const paragraph_ptr_t& pParagraph)
|
||||
{
|
||||
m_arParagraphs.push_back(pParagraph);
|
||||
}
|
||||
|
||||
void CTable::CRow::Clear()
|
||||
{
|
||||
m_arCells.clear();
|
||||
}
|
||||
void CTable::CRow::ToXml(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
oWriter.WriteString(L"<w:tr>");
|
||||
|
||||
oWriter.WriteString(L"<w:trPr>");
|
||||
oWriter.WriteString(L"<w:trHeight w:val=\"");
|
||||
oWriter.AddUInt(static_cast<unsigned int>(m_dHeight * c_dMMToDx));
|
||||
oWriter.WriteString(L"\" w:hRule=\"exact\"/>");
|
||||
oWriter.WriteString(L"</w:trPr>");
|
||||
|
||||
for (const auto& c : m_arCells)
|
||||
c->ToXml(oWriter);
|
||||
|
||||
oWriter.WriteString(L"</w:tr>");
|
||||
}
|
||||
void CTable::CRow::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
|
||||
}
|
||||
void CTable::CRow::AddCell(const cell_ptr_t& pCell)
|
||||
{
|
||||
CBaseItem::RecalcWithNewItem(pCell.get());
|
||||
m_arCells.push_back(pCell);
|
||||
}
|
||||
bool CTable::CRow::IsEmpty() const
|
||||
{
|
||||
return m_arCells.empty();
|
||||
}
|
||||
|
||||
void CTable::Clear()
|
||||
{
|
||||
m_arRows.clear();
|
||||
}
|
||||
void CTable::ToXml(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
oWriter.WriteString(L"<w:tbl>");
|
||||
|
||||
oWriter.WriteString(L"<w:tblPr>");
|
||||
oWriter.WriteString(L"<w:tblW w:w=\"");
|
||||
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
|
||||
oWriter.WriteString(L"\"w:type=\"dxa\"/>");
|
||||
oWriter.WriteString(L"</w:tblPr>");
|
||||
|
||||
oWriter.WriteString(L"<w:tblGrid>");
|
||||
oWriter.WriteString(L"</w:tblGrid>");
|
||||
|
||||
for (const auto& r : m_arRows)
|
||||
r->ToXml(oWriter);
|
||||
|
||||
oWriter.WriteString(L"</w:tbl>");
|
||||
}
|
||||
void CTable::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
|
||||
{
|
||||
|
||||
}
|
||||
void CTable::AddRow(const row_ptr_t& pRow)
|
||||
{
|
||||
CBaseItem::RecalcWithNewItem(pRow.get());
|
||||
m_arRows.push_back(pRow);
|
||||
}
|
||||
bool CTable::IsEmpty() const
|
||||
{
|
||||
return m_arRows.empty();
|
||||
}
|
||||
|
||||
} // namespace NSDocxRenderer
|
||||
82
DocxRenderer/src/logic/elements/Table.h
Normal file
82
DocxRenderer/src/logic/elements/Table.h
Normal file
@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "BaseItem.h"
|
||||
#include "Paragraph.h"
|
||||
|
||||
#include "../../resources/LinesTable.h"
|
||||
|
||||
namespace NSDocxRenderer
|
||||
{
|
||||
class CTable : public CBaseItem
|
||||
{
|
||||
public:
|
||||
class CCell;
|
||||
class CRow;
|
||||
|
||||
using cell_ptr_t = std::shared_ptr<CCell>;
|
||||
using row_ptr_t = std::shared_ptr<CRow>;
|
||||
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
|
||||
|
||||
public:
|
||||
class CCell : public CBaseItem
|
||||
{
|
||||
public:
|
||||
struct CBorder
|
||||
{
|
||||
double dWidth{};
|
||||
double dSpacing{};
|
||||
long lColor{};
|
||||
eLineType lineType{};
|
||||
};
|
||||
|
||||
CCell() = default;
|
||||
virtual ~CCell() = default;
|
||||
virtual void Clear() override final;
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
|
||||
void AddParagraph(const paragraph_ptr_t& pParagraph);
|
||||
|
||||
CBorder m_oBorderTop;
|
||||
CBorder m_oBorderBot;
|
||||
CBorder m_oBorderLeft;
|
||||
CBorder m_oBorderRight;
|
||||
|
||||
private:
|
||||
std::vector<paragraph_ptr_t> m_arParagraphs;
|
||||
};
|
||||
class CRow : public CBaseItem
|
||||
{
|
||||
public:
|
||||
CRow() = default;
|
||||
virtual ~CRow() = default;
|
||||
virtual void Clear() override final;
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
|
||||
void AddCell(const cell_ptr_t& pCell);
|
||||
bool IsEmpty() const;
|
||||
|
||||
private:
|
||||
std::vector<cell_ptr_t> m_arCells;
|
||||
};
|
||||
|
||||
CTable() = default;
|
||||
virtual ~CTable() = default;
|
||||
virtual void Clear() override final;
|
||||
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
|
||||
|
||||
void AddRow(const row_ptr_t& pRow);
|
||||
bool IsEmpty() const;
|
||||
|
||||
private:
|
||||
std::vector<row_ptr_t> m_arRows;
|
||||
};
|
||||
} // namespace NSDocxRenderer
|
||||
|
||||
|
||||
|
||||
@ -37,6 +37,25 @@ namespace NSDocxRenderer
|
||||
return true;
|
||||
}
|
||||
|
||||
double CTextLine::GetLeftNoEnum() const noexcept
|
||||
{
|
||||
double left_no_enum = m_dLeft;
|
||||
const auto& first_sym = m_arConts.front()->GetText().at(0);
|
||||
|
||||
size_t i = 0, j = 0;
|
||||
GetNextSym(i, j);
|
||||
|
||||
if (CContText::IsUnicodeBullet(first_sym))
|
||||
{
|
||||
while (CContText::IsUnicodeSpace(m_arConts[i]->GetText().at(j)) && i && j) GetNextSym(i, j);
|
||||
|
||||
// one more time to get next
|
||||
GetNextSym(i, j);
|
||||
left_no_enum = (!i && !j) ? m_arConts.back()->m_dRight : m_arConts[i]->GetSymLefts().at(j);
|
||||
}
|
||||
return left_no_enum;
|
||||
}
|
||||
|
||||
void CTextLine::MergeConts()
|
||||
{
|
||||
if (m_arConts.empty())
|
||||
@ -97,9 +116,6 @@ namespace NSDocxRenderer
|
||||
wide_space->m_pFontStyle = pFirst->m_pFontStyle;
|
||||
wide_space->m_pShape = nullptr;
|
||||
wide_space->m_iNumDuplicates = 0;
|
||||
|
||||
// cache that value? (calls rarely)
|
||||
wide_space->CalcSelected();
|
||||
};
|
||||
|
||||
if (bIsEqual)
|
||||
@ -206,7 +222,7 @@ namespace NSDocxRenderer
|
||||
m_dHeight = 0.0;
|
||||
|
||||
for (const auto& cont : m_arConts)
|
||||
if(cont)
|
||||
if (cont)
|
||||
RecalcWithNewItem(cont.get());
|
||||
}
|
||||
|
||||
@ -306,4 +322,21 @@ namespace NSDocxRenderer
|
||||
|
||||
return len;
|
||||
}
|
||||
void CTextLine::GetNextSym(size_t& nContPos, size_t& nSymPos) const noexcept
|
||||
{
|
||||
++nSymPos;
|
||||
if (m_arConts[nContPos]->GetLength() <= nSymPos)
|
||||
for (nContPos = nContPos + 1; nContPos < m_arConts.size(); ++nContPos)
|
||||
if (m_arConts[nContPos] && m_arConts[nContPos]->GetLength() != 0)
|
||||
{
|
||||
nSymPos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_arConts.size() <= nContPos)
|
||||
{
|
||||
nContPos = 0;
|
||||
nSymPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,9 @@ namespace NSDocxRenderer
|
||||
bool IsShadingPresent(const CTextLine* pLine) const noexcept;
|
||||
bool IsCanBeDeleted() const;
|
||||
|
||||
double GetLeftNoEnum() const noexcept;
|
||||
|
||||
size_t GetLength() const;
|
||||
void GetNextSym(size_t& nContPos, size_t& nSymPos) const noexcept;
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "../../../../DesktopEditor/raster/BgraFrame.h"
|
||||
#include "../../../../DesktopEditor/graphics/Image.h"
|
||||
#include "../../resources/ImageInfo.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#ifndef DOCXRENDERER_USE_DYNAMIC_LIBRARY
|
||||
|
||||
@ -530,13 +530,15 @@ namespace NSDocxRenderer
|
||||
RELEASEINTERFACE(m_pManager);
|
||||
}
|
||||
|
||||
void CFontManager::LoadFontByFile(const NSStructures::CFont& oFont)
|
||||
bool CFontManager::LoadFontByFile(const NSStructures::CFont& oFont)
|
||||
{
|
||||
if(m_oFont.IsEqual2(&oFont))
|
||||
return;
|
||||
if (m_oFont.IsEqual2(&oFont))
|
||||
return true;
|
||||
|
||||
if (!m_pManager->LoadFontFromFile(oFont.Path, (int)oFont.FaceIndex, (float)oFont.Size, c_dDpiX, c_dDpiY))
|
||||
return false;
|
||||
|
||||
m_oFont = oFont;
|
||||
m_pManager->LoadFontFromFile(m_oFont.Path, (int)m_oFont.FaceIndex, (float)m_oFont.Size, c_dDpiX, c_dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
LoadFontMetrics();
|
||||
@ -546,18 +548,24 @@ namespace NSDocxRenderer
|
||||
m_oFontSelectParams.wsDefaultName = m_oFont.Name;
|
||||
|
||||
CheckPdfResources();
|
||||
|
||||
return true;
|
||||
}
|
||||
void CFontManager::LoadFontByName(const NSStructures::CFont& oFont)
|
||||
bool CFontManager::LoadFontByName(const NSStructures::CFont& oFont)
|
||||
{
|
||||
if(m_oFont.IsEqual2(&oFont))
|
||||
return;
|
||||
if (m_oFont.IsEqual2(&oFont))
|
||||
return true;
|
||||
|
||||
m_oFont = oFont;
|
||||
m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY);
|
||||
m_pManager->AfterLoad();
|
||||
|
||||
if (!m_pManager->LoadFontByName(m_oFont.Name, (float)m_oFont.Size, m_oFont.GetStyle2(), c_dDpiX, c_dDpiY))
|
||||
return false;
|
||||
|
||||
m_pManager->AfterLoad();
|
||||
LoadFontMetrics();
|
||||
LoadFontSelectParams();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const CFontSelectParams& CFontManager::GetFontSelectParams() const noexcept
|
||||
|
||||
@ -117,8 +117,8 @@ namespace NSDocxRenderer
|
||||
CFontManager(NSFonts::IApplicationFonts* pFonts);
|
||||
~CFontManager();
|
||||
|
||||
void LoadFontByFile(const NSStructures::CFont& oFont);
|
||||
void LoadFontByName(const NSStructures::CFont& oFont);
|
||||
bool LoadFontByFile(const NSStructures::CFont& oFont);
|
||||
bool LoadFontByName(const NSStructures::CFont& oFont);
|
||||
|
||||
const CFontSelectParams& GetFontSelectParams() const noexcept;
|
||||
const CFontMetrics& GetFontMetrics() const noexcept;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "ImageManager.h"
|
||||
|
||||
#include "../../../../DesktopEditor/common/Directory.h"
|
||||
#include "../../../../DesktopEditor/raster/BgraFrame.h"
|
||||
|
||||
#include "../../resources/Constants.h"
|
||||
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../../../../DesktopEditor/common/CalculatorCRC32.h"
|
||||
|
||||
#include "ExternalImageStorage.h"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "../elements/Paragraph.h"
|
||||
#include "../styles/ParagraphStyle.h"
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
class ColorTable
|
||||
{
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
#include "VectorGraphics.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <numeric>
|
||||
#include <limits>
|
||||
|
||||
#include "../../../DesktopEditor/graphics/Matrix.h"
|
||||
@ -390,4 +388,50 @@ namespace NSDocxRenderer
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
CHorVerLinesCollector::CHorVerLine::CHorVerLine(const double& _min, const double& _max, const double& _pos)
|
||||
{
|
||||
min = _min;
|
||||
max = _max;
|
||||
pos = _pos;
|
||||
}
|
||||
const std::vector<CHorVerLinesCollector::CHorVerLine>& CHorVerLinesCollector::GetHorizontal() const
|
||||
{
|
||||
return m_arHorizontal;
|
||||
}
|
||||
const std::vector<CHorVerLinesCollector::CHorVerLine>& CHorVerLinesCollector::GetVertical() const
|
||||
{
|
||||
return m_arVertical;
|
||||
}
|
||||
|
||||
void CHorVerLinesCollector::AddVector(const CVectorGraphics& oVector)
|
||||
{
|
||||
double last_x{};
|
||||
double last_y{};
|
||||
|
||||
for (const auto& command : oVector.GetData())
|
||||
{
|
||||
if (command.type == CVectorGraphics::ePathCommandType::pctLine)
|
||||
{
|
||||
double x = command.points.front().x;
|
||||
double y = command.points.front().y;
|
||||
|
||||
if (x - last_x <= std::numeric_limits<double>::epsilon())
|
||||
m_arVertical.push_back({std::min(last_y, y), std::max(last_y, y), x});
|
||||
|
||||
else if (y - last_y <= std::numeric_limits<double>::epsilon())
|
||||
m_arHorizontal.push_back({std::min(last_x, x), std::max(last_x, x), y});
|
||||
}
|
||||
if (!command.points.empty())
|
||||
{
|
||||
last_x = command.points.back().x;
|
||||
last_y = command.points.back().y;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CHorVerLinesCollector::Clear()
|
||||
{
|
||||
m_arVertical.clear();
|
||||
m_arHorizontal.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
#include "../../../DesktopEditor/graphics/GraphicsPath.h"
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
namespace NSDocxRenderer
|
||||
@ -15,7 +14,8 @@ namespace NSDocxRenderer
|
||||
Point() {}
|
||||
Point(double x, double y) : x(x), y(y) {}
|
||||
Point(const Point& point) : x(point.x), y(point.y) {}
|
||||
};
|
||||
Point& operator=(const Point& point) {x = point.x; y = point.y; return *this;}
|
||||
};;
|
||||
|
||||
class CVectorGraphics
|
||||
{
|
||||
@ -96,4 +96,31 @@ namespace NSDocxRenderer
|
||||
static Aggplus::BooleanOpType GetOpType(long nClipType);
|
||||
static std::vector<Point> GetPointsCurve(const std::array<Point, 4>& curve, double step = 0.05);
|
||||
};
|
||||
|
||||
// collect and contains horizontal and vertical lines
|
||||
class CHorVerLinesCollector
|
||||
{
|
||||
public:
|
||||
struct CHorVerLine
|
||||
{
|
||||
double min{};
|
||||
double max{};
|
||||
double pos{};
|
||||
|
||||
CHorVerLine(const double& _min, const double& _max, const double& _pos);
|
||||
};
|
||||
|
||||
CHorVerLinesCollector() = default;
|
||||
~CHorVerLinesCollector() = default;
|
||||
|
||||
const std::vector<CHorVerLine>& GetHorizontal() const;
|
||||
const std::vector<CHorVerLine>& GetVertical() const;
|
||||
|
||||
void AddVector(const CVectorGraphics& oVector);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
std::vector<CHorVerLine> m_arHorizontal;
|
||||
std::vector<CHorVerLine> m_arVertical;
|
||||
};
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
|
||||
if (nContent != std::wstring::npos)
|
||||
{
|
||||
nContent += 11;
|
||||
sContent = sFileContent.substr(nContent, sFileContent.find(L'\"', nContent) - nContent);
|
||||
sContent = sFileContent.substr(nContent, sFileContent.find_first_of(L"\"'", nContent) - nContent);
|
||||
}
|
||||
|
||||
std::wstring sContentPath;
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include "../Common/3dParty/html/htmltoxhtml.h"
|
||||
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
|
||||
@ -63,6 +61,8 @@ const static double HTML_FONTS[7] = {7.5, 10, 12, 13.5, 18, 24, 36};
|
||||
|
||||
#define HtmlTag GumboTag
|
||||
|
||||
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
|
||||
|
||||
const std::map<std::wstring, HtmlTag> m_HTML_TAGS
|
||||
{
|
||||
ADD_TAG(L"a", A),
|
||||
@ -217,6 +217,27 @@ static inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag)
|
||||
return oFound->second;
|
||||
}
|
||||
|
||||
static inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder)
|
||||
{
|
||||
if (oSrcStringBuilder.GetCurSize() < MAX_STRING_BLOCK_SIZE)
|
||||
{
|
||||
oDstStringBuilder.Write(oSrcStringBuilder);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t ulSize = oSrcStringBuilder.GetCurSize();
|
||||
size_t ulCurrentBlockSize = 0, ulPosition = 0;
|
||||
|
||||
while (ulSize > 0)
|
||||
{
|
||||
ulCurrentBlockSize = std::min(ulSize, MAX_STRING_BLOCK_SIZE);
|
||||
oDstStringBuilder.WriteString(oSrcStringBuilder.GetSubData(ulPosition, ulCurrentBlockSize));
|
||||
|
||||
ulSize -= ulCurrentBlockSize;
|
||||
ulPosition += ulCurrentBlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Ячейка таблицы
|
||||
struct CTc
|
||||
{
|
||||
@ -591,7 +612,7 @@ public:
|
||||
: 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)
|
||||
{
|
||||
m_oData.SetText(oCell.m_oData.GetData());
|
||||
WriteToStringBuilder(oCell.m_oData, m_oData);
|
||||
}
|
||||
|
||||
bool Empty()
|
||||
@ -599,6 +620,11 @@ public:
|
||||
return m_bIsEmpty;
|
||||
}
|
||||
|
||||
bool Merged()
|
||||
{
|
||||
return m_bIsMerged;
|
||||
}
|
||||
|
||||
CTableCell* Copy()
|
||||
{
|
||||
return new CTableCell(*this);
|
||||
@ -756,7 +782,7 @@ public:
|
||||
|
||||
if (nPosition < 0)
|
||||
{
|
||||
std::vector<CTableCell*>::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty(); });
|
||||
std::vector<CTableCell*>::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); });
|
||||
|
||||
if (m_arCells.end() != itFoundEmpty)
|
||||
{
|
||||
@ -766,6 +792,7 @@ public:
|
||||
|
||||
if (1 != pCell->GetColspan())
|
||||
{
|
||||
++itFoundEmpty;
|
||||
UINT unColspan = pCell->GetColspan() - 1;
|
||||
|
||||
while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0)
|
||||
@ -798,12 +825,13 @@ public:
|
||||
{
|
||||
delete m_arCells[nPosition];
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
m_arCells[nPosition++] = pCell;
|
||||
m_arCells[nPosition] = pCell;
|
||||
|
||||
if (1 != pCell->GetColspan())
|
||||
{
|
||||
++nPosition;
|
||||
UINT unDeleteCount = pCell->GetColspan() - 1;
|
||||
while (m_arCells[nPosition]->Empty() && nPosition < m_arCells.size() && unDeleteCount > 0)
|
||||
while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0)
|
||||
{
|
||||
delete m_arCells[nPosition];
|
||||
--m_oStyles.m_unMaxIndex;
|
||||
@ -1077,7 +1105,7 @@ public:
|
||||
|
||||
void AddCaption(NSStringUtils::CStringBuilder& oCaption)
|
||||
{
|
||||
m_oCaption += oCaption.GetData();
|
||||
WriteToStringBuilder(oCaption, m_oCaption);
|
||||
}
|
||||
|
||||
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
|
||||
@ -1168,7 +1196,7 @@ public:
|
||||
if (NULL == pCell)
|
||||
continue;
|
||||
|
||||
pCell->SetColspan(unMaxIndex , MAXCOLUMNSINTABLE);
|
||||
pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1180,9 +1208,9 @@ public:
|
||||
if (NULL == pCell)
|
||||
continue;
|
||||
|
||||
if (1 < pCell->GetColspan() && unIndex + pCell->GetColspan() > m_arMinColspan[unIndex])
|
||||
if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex])
|
||||
{
|
||||
pCell->SetColspan(m_arMinColspan[unIndex] - unIndex, MAXCOLUMNSINTABLE);
|
||||
pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1215,42 +1243,40 @@ public:
|
||||
RecalculateMaxColumns();
|
||||
}
|
||||
|
||||
std::wstring ConvertToOOXML()
|
||||
bool ConvertToOOXML(NSStringUtils::CStringBuilder& oStringBuilder)
|
||||
{
|
||||
if (m_arRows.empty())
|
||||
return std::wstring();
|
||||
return false;
|
||||
|
||||
NSStringUtils::CStringBuilder oTable;
|
||||
|
||||
oTable.WriteNodeBegin(L"w:tbl");
|
||||
oTable.WriteNodeBegin(L"w:tblPr");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tbl");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tblPr");
|
||||
|
||||
if (!m_oStyles.m_oWidth.Empty() && !m_oStyles.m_oWidth.Zero())
|
||||
{
|
||||
if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oWidth.GetUnitMeasure())
|
||||
oTable += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>";
|
||||
oStringBuilder += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>";
|
||||
else
|
||||
oTable += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:tblW w:w=\"" + std::to_wstring(m_oStyles.m_oWidth.ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>";
|
||||
}
|
||||
else
|
||||
oTable += L"<w:tblW w:w=\"0\" w:type=\"auto\"/>";
|
||||
oStringBuilder += L"<w:tblW w:w=\"0\" w:type=\"auto\"/>";
|
||||
|
||||
if (!m_oStyles.m_oMargin.GetLeft().Empty() && !m_oStyles.m_oMargin.GetLeft().Zero())
|
||||
{
|
||||
if (NSCSS::UnitMeasure::Percent == m_oStyles.m_oMargin.GetLeft().GetUnitMeasure())
|
||||
oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>";
|
||||
oStringBuilder += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Percent, 5000)) + L"\" w:type=\"pct\"/>";
|
||||
else
|
||||
oTable += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:tblInd w:w=\"" + std::to_wstring(m_oStyles.m_oMargin.GetLeft().ToInt(NSCSS::UnitMeasure::Twips)) + L"\" w:type=\"dxa\"/>";
|
||||
}
|
||||
|
||||
if (!m_oStyles.m_wsAlign.empty())
|
||||
oTable += L"<w:jc w:val=\"" + m_oStyles.m_wsAlign + L"\"/>";
|
||||
oStringBuilder += L"<w:jc w:val=\"" + m_oStyles.m_wsAlign + L"\"/>";
|
||||
|
||||
if (0 < m_oStyles.m_nCellSpacing && m_oStyles.m_oBorder.GetCollapse() != NSCSS::NSProperties::BorderCollapse::Collapse)
|
||||
oTable += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(m_oStyles.m_nCellSpacing) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:tblCellSpacing w:w=\"" + std::to_wstring(m_oStyles.m_nCellSpacing) + L"\" w:type=\"dxa\"/>";
|
||||
|
||||
if (!m_oStyles.m_oBorder.Empty() && !m_oStyles.m_oBorder.Zero())
|
||||
oTable += L"<w:tblBorders>" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L"</w:tblBorders>";
|
||||
oStringBuilder += L"<w:tblBorders>" + CreateBorders(m_oStyles.m_oBorder, NULL, true, (TTableStyles::ETableRules::Groups == m_oStyles.m_enRules && !m_arColgroups.empty()) ? TTableStyles::ETableRules::Cols : m_oStyles.m_enRules) + L"</w:tblBorders>";
|
||||
|
||||
if (!m_oStyles.m_oPadding.Empty() && !m_oStyles.m_oPadding.Zero())
|
||||
{
|
||||
@ -1259,42 +1285,42 @@ public:
|
||||
const int nBottomPadding = std::max(0, m_oStyles.m_oPadding.GetBottom().ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_HEIGHT));
|
||||
const int nRightPadding = std::max(0, m_oStyles.m_oPadding.GetRight() .ToInt(NSCSS::UnitMeasure::Twips, DEFAULT_PAGE_WIDTH ));
|
||||
|
||||
oTable.WriteNodeBegin(L"w:tblCellMar");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tblCellMar");
|
||||
|
||||
if (0 != nTopPadding)
|
||||
oTable += L"<w:top w:w=\"" + std::to_wstring(nTopPadding) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:top w:w=\"" + std::to_wstring(nTopPadding) + L"\" w:type=\"dxa\"/>";
|
||||
|
||||
if (0 != nLeftPadding)
|
||||
oTable += L"<w:left w:w=\"" + std::to_wstring(nLeftPadding) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:left w:w=\"" + std::to_wstring(nLeftPadding) + L"\" w:type=\"dxa\"/>";
|
||||
|
||||
if (0 != nBottomPadding)
|
||||
oTable += L"<w:bottom w:w=\"" + std::to_wstring(nBottomPadding) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:bottom w:w=\"" + std::to_wstring(nBottomPadding) + L"\" w:type=\"dxa\"/>";
|
||||
|
||||
if (0 != nRightPadding)
|
||||
oTable += L"<w:right w:w=\"" + std::to_wstring(nRightPadding) + L"\" w:type=\"dxa\"/>";
|
||||
oStringBuilder += L"<w:right w:w=\"" + std::to_wstring(nRightPadding) + L"\" w:type=\"dxa\"/>";
|
||||
|
||||
oTable.WriteNodeEnd(L"w:tblCellMar");
|
||||
oStringBuilder.WriteNodeEnd(L"w:tblCellMar");
|
||||
}
|
||||
else
|
||||
oTable += L"<w:tblCellMar><w:top w:w=\"15\" w:type=\"dxa\"/><w:left w:w=\"15\" w:type=\"dxa\"/><w:bottom w:w=\"15\" w:type=\"dxa\"/><w:right w:w=\"15\" w:type=\"dxa\"/></w:tblCellMar>";
|
||||
oStringBuilder += L"<w:tblCellMar><w:top w:w=\"15\" w:type=\"dxa\"/><w:left w:w=\"15\" w:type=\"dxa\"/><w:bottom w:w=\"15\" w:type=\"dxa\"/><w:right w:w=\"15\" w:type=\"dxa\"/></w:tblCellMar>";
|
||||
|
||||
oTable += L"<w:tblLook w:val=\"04A0\" w:noVBand=\"1\" w:noHBand=\"0\" w:lastColumn=\"0\" w:firstColumn=\"1\" w:lastRow=\"0\" w:firstRow=\"1\"/>";
|
||||
oTable.WriteNodeEnd(L"w:tblPr");
|
||||
oStringBuilder += L"<w:tblLook w:val=\"04A0\" w:noVBand=\"1\" w:noHBand=\"0\" w:lastColumn=\"0\" w:firstColumn=\"1\" w:lastRow=\"0\" w:firstRow=\"1\"/>";
|
||||
oStringBuilder.WriteNodeEnd(L"w:tblPr");
|
||||
|
||||
if (HaveCaption())
|
||||
{
|
||||
oTable.WriteNodeBegin(L"w:tr");
|
||||
oTable.WriteNodeBegin(L"w:tc");
|
||||
oTable.WriteNodeBegin(L"w:tcPr");
|
||||
oTable += L"<w:tcW w:w=\"0\" w:type=\"auto\"/>";
|
||||
oTable += L"<w:gridSpan w:val=\"" + std::to_wstring(m_unMaxColumns) + L"\"/>";
|
||||
oTable += L"<w:tcBorders><w:top w:val=\"nil\"/><w:left w:val=\"nil\"/><w:bottom w:val=\"nil\"/><w:right w:val=\"nil\"/></w:tcBorders>";
|
||||
oTable += L"<w:vAlign w:val=\"center\"/>";
|
||||
oTable += L"<w:hideMark/>";
|
||||
oTable.WriteNodeEnd(L"w:tcPr");
|
||||
oTable.WriteString(m_oCaption.GetData());
|
||||
oTable.WriteNodeEnd(L"w:tc");
|
||||
oTable.WriteNodeEnd(L"w:tr");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tr");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tc");
|
||||
oStringBuilder.WriteNodeBegin(L"w:tcPr");
|
||||
oStringBuilder += L"<w:tcW w:w=\"0\" w:type=\"auto\"/>";
|
||||
oStringBuilder += L"<w:gridSpan w:val=\"" + std::to_wstring(m_unMaxColumns) + L"\"/>";
|
||||
oStringBuilder += L"<w:tcBorders><w:top w:val=\"nil\"/><w:left w:val=\"nil\"/><w:bottom w:val=\"nil\"/><w:right w:val=\"nil\"/></w:tcBorders>";
|
||||
oStringBuilder += L"<w:vAlign w:val=\"center\"/>";
|
||||
oStringBuilder += L"<w:hideMark/>";
|
||||
oStringBuilder.WriteNodeEnd(L"w:tcPr");
|
||||
WriteToStringBuilder(m_oCaption, oStringBuilder);
|
||||
oStringBuilder.WriteNodeEnd(L"w:tc");
|
||||
oStringBuilder.WriteNodeEnd(L"w:tr");
|
||||
}
|
||||
|
||||
#define CONVERT_ROWS(rows, mode) \
|
||||
@ -1309,7 +1335,7 @@ public:
|
||||
else if (0 != unRowIndex) \
|
||||
nInstruction |= MID_ELEMENT << 4; \
|
||||
nInstruction |= mode; \
|
||||
oTable += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \
|
||||
oStringBuilder += rows[unRowIndex]->ConvertToOOXML(*this, nInstruction); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -1319,9 +1345,9 @@ public:
|
||||
CONVERT_ROWS(m_arRows, PARSE_MODE_BODY)
|
||||
CONVERT_ROWS(m_arFoother, PARSE_MODE_FOOTHER)
|
||||
|
||||
oTable.WriteNodeEnd(L"w:tbl");
|
||||
oStringBuilder.WriteNodeEnd(L"w:tbl");
|
||||
|
||||
return oTable.GetData();
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
std::vector<std::vector<CTableRow*>> m_arHeaders;
|
||||
@ -1561,7 +1587,7 @@ public:
|
||||
}
|
||||
|
||||
// settings.xml
|
||||
std::wstring sSettings = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:clrSchemeMapping w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:bg1=\"light1\" w:bg2=\"light2\" w:followedHyperlink=\"followedHyperlink\" w:hyperlink=\"hyperlink\" w:t1=\"dark1\" w:t2=\"dark2\"/><w:defaultTabStop w:val=\"708\"/><m:mathPr/><w:trackRevisions w:val=\"false\"/><w:footnotePr><w:footnote w:id=\"-1\"/><w:footnote w:id=\"0\"/><w:numFmt w:val=\"decimal\"/><w:numRestart w:val=\"continuous\"/><w:numStart w:val=\"1\"/><w:pos w:val=\"pageBottom\"/></w:footnotePr><w:decimalSymbol w:val=\".\"/><w:listSeparator w:val=\",\"/><w:compat><w:compatSetting w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"15\"/><w:compatSetting w:name=\"overrideTableStyleFontSizeAndJustification\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"enableOpenTypeFeatures\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"doNotFlipMirrorIndents\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"useWord2013TrackBottomHyphenation\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"0\"/></w:compat><w:zoom w:percent=\"100\"/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout></w:shapeDefaults></w:settings>";
|
||||
std::wstring sSettings = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><w:settings xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:v=\"urn:schemas-microsoft-com:vml\"><w:displayBackgroundShape/><w:clrSchemeMapping w:accent1=\"accent1\" w:accent2=\"accent2\" w:accent3=\"accent3\" w:accent4=\"accent4\" w:accent5=\"accent5\" w:accent6=\"accent6\" w:bg1=\"light1\" w:bg2=\"light2\" w:followedHyperlink=\"followedHyperlink\" w:hyperlink=\"hyperlink\" w:t1=\"dark1\" w:t2=\"dark2\"/><w:defaultTabStop w:val=\"708\"/><m:mathPr/><w:trackRevisions w:val=\"false\"/><w:footnotePr><w:footnote w:id=\"-1\"/><w:footnote w:id=\"0\"/><w:numFmt w:val=\"decimal\"/><w:numRestart w:val=\"continuous\"/><w:numStart w:val=\"1\"/><w:pos w:val=\"pageBottom\"/></w:footnotePr><w:decimalSymbol w:val=\".\"/><w:listSeparator w:val=\",\"/><w:compat><w:compatSetting w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"15\"/><w:compatSetting w:name=\"overrideTableStyleFontSizeAndJustification\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"enableOpenTypeFeatures\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"doNotFlipMirrorIndents\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"1\"/><w:compatSetting w:name=\"useWord2013TrackBottomHyphenation\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"0\"/></w:compat><w:zoom w:percent=\"100\"/><w:characterSpacingControl w:val=\"doNotCompress\"/><w:themeFontLang w:val=\"en-US\" w:eastAsia=\"zh-CN\"/><w:shapeDefaults><o:shapedefaults v:ext=\"edit\" spidmax=\"1026\"/><o:shapelayout v:ext=\"edit\"><o:idmap v:ext=\"edit\" data=\"1\"/></o:shapelayout></w:shapeDefaults></w:settings>";
|
||||
NSFile::CFileBinary oSettingsWriter;
|
||||
if (oSettingsWriter.CreateFileW(m_sDst + L"/word/settings.xml"))
|
||||
{
|
||||
@ -1720,6 +1746,15 @@ public:
|
||||
oRelsWriter.CloseFile();
|
||||
}
|
||||
|
||||
for (const std::pair<std::wstring, std::wstring>& oFootnote : m_mFootnotes)
|
||||
{
|
||||
m_oNoteXml.WriteString(L"<w:footnote w:id=\"");
|
||||
m_oNoteXml.WriteString(oFootnote.second);
|
||||
m_oNoteXml.WriteString(L"\"><w:p><w:pPr><w:pStyle w:val=\"footnote-p\"/></w:pPr><w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr></w:r><w:r><w:t xml:space=\"preserve\">");
|
||||
m_oNoteXml.WriteEncodeXmlString(oFootnote.first);
|
||||
m_oNoteXml.WriteString(L"</w:t></w:r></w:p></w:footnote>");
|
||||
}
|
||||
|
||||
m_oNoteXmlRels.WriteString(L"</Relationships>");
|
||||
if (oRelsWriter.CreateFileW(m_sDst + L"/word/_rels/footnotes.xml.rels"))
|
||||
{
|
||||
@ -2178,10 +2213,12 @@ private:
|
||||
NSCSS::CCompiledStyle oStyle;
|
||||
m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors);
|
||||
|
||||
INT nMarLeft = 720;
|
||||
INT nMarRight = 720;
|
||||
INT nMarTop = 100;
|
||||
INT nMarBottom = 100;
|
||||
const bool bInTable = ElementInTable(sSelectors);
|
||||
|
||||
INT nMarLeft = (!bInTable) ? 720 : 0;
|
||||
INT nMarRight = (!bInTable) ? 720 : 0;
|
||||
INT nMarTop = (!bInTable) ? 100 : 0;
|
||||
INT nMarBottom = (!bInTable) ? 100 : 0;
|
||||
|
||||
if (!oStyle.m_oMargin.GetLeft().Empty() && !oStyle.m_oMargin.GetLeft().Zero())
|
||||
nMarLeft = oStyle.m_oMargin.GetLeft().ToInt(NSCSS::Twips, m_oPageData.GetWidth().ToInt(NSCSS::Twips));
|
||||
@ -2294,6 +2331,28 @@ private:
|
||||
m_oDocXml.WriteString(L"\"/>");
|
||||
*/
|
||||
|
||||
if (!sSelectors.back().m_mAttributes.empty())
|
||||
{
|
||||
std::map<std::wstring, std::wstring>::iterator itFound = sSelectors.back().m_mAttributes.find(L"bgcolor");
|
||||
|
||||
if (sSelectors.back().m_mAttributes.end() != itFound)
|
||||
{
|
||||
NSCSS::NSProperties::CColor oColor;
|
||||
oColor.SetValue(itFound->second);
|
||||
|
||||
if (!oColor.Empty() && !oColor.None())
|
||||
{
|
||||
const std::wstring wsHEXColor{oColor.ToHEX()};
|
||||
|
||||
if (!wsHEXColor.empty())
|
||||
m_oDocXml.WriteString(L"<w:background w:color=\"" + wsHEXColor + L"\"/>");
|
||||
|
||||
sSelectors.back().m_mAttributes.erase(itFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_oLightReader.MoveToElement();
|
||||
|
||||
CTextSettings oTS;
|
||||
readStream(&m_oDocXml, sSelectors, oTS);
|
||||
}
|
||||
@ -2328,7 +2387,7 @@ private:
|
||||
|
||||
std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);
|
||||
|
||||
pXml->WriteString(oPPr.GetData());
|
||||
WriteToStringBuilder(oPPr, *pXml);
|
||||
|
||||
NSStringUtils::CStringBuilder oRPr;
|
||||
std::wstring sRStyle;
|
||||
@ -2337,7 +2396,7 @@ private:
|
||||
{
|
||||
sRStyle = wrRPr(&oRPr, arSelectors, oTS);
|
||||
|
||||
pXml->WriteString(oRPr.GetData());
|
||||
WriteToStringBuilder(oRPr, *pXml);
|
||||
|
||||
if (oTS.bQ)
|
||||
pXml->WriteString(L"<w:t xml:space=\"preserve\">"</w:t>");
|
||||
@ -2382,12 +2441,12 @@ private:
|
||||
{
|
||||
CloseP(pXml, arSelectors);
|
||||
OpenP(pXml);
|
||||
pXml->WriteString(oPPr.GetData());
|
||||
WriteToStringBuilder(oPPr, *pXml);
|
||||
sText.erase(0, nAfter + 1);
|
||||
nAfter = 0;
|
||||
}
|
||||
OpenR(pXml);
|
||||
pXml->WriteString(oRPr.GetData());
|
||||
WriteToStringBuilder(oRPr, *pXml);
|
||||
nAfter = sText.find_first_of(L"\n\r\t", nAfter);
|
||||
}
|
||||
|
||||
@ -2937,12 +2996,12 @@ private:
|
||||
}
|
||||
} while (m_oLightReader.ReadNextSiblingNode2(nDeath));
|
||||
|
||||
pXml->WriteString(oSummary.GetData());
|
||||
WriteToStringBuilder(oSummary, *pXml);
|
||||
|
||||
if (bOpened)
|
||||
{
|
||||
m_oState = oBodyState;
|
||||
pXml->WriteString(oBody.GetData());
|
||||
WriteToStringBuilder(oBody, *pXml);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -3248,7 +3307,7 @@ private:
|
||||
CloseP(&oXmlData, sSelectors);
|
||||
|
||||
if (bResult)
|
||||
oXml->WriteString(oXmlData.GetData());
|
||||
WriteToStringBuilder(oXmlData, *oXml);
|
||||
else
|
||||
m_oState = oCurentState;
|
||||
}
|
||||
@ -3614,25 +3673,31 @@ private:
|
||||
|
||||
OpenR(oXml);
|
||||
oXml->WriteString(L"<w:ruby><w:rubyPr><w:rubyAlign w:val=\"" + std::wstring((bConsistsChineseCharacters) ? L"distributeSpace" : L"center") + L"\"/><w:hps w:val=\"" + std::to_wstring(nFontSize) + L"\"/><w:hpsRaise w:val=\"" + std::to_wstring(nFontSize - 2) + L"\"/><w:hpsBaseText w:val=\"" + std::to_wstring(nFontSize) + L"\"/></w:rubyPr>");
|
||||
oXml->WriteString(L"<w:rt>" + oRT.GetData() + L"</w:rt>");
|
||||
oXml->WriteString(L"<w:rubyBase>" + oBase.GetData() + L"</w:rubyBase>");
|
||||
oXml->WriteString(L"<w:rt>");
|
||||
WriteToStringBuilder(oRT, *oXml);
|
||||
oXml->WriteString(L"</w:rt>");
|
||||
oXml->WriteString(L"<w:rubyBase>");
|
||||
WriteToStringBuilder(oBase, *oXml);
|
||||
oXml->WriteString(L"</w:rubyBase>");
|
||||
oXml->WriteString(L"</w:ruby>");
|
||||
CloseR(oXml);
|
||||
}
|
||||
else
|
||||
oXml->WriteString(oBase.GetData());
|
||||
WriteToStringBuilder(oBase, *oXml);
|
||||
|
||||
CloseP(oXml, sSelectors);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, CTextSettings& oTS)
|
||||
bool ParseTable(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS)
|
||||
{
|
||||
if(m_oLightReader.IsEmptyNode())
|
||||
return false;
|
||||
|
||||
CTable oTable;
|
||||
CTextSettings oTextSettings{oTS};
|
||||
oTextSettings.sPStyle.clear();
|
||||
|
||||
NSCSS::CCompiledStyle oStyle;
|
||||
m_oStylesCalculator.GetCompiledStyle(oStyle, sSelectors);
|
||||
@ -3640,9 +3705,9 @@ private:
|
||||
//Table styles
|
||||
std::wstring wsFrame;
|
||||
|
||||
for (const std::pair<std::wstring, std::wstring> oArgument : sSelectors.back().m_mAttributes)
|
||||
for (const std::pair<std::wstring, std::wstring>& oArgument : sSelectors.back().m_mAttributes)
|
||||
{
|
||||
if (L"border" == oArgument.first)
|
||||
if (oStyle.m_oBorder.Empty() && L"border" == oArgument.first)
|
||||
{
|
||||
const int nWidth = NSStringFinder::ToInt(oArgument.second);
|
||||
|
||||
@ -3650,7 +3715,7 @@ private:
|
||||
{
|
||||
oStyle.m_oBorder.SetStyle(L"outset", 0, true);
|
||||
oStyle.m_oBorder.SetWidth(nWidth, 0, true);
|
||||
oStyle.m_oBorder.SetColor(L"auto", 0, true);
|
||||
oStyle.m_oBorder.SetColor(L"auto", 0, true);
|
||||
oTable.SetRules(L"all");
|
||||
}
|
||||
else
|
||||
@ -3729,11 +3794,11 @@ private:
|
||||
if(sName == L"caption")
|
||||
ParseTableCaption(oTable, sSelectors, oTS);
|
||||
if(sName == L"thead")
|
||||
ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeHeader);
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeHeader);
|
||||
if(sName == L"tbody")
|
||||
ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeBody);
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeBody);
|
||||
else if(sName == L"tfoot")
|
||||
ParseTableRows(oTable, sSelectors, oTS, ERowParseMode::ParseModeFoother);
|
||||
ParseTableRows(oTable, sSelectors, oTextSettings, ERowParseMode::ParseModeFoother);
|
||||
else if (sName == L"colgroup")
|
||||
ParseTableColspan(oTable);
|
||||
|
||||
@ -3742,7 +3807,7 @@ private:
|
||||
|
||||
oTable.Shorten();
|
||||
oTable.CompleteTable();
|
||||
oXml->WriteString(oTable.ConvertToOOXML());
|
||||
oTable.ConvertToOOXML(*oXml);
|
||||
WriteEmptyParagraph(oXml, true);
|
||||
|
||||
return true;
|
||||
@ -4735,7 +4800,13 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const s
|
||||
m_internal->m_oLightReader.Clear();
|
||||
m_internal->m_sBase.clear();
|
||||
}
|
||||
m_internal->m_oStylesCalculator.Clear();
|
||||
|
||||
// Очищаем разрешенные файлы стилей
|
||||
// Это необходимо, чтобы мы не могли взять стили из не подключенного файла, но при этом, чтобы данные оставались,
|
||||
// т.к. ко многим файлам может быть подключен один и тот же файл (проблема возникает когда он большой)
|
||||
// и подключать (в нашем случае заново парсить) его будет долго
|
||||
m_internal->m_oStylesCalculator.ClearAllowedStyleFiles();
|
||||
m_internal->m_oStylesCalculator.ClearEmbeddedStyles();
|
||||
}
|
||||
|
||||
m_internal->write();
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#include "HWPFile.h"
|
||||
|
||||
#include "HwpDoc/HWPFile_Private.h"
|
||||
#include "HwpDoc/Common/WriterContext.h"
|
||||
#include "../DesktopEditor/common/File.h"
|
||||
|
||||
#include "HwpDoc/Conversion/Converter2OOXML.h"
|
||||
|
||||
CHWPFile::CHWPFile(const std::wstring& wsFileName)
|
||||
: m_pInternal(new HWP::CHWPFile_Private(wsFileName))
|
||||
CHWPFile::CHWPFile()
|
||||
: m_pInternal(new HWP::CWriterContext())
|
||||
{}
|
||||
|
||||
CHWPFile::~CHWPFile()
|
||||
@ -20,12 +20,20 @@ void CHWPFile::SetTempDirectory(const std::wstring& wsTempDirectory)
|
||||
m_wsTempDirectory = wsTempDirectory;
|
||||
}
|
||||
|
||||
bool CHWPFile::Open()
|
||||
bool CHWPFile::OpenHWP(const std::wstring& wsFilePath)
|
||||
{
|
||||
if (nullptr == m_pInternal)
|
||||
return false;
|
||||
|
||||
return m_pInternal->Open();
|
||||
return m_pInternal->Open(wsFilePath, HWP::EHanType::HWP);
|
||||
}
|
||||
|
||||
bool CHWPFile::OpenHWPX(const std::wstring& wsFilePath)
|
||||
{
|
||||
if (nullptr == m_pInternal)
|
||||
return false;
|
||||
|
||||
return m_pInternal->Open(wsFilePath, HWP::EHanType::HWPX);
|
||||
}
|
||||
|
||||
void CHWPFile::Close()
|
||||
@ -38,7 +46,7 @@ bool CHWPFile::ConvertToOOXML(const std::wstring& wsFilePath)
|
||||
{
|
||||
HWP::CConverter2OOXML oConverter;
|
||||
|
||||
oConverter.SetHWPFile(m_pInternal);
|
||||
oConverter.SetContext(m_pInternal);
|
||||
oConverter.SetTempDirectory(m_wsTempDirectory);
|
||||
|
||||
return oConverter.ConvertToFile(wsFilePath);
|
||||
@ -48,7 +56,17 @@ bool CHWPFile::ConvertToOOXML_Dir(const std::wstring& wsDirectoryPath)
|
||||
{
|
||||
HWP::CConverter2OOXML oConverter;
|
||||
|
||||
oConverter.SetHWPFile(m_pInternal);
|
||||
oConverter.SetContext(m_pInternal);
|
||||
|
||||
return oConverter.ConvertToDir(wsDirectoryPath);
|
||||
}
|
||||
|
||||
bool CHWPFile::IsHWPFormat(const std::wstring& wsFilePath)
|
||||
{
|
||||
return HWP::EHanType::HWP == HWP::CWriterContext::DetectHancom(wsFilePath);
|
||||
}
|
||||
|
||||
bool CHWPFile::IsHWPXFormat(const std::wstring& wsFilePath)
|
||||
{
|
||||
return HWP::EHanType::HWPX == HWP::CWriterContext::DetectHancom(wsFilePath);
|
||||
}
|
||||
|
||||
@ -10,21 +10,26 @@
|
||||
#define HWP_FILE_DECL_EXPORT Q_DECL_EXPORT
|
||||
#endif
|
||||
|
||||
namespace HWP { class CHWPFile_Private; }
|
||||
namespace HWP { class CWriterContext; }
|
||||
class HWP_FILE_DECL_EXPORT CHWPFile
|
||||
{
|
||||
HWP::CHWPFile_Private *m_pInternal;
|
||||
HWP::CWriterContext *m_pInternal;
|
||||
std::wstring m_wsFileName;
|
||||
std::wstring m_wsTempDirectory;
|
||||
public:
|
||||
CHWPFile(const std::wstring& wsFileName);
|
||||
CHWPFile();
|
||||
~CHWPFile();
|
||||
|
||||
void SetTempDirectory(const std::wstring& wsTempDirectory);
|
||||
|
||||
bool Open();
|
||||
bool OpenHWP(const std::wstring& wsFilePath);
|
||||
bool OpenHWPX(const std::wstring& wsFilePath);
|
||||
void Close();
|
||||
bool ConvertToOOXML(const std::wstring& wsFilePath);
|
||||
bool ConvertToOOXML_Dir(const std::wstring& wsDirectoryPath);
|
||||
|
||||
static bool IsHWPFormat(const std::wstring& wsFilePath);
|
||||
static bool IsHWPXFormat(const std::wstring& wsFilePath);
|
||||
};
|
||||
|
||||
#endif // HWPFILE_H
|
||||
|
||||
@ -12,12 +12,16 @@ PWD_ROOT_DIR = $$PWD
|
||||
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
|
||||
LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib
|
||||
|
||||
ADD_DEPENDENCY(kernel, UnicodeConverter, graphics)
|
||||
|
||||
DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY
|
||||
|
||||
SOURCES += \
|
||||
HWPFile.cpp \
|
||||
HwpDoc/Common/XMLReader.cpp \
|
||||
HwpDoc/Common/WriterContext.cpp \
|
||||
HwpDoc/Conversion/Converter2OOXML.cpp \
|
||||
HwpDoc/Conversion/FootnoteConverter.cpp \
|
||||
HwpDoc/Conversion/NumberingConverter.cpp \
|
||||
@ -41,9 +45,10 @@ SOURCES += \
|
||||
HwpDoc/HWPElements/HWPRecordParaText.cpp \
|
||||
HwpDoc/HWPElements/HWPRecordStyle.cpp \
|
||||
HwpDoc/HWPElements/HwpRecordTabDef.cpp \
|
||||
HwpDoc/HWPFile_Private.cpp \
|
||||
HwpDoc/HWPFile.cpp \
|
||||
HwpDoc/HWPSection.cpp \
|
||||
HwpDoc/HWPStream.cpp \
|
||||
HwpDoc/HWPXFile.cpp \
|
||||
HwpDoc/HwpFileHeader.cpp \
|
||||
HwpDoc/OLEdoc/CompoundFile.cpp \
|
||||
HwpDoc/OLEdoc/DirectoryEntry.cpp \
|
||||
@ -59,6 +64,7 @@ SOURCES += \
|
||||
HwpDoc/Paragraph/CtrlContainer.cpp \
|
||||
HwpDoc/Paragraph/CtrlEmpty.cpp \
|
||||
HwpDoc/Paragraph/CtrlEqEdit.cpp \
|
||||
HwpDoc/Paragraph/CtrlField.cpp \
|
||||
HwpDoc/Paragraph/CtrlForm.cpp \
|
||||
HwpDoc/Paragraph/CtrlGeneralShape.cpp \
|
||||
HwpDoc/Paragraph/CtrlHeadFoot.cpp \
|
||||
@ -89,7 +95,9 @@ SOURCES += \
|
||||
|
||||
HEADERS += \
|
||||
HWPFile.h \
|
||||
HwpDoc/Common.h \
|
||||
HwpDoc/Common/Common.h \
|
||||
HwpDoc/Common/XMLNode.h \
|
||||
HwpDoc/Common/WriterContext.h \
|
||||
HwpDoc/Conversion/Converter2OOXML.h \
|
||||
HwpDoc/Conversion/FootnoteConverter.h \
|
||||
HwpDoc/Conversion/NumberingConverter.h \
|
||||
@ -119,9 +127,10 @@ HEADERS += \
|
||||
HwpDoc/HWPElements/HWPType.h \
|
||||
HwpDoc/HWPElements/HwpRecordTabDef.h \
|
||||
HwpDoc/HWPElements/HwpRecordTypes.h \
|
||||
HwpDoc/HWPFile_Private.h \
|
||||
HwpDoc/HWPFile.h \
|
||||
HwpDoc/HWPSection.h \
|
||||
HwpDoc/HWPStream.h \
|
||||
HwpDoc/HWPXFile.h \
|
||||
HwpDoc/HanType.h \
|
||||
HwpDoc/HwpFileHeader.h \
|
||||
HwpDoc/OLEdoc/CompoundFile.h \
|
||||
@ -141,6 +150,7 @@ HEADERS += \
|
||||
HwpDoc/Paragraph/CtrlContainer.h \
|
||||
HwpDoc/Paragraph/CtrlEmpty.h \
|
||||
HwpDoc/Paragraph/CtrlEqEdit.h \
|
||||
HwpDoc/Paragraph/CtrlField.h \
|
||||
HwpDoc/Paragraph/CtrlForm.h \
|
||||
HwpDoc/Paragraph/CtrlGeneralShape.h \
|
||||
HwpDoc/Paragraph/CtrlHeadFoot.h \
|
||||
|
||||
@ -25,6 +25,26 @@ typedef char HWP_BYTE;
|
||||
#define CASE(value) case value : return value
|
||||
#define DEFAULT(value) case value: default: return value
|
||||
|
||||
#define MAKE_STR(value) #value
|
||||
#define MAKE_WSTR(value) L##value
|
||||
#define WSTR(value) MAKE_WSTR(#value)
|
||||
|
||||
#define IF_STRING_IN_ENUM(checked_value, value, enum_type)\
|
||||
if (WSTR(checked_value) == value)\
|
||||
return enum_type::checked_value
|
||||
#define ELSE_IF_STRING_IN_ENUM(checked_value, value, enum_type)\
|
||||
else if (WSTR(checked_value) == value)\
|
||||
return enum_type::checked_value
|
||||
#define ELSE_STRING_IN_ENUM(checked_value, enum_type)\
|
||||
else\
|
||||
return enum_type::checked_value
|
||||
|
||||
#define RETURN_VECTOR_CONST_PTR(type, array_values) \
|
||||
std::vector<const type*> arTempVector(array_values.size()); \
|
||||
for (unsigned int unIndex = 0; unIndex < array_values.size(); ++unIndex) \
|
||||
arTempVector[unIndex] = dynamic_cast<const type*>(array_values[unIndex]); \
|
||||
return arTempVector
|
||||
|
||||
class IRef
|
||||
{
|
||||
unsigned long m_ulRef;
|
||||
346
HwpFile/HwpDoc/Common/WriterContext.cpp
Normal file
346
HwpFile/HwpDoc/Common/WriterContext.cpp
Normal file
@ -0,0 +1,346 @@
|
||||
#include "WriterContext.h"
|
||||
#include "../HWPFile.h"
|
||||
#include "../HWPXFile.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
CWriterContext::CWriterContext()
|
||||
: m_eType(EHanType::NONE), m_pHWPFile(nullptr), m_pHWPXFile(nullptr)
|
||||
{}
|
||||
|
||||
CWriterContext::~CWriterContext()
|
||||
{
|
||||
if (nullptr != m_pHWPFile)
|
||||
delete m_pHWPFile;
|
||||
|
||||
if (nullptr != m_pHWPXFile)
|
||||
delete m_pHWPXFile;
|
||||
}
|
||||
|
||||
void CWriterContext::Clear()
|
||||
{
|
||||
m_eType = EHanType::NONE;
|
||||
|
||||
if (nullptr != m_pHWPFile)
|
||||
{
|
||||
delete m_pHWPFile;
|
||||
m_pHWPFile = nullptr;
|
||||
}
|
||||
|
||||
if (nullptr != m_pHWPXFile)
|
||||
{
|
||||
delete m_pHWPXFile;
|
||||
m_pHWPXFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
EHanType CWriterContext::GetType()
|
||||
{
|
||||
return m_eType;
|
||||
}
|
||||
|
||||
VECTOR<const CHWPSection*> CWriterContext::GetSections()
|
||||
{
|
||||
switch(m_eType)
|
||||
{
|
||||
case EHanType::NONE: break;
|
||||
case EHanType::HWP:
|
||||
{
|
||||
if (nullptr != m_pHWPFile)
|
||||
return m_pHWPFile->GetSections();
|
||||
|
||||
break;
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
if(nullptr != m_pHWPXFile)
|
||||
return m_pHWPXFile->GetSections();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return VECTOR<const CHWPSection*>();
|
||||
}
|
||||
|
||||
EHanType CWriterContext::DetectHancom(const HWP_STRING& sPathToFile)
|
||||
{
|
||||
bool bDetected = false;
|
||||
|
||||
CHWPFile* pHwpTemp = new CHWPFile(sPathToFile);
|
||||
if (nullptr != pHwpTemp)
|
||||
{
|
||||
if (pHwpTemp->Detect())
|
||||
{
|
||||
bDetected = true;
|
||||
pHwpTemp->Close();
|
||||
}
|
||||
|
||||
delete pHwpTemp;
|
||||
}
|
||||
|
||||
if (bDetected)
|
||||
return EHanType::HWP;
|
||||
|
||||
CHWPXFile* pHwpxTemp = new CHWPXFile(sPathToFile);
|
||||
if (nullptr != pHwpxTemp)
|
||||
{
|
||||
if (pHwpxTemp->Detect())
|
||||
{
|
||||
bDetected = true;
|
||||
pHwpxTemp->Close();
|
||||
}
|
||||
|
||||
delete pHwpxTemp;
|
||||
}
|
||||
|
||||
if (bDetected)
|
||||
return EHanType::HWPX;
|
||||
|
||||
return EHanType::NONE;
|
||||
}
|
||||
|
||||
bool CWriterContext::Detect()
|
||||
{
|
||||
switch(m_eType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
if (nullptr == m_pHWPFile)
|
||||
return false;
|
||||
|
||||
return m_pHWPFile->Detect();
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
if (nullptr == m_pHWPXFile)
|
||||
return false;
|
||||
|
||||
return m_pHWPXFile->Detect();
|
||||
}
|
||||
case EHanType::NONE:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWriterContext::Open(const HWP_STRING& sPathToFile, EHanType eHanType)
|
||||
{
|
||||
Clear();
|
||||
|
||||
m_eType = eHanType;
|
||||
|
||||
switch (m_eType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
m_pHWPFile = new CHWPFile(sPathToFile);
|
||||
|
||||
if (nullptr == m_pHWPFile)
|
||||
return false;
|
||||
|
||||
return m_pHWPFile->Open();
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
m_pHWPXFile = new CHWPXFile(sPathToFile);
|
||||
|
||||
if (nullptr == m_pHWPXFile)
|
||||
return false;
|
||||
|
||||
return m_pHWPXFile->Open();
|
||||
}
|
||||
case EHanType::NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CWriterContext::Close()
|
||||
{
|
||||
switch (m_eType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
if (nullptr != m_pHWPFile)
|
||||
m_pHWPFile->Close();
|
||||
break;
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
if (nullptr != m_pHWPXFile)
|
||||
m_pHWPXFile->Close();
|
||||
break;
|
||||
}
|
||||
case EHanType::NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const CHWPDocInfo* CWriterContext::GetDocInfo()
|
||||
{
|
||||
switch (m_eType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
if (nullptr == m_pHWPFile)
|
||||
return nullptr;
|
||||
|
||||
return m_pHWPFile->GetDocInfo();
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
if (nullptr == m_pHWPXFile)
|
||||
return nullptr;
|
||||
|
||||
return m_pHWPXFile->GetDocInfo();
|
||||
}
|
||||
case EHanType::NONE:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const CHWPRecordBorderFill* CWriterContext::GetBorderFill(short shId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordBorderFill*)pDocInfo->GetBorderFill(shId);
|
||||
}
|
||||
|
||||
const CHWPRecordParaShape* CWriterContext::GetParaShape(int nId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordParaShape*)pDocInfo->GetParaShape(nId);
|
||||
}
|
||||
|
||||
const CHWPRecordStyle* CWriterContext::GetParaStyle(short shId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordStyle*)pDocInfo->GetStyle(shId);
|
||||
}
|
||||
|
||||
const CHWPRecordCharShape* CWriterContext::GetCharShape(int nId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordCharShape*)pDocInfo->GetCharShape(nId);
|
||||
}
|
||||
|
||||
const CHWPRecordNumbering* CWriterContext::GetNumbering(short shId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordNumbering*)pDocInfo->GetNumbering(shId);
|
||||
}
|
||||
|
||||
const CHWPRecordBullet* CWriterContext::GetBullet(short shId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHWPRecordBullet*)pDocInfo->GetBullet(shId);
|
||||
}
|
||||
|
||||
const CHwpRecordTabDef* CWriterContext::GetTabDef(short shId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return nullptr;
|
||||
|
||||
return (CHwpRecordTabDef*)pDocInfo->GetTabDef(shId);
|
||||
}
|
||||
|
||||
HWP_STRING CWriterContext::GetBinFilename(const HWP_STRING& sId)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return HWP_STRING();
|
||||
|
||||
const CHWPRecordBinData* pBinData = dynamic_cast<const CHWPRecordBinData*>(pDocInfo->GetBinData(sId));
|
||||
|
||||
return (nullptr != pBinData) ? pBinData->GetPath() : HWP_STRING();
|
||||
}
|
||||
|
||||
bool CWriterContext::GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP_STRING& sFileName)
|
||||
{
|
||||
const CHWPDocInfo* pDocInfo = nullptr;
|
||||
|
||||
pDocInfo = GetDocInfo();
|
||||
|
||||
if (nullptr == pDocInfo)
|
||||
return false;
|
||||
|
||||
const CHWPRecordBinData* pBinData = dynamic_cast<const CHWPRecordBinData*>(pDocInfo->GetBinData(sId));
|
||||
|
||||
if (nullptr == pBinData)
|
||||
return false;
|
||||
|
||||
if (EType::LINK == pBinData->GetType())
|
||||
{
|
||||
switch (m_eType)
|
||||
{
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
sFileName = NSFile::GetFileName(pBinData->GetPath());
|
||||
return m_pHWPXFile->GetChildStream(pBinData->GetPath(), oBuffer);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wostringstream oStringStream;
|
||||
|
||||
switch (m_eType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
oStringStream << L"BIN" << std::setw(4) << std::setfill(L'0') << std::hex << pBinData->GetBinDataID() << L"." << pBinData->GetFormat();
|
||||
sFileName = oStringStream.str();
|
||||
return m_pHWPFile->GetChildStream(oStringStream.str(), pBinData->GetCompressed(), oBuffer);
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
oStringStream << sId << L"." << pBinData->GetFormat();
|
||||
sFileName = oStringStream.str();
|
||||
return m_pHWPXFile->GetChildStream(L"BinData/" + oStringStream.str(), oBuffer);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HWP_STRING CWriterContext::GetBinFormat(const HWP_STRING& sId)
|
||||
{
|
||||
//TODO::реализовать
|
||||
return HWP_STRING();
|
||||
}
|
||||
}
|
||||
50
HwpFile/HwpDoc/Common/WriterContext.h
Normal file
50
HwpFile/HwpDoc/Common/WriterContext.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef WRITERCONTEXT_H
|
||||
#define WRITERCONTEXT_H
|
||||
|
||||
#include "../HanType.h"
|
||||
#include "../HWPFile.h"
|
||||
#include "../HWPXFile.h"
|
||||
|
||||
#include "../HWPElements/HWPRecordParaShape.h"
|
||||
#include "../HWPElements/HWPRecordStyle.h"
|
||||
#include "../HWPElements/HWPRecordCharShape.h"
|
||||
#include "../HWPElements/HWPRecordNumbering.h"
|
||||
#include "../HWPElements/HWPRecordBullet.h"
|
||||
#include "../HWPElements/HwpRecordTabDef.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
class CWriterContext
|
||||
{
|
||||
EHanType m_eType;
|
||||
CHWPFile* m_pHWPFile;
|
||||
CHWPXFile* m_pHWPXFile;
|
||||
public:
|
||||
CWriterContext();
|
||||
~CWriterContext();
|
||||
|
||||
void Clear();
|
||||
EHanType GetType();
|
||||
|
||||
VECTOR<const CHWPSection*> GetSections();
|
||||
static EHanType DetectHancom(const HWP_STRING& sPathToFile);
|
||||
bool Detect();
|
||||
bool Open(const HWP_STRING& sPathToFile, EHanType eHanType);
|
||||
void Close();
|
||||
|
||||
const CHWPDocInfo* GetDocInfo();
|
||||
const CHWPRecordBorderFill* GetBorderFill(short shId);
|
||||
const CHWPRecordParaShape* GetParaShape(int nId);
|
||||
const CHWPRecordStyle* GetParaStyle(short shId);
|
||||
const CHWPRecordCharShape* GetCharShape(int nId);
|
||||
const CHWPRecordNumbering* GetNumbering(short shId);
|
||||
const CHWPRecordBullet* GetBullet(short shId);
|
||||
const CHwpRecordTabDef* GetTabDef(short shId);
|
||||
|
||||
HWP_STRING GetBinFilename(const HWP_STRING& sId);
|
||||
bool GetBinBytes(const HWP_STRING& sId, CHWPStream& oBuffer, HWP_STRING& sFileName);
|
||||
HWP_STRING GetBinFormat(const HWP_STRING& sId);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // WRITERCONTEXT_H
|
||||
24
HwpFile/HwpDoc/Common/XMLNode.h
Normal file
24
HwpFile/HwpDoc/Common/XMLNode.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef XMLNODEH_H
|
||||
#define XMLNODEH_H
|
||||
|
||||
#include "../../../DesktopEditor/xml/include/xmlutils.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
class CXMLNode : public XmlUtils::CXmlNode
|
||||
{
|
||||
public:
|
||||
CXMLNode();
|
||||
CXMLNode(const XmlUtils::CXmlNode& oNode);
|
||||
|
||||
bool GetAttributeBool(const std::wstring& wsName);
|
||||
int GetAttributeColor(const std::wstring& wsName, const int& _default = 0x00000000);
|
||||
CXMLNode GetChild(const std::wstring& wsName);
|
||||
std::vector<CXMLNode> GetChilds();
|
||||
std::vector<CXMLNode> GetChilds(const std::wstring& wsName);
|
||||
};
|
||||
|
||||
int ConvertWidthToHWP(const std::wstring& wsValue);
|
||||
}
|
||||
|
||||
#endif // XMLNODEH_H
|
||||
101
HwpFile/HwpDoc/Common/XMLReader.cpp
Normal file
101
HwpFile/HwpDoc/Common/XMLReader.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "XMLNode.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
CXMLNode::CXMLNode()
|
||||
: XmlUtils::CXmlNode()
|
||||
{}
|
||||
|
||||
CXMLNode::CXMLNode(const CXmlNode& oNode)
|
||||
: XmlUtils::CXmlNode(oNode)
|
||||
{}
|
||||
|
||||
bool CXMLNode::GetAttributeBool(const std::wstring& wsName)
|
||||
{
|
||||
return L"1" == XmlUtils::CXmlNode::GetAttribute(wsName, L"0");
|
||||
}
|
||||
|
||||
int CXMLNode::GetAttributeColor(const std::wstring& wsName, const int& _default)
|
||||
{
|
||||
std::wstring sColor = XmlUtils::CXmlNode::GetAttribute(wsName);
|
||||
|
||||
if (L"none" != sColor)
|
||||
{
|
||||
if (L'#' == sColor.front())
|
||||
sColor.erase(0, 1);
|
||||
|
||||
if (sColor.length() < 6)
|
||||
return _default;
|
||||
|
||||
return std::stoi(sColor.substr(0, 6), nullptr, 16);
|
||||
}
|
||||
|
||||
return _default;
|
||||
}
|
||||
|
||||
CXMLNode CXMLNode::GetChild(const std::wstring& wsName)
|
||||
{
|
||||
return CXMLNode(XmlUtils::CXmlNode::GetNode(wsName));
|
||||
}
|
||||
|
||||
std::vector<CXMLNode> CXMLNode::GetChilds()
|
||||
{
|
||||
std::vector<XmlUtils::CXmlNode> arChilds;
|
||||
XmlUtils::CXmlNode::GetChilds(arChilds);
|
||||
|
||||
std::vector<CXMLNode> arNewChilds(arChilds.size());
|
||||
for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex)
|
||||
arNewChilds[unIndex] = CXMLNode(arChilds[unIndex]);
|
||||
|
||||
return arNewChilds;
|
||||
}
|
||||
|
||||
std::vector<CXMLNode> CXMLNode::GetChilds(const std::wstring& wsName)
|
||||
{
|
||||
std::vector<XmlUtils::CXmlNode> arChilds{XmlUtils::CXmlNode::GetNodes(wsName)};
|
||||
|
||||
std::vector<CXMLNode> arNewChilds(arChilds.size());
|
||||
for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex)
|
||||
arNewChilds[unIndex] = CXMLNode(arChilds[unIndex]);
|
||||
|
||||
return arNewChilds;
|
||||
}
|
||||
|
||||
int ConvertWidthToHWP(const std::wstring& wsValue)
|
||||
{
|
||||
if (wsValue.empty() || L"0.1" == wsValue || L"0.1 mm" == wsValue)
|
||||
return 0;
|
||||
else if (L"0.12" == wsValue || L"0.12 mm" == wsValue)
|
||||
return 1;
|
||||
else if (L"0.15" == wsValue || L"0.15 mm" == wsValue)
|
||||
return 2;
|
||||
else if (L"0.2" == wsValue || L"0.2 mm" == wsValue)
|
||||
return 3;
|
||||
else if (L"0.25" == wsValue || L"0.25 mm" == wsValue)
|
||||
return 4;
|
||||
else if (L"0.3" == wsValue || L"0.3 mm" == wsValue)
|
||||
return 5;
|
||||
else if (L"0.4" == wsValue || L"0.4 mm" == wsValue)
|
||||
return 6;
|
||||
else if (L"0.5" == wsValue || L"0.5 mm" == wsValue)
|
||||
return 7;
|
||||
else if (L"0.6" == wsValue || L"0.6 mm" == wsValue)
|
||||
return 8;
|
||||
else if (L"0.7" == wsValue || L"0.7 mm" == wsValue)
|
||||
return 9;
|
||||
else if (L"1.0" == wsValue || L"1.0 mm" == wsValue)
|
||||
return 10;
|
||||
else if (L"1.5" == wsValue || L"1.5 mm" == wsValue)
|
||||
return 11;
|
||||
else if (L"2.0" == wsValue || L"2.0 mm" == wsValue)
|
||||
return 12;
|
||||
else if (L"3.0" == wsValue || L"3.0 mm" == wsValue)
|
||||
return 13;
|
||||
else if (L"4.0" == wsValue || L"4.0 mm" == wsValue)
|
||||
return 14;
|
||||
else if (L"5.0" == wsValue || L"5.0 mm" == wsValue)
|
||||
return 15;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,9 @@
|
||||
#ifndef CONVERTER2OOXML_H
|
||||
#define CONVERTER2OOXML_H
|
||||
|
||||
#include "../HWPFile_Private.h"
|
||||
#include "../../../DesktopEditor/common/StringBuilder.h"
|
||||
|
||||
#include "../Paragraph/CtrlField.h"
|
||||
#include "../Paragraph/CtrlAutoNumber.h"
|
||||
#include "../Paragraph/CtrlSectionDef.h"
|
||||
#include "../Paragraph/CtrlShapeVideo.h"
|
||||
@ -13,26 +13,57 @@
|
||||
#include "../Paragraph/CtrlShapeOle.h"
|
||||
#include "../Paragraph/CtrlEqEdit.h"
|
||||
#include "../Paragraph/CtrlTable.h"
|
||||
#include "../Paragraph/CtrlNote.h"
|
||||
#include "../Paragraph/ParaText.h"
|
||||
|
||||
#include "../Paragraph/TblCell.h"
|
||||
|
||||
#include "FootnoteConverter.h"
|
||||
#include "OleConverter.h"
|
||||
#include "NumberingConverter.h"
|
||||
|
||||
#include "../Common/WriterContext.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
struct THWPColor
|
||||
{
|
||||
BYTE m_uchRed;
|
||||
BYTE m_uchGreen;
|
||||
BYTE m_uchBlue;
|
||||
};
|
||||
|
||||
struct TConversionState
|
||||
{
|
||||
bool m_bOpenedP;
|
||||
bool m_bOpenedR;
|
||||
bool m_bIsNote;
|
||||
|
||||
bool m_bNeedLineBreak;
|
||||
bool m_bInTextBox; // TODO:: используется, чтобы в wps:txbx не появилась новая фигура (посмотреть этот момент нужно подробнее)
|
||||
|
||||
unsigned short m_ushLastCharShapeId;
|
||||
|
||||
unsigned short m_ushSecdIndex;
|
||||
unsigned int m_unParaIndex;
|
||||
|
||||
THWPColor *m_pHighlightColor;
|
||||
|
||||
VECTOR<const CCtrlHeadFoot*> m_arCtrlsHeadFoot; //only for hwpx
|
||||
std::stack<int> m_arOpenedBookmarks;
|
||||
|
||||
const CCtrlSectionDef* m_pSectionDef;
|
||||
const CCtrlColumnDef* m_pColumnDef;
|
||||
|
||||
enum class EBreakType
|
||||
{
|
||||
Page,
|
||||
Column,
|
||||
TextWrapping,
|
||||
None
|
||||
} m_eBreakType;
|
||||
|
||||
std::map<unsigned int, const CCtrlField*> m_mOpenField;
|
||||
|
||||
TConversionState();
|
||||
};
|
||||
|
||||
@ -43,6 +74,12 @@ struct TRelationship
|
||||
HWP_STRING m_wsTarget;
|
||||
};
|
||||
|
||||
struct TContentType
|
||||
{
|
||||
HWP_STRING m_wsName;
|
||||
HWP_STRING m_wsType;
|
||||
};
|
||||
|
||||
enum class ECellCreator
|
||||
{
|
||||
FILE,
|
||||
@ -52,15 +89,16 @@ enum class ECellCreator
|
||||
|
||||
class CConverter2OOXML
|
||||
{
|
||||
CHWPFile_Private *m_pHWPFile;
|
||||
CWriterContext * m_pContext;
|
||||
HWP_STRING m_sTempDirectory;
|
||||
|
||||
NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml
|
||||
NSStringUtils::CStringBuilder m_oDocXml; // document.xml
|
||||
NSStringUtils::CStringBuilder m_oNoteXmlRels; // footnotes.xml.rels
|
||||
NSStringUtils::CStringBuilder m_oWebSettings; // webSettings.xml
|
||||
NSStringUtils::CStringBuilder m_oContentTypes;// [Content_Types].xml
|
||||
|
||||
VECTOR<TContentType> m_arDefaultContentType;
|
||||
VECTOR<TContentType> m_arContentTypes;
|
||||
VECTOR<TRelationship> m_arRelationships;
|
||||
|
||||
CNumberingConverter m_oNumberingConverter;
|
||||
@ -72,6 +110,8 @@ class CConverter2OOXML
|
||||
unsigned short m_ushTableCount;
|
||||
unsigned short m_ushEquationCount;
|
||||
|
||||
unsigned short m_ushBookmarkCount;
|
||||
|
||||
void CreateEmptyFiles();
|
||||
void FillDefaultData();
|
||||
void Close();
|
||||
@ -84,48 +124,60 @@ class CConverter2OOXML
|
||||
void WriteTableProperties(const CCtrlTable* pTable, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteCell(const CTblCell* pCell, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, ECellCreator eCellCreator);
|
||||
void WriteCellProperties(short shBorderFillID, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteCellBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteBorder(const TBorder& oBorder, const HWP_STRING& sBorderName, NSStringUtils::CStringBuilder& oBuilder);
|
||||
|
||||
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteOleShape(const CCtrlShapeOle* pOleShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteGeometryShape(const CCtrlGeneralShape* pGeneralShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteEqEditShape(const CCtrlEqEdit* pEqEditShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteOleShape(const CCtrlShapeOle* pOleShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void WriteSectionSettings(TConversionState& oState);
|
||||
void WritePicture(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder, const TConversionState& oState);
|
||||
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, NSStringUtils::CStringBuilder& oBuilder, const TConversionState& oState);
|
||||
bool SaveSVGFile(const HWP_STRING& sSVG, const HWP_STRING& sIndex);
|
||||
void WritePicture(const CCtrlShapePic* pCtrlPic, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteVideo(const CCtrlShapeVideo* pCtrlVideo, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
bool SaveSVGFile(const HWP_STRING& sSVG, HWP_STRING& sFileName);
|
||||
HWP_STRING SavePicture(const HWP_STRING& sBinItemId);
|
||||
|
||||
void WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, const TConversionState& oState);
|
||||
void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, const TConversionState& oState);
|
||||
void WriteParaShapeProperties(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteRunnerStyle(short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState, const HWP_STRING& sExternStyles = L"");
|
||||
void WriteTextBorderStyle(short shBorderFillId, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void OpenAnchorNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void CloseAnchorNode(NSStringUtils::CStringBuilder& oBuilder);
|
||||
void OpenDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void CloseDrawingNode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
|
||||
void WriteShapePosition(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteShapeExtent(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteShapeWrapMode(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteShapeProperty(const CCtrlCommon* pCtrlShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
|
||||
void OpenParagraph(short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void CloseParagraph(NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void WriteText(const std::wstring& wsText, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteText(const CParaText* pParaText, const VECTOR<TRangeTag>& arRangeTags, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteText(const HWP_STRING& wsText, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteLineSettings(const CCtrlGeneralShape* pCtrlGeneralShape, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteLineSettings(ELineStyle2 eLineStyle, int nColor, int nThick, HWP_BYTE nCompoundLineType, NSStringUtils::CStringBuilder& oBuilder);
|
||||
void WriteBorderSettings(const CCtrlShapePic* pCtrlPic, NSStringUtils::CStringBuilder& oBuilder);
|
||||
|
||||
void WriteAutoNumber(const CCtrlAutoNumber* pAutoNumber, short shParaShapeID, short shCharShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteCharacter(const CCtrlCharacter* pCharacter, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteShape(const CCtrlGeneralShape* pShape, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteCharacter(const CCtrlCharacter* pCharacter, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void WriteShape(const CCtrlGeneralShape* pShape, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
bool GetBinBytes(const HWP_STRING& sID, CHWPStream& oBuffer, HWP_STRING& sFormat);
|
||||
void WriteNote(const CCtrlNote* pNote, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void WriteField(const CCtrlField* pHyperlink, short shParaShapeID, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
void CloseField(const CCtrlField* pHyperlink, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void WriteCaption(const CCtrlCommon* pCtrlCommon, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
HWP_STRING AddRelationship(const HWP_STRING& wsType, const HWP_STRING& wsTarget);
|
||||
void AddContentType(const HWP_STRING& wsName, const HWP_STRING& wsType);
|
||||
void AddDefaultContentType(const HWP_STRING& wsName);
|
||||
public:
|
||||
CConverter2OOXML();
|
||||
~CConverter2OOXML();
|
||||
|
||||
void WriteParagraph(const CHWPPargraph* pParagraph, NSStringUtils::CStringBuilder& oBuilder, TConversionState& oState);
|
||||
|
||||
void SetHWPFile(CHWPFile_Private* pHWPFile);
|
||||
void SetContext(CWriterContext* pContext);
|
||||
void SetTempDirectory(const HWP_STRING& sTempDirectory);
|
||||
bool ConvertToFile(const HWP_STRING& sFilePath);
|
||||
bool ConvertToDir(const HWP_STRING& sDirectoryPath);
|
||||
|
||||
@ -21,23 +21,28 @@ std::wstring CFootnoteConverter::CreateNote(const CCtrlNote* pNote, CConverter2O
|
||||
|
||||
NSStringUtils::CStringBuilder *pXMLBuilder = &m_oFootnoteXml;
|
||||
std::wstring wsPrefix = L"foot";
|
||||
std::wstring wsIndex;
|
||||
|
||||
if (L" ne" == pNote->GetID())
|
||||
{
|
||||
wsPrefix = L"end";
|
||||
pXMLBuilder = &m_oEndnoteXml;
|
||||
wsIndex = std::to_wstring(++m_ushCountEndnotes);
|
||||
}
|
||||
else
|
||||
wsIndex = std::to_wstring(++m_ushCountFootnotes);
|
||||
|
||||
pXMLBuilder->WriteString(L"<w:" + wsPrefix + L"note w:id=\"" + std::to_wstring(++m_ushCountFootnotes) + L"\">");
|
||||
pXMLBuilder->WriteString(L"<w:" + wsPrefix + L"note w:id=\"" + wsIndex + L"\">");
|
||||
|
||||
TConversionState oState;
|
||||
oState.m_bIsNote = true;
|
||||
|
||||
for (const CHWPPargraph* pParagraph : pNote->GetParagraphs())
|
||||
oConverter.WriteParagraph(pParagraph, *pXMLBuilder, oState);
|
||||
|
||||
pXMLBuilder->WriteString(L"</w:" + wsPrefix + L"note>");
|
||||
|
||||
return L"<w:" + wsPrefix + L"noteReference w:id=\"" + std::to_wstring(m_ushCountFootnotes) + L"\"/>";
|
||||
return L"<w:" + wsPrefix + L"noteReference w:id=\"" + wsIndex + L"\"/>";
|
||||
}
|
||||
|
||||
std::wstring CFootnoteConverter::CreateHeadOrFoot(const CCtrlHeadFoot* pCtrlHeadFoot, CConverter2OOXML& oConverter)
|
||||
|
||||
@ -27,12 +27,14 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
|
||||
if (nullptr == pNumbering || eHeadingType == EHeadingType::NONE || EHeadingType::OUTLINE == eHeadingType)
|
||||
return 0;
|
||||
|
||||
std::vector<const CHWPRecordNumbering*>::const_iterator itFound = std::find(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(), pNumbering);
|
||||
std::vector<std::pair<EHeadingType, const CHWPRecordNumbering*>>::const_iterator itFound = std::find_if(m_arUsedNumbering.cbegin(), m_arUsedNumbering.cend(),
|
||||
[pNumbering, eHeadingType](const std::pair<EHeadingType, const CHWPRecordNumbering*>& oValue)
|
||||
{ return eHeadingType == oValue.first && pNumbering == oValue.second;});
|
||||
|
||||
if (m_arUsedNumbering.cend() != itFound)
|
||||
return itFound - m_arUsedNumbering.cbegin() + 1;
|
||||
|
||||
m_arUsedNumbering.push_back(pNumbering);
|
||||
m_arUsedNumbering.push_back(std::make_pair(eHeadingType, pNumbering));
|
||||
|
||||
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"" + std::to_wstring(m_arUsedNumbering.size()) + L"\">");
|
||||
|
||||
@ -51,7 +53,15 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
|
||||
m_oNumberXml.WriteString(L"<w:suff w:val=\"space\"/>");
|
||||
|
||||
wsLvlText = pNumbering->GetNumFormat(shIndex);
|
||||
std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%');
|
||||
|
||||
if (wsLvlText.empty())
|
||||
{
|
||||
for (short shLvl = 0; shLvl <= shIndex; ++shLvl)
|
||||
wsLvlText += L'%' + std::to_wstring(shLvl + 1) + L'.';
|
||||
}
|
||||
else
|
||||
std::replace(wsLvlText.begin(), wsLvlText.end(), L'^', L'%');
|
||||
|
||||
m_oNumberXml.WriteString(L"<w:lvlText w:val=\"" + wsLvlText + L"\"/>");
|
||||
|
||||
m_oNumberXml.WriteString(L"<w:lvlJc w:val=\"");
|
||||
@ -73,9 +83,8 @@ int CNumberingConverter::CreateNumbering(const CHWPRecordNumbering* pNumbering,
|
||||
{
|
||||
m_oNumberXml.WriteString(L"<w:lvl w:ilvl=\"" + std::to_wstring(shIndex) + L"\">");
|
||||
|
||||
m_oNumberXml.WriteString(L"<w:start w:val=\"1\"/>");
|
||||
m_oNumberXml.WriteString(L"<w:numFmt w:val=\"" + wsNumFormat + L"\"/>");
|
||||
m_oNumberXml.WriteString(L"<w:suff w:val=\"space\"/>");
|
||||
m_oNumberXml.WriteString(L"<w:isLgl w:val=\"false\"/>");
|
||||
|
||||
m_oNumberXml.WriteString(L"<w:lvlJc w:val=\"");
|
||||
switch(pNumbering->GetAlign(shIndex))
|
||||
@ -174,7 +183,7 @@ bool CNumberingConverter::SaveToFile(const std::wstring& wsDirectory)
|
||||
else
|
||||
{
|
||||
for (unsigned short ushIndex = 1; ushIndex <= m_arUsedNumbering.size(); ++ushIndex)
|
||||
m_oNumberXml.WriteString(L"<w:num w:numId=\"" + std::to_wstring(ushIndex) + L"\"><w:abstractNumId w:val=\"" + std::to_wstring(ushIndex) + L"\"/></w:num>");
|
||||
oNumberingData.WriteString(L"<w:num w:numId=\"" + std::to_wstring(ushIndex) + L"\"><w:abstractNumId w:val=\"" + std::to_wstring(ushIndex) + L"\"/></w:num>");
|
||||
}
|
||||
|
||||
oNumberingData.WriteString(L"</w:numbering>");
|
||||
|
||||
@ -11,7 +11,7 @@ namespace HWP
|
||||
class CNumberingConverter
|
||||
{
|
||||
NSStringUtils::CStringBuilder m_oNumberXml;
|
||||
std::vector<const CHWPRecordNumbering*> m_arUsedNumbering;
|
||||
std::vector<std::pair<EHeadingType, const CHWPRecordNumbering*>> m_arUsedNumbering;
|
||||
public:
|
||||
CNumberingConverter();
|
||||
|
||||
|
||||
@ -123,8 +123,8 @@ void COleConverter::CreateChart(CHWPStream& oOleStream)
|
||||
NSStringUtils::CStringBuilder oRelsData;
|
||||
oRelsData.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
oRelsData.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
|
||||
oRelsData.WriteString(L"<Relationship Id=\"rId1\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartStyle\" Target=\"style1.xml\"/>");
|
||||
oRelsData.WriteString(L"<Relationship Id=\"rId2\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartColorStyle\" Target=\"colors1.xml\"/>");
|
||||
oRelsData.WriteString(L"<Relationship Id=\"rId1\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartStyle\" Target=\"style" + std::to_wstring(m_unCountCharts) + L".xml\"/>");
|
||||
oRelsData.WriteString(L"<Relationship Id=\"rId2\" Type=\"http://schemas.microsoft.com/office/2011/relationships/chartColorStyle\" Target=\"colors" + std::to_wstring(m_unCountCharts) + L".xml\"/>");
|
||||
oRelsData.WriteString(L"</Relationships>");
|
||||
|
||||
NSFile::CFileBinary oRelsFile;
|
||||
|
||||
@ -30,11 +30,11 @@ CHWPDocInfo::CHWPDocInfo(EHanType eHanType)
|
||||
: m_eHanType(eHanType), m_eCompatibleDoc(ECompatDoc::HWP)
|
||||
{}
|
||||
|
||||
// CHWPDocInfo::CHWPDocInfo(CHWPXFile* pHWPXFile)
|
||||
// : m_eHanType(EHanType::HWPX), m_pParentHWPX(pHWPXFile)
|
||||
// {}
|
||||
CHWPDocInfo::CHWPDocInfo(CHWPXFile* pHWPXFile)
|
||||
: m_eHanType(EHanType::HWPX), m_pParentHWPX(pHWPXFile), m_eCompatibleDoc(ECompatDoc::UNKNOWN)
|
||||
{}
|
||||
|
||||
CHWPDocInfo::CHWPDocInfo(CHWPFile_Private* pHWPFile)
|
||||
CHWPDocInfo::CHWPDocInfo(CHWPFile* pHWPFile)
|
||||
: m_eHanType(EHanType::HWP), m_pParentHWP(pHWPFile), m_eCompatibleDoc(ECompatDoc::HWP)
|
||||
{}
|
||||
|
||||
@ -58,7 +58,7 @@ CHWPDocInfo::~CHWPDocInfo()
|
||||
REMOVE_LIST_DATA(m_arStyles);
|
||||
REMOVE_LIST_DATA(m_arTabDefs);
|
||||
|
||||
for (std::pair<HWP_STRING, CHWPRecord*> oBinData : m_mBinDatas)
|
||||
for (const std::pair<HWP_STRING, CHWPRecord*>& oBinData : m_mBinDatas)
|
||||
{
|
||||
if (nullptr != oBinData.second)
|
||||
delete oBinData.second;
|
||||
@ -182,8 +182,87 @@ bool CHWPDocInfo::Parse(CHWPStream& oBuffer, int nVersion)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHWPDocInfo::Parse(CXMLNode& oNode, int nVersion)
|
||||
{
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hh:beginNum" == oChild.GetName())
|
||||
m_arRecords.push_back(new CHWPRecordDocumentProperties(*this, oChild, nVersion));
|
||||
else if (L"hh:refList" == oChild.GetName())
|
||||
ReadRefList(oChild, nVersion);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHWPDocInfo::ReadRefList(CXMLNode& oNode, int nVersion)
|
||||
{
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hh:fontfaces" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oFontFaceNode : oChild.GetChilds(L"hh:fontface"))
|
||||
for (CXMLNode& oFontNode : oFontFaceNode.GetChilds(L"hh:font"))
|
||||
m_arFaseNames.push_back(new CHWPRecordFaceName(*this, oFontNode, nVersion));
|
||||
}
|
||||
else if (L"hh:borderFills" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oBorderFillNode : oChild.GetChilds(L"hh:borderFill"))
|
||||
m_arBorderFills.push_back(new CHWPRecordBorderFill(*this, oBorderFillNode, nVersion));
|
||||
}
|
||||
else if (L"hh:charProperties" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oCharPrNode : oChild.GetChilds(L"hh:charPr"))
|
||||
m_arCharShapes.push_back(new CHWPRecordCharShape(*this, oCharPrNode, nVersion));
|
||||
}
|
||||
else if (L"hh:tabProperties" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oTabPrNode : oChild.GetChilds(L"hh:tabPr"))
|
||||
m_arTabDefs.push_back(new CHwpRecordTabDef(*this, oTabPrNode, nVersion));
|
||||
}
|
||||
else if (L"hh:numberings" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oNumberingNode : oChild.GetChilds(L"hh:numbering"))
|
||||
m_arNumberings.push_back(new CHWPRecordNumbering(*this, oNumberingNode, nVersion));
|
||||
}
|
||||
else if (L"hh:bullets" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oBulletNode : oChild.GetChilds())
|
||||
m_arBullets.push_back(new CHWPRecordBullet(*this, oBulletNode, nVersion));
|
||||
}
|
||||
else if (L"hh:paraProperties" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oParaPrNode : oChild.GetChilds(L"hh:paraPr"))
|
||||
m_arParaShapes.push_back(new CHWPRecordParaShape(*this, oParaPrNode, nVersion));
|
||||
}
|
||||
else if (L"hh:styles" == oChild.GetName())
|
||||
{
|
||||
for (CXMLNode& oStyleNode : oChild.GetChilds(L"hh:style"))
|
||||
m_arStyles.push_back(new CHWPRecordStyle(*this, oStyleNode, nVersion));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHWPDocInfo::ReadContentHpf(CXMLNode& oNode, int nVersion)
|
||||
{
|
||||
CHWPRecordBinData *pRecordBinData = nullptr;
|
||||
|
||||
for (CXMLNode& oChild : oNode.GetChilds(L"opf:manifest"))
|
||||
{
|
||||
for (CXMLNode& oGrandChild : oChild.GetChilds(L"opf:item"))
|
||||
{
|
||||
pRecordBinData = new CHWPRecordBinData(oGrandChild, nVersion);
|
||||
m_mBinDatas.insert(std::make_pair<HWP_STRING, CHWPRecord*>(pRecordBinData->GetItemID(), (HWP::CHWPRecord*)pRecordBinData));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define GET_RECORD(array_records, index) \
|
||||
if (array_records.size() <= index) \
|
||||
if (array_records.size() <= index || index < 0) \
|
||||
return nullptr; \
|
||||
return array_records[index]
|
||||
|
||||
@ -209,7 +288,7 @@ const CHWPRecord* CHWPDocInfo::GetCharShape(int nIndex) const
|
||||
|
||||
const CHWPRecord* CHWPDocInfo::GetNumbering(int nIndex) const
|
||||
{
|
||||
GET_RECORD(m_arNumberings, nIndex - 1);
|
||||
GET_RECORD(m_arNumberings, nIndex);
|
||||
}
|
||||
|
||||
const CHWPRecord* CHWPDocInfo::GetBullet(int nIndex) const
|
||||
@ -232,17 +311,40 @@ const CHWPRecord* CHWPDocInfo::GetTabDef(int nIndex) const
|
||||
GET_RECORD(m_arTabDefs, nIndex);
|
||||
}
|
||||
|
||||
CHWPFile_Private* CHWPDocInfo::GetParentHWP()
|
||||
CHWPFile* CHWPDocInfo::GetParentHWP()
|
||||
{
|
||||
return m_pParentHWP;
|
||||
}
|
||||
|
||||
const CHWPRecord* CHWPDocInfo::GetBinData(const HWP_STRING& sID) const
|
||||
{
|
||||
if (m_mBinDatas.end() == m_mBinDatas.find(sID))
|
||||
return nullptr;
|
||||
switch (m_eHanType)
|
||||
{
|
||||
case EHanType::HWP:
|
||||
{
|
||||
short shID = std::stoi(sID) - 1;
|
||||
|
||||
return m_mBinDatas.at(sID);
|
||||
if (shID >= m_mBinDatas.size())
|
||||
return nullptr;
|
||||
|
||||
std::map<HWP_STRING, CHWPRecord*>::const_iterator itElement = m_mBinDatas.cbegin();
|
||||
|
||||
for (unsigned short ushIndex = 0; ushIndex < shID; ++ushIndex)
|
||||
++itElement;
|
||||
|
||||
return itElement->second;
|
||||
}
|
||||
case EHanType::HWPX:
|
||||
{
|
||||
if (m_mBinDatas.end() == m_mBinDatas.find(sID))
|
||||
return nullptr;
|
||||
|
||||
return m_mBinDatas.at(sID);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
EHanType CHWPDocInfo::GetHanType() const
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "HanType.h"
|
||||
#include "HWPStream.h"
|
||||
#include "HWPElements/HWPRecord.h"
|
||||
#include "Common/XMLNode.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -17,12 +18,13 @@ enum class ECompatDoc
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
class CHWPFile_Private;
|
||||
class CHWPFile;
|
||||
class CHWPXFile;
|
||||
class CHWPDocInfo
|
||||
{
|
||||
EHanType m_eHanType;
|
||||
// CHWPXFile *m_pParentHWPX;
|
||||
CHWPFile_Private *m_pParentHWP;
|
||||
CHWPXFile *m_pParentHWPX;
|
||||
CHWPFile *m_pParentHWP;
|
||||
VECTOR<CHWPRecord*> m_arRecords;
|
||||
|
||||
std::map<HWP_STRING, CHWPRecord*> m_mBinDatas;
|
||||
@ -38,12 +40,14 @@ class CHWPDocInfo
|
||||
ECompatDoc m_eCompatibleDoc;
|
||||
public:
|
||||
CHWPDocInfo(EHanType eHanType);
|
||||
// CHWPDocInfo(CHWPXFile* pHWPXFile);
|
||||
CHWPDocInfo(CHWPFile_Private* pHWPFile);
|
||||
CHWPDocInfo(CHWPXFile* pHWPXFile);
|
||||
CHWPDocInfo(CHWPFile* pHWPFile);
|
||||
|
||||
~CHWPDocInfo();
|
||||
|
||||
bool Parse(CHWPStream& oBuffer, int nVersion);
|
||||
bool Parse(CXMLNode& oNode, int nVersion);
|
||||
bool ReadContentHpf(CXMLNode& oNode, int nVersion);
|
||||
|
||||
const CHWPRecord* GetRecord(int nIndex) const;
|
||||
const CHWPRecord* GetFaceName(int nIndex) const;
|
||||
@ -55,11 +59,13 @@ public:
|
||||
const CHWPRecord* GetStyle(int nIndex) const;
|
||||
const CHWPRecord* GetTabDef(int nIndex) const;
|
||||
|
||||
CHWPFile_Private* GetParentHWP();
|
||||
CHWPFile* GetParentHWP();
|
||||
|
||||
const CHWPRecord* GetBinData(const HWP_STRING& sID) const;
|
||||
EHanType GetHanType() const;
|
||||
ECompatDoc GetCompatibleDoc() const;
|
||||
private:
|
||||
bool ReadRefList(CXMLNode& oNode, int nVersion);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
#include "HWPRecordBinData.h"
|
||||
|
||||
#include "../HWPFile_Private.h"
|
||||
#include "../HWPFile.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
namespace HWP
|
||||
@ -11,10 +12,9 @@ ECompressed GetCompressed(int nValue)
|
||||
{
|
||||
SWITCH(ECompressed, nValue)
|
||||
{
|
||||
CASE(ECompressed::FOLLOW_STORAGE);
|
||||
DEFAULT(ECompressed::FOLLOW_STORAGE);
|
||||
CASE(ECompressed::COMPRESS);
|
||||
CASE(ECompressed::NO_COMPRESS);
|
||||
DEFAULT(ECompressed::UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,34 +22,27 @@ EType GetType(int nValue)
|
||||
{
|
||||
SWITCH(EType, nValue)
|
||||
{
|
||||
CASE(EType::LINK);
|
||||
DEFAULT(EType::LINK);
|
||||
CASE(EType::EMBEDDING);
|
||||
CASE(EType::STORAGE);
|
||||
DEFAULT(EType::UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EState GetState(int nValue)
|
||||
{
|
||||
SWITCH(EState, nValue)
|
||||
{
|
||||
CASE(EState::NEVER_ACCESSED);
|
||||
DEFAULT(EState::NEVER_ACCESSED);
|
||||
CASE(EState::FOUND_FILE_BY_ACCESS);
|
||||
CASE(EState::ACCESS_FAILED);
|
||||
CASE(EState::LINK_ACCESS_IGNORED);
|
||||
DEFAULT(EState::UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
CHWPRecordBinData::CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize)
|
||||
{
|
||||
if (EHanType::HWP == oDocInfo.GetHanType())
|
||||
{
|
||||
if (oDocInfo.GetParentHWP()->GetBinData().empty())
|
||||
oDocInfo.GetParentHWP()->SetBinData(oDocInfo.GetParentHWP()->GetOleFile()->GetChildEntries(L"BinData"));
|
||||
}
|
||||
|
||||
oBuffer.SavePosition();
|
||||
|
||||
short shTypeBits;
|
||||
@ -81,6 +74,37 @@ CHWPRecordBinData::CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLe
|
||||
oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true));
|
||||
}
|
||||
|
||||
CHWPRecordBinData::CHWPRecordBinData(CXMLNode& oNode, int nVersion)
|
||||
: CHWPRecord(EHWPTag::HWPTAG_BIN_DATA, 0, 0)
|
||||
{
|
||||
m_sItemID = oNode.GetAttribute(L"id");
|
||||
|
||||
HWP_STRING sType = oNode.GetAttribute(L"isEmbeded");
|
||||
|
||||
if (L"0" == sType)
|
||||
{
|
||||
m_eType = EType::LINK;
|
||||
|
||||
m_sAPath = oNode.GetAttribute(L"sub-path");
|
||||
|
||||
if (m_sAPath.empty())
|
||||
m_sAPath = oNode.GetAttribute(L"href");
|
||||
}
|
||||
else if (L"1" == sType)
|
||||
{
|
||||
m_eType = EType::EMBEDDING;
|
||||
m_sAPath = oNode.GetAttribute(L"href");
|
||||
}
|
||||
else
|
||||
m_sAPath = oNode.GetAttribute(L"href");
|
||||
|
||||
m_sFormat = oNode.GetAttribute(L"media-type");
|
||||
|
||||
std::wregex oRegex(L"image/(.*)");
|
||||
|
||||
m_sFormat = std::regex_replace(m_sFormat, oRegex, L"$1");
|
||||
}
|
||||
|
||||
HWP_STRING CHWPRecordBinData::GetPath() const
|
||||
{
|
||||
return m_sAPath;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "HWPRecord.h"
|
||||
#include "../HWPStream.h"
|
||||
#include "../HWPDocInfo.h"
|
||||
#include "../Common/XMLNode.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
@ -12,15 +13,13 @@ enum class ECompressed
|
||||
FOLLOW_STORAGE = 0x00,
|
||||
COMPRESS = 0x10,
|
||||
NO_COMPRESS = 0x20,
|
||||
UNKNOWN
|
||||
};
|
||||
|
||||
enum class EType
|
||||
{
|
||||
LINK = 0x0,
|
||||
EMBEDDING = 0x1,
|
||||
STORAGE = 0x2,
|
||||
UNKNOWN
|
||||
STORAGE = 0x2
|
||||
};
|
||||
|
||||
enum class EState
|
||||
@ -28,8 +27,7 @@ enum class EState
|
||||
NEVER_ACCESSED = 0x000,
|
||||
FOUND_FILE_BY_ACCESS = 0x100,
|
||||
ACCESS_FAILED = 0x200,
|
||||
LINK_ACCESS_IGNORED = 0x400,
|
||||
UNKNOWN
|
||||
LINK_ACCESS_IGNORED = 0x400
|
||||
};
|
||||
|
||||
class CHWPRecordBinData : public CHWPRecord
|
||||
@ -46,6 +44,7 @@ class CHWPRecordBinData : public CHWPRecord
|
||||
HWP_STRING m_sItemID;
|
||||
public:
|
||||
CHWPRecordBinData(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
|
||||
CHWPRecordBinData(CXMLNode& oNode, int nVersion);
|
||||
|
||||
HWP_STRING GetPath() const;
|
||||
HWP_STRING GetItemID() const;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "HWPRecordBorderFill.h"
|
||||
#include <regex>
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
@ -58,6 +59,18 @@ EColorFillPattern GetColorFillPattern(int nPattern)
|
||||
}
|
||||
}
|
||||
|
||||
void TBorder::ReadFromNode(CXMLNode& oNode)
|
||||
{
|
||||
m_eStyle = GetLineStyle2(oNode.GetAttribute(L"type"));
|
||||
|
||||
HWP_STRING sColor = std::regex_replace(oNode.GetAttribute(L"color"), std::wregex(L"^#([0-9A-Fa-f]+)$"), L"$1");
|
||||
|
||||
if (L"none" != sColor)
|
||||
m_nColor = std::stoi(sColor, 0, 16);
|
||||
|
||||
m_chWidth = (HWP_BYTE)ConvertWidthToHWP(oNode.GetAttribute(L"width"));
|
||||
}
|
||||
|
||||
CFill::CFill()
|
||||
{}
|
||||
|
||||
@ -138,6 +151,83 @@ CFill::CFill(CHWPStream& oBuffer, int nOff, int nSize)
|
||||
m_nSize = oBuffer.GetDistanceToLastPos(true);
|
||||
}
|
||||
|
||||
CFill::CFill(CXMLNode& oNode)
|
||||
{
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hc:winBrush" == oChild.GetName())
|
||||
{
|
||||
ReadWinBrush(oChild);
|
||||
m_nFillType |= 0x01;
|
||||
}
|
||||
else if (L"hc:gradation" == oChild.GetName())
|
||||
{
|
||||
ReadGradation(oChild);
|
||||
m_nFillType |= 0x04;
|
||||
}
|
||||
else if (L"hc:imgBrush" == oChild.GetName())
|
||||
{
|
||||
ReadImgBrush(oChild);
|
||||
m_nFillType |= 0x02;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFill::ReadWinBrush(CXMLNode& oNode)
|
||||
{
|
||||
m_nFaceColor = oNode.GetAttributeColor(L"faceColor", 0xFFFFFFFF);
|
||||
m_nHatchColor = oNode.GetAttributeColor(L"hatchColor", 0x000000);
|
||||
m_eHatchStyle = GetColorFillPattern(oNode.GetAttributeInt(L"hatchStyle", -1));
|
||||
m_chAlpha = (HWP_BYTE)oNode.GetAttributeInt(L"alpha", 255);
|
||||
}
|
||||
|
||||
void CFill::ReadGradation(CXMLNode& oNode)
|
||||
{
|
||||
m_eGradType = GetGradFillType(oNode.GetAttributeInt(L"type"));
|
||||
m_nAngle = oNode.GetAttributeInt(L"angle");
|
||||
m_nCenterX = oNode.GetAttributeInt(L"centerX");
|
||||
m_nCenterY = oNode.GetAttributeInt(L"centerY");
|
||||
m_nStep = oNode.GetAttributeInt(L"step");
|
||||
m_nColorNum = oNode.GetAttributeInt(L"colorNum");
|
||||
m_chStepCenter = (HWP_BYTE)oNode.GetAttributeInt(L"stepCenter");
|
||||
m_chAlpha = (HWP_BYTE)oNode.GetAttributeInt(L"alpha", 255);
|
||||
|
||||
std::vector<XmlUtils::CXmlNode> arChilds;
|
||||
|
||||
oNode.GetNodes(L"Color", arChilds);
|
||||
|
||||
m_arColors.resize(arChilds.size());
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex)
|
||||
m_arColors[unIndex] = std::stoi(std::regex_replace(arChilds[unIndex].GetText(), std::wregex(L"\\D"), L""), 0, 16);
|
||||
}
|
||||
|
||||
void CFill::ReadImgBrush(CXMLNode& oNode)
|
||||
{
|
||||
m_eMode = GetImageFillType(oNode.GetAttributeInt(L"mode", (int)EImageFillType::NONE));
|
||||
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hc:img" == oChild.GetName())
|
||||
{
|
||||
m_chBright = (HWP_BYTE)oChild.GetAttributeInt(L"bright");
|
||||
m_chContrast = (HWP_BYTE)oChild.GetAttributeInt(L"contrast");
|
||||
|
||||
HWP_STRING sEffect = oChild.GetAttribute(L"effect");
|
||||
|
||||
if (L"REAL_PIC" == sEffect)
|
||||
m_chEffect = 0;
|
||||
else if (L"GRAY_SCALE" == sEffect)
|
||||
m_chEffect = 1;
|
||||
else if (L"BLACK_WHITE" == sEffect)
|
||||
m_chEffect = 2;
|
||||
|
||||
m_sBinItemID = oChild.GetAttribute(L"binaryItemIDRef");
|
||||
m_chAlpha = (HWP_BYTE)oChild.GetAttributeInt(L"alpha", 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int CFill::GetSize() const
|
||||
{
|
||||
return m_nSize;
|
||||
@ -174,11 +264,11 @@ HWP_STRING CFill::GetBinItemID() const
|
||||
}
|
||||
|
||||
CHWPRecordBorderFill::CHWPRecordBorderFill(int nTagNum, int nLevel, int nSize)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize), m_pParent(nullptr)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize), m_pFill(nullptr)
|
||||
{}
|
||||
|
||||
CHWPRecordBorderFill::CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize), m_pFill(nullptr)
|
||||
{
|
||||
short shTypeBits;
|
||||
oBuffer.ReadShort(shTypeBits);
|
||||
@ -208,7 +298,75 @@ CHWPRecordBorderFill::CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, int nTagNum, i
|
||||
READ_SIDE(m_oBottom);
|
||||
READ_SIDE(m_oDiagonal);
|
||||
|
||||
m_oFill = CFill(oBuffer, 0, 0); // TODO:: перейти от использования off и size
|
||||
m_pFill = new CFill(oBuffer, 0, 0); // TODO:: перейти от использования off и size
|
||||
}
|
||||
|
||||
CHWPRecordBorderFill::CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion)
|
||||
: CHWPRecord(EHWPTag::HWPTAG_BORDER_FILL, 0, 0), m_pFill(nullptr)
|
||||
{
|
||||
m_bThreeD = oNode.GetAttributeBool(L"threeD");
|
||||
m_bShadow = oNode.GetAttributeBool(L"shadow");
|
||||
m_bBreakCellSeparateLine = oNode.GetAttributeBool(L"breakCellSeparateLine");
|
||||
|
||||
HWP_STRING sChildName;
|
||||
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hh:slash" == oChild.GetName())
|
||||
{
|
||||
HWP_STRING sType = oChild.GetAttribute(L"type");
|
||||
|
||||
if (L"NONE" == sType)
|
||||
m_chSlash = 0x0;
|
||||
else if (L"CENTER" == sType)
|
||||
m_chSlash = 0b010;
|
||||
else if (L"CENTER_BELOW" == sType)
|
||||
m_chSlash = 0b011;
|
||||
else if (L"CENTER_ABOVE" == sType)
|
||||
m_chSlash = 0b110;
|
||||
else if (L"ALL" == sType)
|
||||
m_chSlash = 0b111;
|
||||
|
||||
m_chCrookedSlash = oChild.GetAttributeBool(L"Crooked");
|
||||
m_bCounterSlash = oChild.GetAttributeBool(L"isCounter");
|
||||
}
|
||||
else if (L"hh:backSlash" == oChild.GetName())
|
||||
{
|
||||
HWP_STRING sType = oChild.GetAttribute(L"type");
|
||||
|
||||
if (L"NONE" == sType)
|
||||
m_chBackSlash = 0x0;
|
||||
else if (L"CENTER" == sType)
|
||||
m_chBackSlash = 0b010;
|
||||
else if (L"CENTER_BELOW" == sType)
|
||||
m_chBackSlash = 0b011;
|
||||
else if (L"CENTER_ABOVE" == sType)
|
||||
m_chBackSlash = 0b110;
|
||||
else if (L"ALL" == sType)
|
||||
m_chBackSlash = 0b111;
|
||||
|
||||
m_chCrookedBackSlash = oChild.GetAttributeBool(L"Crooked");
|
||||
m_bCounterBackSlash = oChild.GetAttributeBool(L"isCounter");
|
||||
}
|
||||
else if (L"hh:leftBorder" == oChild.GetName())
|
||||
m_oLeft.ReadFromNode(oChild);
|
||||
else if (L"hh:rightBorder" == oChild.GetName())
|
||||
m_oRight.ReadFromNode(oChild);
|
||||
else if (L"hh:topBorder" == oChild.GetName())
|
||||
m_oTop.ReadFromNode(oChild);
|
||||
else if (L"hh:bottomBorder" == oChild.GetName())
|
||||
m_oBottom.ReadFromNode(oChild);
|
||||
else if (L"hh:diagonal" == oChild.GetName())
|
||||
m_oDiagonal.ReadFromNode(oChild);
|
||||
else if (L"hc:fillBrush" == oChild.GetName())
|
||||
m_pFill = new CFill(oChild);
|
||||
}
|
||||
}
|
||||
|
||||
CHWPRecordBorderFill::~CHWPRecordBorderFill()
|
||||
{
|
||||
if (nullptr != m_pFill)
|
||||
delete m_pFill;
|
||||
}
|
||||
|
||||
TBorder CHWPRecordBorderFill::GetLeftBorder() const
|
||||
@ -233,7 +391,8 @@ TBorder CHWPRecordBorderFill::GetBottomBorder() const
|
||||
|
||||
const CFill* CHWPRecordBorderFill::GetFill() const
|
||||
{
|
||||
return &m_oFill;
|
||||
return m_pFill;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "../HWPDocInfo.h"
|
||||
#include "HwpRecordTypes.h"
|
||||
#include "../HWPStream.h"
|
||||
#include "../Common/XMLNode.h"
|
||||
#include <vector>
|
||||
|
||||
namespace HWP
|
||||
@ -13,6 +14,8 @@ struct TBorder
|
||||
ELineStyle2 m_eStyle;
|
||||
HWP_BYTE m_chWidth;
|
||||
int m_nColor;
|
||||
|
||||
void ReadFromNode(CXMLNode& oNode);
|
||||
};
|
||||
|
||||
enum class EImageFillType
|
||||
@ -82,9 +85,14 @@ class CFill : public IRef
|
||||
HWP_BYTE m_chStepCenter;
|
||||
|
||||
HWP_BYTE m_chAlpha;
|
||||
|
||||
void ReadWinBrush(CXMLNode& oNode);
|
||||
void ReadGradation(CXMLNode& oNode);
|
||||
void ReadImgBrush(CXMLNode& oNode);
|
||||
public:
|
||||
CFill();
|
||||
CFill(CHWPStream& oBuffer, int nOff, int nSize);
|
||||
CFill(CXMLNode& oNode);
|
||||
|
||||
int GetSize() const;
|
||||
bool NoneFill() const;
|
||||
@ -98,7 +106,6 @@ public:
|
||||
|
||||
class CHWPRecordBorderFill : public CHWPRecord
|
||||
{
|
||||
CHWPDocInfo *m_pParent;
|
||||
static constexpr const float LINE_THICK[] = { 0.1f, 0.12f, 0.15f, 0.2f, 0.25f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 1.0f, 1.5f, 2.0f, 3.0f, 4.0f, 5.0f };
|
||||
|
||||
bool m_bThreeD;
|
||||
@ -116,10 +123,12 @@ class CHWPRecordBorderFill : public CHWPRecord
|
||||
TBorder m_oTop;
|
||||
TBorder m_oBottom;
|
||||
TBorder m_oDiagonal;
|
||||
CFill m_oFill;
|
||||
CFill *m_pFill;
|
||||
public:
|
||||
CHWPRecordBorderFill(int nTagNum, int nLevel, int nSize);
|
||||
CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
|
||||
CHWPRecordBorderFill(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion);
|
||||
~CHWPRecordBorderFill();
|
||||
|
||||
TBorder GetLeftBorder() const;
|
||||
TBorder GetRightBorder() const;
|
||||
|
||||
@ -19,7 +19,7 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve
|
||||
oBuffer.ReadShort(m_oHeaderInfo.m_shTextOffset);
|
||||
oBuffer.ReadInt(m_oHeaderInfo.m_nCharShape);
|
||||
|
||||
oBuffer.Skip(2); //TODO:: ByteBuffer.wrap(buf, offset, 2).order(ByteOrder.LITTLE_ENDIAN).getChar();
|
||||
oBuffer.ReadChar(m_chBulletChar);
|
||||
|
||||
if (nSize > oBuffer.GetDistanceToLastPos())
|
||||
oBuffer.ReadInt(m_nBulletImage);
|
||||
@ -33,12 +33,29 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve
|
||||
if (nSize > oBuffer.GetDistanceToLastPos())
|
||||
oBuffer.ReadByte(m_chImageEffect);
|
||||
|
||||
if (nSize > oBuffer.GetDistanceToLastPos(true))
|
||||
if (nSize > oBuffer.GetDistanceToLastPos())
|
||||
{
|
||||
short shValue;
|
||||
oBuffer.ReadShort(shValue);
|
||||
|
||||
m_sBinItemRefID = TO_HWP_STRING(shValue);
|
||||
}
|
||||
|
||||
if (nSize > oBuffer.GetDistanceToLastPos(true))
|
||||
oBuffer.ReadChar(m_chCheckBulletChar);
|
||||
}
|
||||
|
||||
CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion)
|
||||
: CHWPRecord(EHWPTag::HWPTAG_BULLET, 0, 0), m_pParent(&oDocInfo)
|
||||
{
|
||||
m_chBulletChar = oNode.GetAttribute(L"char").at(0);
|
||||
m_chCheckBulletChar = oNode.GetAttribute(L"checkedChar").at(0);
|
||||
m_nBulletImage = oNode.GetAttributeInt(L"useImage");
|
||||
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hc:img" == oChild.GetName())
|
||||
m_sBinItemRefID = oChild.GetAttribute(L"binaryItemIDRef");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "../HWPStream.h"
|
||||
#include "../HWPDocInfo.h"
|
||||
#include "HWPRecordNumbering.h"
|
||||
#include "../Common/XMLNode.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
@ -13,16 +14,17 @@ class CHWPRecordBullet : public CHWPRecord
|
||||
CHWPDocInfo *m_pParent;
|
||||
|
||||
TNumbering m_oHeaderInfo;
|
||||
wchar_t m_wchBulletChar;
|
||||
HWP_CHAR m_chBulletChar;
|
||||
int m_nBulletImage;
|
||||
|
||||
HWP_BYTE m_chBright;
|
||||
HWP_BYTE m_chContrast;
|
||||
HWP_BYTE m_chImageEffect;
|
||||
HWP_STRING m_sBinItemRefID;
|
||||
wchar_t m_wchCheckBulletChar;
|
||||
HWP_CHAR m_chCheckBulletChar;
|
||||
public:
|
||||
CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
|
||||
CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,31 @@
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
EAccent GetAccent(int nValue)
|
||||
{
|
||||
SWITCH(EAccent, nValue)
|
||||
{
|
||||
DEFAULT(EAccent::NONE);
|
||||
CASE(EAccent::DOT);
|
||||
CASE(EAccent::RING);
|
||||
CASE(EAccent::CARON);
|
||||
CASE(EAccent::TILDE);
|
||||
CASE(EAccent::ARAEA);
|
||||
CASE(EAccent::TWOARAEA);
|
||||
}
|
||||
}
|
||||
|
||||
EAccent GetAccent(const HWP_STRING& sValue)
|
||||
{
|
||||
IF_STRING_IN_ENUM(DOT, sValue, EAccent);
|
||||
ELSE_IF_STRING_IN_ENUM(RING, sValue, EAccent);
|
||||
ELSE_IF_STRING_IN_ENUM(CARON, sValue, EAccent);
|
||||
ELSE_IF_STRING_IN_ENUM(TILDE, sValue, EAccent);
|
||||
ELSE_IF_STRING_IN_ENUM(ARAEA, sValue, EAccent);
|
||||
ELSE_IF_STRING_IN_ENUM(TWOARAEA, sValue, EAccent);
|
||||
ELSE_STRING_IN_ENUM(NONE, EAccent);
|
||||
}
|
||||
|
||||
ELang GetLang(int nValue)
|
||||
{
|
||||
switch (static_cast<ELang>(nValue))
|
||||
@ -23,48 +48,76 @@ ELang GetLang(int nValue)
|
||||
|
||||
EUnderline GetUnderline(int nValue)
|
||||
{
|
||||
switch(static_cast<EUnderline>(nValue))
|
||||
SWITCH(EUnderline, nValue)
|
||||
{
|
||||
case EUnderline::NONE:
|
||||
case EUnderline::BOTTOM:
|
||||
case EUnderline::CENTER:
|
||||
case EUnderline::TOP:
|
||||
return static_cast<EUnderline>(nValue);
|
||||
default:
|
||||
return EUnderline::NONE;
|
||||
DEFAULT(EUnderline::NONE);
|
||||
CASE(EUnderline::BOTTOM);
|
||||
CASE(EUnderline::CENTER);
|
||||
CASE(EUnderline::TOP);
|
||||
}
|
||||
}
|
||||
|
||||
EUnderline GetUnderline(const HWP_STRING& sValue)
|
||||
{
|
||||
IF_STRING_IN_ENUM(BOTTOM, sValue, EUnderline);
|
||||
ELSE_IF_STRING_IN_ENUM(CENTER, sValue, EUnderline);
|
||||
ELSE_IF_STRING_IN_ENUM(TOP, sValue, EUnderline);
|
||||
ELSE_STRING_IN_ENUM(NONE, EUnderline);
|
||||
}
|
||||
|
||||
EOutline GetOutline(int nValue)
|
||||
{
|
||||
switch(static_cast<EOutline>(nValue))
|
||||
SWITCH(EOutline, nValue)
|
||||
{
|
||||
case EOutline::NONE:
|
||||
case EOutline::SOLID:
|
||||
case EOutline::DOTTED:
|
||||
case EOutline::BOLD:
|
||||
case EOutline::DASHED:
|
||||
case EOutline::DASH_DOT:
|
||||
case EOutline::DASH_2DOT:
|
||||
return static_cast<EOutline>(nValue);
|
||||
default:
|
||||
return EOutline::NONE;
|
||||
DEFAULT(EOutline::NONE);
|
||||
CASE(EOutline::SOLID);
|
||||
CASE(EOutline::DOTTED);
|
||||
CASE(EOutline::BOLD);
|
||||
CASE(EOutline::DASHED);
|
||||
CASE(EOutline::DASH_DOT);
|
||||
CASE(EOutline::DASH_2DOT);
|
||||
}
|
||||
}
|
||||
|
||||
EOutline GetOutline(const HWP_STRING& sValue)
|
||||
{
|
||||
IF_STRING_IN_ENUM(SOLID, sValue, EOutline);
|
||||
ELSE_IF_STRING_IN_ENUM(DOTTED, sValue, EOutline);
|
||||
ELSE_IF_STRING_IN_ENUM(BOLD, sValue, EOutline);
|
||||
ELSE_IF_STRING_IN_ENUM(DASHED, sValue, EOutline);
|
||||
ELSE_IF_STRING_IN_ENUM(DASH_DOT, sValue, EOutline);
|
||||
ELSE_IF_STRING_IN_ENUM(DASH_2DOT, sValue, EOutline);
|
||||
ELSE_STRING_IN_ENUM(NONE, EOutline);
|
||||
}
|
||||
|
||||
EShadow GetShadow(int nValue)
|
||||
{
|
||||
switch(static_cast<EShadow>(nValue))
|
||||
SWITCH(EShadow, nValue)
|
||||
{
|
||||
case EShadow::NONE:
|
||||
case EShadow::DISCRETE:
|
||||
case EShadow::CONTINUOUS:
|
||||
return static_cast<EShadow>(nValue);
|
||||
default:
|
||||
return EShadow::NONE;
|
||||
DEFAULT(EShadow::NONE);
|
||||
CASE(EShadow::DISCRETE);
|
||||
CASE(EShadow::CONTINUOUS);
|
||||
}
|
||||
}
|
||||
|
||||
EShadow GetShadow(const HWP_STRING& sValue)
|
||||
{
|
||||
IF_STRING_IN_ENUM(DISCRETE, sValue, EShadow);
|
||||
ELSE_IF_STRING_IN_ENUM(CONTINUOUS, sValue, EShadow);
|
||||
ELSE_STRING_IN_ENUM(NONE, EShadow);
|
||||
}
|
||||
|
||||
void CHWPRecordCharShape::ReadContainerData(CXMLNode& oNode, short arValues[], int nDefaultValue)
|
||||
{
|
||||
arValues[(int)ELang::HANGUL] = oNode.GetAttributeInt(L"hangul", nDefaultValue);
|
||||
arValues[(int)ELang::LATIN] = oNode.GetAttributeInt(L"latin", nDefaultValue);
|
||||
arValues[(int)ELang::HANJA] = oNode.GetAttributeInt(L"hanja", nDefaultValue);
|
||||
arValues[(int)ELang::JAPANESE] = oNode.GetAttributeInt(L"japanese", nDefaultValue);
|
||||
arValues[(int)ELang::OTHER] = oNode.GetAttributeInt(L"other", nDefaultValue);
|
||||
arValues[(int)ELang::SYMBOL] = oNode.GetAttributeInt(L"symbol", nDefaultValue);
|
||||
arValues[(int)ELang::USER] = oNode.GetAttributeInt(L"user", nDefaultValue);
|
||||
}
|
||||
|
||||
CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion)
|
||||
: CHWPRecord(nTagNum, nLevel, nSize), m_pParent(&oDocInfo)
|
||||
{
|
||||
@ -142,6 +195,105 @@ CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int
|
||||
oBuffer.RemoveLastSavedPos();
|
||||
}
|
||||
|
||||
CHWPRecordCharShape::CHWPRecordCharShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion)
|
||||
: CHWPRecord(EHWPTag::HWPTAG_HWP_CHAR_SHAPE, 0, 0), m_pParent(&oDocInfo),
|
||||
m_bItalic(false), m_bBold(false), m_bEmboss(false), m_bEngrave(false),
|
||||
m_bSuperScript(false), m_bSubScript(false)
|
||||
{
|
||||
m_eUnderline = EUnderline::NONE;
|
||||
m_eUnderLineShape = ELineStyle1::SOLID;
|
||||
m_eOutline = EOutline::NONE;
|
||||
m_eShadow = EShadow::NONE;
|
||||
m_eStrikeOutShape = ELineStyle2::NONE;
|
||||
|
||||
m_nHeight = oNode.GetAttributeInt(L"height", 1000);
|
||||
m_nTextColor = oNode.GetAttributeColor(L"textColor", 0x000000);
|
||||
m_nShadeColor = oNode.GetAttributeColor(L"shadeColor", 0xFFFFFFFF);
|
||||
m_bUseFontSpace = oNode.GetAttributeBool(L"useFontSpace");
|
||||
m_bUseKerning = oNode.GetAttributeBool(L"useKerning");
|
||||
|
||||
m_eSymMark = GetAccent(oNode.GetAttribute(L"symMark"));
|
||||
|
||||
m_shBorderFillIDRef = oNode.GetAttributeInt(L"borderFillIDRef");
|
||||
|
||||
for (CXMLNode& oChild : oNode.GetChilds())
|
||||
{
|
||||
if (L"hh:fontRef" == oChild.GetName())
|
||||
{
|
||||
if (nullptr == m_pParent)
|
||||
continue;
|
||||
|
||||
const CHWPRecordFaceName* pFaceName = nullptr;
|
||||
|
||||
#define UPDATE_FACENAME(node_name, elang_type) \
|
||||
pFaceName = dynamic_cast<const CHWPRecordFaceName*>(m_pParent->GetFaceName(oChild.GetAttributeInt(node_name))); \
|
||||
if (nullptr != pFaceName) \
|
||||
m_arFontNames[(int)elang_type] = pFaceName->GetFaceName()
|
||||
|
||||
UPDATE_FACENAME(L"hangul", ELang::HANGUL);
|
||||
UPDATE_FACENAME(L"latin", ELang::LATIN);
|
||||
UPDATE_FACENAME(L"hanja", ELang::HANJA);
|
||||
UPDATE_FACENAME(L"japanese", ELang::JAPANESE);
|
||||
UPDATE_FACENAME(L"other", ELang::OTHER);
|
||||
UPDATE_FACENAME(L"symbol", ELang::SYMBOL);
|
||||
UPDATE_FACENAME(L"user", ELang::USER);
|
||||
}
|
||||
else if (L"hh:ratio" == oChild.GetName())
|
||||
ReadContainerData(oChild, m_arRatios, 100);
|
||||
else if (L"hh:spacing" == oChild.GetName())
|
||||
ReadContainerData(oChild, m_arSpacings);
|
||||
else if (L"hh:relSz" == oChild.GetName())
|
||||
ReadContainerData(oChild, m_arRelSizes, 100);
|
||||
else if (L"hh:offset" == oChild.GetName())
|
||||
ReadContainerData(oChild, m_arCharOffset);
|
||||
else if (L"hh:underline" == oChild.GetName())
|
||||
{
|
||||
m_eUnderline = GetUnderline(oChild.GetAttribute(L"type"));
|
||||
m_eUnderLineShape = GetLineStyle1(oChild.GetAttribute(L"shape"));
|
||||
m_nUnderlineColor = oChild.GetAttributeColor(L"color");
|
||||
}
|
||||
else if (L"hh:strikeout" == oChild.GetName())
|
||||
{
|
||||
m_eStrikeOutShape = GetLineStyle2(oChild.GetAttribute(L"shape"));
|
||||
m_nStrikeOutColor = oChild.GetAttributeColor(L"color");
|
||||
|
||||
if (L"3D" == oChild.GetAttribute(L"shape"))
|
||||
m_eStrikeOutShape = ELineStyle2::NONE;
|
||||
}
|
||||
else if (L"hh:outline" == oChild.GetName())
|
||||
{
|
||||
m_eOutline = GetOutline(oChild.GetAttribute(L"type"));
|
||||
}
|
||||
else if (L"hh:shadow" == oChild.GetName())
|
||||
{
|
||||
HWP_STRING sType = oChild.GetAttribute(L"type");
|
||||
|
||||
if (L"DROP" == sType)
|
||||
m_eShadow = EShadow::DISCRETE;
|
||||
else if (L"CONTINUOUS" == sType)
|
||||
m_eShadow = EShadow::CONTINUOUS;
|
||||
else
|
||||
m_eShadow = EShadow::NONE;
|
||||
|
||||
m_nShadowColor = oChild.GetAttributeColor(L"color");
|
||||
m_chShadowOffsetX = (HWP_BYTE)oChild.GetAttributeInt(L"offsetX");
|
||||
m_chShadowOffsetY = (HWP_BYTE)oChild.GetAttributeInt(L"offsetY");
|
||||
}
|
||||
else if (L"hh:italic" == oChild.GetName())
|
||||
m_bItalic = true;
|
||||
else if (L"hh:bold" == oChild.GetName())
|
||||
m_bBold = true;
|
||||
else if (L"hh:emboss" == oChild.GetName())
|
||||
m_bEmboss = true;
|
||||
else if (L"hh:engrave" == oChild.GetName())
|
||||
m_bEmboss = true;
|
||||
else if (L"hh:supscript" == oChild.GetName())
|
||||
m_bSuperScript = true;
|
||||
else if (L"hh:subscript" == oChild.GetName())
|
||||
m_bSubScript = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CHWPRecordCharShape::Bold() const
|
||||
{
|
||||
return m_bBold;
|
||||
@ -157,6 +309,11 @@ bool CHWPRecordCharShape::Underline() const
|
||||
return EUnderline::NONE != m_eUnderline;
|
||||
}
|
||||
|
||||
bool CHWPRecordCharShape::StrikeOut() const
|
||||
{
|
||||
return ELineStyle2::NONE != m_eStrikeOutShape;
|
||||
}
|
||||
|
||||
int CHWPRecordCharShape::GetHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
@ -177,6 +334,16 @@ int CHWPRecordCharShape::GetUnderlineColor() const
|
||||
return m_nUnderlineColor;
|
||||
}
|
||||
|
||||
ELineStyle2 CHWPRecordCharShape::GetStrikeOutType() const
|
||||
{
|
||||
return m_eStrikeOutShape;
|
||||
}
|
||||
|
||||
int CHWPRecordCharShape::GetStrikeOutColor() const
|
||||
{
|
||||
return m_nStrikeOutColor;
|
||||
}
|
||||
|
||||
short CHWPRecordCharShape::GetRelSize(ELang eLang) const
|
||||
{
|
||||
if (ELang::MAX == eLang)
|
||||
@ -205,4 +372,9 @@ int CHWPRecordCharShape::GetTextColor() const
|
||||
{
|
||||
return m_nTextColor;
|
||||
}
|
||||
|
||||
short CHWPRecordCharShape::GetBorderFillID() const
|
||||
{
|
||||
return m_shBorderFillIDRef;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "../HWPStream.h"
|
||||
#include "HWPRecord.h"
|
||||
#include "HwpRecordTypes.h"
|
||||
#include "../Common/XMLNode.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
@ -58,22 +59,8 @@ enum class EAccent
|
||||
TWOARAEA
|
||||
};
|
||||
|
||||
inline EAccent GetAccent(int nValue)
|
||||
{
|
||||
switch(static_cast<EAccent>(nValue))
|
||||
{
|
||||
case EAccent::NONE:
|
||||
case EAccent::DOT:
|
||||
case EAccent::RING:
|
||||
case EAccent::CARON:
|
||||
case EAccent::TILDE:
|
||||
case EAccent::ARAEA:
|
||||
case EAccent::TWOARAEA:
|
||||
return static_cast<EAccent>(nValue);
|
||||
default:
|
||||
return EAccent::NONE;
|
||||
}
|
||||
}
|
||||
EAccent GetAccent(int nValue);
|
||||
EAccent GetAccent(const HWP_STRING& sValue);
|
||||
|
||||
#define MAX_ELEMENTS (int)ELang::MAX
|
||||
|
||||
@ -112,22 +99,32 @@ class CHWPRecordCharShape : public CHWPRecord
|
||||
int m_nShadowColor;
|
||||
short m_shBorderFillIDRef;
|
||||
int m_nStrikeOutColor;
|
||||
|
||||
void ReadContainerData(CXMLNode& oNode, short arValues[], int nDefaultValue = 0);
|
||||
public:
|
||||
CHWPRecordCharShape(CHWPDocInfo& oDocInfo, int nTagNum, int nLevel, int nSize, CHWPStream& oBuffer, int nOff, int nVersion);
|
||||
CHWPRecordCharShape(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion);
|
||||
|
||||
bool Bold() const;
|
||||
bool Italic() const;
|
||||
bool Underline() const;
|
||||
bool StrikeOut() const;
|
||||
|
||||
int GetHeight() const;
|
||||
|
||||
EUnderline GetUnderlineType() const;
|
||||
ELineStyle1 GetUnderlineStyle() const;
|
||||
int GetUnderlineColor() const;
|
||||
|
||||
ELineStyle2 GetStrikeOutType() const;
|
||||
int GetStrikeOutColor() const;
|
||||
|
||||
short GetRelSize(ELang eLang) const;
|
||||
HWP_STRING GetFontName(ELang eLang) const;
|
||||
short GetSpacing(ELang eLang) const;
|
||||
int GetTextColor() const;
|
||||
|
||||
short GetBorderFillID() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "HWPRecordCtrlData.h"
|
||||
#include "../Paragraph/CtrlField.h"
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
@ -35,7 +36,53 @@ int CHWPRecordCtrlData::ParseCtrl(CCtrl& oCtrl, int nSize, CHWPStream& oBuffer,
|
||||
// TODO:: Вернуться к этому моменту
|
||||
// Само по себе содержание документа Hankom не позволяет понять, как его интерпретировать.
|
||||
|
||||
oBuffer.Skip(nSize);
|
||||
oBuffer.SavePosition();
|
||||
|
||||
if (ECtrlObjectType::Field == oCtrl.GetCtrlType())
|
||||
{
|
||||
short shSetID, shNumberItems;
|
||||
|
||||
oBuffer.ReadShort(shSetID);
|
||||
oBuffer.ReadShort(shNumberItems);
|
||||
|
||||
short shItemID, shItemType;
|
||||
for (unsigned short ushIndex = 0; ushIndex < shNumberItems; ++ushIndex)
|
||||
{
|
||||
oBuffer.ReadShort(shItemID);
|
||||
short shUnknownValue;
|
||||
oBuffer.ReadShort(shUnknownValue); // Unknown Data
|
||||
oBuffer.ReadShort(shItemType);
|
||||
|
||||
switch (GetParamItemType(shItemType))
|
||||
{
|
||||
case EParamItemType::PIT_NULL: oBuffer.Skip(4); break;
|
||||
case EParamItemType::PIT_BSTR:
|
||||
{
|
||||
HWP_STRING sValue;
|
||||
oBuffer.ReadString(sValue, EStringCharacter::UTF16);
|
||||
|
||||
if (EFieldType::Bookmark == ((CCtrlField&)oCtrl).GetType())
|
||||
((CCtrlField&)oCtrl).AddStringParam(L"bookmarkname", sValue);
|
||||
|
||||
break;
|
||||
}
|
||||
case EParamItemType::PIT_I1: oBuffer.Skip(1); break;
|
||||
case EParamItemType::PIT_I2: oBuffer.Skip(2); break;
|
||||
case EParamItemType::PIT_I4: oBuffer.Skip(4); break;
|
||||
case EParamItemType::PIT_I: oBuffer.Skip(4); break;
|
||||
case EParamItemType::PIT_UI1: oBuffer.Skip(1); break;
|
||||
case EParamItemType::PIT_UI2: oBuffer.Skip(2); break;
|
||||
case EParamItemType::PIT_UI4: oBuffer.Skip(4); break;
|
||||
case EParamItemType::PIT_UI: oBuffer.Skip(4); break;
|
||||
case EParamItemType::PIT_SET:
|
||||
case EParamItemType::PIT_ARRAY:
|
||||
case EParamItemType::PIT_BINDATA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oBuffer.Skip(nSize - oBuffer.GetDistanceToLastPos(true));
|
||||
return nSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
#include "../HWPStream.h"
|
||||
#include "HWPRecord.h"
|
||||
#include "../Paragraph/Ctrl.h"
|
||||
#include <list>
|
||||
|
||||
namespace HWP
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user