mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-03-31 10:21:37 +08:00
Compare commits
340 Commits
v8.3.0.13
...
fix/OOXml2
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 30f96cbc6c | |||
| 007362d8be | |||
| f4aac048ea | |||
| f815fec8ed | |||
| 4ec217226d | |||
| 3cef41e876 | |||
| 20bff1d6fe | |||
| 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 | |||
| 321e0de9f3 | |||
| ca77113e79 | |||
| 2098c72a35 | |||
| 06e34fc303 | |||
| 7b56d56c0e | |||
| aa90104b18 | |||
| 98b285ab64 | |||
| cbd7e8ee7b | |||
| b76235d4fc | |||
| b9e1d77038 | |||
| 8f448d3842 | |||
| 89d7242d21 | |||
| 9aaa241523 | |||
| 02bd5c4b0b | |||
| 4003a39ef9 | |||
| a5fed4af70 | |||
| a9d8cbbc57 | |||
| 6c79ab37fa | |||
| 17762b71db | |||
| be2f142fd3 | |||
| fdcb2cf7ba | |||
| 07bf7a44aa | |||
| a2bfbd8368 | |||
| 25553904df | |||
| 954ef08975 | |||
| aea8b7873c | |||
| a7774a6bc3 | |||
| 4d15b5c19d | |||
| e230fa1d43 | |||
| 3d30144ebb | |||
| 3365ca15d6 | |||
| c0debdfe39 | |||
| f7d55d48fe | |||
| f2510a9410 | |||
| f2a8a9878b | |||
| 39adc06921 | |||
| 64af642c40 | |||
| ef26ac732e | |||
| 8bbaaf4cef | |||
| de821b73c8 | |||
| a7d5fe3994 | |||
| 7deeefbcf4 | |||
| 3666bdf6fc | |||
| eaa7bb30db | |||
| d4619c5786 | |||
| 0f3852ab1e | |||
| fb5b1c5a6e | |||
| cef8ac9fd9 | |||
| 45aa5df267 | |||
| e8c94aa103 | |||
| aa5b7e1276 | |||
| dd98d0c11d | |||
| 08971025bd | |||
| 00f6a823d6 | |||
| b4f4da26d6 | |||
| 1c9f7ac597 | |||
| 673139f5a9 | |||
| 4bf0cee034 | |||
| 00abbab370 | |||
| 3125a7a928 | |||
| f20c944c72 | |||
| 6d7dc6517b | |||
| 6fd84c6c8c | |||
| d37f31208c | |||
| c472b19e0d | |||
| 7b03bcde89 | |||
| 03a7eb0fd4 | |||
| c0a779727e | |||
| 52d3f0bc19 | |||
| c17497e304 | |||
| 6bc4ecbc73 | |||
| 2246077589 | |||
| 91eb74773b | |||
| 5b8d2660aa | |||
| 60ad1c10fd | |||
| 36b0cc524e | |||
| bb33e70b3e | |||
| 5f2d7b2f5a | |||
| 02aeaa6a64 | |||
| 7696541430 | |||
| 614156f575 | |||
| 397abd51a5 | |||
| d311090ced | |||
| 4a110d68c1 | |||
| 505a3c6224 | |||
| 75a21ee162 | |||
| 440cf968d5 | |||
| 3daa374a51 | |||
| 5d83d912fc | |||
| 695fd3ba1c | |||
| 75f68904f2 | |||
| b99badda9f | |||
| 48d86cb7ce | |||
| 9991cc8c03 | |||
| 36a3b693d5 | |||
| dbd6be9520 | |||
| 42ef948fcc | |||
| 69f4ac3ed7 | |||
| 328e379ec2 | |||
| 7d65d4b11a | |||
| 57ba4355f9 | |||
| 2eea44bc8c | |||
| cb982a1ad4 | |||
| 0aca0a0a5a | |||
| 0c1df859e2 | |||
| 7a153285c8 | |||
| c2d00ee819 | |||
| 3603787df8 | |||
| d58424d089 | |||
| fe2ca8c566 | |||
| 20d2ff7954 | |||
| b125c19d02 | |||
| 2f2d11a5f6 | |||
| de4897fdef | |||
| f9952d0f94 | |||
| 5483a8d36b | |||
| 80ac89f16b | |||
| fcf9830aa6 | |||
| d7b435a446 | |||
| 887d963d8d | |||
| bc4c39b7aa | |||
| 8d89026d19 | |||
| 4e6e3ce5f0 | |||
| 3d7eced836 | |||
| 7130b1be34 | |||
| a5917c389f | |||
| eee80b0f87 | |||
| 35dff37820 | |||
| 2f45a87669 | |||
| 185b3d54eb | |||
| f7f059b6c0 | |||
| 2a9044d066 | |||
| a93f00d0af | |||
| f9f4efc383 | |||
| 12ad4e604b | |||
| e0ad062380 | |||
| b72f678c1d | |||
| 59f41bcdec | |||
| e8aa709d4e | |||
| c4515aca3a | |||
| b776b7b63f | |||
| 134a214a0b | |||
| 95f604ec68 | |||
| ecd71dd92a | |||
| d8bd9ef845 | |||
| bd3cabd236 | |||
| 7e11af5553 | |||
| 168dc1ddb8 | |||
| 8918b7fae0 | |||
| d20d1af154 | |||
| 925ffa09e2 | |||
| 6b9fc964b9 | |||
| 9242ab9743 | |||
| e14cc2d5c5 | |||
| 295dbbbb86 | |||
| 265db0216b | |||
| 10ff332f4d | |||
| f57179911f | |||
| 2ba281a5ee | |||
| ce0f8251d3 | |||
| f019dfbb07 | |||
| c83a8a3a54 | |||
| 1c362612e3 | |||
| cf346bd535 | |||
| 536dac5fc9 | |||
| dc4074299c | |||
| caac75fcc1 | |||
| bb204098a1 | |||
| 1e9a63083b | |||
| b3f5d84a51 | |||
| ec50e77695 | |||
| cc2867e292 | |||
| 92b0f4e654 | |||
| 3503eee5b6 | |||
| cebc04b852 | |||
| dbfdffd0c5 | |||
| b8d2cba3ae | |||
| b56d62442d | |||
| 50fec65617 | |||
| 42466cf648 | |||
| b4bb20bea7 | |||
| 2ce37e34c4 | |||
| c8b8462d31 |
@ -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);
|
||||
|
||||
@ -13,14 +13,14 @@ namespace NSCSS
|
||||
delete m_pInternal;
|
||||
}
|
||||
|
||||
CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure) const
|
||||
CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector<CNode> &arSelectors) const
|
||||
{
|
||||
return m_pInternal->GetCompiledStyle(arSelectors, bIsSettings, unitMeasure);
|
||||
return m_pInternal->GetCompiledStyle(arSelectors);
|
||||
}
|
||||
|
||||
bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) const
|
||||
bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors) const
|
||||
{
|
||||
return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure);
|
||||
return m_pInternal->GetCompiledStyle(oStyle, arSelectors);
|
||||
}
|
||||
|
||||
std::wstring CCssCalculator::CalculateStyleId(const CNode& oNode)
|
||||
@ -48,26 +48,11 @@ namespace NSCSS
|
||||
m_pInternal->AddStylesFromFile(wsFileName);
|
||||
}
|
||||
|
||||
void CCssCalculator::SetUnitMeasure(const UnitMeasure& nType)
|
||||
{
|
||||
m_pInternal->SetUnitMeasure(nType);
|
||||
}
|
||||
|
||||
void CCssCalculator::SetDpi(const unsigned short int& nValue)
|
||||
{
|
||||
m_pInternal->SetDpi(nValue);
|
||||
}
|
||||
|
||||
void CCssCalculator::SetBodyTree(const CTree &oTree)
|
||||
{
|
||||
m_pInternal->SetBodyTree(oTree);
|
||||
}
|
||||
|
||||
UnitMeasure CCssCalculator::GetUnitMeasure() const
|
||||
{
|
||||
return m_pInternal->GetUnitMeasure();
|
||||
}
|
||||
|
||||
std::wstring CCssCalculator::GetEncoding() const
|
||||
{
|
||||
return m_pInternal->GetEncoding();
|
||||
@ -78,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();
|
||||
|
||||
@ -19,8 +19,8 @@ namespace NSCSS
|
||||
CCssCalculator();
|
||||
~CCssCalculator();
|
||||
|
||||
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
|
||||
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
|
||||
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors) const;
|
||||
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors) const;
|
||||
|
||||
std::wstring CalculateStyleId(const CNode& oNode);
|
||||
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector<CNode> &arSelectors);
|
||||
@ -30,14 +30,15 @@ namespace NSCSS
|
||||
void AddStyles (const std::wstring& wsStyle);
|
||||
void AddStylesFromFile(const std::wstring& wsFileName);
|
||||
|
||||
void SetUnitMeasure(const UnitMeasure& nType);
|
||||
void SetDpi(const unsigned short int& nValue);
|
||||
void SetBodyTree(const CTree &oTree);
|
||||
|
||||
UnitMeasure GetUnitMeasure() const;
|
||||
std::wstring GetEncoding() const;
|
||||
unsigned short int GetDpi() const;
|
||||
|
||||
void ClearPageData();
|
||||
void ClearEmbeddedStyles();
|
||||
void ClearAllowedStyleFiles();
|
||||
void ClearStylesFromFile(const std::wstring& wsFilePath);
|
||||
void Clear();
|
||||
};
|
||||
}
|
||||
|
||||
@ -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,61 +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_UnitMeasure(Point), m_mStatictics(NULL), 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();
|
||||
|
||||
if (NULL != m_mStatictics)
|
||||
delete m_mStatictics;
|
||||
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)
|
||||
{
|
||||
@ -110,162 +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, bool bIsSettings)
|
||||
{
|
||||
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 (oFindId != m_mData.end() && NULL != m_mStatictics)
|
||||
{
|
||||
std::map<StatistickElement, unsigned int>::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, wsId});
|
||||
|
||||
if ((m_mStatictics->end() != oFindCountId) &&
|
||||
(((bIsSettings && oFindCountId->second < MaxNumberRepetitions) ||
|
||||
(!bIsSettings && oFindCountId->second >= MaxNumberRepetitions))))
|
||||
{
|
||||
if (!oFindId->second->Empty())
|
||||
arFindedElements.push_back(oFindId->second);
|
||||
}
|
||||
|
||||
FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!arClasses.empty())
|
||||
{
|
||||
if (!bIsSettings)
|
||||
{
|
||||
for (std::vector<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.end())
|
||||
{
|
||||
if (!oFindClass->second->Empty())
|
||||
arFindedElements.push_back(oFindClass->second);
|
||||
|
||||
FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oFindName != m_mData.end())
|
||||
{
|
||||
if (!bIsSettings)
|
||||
{
|
||||
if (!oFindName->second->Empty())
|
||||
arFindedElements.push_back(oFindName->second);
|
||||
|
||||
FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses);
|
||||
}
|
||||
}
|
||||
|
||||
if (arFindedElements.size() > 1)
|
||||
{
|
||||
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
|
||||
[](CElement* oFirstElement, CElement* oSecondElement)
|
||||
{
|
||||
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
|
||||
});
|
||||
}
|
||||
|
||||
return arFindedElements;
|
||||
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;
|
||||
@ -273,7 +251,7 @@ namespace NSCSS
|
||||
switch (oRule->type) {
|
||||
case KatanaRuleStyle:
|
||||
{
|
||||
GetStyleRule((KatanaStyleRule*)oRule);
|
||||
GetStyleRule((KatanaStyleRule*)oRule, mStyleData);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -281,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;
|
||||
@ -297,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;
|
||||
@ -313,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;
|
||||
@ -342,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;
|
||||
@ -375,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;
|
||||
@ -408,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>();
|
||||
@ -425,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;
|
||||
@ -444,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>();
|
||||
@ -457,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);
|
||||
|
||||
@ -467,52 +450,213 @@ 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
|
||||
CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector<CNode>& arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure)
|
||||
CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector<CNode>& arSelectors)
|
||||
{
|
||||
if (arSelectors.empty())
|
||||
return CCompiledStyle();
|
||||
|
||||
CCompiledStyle oStyle;
|
||||
|
||||
GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure);
|
||||
GetCompiledStyle(oStyle, arSelectors);
|
||||
|
||||
return oStyle;
|
||||
}
|
||||
|
||||
bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure)
|
||||
bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors)
|
||||
{
|
||||
if (arSelectors.empty())
|
||||
return false;
|
||||
|
||||
SetUnitMeasure(unitMeasure);
|
||||
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
|
||||
|
||||
if (!bIsSettings)
|
||||
if (oItem != m_mUsedStyles.end())
|
||||
{
|
||||
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
|
||||
|
||||
if (oItem != m_mUsedStyles.end())
|
||||
{
|
||||
oStyle = oItem->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (NULL == m_mStatictics || m_mStatictics->empty())
|
||||
{
|
||||
oStyle.SetDpi(m_nDpi);
|
||||
oStyle.SetUnitMeasure(m_UnitMeasure);
|
||||
oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes));
|
||||
|
||||
return false;
|
||||
oStyle = oItem->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
oStyle.SetDpi(m_nDpi);
|
||||
oStyle.SetUnitMeasure(m_UnitMeasure);
|
||||
|
||||
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors);
|
||||
std::vector<std::wstring> arPrevNodes;
|
||||
@ -535,25 +679,10 @@ namespace NSCSS
|
||||
|
||||
oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1);
|
||||
|
||||
for (const CElement* oElement : FindElements(arNodes, arPrevNodes, bIsSettings))
|
||||
for (const CElement* oElement : FindElements(arNodes, arPrevNodes))
|
||||
oTempStyle.AddStyle(oElement->GetStyle(), i + 1);
|
||||
|
||||
if (NULL != m_mStatictics)
|
||||
{
|
||||
std::map<StatistickElement, unsigned int>::const_iterator oFindCountStyle = m_mStatictics->find(StatistickElement{StatistickElement::IsStyle, arSelectors[i].m_wsStyle});
|
||||
|
||||
if (oFindCountStyle != m_mStatictics->end())
|
||||
{
|
||||
if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) ||
|
||||
(!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions))
|
||||
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
else if (!bIsSettings)
|
||||
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
}
|
||||
else /*if (bIsSettings)*/
|
||||
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
}
|
||||
else
|
||||
if (!arSelectors[i].m_wsStyle.empty())
|
||||
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
|
||||
|
||||
oStyle += oTempStyle;
|
||||
@ -569,7 +698,7 @@ namespace NSCSS
|
||||
|
||||
oStyle.SetID(CalculateStyleId(arSelectors.back()));
|
||||
|
||||
if (!bIsSettings && !oStyle.Empty())
|
||||
if (!oStyle.Empty())
|
||||
m_mUsedStyles[arSelectors] = oStyle;
|
||||
|
||||
return true;
|
||||
@ -597,7 +726,7 @@ namespace NSCSS
|
||||
SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true);
|
||||
}
|
||||
|
||||
for (const CElement* oElement : FindElements(arNodes, arNextNodes, false))
|
||||
for (const CElement* oElement : FindElements(arNodes, arNextNodes))
|
||||
{
|
||||
std::map<std::wstring, std::wstring> mRules = oElement->GetStyle();
|
||||
if (mRules.end() != mRules.find(L"page"))
|
||||
@ -611,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)
|
||||
@ -654,32 +761,28 @@ namespace NSCSS
|
||||
m_nDpi = nValue;
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::SetBodyTree(const CTree &oTree)
|
||||
{
|
||||
if (NULL == m_mStatictics)
|
||||
m_mStatictics = new std::map<StatistickElement, unsigned int>();
|
||||
|
||||
CTree::CountingNumberRepetitions(oTree, *m_mStatictics);
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::SetUnitMeasure(const UnitMeasure& nType)
|
||||
{
|
||||
m_UnitMeasure = nType;
|
||||
}
|
||||
|
||||
unsigned short int CCssCalculator_Private::GetDpi() const
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
UnitMeasure CCssCalculator_Private::GetUnitMeasure() const
|
||||
void CCssCalculator_Private::ClearAllowedStyleFiles()
|
||||
{
|
||||
return m_UnitMeasure;
|
||||
m_oStyleStorage.ClearAllowedStyleFiles();
|
||||
}
|
||||
|
||||
void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath)
|
||||
{
|
||||
m_oStyleStorage.ClearStylesFromFile(wsFilePath);
|
||||
}
|
||||
|
||||
std::wstring CCssCalculator_Private::GetEncoding() const
|
||||
@ -691,12 +794,22 @@ namespace NSCSS
|
||||
{
|
||||
m_sEncoding = L"UTF-8";
|
||||
m_nDpi = 96;
|
||||
m_UnitMeasure = Point;
|
||||
|
||||
m_mData.clear();
|
||||
m_arFiles.clear();
|
||||
m_oStyleStorage.Clear();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
m_mUsedStyles.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
@ -797,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,16 +14,43 @@
|
||||
|
||||
namespace NSCSS
|
||||
{
|
||||
class CCssCalculator_Private
|
||||
class CStyleStorage
|
||||
{
|
||||
unsigned short int m_nDpi;
|
||||
unsigned short int m_nCountNodes;
|
||||
UnitMeasure m_UnitMeasure;
|
||||
public:
|
||||
CStyleStorage();
|
||||
~CStyleStorage();
|
||||
|
||||
std::list<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;
|
||||
@ -33,29 +58,14 @@ namespace NSCSS
|
||||
} TPageData;
|
||||
|
||||
std::vector<TPageData> m_arPageDatas;
|
||||
|
||||
std::map<StatistickElement, unsigned int> *m_mStatictics; // Количество повторений свойств id и style у селекторов
|
||||
|
||||
#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, bool bIsSettings);
|
||||
#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);
|
||||
|
||||
@ -65,36 +75,60 @@ 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();
|
||||
|
||||
#ifdef CSS_CALCULATOR_WITH_XHTML
|
||||
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
|
||||
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
|
||||
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors);
|
||||
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors);
|
||||
|
||||
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);
|
||||
|
||||
void SetUnitMeasure(const UnitMeasure& nType);
|
||||
void SetDpi(unsigned short int nValue);
|
||||
void SetBodyTree(const CTree &oTree);
|
||||
|
||||
UnitMeasure GetUnitMeasure() const;
|
||||
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();
|
||||
};
|
||||
}
|
||||
|
||||
@ -2,29 +2,6 @@
|
||||
|
||||
namespace NSCSS
|
||||
{
|
||||
bool StatistickElement::operator<(const StatistickElement &oStatistickElement) const
|
||||
{
|
||||
return sValue < oStatistickElement.sValue;
|
||||
}
|
||||
|
||||
void CTree::Clear()
|
||||
{
|
||||
m_arrChild.clear();
|
||||
m_oNode.Clear();
|
||||
}
|
||||
|
||||
void CTree::CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics)
|
||||
{
|
||||
if (!oTree.m_oNode.m_wsId.empty())
|
||||
++mStatictics[StatistickElement{StatistickElement::IsId, L'#' + oTree.m_oNode.m_wsId}];
|
||||
if (!oTree.m_oNode.m_wsStyle.empty())
|
||||
++mStatictics[StatistickElement{StatistickElement::IsStyle, oTree.m_oNode.m_wsStyle}];
|
||||
|
||||
if (!oTree.m_arrChild.empty())
|
||||
for (const CTree& oChildren : oTree.m_arrChild)
|
||||
CountingNumberRepetitions(oChildren, mStatictics);
|
||||
}
|
||||
|
||||
namespace NSConstValues
|
||||
{
|
||||
const std::map<std::wstring, std::wstring> COLORS
|
||||
|
||||
@ -16,28 +16,6 @@ namespace NSCSS
|
||||
ScalingDirectionY = 2
|
||||
} ScalingDirection;
|
||||
|
||||
struct StatistickElement
|
||||
{
|
||||
enum TypeElement
|
||||
{
|
||||
IsStyle = 0,
|
||||
IsId
|
||||
} m_enType;
|
||||
std::wstring sValue;
|
||||
|
||||
bool operator<(const StatistickElement& oStatistickElement) const;
|
||||
};
|
||||
|
||||
struct CTree
|
||||
{
|
||||
NSCSS::CNode m_oNode;
|
||||
std::vector<CTree> m_arrChild;
|
||||
|
||||
void Clear();
|
||||
|
||||
static void CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics);
|
||||
};
|
||||
|
||||
namespace NSConstValues
|
||||
{
|
||||
extern const std::map<std::wstring, std::wstring> COLORS;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -513,6 +513,9 @@ namespace NSCSS
|
||||
return (*static_cast<std::wstring*>(m_oValue)) == (*static_cast<std::wstring*>(oColor.m_oValue));
|
||||
case ColorUrl:
|
||||
return (*static_cast<CURL*>(m_oValue)) == (*static_cast<CURL*>(oColor.m_oValue));
|
||||
case ColorContextStroke:
|
||||
case ColorContextFill:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,6 +535,9 @@ namespace NSCSS
|
||||
return (*static_cast<std::wstring*>(m_oValue)) != (*static_cast<std::wstring*>(oColor.m_oValue));
|
||||
case ColorUrl:
|
||||
return (*static_cast<CURL*>(m_oValue)) != (*static_cast<CURL*>(oColor.m_oValue));
|
||||
case ColorContextStroke:
|
||||
case ColorContextFill:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,6 +567,9 @@ namespace NSCSS
|
||||
m_oValue = new CURL(*static_cast<CURL*>(oColor.m_oValue));
|
||||
break;
|
||||
}
|
||||
case ColorContextStroke:
|
||||
case ColorContextFill:
|
||||
break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
@ -580,6 +589,39 @@ namespace NSCSS
|
||||
: CValue(NULL, 0, false), m_oOpacity(1.), m_enType(ColorEmpty)
|
||||
{}
|
||||
|
||||
CColor::CColor(const CColor& oColor)
|
||||
: CValue(NULL, 0, false), m_oOpacity(oColor.m_oOpacity), m_enType(oColor.m_enType)
|
||||
{
|
||||
switch (m_enType)
|
||||
{
|
||||
case ColorRGB:
|
||||
{
|
||||
TRGB *pRGB = static_cast<TRGB*>(oColor.m_oValue);
|
||||
m_oValue = new TRGB(*pRGB);
|
||||
break;
|
||||
}
|
||||
case ColorHEX:
|
||||
{
|
||||
std::wstring* pValue = static_cast<std::wstring*>(oColor.m_oValue);
|
||||
m_oValue = new std::wstring(*pValue);
|
||||
break;
|
||||
}
|
||||
case ColorUrl:
|
||||
{
|
||||
CURL *pURL = static_cast<CURL*>(oColor.m_oValue);
|
||||
m_oValue = new CURL(*pURL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CColor::~CColor()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CColor::SetEmpty(unsigned int unLevel)
|
||||
{
|
||||
Clear();
|
||||
@ -875,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())
|
||||
|
||||
@ -224,6 +224,8 @@ namespace NSCSS
|
||||
{
|
||||
public:
|
||||
CColor();
|
||||
CColor(const CColor& oColor);
|
||||
~CColor();
|
||||
|
||||
bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override;
|
||||
bool SetOpacity(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true);
|
||||
@ -240,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");
|
||||
|
||||
@ -905,6 +905,10 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName)
|
||||
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
|
||||
else if (0 == sExt.compare(L".key"))
|
||||
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
|
||||
else if (0 == sExt.compare(L".hwp"))
|
||||
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP;
|
||||
else if (0 == sExt.compare(L".hwpx"))
|
||||
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX;
|
||||
|
||||
if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN)
|
||||
return true;
|
||||
@ -1371,6 +1375,7 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type)
|
||||
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM:
|
||||
return L".dotm";
|
||||
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC:
|
||||
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT:
|
||||
return L".doc";
|
||||
case AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT:
|
||||
return L".odt";
|
||||
|
||||
@ -57,6 +57,8 @@
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0016
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0017
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0018
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0019
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0020
|
||||
|
||||
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_XML AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0030
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#define LOG_BUFFER_SIZE 1000
|
||||
|
||||
// not intended for use in production. only for testing/debugging purposes
|
||||
namespace Logging
|
||||
{
|
||||
void logBytes(char* name, unsigned char* str, int len)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -296,7 +304,7 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
|
||||
else if (1 == m_nFileType)
|
||||
pNative->m_strEditorType = L"presentation";
|
||||
else if (7 == m_nFileType)
|
||||
pNative->m_strEditorType = L"draw";
|
||||
pNative->m_strEditorType = L"visio";
|
||||
else
|
||||
pNative->m_strEditorType = L"spreadsheet";
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -986,7 +986,7 @@ namespace NSDoctRenderer
|
||||
case DoctRendererFormat::IMAGE:
|
||||
{
|
||||
editorType = NSDoctRenderer::DoctRendererEditorType::VISIO;
|
||||
m_pInternal->m_strEditorType = L"draw";
|
||||
m_pInternal->m_strEditorType = L"visio";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@ -121,7 +121,7 @@ drawingfile_support {
|
||||
embed/DrawingFileEmbed.h
|
||||
|
||||
SOURCES += \
|
||||
../../HtmlRenderer/src/HTMLRendererText.cpp \
|
||||
../graphics/pro/js/wasm/src/HTMLRendererText.cpp \
|
||||
embed/DrawingFileEmbed.cpp
|
||||
|
||||
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/DrawingFileEmbed.h)
|
||||
|
||||
@ -38,8 +38,8 @@
|
||||
#include "../../PdfFile/PdfFile.h"
|
||||
#include "../../XpsFile/XpsFile.h"
|
||||
#include "../../DjVuFile/DjVu.h"
|
||||
#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
|
||||
#include "../../HtmlRenderer/include/HTMLRendererText.h"
|
||||
#include "../graphics/pro/js/wasm/src/serialize.h"
|
||||
#include "../graphics/pro/js/wasm/src/HTMLRendererText.h"
|
||||
#include "../../DocxRenderer/DocxRenderer.h"
|
||||
|
||||
#define CHECKER_FILE_BUFFER_LEN 4096
|
||||
|
||||
@ -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)
|
||||
@ -100,12 +109,12 @@ namespace NSDoctRenderer
|
||||
}
|
||||
case DoctRendererEditorType::VISIO:
|
||||
{
|
||||
if (!NSFile::CFileBinary::Exists(config->m_strSdkPath + L"/draw/sdk-all-min.js"))
|
||||
if (!NSFile::CFileBinary::Exists(config->m_strSdkPath + L"/visio/sdk-all-min.js"))
|
||||
return L"";
|
||||
AppendScript(builder, config->m_strSdkPath + L"/draw/sdk-all-min.js");
|
||||
AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all-min.js");
|
||||
AppendScript(builder, sFontsPath);
|
||||
AppendScript(builder, config->m_strSdkPath + L"/draw/sdk-all.js");
|
||||
sCachePath = config->m_strSdkPath + L"/draw/sdk-all";
|
||||
AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all.js");
|
||||
sCachePath = config->m_strSdkPath + L"/visio/sdk-all";
|
||||
break;
|
||||
}
|
||||
case DoctRendererEditorType::PDF:
|
||||
@ -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;
|
||||
}
|
||||
@ -147,7 +157,7 @@ namespace NSDoctRenderer
|
||||
}
|
||||
case DoctRendererEditorType::VISIO:
|
||||
{
|
||||
return config->m_strSdkPath + L"/draw/sdk-all.bin";
|
||||
return config->m_strSdkPath + L"/visio/sdk-all.bin";
|
||||
}
|
||||
case DoctRendererEditorType::PDF:
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "DrawingFileEmbed.h"
|
||||
#include "../drawingfile.h"
|
||||
#include "../../raster/BgraFrame.h"
|
||||
|
||||
JSSmart<CJSValue> WasmMemoryToJS(BYTE* pWasmData)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -191,6 +191,16 @@ namespace Aggplus
|
||||
{
|
||||
}
|
||||
|
||||
CClipMulti::clip_rasterizer* CClipMulti::GetRasterizer()
|
||||
{
|
||||
if (!m_bIsClip)
|
||||
{
|
||||
m_rasterizer.reset();
|
||||
return &m_rasterizer;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CClipMulti::Create(LONG width, LONG height)
|
||||
{
|
||||
m_lWidth = width;
|
||||
@ -212,62 +222,52 @@ namespace Aggplus
|
||||
|
||||
typedef agg::conv_curve<trans_type> conv_crv_type;
|
||||
conv_crv_type c_c_path(trans);
|
||||
|
||||
|
||||
m_rasterizer.add_path(c_c_path);
|
||||
m_rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
|
||||
GenerateClip2(pPath->m_internal->m_bEvenOdd);
|
||||
}
|
||||
|
||||
void CClipMulti::GenerateClip2(bool bEvenOdd)
|
||||
{
|
||||
m_rasterizer.filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
|
||||
m_bIsClip = true;
|
||||
m_bIsClip2 = false;
|
||||
}
|
||||
|
||||
void CClipMulti::Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op)
|
||||
void CClipMulti::Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer)
|
||||
{
|
||||
if (!pRasterizer)
|
||||
return;
|
||||
|
||||
if (!m_bIsClip)
|
||||
return GenerateClip(pPath, pMatrix);
|
||||
return GenerateClip2(bEvenOdd);
|
||||
|
||||
if (!m_bIsClip2)
|
||||
{
|
||||
// смешивать надо с растерайзером
|
||||
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
|
||||
rasterizer.clip_box(0, 0, m_lWidth, m_lHeight);
|
||||
|
||||
typedef agg::conv_transform<agg::path_storage> trans_type;
|
||||
trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx);
|
||||
|
||||
typedef agg::conv_curve<trans_type> conv_crv_type;
|
||||
conv_crv_type c_c_path(trans);
|
||||
|
||||
rasterizer.add_path(c_c_path);
|
||||
rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
|
||||
scanline_type sl1;
|
||||
scanline_type sl2;
|
||||
scanline_type sl;
|
||||
|
||||
agg::sbool_combine_shapes_aa(op, m_rasterizer, rasterizer, sl1, sl2, sl, m_storage1);
|
||||
agg::sbool_combine_shapes_aa(op, m_rasterizer, *pRasterizer, sl1, sl2, sl, m_storage1);
|
||||
|
||||
m_lCurStorage = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// надо смешивать со стораджем
|
||||
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
|
||||
rasterizer.clip_box(0, 0, m_lWidth, m_lHeight);
|
||||
|
||||
typedef agg::conv_transform<agg::path_storage> trans_type;
|
||||
trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx);
|
||||
|
||||
typedef agg::conv_curve<trans_type> conv_crv_type;
|
||||
conv_crv_type c_c_path(trans);
|
||||
|
||||
rasterizer.add_path(c_c_path);
|
||||
rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
pRasterizer->filling_rule(op ? agg::fill_even_odd : agg::fill_non_zero);
|
||||
|
||||
scanline_type sl1;
|
||||
scanline_type sl2;
|
||||
scanline_type sl;
|
||||
|
||||
agg::sbool_combine_shapes_aa(op, rasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
|
||||
agg::sbool_combine_shapes_aa(op, *pRasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
|
||||
(m_lCurStorage == 1) ? m_storage2 : m_storage1);
|
||||
|
||||
if (1 == m_lCurStorage)
|
||||
|
||||
@ -138,10 +138,11 @@ public:
|
||||
|
||||
class CClipMulti
|
||||
{
|
||||
typedef agg::scanline_p8 scanline_type;
|
||||
|
||||
public:
|
||||
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> m_rasterizer;
|
||||
typedef agg::scanline_p8 scanline_type;
|
||||
typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> clip_rasterizer;
|
||||
|
||||
clip_rasterizer m_rasterizer;
|
||||
|
||||
agg::scanline_storage_aa8 m_storage1;
|
||||
agg::scanline_storage_aa8 m_storage2;
|
||||
@ -158,10 +159,13 @@ public:
|
||||
CClipMulti();
|
||||
~CClipMulti();
|
||||
|
||||
clip_rasterizer* GetRasterizer();
|
||||
|
||||
void Create(LONG width, LONG height);
|
||||
void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix);
|
||||
void GenerateClip2(bool bEvenOdd);
|
||||
|
||||
void Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op);
|
||||
void Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer);
|
||||
|
||||
bool IsClip();
|
||||
bool IsClip2();
|
||||
|
||||
@ -502,18 +502,41 @@ namespace Aggplus
|
||||
return Ok;
|
||||
}
|
||||
|
||||
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op)
|
||||
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen)
|
||||
{
|
||||
Aggplus::CMatrix m;
|
||||
return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op);
|
||||
return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op, pPen);
|
||||
}
|
||||
|
||||
Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op)
|
||||
Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen)
|
||||
{
|
||||
if (NULL == pPath)
|
||||
return InvalidParameter;
|
||||
|
||||
m_oClip.Combine(pPath, pTransform, op);
|
||||
bool bTempRasterizer = false;
|
||||
CClipMulti::clip_rasterizer* pRasterizer = m_oClip.GetRasterizer();
|
||||
if (!pRasterizer)
|
||||
{
|
||||
pRasterizer = new CClipMulti::clip_rasterizer();
|
||||
pRasterizer->clip_box(0, 0, m_oClip.m_lWidth, m_oClip.m_lHeight);
|
||||
bTempRasterizer = true;
|
||||
}
|
||||
|
||||
agg::trans_affine* pAffine = NULL;
|
||||
if (pPen)
|
||||
pAffine = DoStrokePath(pPen, pPath, pRasterizer);
|
||||
else
|
||||
{
|
||||
typedef agg::conv_transform<agg::path_storage> trans_type;
|
||||
trans_type trans(pPath->m_internal->m_agg_ps, pTransform->m_internal->m_agg_mtx);
|
||||
|
||||
typedef agg::conv_curve<trans_type> conv_crv_type;
|
||||
conv_crv_type c_c_path(trans);
|
||||
|
||||
pRasterizer->add_path(c_c_path);
|
||||
}
|
||||
|
||||
m_oClip.Combine(pPath->m_internal->m_bEvenOdd, op, pRasterizer);
|
||||
|
||||
// write to clips history
|
||||
CGraphics_ClipStateRecord* pRecord = new CGraphics_ClipStateRecord();
|
||||
@ -522,6 +545,11 @@ namespace Aggplus
|
||||
pRecord->Operation = op;
|
||||
m_oClipState.AddRecord(pRecord);
|
||||
|
||||
if (pAffine)
|
||||
delete pAffine;
|
||||
if (bTempRasterizer)
|
||||
delete pRasterizer;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
@ -610,180 +638,7 @@ namespace Aggplus
|
||||
|
||||
m_rasterizer.get_rasterizer().reset();
|
||||
|
||||
agg::line_join_e LineJoin = agg::round_join;
|
||||
switch(pPen->LineJoin)
|
||||
{
|
||||
case LineJoinMiter : LineJoin = agg::miter_join_revert; break;
|
||||
case LineJoinBevel : LineJoin = agg::bevel_join; break;
|
||||
case LineJoinRound : LineJoin = agg::round_join; break;
|
||||
case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break;
|
||||
default: break;
|
||||
}
|
||||
agg::line_cap_e LineCap = agg::round_cap;
|
||||
switch(pPen->LineStartCap)
|
||||
{
|
||||
case LineCapFlat : LineCap = agg::butt_cap; break;
|
||||
case LineCapRound : LineCap = agg::round_cap; break;
|
||||
case LineCapSquare : LineCap = agg::square_cap; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
double dWidth = pPen->Size;
|
||||
if (!m_bIntegerGrid && m_bIs0PenWidthAs1px)
|
||||
{
|
||||
double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant()));
|
||||
if (0 == dWidth)
|
||||
{
|
||||
double dX = 0.72, dY = 0.72;
|
||||
agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx;
|
||||
invert.transform_2x2(&dX, &dY);
|
||||
dWidth = std::min(abs(dX), abs(dY));
|
||||
}
|
||||
else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet))
|
||||
dWidth = dWidthMinSize;
|
||||
}
|
||||
|
||||
double dblMiterLimit = pPen->MiterLimit;
|
||||
|
||||
agg::path_storage path_copy(pPath->m_internal->m_agg_ps);
|
||||
bool bIsUseIdentity = m_bIntegerGrid;
|
||||
if (!bIsUseIdentity)
|
||||
{
|
||||
agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx;
|
||||
double dDet = full_trans->determinant();
|
||||
|
||||
if (fabs(dDet) < 0.0001)
|
||||
{
|
||||
path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx);
|
||||
dWidth *= sqrt(fabs(dDet));
|
||||
|
||||
bIsUseIdentity = true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
|
||||
|
||||
conv_crv_type c_c_path(path_copy);
|
||||
c_c_path.approximation_scale(25.0);
|
||||
c_c_path.approximation_method(agg::curve_inc);
|
||||
DashStyle eStyle = (DashStyle)pPen->DashStyle;
|
||||
|
||||
if (DashStyleCustom == eStyle)
|
||||
{
|
||||
if (0 == pPen->Count || NULL == pPen->DashPattern)
|
||||
{
|
||||
eStyle = DashStyleSolid;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bFoundNormal = false;
|
||||
for (int i = 0; i < pPen->Count; i++)
|
||||
{
|
||||
if (fabs(pPen->DashPattern[i]) > 0.0001)
|
||||
{
|
||||
bFoundNormal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFoundNormal)
|
||||
eStyle = DashStyleSolid;
|
||||
}
|
||||
}
|
||||
|
||||
agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx;
|
||||
if (bIsUseIdentity)
|
||||
pAffine = new agg::trans_affine();
|
||||
|
||||
if (DashStyleSolid == eStyle)
|
||||
{
|
||||
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
|
||||
Path_Conv_StrokeN pgN(c_c_path);
|
||||
|
||||
//pgN.line_join(agg::miter_join_revert);
|
||||
|
||||
pgN.line_cap(LineCap);
|
||||
|
||||
pgN.line_join(LineJoin);
|
||||
pgN.inner_join(agg::inner_round);
|
||||
|
||||
pgN.miter_limit(dblMiterLimit);
|
||||
pgN.width(dWidth);
|
||||
|
||||
pgN.approximation_scale(25.0);
|
||||
|
||||
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
|
||||
|
||||
transStroke trans(pgN, *pAffine);
|
||||
m_rasterizer.get_rasterizer().add_path(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
|
||||
Path_Conv_Dash poly2_dash(c_c_path);
|
||||
|
||||
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
|
||||
Path_Conv_StrokeD pgD(poly2_dash);
|
||||
|
||||
switch (eStyle)
|
||||
{
|
||||
case DashStyleDash:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDot:
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDashDot:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDashDotDot:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
default:
|
||||
case DashStyleCustom:
|
||||
{
|
||||
double offset = pPen->DashOffset;
|
||||
double* params = pPen->DashPattern;
|
||||
LONG lCount = pPen->Count;
|
||||
LONG lCount2 = lCount / 2;
|
||||
|
||||
double dKoef = 1.0;
|
||||
|
||||
for (LONG i = 0; i < lCount2; ++i)
|
||||
{
|
||||
if (0 == i)
|
||||
{
|
||||
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
|
||||
}
|
||||
else
|
||||
{
|
||||
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
|
||||
}
|
||||
}
|
||||
if (1 == (lCount % 2))
|
||||
{
|
||||
poly2_dash.add_dash(params[lCount - 1] * dKoef, 0);
|
||||
}
|
||||
poly2_dash.dash_start(offset * dKoef);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant()));
|
||||
if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize)
|
||||
dWidth = dWidthMinSize;
|
||||
|
||||
pgD.line_cap(LineCap);
|
||||
pgD.line_join(LineJoin);
|
||||
pgD.miter_limit(dblMiterLimit);
|
||||
pgD.width(dWidth);
|
||||
|
||||
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, *pAffine);
|
||||
m_rasterizer.get_rasterizer().add_path(trans);
|
||||
}
|
||||
agg::trans_affine* pAffine = DoStrokePath(pPen, pPath, &m_rasterizer.get_rasterizer());
|
||||
|
||||
CColor oColor((BYTE)(pPen->Alpha * m_dGlobalAlpha), pPen->Color, m_bSwapRGB);
|
||||
CBrushSolid oBrush(oColor);
|
||||
@ -798,8 +653,7 @@ namespace Aggplus
|
||||
if (gamma >= 0)
|
||||
m_rasterizer.gamma(1.0);
|
||||
|
||||
if (bIsUseIdentity)
|
||||
RELEASEOBJECT(pAffine);
|
||||
RELEASEOBJECT(pAffine);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
@ -2243,6 +2097,186 @@ namespace Aggplus
|
||||
break;
|
||||
}
|
||||
}
|
||||
template<class Rasterizer>
|
||||
agg::trans_affine* CGraphics::DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* pRasterizer)
|
||||
{
|
||||
agg::line_join_e LineJoin = agg::round_join;
|
||||
switch(pPen->LineJoin)
|
||||
{
|
||||
case LineJoinMiter : LineJoin = agg::miter_join_revert; break;
|
||||
case LineJoinBevel : LineJoin = agg::bevel_join; break;
|
||||
case LineJoinRound : LineJoin = agg::round_join; break;
|
||||
case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break;
|
||||
default: break;
|
||||
}
|
||||
agg::line_cap_e LineCap = agg::round_cap;
|
||||
switch(pPen->LineStartCap)
|
||||
{
|
||||
case LineCapFlat : LineCap = agg::butt_cap; break;
|
||||
case LineCapRound : LineCap = agg::round_cap; break;
|
||||
case LineCapSquare : LineCap = agg::square_cap; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
double dWidth = pPen->Size;
|
||||
if (!m_bIntegerGrid && m_bIs0PenWidthAs1px)
|
||||
{
|
||||
double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant()));
|
||||
if (0 == dWidth)
|
||||
{
|
||||
double dX = 0.72, dY = 0.72;
|
||||
agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx;
|
||||
invert.transform_2x2(&dX, &dY);
|
||||
dWidth = std::min(abs(dX), abs(dY));
|
||||
}
|
||||
else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet))
|
||||
dWidth = dWidthMinSize;
|
||||
}
|
||||
|
||||
double dblMiterLimit = pPen->MiterLimit;
|
||||
|
||||
agg::path_storage path_copy(pPath->m_internal->m_agg_ps);
|
||||
bool bIsUseIdentity = m_bIntegerGrid;
|
||||
if (!bIsUseIdentity)
|
||||
{
|
||||
agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx;
|
||||
double dDet = full_trans->determinant();
|
||||
|
||||
if (fabs(dDet) < 0.0001)
|
||||
{
|
||||
path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx);
|
||||
dWidth *= sqrt(fabs(dDet));
|
||||
|
||||
bIsUseIdentity = true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
|
||||
|
||||
conv_crv_type c_c_path(path_copy);
|
||||
c_c_path.approximation_scale(25.0);
|
||||
c_c_path.approximation_method(agg::curve_inc);
|
||||
DashStyle eStyle = (DashStyle)pPen->DashStyle;
|
||||
|
||||
if (DashStyleCustom == eStyle)
|
||||
{
|
||||
if (0 == pPen->Count || NULL == pPen->DashPattern)
|
||||
{
|
||||
eStyle = DashStyleSolid;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bFoundNormal = false;
|
||||
for (int i = 0; i < pPen->Count; i++)
|
||||
{
|
||||
if (fabs(pPen->DashPattern[i]) > 0.0001)
|
||||
{
|
||||
bFoundNormal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFoundNormal)
|
||||
eStyle = DashStyleSolid;
|
||||
}
|
||||
}
|
||||
|
||||
agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx;
|
||||
if (bIsUseIdentity)
|
||||
pAffine = new agg::trans_affine();
|
||||
|
||||
if (DashStyleSolid == eStyle)
|
||||
{
|
||||
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
|
||||
Path_Conv_StrokeN pgN(c_c_path);
|
||||
|
||||
//pgN.line_join(agg::miter_join_revert);
|
||||
|
||||
pgN.line_cap(LineCap);
|
||||
|
||||
pgN.line_join(LineJoin);
|
||||
pgN.inner_join(agg::inner_round);
|
||||
|
||||
pgN.miter_limit(dblMiterLimit);
|
||||
pgN.width(dWidth);
|
||||
|
||||
pgN.approximation_scale(25.0);
|
||||
|
||||
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
|
||||
|
||||
transStroke trans(pgN, *pAffine);
|
||||
pRasterizer->add_path(trans);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
|
||||
Path_Conv_Dash poly2_dash(c_c_path);
|
||||
|
||||
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
|
||||
Path_Conv_StrokeD pgD(poly2_dash);
|
||||
|
||||
switch (eStyle)
|
||||
{
|
||||
case DashStyleDash:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDot:
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDashDot:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
case DashStyleDashDotDot:
|
||||
poly2_dash.add_dash(3.00*dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
poly2_dash.add_dash(dWidth, dWidth);
|
||||
break;
|
||||
default:
|
||||
case DashStyleCustom:
|
||||
{
|
||||
double offset = pPen->DashOffset;
|
||||
double* params = pPen->DashPattern;
|
||||
LONG lCount = pPen->Count;
|
||||
LONG lCount2 = lCount / 2;
|
||||
|
||||
double dKoef = 1.0;
|
||||
|
||||
for (LONG i = 0; i < lCount2; ++i)
|
||||
{
|
||||
if (0 == i)
|
||||
{
|
||||
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
|
||||
}
|
||||
else
|
||||
{
|
||||
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
|
||||
}
|
||||
}
|
||||
if (1 == (lCount % 2))
|
||||
{
|
||||
poly2_dash.add_dash(params[lCount - 1] * dKoef, 0);
|
||||
}
|
||||
poly2_dash.dash_start(offset * dKoef);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant()));
|
||||
if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize)
|
||||
dWidth = dWidthMinSize;
|
||||
|
||||
pgD.line_cap(LineCap);
|
||||
pgD.line_join(LineJoin);
|
||||
pgD.miter_limit(dblMiterLimit);
|
||||
pgD.width(dWidth);
|
||||
|
||||
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, *pAffine);
|
||||
pRasterizer->add_path(trans);
|
||||
}
|
||||
|
||||
return bIsUseIdentity ? pAffine : NULL;
|
||||
}
|
||||
// text methods
|
||||
int CGraphics::FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush)
|
||||
{
|
||||
|
||||
@ -360,8 +360,8 @@ public:
|
||||
Status SetClip(CGraphicsPath* pPath);
|
||||
Status ResetClip();
|
||||
Status ExclugeClip(CGraphicsPath* pPath);
|
||||
Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op);
|
||||
Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op);
|
||||
Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL);
|
||||
Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL);
|
||||
|
||||
// измерение текста
|
||||
INT MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight);
|
||||
@ -453,6 +453,8 @@ protected:
|
||||
void DoFillPathTextureClampSz3(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha = 255);
|
||||
|
||||
void DoFillPath(const CBrush* Brush);
|
||||
template<class Rasterizer>
|
||||
agg::trans_affine* DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* ras);
|
||||
|
||||
// text methods
|
||||
int FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush);
|
||||
|
||||
@ -822,7 +822,8 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType)
|
||||
m_pPath->SetRuler(bIsIn ? false : true);
|
||||
|
||||
INT bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode));
|
||||
m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or);
|
||||
INT bIsStrokePath = (c_nClipToStrokePath == (0x0010 & m_lCurrentClipMode));
|
||||
m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or, bIsStrokePath ? &m_oPen : NULL);
|
||||
|
||||
//m_pRenderer->SetClip(m_pPath);
|
||||
break;
|
||||
|
||||
@ -96,6 +96,9 @@ const long c_nBaselineShift = 0xa041;
|
||||
// типы клипа
|
||||
const long c_nClipRegionTypeWinding = 0x0000;
|
||||
const long c_nClipRegionTypeEvenOdd = 0x0001;
|
||||
// тип преобразования пути для клипов
|
||||
const long c_nClipToPath = 0x0000;
|
||||
const long c_nClipToStrokePath = 0x0010;
|
||||
// тип объединения клипов
|
||||
const long c_nClipRegionIntersect = 0x0000;
|
||||
const long c_nClipRegionUnion = 0x0100;
|
||||
|
||||
@ -312,14 +312,14 @@ namespace Aggplus
|
||||
agg::trans_affine& m1 = mm1->m_internal->m_agg_mtx;
|
||||
agg::trans_affine& m2 = mm2->m_internal->m_agg_mtx;
|
||||
|
||||
bool bMain = (fabs(m1.sx - m2.sx) < eps &&
|
||||
fabs(m1.sy - m2.sy) < eps &&
|
||||
fabs(m1.shx - m2.shx) < eps &&
|
||||
fabs(m1.shy - m2.shy) < eps) ? true : false;
|
||||
bool bMain = fabs(m1.sx - m2.sx) < eps &&
|
||||
fabs(m1.sy - m2.sy) < eps &&
|
||||
fabs(m1.shx - m2.shx) < eps &&
|
||||
fabs(m1.shy - m2.shy) < eps;
|
||||
|
||||
if (!bMain || bIsOnlyMain)
|
||||
return bMain;
|
||||
|
||||
return (fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps) ? true : false;
|
||||
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -645,12 +645,17 @@ void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
|
||||
m_nSy = pReader->ReadByte();
|
||||
}
|
||||
|
||||
int CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; }
|
||||
double CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; }
|
||||
const std::wstring& CAnnotFieldInfo::CStampAnnotPr::GetName() { return m_wsName; }
|
||||
void CAnnotFieldInfo::CStampAnnotPr::GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dInRect[0]; dRD2 = m_dInRect[1]; dRD3 = m_dInRect[2]; dRD4 = m_dInRect[3]; }
|
||||
void CAnnotFieldInfo::CStampAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
|
||||
{
|
||||
m_wsName = pReader->ReadString();
|
||||
m_nRotate = pReader->ReadInt();
|
||||
m_nRotate = pReader->ReadDouble();
|
||||
m_dInRect[0] = pReader->ReadDouble();
|
||||
m_dInRect[1] = pReader->ReadDouble();
|
||||
m_dInRect[2] = pReader->ReadDouble();
|
||||
m_dInRect[3] = pReader->ReadDouble();
|
||||
}
|
||||
|
||||
bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; }
|
||||
|
||||
@ -408,14 +408,16 @@ public:
|
||||
class GRAPHICS_DECL CStampAnnotPr
|
||||
{
|
||||
public:
|
||||
int GetRotate();
|
||||
double GetRotate();
|
||||
const std::wstring& GetName();
|
||||
void GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4);
|
||||
|
||||
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
|
||||
|
||||
private:
|
||||
int m_nRotate;
|
||||
double m_nRotate;
|
||||
std::wstring m_wsName;
|
||||
double m_dInRect[4]{};
|
||||
};
|
||||
|
||||
CAnnotFieldInfo();
|
||||
|
||||
@ -123,6 +123,7 @@ namespace MetaFile
|
||||
|
||||
virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0;
|
||||
virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0;
|
||||
virtual bool LoadFromString(const std::wstring& data) = 0;
|
||||
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0;
|
||||
virtual void Close() = 0;
|
||||
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) = 0;
|
||||
@ -131,6 +132,7 @@ namespace MetaFile
|
||||
virtual NSFonts::IFontManager* get_FontManager() = 0;
|
||||
|
||||
virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) = 0;
|
||||
virtual void SetTempDirectory(const std::wstring& dir) = 0;
|
||||
|
||||
//Для тестов
|
||||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||||
|
||||
@ -135,7 +135,7 @@
|
||||
},
|
||||
{
|
||||
"folder": "./wasm/src/",
|
||||
"files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp"]
|
||||
"files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp", "HTMLRendererText.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "freetype-2.10.4/src/",
|
||||
@ -201,10 +201,6 @@
|
||||
"folder": "../",
|
||||
"files": ["officedrawingfile.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "../../../../HtmlRenderer/src/",
|
||||
"files": ["HTMLRendererText.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "../../../../UnicodeConverter/",
|
||||
"files": ["UnicodeConverter.cpp"]
|
||||
@ -227,7 +223,7 @@
|
||||
},
|
||||
{
|
||||
"folder": "../../../../DocxRenderer/src/logic/elements",
|
||||
"files": ["BaseItem.cpp", "ContText.cpp", "DropCap.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp"]
|
||||
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"]
|
||||
},
|
||||
{
|
||||
"folder": "../../../common",
|
||||
|
||||
@ -19,7 +19,7 @@ include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
|
||||
include(../../freetype.pri)
|
||||
|
||||
ADD_DEPENDENCY(UnicodeConverter, kernel, HtmlRenderer)
|
||||
ADD_DEPENDENCY(UnicodeConverter, kernel)
|
||||
|
||||
INCLUDEPATH += \
|
||||
$$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \
|
||||
@ -704,7 +704,6 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \
|
||||
@ -720,14 +719,15 @@ SOURCES += \
|
||||
$$DOCX_RENDERER_ROOT_DIR/DocxRenderer.cpp \
|
||||
$$DOCX_RENDERER_ROOT_DIR/src/resources/resources.cpp
|
||||
|
||||
HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h
|
||||
SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp
|
||||
HEADERS += $$CORE_ROOT_DIR/DesktopEditor/doctrenderer/drawingfile.h
|
||||
|
||||
HEADERS += \
|
||||
../wasm/src/drawingfile.h \
|
||||
../wasm/src/serialize.h
|
||||
../wasm/src/serialize.h \
|
||||
../wasm/src/HTMLRendererText.h \
|
||||
../wasm/src/Text.h
|
||||
|
||||
SOURCES += \
|
||||
../wasm/src/pdfwriter.cpp \
|
||||
../wasm/src/HTMLRendererText.cpp \
|
||||
../wasm/src/drawingfile.cpp \
|
||||
../wasm/src/drawingfile_test.cpp
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
* (c) Copyright Ascensio System SIA 2010-2024
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -68,16 +68,6 @@ CFile.prototype.unlockPageNumForFontsLoader = function()
|
||||
drawingFile.fontPageUpdateType = UpdateFontsSource.Undefined;
|
||||
};
|
||||
|
||||
CFile.prototype.getOriginPage = function(originIndex)
|
||||
{
|
||||
for (let i = 0; i < this.pages.length; ++i)
|
||||
{
|
||||
if (this.pages[i]["originIndex"] == originIndex)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
CFile.prototype["getPages"] = function()
|
||||
{
|
||||
return this.pages;
|
||||
@ -241,18 +231,17 @@ CFile.prototype["getLinks"] = function(pageIndex)
|
||||
// TEXT
|
||||
CFile.prototype["getGlyphs"] = function(pageIndex)
|
||||
{
|
||||
let i = this.getOriginPage(pageIndex);
|
||||
if (i < 0)
|
||||
return null;
|
||||
let page = this.pages[i];
|
||||
if (!page || page.fonts.length > 0)
|
||||
let page = this.pages[pageIndex];
|
||||
if (page.originIndex == undefined)
|
||||
return [];
|
||||
if (page.fonts.length > 0)
|
||||
{
|
||||
// waiting fonts
|
||||
return null;
|
||||
}
|
||||
|
||||
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
|
||||
let res = this._getGlyphs(pageIndex);
|
||||
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
|
||||
let res = this._getGlyphs(page.originIndex);
|
||||
// there is no need to delete the result; this buffer is used as a text buffer
|
||||
// for text commands on other pages. After receiving ALL text pages,
|
||||
// you need to call destroyTextInfo()
|
||||
@ -1290,7 +1279,7 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex)
|
||||
else if (rec["Type"] == 12)
|
||||
{
|
||||
rec["Icon"] = reader.readString();
|
||||
rec["Rotate"] = reader.readInt();
|
||||
rec["Rotate"] = reader.readDouble2();
|
||||
rec["InRect"] = [];
|
||||
for (let i = 0; i < 8; ++i)
|
||||
rec["InRect"].push(reader.readDouble2());
|
||||
@ -1391,18 +1380,17 @@ CFile.prototype["free"] = function(pointer)
|
||||
// PIXMAP
|
||||
CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor)
|
||||
{
|
||||
let i = this.getOriginPage(pageIndex);
|
||||
if (i < 0)
|
||||
let page = this.pages[pageIndex];
|
||||
if (page.originIndex == undefined)
|
||||
return null;
|
||||
let page = this.pages[i];
|
||||
if (!page || page.fonts.length > 0)
|
||||
if (page.fonts.length > 0)
|
||||
{
|
||||
// waiting fonts
|
||||
return null;
|
||||
}
|
||||
|
||||
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
|
||||
let ptr = this._getPixmap(pageIndex, width, height, backgroundColor);
|
||||
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
|
||||
let ptr = this._getPixmap(page.originIndex, width, height, backgroundColor);
|
||||
this.unlockPageNumForFontsLoader();
|
||||
|
||||
if (page.fonts.length > 0)
|
||||
|
||||
@ -29,8 +29,8 @@
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#include "../include/HTMLRendererText.h"
|
||||
#include "./Text.h"
|
||||
#include "HTMLRendererText.h"
|
||||
#include "Text.h"
|
||||
|
||||
namespace NSHtmlRenderer
|
||||
{
|
||||
@ -40,52 +40,35 @@ namespace NSHtmlRenderer
|
||||
double m_dWidth;
|
||||
double m_dHeght;
|
||||
|
||||
NSStructures::CBrush m_oBrush;
|
||||
NSStructures::CBrush m_oLastBrush;
|
||||
|
||||
NSStructures::CFont m_oFont;
|
||||
NSStructures::CFont* m_pFont;
|
||||
NSStructures::CFont m_oInstalledFont;
|
||||
LONG m_lCurrentFont;
|
||||
double m_dCurrentFontSize;
|
||||
|
||||
Aggplus::CMatrix m_oTransform;
|
||||
Aggplus::CMatrix m_oLastTransform;
|
||||
|
||||
bool m_bIsChangedFontParamBetweenDrawText;
|
||||
LONG m_lCurrentCommandType;
|
||||
LONG m_lSrcFileType;
|
||||
|
||||
CHText m_oSmartText;
|
||||
CMetafile m_oPage;
|
||||
NSWasm::CData m_oPage;
|
||||
|
||||
int* m_pTempUnicodes;
|
||||
int m_nTempUnicodesAlloc;
|
||||
int m_nTempUnicodesLen;
|
||||
int* m_pTempUnicodes; // массив юникодов
|
||||
int m_nTempUnicodesAlloc; // размер выделенной памяти
|
||||
int m_nTempUnicodesLen; // размер используемой памяти
|
||||
|
||||
bool m_bIsFontsInit;
|
||||
|
||||
public:
|
||||
CHTMLRendererText_Private()
|
||||
{
|
||||
m_bIsChangedFontParamBetweenDrawText = true;
|
||||
m_lSrcFileType = 0;
|
||||
m_pTempUnicodes = NULL;
|
||||
m_nTempUnicodesLen = 0;
|
||||
m_nTempUnicodesAlloc = 0;
|
||||
|
||||
m_bIsFontsInit = false;
|
||||
|
||||
m_lCurrentFont = 0;
|
||||
m_dCurrentFontSize = 0;
|
||||
m_pFont = &m_oFont;
|
||||
}
|
||||
~CHTMLRendererText_Private()
|
||||
{
|
||||
RELEASEARRAYOBJECTS(m_pTempUnicodes);
|
||||
}
|
||||
|
||||
public:
|
||||
void GetUnicodes(const std::wstring& sText)
|
||||
{
|
||||
int nLen = (int)sText.length();
|
||||
@ -101,7 +84,7 @@ namespace NSHtmlRenderer
|
||||
|
||||
if (sizeof(wchar_t) == 2)
|
||||
{
|
||||
for (int nIndex = 0, nGlyphIndex = 0; nIndex < nLen; ++nIndex, ++nGlyphIndex)
|
||||
for (int nIndex = 0; nIndex < nLen; ++nIndex)
|
||||
{
|
||||
int code = (int)pWchars[nIndex];
|
||||
if (code >= 0xD800 && code <= 0xDFFF && (nIndex + 1) < nLen)
|
||||
@ -109,32 +92,25 @@ namespace NSHtmlRenderer
|
||||
++nIndex;
|
||||
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[nIndex]));
|
||||
}
|
||||
|
||||
m_pTempUnicodes[m_nTempUnicodesLen++] = code;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int nIndex = 0; nIndex < nLen; ++nIndex )
|
||||
{
|
||||
for (int nIndex = 0; nIndex < nLen; ++nIndex)
|
||||
m_pTempUnicodes[m_nTempUnicodesLen++] = (int)pWchars[nIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y,
|
||||
const double& width, const double& height, const bool& bIsChangedFontParamBetweenDrawText)
|
||||
void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y)
|
||||
{
|
||||
bool bIsDumpFont = false;
|
||||
if (!m_oInstalledFont.IsEqual(&m_oFont))
|
||||
{
|
||||
m_oInstalledFont = m_oFont;
|
||||
bIsDumpFont = true;
|
||||
|
||||
m_dCurrentFontSize = m_oInstalledFont.Size;
|
||||
}
|
||||
|
||||
m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, width, height, bIsDumpFont, this);
|
||||
m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, bIsDumpFont);
|
||||
}
|
||||
};
|
||||
|
||||
@ -149,9 +125,6 @@ namespace NSHtmlRenderer
|
||||
|
||||
void CHTMLRendererText::Init(IOfficeDrawingFile* pFile, int nCacheSize)
|
||||
{
|
||||
m_pInternal->m_oBrush.SetDefaultParams();
|
||||
m_pInternal->m_oLastBrush.SetDefaultParams();
|
||||
|
||||
m_pInternal->m_oFont.SetDefaultParams();
|
||||
m_pInternal->m_oInstalledFont.SetDefaultParams();
|
||||
m_pInternal->m_oInstalledFont.Name = L"";
|
||||
@ -159,87 +132,38 @@ namespace NSHtmlRenderer
|
||||
m_pInternal->m_oTransform.Reset();
|
||||
m_pInternal->m_oLastTransform.Reset();
|
||||
|
||||
m_pInternal->m_oLastBrush.Color1 = -1;
|
||||
m_pInternal->m_dCurrentFontSize = 0.0;
|
||||
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
|
||||
m_pInternal->m_lCurrentCommandType = -1;
|
||||
|
||||
m_pInternal->m_oSmartText.NewPage();
|
||||
|
||||
if (!m_pInternal->m_bIsFontsInit)
|
||||
{
|
||||
m_pInternal->m_oSmartText.m_oFontManager.m_pFont = &m_pInternal->m_oFont;
|
||||
|
||||
m_pInternal->m_oSmartText.m_pLastBrush = &m_pInternal->m_oLastBrush;
|
||||
m_pInternal->m_oSmartText.m_pBrush = &m_pInternal->m_oBrush;
|
||||
|
||||
m_pInternal->m_oSmartText.m_pFont = &m_pInternal->m_oFont;
|
||||
|
||||
m_pInternal->m_oSmartText.m_oFontManager.Init(pFile->GetFonts(), nCacheSize);
|
||||
m_pInternal->m_oSmartText.m_pTransform = &m_pInternal->m_oTransform;
|
||||
m_pInternal->m_oSmartText.m_pLastTransform = &m_pInternal->m_oLastTransform;
|
||||
|
||||
m_pInternal->m_oSmartText.m_pPageMeta = &m_pInternal->m_oPage;
|
||||
|
||||
OfficeDrawingFileType eType = pFile->GetType();
|
||||
switch (eType)
|
||||
{
|
||||
case odftPDF:
|
||||
{
|
||||
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF;
|
||||
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
|
||||
break;
|
||||
}
|
||||
case odftDJVU:
|
||||
{
|
||||
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU;
|
||||
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
|
||||
break;
|
||||
}
|
||||
case odftXPS:
|
||||
{
|
||||
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS;
|
||||
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_pInternal->m_bIsFontsInit = true;
|
||||
m_pInternal->m_oSmartText.Init(pFile->GetFonts(), nCacheSize);
|
||||
}
|
||||
|
||||
m_pInternal->m_oPage.ClearNoAttack();
|
||||
m_pInternal->m_oPage.WriteLONG(0);
|
||||
|
||||
m_pInternal->m_oPage.SkipLen();
|
||||
// статистика
|
||||
m_pInternal->m_oPage.WriteLONG(0);
|
||||
m_pInternal->m_oPage.WriteLONG(0);
|
||||
m_pInternal->m_oPage.WriteLONG(0);
|
||||
m_pInternal->m_oPage.WriteLONG(0);
|
||||
|
||||
m_pInternal->m_oPage.AddInt(0);
|
||||
m_pInternal->m_oPage.AddInt(0);
|
||||
m_pInternal->m_oPage.AddInt(0);
|
||||
m_pInternal->m_oPage.AddInt(0);
|
||||
}
|
||||
|
||||
BYTE* CHTMLRendererText::GetBuffer()
|
||||
{
|
||||
m_pInternal->m_oSmartText.ClosePage();
|
||||
LONG lPos = m_pInternal->m_oPage.GetPosition();
|
||||
m_pInternal->m_oPage.Seek(0);
|
||||
// len
|
||||
m_pInternal->m_oPage.WriteLONG(lPos);
|
||||
// stat
|
||||
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountParagraphs);
|
||||
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountWords);
|
||||
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSymbols);
|
||||
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSpaces);
|
||||
// seek to end
|
||||
m_pInternal->m_oPage.Seek(lPos);
|
||||
|
||||
m_pInternal->m_oPage.WriteLen();
|
||||
// статистика
|
||||
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountParagraphs, 4);
|
||||
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountWords, 8);
|
||||
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSymbols, 12);
|
||||
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSpaces, 16);
|
||||
|
||||
m_pInternal->m_oSmartText.ClearStatistics();
|
||||
return m_pInternal->m_oPage.GetData();
|
||||
return m_pInternal->m_oPage.GetBuffer();
|
||||
}
|
||||
|
||||
HRESULT CHTMLRendererText::get_Type(LONG* lType)
|
||||
{
|
||||
*lType = c_nHtmlRendrererText;
|
||||
@ -247,10 +171,7 @@ namespace NSHtmlRenderer
|
||||
}
|
||||
|
||||
//-------- Функции для работы со страницей --------------------------------------------------
|
||||
HRESULT CHTMLRendererText::NewPage()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::NewPage() { return S_OK; }
|
||||
HRESULT CHTMLRendererText::get_Height(double* dHeight)
|
||||
{
|
||||
*dHeight = m_pInternal->m_dHeght;
|
||||
@ -311,36 +232,12 @@ namespace NSHtmlRenderer
|
||||
HRESULT CHTMLRendererText::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; }
|
||||
|
||||
// brush ------------------------------------------------------------------------------------
|
||||
HRESULT CHTMLRendererText::get_BrushType(LONG* lType)
|
||||
{
|
||||
*lType = m_pInternal->m_oBrush.Type;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::put_BrushType(const LONG& lType)
|
||||
{
|
||||
m_pInternal->m_oBrush.Type = lType;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor)
|
||||
{
|
||||
*lColor = m_pInternal->m_oBrush.Color1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor)
|
||||
{
|
||||
m_pInternal->m_oBrush.Color1 = lColor;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha)
|
||||
{
|
||||
*lAlpha = m_pInternal->m_oBrush.Alpha1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha)
|
||||
{
|
||||
m_pInternal->m_oBrush.Alpha1 = lAlpha;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_BrushType(LONG* lType) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::put_BrushType(const LONG& lType) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::get_BrushColor2(LONG* lColor) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::put_BrushColor2(const LONG& lColor) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::get_BrushAlpha2(LONG* lAlpha) { return S_OK; }
|
||||
@ -366,7 +263,6 @@ namespace NSHtmlRenderer
|
||||
HRESULT CHTMLRendererText::put_FontName(const std::wstring& bsName)
|
||||
{
|
||||
m_pInternal->m_oFont.Name = bsName;
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_FontPath(std::wstring* bsName)
|
||||
@ -377,7 +273,6 @@ namespace NSHtmlRenderer
|
||||
HRESULT CHTMLRendererText::put_FontPath(const std::wstring& bsName)
|
||||
{
|
||||
m_pInternal->m_oFont.Path = bsName;
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_FontSize(double* dSize)
|
||||
@ -387,11 +282,7 @@ namespace NSHtmlRenderer
|
||||
}
|
||||
HRESULT CHTMLRendererText::put_FontSize(const double& dSize)
|
||||
{
|
||||
if (m_pInternal->m_oFont.Size != dSize)
|
||||
{
|
||||
m_pInternal->m_oFont.Size = dSize;
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
|
||||
}
|
||||
m_pInternal->m_oFont.Size = dSize;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_FontStyle(LONG* lStyle)
|
||||
@ -401,12 +292,7 @@ namespace NSHtmlRenderer
|
||||
}
|
||||
HRESULT CHTMLRendererText::put_FontStyle(const LONG& lStyle)
|
||||
{
|
||||
LONG lOld = m_pInternal->m_oFont.GetStyle();
|
||||
if (lOld != lStyle)
|
||||
{
|
||||
m_pInternal->m_oFont.SetStyle(lStyle);
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
|
||||
}
|
||||
m_pInternal->m_oFont.SetStyle(lStyle);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::get_FontStringGID(INT* bGID)
|
||||
@ -443,58 +329,34 @@ namespace NSHtmlRenderer
|
||||
//-------- Функции для вывода текста --------------------------------------------------------
|
||||
HRESULT CHTMLRendererText::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h)
|
||||
{
|
||||
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
|
||||
return S_OK;
|
||||
|
||||
int _c = (int)c;
|
||||
m_pInternal->WriteText(&_c, NULL, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
|
||||
m_pInternal->WriteText(&_c, NULL, 1, x, y);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h)
|
||||
{
|
||||
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
|
||||
return S_OK;
|
||||
|
||||
m_pInternal->GetUnicodes(bsText);
|
||||
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
|
||||
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h)
|
||||
{
|
||||
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
|
||||
return S_OK;
|
||||
|
||||
int _c = (int)c;
|
||||
int _g = (int)gid;
|
||||
|
||||
m_pInternal->WriteText(&_c, &_g, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
|
||||
m_pInternal->WriteText(&_c, &_g, 1, x, y);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h)
|
||||
{
|
||||
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
|
||||
return S_OK;
|
||||
|
||||
m_pInternal->GetUnicodes(bsUnicodeText);
|
||||
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
|
||||
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
|
||||
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-------- Маркеры для команд ---------------------------------------------------------------
|
||||
HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType)
|
||||
{
|
||||
m_pInternal->m_lCurrentCommandType = lType;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::EndCommand(const DWORD& lType)
|
||||
{
|
||||
m_pInternal->m_lCurrentCommandType = -1;
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType) { return S_OK; }
|
||||
HRESULT CHTMLRendererText::EndCommand(const DWORD& lType) { return S_OK; }
|
||||
|
||||
//-------- Функции для работы с Graphics Path -----------------------------------------------
|
||||
HRESULT CHTMLRendererText::PathCommandMoveTo(const double& x, const double& y) { return S_OK; }
|
||||
@ -32,8 +32,8 @@
|
||||
#ifndef _ASC_HTMLRENDERER3_TEXT_H_
|
||||
#define _ASC_HTMLRENDERER3_TEXT_H_
|
||||
|
||||
#include "../../DesktopEditor/graphics/IRenderer.h"
|
||||
#include "../../DesktopEditor/graphics/pro/officedrawingfile.h"
|
||||
#include "../../../../IRenderer.h"
|
||||
#include "../../../officedrawingfile.h"
|
||||
|
||||
#ifndef HTMLRENDERER_USE_DYNAMIC_LIBRARY
|
||||
#define HTMLRENDERER_DECL_EXPORT
|
||||
409
DesktopEditor/graphics/pro/js/wasm/src/Text.h
Normal file
409
DesktopEditor/graphics/pro/js/wasm/src/Text.h
Normal file
@ -0,0 +1,409 @@
|
||||
/*
|
||||
* (c) Copyright Ascensio System SIA 2010-2023
|
||||
*
|
||||
* This program is a free software product. You can redistribute it and/or
|
||||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||||
* version 3 as published by the Free Software Foundation. In accordance with
|
||||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||||
* of any third-party rights.
|
||||
*
|
||||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*
|
||||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||||
* street, Riga, Latvia, EU, LV-1050.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of the Program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU AGPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||||
* grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||||
* well as technical writing content are licensed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
*
|
||||
*/
|
||||
#ifndef _ASC_HTMLRENDERER_TEXT_H_
|
||||
#define _ASC_HTMLRENDERER_TEXT_H_
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "serialize.h"
|
||||
#include "../../../../structures.h"
|
||||
#include "../../../Fonts.h"
|
||||
|
||||
namespace NSHtmlRenderer
|
||||
{
|
||||
struct CHFontInfo
|
||||
{
|
||||
int m_lAscent;
|
||||
int m_lDescent;
|
||||
int m_lUnitsPerEm;
|
||||
|
||||
CHFontInfo() : m_lAscent(0), m_lDescent(0), m_lUnitsPerEm(0) {}
|
||||
CHFontInfo(const CHFontInfo& oSrc) : m_lAscent(oSrc.m_lAscent), m_lDescent(oSrc.m_lDescent), m_lUnitsPerEm(oSrc.m_lUnitsPerEm) {}
|
||||
CHFontInfo& operator=(const CHFontInfo& oSrc)
|
||||
{
|
||||
m_lAscent = oSrc.m_lAscent;
|
||||
m_lDescent = oSrc.m_lDescent;
|
||||
m_lUnitsPerEm = oSrc.m_lUnitsPerEm;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class CFontManagerWrapper
|
||||
{
|
||||
private:
|
||||
NSFonts::IFontManager* m_pManager;
|
||||
public:
|
||||
NSStructures::CFont* m_pFont;
|
||||
CHFontInfo m_oCurrentInfo;
|
||||
|
||||
public:
|
||||
CFontManagerWrapper() : m_pManager(NULL) {}
|
||||
virtual ~CFontManagerWrapper()
|
||||
{
|
||||
RELEASEOBJECT(m_pManager);
|
||||
}
|
||||
|
||||
void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0)
|
||||
{
|
||||
RELEASEOBJECT(m_pManager);
|
||||
m_pManager = pApplicationFonts->GenerateFontManager();
|
||||
if (nCacheSize)
|
||||
{
|
||||
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
|
||||
pFontCache->SetStreams(pApplicationFonts->GetStreams());
|
||||
pFontCache->SetCacheSize(nCacheSize);
|
||||
m_pManager->SetOwnerCache(pFontCache);
|
||||
}
|
||||
}
|
||||
void SetStringGID(INT bGid)
|
||||
{
|
||||
m_pManager->SetStringGID(bGid);
|
||||
}
|
||||
void LoadCurrentFont()
|
||||
{
|
||||
if (m_pFont->Path.empty())
|
||||
LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle());
|
||||
else
|
||||
LoadFontByFile(m_pFont->Path, m_pFont->Size);
|
||||
}
|
||||
double MeasureString(const unsigned int* symbols, const int& count, double x, double y)
|
||||
{
|
||||
if (!m_pManager)
|
||||
return 0;
|
||||
|
||||
m_pManager->LoadString1(symbols, count, (float)x, (float)y);
|
||||
TBBox _box = m_pManager->MeasureString2();
|
||||
|
||||
return abs((_box.fMaxX - _box.fMinX) * 25.4 / 72.0);
|
||||
}
|
||||
|
||||
private:
|
||||
inline void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle)
|
||||
{
|
||||
m_pManager->LoadFontByName(strName, dSize, lStyle, 72.0, 72.0);
|
||||
LoadFontMetrics();
|
||||
}
|
||||
inline void LoadFontByFile(const std::wstring& strPath, const double& dSize)
|
||||
{
|
||||
m_pManager->LoadFontFromFile(strPath, 0, dSize, 72.0, 72.0);
|
||||
LoadFontMetrics();
|
||||
}
|
||||
void LoadFontMetrics()
|
||||
{
|
||||
m_pManager->AfterLoad();
|
||||
m_oCurrentInfo.m_lAscent = abs(m_pManager->GetAscender());
|
||||
m_oCurrentInfo.m_lDescent = abs(m_pManager->GetDescender());
|
||||
m_oCurrentInfo.m_lUnitsPerEm = abs(m_pManager->GetUnitsPerEm());
|
||||
}
|
||||
};
|
||||
|
||||
struct CHText
|
||||
{
|
||||
CFontManagerWrapper m_oFontManager;
|
||||
Aggplus::CMatrix* m_pTransform;
|
||||
Aggplus::CMatrix* m_pLastTransform;
|
||||
|
||||
NSWasm::CHLine m_oLine;
|
||||
NSWasm::CData* m_pPageMeta;
|
||||
|
||||
LONG m_nCountParagraphs;
|
||||
LONG m_nCountWords;
|
||||
LONG m_nCountSymbols;
|
||||
LONG m_nCountSpaces;
|
||||
|
||||
CHText() : m_oFontManager(), m_oLine()
|
||||
{
|
||||
m_nCountParagraphs = 0;
|
||||
m_nCountWords = 0;
|
||||
m_nCountSymbols = 0;
|
||||
m_nCountSpaces = 0;
|
||||
}
|
||||
|
||||
void ClearStatistics()
|
||||
{
|
||||
m_nCountParagraphs = 0;
|
||||
m_nCountWords = 0;
|
||||
m_nCountSymbols = 0;
|
||||
m_nCountSpaces = 0;
|
||||
}
|
||||
void ClosePage()
|
||||
{
|
||||
if (m_oLine.GetCountChars())
|
||||
DumpLine();
|
||||
}
|
||||
void CommandText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y, bool bIsDumpFont)
|
||||
{
|
||||
// 1) сначала определяем точку отсчета и направление baseline
|
||||
double _x1 = x;
|
||||
double _y1 = y;
|
||||
double _x2 = x + 1;
|
||||
double _y2 = y;
|
||||
m_pTransform->TransformPoint(_x1, _y1);
|
||||
m_pTransform->TransformPoint(_x2, _y2);
|
||||
|
||||
double _k = 0;
|
||||
double _b = 0;
|
||||
bool _isConstX = false;
|
||||
if (fabs(_x1 - _x2) < 0.001)
|
||||
{
|
||||
_isConstX = true;
|
||||
_b = _x1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_k = (_y1 - _y2) / (_x1 - _x2);
|
||||
_b = _y1 - _k * _x1;
|
||||
}
|
||||
|
||||
double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2));
|
||||
if (dAbsVec == 0)
|
||||
dAbsVec = 1;
|
||||
|
||||
bool bIsNewLine = true;
|
||||
if (m_oLine.GetCountChars())
|
||||
{
|
||||
if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001)
|
||||
bIsNewLine = false;
|
||||
else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001)
|
||||
bIsNewLine = false;
|
||||
|
||||
if (bIsNewLine) // не совпала baseline. поэтому просто скидываем линию в поток
|
||||
DumpLine();
|
||||
}
|
||||
|
||||
// теперь нужно определить сдвиг по baseline относительно destination точки
|
||||
double dOffsetX = 0;
|
||||
LONG nCountChars = m_oLine.GetCountChars();
|
||||
if (0 == nCountChars)
|
||||
{
|
||||
m_oLine.m_bIsConstX = _isConstX;
|
||||
m_oLine.m_dK = _k;
|
||||
m_oLine.m_dB = _b;
|
||||
|
||||
m_oLine.m_dX = _x1;
|
||||
m_oLine.m_dY = _y1;
|
||||
|
||||
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
|
||||
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
|
||||
|
||||
m_oLine.m_dEndX = _x1;
|
||||
m_oLine.m_dEndY = _y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
double sx = _x1 - m_oLine.m_dEndX;
|
||||
double sy = _y1 - m_oLine.m_dEndY;
|
||||
double len = sqrt(sx*sx + sy*sy);
|
||||
|
||||
if (sx * m_oLine.m_ex >= 0 && sy * m_oLine.m_ey >= 0)
|
||||
{
|
||||
// продолжаем линию
|
||||
dOffsetX = len;
|
||||
|
||||
// теперь посмотрим, может быть нужно вставить пробел??
|
||||
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
|
||||
if (dOffsetX > (pLastChar->width + 0.5))
|
||||
{
|
||||
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
|
||||
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
|
||||
pLastChar = &m_oLine.m_pChars[m_oLine.m_lCharsTail - 2];
|
||||
pSpaceChar->x = pLastChar->width;
|
||||
pSpaceChar->width = dOffsetX - pLastChar->width;
|
||||
pSpaceChar->unicode = 0xFFFF;
|
||||
dOffsetX -= pLastChar->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// буква сдвинута влево относительно предыдущей буквы
|
||||
// на такую ситуацию реагируем просто - просто начинаем новую линию,
|
||||
// предварительно сбросив старую
|
||||
DumpLine();
|
||||
|
||||
m_oLine.m_bIsConstX = _isConstX;
|
||||
|
||||
m_oLine.m_dX = _x1;
|
||||
m_oLine.m_dY = _y1;
|
||||
|
||||
m_oLine.m_dK = _k;
|
||||
m_oLine.m_dB = _b;
|
||||
|
||||
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
|
||||
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
|
||||
}
|
||||
|
||||
m_oLine.m_dEndX = _x1;
|
||||
m_oLine.m_dEndY = _y1;
|
||||
}
|
||||
|
||||
if (!Aggplus::CMatrix::IsEqual(m_pLastTransform, m_pTransform, 0.001, true))
|
||||
{ // смотрим, совпадает ли главная часть матрицы
|
||||
bIsDumpFont = true;
|
||||
*m_pLastTransform = *m_pTransform;
|
||||
m_oLine.m_bIsSetUpTransform = true;
|
||||
m_oLine.m_sx = m_pTransform->sx();
|
||||
m_oLine.m_shx = m_pTransform->shx();
|
||||
m_oLine.m_shy = m_pTransform->shy();
|
||||
m_oLine.m_sy = m_pTransform->sy();
|
||||
}
|
||||
|
||||
// все, baseline установлен. теперь просто продолжаем линию
|
||||
if (bIsDumpFont)
|
||||
m_oFontManager.LoadCurrentFont();
|
||||
|
||||
double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm);
|
||||
double dAscender = m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dAbsVec;
|
||||
double dDescender = m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dAbsVec;
|
||||
|
||||
if (m_oLine.m_dAscent < dAscender)
|
||||
m_oLine.m_dAscent = dAscender;
|
||||
if (m_oLine.m_dDescent < dDescender)
|
||||
m_oLine.m_dDescent = dDescender;
|
||||
|
||||
const int* input = NULL;
|
||||
if (NULL != pGids)
|
||||
{
|
||||
input = pGids;
|
||||
m_oFontManager.SetStringGID(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
input = pUnicodes;
|
||||
m_oFontManager.SetStringGID(FALSE);
|
||||
}
|
||||
|
||||
double dPlusOffset = 0;
|
||||
double dPrevW = dOffsetX;
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
double dW = m_oFontManager.MeasureString((const unsigned int*)(input + i), 1, 0, 0);
|
||||
|
||||
NSWasm::CHChar* pChar = m_oLine.AddTail();
|
||||
pChar->unicode = pUnicodes[i];
|
||||
|
||||
pChar->x = dPrevW;
|
||||
if (i)
|
||||
dPlusOffset += dPrevW;
|
||||
dPrevW = dW;
|
||||
pChar->width = dW * dAbsVec;
|
||||
|
||||
if (i == nCount - 1)
|
||||
{
|
||||
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
|
||||
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
|
||||
}
|
||||
}
|
||||
}
|
||||
void DumpLine()
|
||||
{
|
||||
LONG nCount = m_oLine.GetCountChars();
|
||||
if (!nCount)
|
||||
{
|
||||
m_oLine.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_oLine.m_bIsSetUpTransform)
|
||||
{
|
||||
// выставится трансформ!!!
|
||||
// cравнивать нужно с ним!!!
|
||||
m_pLastTransform->SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy);
|
||||
}
|
||||
|
||||
// скидываем линию в поток pMeta
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_dX);
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_dY);
|
||||
|
||||
bool bHorizontal = false;
|
||||
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
|
||||
bHorizontal = true;
|
||||
m_pPageMeta->WriteBYTE(!bHorizontal ? 1 : 0);
|
||||
if (!bHorizontal)
|
||||
{
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_ex);
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_ey);
|
||||
}
|
||||
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_dAscent);
|
||||
m_pPageMeta->WriteDouble(m_oLine.m_dDescent);
|
||||
|
||||
m_nCountParagraphs++;
|
||||
|
||||
// width
|
||||
LONG _position = m_pPageMeta->GetSize();
|
||||
m_pPageMeta->AddInt(0);
|
||||
|
||||
double dWidthLine = 0;
|
||||
double dCurrentGlyphLineOffset = 0;
|
||||
m_pPageMeta->AddInt(nCount);
|
||||
NSWasm::CHChar* pChar = NULL;
|
||||
bool bIsLastSymbol = false;
|
||||
for (LONG lIndexChar = 0; lIndexChar < nCount; ++lIndexChar)
|
||||
{
|
||||
pChar = &m_oLine.m_pChars[lIndexChar];
|
||||
|
||||
if (lIndexChar)
|
||||
{
|
||||
m_pPageMeta->WriteDouble(pChar->x);
|
||||
dCurrentGlyphLineOffset += pChar->x;
|
||||
}
|
||||
|
||||
if (pChar->unicode == 0xFFFF || pChar->unicode == 32 || pChar->unicode == 9)
|
||||
{
|
||||
m_nCountSpaces++;
|
||||
if (bIsLastSymbol)
|
||||
{
|
||||
bIsLastSymbol = false;
|
||||
m_nCountWords++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nCountSymbols++;
|
||||
bIsLastSymbol = true;
|
||||
}
|
||||
|
||||
m_pPageMeta->AddInt(pChar->unicode); // юникодное значение
|
||||
m_pPageMeta->WriteDouble(pChar->width); // ширина буквы
|
||||
}
|
||||
if (bIsLastSymbol)
|
||||
m_nCountWords++;
|
||||
|
||||
if (pChar)
|
||||
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
|
||||
m_pPageMeta->AddInt((int)(dWidthLine * 10000.0), _position);
|
||||
m_oLine.Clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _ASC_HTMLRENDERER_TEXT_H_
|
||||
@ -10,6 +10,10 @@ unsigned char READ_BYTE(BYTE* x)
|
||||
{
|
||||
return x ? x[0] : 1;
|
||||
}
|
||||
unsigned short READ_SHORT(BYTE* x)
|
||||
{
|
||||
return x ? (x[0] | x[1] << 8) : 2;
|
||||
}
|
||||
unsigned int READ_INT(BYTE* x)
|
||||
{
|
||||
return x ? (x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) : 4;
|
||||
@ -1086,15 +1090,82 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// GLYPHS
|
||||
if (false && nPagesCount > 0)
|
||||
if (true && nPagesCount > 0)
|
||||
{
|
||||
// TODO:
|
||||
BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage);
|
||||
nLength = READ_INT(pGlyphs);
|
||||
int i = 4;
|
||||
nLength -= 20;
|
||||
|
||||
int nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << "Stats Paragraphs " << nPathLength;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Words " << nPathLength;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Symbols " << nPathLength;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Spaces " << nPathLength << std::endl;
|
||||
|
||||
while (i < nLength)
|
||||
{
|
||||
int nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << "Line X " << (double)nPathLength / 10000.0;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Y " << (double)nPathLength / 10000.0;
|
||||
nPathLength = READ_BYTE(pGlyphs + i);
|
||||
i += 1;
|
||||
if (nPathLength)
|
||||
{
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Ex " << (double)nPathLength / 10000.0;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Ey " << (double)nPathLength / 10000.0;
|
||||
}
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Ascent " << (double)nPathLength / 10000.0;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Descent " << (double)nPathLength / 10000.0;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " LineWidth " << (double)nPathLength / 10000.0;
|
||||
int nCharLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Chars:" << std::endl;
|
||||
for (int j = 0; j < nCharLength; ++j)
|
||||
{
|
||||
int nCharX = 0;
|
||||
if (j)
|
||||
{
|
||||
nCharX = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
}
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " Unicode " << nPathLength;
|
||||
nPathLength = READ_INT(pGlyphs + i);
|
||||
i += 4;
|
||||
std::cout << " width " << (double)nPathLength / 10000.0;
|
||||
if (nCharX)
|
||||
std::cout << " charX " << (double)nCharX / 10000.0;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
DestroyTextInfo(pGrFile);
|
||||
}
|
||||
|
||||
// INTERACTIVE FORMS
|
||||
if (true)
|
||||
if (false)
|
||||
{
|
||||
ReadInteractiveFormsFonts(pGrFile, 1);
|
||||
ReadInteractiveFormsFonts(pGrFile, 2);
|
||||
@ -1799,7 +1870,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
std::cout << "Rotate " << nPathLength << ", ";
|
||||
std::cout << "Rotate " << nPathLength / 10000.0 << ", ";
|
||||
|
||||
nPathLength = READ_INT(pAnnots + i);
|
||||
i += 4;
|
||||
@ -1855,7 +1926,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
// SCAN PAGE
|
||||
if (true)
|
||||
if (false)
|
||||
{
|
||||
BYTE* pScan = ScanPage(pGrFile, nTestPage, 1);
|
||||
if (pScan)
|
||||
|
||||
@ -42,6 +42,7 @@ namespace MetaFile
|
||||
virtual void SetImageSize(int nWidth, int nHeight) {}
|
||||
virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; }
|
||||
virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; }
|
||||
virtual bool LoadFromString(const std::wstring& data) { return false; }
|
||||
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; }
|
||||
virtual void Close() {}
|
||||
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) {}
|
||||
@ -50,6 +51,7 @@ namespace MetaFile
|
||||
virtual NSFonts::IFontManager* get_FontManager() { return NULL; }
|
||||
|
||||
virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) { return L""; }
|
||||
virtual void SetTempDirectory(const std::wstring& dir) {}
|
||||
|
||||
virtual void ConvertToXml(const wchar_t* wsFilePath) {}
|
||||
virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) {}
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
#ifndef _WASM_SERIALIZE_H
|
||||
#define _WASM_SERIALIZE_H
|
||||
|
||||
#include "../../../../../common/StringExt.h"
|
||||
#include "../../../../../common/StringUTF32.h"
|
||||
#include "../../../../../graphics/IRenderer.h"
|
||||
#include "../../../../../graphics/pro/Fonts.h"
|
||||
#include <vector>
|
||||
#include "../../../../../common/File.h"
|
||||
|
||||
namespace NSWasm
|
||||
@ -208,58 +205,32 @@ namespace NSWasm
|
||||
}
|
||||
};
|
||||
|
||||
class CHChar
|
||||
struct CHChar
|
||||
{
|
||||
public:
|
||||
int unicode; // юникодное значение
|
||||
int gid; // индекс глифа в файле
|
||||
double x; // сдвиг по baseline
|
||||
double width; // ширина символа (сдвиг до след буквы)
|
||||
double* matrix; // матрица преобразования (!!! без сдвига)
|
||||
int unicode; // юникодное значение
|
||||
double x; // сдвиг по baseline
|
||||
double width; // ширина символа (сдвиг до след буквы)
|
||||
|
||||
public:
|
||||
CHChar()
|
||||
{
|
||||
unicode = 0;
|
||||
gid = 0;
|
||||
width = 0;
|
||||
matrix = NULL;
|
||||
}
|
||||
CHChar(const CHChar& oSrc)
|
||||
{
|
||||
*this = oSrc;
|
||||
}
|
||||
CHChar() : unicode(0), x(0), width(0) {}
|
||||
CHChar(const CHChar& oSrc) { *this = oSrc; }
|
||||
CHChar& operator=(const CHChar& oSrc)
|
||||
{
|
||||
unicode = oSrc.unicode;
|
||||
gid = oSrc.gid;
|
||||
x = oSrc.x;
|
||||
width = oSrc.width;
|
||||
matrix = NULL;
|
||||
if (NULL != oSrc.matrix)
|
||||
{
|
||||
matrix = new double[4];
|
||||
memcpy(matrix, oSrc.matrix, 4 * sizeof(double));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~CHChar()
|
||||
{
|
||||
RELEASEARRAYOBJECTS(matrix);
|
||||
}
|
||||
|
||||
inline void Clear()
|
||||
{
|
||||
unicode = 0;
|
||||
gid = 0;
|
||||
x = 0;
|
||||
width = 0;
|
||||
|
||||
RELEASEARRAYOBJECTS(matrix);
|
||||
}
|
||||
};
|
||||
|
||||
class CHLine
|
||||
struct CHLine
|
||||
{
|
||||
public:
|
||||
double m_dAscent;
|
||||
double m_dDescent;
|
||||
double m_dX;
|
||||
@ -288,7 +259,6 @@ namespace NSWasm
|
||||
double m_shx;
|
||||
double m_shy;
|
||||
|
||||
public:
|
||||
CHLine()
|
||||
{
|
||||
m_dAscent = 0;
|
||||
@ -374,9 +344,7 @@ namespace NSWasm
|
||||
{
|
||||
CHChar* pNews = new CHChar[2 * m_lSizeChars];
|
||||
for (LONG i = 0; i < m_lSizeChars; ++i)
|
||||
{
|
||||
pNews[i] = m_pChars[i];
|
||||
}
|
||||
|
||||
RELEASEARRAYOBJECTS(m_pChars);
|
||||
m_pChars = pNews;
|
||||
@ -392,10 +360,18 @@ namespace NSWasm
|
||||
|
||||
inline CHChar* GetTail()
|
||||
{
|
||||
if (0 == m_lCharsTail)
|
||||
return NULL;
|
||||
if (m_lCharsTail >= m_lSizeChars)
|
||||
{
|
||||
CHChar* pNews = new CHChar[2 * m_lSizeChars];
|
||||
for (LONG i = 0; i < m_lSizeChars; ++i)
|
||||
pNews[i] = m_pChars[i];
|
||||
|
||||
return &m_pChars[m_lCharsTail - 1];
|
||||
RELEASEARRAYOBJECTS(m_pChars);
|
||||
m_pChars = pNews;
|
||||
m_lSizeChars *= 2;
|
||||
}
|
||||
|
||||
return m_lCharsTail ? &m_pChars[m_lCharsTail - 1] : NULL;
|
||||
}
|
||||
|
||||
inline LONG GetCountChars()
|
||||
|
||||
@ -19,6 +19,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
|
||||
\
|
||||
$$METAFILE_PATH/Emf/EmfTypes.h \
|
||||
$$METAFILE_PATH/Emf/EmfObjects.h \
|
||||
$$METAFILE_PATH/Emf/EmfPlusObjects.h \
|
||||
$$METAFILE_PATH/Emf/EmfPlayer.h \
|
||||
$$METAFILE_PATH/Emf/EmfFile.h \
|
||||
$$METAFILE_PATH/Wmf/WmfObjects.h \
|
||||
|
||||
@ -327,6 +327,13 @@ namespace MetaFile
|
||||
if (NULL == pCommand)
|
||||
return false;
|
||||
|
||||
if (PATH_COMMAND_MOVETO == pCommand->GetType() && !m_arCommands.empty() && PATH_COMMAND_MOVETO == m_arCommands.back()->GetType())
|
||||
{
|
||||
CPathCommandBase* pLastCommand = m_arCommands.back();
|
||||
m_arCommands.pop_back();
|
||||
delete pLastCommand;
|
||||
}
|
||||
|
||||
m_arCommands.push_back(pCommand);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ namespace MetaFile
|
||||
{
|
||||
CPathCommandArcTo *pCommandArcTo = (CPathCommandArcTo*)pCommand;
|
||||
|
||||
oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(),
|
||||
oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(),
|
||||
pCommandArcTo->GetRight(), pCommandArcTo->GetBottom(),
|
||||
pCommandArcTo->GetStartAngle(), pCommandArcTo->GetSweepAngle());
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#define _METAFILE_COMMON_METAFILEOBJECTS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace MetaFile
|
||||
{
|
||||
@ -70,22 +71,33 @@ namespace MetaFile
|
||||
virtual void GetBounds(double& left, double& top, double& width, double& height) const = 0;
|
||||
virtual void GetCenterPoint(double& dX, double& dY) const = 0;
|
||||
|
||||
virtual void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const = 0;
|
||||
|
||||
virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const = 0;
|
||||
};
|
||||
|
||||
class ILineCap
|
||||
{
|
||||
public:
|
||||
ILineCap(){}
|
||||
virtual ~ILineCap(){}
|
||||
};
|
||||
|
||||
class IPen
|
||||
{
|
||||
public:
|
||||
IPen(){}
|
||||
virtual ~IPen(){}
|
||||
|
||||
virtual int GetColor() const = 0;
|
||||
virtual unsigned int GetStyle() const = 0;
|
||||
virtual double GetWidth() const = 0;
|
||||
virtual unsigned int GetAlpha() const = 0;
|
||||
virtual double GetMiterLimit() const = 0;
|
||||
virtual double GetDashOffset() const = 0;
|
||||
virtual void GetDashData(double*&, unsigned int&) const = 0;
|
||||
virtual int GetColor() const = 0;
|
||||
virtual unsigned int GetStyle() const = 0;
|
||||
virtual double GetWidth() const = 0;
|
||||
virtual unsigned int GetAlpha() const = 0;
|
||||
virtual double GetMiterLimit() const = 0;
|
||||
virtual double GetDashOffset() const = 0;
|
||||
virtual void GetDashData(double*&, unsigned int&) const = 0;
|
||||
virtual const ILineCap* GetStartLineCap() const = 0;
|
||||
virtual const ILineCap* GetEndLineCap() const = 0;
|
||||
};
|
||||
|
||||
class IRegion
|
||||
|
||||
@ -100,6 +100,8 @@ namespace MetaFile
|
||||
m_bStartedPath = false;
|
||||
m_bUpdatedClip = true;
|
||||
|
||||
m_pRenderer->CommandLong(c_nPenWidth0As1px, 1);
|
||||
|
||||
//int alpha = 0xff;
|
||||
//m_pRenderer->put_BrushAlpha1(alpha);
|
||||
//m_pRenderer->put_BrushType(c_BrushTypeSolid);
|
||||
@ -1107,12 +1109,11 @@ namespace MetaFile
|
||||
|
||||
m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx());
|
||||
|
||||
long Colors[2];
|
||||
Colors[0] = pBrush->GetColor() + (pBrush->GetAlpha() << 24);
|
||||
Colors[1] = pBrush->GetColor2() + (pBrush->GetAlpha2() << 24);
|
||||
double Position[2] = {0, 1};
|
||||
std::vector<long> arColors;
|
||||
std::vector<double> arPositions;
|
||||
|
||||
m_pRenderer->put_BrushGradientColors(Colors,Position,2);
|
||||
pBrush->GetGradientColors(arColors, arPositions);
|
||||
m_pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size());
|
||||
|
||||
}
|
||||
else if ( BS_RADIALGRADIENT == unBrushStyle ||
|
||||
@ -1180,7 +1181,6 @@ namespace MetaFile
|
||||
return false;
|
||||
|
||||
unsigned int unMetaPenStyle = pPen->GetStyle();
|
||||
|
||||
unsigned int ulPenStyle = unMetaPenStyle & PS_STYLE_MASK;
|
||||
|
||||
if (PS_NULL == ulPenStyle)
|
||||
@ -1218,22 +1218,8 @@ namespace MetaFile
|
||||
else if (PS_JOIN_MITER == ulPenJoin)
|
||||
nJoinStyle = Aggplus::LineJoinMiter;
|
||||
|
||||
double dWidth = pPen->GetWidth();
|
||||
|
||||
if (Equals(0, dWidth) || (Equals(1, dWidth) && PS_COSMETIC == ulPenType))
|
||||
{
|
||||
double dRendererDpiX;
|
||||
m_pRenderer->get_DpiX(&dRendererDpiX);
|
||||
|
||||
dWidth = 25.4 / 96. * m_pFile->GetDpi() / dRendererDpiX;
|
||||
|
||||
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
|
||||
nJoinStyle = Aggplus::LineJoinMiter;
|
||||
}
|
||||
else
|
||||
dWidth *= m_dScaleX;
|
||||
|
||||
double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;
|
||||
const double dWidth = pPen->GetWidth() * m_dScaleX;
|
||||
const double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;
|
||||
|
||||
BYTE nDashStyle = Aggplus::DashStyleSolid;
|
||||
|
||||
@ -1246,10 +1232,16 @@ namespace MetaFile
|
||||
{
|
||||
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
|
||||
|
||||
double dM11, dTemp;
|
||||
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
|
||||
double dDpi;
|
||||
m_pRenderer->get_DpiX(&dDpi);
|
||||
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
|
||||
|
||||
std::vector<double> arDashes(unSizeDash);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
|
||||
arDashes[unIndex] = pDataDash[unIndex] * dWidth;
|
||||
arDashes[unIndex] = pDataDash[unIndex] * dNewWidth;
|
||||
|
||||
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
|
||||
|
||||
@ -1259,39 +1251,45 @@ namespace MetaFile
|
||||
{
|
||||
std::vector<double> arDashPattern;
|
||||
|
||||
double dM11, dTemp;
|
||||
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
|
||||
double dDpi;
|
||||
m_pRenderer->get_DpiX(&dDpi);
|
||||
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
|
||||
|
||||
switch (ulPenStyle)
|
||||
{
|
||||
case PS_DASH:
|
||||
{
|
||||
arDashPattern.push_back(9 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(9 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
|
||||
break;
|
||||
}
|
||||
case PS_DOT:
|
||||
{
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
|
||||
break;
|
||||
}
|
||||
case PS_DASHDOT:
|
||||
{
|
||||
arDashPattern.push_back(9 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(9 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
|
||||
break;
|
||||
}
|
||||
case PS_DASHDOTDOT:
|
||||
{
|
||||
arDashPattern.push_back(9 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(3 * dWidth);
|
||||
arDashPattern.push_back(9 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
arDashPattern.push_back(3 * dNewWidth);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -349,6 +349,8 @@ typedef unsigned char BYTE;
|
||||
|
||||
namespace MetaFile
|
||||
{
|
||||
#define DEFAULT_FONT_SIZE 14
|
||||
|
||||
enum InterpretatorType
|
||||
{
|
||||
Emf,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -48,6 +48,8 @@ namespace MetaFile
|
||||
{
|
||||
bool Equals(double dFirst, double dSecond, double dEpsilon = DBL_EPSILON);
|
||||
std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet);
|
||||
std::wstring ConvertToWString(double dValue, int nAccuracy = -1);
|
||||
std::wstring ConvertToWString(const std::vector<double>& arValues, int nAccuracy = -1);
|
||||
|
||||
struct TRgbQuad
|
||||
{
|
||||
@ -88,13 +90,34 @@ namespace MetaFile
|
||||
};
|
||||
|
||||
typedef std::pair<const std::wstring, std::wstring> NodeAttribute;
|
||||
typedef std::vector<NodeAttribute> NodeAttributes;
|
||||
// typedef std::vector<NodeAttribute> NodeAttributes;
|
||||
|
||||
class NodeAttributes : public std::vector<NodeAttribute>
|
||||
{
|
||||
public:
|
||||
using std::vector<NodeAttribute>::vector;
|
||||
|
||||
void Add(const std::wstring& wsNameArgument, const std::wstring& wsValueArgument)
|
||||
{
|
||||
emplace_back(NodeAttribute{wsNameArgument, wsValueArgument});
|
||||
}
|
||||
|
||||
void Add(const std::wstring& wsNameArgument, const double& dValueArgument, int nAccuracy = -1)
|
||||
{
|
||||
emplace_back(NodeAttribute{wsNameArgument, ConvertToWString(dValueArgument, nAccuracy)});
|
||||
}
|
||||
|
||||
void Add(const std::wstring& wsNameArgument, const int& nValueArgument)
|
||||
{
|
||||
emplace_back(NodeAttribute{wsNameArgument, std::to_wstring(nValueArgument)});
|
||||
}
|
||||
};
|
||||
|
||||
class CDataStream
|
||||
{
|
||||
public:
|
||||
|
||||
CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pEnd(NULL), pCur(NULL)
|
||||
CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pCur(NULL), pEnd(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1159,8 +1182,5 @@ namespace MetaFile
|
||||
|
||||
std::wstring StringNormalization(const std::wstring& wsString);
|
||||
bool StringEquals(const std::wstring& wsFirstString, const std::wstring& wsSecondString);
|
||||
|
||||
std::wstring ConvertToWString(double dValue, int nAccuracy = -1);
|
||||
std::wstring ConvertToWString(const std::vector<double>& arValues, int nAccuracy = -1);
|
||||
};
|
||||
#endif // _METAFILE_COMMON_METAFILEUTILS_H
|
||||
|
||||
@ -41,7 +41,7 @@ namespace MetaFile
|
||||
}
|
||||
|
||||
void CEmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx,
|
||||
int iGraphicsMode, double dXScale, double dYScale)
|
||||
int iGraphicsMode, double dXScale, double dYScale)
|
||||
{
|
||||
if (NULL != m_pMetaFileRenderer)
|
||||
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);
|
||||
|
||||
@ -33,7 +33,8 @@ namespace MetaFile
|
||||
return;
|
||||
|
||||
std::swap(m_pParser, m_oSecondConditional.m_pParser);
|
||||
std::swap(m_oClip, m_oSecondConditional.m_oClip);
|
||||
|
||||
SwapClips(m_oClip, m_oSecondConditional.m_oClip);
|
||||
}
|
||||
|
||||
InterpretatorType CEmfInterpretatorSvg::GetType() const
|
||||
@ -107,7 +108,7 @@ namespace MetaFile
|
||||
|
||||
if (NULL == pPath)
|
||||
return;
|
||||
|
||||
|
||||
const std::wstring wsValue = CreatePath(*pPath);
|
||||
|
||||
if (wsValue.empty())
|
||||
@ -117,6 +118,7 @@ namespace MetaFile
|
||||
|
||||
AddClip();
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
|
||||
WriteNode(L"path" , arAttributes);
|
||||
@ -175,6 +177,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
|
||||
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
|
||||
{
|
||||
@ -238,6 +241,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
|
||||
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
|
||||
{
|
||||
@ -292,6 +296,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
|
||||
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
|
||||
{
|
||||
@ -325,6 +330,7 @@ namespace MetaFile
|
||||
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -365,6 +371,7 @@ namespace MetaFile
|
||||
{L"y2", ConvertToWString(oPoint.Y)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -373,21 +380,29 @@ namespace MetaFile
|
||||
|
||||
void CEmfInterpretatorSvg::HANDLE_EMR_PIE(const TRectL &oBox, const TPointL &oStart, const TPointL &oEnd)
|
||||
{
|
||||
short shCenterX = (oBox.Left + oBox.Right) / 2;
|
||||
short shCenterY = (oBox.Top + oBox.Bottom) / 2;
|
||||
int nCenterX = (oBox.Left + oBox.Right) / 2;
|
||||
int nCenterY = (oBox.Top + oBox.Bottom) / 2;
|
||||
|
||||
short shRadiusX = std::abs(oBox.Right - oBox.Left) / 2;
|
||||
short shRadiusY = std::abs(oBox.Bottom - oBox.Top) / 2;
|
||||
|
||||
std::wstring wsPath = L'M' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L' ' +
|
||||
double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX);
|
||||
double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX);
|
||||
|
||||
if (dEndAngle > dStartAngle)
|
||||
dEndAngle -= 2 * M_PI;
|
||||
|
||||
std::wstring wsPath = L'M' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L' ' +
|
||||
L'L' + ConvertToWString(oStart.X)+ L' ' + ConvertToWString(oStart.Y)+ L' ' +
|
||||
L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0, 0, 0, " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' +
|
||||
L'L' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L" Z";
|
||||
L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0 " +
|
||||
((std::abs(dEndAngle - dStartAngle) > M_PI) ? L'1' : L'0') + L" 0 " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' +
|
||||
L'L' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L" Z";
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsPath}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -402,14 +417,15 @@ namespace MetaFile
|
||||
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -424,14 +440,15 @@ namespace MetaFile
|
||||
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -446,14 +463,15 @@ namespace MetaFile
|
||||
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -468,14 +486,15 @@ namespace MetaFile
|
||||
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -509,9 +528,9 @@ namespace MetaFile
|
||||
wsValue += L" C ";
|
||||
oLastType = 0x04;
|
||||
}
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
unIndex += 3;
|
||||
}
|
||||
@ -526,6 +545,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -559,9 +579,9 @@ namespace MetaFile
|
||||
wsValue += L" C ";
|
||||
oLastType = 0x04;
|
||||
}
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
unIndex += 3;
|
||||
}
|
||||
@ -576,6 +596,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -596,6 +617,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -616,6 +638,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -636,6 +659,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -658,6 +682,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -680,6 +705,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -702,6 +728,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -729,10 +756,11 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
arAttributes.push_back({L"fill-rule", L"evenodd"});
|
||||
arAttributes.Add(L"fill-rule", L"evenodd");
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
}
|
||||
@ -758,10 +786,11 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
arAttributes.push_back({L"fill-rule", L"evenodd"});
|
||||
arAttributes.Add(L"fill-rule", L"evenodd");
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
}
|
||||
@ -787,10 +816,11 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
arAttributes.push_back({L"fill-rule", L"evenodd"});
|
||||
arAttributes.Add(L"fill-rule", L"evenodd");
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
}
|
||||
@ -816,10 +846,11 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
arAttributes.push_back({L"fill-rule", L"evenodd"});
|
||||
arAttributes.Add(L"fill-rule", L"evenodd");
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
}
|
||||
@ -828,13 +859,14 @@ namespace MetaFile
|
||||
{
|
||||
TRectD oNewRect = TranslateRect(oBox);
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes, oNewRect.Right - oNewRect.Left, oNewRect.Bottom - oNewRect.Top);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -845,15 +877,16 @@ namespace MetaFile
|
||||
{
|
||||
TRectD oNewRect = TranslateRect(oBox);
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
|
||||
{L"rx", ConvertToWString((double)oCorner.X / 2.)},
|
||||
{L"ry", ConvertToWString((double)oCorner.Y / 2.)}};
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
|
||||
{L"rx", ConvertToWString((double)oCorner.X / 2.)},
|
||||
{L"ry", ConvertToWString((double)oCorner.Y / 2.)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -889,6 +922,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes, std::fabs(oBounds.Right - oBounds.Left), std::fabs(oBounds.Bottom - oBounds.Top));
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -914,6 +948,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -928,15 +963,16 @@ namespace MetaFile
|
||||
NodeAttributes arAttributes;
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
if (4 == arVertex.size())
|
||||
{
|
||||
arAttributes.push_back({L"x", ConvertToWString(std::min(arVertex[0].nX, arVertex[1].nX))});
|
||||
arAttributes.push_back({L"y", ConvertToWString(std::min(arVertex[0].nY, arVertex[2].nY))});
|
||||
arAttributes.push_back({L"width", ConvertToWString(std::abs(arVertex[1].nX - arVertex[0].nX))});
|
||||
arAttributes.push_back({L"height", ConvertToWString(std::abs(arVertex[2].nY - arVertex[0].nY))});
|
||||
arAttributes.Add(L"x", std::min(arVertex[0].nX, arVertex[1].nX));
|
||||
arAttributes.Add(L"y", std::min(arVertex[0].nY, arVertex[2].nY));
|
||||
arAttributes.Add(L"width", std::abs(arVertex[1].nX - arVertex[0].nX));
|
||||
arAttributes.Add(L"height", std::abs(arVertex[2].nY - arVertex[0].nY));
|
||||
WriteNode(L"rect" , arAttributes);
|
||||
}
|
||||
else if (3 == arVertex.size())
|
||||
@ -950,7 +986,7 @@ namespace MetaFile
|
||||
std::wstring wsValue = CreatePath(oPath);
|
||||
|
||||
if (!wsValue.empty())
|
||||
arAttributes.push_back({L"d", wsValue});
|
||||
arAttributes.Add(L"d", wsValue);
|
||||
|
||||
WriteNode(L"path" , arAttributes);
|
||||
}
|
||||
@ -969,16 +1005,17 @@ namespace MetaFile
|
||||
{
|
||||
oTempRect = TranslateRect(oRect);
|
||||
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
}
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -998,16 +1035,17 @@ namespace MetaFile
|
||||
{
|
||||
oTempRect = TranslateRect(oRect);
|
||||
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
}
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1016,6 +1054,7 @@ namespace MetaFile
|
||||
|
||||
void CEmfInterpretatorSvg::HANDLE_EMR_FRAMERGN(const TRectL &oBounds, unsigned int unIhBrush, int nWidth, int nHeight, const TRegionDataHeader &oRegionDataHeader, const std::vector<TRectL> &arRects)
|
||||
{
|
||||
m_bUpdatedClip = false;
|
||||
}
|
||||
|
||||
void CEmfInterpretatorSvg::HANDLE_EMFPLUS_OFFSETCLIP(double dX, double dY)
|
||||
@ -1085,6 +1124,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
|
||||
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
|
||||
{
|
||||
@ -1111,14 +1151,15 @@ namespace MetaFile
|
||||
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
|
||||
|
||||
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
|
||||
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1158,14 +1199,14 @@ namespace MetaFile
|
||||
int nColor = m_pParser->GetTextColor();
|
||||
|
||||
if (0 != nColor)
|
||||
arNodeAttributes.push_back({L"fill", CalculateColor(nColor, 255)});
|
||||
arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255));
|
||||
|
||||
double dFontHeight = std::fabs(pFont->GetHeight());
|
||||
|
||||
if (dFontHeight < 0.01)
|
||||
dFontHeight = 18;
|
||||
|
||||
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
|
||||
arNodeAttributes.Add(L"font-size", dFontHeight);
|
||||
|
||||
NSStringUtils::CStringBuilder oFontName;
|
||||
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
|
||||
@ -1188,21 +1229,21 @@ namespace MetaFile
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
}
|
||||
#endif
|
||||
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
|
||||
arNodeAttributes.Add(L"font-family", oFontName.GetData());
|
||||
}
|
||||
|
||||
if (pFont->GetWeight() > 550)
|
||||
arNodeAttributes.push_back({L"font-weight", L"bold"});
|
||||
arNodeAttributes.Add(L"font-weight", L"bold");
|
||||
|
||||
if (pFont->IsItalic())
|
||||
arNodeAttributes.push_back({L"font-style", L"italic"});
|
||||
arNodeAttributes.Add(L"font-style", L"italic");
|
||||
|
||||
if (pFont->IsUnderline() && pFont->IsStrikeOut())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"underline line-through"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"underline line-through");
|
||||
else if (pFont->IsUnderline())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"underline"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"underline");
|
||||
else if (pFont->IsStrikeOut())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"line-through"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"line-through");
|
||||
|
||||
AddTransform(arNodeAttributes);
|
||||
AddClip();
|
||||
@ -1218,8 +1259,8 @@ namespace MetaFile
|
||||
wsX.pop_back();
|
||||
wsY.pop_back();
|
||||
|
||||
arNodeAttributes.push_back({L"x", wsX});
|
||||
arNodeAttributes.push_back({L"y", wsY});
|
||||
arNodeAttributes.Add(L"x", wsX);
|
||||
arNodeAttributes.Add(L"y", wsY);
|
||||
|
||||
WriteNode(L"text", arNodeAttributes, wsText);
|
||||
}
|
||||
@ -1234,6 +1275,7 @@ namespace MetaFile
|
||||
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1254,6 +1296,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1273,7 +1316,9 @@ namespace MetaFile
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddLineCaps(arAttributes, pPath);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1295,17 +1340,18 @@ namespace MetaFile
|
||||
{
|
||||
oTempRect = oRect.ToRectD();
|
||||
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
|
||||
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
|
||||
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
}
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1332,6 +1378,7 @@ namespace MetaFile
|
||||
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1353,6 +1400,7 @@ namespace MetaFile
|
||||
TRectD oPathRect = pPath->GetBounds();
|
||||
|
||||
AddFill(arAttributes, std::fabs(oPathRect.Right - oPathRect.Left), std::fabs(oPathRect.Bottom - oPathRect.Top));
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -1377,6 +1425,7 @@ namespace MetaFile
|
||||
NodeAttributes arAttributes = {{L"points", wsValue}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
|
||||
NodeAttributes arGAttributes;
|
||||
@ -1387,17 +1436,18 @@ namespace MetaFile
|
||||
|
||||
void CEmfInterpretatorSvg::HANDLE_EMFPLUS_FILLRECTS(unsigned int unBrushId, const std::vector<TEmfPlusRectF> &arRects)
|
||||
{
|
||||
if (arRects.empty())
|
||||
return;
|
||||
|
||||
std::wstring wsValue;
|
||||
|
||||
TRectD oTempRect;
|
||||
TXForm oFileTransform(m_pParser->GetTransform());
|
||||
|
||||
for (const TEmfPlusRectF& oRect : arRects)
|
||||
{
|
||||
oTempRect = oRect.ToRectD();
|
||||
|
||||
m_pParser->GetTransform().Apply(oTempRect.Left, oTempRect.Top);
|
||||
m_pParser->GetTransform().Apply(oTempRect.Right, oTempRect.Bottom);
|
||||
|
||||
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
|
||||
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
|
||||
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
|
||||
@ -1405,9 +1455,13 @@ namespace MetaFile
|
||||
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
|
||||
}
|
||||
|
||||
wsValue.pop_back();
|
||||
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddTransform(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddClip();
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
@ -1448,25 +1502,15 @@ namespace MetaFile
|
||||
CInterpretatorSvgBase::PathClip(oPath, nClipMode, pTransform);
|
||||
}
|
||||
|
||||
TRectD CEmfInterpretatorSvg::TranslateRect(const TRectL &oRect) const
|
||||
void CEmfInterpretatorSvg::SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip)
|
||||
{
|
||||
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
|
||||
if (oFirstClip.StartedClip())
|
||||
WriteNodeEnd(L"g");
|
||||
|
||||
if (oNewRect.Right < oNewRect.Left)
|
||||
{
|
||||
double dTempValue = oNewRect.Left;
|
||||
oNewRect.Left = oNewRect.Right;
|
||||
oNewRect.Right = dTempValue;
|
||||
}
|
||||
if (oSecondClip.StartedClip())
|
||||
WriteNodeBegin(L"g", {{L"clip-path", L"url(#" + oSecondClip.GetClipId() + L')'}});
|
||||
|
||||
if (oNewRect.Bottom < oNewRect.Top)
|
||||
{
|
||||
double dTempValue = oNewRect.Top;
|
||||
oNewRect.Top = oNewRect.Bottom;
|
||||
oNewRect.Bottom = dTempValue;
|
||||
}
|
||||
|
||||
return oNewRect;
|
||||
std::swap(oFirstClip, oSecondClip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ namespace MetaFile
|
||||
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
|
||||
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
|
||||
|
||||
TRectD TranslateRect(const TRectL &oRect) const;
|
||||
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -155,9 +155,38 @@ namespace MetaFile
|
||||
unHeight = unDibHeigth;
|
||||
}
|
||||
|
||||
CEmfLogFont::CEmfLogFont(bool bFixedLength) : m_bFixedLength(bFixedLength)
|
||||
void CEmfLogBrushEx::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
|
||||
{
|
||||
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
|
||||
arPositions = {0., 1.};
|
||||
}
|
||||
|
||||
CEmfLogFont::CEmfLogFont(bool bFixedLength)
|
||||
: m_bFixedLength(bFixedLength)
|
||||
{
|
||||
oDesignVector.pValues = NULL;
|
||||
|
||||
oLogFontEx.oLogFont.nHeight = DEFAULT_FONT_SIZE;
|
||||
oLogFontEx.oLogFont.nWidth = 0;
|
||||
oLogFontEx.oLogFont.nEscapement = 0;
|
||||
oLogFontEx.oLogFont.nOrientation = 0;
|
||||
oLogFontEx.oLogFont.nWeight = 400;
|
||||
oLogFontEx.oLogFont.uchItalic = 0x00;
|
||||
oLogFontEx.oLogFont.uchUnderline = 0x00;
|
||||
oLogFontEx.oLogFont.uchStrikeOut = 0x00;
|
||||
oLogFontEx.oLogFont.uchCharSet = 0x01;
|
||||
oLogFontEx.oLogFont.uchOutPrecision = 0x00;
|
||||
oLogFontEx.oLogFont.uchClipPrecision = 0x00;
|
||||
oLogFontEx.oLogFont.uchQuality = 0x00;
|
||||
oLogFontEx.oLogFont.uchPitchAndFamily = 0x00;
|
||||
|
||||
memset(oLogFontEx.oLogFont.ushFaceName, 0x00, 32);
|
||||
|
||||
oLogFontEx.oLogFont.ushFaceName[0] = 'A';
|
||||
oLogFontEx.oLogFont.ushFaceName[1] = 'r';
|
||||
oLogFontEx.oLogFont.ushFaceName[2] = 'i';
|
||||
oLogFontEx.oLogFont.ushFaceName[3] = 'a';
|
||||
oLogFontEx.oLogFont.ushFaceName[4] = 'l';
|
||||
}
|
||||
|
||||
CEmfLogFont::~CEmfLogFont()
|
||||
@ -271,6 +300,16 @@ namespace MetaFile
|
||||
unSize = 0;
|
||||
}
|
||||
|
||||
const ILineCap* CEmfLogPen::GetStartLineCap() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ILineCap* CEmfLogPen::GetEndLineCap() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CEmfLogPalette::CEmfLogPalette() : ushNumberOfEntries(0), pPaletteEntries(NULL)
|
||||
{}
|
||||
|
||||
|
||||
@ -77,6 +77,8 @@ namespace MetaFile
|
||||
void GetBounds(double& left, double& top, double& width, double& height) const override;
|
||||
void GetCenterPoint(double& dX, double& dY) const override;
|
||||
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
|
||||
|
||||
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
|
||||
public:
|
||||
unsigned int unBrushStyle;
|
||||
TRGBA oColor;
|
||||
@ -122,13 +124,15 @@ namespace MetaFile
|
||||
virtual EEmfObjectType GetType() const override;
|
||||
|
||||
// IPen
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
const ILineCap* GetStartLineCap() const override;
|
||||
const ILineCap* GetEndLineCap() const override;
|
||||
public:
|
||||
unsigned int unPenStyle;
|
||||
unsigned int unWidth;
|
||||
|
||||
@ -1659,13 +1659,15 @@ namespace MetaFile
|
||||
|
||||
RestoreDC(-1);
|
||||
}
|
||||
else if (sType == "GDIC")
|
||||
else if (sType == "GDIC" && NULL != m_pInterpretator)
|
||||
{
|
||||
unsigned int unPublicCommentIdentifier;
|
||||
|
||||
m_oStream >> unPublicCommentIdentifier;
|
||||
|
||||
if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier)
|
||||
// At the moment, we are disabling support for embedded MWF files (in bug #71100 - The plus-minus symbol is not displayed correctly)
|
||||
// From the tests, it became clear that the embedded WMF files are ignored
|
||||
if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier && false)
|
||||
{
|
||||
m_oStream.Skip(12); // Version, Reserved, Checksum, Flags
|
||||
|
||||
|
||||
@ -78,8 +78,8 @@ namespace MetaFile
|
||||
unsigned int ulWidth, ulHeight;
|
||||
|
||||
if (ReadImage(oTEmfStretchDIBITS.unOffBmiSrc, oTEmfStretchDIBITS.unCbBmiSrc,
|
||||
oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc,
|
||||
sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight))
|
||||
oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc,
|
||||
sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight))
|
||||
{
|
||||
if (m_pInterpretator)
|
||||
{
|
||||
@ -761,7 +761,11 @@ namespace MetaFile
|
||||
RELEASEOBJECT(m_pInterpretator);
|
||||
|
||||
if (InterpretatorType::Svg == oInterpretatorType)
|
||||
m_pInterpretator = new CEmfInterpretatorSvg(this, dWidth, dHeight);
|
||||
{
|
||||
CEmfInterpretatorSvg *pEmfInterpretatorSvg = new CEmfInterpretatorSvg(this, dWidth, dHeight);
|
||||
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
|
||||
m_pInterpretator = pEmfInterpretatorSvg;
|
||||
}
|
||||
}
|
||||
|
||||
CEmfInterpretatorBase* CEmfParserBase::GetInterpretator()
|
||||
@ -1505,11 +1509,19 @@ namespace MetaFile
|
||||
if (NULL != m_pInterpretator && (NULL == m_pPath || Svg != m_pInterpretator->GetType()))
|
||||
m_pInterpretator->HANDLE_EMR_PIE(oBox, oStart, oEnd);
|
||||
|
||||
double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y);
|
||||
double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y) - dStartAngle;
|
||||
const int nCenterX = (oBox.Left + oBox.Right) / 2;
|
||||
const int nCenterY = (oBox.Top + oBox.Bottom) / 2;
|
||||
|
||||
ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle, dSweepAngle);
|
||||
LineTo((oBox.Left + oBox.Right) / 2, (oBox.Top + oBox.Bottom) / 2);
|
||||
double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX);
|
||||
double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX);
|
||||
|
||||
if (dEndAngle > dStartAngle)
|
||||
dEndAngle -= 2 * M_PI;
|
||||
|
||||
MoveTo(nCenterX, nCenterY);
|
||||
LineTo(oStart.X, oStart.Y);
|
||||
ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle * 180. / M_PI, (dEndAngle - dStartAngle) * 180. / M_PI);
|
||||
LineTo(nCenterX, nCenterY);
|
||||
ClosePath();
|
||||
DrawPath(true, true);
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
|
||||
#define LOG_EMF_RECORDS 0
|
||||
#define LOG_EMF_RECORDS 1
|
||||
|
||||
#ifdef LOG_EMF_RECORDS
|
||||
#if 1 == LOG_EMF_RECORDS
|
||||
|
||||
@ -655,20 +655,18 @@ namespace MetaFile
|
||||
|
||||
m_oStream >> unPositionCount;
|
||||
|
||||
std::vector<double> arBlendPositions(unPositionCount);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
|
||||
m_oStream >> arBlendPositions[unIndex];
|
||||
|
||||
std::vector<TEmfPlusARGB> arBlendColors(unPositionCount);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
|
||||
m_oStream >> arBlendColors[unIndex];
|
||||
|
||||
if (1 < unPositionCount)
|
||||
if (unPositionCount > 1)
|
||||
{
|
||||
pEmfPlusBrush->oColorBack = arBlendColors[0];
|
||||
pEmfPlusBrush->oColor = arBlendColors.back();
|
||||
pEmfPlusBrush->arGradientColors.resize(unPositionCount);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
|
||||
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second;
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
|
||||
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
|
||||
|
||||
pEmfPlusBrush->oColor = pEmfPlusBrush->arGradientColors[unPositionCount - 1].first;
|
||||
pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors[0].first;
|
||||
}
|
||||
}
|
||||
|
||||
@ -679,13 +677,40 @@ namespace MetaFile
|
||||
//TODO: реализовать
|
||||
pEmfPlusBrush->unStyle = BS_LINEARGRADIENT;
|
||||
|
||||
m_oStream.Skip(8); // BrushDataFlags, WrapMode
|
||||
int nBrushDataFlags;
|
||||
m_oStream >> nBrushDataFlags;
|
||||
|
||||
m_oStream.Skip(4); // WrapMode
|
||||
|
||||
// m_oStream >> pEmfPlusBrush->RectF;
|
||||
m_oStream.Skip(16);
|
||||
m_oStream >> pEmfPlusBrush->oColor;
|
||||
m_oStream >> pEmfPlusBrush->oColorBack;
|
||||
|
||||
m_oStream.Skip(8); // Reserved1, Reserved2
|
||||
|
||||
if (BrushDataTransform & nBrushDataFlags)
|
||||
{
|
||||
m_oStream.Skip(24);
|
||||
}
|
||||
|
||||
if (BrushDataPresetColors & nBrushDataFlags)
|
||||
{
|
||||
int nPositionCount;
|
||||
m_oStream >> nPositionCount;
|
||||
|
||||
if (nPositionCount > 1)
|
||||
{
|
||||
pEmfPlusBrush->arGradientColors.resize(nPositionCount);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex)
|
||||
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second;
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex)
|
||||
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -2266,16 +2291,21 @@ namespace MetaFile
|
||||
if (NULL != pEmfPlusPen->pBrush)
|
||||
m_pDC->SetBrush(pEmfPlusPen->pBrush);
|
||||
|
||||
CPathConverter oPathConverter;
|
||||
CPath oNewPath, oLineCapPath;
|
||||
|
||||
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
|
||||
|
||||
oNewPath.DrawOn(m_pInterpretator, true, false);
|
||||
oLineCapPath.DrawOn(m_pInterpretator, false, true);
|
||||
|
||||
if (NULL != m_pInterpretator)
|
||||
m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, &oNewPath);
|
||||
{
|
||||
CPathConverter oPathConverter;
|
||||
CPath oNewPath, oLineCapPath;
|
||||
|
||||
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
|
||||
|
||||
if (InterpretatorType::Render == m_pInterpretator->GetType())
|
||||
{
|
||||
oNewPath.DrawOn(m_pInterpretator, true, false);
|
||||
oLineCapPath.DrawOn(m_pInterpretator, false, true);
|
||||
}
|
||||
else
|
||||
m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, pPath);
|
||||
}
|
||||
|
||||
if (NULL != pEmfPlusPen->pBrush)
|
||||
m_pDC->RemoveBrush(pEmfPlusPen->pBrush);
|
||||
@ -3126,7 +3156,6 @@ namespace MetaFile
|
||||
m_oStream >> oMatrix;
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_RESETWORLDTRANSFORM()
|
||||
@ -3134,7 +3163,6 @@ namespace MetaFile
|
||||
m_bBanEmfProcessing = true;
|
||||
|
||||
m_pDC->ResetTransform();
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_ROTATEWORLDTRANSFORM(unsigned short unShFlags)
|
||||
@ -3153,7 +3181,6 @@ namespace MetaFile
|
||||
TEmfPlusXForm oMatrix(dCosTheta, dSinTheta, -dSinTheta, dCosTheta, 0, 0);
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_SCALEWORLDTRANSFORM(unsigned short unShFlags)
|
||||
@ -3168,7 +3195,6 @@ namespace MetaFile
|
||||
TEmfPlusXForm oMatrix(dSx, 0, 0, dSy, 0, 0);
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_SETPAGETRANSFORM(unsigned short unShFlags)
|
||||
@ -3185,8 +3211,6 @@ namespace MetaFile
|
||||
|
||||
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
|
||||
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
|
||||
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_SETWORLDTRANSFORM()
|
||||
@ -3196,11 +3220,8 @@ namespace MetaFile
|
||||
m_oStream >> oMatrix;
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, MWT_SET);
|
||||
|
||||
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
|
||||
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
|
||||
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_TRANSLATEWORLDTRANSFORM(unsigned short unShFlags)
|
||||
@ -3213,7 +3234,6 @@ namespace MetaFile
|
||||
TEmfPlusXForm oMatrix(1, 0, 0, 1, dX, dY);
|
||||
|
||||
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
|
||||
UpdateOutputDC();
|
||||
}
|
||||
|
||||
void CEmfPlusParser::Read_EMFPLUS_ENDOFFILE()
|
||||
|
||||
@ -27,7 +27,6 @@ namespace MetaFile
|
||||
|
||||
void SetStream(BYTE *pBytes, unsigned int unSize);
|
||||
bool GetBanEMFProcesses();
|
||||
|
||||
private:
|
||||
void RegisterObject(CEmfPlusObject* pObject, unsigned int unIndex);
|
||||
|
||||
|
||||
@ -728,7 +728,7 @@ namespace MetaFile
|
||||
m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
|
||||
m_oFinalTransform2.Init();
|
||||
m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
// m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
|
||||
m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
|
||||
}
|
||||
|
||||
@ -79,6 +79,26 @@ namespace MetaFile
|
||||
height = oRectF.dHeight;
|
||||
}
|
||||
|
||||
void CEmfPlusBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
|
||||
{
|
||||
if (arGradientColors.empty())
|
||||
{
|
||||
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
|
||||
arPositions = {0., 1.};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
arColors.resize(arGradientColors.size());
|
||||
arPositions.resize(arGradientColors.size());
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < arGradientColors.size(); ++unIndex)
|
||||
{
|
||||
arColors[unIndex] = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha);
|
||||
arPositions[unIndex] = arGradientColors[unIndex].second;
|
||||
}
|
||||
}
|
||||
|
||||
CEmfPlusPen::CEmfPlusPen()
|
||||
: unStyle(PS_SOLID | PS_GEOMETRIC | PS_STARTCAP_FLAT | PS_ENDCAP_FLAT | PS_JOIN_MITER), dWidth(1), oColor(0, 0, 0),
|
||||
pBrush(NULL), dMiterLimit(0), dDashOffset(0),
|
||||
@ -90,7 +110,7 @@ namespace MetaFile
|
||||
RELEASEOBJECT(pBrush)
|
||||
RELEASEARRAYOBJECTS(pDataDash)
|
||||
RELEASEOBJECT(pLineStartCapData)
|
||||
RELEASEOBJECT(pLineEndCapData)
|
||||
RELEASEOBJECT(pLineEndCapData)
|
||||
}
|
||||
|
||||
EEmfObjectType CEmfPlusPen::GetType() const
|
||||
@ -148,6 +168,16 @@ namespace MetaFile
|
||||
unSize = unSizeDash;
|
||||
}
|
||||
|
||||
const ILineCap* CEmfPlusPen::GetStartLineCap() const
|
||||
{
|
||||
return pLineStartCapData;
|
||||
}
|
||||
|
||||
const ILineCap* CEmfPlusPen::GetEndLineCap() const
|
||||
{
|
||||
return pLineEndCapData;
|
||||
}
|
||||
|
||||
CEmfPlusFont::CEmfPlusFont()
|
||||
: m_dEmSize(18), m_unSizeUnit(0), m_bBold(false),
|
||||
m_bItalic(false), m_bUnderline(false), m_bStrikeout(false),
|
||||
|
||||
@ -189,6 +189,7 @@ namespace MetaFile
|
||||
void GetCenterPoint(double& dX, double& dY) const override;
|
||||
void GetBounds(double& left, double& top, double& width, double& height) const override;
|
||||
|
||||
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
|
||||
public:
|
||||
TEmfPlusARGB oColor;
|
||||
TEmfPlusARGB oColorBack;
|
||||
@ -198,6 +199,8 @@ namespace MetaFile
|
||||
TEmfPlusPointF oCenterPoint;
|
||||
unsigned int unAngle;
|
||||
std::wstring wsDibPatternPath;
|
||||
|
||||
std::vector<std::pair<TEmfPlusARGB, double>> arGradientColors;
|
||||
};
|
||||
|
||||
class CEmfPlusPen: public CEmfPlusObject, public IPen
|
||||
@ -209,14 +212,15 @@ namespace MetaFile
|
||||
virtual EEmfPlusObjectType GetObjectType() const override;
|
||||
|
||||
// IPen
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
const ILineCap* GetStartLineCap() const override;
|
||||
const ILineCap* GetEndLineCap() const override;
|
||||
public:
|
||||
unsigned int unStyle;
|
||||
double dWidth;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define EMFPLUSTYPES_H
|
||||
|
||||
#include "EmfTypes.h"
|
||||
#include "../Common/MetaFileObjects.h"
|
||||
|
||||
namespace MetaFile
|
||||
{
|
||||
@ -243,7 +244,7 @@ namespace MetaFile
|
||||
CustomLineCapDataLinePath = 0x00000002
|
||||
} CustomLineCapDataFlags;
|
||||
|
||||
class CLineCapData
|
||||
class CLineCapData : public ILineCap
|
||||
{
|
||||
public:
|
||||
CLineCapData() {};
|
||||
|
||||
@ -448,6 +448,37 @@ namespace MetaFile
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMetaFile::LoadFromString(const std::wstring& data)
|
||||
{
|
||||
#ifdef METAFILE_SUPPORT_SVG
|
||||
RELEASEINTERFACE(m_pFontManager);
|
||||
|
||||
if (m_pAppFonts)
|
||||
{
|
||||
m_pFontManager = m_pAppFonts->GenerateFontManager();
|
||||
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
|
||||
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
|
||||
m_pFontManager->SetOwnerCache(pMeasurerCache);
|
||||
}
|
||||
|
||||
m_oSvgFile.SetFontManager(m_pFontManager);
|
||||
|
||||
if (m_oSvgFile.ReadFromWString(data) == true)
|
||||
{
|
||||
m_lType = c_lMetaSvg;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMetaFile::SetTempDirectory(const std::wstring& dir)
|
||||
{
|
||||
#ifdef METAFILE_SUPPORT_SVG
|
||||
m_oSvgFile.SetWorkingDirectory(dir);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
|
||||
{
|
||||
if (NULL == pRenderer)
|
||||
|
||||
@ -64,6 +64,7 @@ namespace MetaFile
|
||||
|
||||
bool LoadFromFile(const wchar_t* wsFilePath);
|
||||
bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize);
|
||||
bool LoadFromString(const std::wstring& data);
|
||||
bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
|
||||
void Close();
|
||||
void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH);
|
||||
@ -75,6 +76,8 @@ namespace MetaFile
|
||||
//конвертация в Svg
|
||||
std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0);
|
||||
|
||||
void SetTempDirectory(const std::wstring& dir);
|
||||
|
||||
//Для тестов
|
||||
#ifdef METAFILE_SUPPORT_WMF_EMF
|
||||
void ConvertToXml(const wchar_t *wsFilePath);
|
||||
|
||||
@ -358,6 +358,12 @@ void CSvmBrush::GetBounds(double& left, double& top, double& width, double& heig
|
||||
void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const
|
||||
{}
|
||||
|
||||
void CSvmBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
|
||||
{
|
||||
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
|
||||
arPositions = {0., 1.};
|
||||
}
|
||||
|
||||
int CSvmPen::GetColor() const
|
||||
{
|
||||
return METAFILE_RGBA(Color.r, Color.g, Color.b, 0);
|
||||
|
||||
@ -300,6 +300,7 @@ public:
|
||||
void GetBounds(double& left, double& top, double& width, double& height) const override;
|
||||
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
|
||||
|
||||
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
|
||||
public:
|
||||
unsigned short BrushStyleEx; //angle, or ....
|
||||
unsigned short BrushStyle;
|
||||
@ -448,6 +449,14 @@ public:
|
||||
arDatas = NULL;
|
||||
unSize = 0;
|
||||
}
|
||||
const ILineCap* GetStartLineCap() const override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
const ILineCap* GetEndLineCap() const override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
public:
|
||||
unsigned short PenStyle;
|
||||
int Width;
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
|
||||
#include "../../common/Directory.h"
|
||||
#include "../../fontengine/ApplicationFonts.h"
|
||||
#include "../../../HtmlRenderer/include/ASCSVGWriter.h"
|
||||
#include "MetaFile.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
|
||||
@ -75,7 +75,8 @@ namespace MetaFile
|
||||
};
|
||||
|
||||
CInterpretatorSvgBase::CInterpretatorSvgBase(IMetaFileBase *pParser, double dWidth, double dHeight)
|
||||
: m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()), m_bExternXmlWriter(false), m_bUpdatedClip(true)
|
||||
: m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()),
|
||||
m_bExternXmlWriter(false), m_bUpdatedClip(true), m_eShapeRendering(EShapeRendering::Auto)
|
||||
{}
|
||||
|
||||
CInterpretatorSvgBase::~CInterpretatorSvgBase()
|
||||
@ -127,6 +128,11 @@ namespace MetaFile
|
||||
return m_pXmlWriter;
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::SetShapeRendering(EShapeRendering eShapeRenderingType)
|
||||
{
|
||||
m_eShapeRendering = eShapeRenderingType;
|
||||
}
|
||||
|
||||
std::wstring CInterpretatorSvgBase::GetFile()
|
||||
{
|
||||
return m_pXmlWriter->GetXmlString();
|
||||
@ -211,16 +217,6 @@ namespace MetaFile
|
||||
m_pXmlWriter->WriteNodeEnd(wsNodeName, false, false);
|
||||
}
|
||||
|
||||
static void EraseWords(std::wstring& wsString, const std::vector<std::wstring>& arWords)
|
||||
{
|
||||
size_t unBegin = 0;
|
||||
for (const std::wstring& wsWord : arWords)
|
||||
{
|
||||
while (std::wstring::npos != (unBegin = wsString.find(wsWord)))
|
||||
wsString.erase(unBegin, wsWord.length());
|
||||
}
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::WriteText(const std::wstring &wsText, const TPointD &oCoord, const TRectL &oBounds, const TPointD &oScale, const std::vector<double>& arDx)
|
||||
{
|
||||
if (NULL == m_pParser || NULL == m_pParser->GetFont())
|
||||
@ -256,30 +252,31 @@ namespace MetaFile
|
||||
WriteNodeBegin(L"g", {});
|
||||
bWriteG = true;
|
||||
|
||||
WriteNode(L"rect", {{L"x", ConvertToWString(oBounds.Left)},
|
||||
{L"y", ConvertToWString(oBounds.Top)},
|
||||
{L"width", ConvertToWString(oBounds.Right - oBounds.Left)},
|
||||
{L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)},
|
||||
{L"fill", wsFillRect},
|
||||
{L"stroke", L"none"}});
|
||||
NodeAttributes arRectAttributes{{L"x", ConvertToWString(oBounds.Left)},
|
||||
{L"y", ConvertToWString(oBounds.Top)},
|
||||
{L"width", ConvertToWString(oBounds.Right - oBounds.Left)},
|
||||
{L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)},
|
||||
{L"fill", wsFillRect},
|
||||
{L"stroke", L"none"}};
|
||||
|
||||
AddShapeRendering(arRectAttributes);
|
||||
|
||||
WriteNode(L"rect", arNodeAttributes);
|
||||
}
|
||||
|
||||
int nColor = m_pParser->GetTextColor();
|
||||
|
||||
if (0 != nColor)
|
||||
arNodeAttributes.push_back({L"fill", CalculateColor(nColor, 255)});
|
||||
arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255));
|
||||
|
||||
const IFont *pFont = m_pParser->GetFont();
|
||||
|
||||
if (NULL == pFont)
|
||||
return;
|
||||
|
||||
double dFontHeight = std::fabs(pFont->GetHeight());
|
||||
|
||||
if (dFontHeight < 0.01)
|
||||
dFontHeight = 18;
|
||||
dFontHeight = DEFAULT_FONT_SIZE;
|
||||
|
||||
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
|
||||
arNodeAttributes.Add(L"font-size", dFontHeight);
|
||||
|
||||
NSStringUtils::CStringBuilder oFontName;
|
||||
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
|
||||
@ -302,21 +299,21 @@ namespace MetaFile
|
||||
oFontName.WriteEncodeXmlString(L"\'");
|
||||
}
|
||||
#endif
|
||||
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
|
||||
arNodeAttributes.Add(L"font-family", oFontName.GetData());
|
||||
}
|
||||
|
||||
if (pFont->GetWeight() > 550)
|
||||
arNodeAttributes.push_back({L"font-weight", L"bold"});
|
||||
arNodeAttributes.Add(L"font-weight", L"bold");
|
||||
|
||||
if (pFont->IsItalic())
|
||||
arNodeAttributes.push_back({L"font-style", L"italic"});
|
||||
arNodeAttributes.Add(L"font-style", L"italic");
|
||||
|
||||
if (pFont->IsUnderline() && pFont->IsStrikeOut())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"underline line-through"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"underline line-through");
|
||||
else if (pFont->IsUnderline())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"underline"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"underline");
|
||||
else if (pFont->IsStrikeOut())
|
||||
arNodeAttributes.push_back({L"text-decoration", L"line-through"});
|
||||
arNodeAttributes.Add(L"text-decoration", L"line-through");
|
||||
|
||||
//TODO:: разобраться для корректной работы
|
||||
// double dFontCharSpace = pFont->GetCharSet();
|
||||
@ -338,14 +335,14 @@ namespace MetaFile
|
||||
}
|
||||
else if (ulTextAlign & TA_BOTTOM || ulVTextAlign == VTA_BOTTOM)
|
||||
{
|
||||
arNodeAttributes.push_back({L"dominant-baseline", L"auto"});
|
||||
arNodeAttributes.Add(L"dominant-baseline", L"auto");
|
||||
|
||||
if (ulVTextAlign != VTA_BOTTOM)
|
||||
ulTextAlign -= TA_BOTTOM;
|
||||
}
|
||||
else if (ulVTextAlign == VTA_CENTER)
|
||||
{
|
||||
arNodeAttributes.push_back({L"dominant-baseline", L"middle"});
|
||||
arNodeAttributes.Add(L"dominant-baseline", L"middle");
|
||||
}
|
||||
else // if (ulTextAlign & TA_TOP)
|
||||
{
|
||||
@ -355,14 +352,14 @@ namespace MetaFile
|
||||
if (ulTextAlign == TA_RIGHT)
|
||||
{
|
||||
if (arDx.empty())
|
||||
arNodeAttributes.push_back({L"text-anchor", L"end"});
|
||||
arNodeAttributes.Add(L"text-anchor", L"end");
|
||||
else
|
||||
dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0);
|
||||
}
|
||||
else if (ulTextAlign == TA_CENTER)
|
||||
{
|
||||
if (arDx.empty())
|
||||
arNodeAttributes.push_back({L"text-anchor", L"middle"});
|
||||
arNodeAttributes.Add(L"text-anchor", L"middle");
|
||||
else
|
||||
dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0) / 2;
|
||||
}
|
||||
@ -394,7 +391,7 @@ namespace MetaFile
|
||||
if (oScale.Y < -0.00001)
|
||||
dXCoord -= dFontHeight * dSin;
|
||||
|
||||
arNodeAttributes.push_back({L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')'});
|
||||
arNodeAttributes.Add(L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')');
|
||||
|
||||
if (oScale.Y > 0.00001)
|
||||
dXCoord -= dFontHeight * dSin;
|
||||
@ -402,7 +399,7 @@ namespace MetaFile
|
||||
|
||||
AddTransform(arNodeAttributes, &oTransform);
|
||||
|
||||
arNodeAttributes.push_back({L"xml:space", L"preserve"});
|
||||
arNodeAttributes.Add(L"xml:space", L"preserve");
|
||||
|
||||
size_t unPosLineBreak = wsNormalizedText.find(L"\n");
|
||||
|
||||
@ -424,8 +421,8 @@ namespace MetaFile
|
||||
|
||||
if (std::wstring::npos == unPosLineBreak)
|
||||
{
|
||||
arNodeAttributes.push_back({L"x", wsXCoord});
|
||||
arNodeAttributes.push_back({L"y", ConvertToWString(dYCoord)});
|
||||
arNodeAttributes.Add(L"x", wsXCoord);
|
||||
arNodeAttributes.Add(L"y", dYCoord);
|
||||
|
||||
WriteNode(L"text", arNodeAttributes, wsNormalizedText);
|
||||
}
|
||||
@ -439,7 +436,7 @@ namespace MetaFile
|
||||
do
|
||||
{
|
||||
WriteNode(L"tspan", {{L"x", wsXCoord},
|
||||
{L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart));
|
||||
{L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart));
|
||||
|
||||
dYNewCoord += dFontHeight * 1.6;
|
||||
unStart = wsNormalizedText.find_first_not_of(L"\n", unPosLineBreak);
|
||||
@ -499,6 +496,7 @@ namespace MetaFile
|
||||
{L"height", ConvertToWString(dH)},
|
||||
{L"fill", CalculateColor(pBuffer[2], pBuffer[1], pBuffer[0], 255)}};
|
||||
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes, &oTransform);
|
||||
AddClip();
|
||||
|
||||
@ -562,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);
|
||||
}
|
||||
@ -579,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);
|
||||
}
|
||||
@ -630,10 +626,10 @@ namespace MetaFile
|
||||
|
||||
switch (m_pParser->GetRop2Mode())
|
||||
{
|
||||
case R2_BLACK: arAttributes.push_back({L"stroke", L"rgb(0, 0, 0)"}); break;
|
||||
case R2_BLACK: arAttributes.Add(L"stroke", L"rgb(0, 0, 0)"); break;
|
||||
case R2_NOP: return;
|
||||
case R2_WHITE: arAttributes.push_back({L"stroke", L"rgb(255, 255, 255)"}); break;
|
||||
default: arAttributes.push_back({L"stroke", CalculateColor(pPen->GetColor(), pPen->GetAlpha())}); break;
|
||||
case R2_WHITE: arAttributes.Add(L"stroke", L"rgb(255, 255, 255)"); break;
|
||||
default: arAttributes.Add(L"stroke", CalculateColor(pPen->GetColor(), pPen->GetAlpha())); break;
|
||||
}
|
||||
|
||||
unsigned int unMetaPenStyle = pPen->GetStyle();
|
||||
@ -668,19 +664,16 @@ namespace MetaFile
|
||||
|
||||
double dStrokeWidth = std::fabs(m_pParser->GetPen()->GetWidth());
|
||||
|
||||
if (Equals(0, dStrokeWidth) || (Equals(1, dStrokeWidth) && PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK)))
|
||||
if (Equals(0., dStrokeWidth))
|
||||
{
|
||||
dStrokeWidth = 1;
|
||||
arAttributes.push_back({L"vector-effect", L"non-scaling-stroke"});
|
||||
|
||||
wsLineCap = L"butt";
|
||||
wsLineJoin = L"miter";
|
||||
dStrokeWidth = 1.;
|
||||
arAttributes.Add(L"vector-effect", L"non-scaling-stroke");
|
||||
}
|
||||
|
||||
arAttributes.push_back({L"stroke-width", ConvertToWString(dStrokeWidth)});
|
||||
arAttributes.push_back({L"stroke-miterlimit", ConvertToWString(pPen->GetMiterLimit())});
|
||||
arAttributes.push_back({L"stroke-linecap", wsLineCap});
|
||||
arAttributes.push_back({L"stroke-linejoin", wsLineJoin});
|
||||
arAttributes.Add(L"stroke-width", dStrokeWidth);
|
||||
arAttributes.Add(L"stroke-miterlimit", pPen->GetMiterLimit());
|
||||
arAttributes.Add(L"stroke-linecap", wsLineCap);
|
||||
arAttributes.Add(L"stroke-linejoin", wsLineJoin);
|
||||
|
||||
double* arDatas = NULL;
|
||||
unsigned int unDataSize = 0;
|
||||
@ -700,23 +693,23 @@ namespace MetaFile
|
||||
}
|
||||
wsDashArray.pop_back();
|
||||
|
||||
arAttributes.push_back({L"stroke-dasharray", wsDashArray});
|
||||
arAttributes.Add(L"stroke-dasharray", wsDashArray);
|
||||
}
|
||||
else if (PS_DASH == ulPenStyle)
|
||||
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2)});
|
||||
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2));
|
||||
else if (PS_DOT == ulPenStyle)
|
||||
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth)});
|
||||
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth));
|
||||
else if (PS_DASHDOT == ulPenStyle)
|
||||
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)});
|
||||
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2));
|
||||
else if (PS_DASHDOTDOT == ulPenStyle)
|
||||
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)});
|
||||
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2));
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::AddFill(NodeAttributes &arAttributes, double dWidth, double dHeight)
|
||||
{
|
||||
if (NULL == m_pParser)
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"none"});
|
||||
arAttributes.Add(L"fill", L"none");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -735,7 +728,7 @@ namespace MetaFile
|
||||
|
||||
if (NULL == pBrush || BS_NULL == pBrush->GetStyle())
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"none"});
|
||||
arAttributes.Add(L"fill", L"none");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -743,7 +736,7 @@ namespace MetaFile
|
||||
{
|
||||
case BS_SOLID:
|
||||
{
|
||||
arAttributes.push_back({L"fill", CalculateColor(pBrush->GetColor(), pBrush->GetAlpha())});
|
||||
arAttributes.Add(L"fill", CalculateColor(pBrush->GetColor(), pBrush->GetAlpha()));
|
||||
return;
|
||||
}
|
||||
case BS_HATCHED:
|
||||
@ -752,7 +745,7 @@ namespace MetaFile
|
||||
|
||||
if (!wsStyleId.empty())
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
|
||||
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -764,7 +757,7 @@ namespace MetaFile
|
||||
|
||||
if (!wsStyleId.empty())
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
|
||||
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -774,7 +767,7 @@ namespace MetaFile
|
||||
|
||||
if (!wsStyleId.empty())
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
|
||||
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -788,12 +781,12 @@ namespace MetaFile
|
||||
|
||||
if (!wsStyleId.empty())
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
|
||||
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
arAttributes.push_back({L"fill", L"none"});
|
||||
arAttributes.Add(L"fill", L"none");
|
||||
}
|
||||
}
|
||||
|
||||
@ -832,7 +825,7 @@ namespace MetaFile
|
||||
|
||||
if (bScale && !bTranslate)
|
||||
{
|
||||
wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')';
|
||||
wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')';
|
||||
}
|
||||
else if (bTranslate && !bScale)
|
||||
{
|
||||
@ -840,18 +833,18 @@ namespace MetaFile
|
||||
}
|
||||
else if (bScale && bTranslate)
|
||||
{
|
||||
wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' +
|
||||
ConvertToWString(oOldTransform.M12) + L',' +
|
||||
ConvertToWString(oOldTransform.M21) + L',' +
|
||||
ConvertToWString(oOldTransform.M22) + L',' +
|
||||
ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')';
|
||||
wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' +
|
||||
ConvertToWString(oOldTransform.M12) + L',' +
|
||||
ConvertToWString(oOldTransform.M21) + L',' +
|
||||
ConvertToWString(oOldTransform.M22) + L',' +
|
||||
ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')';
|
||||
}
|
||||
else return;
|
||||
|
||||
if (NULL != pFoundTransform)
|
||||
pFoundTransform->second.insert(0, wsValue + L' ');
|
||||
else
|
||||
arAttributes.push_back({L"transform", wsValue});
|
||||
arAttributes.Add(L"transform", wsValue);
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::AddClip()
|
||||
@ -891,7 +884,101 @@ namespace MetaFile
|
||||
|
||||
void CInterpretatorSvgBase::AddNoneFill(NodeAttributes &arAttributes) const
|
||||
{
|
||||
arAttributes.push_back({L"fill", L"none"});
|
||||
arAttributes.Add(L"fill", L"none");
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::AddShapeRendering(NodeAttributes& arAttributes) const
|
||||
{
|
||||
switch (m_eShapeRendering)
|
||||
{
|
||||
case EShapeRendering::OptimizeSpeed:
|
||||
{
|
||||
arAttributes.Add(L"shape-rendering", L"optimizeSpeed");
|
||||
break;
|
||||
}
|
||||
case EShapeRendering::CrispEdges:
|
||||
{
|
||||
arAttributes.Add(L"shape-rendering", L"crispEdges");
|
||||
break;
|
||||
}
|
||||
case EShapeRendering::GeometricPrecision:
|
||||
{
|
||||
arAttributes.Add(L"shape-rendering", L"geometricPrecision");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TPointD GetFirstPoint(const CPathCommandBase* pPathCommand)
|
||||
{
|
||||
if (NULL == pPathCommand)
|
||||
return {0., 0.};
|
||||
|
||||
switch (pPathCommand->GetType())
|
||||
{
|
||||
case EPathCommandType::PATH_COMMAND_MOVETO:
|
||||
{
|
||||
CPathCommandMoveTo* pMoveTo{(CPathCommandMoveTo*)pPathCommand};
|
||||
return {pMoveTo->GetX(), pMoveTo->GetY()};
|
||||
}
|
||||
case EPathCommandType::PATH_COMMAND_LINETO:
|
||||
{
|
||||
CPathCommandLineTo* pLineTo{(CPathCommandLineTo*)pPathCommand};
|
||||
return {pLineTo->GetX(), pLineTo->GetY()};
|
||||
}
|
||||
default:
|
||||
return {0., 0.};
|
||||
}
|
||||
}
|
||||
|
||||
void CInterpretatorSvgBase::AddLineCaps(NodeAttributes& arAttributes, const CPath* pMainPath)
|
||||
{
|
||||
if (NULL == m_pParser || NULL == m_pParser->GetPen() || NULL == pMainPath)
|
||||
return;
|
||||
|
||||
const IPen *pPen = m_pParser->GetPen();
|
||||
const std::vector<CPathCommandBase *> arCommands{pMainPath->GetCommands()};
|
||||
const CLineCapData* pStartLineCap = dynamic_cast<const CLineCapData*>(pPen->GetStartLineCap());
|
||||
|
||||
if (NULL != pStartLineCap)
|
||||
{
|
||||
double dAngle = 0.;
|
||||
|
||||
if (arCommands.size() > 1)
|
||||
{
|
||||
const TPointD oFirstPoint {GetFirstPoint(arCommands[0])};
|
||||
const TPointD oSecondPoint{GetFirstPoint(arCommands[1])};
|
||||
|
||||
dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.;
|
||||
}
|
||||
|
||||
const std::wstring wsStartLineCapId{CreateLineCap(pStartLineCap, dAngle)};
|
||||
|
||||
if (!wsStartLineCapId.empty())
|
||||
arAttributes.Add(L"marker-start", L"url(#" + wsStartLineCapId + L')');
|
||||
}
|
||||
|
||||
const CLineCapData* pEndLineCap = dynamic_cast<const CLineCapData*>(pPen->GetEndLineCap());
|
||||
|
||||
if (NULL != pEndLineCap)
|
||||
{
|
||||
double dAngle = 0.;
|
||||
|
||||
if (arCommands.size() > 1)
|
||||
{
|
||||
const TPointD oFirstPoint {GetFirstPoint(arCommands[arCommands.size() - 1])};
|
||||
const TPointD oSecondPoint{GetFirstPoint(arCommands[arCommands.size() - 2])};
|
||||
|
||||
dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.;
|
||||
}
|
||||
|
||||
const std::wstring wsEndLineCapId{CreateLineCap(pEndLineCap, dAngle)};
|
||||
|
||||
if (!wsEndLineCapId.empty())
|
||||
arAttributes.Add(L"marker-end", L"url(#" + wsEndLineCapId + L')');
|
||||
}
|
||||
}
|
||||
|
||||
TPointD CInterpretatorSvgBase::GetCutPos() const
|
||||
@ -902,7 +989,7 @@ namespace MetaFile
|
||||
return TPointD(m_oViewport.dLeft, m_oViewport.dRight);
|
||||
}
|
||||
|
||||
std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform)
|
||||
std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform) const
|
||||
{
|
||||
if (NULL == m_pParser || oPath.Empty())
|
||||
return std::wstring();
|
||||
@ -969,9 +1056,9 @@ namespace MetaFile
|
||||
oTransform.Apply(oPoint2.X, oPoint2.Y);
|
||||
oTransform.Apply(oPointE.X, oPointE.Y);
|
||||
|
||||
wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' +
|
||||
ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' +
|
||||
ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' ';
|
||||
wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' +
|
||||
ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' +
|
||||
ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' ';
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1187,16 +1274,23 @@ namespace MetaFile
|
||||
|
||||
std::wstring wsStyleId;
|
||||
|
||||
if (BS_LINEARGRADIENT == pBrush->GetStyle() ||
|
||||
BS_RECTGRADIENT == pBrush->GetStyle() ||
|
||||
BS_PATHGRADIENT == pBrush->GetStyle())
|
||||
if (BS_LINEARGRADIENT == pBrush->GetStyle() ||
|
||||
BS_RECTGRADIENT == pBrush->GetStyle() ||
|
||||
BS_PATHGRADIENT == pBrush->GetStyle())
|
||||
{
|
||||
wsStyleId = L"LINEARGRADIENT_" + ConvertToWString(++m_unNumberDefs, 0);
|
||||
|
||||
m_wsDefs += L"<linearGradient id=\"" + wsStyleId + L"\">" +
|
||||
L"<stop offset=\"0%\" stop-color=\"" + CalculateColor(pBrush->GetColor(), pBrush->GetAlpha()) + L"\"/>" +
|
||||
L"<stop offset=\"100%\" stop-color=\"" + CalculateColor(pBrush->GetColor2(), pBrush->GetAlpha2()) + L"\"/>" +
|
||||
L"</linearGradient>";
|
||||
m_wsDefs += L"<linearGradient id=\"" + wsStyleId + L"\">";
|
||||
|
||||
std::vector<long> arColors;
|
||||
std::vector<double> arPositions;
|
||||
pBrush->GetGradientColors(arColors, arPositions);
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex)
|
||||
m_wsDefs += L"<stop offset=\"" + ConvertToWString(arPositions[unIndex], 2) +
|
||||
L"\" stop-color=\"" + CalculateColor(arColors[unIndex]) + L"\"/>";
|
||||
|
||||
m_wsDefs += L"</linearGradient>";
|
||||
|
||||
return wsStyleId;
|
||||
}
|
||||
@ -1237,6 +1331,46 @@ namespace MetaFile
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
std::wstring CInterpretatorSvgBase::CreateLineCap(const CLineCapData* pLineCap, const double& dAngle)
|
||||
{
|
||||
if (NULL == pLineCap)
|
||||
return std::wstring();
|
||||
|
||||
CustomLineCapDataType enLineCapDataType = pLineCap->GetType();
|
||||
|
||||
if (CustomLineCapDataType::CustomLineCapDataTypeDefault == enLineCapDataType)
|
||||
{
|
||||
const TEmfPlusCustomLineCapData* pCustomLineCap = dynamic_cast<const TEmfPlusCustomLineCapData*>(pLineCap);
|
||||
|
||||
if (NULL == pCustomLineCap)
|
||||
return std::wstring();
|
||||
|
||||
const std::wstring wsPath = CreatePath(*pCustomLineCap->pPath);
|
||||
|
||||
if (wsPath.empty())
|
||||
return std::wstring();
|
||||
|
||||
const std::wstring wsMarkerId {L"CUSTOM_MARKER_" + std::to_wstring(++m_unNumberDefs)};
|
||||
const TRectD oPathBounds{pCustomLineCap->pPath->GetBounds()};
|
||||
const double dWidth {std::abs(oPathBounds.Right - oPathBounds.Left)};
|
||||
const double dHeight {std::abs(oPathBounds.Bottom - oPathBounds.Top)};
|
||||
const std::wstring wsWidth {ConvertToWString(dWidth)};
|
||||
const std::wstring wsHeight {ConvertToWString(dHeight)};
|
||||
const std::wstring wsViewBox {L"viewBox=\"" + ConvertToWString(oPathBounds.Left) + L' ' + ConvertToWString(oPathBounds.Top) +
|
||||
L' ' + wsWidth + L' ' + wsHeight + L'\"'};
|
||||
|
||||
const double dRefY = -dHeight * (std::min)(3. / dWidth, 3. / dHeight);
|
||||
|
||||
m_wsDefs += L"<marker id=\"" + wsMarkerId + L"\" " + wsViewBox + L" markerWidth=\"" +
|
||||
wsWidth + L"\" markerHeight=\"" + wsHeight + L"\" refY=\"" + ConvertToWString(dRefY) +
|
||||
L"\" orient=\"" + std::to_wstring(dAngle) + L"\"><path d=\"" + wsPath + L"\"/></marker>";
|
||||
|
||||
return wsMarkerId;
|
||||
}
|
||||
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
CHatchGenerator::CHatchGenerator()
|
||||
: m_nHatchStyle(-1), m_unNumber(0), m_chStrokeAlpha(255), m_nBackgroundColor(-1), m_chBackgroundAlpha(255)
|
||||
{}
|
||||
@ -1936,4 +2070,29 @@ namespace MetaFile
|
||||
|
||||
return L"rgba(" + std::to_wstring(uchRed) + L", " + std::to_wstring(uchGreen) + L", " + std::to_wstring(uchBlue) + L", " + ConvertToWString((double)uchAlpha / 255., 3) + L')';
|
||||
}
|
||||
|
||||
std::wstring CalculateColor(unsigned int unColor)
|
||||
{
|
||||
BYTE chAlpha = unColor >> 24;
|
||||
|
||||
return CalculateColor(unColor, chAlpha);
|
||||
}
|
||||
|
||||
void NormalizeRect(TRectD& oRect)
|
||||
{
|
||||
if (oRect.Right < oRect.Left)
|
||||
std::swap(oRect.Right, oRect.Left);
|
||||
|
||||
if (oRect.Bottom < oRect.Top)
|
||||
std::swap(oRect.Bottom, oRect.Top);
|
||||
}
|
||||
|
||||
TRectD TranslateRect(const TRectL& oRect)
|
||||
{
|
||||
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
|
||||
|
||||
NormalizeRect(oNewRect);
|
||||
|
||||
return oNewRect;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ namespace MetaFile
|
||||
|
||||
void AddClipValue(const std::wstring& wsId, const std::wstring& wsValue, int nClipMode = RGN_AND);
|
||||
|
||||
inline std::wstring GetClip() const;
|
||||
inline std::wstring GetClipId() const;
|
||||
std::wstring GetClip() const;
|
||||
std::wstring GetClipId() const;
|
||||
private:
|
||||
struct TClipValue
|
||||
{
|
||||
@ -77,6 +77,14 @@ namespace MetaFile
|
||||
bool m_bStartClip;
|
||||
};
|
||||
|
||||
enum class EShapeRendering
|
||||
{
|
||||
Auto,
|
||||
OptimizeSpeed,
|
||||
CrispEdges,
|
||||
GeometricPrecision
|
||||
};
|
||||
|
||||
class CInterpretatorSvgBase : public IOutputDevice
|
||||
{
|
||||
public:
|
||||
@ -90,6 +98,8 @@ namespace MetaFile
|
||||
void SetXmlWriter(XmlUtils::CXmlWriter* pXmlWriter);
|
||||
XmlUtils::CXmlWriter* GetXmlWriter();
|
||||
|
||||
void SetShapeRendering(EShapeRendering eShapeRenderingType);
|
||||
|
||||
std::wstring GetFile();
|
||||
void IncludeSvg(const std::wstring& wsSvg, const TRectD& oRect, const TRectD& oClipRect, TXForm *pTransform);
|
||||
private:
|
||||
@ -115,14 +125,18 @@ namespace MetaFile
|
||||
void CloseClip();
|
||||
|
||||
void AddNoneFill(NodeAttributes &arAttributes) const;
|
||||
void AddShapeRendering(NodeAttributes &arAttributes) const;
|
||||
|
||||
void AddLineCaps(NodeAttributes &arAttributes, const CPath* pMainPath);
|
||||
|
||||
TPointD GetCutPos() const;
|
||||
|
||||
std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL);
|
||||
std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL) const;
|
||||
std::wstring CreateHatchStyle(unsigned int unHatchStyle, double dWidth, double dHeight);
|
||||
std::wstring CreateDibPatternStyle(const IBrush* pBrush);
|
||||
std::wstring CreatePatternStyle(const IBrush* pBrush);
|
||||
std::wstring CreateGradient(const IBrush *pBrush);
|
||||
std::wstring CreateLineCap(const CLineCapData* pLineCap, const double& dAngle);
|
||||
private:
|
||||
TSvgViewport m_oViewport;
|
||||
TPointD m_oSizeWindow;
|
||||
@ -138,12 +152,17 @@ namespace MetaFile
|
||||
bool m_bUpdatedClip;
|
||||
CSvgClip m_oClip;
|
||||
|
||||
EShapeRendering m_eShapeRendering;
|
||||
|
||||
friend class CEmfInterpretatorSvg;
|
||||
friend class CWmfInterpretatorSvg;
|
||||
};
|
||||
|
||||
std::wstring CalculateColor(unsigned int unColor);
|
||||
std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha);
|
||||
std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha);
|
||||
void NormalizeRect(TRectD& oRect);
|
||||
TRectD TranslateRect(const TRectL &oRect);
|
||||
}
|
||||
|
||||
#endif // CINTERPRETATORSVGBASE_H
|
||||
|
||||
@ -29,7 +29,7 @@ namespace MetaFile
|
||||
}
|
||||
|
||||
void CWmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx,
|
||||
int iGraphicsMode, double dXScale, double dYScale)
|
||||
int iGraphicsMode, double dXScale, double dYScale)
|
||||
{
|
||||
if (NULL != m_pMetaFileRenderer)
|
||||
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);
|
||||
|
||||
@ -19,7 +19,7 @@ namespace MetaFile
|
||||
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight) override;
|
||||
|
||||
void DrawString(std::wstring& wsText, unsigned int unCharsCount, double dX, double dY, double* pDx,
|
||||
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override;
|
||||
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override;
|
||||
|
||||
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override;
|
||||
|
||||
|
||||
@ -110,6 +110,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -136,6 +137,7 @@ namespace MetaFile
|
||||
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -189,6 +191,7 @@ namespace MetaFile
|
||||
NodeAttributes arAttributes = {{L"d", wsValue}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -215,6 +218,7 @@ namespace MetaFile
|
||||
{L"y2", ConvertToWString(shY)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -230,12 +234,13 @@ namespace MetaFile
|
||||
{
|
||||
TRectD oNewRect;
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)},
|
||||
{L"y", ConvertToWString(shY)},
|
||||
{L"width", ConvertToWString(shW)},
|
||||
{L"height", ConvertToWString(shH)}};
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)},
|
||||
{L"y", ConvertToWString(shY)},
|
||||
{L"width", ConvertToWString(shW)},
|
||||
{L"height", ConvertToWString(shH)}};
|
||||
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -260,6 +265,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -280,6 +286,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddNoneFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -300,6 +307,7 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -327,30 +335,27 @@ namespace MetaFile
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
arAttributes.push_back({L"fill-rule", L"evenodd"});
|
||||
arAttributes.Add(L"fill-rule", L"evenodd");
|
||||
|
||||
WriteNode(L"path", arAttributes);
|
||||
}
|
||||
|
||||
void CWmfInterpretatorSvg::HANDLE_META_RECTANGLE(short shB, short shR, short shT, short shL)
|
||||
{
|
||||
TRectD oNewRect;
|
||||
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
|
||||
|
||||
oNewRect.Left = shL;
|
||||
oNewRect.Top = shT;
|
||||
oNewRect.Right = shR;
|
||||
oNewRect.Bottom = shB;
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
@ -359,22 +364,18 @@ namespace MetaFile
|
||||
|
||||
void CWmfInterpretatorSvg::HANDLE_META_ROUNDRECT(short shH, short shW, short shB, short shR, short shT, short shL)
|
||||
{
|
||||
TRectD oNewRect;
|
||||
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
|
||||
|
||||
oNewRect.Left = shL;
|
||||
oNewRect.Top = shT;
|
||||
oNewRect.Right = shR;
|
||||
oNewRect.Bottom = shB;
|
||||
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
|
||||
{L"rx", ConvertToWString((double)shW / 2.)},
|
||||
{L"ry", ConvertToWString((double)shH / 2.)}};
|
||||
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
|
||||
{L"y", ConvertToWString(oNewRect.Top)},
|
||||
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
|
||||
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
|
||||
{L"rx", ConvertToWString((double)shW / 2.)},
|
||||
{L"ry", ConvertToWString((double)shH / 2.)}};
|
||||
|
||||
AddStroke(arAttributes);
|
||||
AddFill(arAttributes);
|
||||
AddShapeRendering(arAttributes);
|
||||
AddTransform(arAttributes);
|
||||
AddClip();
|
||||
|
||||
|
||||
@ -162,9 +162,24 @@ namespace MetaFile
|
||||
unHeight = unDibHeigth;
|
||||
}
|
||||
|
||||
void CWmfBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
|
||||
{
|
||||
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
|
||||
arPositions = {0., 1.};
|
||||
}
|
||||
|
||||
CWmfFont::CWmfFont()
|
||||
: shHeight(DEFAULT_FONT_SIZE), shWidth(0), shEscapement(0), shOrientation(0), shWeight(400),
|
||||
uchItalic(0x00), uchUnderline(0x00), uchStrikeOut(0x00), uchCharSet(0x01), uchOutPrecision(0x00),
|
||||
uchClipPrecision(0x00), uchQuality(0x00), uchPitchAndFamily(0x00)
|
||||
{
|
||||
memset(uchFacename, 0x00, 32);
|
||||
|
||||
uchFacename[0] = 'A';
|
||||
uchFacename[1] = 'r';
|
||||
uchFacename[2] = 'i';
|
||||
uchFacename[3] = 'a';
|
||||
uchFacename[4] = 'l';
|
||||
}
|
||||
|
||||
CWmfFont::~CWmfFont()
|
||||
@ -281,6 +296,16 @@ namespace MetaFile
|
||||
unSize = 0;
|
||||
}
|
||||
|
||||
const ILineCap* CWmfPen::GetStartLineCap() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ILineCap* CWmfPen::GetEndLineCap() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CWmfRegion::CWmfRegion() : pScans(NULL)
|
||||
{}
|
||||
|
||||
|
||||
@ -82,6 +82,8 @@ namespace MetaFile
|
||||
void GetBounds(double& left, double& top, double& width, double& height) const override;
|
||||
void GetCenterPoint(double& dX, double& dY) const override;
|
||||
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
|
||||
|
||||
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
|
||||
public:
|
||||
|
||||
unsigned short ushBrushStyle;
|
||||
@ -146,13 +148,15 @@ namespace MetaFile
|
||||
virtual EWmfObjectType GetType() const override;
|
||||
|
||||
// IPen
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
int GetColor() const override;
|
||||
unsigned int GetStyle() const override;
|
||||
double GetWidth() const override;
|
||||
unsigned int GetAlpha() const override;
|
||||
double GetMiterLimit() const override;
|
||||
double GetDashOffset() const override;
|
||||
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
|
||||
const ILineCap* GetStartLineCap() const override;
|
||||
const ILineCap* GetEndLineCap() const override;
|
||||
public:
|
||||
unsigned short ushPenStyle;
|
||||
TPointS oWidth;
|
||||
|
||||
@ -194,7 +194,11 @@ namespace MetaFile
|
||||
RELEASEOBJECT(m_pInterpretator);
|
||||
|
||||
if (InterpretatorType::Svg == oInterpretatorType)
|
||||
m_pInterpretator = new CWmfInterpretatorSvg(this, unWidth, unHeight);
|
||||
{
|
||||
CWmfInterpretatorSvg *pWmfInterpretatorSvg = new CWmfInterpretatorSvg(this, unWidth, unHeight);
|
||||
pWmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
|
||||
m_pInterpretator = pWmfInterpretatorSvg;
|
||||
}
|
||||
}
|
||||
|
||||
void CWmfParserBase::SetInterpretator(IOutputDevice *pOutput, const wchar_t *wsFilePath)
|
||||
@ -233,12 +237,9 @@ namespace MetaFile
|
||||
|
||||
m_oDCRect = m_oPlaceable.oBoundingBox;
|
||||
|
||||
const USHORT ushFileDpi = GetDpi();
|
||||
const USHORT ushRendererDpi = 96;
|
||||
|
||||
if (ushFileDpi != ushRendererDpi && 0 != ushFileDpi)
|
||||
if (96 != m_oPlaceable.ushInch)
|
||||
{
|
||||
const double dKoef = (double)ushRendererDpi / (double)ushFileDpi;
|
||||
const double dKoef = 96. / (double)m_oPlaceable.ushInch;
|
||||
|
||||
m_oDCRect.Left = std::round(m_oDCRect.Left * dKoef);
|
||||
m_oDCRect.Top = std::round(m_oDCRect.Top * dKoef);
|
||||
@ -685,8 +686,8 @@ namespace MetaFile
|
||||
{
|
||||
TRectL oClip = oSrcRect;
|
||||
|
||||
oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth ) - 1;
|
||||
oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight) - 1;
|
||||
oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth );
|
||||
oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight);
|
||||
|
||||
BYTE* pNewBuffer = ClipBuffer(pBgra, unWidth, unHeight, oClip);
|
||||
|
||||
@ -787,6 +788,8 @@ namespace MetaFile
|
||||
|
||||
if (NULL != m_pInterpretator)
|
||||
{
|
||||
UpdateDCRect();
|
||||
|
||||
m_pDC->SetWindowOrg(m_oDCRect.Left, m_oDCRect.Top);
|
||||
m_pDC->SetWindowExt(m_oDCRect.Right - m_oDCRect.Left, m_oDCRect.Bottom - m_oDCRect.Top);
|
||||
m_pDC->SetViewportOrg(m_oDCRect.Left, m_oDCRect.Top);
|
||||
|
||||
@ -236,8 +236,8 @@ namespace MetaFile
|
||||
{
|
||||
m_pBrush = &m_oDefaultBrush;
|
||||
m_pPen = &m_oDefaultPen;
|
||||
m_pFont = &m_oDefaultFont;
|
||||
m_pPalette = NULL;
|
||||
m_pFont = NULL;
|
||||
m_pRegion = NULL;
|
||||
m_ushMapMode = MM_TEXT;
|
||||
m_dPixelWidth = 1;
|
||||
@ -350,7 +350,7 @@ namespace MetaFile
|
||||
}
|
||||
const CWmfFont* CWmfDC::GetFont() const
|
||||
{
|
||||
return m_pFont;
|
||||
return (NULL != m_pFont) ? m_pFont : &m_oDefaultFont;
|
||||
}
|
||||
void CWmfDC::SetRegion(CWmfRegion* pRegion)
|
||||
{
|
||||
@ -609,6 +609,7 @@ namespace MetaFile
|
||||
if (!m_oViewport.h) m_oViewport.h = nMinCy;
|
||||
}
|
||||
}
|
||||
|
||||
void CWmfDC::SetTextColor(TRGBA& oColor)
|
||||
{
|
||||
m_oTextColor = oColor;
|
||||
|
||||
@ -147,6 +147,7 @@ namespace MetaFile
|
||||
|
||||
CClip m_oClip;
|
||||
CWmfBrush m_oDefaultBrush;
|
||||
CWmfFont m_oDefaultFont;
|
||||
CWmfPen m_oDefaultPen;
|
||||
CWmfBrush* m_pBrush;
|
||||
CWmfPen* m_pPen;
|
||||
|
||||
@ -7,15 +7,13 @@
|
||||
#include "CSvgParser.h"
|
||||
#include "SvgObjects/CStyle.h"
|
||||
|
||||
#define SVG_DECL_IMPORT Q_DECL_IMPORT
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
struct TFontArguments;
|
||||
class CFont;
|
||||
}
|
||||
|
||||
class SVG_DECL_IMPORT CSvgFile
|
||||
class CSvgFile
|
||||
{
|
||||
public:
|
||||
CSvgFile();
|
||||
|
||||
@ -6,7 +6,6 @@ namespace SVG
|
||||
: m_pInternal(new NSCSS::CCssCalculator_Private)
|
||||
{
|
||||
m_pInternal->SetDpi(96);
|
||||
m_pInternal->SetUnitMeasure(NSCSS::UnitMeasure::Pixel);
|
||||
}
|
||||
|
||||
CSvgCalculator::~CSvgCalculator()
|
||||
@ -30,139 +29,22 @@ namespace SVG
|
||||
if (NULL == pSvgObject)
|
||||
return;
|
||||
|
||||
const std::map<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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user