Compare commits

..

123 Commits

Author SHA1 Message Date
2a4d97c7b4 fix loss of an attribute in sqrt 2025-11-20 16:18:28 +03:00
94f06bf997 Merge pull request 'fix bug #78614' (#537) from fix/bug78614 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/537
2025-11-20 10:09:25 +00:00
230316aefa fix bug #78614 2025-11-20 12:51:35 +03:00
50c7e106fb Merge pull request 'Fix bug #78449' (#535) from fix/bug-78449 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/535
2025-11-19 15:16:23 +00:00
6b5ee390a2 Fix bug #78449 2025-11-19 18:08:55 +03:00
9049e2e6a8 Merge pull request 'Fix bugs' (#533) from fix/metafile into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/533
2025-11-18 11:26:53 +00:00
67c6707072 Merge pull request 'Fix bug 76845' (#531) from fix/bug-76845 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/531
2025-11-18 08:10:19 +00:00
0c29a5d436 Fix bug 76845 2025-11-18 11:06:10 +03:00
02d492ff90 Fix typo 2025-11-17 23:02:02 +03:00
a7026ccb8d Fix bug #77816 2025-11-17 23:01:50 +03:00
ae8fb19147 Merge pull request 'fix bug #78248' (#530) from fix/fix-bugs into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/530
2025-11-14 08:05:38 +00:00
12083905dc fix bug #78248 2025-11-14 10:46:48 +03:00
e653442b8c Merge pull request 'Fix bug #74743' (#529) from fix/bug-74743 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/529
2025-11-13 18:10:58 +00:00
511cfb6158 Fix bug #74743 2025-11-13 20:08:15 +03:00
6b80b39d4d Merge pull request 'fix bug #78278' (#525) from fix/bug78278 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/525
2025-11-13 14:32:04 +00:00
cbf138b1eb Merge pull request 'fix/fix-bugs' (#528) from fix/fix-bugs into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/528
2025-11-13 12:43:13 +00:00
897f8fa9f2 Merge pull request 'fix/sysroot' (#527) from fix/sysroot into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/527
2025-11-13 12:19:14 +00:00
8feb44225d Fix bug 2025-11-13 14:52:11 +03:00
517e337049 Fix building with newer qmake 2025-11-13 14:31:35 +03:00
c05231cf58 Merge pull request 'Fix bug in metafile conversion' (#526) from fix/metafile into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/526
2025-11-13 10:57:15 +00:00
66b1007ab4 fix bug #78278 2025-11-13 12:44:09 +03:00
62413b8df5 Fix bug in metafile conversion 2025-11-13 03:03:25 +03:00
f93c259977 . 2025-11-12 20:57:32 +03:00
910ff6a6dd Merge pull request 'Fix bug 78223' (#523) from fix/bug-78223 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/523
2025-11-12 10:42:18 +00:00
22e5bcbde3 Fix bug 78223 2025-11-12 13:05:51 +03:00
a77cbf903b fix bug #77941 2025-11-12 10:52:37 +03:00
9b4416952f Merge pull request 'fix bug #78156' (#521) from fix/bug78156 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/521
2025-11-12 07:10:09 +00:00
a320b5bd5a Fix build 2025-11-11 22:46:36 +03:00
34a1f117c9 Merge pull request 'For bug #74646' (#522) from fix/md into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/522
2025-11-11 16:16:23 +00:00
ec4700ac38 For bug #74646 2025-11-11 18:57:35 +03:00
85047874b7 fix bug #78156 2025-11-11 10:03:48 +03:00
52bf1a6988 Merge pull request 'Fix bugs' (#517) from fix/bug-77446 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/517
2025-11-10 12:46:20 +00:00
27746f5c2b Merge pull request 'fix bug #76076' (#519) from fix/bug76076 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/519
2025-11-10 11:57:02 +00:00
d3710a755e Merge pull request 'Fix md bugs' (#518) from fix/md into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/518
2025-11-10 11:56:06 +00:00
5c8dcd7ed2 Merge pull request 'Fix bug 78035' (#520) from fix/pdf-bugs into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/520
2025-11-10 11:51:18 +00:00
5c0b3744ee Fix bug 78035 2025-11-10 13:53:51 +03:00
1f3467d75f Fix serNum loading 2025-11-10 15:38:25 +06:00
a1d8597b4f fix bug #76076 2025-11-10 15:02:27 +06:00
15dc718211 Fix bug #74969 2025-11-08 00:23:30 +03:00
1db12e66c6 For bug #74743 2025-11-08 00:07:43 +03:00
5de19652f2 Fix bug #74726 2025-11-07 14:36:31 +03:00
76b5bd594d Fix bug #77446 2025-11-07 13:22:07 +03:00
61b55c9230 Merge pull request 'Fix bugs in svg' (#516) from fix/bug-78017 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/516
2025-11-07 09:51:04 +00:00
22aecb56ec Fix bug in svg 2025-11-07 12:48:08 +03:00
3586a010a8 Fix bug #78017 2025-11-06 20:48:57 +03:00
146fc90746 Merge pull request 'Fix bug 78049' (#513) from fix/bug-78049 into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/513
2025-11-06 13:37:03 +00:00
4452d7bf3d Fix bug 78049 2025-11-06 16:18:42 +03:00
673678e80a Merge pull request 'Fix bug in svg' (#512) from fix/svg into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/512
2025-11-06 12:43:45 +00:00
b51960e925 fix bug #78023 2025-11-06 15:24:42 +03:00
0477002e85 Fix bug in svg 2025-11-06 00:59:45 +03:00
68f1c6f97d for bug #78007 2025-11-05 18:05:49 +03:00
6f85ce7116 Merge pull request 'Fix bugs 77966, 77904' (#510) from fix/pdf-bugs into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/510
2025-11-05 11:20:13 +00:00
d920492afe Fix bug 77966 2025-11-05 14:03:25 +03:00
d69a54de38 Fix bug 77904 2025-11-05 14:03:02 +03:00
cbb1df1522 Merge pull request 'Fix SVG' (#509) from fix/svg into release/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/509
2025-11-01 18:50:12 +00:00
3b0e98fc4a Fix typo 2025-11-01 18:16:43 +03:00
a29eb52e1a Fix build 2025-11-01 18:15:14 +03:00
16eb1b51e7 fix bug #77963 2025-11-01 13:10:54 +03:00
527ff672d9 Merge pull request 'Fix md/html bugs' (#507) from fix/md into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/507
2025-10-31 13:27:05 +00:00
aa24268a2e Fix bug #74743 2025-10-31 16:19:42 +03:00
39e4c3a09c Fix build 2025-10-31 15:03:44 +03:00
8158ace0eb Fix bug #74969 2025-10-31 02:58:19 +03:00
f38ce7b61b change type in binary paraId 2025-10-30 18:37:46 +03:00
95a1b39fb1 Fix bugs 2025-10-30 18:15:47 +03:00
f58be7754a Fixed a bug calculating complex styles in CSS 2025-10-30 18:15:34 +03:00
a31c3ee00a Fix bug #74646 2025-10-30 16:41:07 +03:00
23e9187f5a fix bug #77929 2025-10-30 14:40:52 +03:00
0e991719bf fix bug #77664 2025-10-29 17:18:11 +03:00
ca2504edb6 Fix bug #74647 2025-10-28 18:49:06 +03:00
07bedd847e Fix bug #77940 2025-10-28 18:13:02 +03:00
506a805654 Merge branch release/v9.1.0 into hotfix/v9.2.0 2025-10-28 11:58:13 +00:00
1bdff9e7fe For bug #74647 2025-10-28 14:15:00 +03:00
8fab1802df Added support for text fill transparency in svg 2025-10-28 14:13:12 +03:00
bfffcda0c5 Fix bug in SVG 2025-10-28 12:15:14 +03:00
e96ceab1e3 Fix bugs in svg gradient 2025-10-28 12:05:05 +03:00
5046c1b326 add labeledCheckBox 2025-10-28 11:27:56 +03:00
6616a11e7c Merge pull request 'Fix bugs' (#501) from fix/bug-72300 into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/501
2025-10-27 16:43:58 +00:00
45e97b76f0 Merge branch 'hotfix/v9.2.0' into fix/bug-72300 2025-10-27 19:37:13 +03:00
d3017c2777 Merge pull request 'Fix MD bugs' (#500) from fix/md into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/500
2025-10-27 16:24:39 +00:00
41c4032fe8 Fix build 2025-10-27 17:54:56 +03:00
df49a4fbde Redesigned bounds calculation in svg and refactoring 2025-10-26 20:53:31 +03:00
3d586a4bb6 Added processing of hidden elements in html 2025-10-26 17:57:21 +03:00
6d76fd71cc Fixed a bug with CSS styles calculation 2025-10-26 17:56:50 +03:00
170cada6e6 Remove logs 2025-10-24 19:45:17 +03:00
e4825294ed Merge pull request 'For bug 77199' (#499) from for/bug-77199 into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/499
2025-10-24 11:31:36 +00:00
17c336d57c Fix build 2025-10-24 14:24:02 +03:00
4e7af40367 For bug 77199 2025-10-24 14:23:45 +03:00
b7230d16fc Merge pull request 'fix/bugs' (#498) from fix/bugs into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/498
2025-10-24 11:12:01 +00:00
22a7e6bb05 fix bug #77587 2025-10-24 13:17:02 +03:00
a4ed2dea41 fix bug #77232 2025-10-24 13:14:22 +03:00
ab2eabdd23 Merge pull request 'Fix bug 77823' (#497) from fix/bug-77823 into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/497
2025-10-24 09:15:58 +00:00
ab052c7c59 . 2025-10-24 10:23:24 +03:00
2b209ed5e4 Fix bug #77443 2025-10-24 01:45:24 +03:00
04bce828be Fix bug #77442 2025-10-24 01:38:24 +03:00
4c5259494d Refactoring 2025-10-24 01:37:24 +03:00
289a77a978 . 2025-10-23 20:29:57 +03:00
a22cc4e410 add ext logging 2025-10-23 20:26:35 +03:00
091af38e0d fix bug #73635 2025-10-23 15:35:09 +03:00
2b214ab07d Fix bug 77823 2025-10-23 13:13:15 +03:00
c8b34959d7 fix bug #77807 2025-10-23 12:07:31 +03:00
2bf44900de Fix bug #77441 2025-10-22 20:29:38 +03:00
c235a4c646 Fix bug #77440 2025-10-22 18:58:37 +03:00
3bdd0e2053 Merge pull request 'fix bug #77651' (#495) from fix/bug77651 into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/495
2025-10-22 13:23:04 +00:00
339820e5df Merge pull request 'fix bug #76076' (#496) from fix/bug76076 into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/496
2025-10-22 13:22:34 +00:00
475cbb6f8a fix bug #77651 2025-10-22 14:57:57 +06:00
ee784a7189 Merge pull request 'Fix pdf bugs' (#494) from fix/pdf-bugs into hotfix/v9.2.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/494
2025-10-20 14:22:46 +00:00
650fb84b6d For bug 75161 2025-10-20 17:18:41 +03:00
4a2d0b5e1f Fix reset font settings 2025-10-20 16:11:16 +03:00
1d58d8fc7f Fix bug 77608 2025-10-20 10:15:25 +03:00
b0a850745d Merge branch 'fix/fix-bugs' into hotfix/v9.2.0 2025-10-17 20:57:29 +03:00
a0a9d899a8 fix binary paraId 2025-10-17 17:56:14 +03:00
7156669830 Intermediate refactoring 2025-10-15 19:06:28 +03:00
3b85841ea6 fix bug #77472 2025-10-15 12:37:04 +03:00
4899ed4e7f fix bug #77562 2025-10-15 12:36:08 +03:00
f335a5b024 fix bug #73585 2025-10-15 12:35:03 +03:00
6eeae2e804 Intermediate refactoring 2025-10-14 20:42:24 +03:00
82e281cf6b Merge branch release/v9.1.0 into master 2025-10-14 14:36:21 +00:00
66d94cf00c Intermediate refactoring 2025-10-09 18:59:40 +03:00
d0f1691a5e Fix bug #72300 2025-10-09 17:36:17 +03:00
0ccff9944d Merge branch 'release/v9.1.0' into fix/bug-72300 2025-10-09 16:50:28 +03:00
a220822b7b fix bug #76076 2025-10-03 16:06:46 +06:00
21a637594a For bug #72300 2025-10-02 18:20:12 +03:00
a517cef437 Merge branch hotfix/v9.0.4 into master 2025-09-11 08:40:05 +00:00
161 changed files with 3686 additions and 1914 deletions

View File

@ -514,6 +514,9 @@ namespace NSCSS
return true;
}
if (!arSelectors.back().m_pCompiledStyle->Empty())
return true;
arSelectors.back().m_pCompiledStyle->SetDpi(m_nDpi);
unsigned int unStart = 0;
@ -522,8 +525,8 @@ namespace NSCSS
if (itFound != arSelectors.crend())
unStart = itFound.base() - arSelectors.cbegin();
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors, unStart);
std::vector<std::wstring> arPrevNodes;
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors, unStart, arSelectors.size());
std::vector<std::wstring> arPrevNodes = CalculateAllNodes(arSelectors, 0, unStart);
bool bInTable = false;
for (size_t i = 0; i < unStart; ++i)
@ -548,6 +551,7 @@ namespace NSCSS
{
arSelectors[i].m_pCompiledStyle->m_oBackground.Clear();
arSelectors[i].m_pCompiledStyle->m_oBorder.Clear();
arSelectors[i].m_pCompiledStyle->m_oDisplay.Clear();
}
arSelectors[i].m_pCompiledStyle->AddStyle(arSelectors[i].m_mAttributes, i + 1);
@ -592,11 +596,14 @@ namespace NSCSS
}
#endif
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors, unsigned int unStart)
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors, unsigned int unStart, unsigned int unEnd)
{
if ((0 != unEnd && (unEnd < unStart || unEnd > arSelectors.size())) || (unStart == unEnd))
return std::vector<std::wstring>();
std::vector<std::wstring> arNodes;
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend() - unStart; ++oNode)
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin() + ((0 != unEnd) ? (arSelectors.size() - unEnd) : 0); oNode != arSelectors.rend() - unStart; ++oNode)
{
if (!oNode->m_wsName.empty())
arNodes.push_back(oNode->m_wsName);
@ -627,7 +634,7 @@ namespace NSCSS
if (arNextNodes.empty())
return;
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.cbegin(), arNextNodes.cend());
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
if (!arTempPrev.empty())
@ -644,20 +651,19 @@ namespace NSCSS
std::vector<const CElement*> arFindedElements;
std::wstring wsName, wsId;
std::wstring wsName, wsClasses, 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());
wsClasses = arNodes.back();
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(wsClasses, false, L" ");
arNodes.pop_back();
}
@ -665,7 +671,6 @@ namespace NSCSS
{
wsName = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsName);
}
if (!wsId.empty())
@ -724,6 +729,14 @@ namespace NSCSS
{ return oFirstElement->GetWeight() > oSecondElement->GetWeight(); });
}
if (!wsId.empty())
arNextNodes.push_back(wsId);
if (!wsClasses.empty())
arNextNodes.push_back(wsClasses);
arNextNodes.push_back(wsName);
return arFindedElements;
}
@ -738,7 +751,7 @@ namespace NSCSS
if (arSelectors.empty())
return false;
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors);
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors, 0, arSelectors.size());
std::vector<std::wstring> arNextNodes;
for (size_t i = 0; i < arSelectors.size(); ++i)

View File

@ -110,7 +110,7 @@ namespace NSCSS
void ClearPageData();
#endif
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors, unsigned int unStart = 0);
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors, unsigned int unStart, unsigned int unEnd);
std::vector<const CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
void AddStyles(const std::string& sStyle);

View File

@ -176,14 +176,14 @@ namespace NSCSS
return arElements;
}
std::vector<CElement *> CElement::GetPrevElements(const std::vector<std::wstring>::const_reverse_iterator& oNodesRBegin, const std::vector<std::wstring>::const_reverse_iterator& oNodesREnd) const
std::vector<CElement *> CElement::GetPrevElements(const std::vector<std::wstring>::const_iterator& oNodesBegin, const std::vector<std::wstring>::const_iterator& oNodesEnd) const
{
if (oNodesRBegin >= oNodesREnd || m_arPrevElements.empty())
if (oNodesBegin >= oNodesEnd || m_arPrevElements.empty())
return std::vector<CElement*>();
std::vector<CElement*> arElements;
for (std::vector<std::wstring>::const_reverse_iterator iWord = oNodesRBegin; iWord != oNodesREnd; ++iWord)
for (std::vector<std::wstring>::const_iterator iWord = oNodesBegin; iWord != oNodesEnd; ++iWord)
{
if ((*iWord)[0] == L'.' && ((*iWord).find(L" ") != std::wstring::npos))
{
@ -195,7 +195,7 @@ namespace NSCSS
if (oPrevElement->m_sSelector == wsClass)
{
arElements.push_back(oPrevElement);
std::vector<CElement*> arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd);
std::vector<CElement*> arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesEnd);
arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end());
}
}
@ -208,9 +208,8 @@ namespace NSCSS
if (oPrevElement->m_sSelector == *iWord)
{
arElements.push_back(oPrevElement);
std::vector<CElement*> arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesREnd);
std::vector<CElement*> arTempElements = oPrevElement->GetPrevElements(iWord + 1, oNodesEnd);
arElements.insert(arElements.end(), arTempElements.begin(), arTempElements.end());
// return arElements;
}
}
}

View File

@ -39,7 +39,7 @@ namespace NSCSS
std::map<std::wstring, std::wstring> GetFullStyle(const std::vector<CNode>& arSelectors) const;
std::map<std::wstring, std::wstring> GetFullStyle(const std::vector<std::wstring>& arNodes) const;
std::vector<CElement *> GetNextOfKin(const std::wstring& sName, const std::vector<std::wstring>& arClasses = {}) const;
std::vector<CElement *> GetPrevElements(const std::vector<std::wstring>::const_reverse_iterator& oNodesRBegin, const std::vector<std::wstring>::const_reverse_iterator& oNodesREnd) const;
std::vector<CElement *> GetPrevElements(const std::vector<std::wstring>::const_iterator& oNodesBegin, const std::vector<std::wstring>::const_iterator& oNodesEnd) const;
std::map<std::wstring, std::wstring> GetConvertStyle(const std::vector<CNode>& arNodes) const;
CElement *FindPrevElement(const std::wstring& sSelector) const;

View File

@ -18,6 +18,7 @@ namespace NSCSS
std::wstring m_wsId; // Id тэга
std::wstring m_wsStyle; // Стиль тэга
std::map<std::wstring, std::wstring> m_mAttributes; // Остальные аттрибуты тэга
//TODO:: возможно использование std::wstring излишне
#ifdef CSS_CALCULATOR_WITH_XHTML
CCompiledStyle *m_pCompiledStyle;

View File

@ -149,7 +149,7 @@ namespace NSCSS
case NSCSS::Millimeter:
return dValue * 0.01764;
case NSCSS::Inch:
return dValue * 1440.;
return dValue / 1440.;
case NSCSS::Peak:
return dValue * 0.004167; // 0.004167 = 6 / 1440
default:

View File

@ -69,7 +69,8 @@ namespace NSCSS
R_Highlight,
R_Shd,
R_SmallCaps,
R_Kern
R_Kern,
R_Vanish
} RunnerProperties;
typedef enum

View File

@ -436,12 +436,13 @@ namespace NSCSS
return true;
}
bool CDigit::SetValue(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CDigit::SetValue(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
if (CHECK_CONDITIONS && !bHardMode)
return false;
m_oValue = dValue;
m_enUnitMeasure = enUnitMeasure;
m_oValue = dValue;
if (UINT_MAX == unLevel)
m_unLevel++;
@ -1326,6 +1327,23 @@ namespace NSCSS
return true;
}
CMatrix& CMatrix::operator+=(const CMatrix& oMatrix)
{
m_oValue.insert(m_oValue.end(), oMatrix.m_oValue.begin(), oMatrix.m_oValue.end());
return *this;
}
CMatrix& CMatrix::operator-=(const CMatrix& oMatrix)
{
for (MatrixValues::const_reverse_iterator itElement = oMatrix.m_oValue.crbegin(); itElement < oMatrix.m_oValue.crend(); ++itElement)
{
if (!m_oValue.empty() && m_oValue.back() == *itElement)
m_oValue.pop_back();
}
return *this;
}
// DISPLAY
CDisplay::CDisplay()
{
@ -1465,6 +1483,21 @@ namespace NSCSS
(m_eWhiteSpace.Empty() || m_eWhiteSpace == EWhiteSpace::Normal);
}
void CDisplay::Clear()
{
m_oX.Clear();
m_oY.Clear();
m_oWidth.Clear();
m_oHeight.Clear();
m_oHAlign.Clear();
m_oVAlign.Clear();
m_oDisplay.Clear();
m_eWhiteSpace.Clear();
}
CDisplay &CDisplay::operator+=(const CDisplay &oDisplay)
{
m_oX += oDisplay.m_oX;
@ -1743,9 +1776,9 @@ namespace NSCSS
return m_oWidth.SetValue(wsNewValue, unLevel, bHardMode);
}
bool CBorderSide::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorderSide::SetWidth(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oWidth.SetValue(dValue, unLevel, bHardMode);
return m_oWidth.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CBorderSide::SetStyle(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -1921,14 +1954,14 @@ namespace NSCSS
return bResult;
}
bool CBorder::SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorder::SetWidth(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
bool bResult = false;
if (m_oLeft .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
if (m_oTop .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
if (m_oRight .SetWidth(dValue, unLevel, bHardMode)) bResult = true;
if (m_oBottom.SetWidth(dValue, unLevel, bHardMode)) bResult = true;
if (m_oLeft .SetWidth(dValue, enUnitMeasure, unLevel, bHardMode)) bResult = true;
if (m_oTop .SetWidth(dValue, enUnitMeasure, unLevel, bHardMode)) bResult = true;
if (m_oRight .SetWidth(dValue, enUnitMeasure, unLevel, bHardMode)) bResult = true;
if (m_oBottom.SetWidth(dValue, enUnitMeasure, unLevel, bHardMode)) bResult = true;
return bResult;
}
@ -1972,9 +2005,9 @@ namespace NSCSS
return m_oLeft.SetWidth(wsValue, unLevel, bHardMode);
}
bool CBorder::SetWidthLeftSide(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorder::SetWidthLeftSide(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetWidth(dValue, unLevel, bHardMode);
return m_oLeft.SetWidth(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CBorder::SetStyleLeftSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -1997,9 +2030,9 @@ namespace NSCSS
return m_oTop.SetWidth(wsValue, unLevel, bHardMode);
}
bool CBorder::SetWidthTopSide(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorder::SetWidthTopSide(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oTop.SetWidth(dValue, unLevel, bHardMode);
return m_oTop.SetWidth(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CBorder::SetStyleTopSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -2022,9 +2055,9 @@ namespace NSCSS
return m_oRight.SetWidth(wsValue, unLevel, bHardMode);
}
bool CBorder::SetWidthRightSide(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorder::SetWidthRightSide(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetWidth(dValue, unLevel, bHardMode);
return m_oRight.SetWidth(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CBorder::SetStyleRightSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -2047,9 +2080,9 @@ namespace NSCSS
return m_oBottom.SetWidth(wsValue, unLevel, bHardMode);
}
bool CBorder::SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CBorder::SetWidthBottomSide(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetWidth(dValue, unLevel, bHardMode);
return m_oBottom.SetWidth(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CBorder::SetStyleBottomSide(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -2348,39 +2381,49 @@ namespace NSCSS
return m_oTop.SetValue(wsValue, unLevel, bHardMode);
}
bool CIndent::SetTop(const double& dValue, unsigned int unLevel, bool bHardMode)
{
return m_oTop.SetValue(dValue, unLevel, bHardMode);
}
bool CIndent::SetRight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetValue(wsValue, unLevel, bHardMode);
}
bool CIndent::SetRight(const double& dValue, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetValue(dValue, unLevel, bHardMode);
}
bool CIndent::SetBottom(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetValue(wsValue, unLevel, bHardMode);
}
bool CIndent::SetBottom(const double& dValue, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetValue(dValue, unLevel, bHardMode);
}
bool CIndent::SetLeft(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetValue(wsValue, unLevel, bHardMode);
}
bool CIndent::SetLeft(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CIndent::SetValues(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetValue(dValue, unLevel, bHardMode);
const bool bTopResult = SetTop (dValue, enUnitMeasure, unLevel, bHardMode);
const bool bRightResult = SetRight (dValue, enUnitMeasure, unLevel, bHardMode);
const bool bBottomResult = SetBottom (dValue, enUnitMeasure, unLevel, bHardMode);
const bool bLeftResult = SetLeft (dValue, enUnitMeasure, unLevel, bHardMode);
return bTopResult || bRightResult || bBottomResult || bLeftResult;
}
bool CIndent::SetTop(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oTop.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CIndent::SetRight(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oRight.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CIndent::SetBottom(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oBottom.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CIndent::SetLeft(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oLeft.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
void CIndent::UpdateAll(const double& dParentFontSize, const double& dCoreFontSize)
@ -2672,9 +2715,9 @@ namespace NSCSS
return m_oSize.SetValue(wsNewValue, unLevel, bHardMode);
}
bool CFont:: SetSize(const double& dValue, unsigned int unLevel, bool bHardMode)
bool CFont:: SetSize(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oSize.SetValue(dValue, unLevel, bHardMode);
return m_oSize.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CFont::SetLineHeight(const std::wstring &wsValue, unsigned int unLevel, bool bHardMode)
@ -2999,6 +3042,31 @@ namespace NSCSS
return m_oHeader.SetValue(wsValue, unLevel, bHardMode);
}
bool CPage::SetWidth(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oWidth.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CPage::SetHeight(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oHeight.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CPage::SetMargin(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oMargin.SetValues(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CPage::SetFooter(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oFooter.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
bool CPage::SetHeader(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode)
{
return m_oHeader.SetValue(dValue, enUnitMeasure, unLevel, bHardMode);
}
const CDigit &CPage::GetWidth() const
{
return m_oWidth;

View File

@ -138,7 +138,7 @@ namespace NSCSS
bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override;
bool SetValue(const CDigit& oValue);
bool SetValue(const double& dValue, unsigned int unLevel, bool bHardMode);
bool SetValue(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel = 0, bool bHardMode = true);
bool Empty() const override;
bool Zero() const;
@ -302,6 +302,8 @@ namespace NSCSS
void ApplyTranform(Aggplus::CMatrix& oMatrix, Aggplus::MatrixOrder order = Aggplus::MatrixOrderPrepend) const;
bool operator==(const CMatrix& oMatrix) const;
CMatrix& operator+=(const CMatrix& oMatrix);
CMatrix& operator-=(const CMatrix& oMatrix);
};
class CEnum : public CValue<int>
@ -371,6 +373,7 @@ namespace NSCSS
const CEnum& GetWhiteSpace() const;
bool Empty() const;
void Clear();
CDisplay& operator+=(const CDisplay& oDisplay);
bool operator==(const CDisplay& oDisplay) const;
@ -472,7 +475,7 @@ namespace NSCSS
bool SetValue(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
@ -524,7 +527,7 @@ namespace NSCSS
bool SetSides(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyle(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColor(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetCollapse(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
@ -532,28 +535,28 @@ namespace NSCSS
//Left Side
bool SetLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthLeftSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthLeftSide (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyleLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorLeftSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Top Side
bool SetTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthTopSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthTopSide (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyleTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorTopSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Right Side
bool SetRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthRightSide (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthRightSide (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyleRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorRightSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
//Bottom Side
bool SetBottomSide (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthBottomSide(const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidthBottomSide(const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetStyleBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetColorBottomSide(const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
@ -666,13 +669,15 @@ namespace NSCSS
bool SetValues (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetTop (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetTop (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetRight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetRight (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetBottom (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetBottom (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetLeft (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetLeft (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetValues (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetTop (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetRight (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetBottom (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetLeft (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
void UpdateAll (const double& dParentFontSize, const double& dCoreFontSize);
void UpdateTop (const double& dParentFontSize, const double& dCoreFontSize);
@ -685,6 +690,9 @@ namespace NSCSS
const CDigit& GetBottom() const;
const CDigit& GetLeft () const;
bool GetAfterAutospacing () const;
bool GetBeforeAutospacing() const;
bool Empty() const;
bool Zero() const;
@ -712,7 +720,7 @@ namespace NSCSS
bool SetValue (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetSize (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetSize (const double& dValue, unsigned int unLevel, bool bHardMode = false);
bool SetSize (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetLineHeight (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetFamily (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetStretch (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
@ -762,6 +770,12 @@ namespace NSCSS
bool SetFooter (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetHeader (const std::wstring& wsValue, unsigned int unLevel, bool bHardMode = false);
bool SetWidth (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetHeight (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetMargin (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetFooter (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
bool SetHeader (const double& dValue, UnitMeasure enUnitMeasure, unsigned int unLevel, bool bHardMode = false);
const CDigit& GetWidth() const;
const CDigit& GetHeight() const;
const CIndent& GetMargin() const;

View File

@ -341,14 +341,14 @@ namespace NSCSS
sSpacingValue.reserve(128);
if (!oStyle.m_oMargin.GetTop().Empty() && !oStyle.m_oMargin.GetTop().Zero())
sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"0\"";
sSpacingValue += L"w:before=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetTop(), NSCSS::Twips)) + L"\" w:beforeAutospacing=\"1\"";
else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable)
sSpacingValue += L"w:before=\"0\" w:beforeAutospacing=\"0\"";
sSpacingValue += L"w:before=\"0\" w:beforeAutospacing=\"1\"";
if (!oStyle.m_oMargin.GetBottom().Empty() && !oStyle.m_oMargin.GetBottom().Zero())
sSpacingValue += L" w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"0\"";
sSpacingValue += L" w:after=\"" + std::to_wstring(VALUE_TO_INT(oStyle.m_oMargin.GetBottom(), NSCSS::Twips)) + L"\" w:afterAutospacing=\"1\"";
else if (oStyle.m_oMargin.GetBottom().Zero() || bInTable)
sSpacingValue += L" w:after=\"0\" w:afterAutospacing=\"0\"";
sSpacingValue += L" w:after=\"0\" w:afterAutospacing=\"1\"";
if (!oStyle.m_oFont.GetLineHeight().Empty() && !oStyle.m_oFont.GetLineHeight().Zero())
{
@ -509,6 +509,9 @@ namespace NSCSS
else if (L"serif" == wsFontFamily)
wsFontFamily = L"Times New Roman";
if (oStyle.m_oDisplay.GetDisplay() == L"none")
oXmlElement.AddPropertiesInR(RProperties::R_Vanish, L"true");
oXmlElement.AddPropertiesInR(RProperties::R_RFonts, oStyle.m_oFont.GetFamily().ToWString());
oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString());
oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString());

View File

@ -473,6 +473,12 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const
sRStyle += L"<w:kern w:val=\"" + oItem.second + L"\"/>";
break;
}
case CSSProperties::RunnerProperties::R_Vanish:
{
if (oItem.second == L"true")
sRStyle += L"<w:vanish/>";
break;
}
default:
break;
}

View File

@ -5,6 +5,9 @@
namespace Md
{
#define MD_PARSER_FLAGS MD_DIALECT_GITHUB | MD_FLAG_NOINDENTEDCODEBLOCKS | MD_HTML_FLAG_SKIP_UTF8_BOM | MD_FLAG_HARD_SOFT_BREAKS | MD_HTML_FLAG_XHTML
#define MD_RENDERER_FLAGS MD_HTML_FLAG_XHTML
void ToHtml(const MD_CHAR* pValue, MD_SIZE uSize, void* pData)
{
if (NULL != pData)
@ -14,7 +17,7 @@ void ToHtml(const MD_CHAR* pValue, MD_SIZE uSize, void* pData)
std::string ConvertMdStringToHtml(const std::string& sMdString)
{
std::string sData;
md_html(sMdString.c_str(), sMdString.length(), ToHtml, &sData, 0, 0);
md_html(sMdString.c_str(), sMdString.length(), ToHtml, &sData, MD_PARSER_FLAGS, MD_RENDERER_FLAGS);
return sData;
}
@ -36,22 +39,21 @@ void WriteBaseHtmlStyles(NSFile::CFileBinary& oFile)
oFile.WriteStringUTF8(L"img { vertical-align: middle; }");
// Styles for tables
oFile.WriteStringUTF8(L"table { margin-bottom: 20px; width: 100%; max-width: 100%; border-spacing:0; border-collapse: collapse; border-color: gray;}");
oFile.WriteStringUTF8(L"thead { display: table-header-group; vertical-align: middle; }");
oFile.WriteStringUTF8(L"table { margin-bottom: 20px; width: 100%; max-width: 100%; border-spacing:0; border-collapse: collapse; border-color: gray; vertical-align:middle;}");
oFile.WriteStringUTF8(L"thead { display: table-header-group;}");
oFile.WriteStringUTF8(L"tr { display: table-row; }");
oFile.WriteStringUTF8(L"th { text-align: left; display: table-cell; font-weight: bold; }");
oFile.WriteStringUTF8(L"th { text-align: center; display: table-cell; font-weight: bold; }");
oFile.WriteStringUTF8(L"table thead tr th { vertical-align: bottom; border-bottom: 2px solid #ddd; }");
oFile.WriteStringUTF8(L"table thead tr th, table tbody tr th, table thead tr td, table tbody tr td { padding 8px; line-height: 1.4; vertical-align: top; border-top: 1px solid #ddd; }");
oFile.WriteStringUTF8(L"table > caption + thead > tr > th, table > colgroup + thead > tr > th, table > thead > tr > th, table > caption + thead > tr > td, table > colgroup + thead > tr > td, table > thead > tr > td { border-top: 0; }");
oFile.WriteStringUTF8(L"table thead tr th, table thead tr td { border-bottom: 2px solid #ddd; border-top: none; }");
oFile.WriteStringUTF8(L"table tbody tr th, table tbody tr td { padding 8px; line-height: 1.4; border-top: 1px solid #ddd; }");
// Styles for blockquote
oFile.WriteStringUTF8(L"blockquote { border-left: 3px solid #e9e9e9; margin: 1.5em 0; padding: 0.5em 10px 0.5em 24px; font-size: 1.25rem; display: block; margin-top: 8pt; font-style: italic; color: #404040; }");
// Styles for code
oFile.WriteStringUTF8(L"code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; border-radius: 4px; }");
oFile.WriteStringUTF8(L"pre code { padding: 0px; white-space: pre-wrap; border-radius: 0; background-color: #f5f5f5; color:black; }");
oFile.WriteStringUTF8(L"pre { display: block; padding: 9.5px; margin: 0 0 10px; line-height: 1.4; word-break: break-all; word-wrap: break-word; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; font-size: 1em; }");
oFile.WriteStringUTF8(L"code { padding: 2px 4px; font-size: 90%; color: #c7254e; background-color: #f9f2f4; }");
oFile.WriteStringUTF8(L"pre code { padding: 0px; white-space: pre-wrap; border-radius: 0; background-color: #f8f8f8; color:black; }");
oFile.WriteStringUTF8(L"pre { display: block; padding: 9.5px; margin: 0 0 10px; line-height: 1.4; word-break: break-all; word-wrap: break-word; background-color: #f8f8f8; border: none; font-size: 1em; }");
oFile.WriteStringUTF8(L"code, pre { font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace; }");
// Styles for headings
@ -87,9 +89,7 @@ bool ConvertMdFileToHtml(const std::wstring& wsPathToMdFile, const std::wstring&
bool bResult = true;
if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile,
MD_DIALECT_GITHUB | MD_FLAG_NOINDENTEDCODEBLOCKS | MD_HTML_FLAG_SKIP_UTF8_BOM,
0))
if (0 != md_html(sMdData.c_str(), sMdData.length(), ToHtmlFile, &oFile, MD_PARSER_FLAGS, MD_RENDERER_FLAGS))
bResult = false;
oFile.WriteStringUTF8(L"</body></html>");

View File

@ -45,6 +45,7 @@ win32 {
}
DEFINES += COPYRIGHT_YEAR=$${CURRENT_YEAR}
#DEFINES += _LOGOUT_ALWAYS
QMAKE_TARGET_COMPANY = $$PUBLISHER_NAME
QMAKE_TARGET_COPYRIGHT = © $${PUBLISHER_NAME} $${CURRENT_YEAR}. All rights reserved.
@ -202,12 +203,12 @@ core_win_64 {
core_linux {
DEFINES += LINUX _LINUX
QMAKE_CUSTOM_SYSROOT = $$(QMAKE_CUSTOM_SYSROOT)
QMAKE_CUSTOM_SYSROOT = $$(QMAKE_CUSTOM_SYSROOT)
QMAKE_CUSTOM_SYSROOT_BIN = $$(QMAKE_CUSTOM_SYSROOT)/usr/bin/
core_linux_64 {
!linux_arm64 { # x86_64
QMAKE_CUSTOM_SYSROOT_LIB = $$(QMAKE_CUSTOM_SYSROOT)/usr/lib/x86_64-linux-gnu
core_linux_64 {
!linux_arm64 { # x86_64
QMAKE_CUSTOM_SYSROOT_LIB = $$(QMAKE_CUSTOM_SYSROOT)/usr/lib/x86_64-linux-gnu
!isEmpty(QMAKE_CUSTOM_SYSROOT) {
message("using custom sysroot $$QMAKE_CUSTOM_SYSROOT")
QMAKE_CC = $$join(QMAKE_CUSTOM_SYSROOT_BIN, , , "gcc")
@ -216,7 +217,7 @@ core_linux {
QMAKE_LINK_SHLIB = $$join(QMAKE_CUSTOM_SYSROOT_BIN, , , "g++")
QMAKE_CFLAGS += --sysroot $$QMAKE_CUSTOM_SYSROOT
QMAKE_CXXFLAGS += --sysroot $$QMAKE_CUSTOM_SYSROOT
QMAKE_CXXFLAGS += --sysroot $$QMAKE_CUSTOM_SYSROOT -std=gnu++1y
QMAKE_LFLAGS += --sysroot $$QMAKE_CUSTOM_SYSROOT
}
}

View File

@ -45,6 +45,10 @@
#undef DeleteFile
#endif
#if defined(GetSystemDirectory)
#undef GetSystemDirectory
#endif
#ifndef _BUILD_FILE_CROSSPLATFORM_H_
#define _BUILD_FILE_CROSSPLATFORM_H_

View File

@ -29,11 +29,11 @@
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _SYSTEMUTILS_H
#define _SYSTEMUTILS_H
#pragma once
#include <string>
#include "../../Common/kernel_config.h"
#include "../../OdfFile/Common/logging.h"
#define VALUE_STRINGIFY(d) L##d
#define VALUE_TO_STR(v) VALUE_STRINGIFY(v)
@ -76,4 +76,3 @@ namespace NSSystemUtils
};
KERNEL_DECL std::wstring GetSystemDirectory(const SystemDirectoryType& type);
}
#endif // _SYSTEMUTILS_H

View File

@ -161,7 +161,7 @@
},
{
"folder": "../../../common/",
"files": ["File.cpp", "Directory.cpp", "ByteBuilder.cpp", "Base64.cpp", "StringExt.cpp", "Path.cpp", "SystemUtils.cpp"]
"files": ["File.cpp", "Directory.cpp", "ByteBuilder.cpp", "Base64.cpp", "StringExt.cpp", "Path.cpp", "SystemUtils.cpp", "StringUTF32.cpp", "StringBuilder.cpp"]
},
{
"folder": "../../../../Common/3dParty/icu/icu/source/common/",
@ -252,8 +252,8 @@
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"]
},
{
"folder": "../../../common",
"files": ["StringUTF32.cpp", "StringBuilder.cpp"]
"folder": "../../../../OdfFile/Common",
"files": ["logging.cpp"]
}
]
}

View File

@ -621,6 +621,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF
oFont["vertical"] = readDoubleFunc.call(reader);
if (nFontFlag & (1 << 6))
oFont["actual"] = readStringFunc.call(reader);
oFont["rtl"] = (nFontFlag >> 7) & 1;
oFont["size"] = readDoubleFunc.call(reader);
oFont["color"] = [];
oFont["color"].push(readDouble2Func.call(reader));

View File

@ -1046,7 +1046,7 @@ int main(int argc, char* argv[])
RELEASEARRAYOBJECTS(pFileData);
// SPLIT & MERGE
if (true)
if (false)
{
int nBufferLen = NULL;
BYTE* pBuffer = NULL;
@ -1513,6 +1513,8 @@ int main(int argc, char* argv[])
std::cout << "; font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; ";
i += nPathLength;
}
if (nFontFlag & (1 << 7))
std::cout << "; dir:rtl; ";
nPathLength = READ_INT(pAnnots + i);
i += 4;

View File

@ -121,7 +121,8 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CFont.h \
$$METAFILE_PATH/svg/SvgObjects/CStyle.h \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.h \
$$METAFILE_PATH/svg/SvgUtils.h
$$METAFILE_PATH/svg/SvgUtils.h \
$$METAFILE_PATH/svg/SvgReader.h
SOURCES += \
$$METAFILE_PATH/svg/CSvgFile.cpp \
@ -145,7 +146,8 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CPolyline.cpp \
$$METAFILE_PATH/svg/SvgObjects/CFont.cpp \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.cpp \
$$METAFILE_PATH/svg/SvgObjects/CStyle.cpp
$$METAFILE_PATH/svg/SvgObjects/CStyle.cpp \
$$METAFILE_PATH/svg/SvgReader.cpp
CONFIG += css_calculator_without_xhtml

View File

@ -53,7 +53,7 @@ namespace MetaFile
virtual void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int nBlendMode) = 0;
virtual void DrawString(std::wstring& wsText, unsigned int unCharsCount, double dX, double dY, double* pDx,
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) = 0;
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1, bool bUseGID = false) = 0;
virtual void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) = 0;

View File

@ -352,7 +352,7 @@ namespace MetaFile
}
void DrawString(std::wstring& wsText, unsigned int unCharsCount, double _dX, double _dY, double* pDx, int iGraphicsMode, double dXScale, double dYScale)
void DrawString(std::wstring& wsText, unsigned int unCharsCount, double _dX, double _dY, double* pDx, int iGraphicsMode, double dXScale, double dYScale, bool bUseGID)
{
CheckEndPath();
const IFont* pFont = m_pFile->GetFont();
@ -681,11 +681,12 @@ namespace MetaFile
m_pRenderer->put_BrushColor1(m_pFile->GetTextColor());
m_pRenderer->put_BrushAlpha1(255);
if (bUseGID)
m_pRenderer->put_FontStringGID(TRUE);
// Рисуем сам текст
if (NULL == pDx)
{
m_pRenderer->CommandDrawText(wsString, dX, dY, 0, 0);
}
else
{
unsigned int unUnicodeLen = 0;
@ -704,6 +705,9 @@ namespace MetaFile
}
}
if (bUseGID)
m_pRenderer->put_FontStringGID(FALSE);
if (bChangeCTM)
m_pRenderer->ResetTransform();
}
@ -1233,7 +1237,7 @@ namespace MetaFile
// Вычисление минимально возможной ширины пера
// # Код явялется дублированным из Graphics
const double dSqrtDet = sqrt(abs(oMatrix.Determinant()));
const double dSqrtDet = sqrt(fabs(oMatrix.Determinant()));
const double dWidthMinSize = (dSqrtDet != 0) ? (1.0 / dSqrtDet) : dWidth;
if (0 == pPen->GetWidth())

View File

@ -999,20 +999,21 @@ namespace MetaFile
{
std::wstring wsText;
for (const wchar_t& wChar : wsString)
if (wChar == L'<')
{
if (wChar == L'<')
wsText += L"&lt;";
else if (wChar == L'>')
else if (wChar == L'>')
wsText += L"&gt;";
else if (wChar == L'&')
else if (wChar == L'&')
wsText += L"&amp;";
else if (wChar == L'\'')
else if (wChar == L'\'')
wsText += L"&apos;";
else if (wChar == L'"')
else if (wChar == L'"')
wsText += L"&quot;";
else if (wChar == L'\r' || (wChar >= 0x00 && wChar <=0x1F))
continue;
else wsText += wChar;
else wsText += wChar;
}
return wsText;
}

View File

@ -218,7 +218,7 @@ namespace MetaFile
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) 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, bool bUseGID = false) override {};
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override {};

View File

@ -80,10 +80,10 @@ namespace MetaFile
}
void CEmfInterpretatorArray::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, bool bUseGID)
{
for (CEmfInterpretatorBase* pInterpretator : m_arInterpretators)
pInterpretator->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);
pInterpretator->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale, bUseGID);
}
void CEmfInterpretatorArray::DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints)

View File

@ -36,7 +36,7 @@ namespace MetaFile
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) 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, bool bUseGID = false) override;
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override;

View File

@ -41,10 +41,10 @@ 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, bool bUseGID)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale, bUseGID);
}
void CEmfInterpretatorRender::DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints)

View File

@ -22,7 +22,7 @@ namespace MetaFile
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) 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, bool bUseGID = false) override;
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override;

View File

@ -346,7 +346,7 @@ namespace MetaFile
if (NULL != oTEmfExtTextoutA.oEmrText.pOutputDx)
arDx = std::vector<double>(oTEmfExtTextoutA.oEmrText.pOutputDx, oTEmfExtTextoutA.oEmrText.pOutputDx + oTEmfExtTextoutA.oEmrText.unChars);
WriteText(wsText, TPointD(oTEmfExtTextoutA.oEmrText.oReference.X, oTEmfExtTextoutA.oEmrText.oReference.Y), oTEmfExtTextoutA.oBounds, TPointD(oTEmfExtTextoutA.dExScale, oTEmfExtTextoutA.dEyScale), arDx);
WriteText(wsText, TPointD(oTEmfExtTextoutA.oEmrText.oReference.X, oTEmfExtTextoutA.oEmrText.oReference.Y), oTEmfExtTextoutA.oBounds, TPointD(oTEmfExtTextoutA.dExScale, oTEmfExtTextoutA.dEyScale), arDx, oTEmfExtTextoutA.oEmrText.unOptions & 0x00000010);
}
void CEmfInterpretatorSvg::HANDLE_EMR_EXTTEXTOUTW(const TEmfExtTextoutW &oTEmfExtTextoutW)
@ -358,7 +358,7 @@ namespace MetaFile
if (NULL != oTEmfExtTextoutW.oEmrText.pOutputDx)
arDx = std::vector<double>(oTEmfExtTextoutW.oEmrText.pOutputDx, oTEmfExtTextoutW.oEmrText.pOutputDx + oTEmfExtTextoutW.oEmrText.unChars);
WriteText(wsText, TPointD(oTEmfExtTextoutW.oEmrText.oReference.X, oTEmfExtTextoutW.oEmrText.oReference.Y), oTEmfExtTextoutW.oBounds, TPointD(oTEmfExtTextoutW.dExScale, oTEmfExtTextoutW.dEyScale), arDx);
WriteText(wsText, TPointD(oTEmfExtTextoutW.oEmrText.oReference.X, oTEmfExtTextoutW.oEmrText.oReference.Y), oTEmfExtTextoutW.oBounds, TPointD(oTEmfExtTextoutW.dExScale, oTEmfExtTextoutW.dEyScale), arDx, oTEmfExtTextoutW.oEmrText.unOptions & 0x00000010);
}
void CEmfInterpretatorSvg::HANDLE_EMR_LINETO(const TPointL &oPoint)

View File

@ -202,7 +202,7 @@ namespace MetaFile
void End() 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, bool bUseGID = false) override {};
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override {};

View File

@ -216,7 +216,7 @@ namespace MetaFile
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) 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, bool bUseGID = false) override {};
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override {};

View File

@ -411,7 +411,7 @@ namespace MetaFile
}
void CEmfParserBase::DrawText(std::wstring &wsString, unsigned int unCharsCount, int _nX, int _nY,
int *pnDx, int iGraphicsMode, TScale oScale)
int *pnDx, int iGraphicsMode, TScale oScale, bool bUseGID)
{
int nX = _nX;
int nY = _nY;
@ -448,7 +448,7 @@ namespace MetaFile
}
}
m_pInterpretator->DrawString(wsString, unCharsCount, dX, dY, pdDx, iGraphicsMode, oScale.X, oScale.Y);
m_pInterpretator->DrawString(wsString, unCharsCount, dX, dY, pdDx, iGraphicsMode, oScale.X, oScale.Y, bUseGID);
if (pdDx)
delete[] pdDx;
@ -480,7 +480,7 @@ namespace MetaFile
}
}
DrawText(wsText, oText.unChars, oText.oReference.X, oText.oReference.Y, pDx, iGraphicsMode, oScale);
DrawText(wsText, oText.unChars, oText.oReference.X, oText.oReference.Y, pDx, iGraphicsMode, oScale, oText.unOptions & 0x00000010);
if (pDx)
delete[] pDx;
@ -550,7 +550,7 @@ namespace MetaFile
}
if (unLen)
DrawText(wsText, unLen, oText.oReference.X, oText.oReference.Y, pDx, iGraphicsMode, oScale);
DrawText(wsText, unLen, oText.oReference.X, oText.oReference.Y, pDx, iGraphicsMode, oScale, oText.unOptions & 0x00000010);
if (pDx)
delete[] pDx;

View File

@ -156,7 +156,7 @@ namespace MetaFile
void ArcTo(int nL, int nT, int nR, int nB, double dStart, double dSweep);
void DrawPath(bool bStroke, bool bFill, bool bClosePath = true);
void DrawText(std::wstring &wsString, unsigned int unCharsCount, int _nX, int _nY, int *pnDx, int iGraphicsMode, TScale oScale);
void DrawText(std::wstring &wsString, unsigned int unCharsCount, int _nX, int _nY, int *pnDx, int iGraphicsMode, TScale oScale, bool bUseGID);
void DrawTextA(TEmrTextA &oText, int iGraphicsMode, TScale oScale = TScale(1, 1));
void DrawTextW(TEmrTextW &oText, int iGraphicsMode, TScale oScale = TScale(1, 1));

View File

@ -68,6 +68,10 @@ namespace MetaFile
#ifdef METAFILE_SUPPORT_SVM
m_oSvmFile.SetFontManager(m_pFontManager);
#endif
#ifdef METAFILE_SUPPORT_SVG
m_oSvgFile.SetFontManager(m_pFontManager);
#endif
m_lType = 0;
}
@ -84,7 +88,6 @@ namespace MetaFile
std::wstring CMetaFile::ConvertToSvg(unsigned int unWidth, unsigned int unHeight)
{
#ifdef METAFILE_SUPPORT_WMF_EMF
if (c_lMetaWmf == m_lType)
{

View File

@ -217,15 +217,23 @@ namespace MetaFile
m_pXmlWriter->WriteNodeEnd(wsNodeName, false, false);
}
void CInterpretatorSvgBase::WriteText(const std::wstring &wsText, const TPointD &oCoord, const TRectL &oBounds, const TPointD &oScale, const std::vector<double>& arDx)
void UpdateStringByGID(std::wstring &wsValue, const std::wstring& wsFontName, const double& dFontSize, const int& nFontStyle, NSFonts::IFontManager* pFontManeger)
{
if (nullptr == pFontManeger)
return;
pFontManeger->LoadFontByName(wsFontName, dFontSize, nFontStyle, 96, 96);
for (wchar_t& wChar : wsValue)
wChar = (wchar_t)pFontManeger->GetUnicodeByGID(wChar);
}
void CInterpretatorSvgBase::WriteText(const std::wstring &wsText, const TPointD &oCoord, const TRectL &oBounds, const TPointD &oScale, const std::vector<double>& arDx, bool bUseGID)
{
if (NULL == m_pParser || NULL == m_pParser->GetFont())
return;
const std::wstring wsNormalizedText = StringNormalization(wsText);
if (wsNormalizedText.empty())
return;
std::wstring wsNormalizedText{wsText};
AddClip();
@ -298,6 +306,22 @@ namespace MetaFile
oFontName.WriteEncodeXmlString(pFontInfo->m_wsFontName);
oFontName.WriteEncodeXmlString(L"\'");
}
if (bUseGID)
{
int nStyle = 0;
if (pFont->GetWeight() > 550)
nStyle |= 0x01;
if (pFont->IsItalic())
nStyle |= 0x02;
if (pFont->IsUnderline())
nStyle |= (1 << 2);
if (pFont->IsStrikeOut())
nStyle |= (1 << 7);
UpdateStringByGID(wsNormalizedText, (NULL != pFontInfo) ? pFontInfo->m_wsFontName : pFont->GetFaceName(),
dFontHeight, nStyle, m_pParser->GetFontManager());
}
#endif
arNodeAttributes.Add(L"font-family", oFontName.GetData());
}
@ -424,7 +448,7 @@ namespace MetaFile
arNodeAttributes.Add(L"x", wsXCoord);
arNodeAttributes.Add(L"y", dYCoord);
WriteNode(L"text", arNodeAttributes, wsNormalizedText);
WriteNode(L"text", arNodeAttributes, StringNormalization(wsNormalizedText));
}
else
{
@ -436,7 +460,7 @@ namespace MetaFile
do
{
WriteNode(L"tspan", {{L"x", wsXCoord},
{L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart));
{L"y", ConvertToWString(dYNewCoord)}}, StringNormalization(wsNormalizedText.substr(unStart, unPosLineBreak - unStart)));
dYNewCoord += dFontHeight * 1.6;
unStart = wsNormalizedText.find_first_not_of(L"\n", unPosLineBreak);

View File

@ -106,7 +106,7 @@ namespace MetaFile
void WriteNode(const std::wstring& wsNodeName, const NodeAttributes& arAttributes, const std::wstring& wsValueNode = L"");
void WriteNodeBegin(const std::wstring& wsNodeName, const NodeAttributes& arAttributes);
void WriteNodeEnd(const std::wstring& wsNodeName);
void WriteText(const std::wstring& wsText, const TPointD& oCoord, const TRectL& oBounds = TRectL(), const TPointD& oScale = TPointD(1, 1), const std::vector<double>& arDx = {});
void WriteText(const std::wstring& wsText, const TPointD& oCoord, const TRectL& oBounds = TRectL(), const TPointD& oScale = TPointD(1, 1), const std::vector<double>& arDx = {}, bool bUseGID = false);
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) override;

View File

@ -29,10 +29,10 @@ 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, bool bUseGID)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale, bUseGID);
}
void CWmfInterpretatorRender::DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints)

View File

@ -19,7 +19,7 @@ namespace MetaFile
void DrawBitmap(double dX, double dY, double dW, double dH, BYTE* pBuffer, unsigned int unWidth, unsigned int unHeight, unsigned int unBlendMode) 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, bool bUseGID = false) override;
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override;

View File

@ -109,7 +109,7 @@ namespace MetaFile
void End() 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, bool bUseGID = false) override {};
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override {};

View File

@ -1740,8 +1740,8 @@ namespace MetaFile
const TRectL& oEmfRect{oEmfParser.GetDCBounds()};
const TRectL& oCurentRect{GetDCBounds()};
const double dScaleX = std::abs((oCurentRect.Right - oCurentRect.Left) / (oEmfRect.Right - oEmfRect.Left));
const double dScaleY = std::abs((oCurentRect.Bottom - oCurentRect.Top) / (oEmfRect.Bottom - oEmfRect.Top));
const double dScaleX = std::abs((double)(oCurentRect.Right - oCurentRect.Left) / (double)(oEmfRect.Right - oEmfRect.Left));
const double dScaleY = std::abs((double)(oCurentRect.Bottom - oCurentRect.Top) / (double)(oEmfRect.Bottom - oEmfRect.Top));
const bool bAddGElement = !Equals(1., dScaleX) || !Equals(1., dScaleY);

View File

@ -3,11 +3,13 @@
#include "SvgObjects/CContainer.h"
#include "SvgObjects/CFont.h"
#include "CSvgParser.h"
#define SVG_FILE_WIDTH 300
#define SVG_FILE_HEIGHT 150
CSvgFile::CSvgFile()
: m_oContainer(L"svg")
: m_pContainer(NULL), m_pFontManager(NULL)
{}
CSvgFile::~CSvgFile()
@ -24,7 +26,10 @@ bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize)
bool CSvgFile::ReadFromWString(const std::wstring &wsContext)
{
Clear();
return m_oParser.LoadFromString(wsContext, &m_oContainer, this);
SVG::CSvgParser oSvgParser(m_pFontManager);
return oSvgParser.LoadFromString(wsContext, m_pContainer, this);
}
bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
@ -33,58 +38,14 @@ bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
m_wsWorkingDirectory = NSFile::GetDirectoryName(wsFile);
return m_oParser.LoadFromFile(wsFile, &m_oContainer, this);
SVG::CSvgParser oSvgParser(m_pFontManager);
return oSvgParser.LoadFromFile(wsFile, m_pContainer, this);
}
bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const
{
if (m_oContainer.Empty())
return false;
SVG::TRect oWindow = m_oContainer.GetWindow();
dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
dWidth = 0.;
dHeight = 0.;
if (!oWindow.m_oWidth.Empty() && !oWindow.m_oWidth.Zero())
{
if (NSCSS::Percent == oWindow.m_oWidth.GetUnitMeasure())
{
if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero())
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel));
else
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
else
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel);
}
else
dWidth = m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel);
if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero())
{
if (NSCSS::Percent == oWindow.m_oHeight.GetUnitMeasure())
{
if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero())
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel));
else
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
else
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
}
else
dHeight = m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel);
if (DBL_EPSILON > dWidth)
dWidth = SVG_FILE_WIDTH;
if (DBL_EPSILON > dHeight)
dHeight = SVG_FILE_HEIGHT;
return true;
return CalculateFinalSize(true, dX, dY, dWidth, dHeight);
}
const SVG::CSvgCalculator *CSvgFile::GetSvgCalculator() const
@ -94,7 +55,7 @@ const SVG::CSvgCalculator *CSvgFile::GetSvgCalculator() const
void CSvgFile::SetFontManager(NSFonts::IFontManager *pFontManager)
{
m_oParser.SetFontManager(pFontManager);
m_pFontManager = pFontManager;
}
void CSvgFile::SetWorkingDirectory(const std::wstring &wsWorkingDirectory)
@ -107,7 +68,13 @@ bool CSvgFile::MarkObject(SVG::CObject *pObject)
if (NULL == pObject || pObject->GetId().empty())
return false;
pObject->AddRef();
pObject->Mark();
const MarkedMap::const_iterator itFound = m_mMarkedObjects.find(pObject->GetId());
if (m_mMarkedObjects.cend() != itFound)
RELEASEINTERFACE(m_mMarkedObjects[pObject->GetId()])
m_mMarkedObjects[pObject->GetId()] = pObject;
return true;
@ -160,69 +127,41 @@ void CSvgFile::AddFontFace(const SVG::TFontArguments& oArguments, const std::wst
bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer || m_oContainer.Empty())
if (NULL == pRenderer || NULL == m_pContainer || m_pContainer->Empty())
return false;
SVG::TRect oWindow = m_oContainer.GetWindow();
SVG::TRect oViewBox = m_oContainer.GetViewBox();
double dFileX, dFileY, dFileWidth, dFileHeight;
if (oWindow.m_oWidth.Empty() || oWindow.m_oWidth.Zero())
{
if (oViewBox.m_oWidth.Empty() || oViewBox.m_oWidth.Zero())
oWindow.m_oWidth = SVG_FILE_WIDTH;
else
{
oWindow.m_oWidth = oViewBox.m_oWidth;
oViewBox.m_oWidth.Clear();
}
}
if (oWindow.m_oHeight.Empty() || oWindow.m_oHeight.Zero())
{
if (oViewBox.m_oHeight.Empty() || oViewBox.m_oHeight.Zero())
oWindow.m_oHeight = SVG_FILE_HEIGHT;
else
{
oWindow.m_oHeight = oViewBox.m_oHeight;
oViewBox.m_oHeight.Clear();
}
}
double dViewBoxWidth = oViewBox.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
double dViewBoxHeight = oViewBox.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
double dWindowWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, dViewBoxWidth);
double dWindowHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, dViewBoxHeight);
if (SVG::Equals(0., dWindowWidth) || SVG::Equals(0., dWindowHeight))
if (!CalculateFinalSize(false, dFileX, dFileY, dFileWidth, dFileHeight))
return false;
double oldTransform[6];
oldTransform[0] = oldTransform[3] = 1;
oldTransform[1] = oldTransform[2] = oldTransform[4] = oldTransform[5] = 0;
pRenderer->GetTransform(&oldTransform[0], &oldTransform[1], &oldTransform[2], &oldTransform[3], &oldTransform[4], &oldTransform[5]);
pRenderer->ResetTransform();
double dM11 = dWidth / dWindowWidth;
double dM22 = dHeight / dWindowHeight;
const double dM11 = dWidth / dFileWidth;
const double dM22 = dHeight / dFileHeight;
double dScaleX = 1, dScaleY = 1;
double dScaleX = 1.,
dScaleY = 1.;
double dTranslateX = dFileX * dM11,
dTranslateY = dFileY * dM22;
if (!SVG::Equals(0., dViewBoxWidth))
dScaleX = dWindowWidth / dViewBoxWidth;
const SVG::TRect oViewBox{m_pContainer->GetViewBox()};
if (!SVG::Equals(0., dViewBoxHeight))
dScaleY = dWindowHeight / dViewBoxHeight;
if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
{
dScaleX = dFileWidth / oViewBox.m_oWidth .ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH );
dScaleY = dFileHeight / oViewBox.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
double dMinScale = std::min(dScaleX, dScaleY);
dTranslateX -= oViewBox.m_oX.ToDouble(NSCSS::Pixel) * dScaleX * dM11;
dTranslateY -= oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22;
}
double dSkipX = -oViewBox.m_oX.ToDouble(NSCSS::Pixel) * dScaleX * dM11;
double dSkipY = -oViewBox.m_oY.ToDouble(NSCSS::Pixel) * dScaleY * dM22;
pRenderer->SetTransform(dM11 * dScaleX, 0, 0, dM22 * dScaleY, dTranslateX, dTranslateY);
pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dSkipX, dSkipY);
bool bResult = m_oContainer.Draw(pRenderer, this);
bool bResult = m_pContainer->Draw(pRenderer, this);
pRenderer->SetTransform(oldTransform[0], oldTransform[1], oldTransform[2], oldTransform[3], oldTransform[4], oldTransform[5]);
@ -231,7 +170,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
void CSvgFile::Clear()
{
m_oContainer.Clear();
RELEASEINTERFACE(m_pContainer);
m_oSvgCalculator.Clear();
for (MarkedMap::reference oIter : m_mMarkedObjects)
@ -240,3 +179,141 @@ void CSvgFile::Clear()
m_mMarkedObjects.clear();
m_wsWorkingDirectory.clear();
}
bool CSvgFile::CalculateFinalSize(bool bUseViewBox, double& dX, double& dY, double& dWidth, double& dHeight) const
{
if (NULL == m_pContainer || m_pContainer->Empty())
return false;
const SVG::TRect oWindow = m_pContainer->GetWindow();
const SVG::TRect oViewBox = m_pContainer->GetViewBox();
const double dViewBoxWidth {oViewBox.m_oWidth .ToDouble()};
const double dViewBoxHeigth{oViewBox.m_oHeight.ToDouble()};
dX = 0.;
dY = 0.;
dWidth = 0.;
dHeight = 0.;
#define GET_PREV_WIDTH_VALUE ((NSCSS::UnitMeasure::Em == oWindow.m_oWidth.GetUnitMeasure() || NSCSS::UnitMeasure::Rem == oWindow.m_oWidth.GetUnitMeasure()) ? DEFAULT_FONT_SIZE : ((!SVG::Equals(0., dViewBoxWidth )) ? dViewBoxWidth : SVG_FILE_WIDTH))
#define GET_PREV_HEIGHT_VALUE ((NSCSS::UnitMeasure::Em == oWindow.m_oHeight.GetUnitMeasure() || NSCSS::UnitMeasure::Rem == oWindow.m_oHeight.GetUnitMeasure()) ? DEFAULT_FONT_SIZE : ((!SVG::Equals(0., dViewBoxHeigth )) ? dViewBoxHeigth : SVG_FILE_HEIGHT))
if (!oWindow.m_oWidth.Empty() && !oWindow.m_oHeight.Empty())
{
dWidth = oWindow.m_oWidth .ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
return true;
}
if (bUseViewBox)
{
if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
{
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
dHeight = dWidth / dAspectRatio;
return true;
}
if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
dWidth = dHeight * dAspectRatio;
return true;
}
dX = oViewBox.m_oX.ToDouble();
dY = oViewBox.m_oY.ToDouble();
dWidth = dViewBoxWidth;
dHeight = dViewBoxHeigth;
return true;
}
}
if (!oWindow.m_oWidth.Empty() || !oWindow.m_oHeight.Empty())
{
if (!oViewBox.m_oWidth.Empty() && !oViewBox.m_oHeight.Empty())
{
const double dAspectRatio{dViewBoxWidth / dViewBoxHeigth};
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = dWidth / dAspectRatio;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = dHeight * dAspectRatio;
}
return true;
}
if (NULL != m_pContainer && !m_pContainer->Empty())
{
SVG::SvgMatrix oTransform;
const SVG::TBounds oBounds{m_pContainer->GetBounds(&oTransform)};
const double dContentWidth {oBounds.m_dRight - oBounds.m_dLeft};
const double dContentHeight{oBounds.m_dBottom - oBounds.m_dTop };
const double dAspectRatio{dContentWidth / dContentHeight};
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = dWidth / dAspectRatio;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = dHeight * dAspectRatio;
}
dX = oBounds.m_dLeft;
dY = oBounds.m_dTop;
return true;
}
if (!oWindow.m_oWidth.Empty())
{
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, GET_PREV_WIDTH_VALUE);
dHeight = SVG_FILE_HEIGHT;
}
else if (!oWindow.m_oHeight.Empty())
{
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, GET_PREV_HEIGHT_VALUE);
dWidth = SVG_FILE_WIDTH;
}
return true;
}
if (NULL != m_pContainer && !m_pContainer->Empty())
{
SVG::SvgMatrix oTransform;
const SVG::TBounds oBounds{m_pContainer->GetBounds(&oTransform)};
dX = oBounds.m_dLeft;
dY = oBounds.m_dTop;
dWidth = oBounds.m_dRight - oBounds.m_dLeft;
dHeight = oBounds.m_dBottom - oBounds.m_dTop;
return true;
}
dWidth = SVG_FILE_WIDTH;
dHeight = SVG_FILE_HEIGHT;
return true;
}

View File

@ -4,13 +4,13 @@
#include "../../../graphics/IRenderer.h"
#include "../../../graphics/pro/Fonts.h"
#include "CSvgParser.h"
#include "SvgObjects/CStyle.h"
namespace SVG
{
struct TFontArguments;
class CFont;
class CGraphicsContainer;
}
class CSvgFile
@ -43,9 +43,11 @@ class CSvgFile
private:
void Clear();
SVG::CSvgParser m_oParser;
SVG::CGraphicsContainer m_oContainer;
bool CalculateFinalSize(bool bUseViewBox, double& dX, double& dY, double& dWidth, double& dHeight) const;
SVG::CGraphicsContainer *m_pContainer;
SVG::CSvgCalculator m_oSvgCalculator;
NSFonts::IFontManager *m_pFontManager;
typedef std::map<std::wstring, SVG::CObject*> MarkedMap;

View File

@ -24,16 +24,16 @@
#include "SvgObjects/CMask.h"
#include "SvgObjects/CUse.h"
#include "../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
CSvgParser::CSvgParser()
: m_pFontManager(NULL)
{
}
CSvgParser::CSvgParser(NSFonts::IFontManager* pFontManager)
: m_pFontManager(pFontManager)
{}
CSvgParser::~CSvgParser()
{
}
{}
void CSvgParser::SetFontManager(NSFonts::IFontManager *pFontManager)
{
@ -74,7 +74,7 @@ namespace SVG
return std::string(itEncodingValueBegin, itEncodingValueEnd);
}
bool CSvgParser::LoadFromFile(const std::wstring &wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::LoadFromFile(const std::wstring &wsFile, CGraphicsContainer*& pContainer, CSvgFile* pFile) const
{
if (wsFile.empty() || NULL == pFile)
return false;
@ -102,69 +102,54 @@ namespace SVG
else
return false;
XmlUtils::IXmlDOMDocument::DisableOutput();
bool bResult = LoadFromString(wsContent, pContainer, pFile);
XmlUtils::IXmlDOMDocument::EnableOutput();
return bResult;
return LoadFromString(wsContent, pContainer, pFile);
}
bool CSvgParser::LoadFromString(const std::wstring &wsContentent, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::LoadFromString(const std::wstring &wsContent, CGraphicsContainer*& pContainer, CSvgFile* pFile) const
{
if (wsContentent.empty() || NULL == pFile)
if (wsContent.empty() || NULL == pFile)
return false;
XmlUtils::CXmlNode oXml;
if (!oXml.FromXmlString(wsContentent))
CSvgReader oReader;
if (!oReader.ReadFromString(wsContent))
return false;
ScanStyles(oXml, pFile);
ScanStyles(oReader, pFile);
oReader.MoveToStart();
if (NULL != pContainer)
pContainer->SetData(oXml);
RELEASEINTERFACE(pContainer);
return LoadFromXmlNode(oXml, pContainer, pFile);
pContainer = CObject::Create<CGraphicsContainer>(oReader, pFile);
if (NULL == pContainer)
return false;
return ReadChildrens(oReader, pContainer, pFile, pContainer);
}
bool CSvgParser::LoadFromXmlNode(XmlUtils::CXmlNode &oElement, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::ScanStyles(CSvgReader& oReader, CSvgFile *pFile) const
{
if (NULL == pFile || !oElement.IsValid())
if (oReader.IsEmptyNode() || NULL == pFile)
return false;
const CSvgCalculator *pSvgCalculator = pFile->GetSvgCalculator();
const std::string sElementName = oReader.GetName();
if (NULL != pSvgCalculator)
pSvgCalculator->SetData(pContainer);
return ReadChildrens(oElement, pContainer, pFile, pContainer);
}
bool CSvgParser::ScanStyles(XmlUtils::CXmlNode &oElement, CSvgFile *pFile) const
{
if (!oElement.IsValid() || NULL == pFile)
return false;
std::wstring wsElementName = oElement.GetName();
if (L"style" == wsElementName)
if ("style" == sElementName)
{
ParseStyles(oElement.GetText(), pFile);
ParseStyles(oReader.GetText(), pFile);
return true;
}
bool bScanResult = false;
if (L"svg" == wsElementName || L"g" == wsElementName || L"defs" == wsElementName)
if ("svg" == sElementName || "g" == sElementName || "defs" == sElementName)
{
std::vector<XmlUtils::CXmlNode> arChilds;
oElement.GetChilds(arChilds);
for (XmlUtils::CXmlNode& oChild : arChilds)
WHILE_READ_NEXT_NODE(oReader)
{
if (ScanStyles(oChild, pFile))
if (ScanStyles(oReader, pFile))
bScanResult = true;
}
END_WHILE
}
return bScanResult;
@ -224,155 +209,103 @@ namespace SVG
oSearchStart = oMatch.suffix().first;
}
}
template <class ObjectType>
bool CSvgParser::ReadObject(XmlUtils::CXmlNode &oElement, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
bool CSvgParser::ReadObject(CSvgReader& oReader, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
{
if (!oElement.IsValid() || NULL == pFile)
if (NULL == pFile)
return false;
std::wstring wsElementName = oElement.GetName();
const std::string sElementName = oReader.GetName();
CObject *pObject = NULL;
if (L"svg" == wsElementName || L"g" == wsElementName || L"a" == wsElementName)
if ("svg" == sElementName || "g" == sElementName || "a" == sElementName)
{
pObject = new CGraphicsContainer(oElement, pParent);
if (!ReadChildrens(oElement, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
pObject = CObject::Create<CGraphicsContainer>(oReader, pFile, pParent);
if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
{
RELEASEOBJECT(pObject);
RELEASEINTERFACE(pObject);
return false;
}
}
else if (L"line" == wsElementName)
pObject = new CLine(oElement, pParent);
else if (L"rect" == wsElementName)
pObject = new CRect(oElement, pParent);
else if (L"circle" == wsElementName)
pObject = new CCircle(oElement, pParent);
else if (L"ellipse" == wsElementName)
pObject = new CEllipse(oElement, pParent);
else if (L"path" == wsElementName)
pObject = new CPath(oElement, pParent);
else if (L"polyline" == wsElementName)
pObject = new CPolyline(oElement, pParent);
else if (L"polygon" == wsElementName)
pObject = new CPolygon(oElement, pParent);
else if (L"image" == wsElementName)
pObject = new CImage(oElement, pParent);
else if (L"use" == wsElementName)
pObject = new CUse(oElement, pParent);
else if (L"text" == wsElementName)
else if ("line" == sElementName)
pObject = CObject::Create<CLine>(oReader, pFile, pParent);
else if ("rect" == sElementName)
pObject = CObject::Create<CRect>(oReader, pFile, pParent);
else if ("circle" == sElementName)
pObject = CObject::Create<CCircle>(oReader, pFile, pParent);
else if ("ellipse" == sElementName)
pObject = CObject::Create<CEllipse>(oReader, pFile, pParent);
else if ("path" == sElementName)
pObject = CObject::Create<CPath>(oReader, pFile, pParent);
else if ("polyline" == sElementName)
pObject = CObject::Create<CPolyline>(oReader, pFile, pParent);
else if ("polygon" == sElementName)
pObject = CObject::Create<CPolygon>(oReader, pFile, pParent);
else if ("image" == sElementName)
pObject = CObject::Create<CImage>(oReader, pFile, pParent);
else if ("use" == sElementName)
pObject = CObject::Create<CUse>(oReader, pFile, pParent);
else if ("text" == sElementName)
pObject = CObject::Create<CText>(oReader, pFile, pParent, m_pFontManager);
else if ("tspan" == sElementName)
pObject = CObject::Create<CTSpan>(oReader, pFile, pParent, m_pFontManager);
else if ("textPath" == sElementName)
pObject = CObject::Create<CTextPath>(oReader, pFile, pParent, m_pFontManager);
else if ("switch" == sElementName)
{
pObject = CText::Create(oElement, pParent, m_pFontManager);
ReadChildrens(oElement, (CText*)pObject, pFile, (CText*)pObject);
}
else if (L"tspan" == wsElementName)
{
pObject = CTSpan::Create(oElement, pParent, m_pFontManager);
ReadChildrens(oElement, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
}
else if (L"textPath" == wsElementName)
{
pObject = CTextPath::Create(oElement, pParent, m_pFontManager, pFile);
ReadChildrens(oElement, (CTextPath*)pObject, pFile);
}
else if (L"switch" == wsElementName)
{
pObject = new CSwitch(oElement, pParent);
ReadChildrens(oElement, (CSwitch*)pObject, pFile);
pObject = CObject::Create<CSwitch>(oReader, pFile, pParent);
ReadChildrens(oReader, (CSwitch*)pObject, pFile);
}
//defs
else if (L"defs" == wsElementName)
return ReadChildrens<CRenderedObject>(oElement, NULL, pFile);
else if(L"linearGradient" == wsElementName)
else if ("defs" == sElementName)
return ReadChildrens<CRenderedObject>(oReader, NULL, pFile);
else if("linearGradient" == sElementName)
pObject = CObject::Create<CLinearGradient>(oReader, pFile);
else if ("radialGradient" == sElementName)
pObject = CObject::Create<CRadialGradient>(oReader, pFile);
else if ("pattern" == sElementName)
{
pObject = new CLinearGradient(oElement);
ReadChildrens(oElement, (CLinearGradient*)pObject, pFile);
pObject = CObject::Create<CPattern>(oReader, pFile);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CPattern*)pObject)->GetContainer()), pFile);
}
else if (L"radialGradient" == wsElementName)
else if ("clipPath" == sElementName)
{
pObject = new CRadialGradient(oElement);
ReadChildrens(oElement, (CRadialGradient*)pObject, pFile);
pObject = CObject::Create<CClipPath>(oReader, pFile);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CClipPath*)pObject)->GetContainer()), pFile);
}
else if (L"stop" == wsElementName)
else if ("marker" == sElementName)
{
CStopElement *pStopElement = new CStopElement(oElement);
if (AddObject((ObjectType*)pStopElement, pContainer))
{
UpdateStyles(pStopElement, pFile);
return true;
}
else
{
RELEASEOBJECT(pStopElement);
return false;
}
pObject = CObject::Create<CMarker>(oReader, pFile);
ReadChildrens(oReader, (CMarker*)pObject, pFile);
}
else if (L"pattern" == wsElementName)
else if ("mask" == sElementName)
{
pObject = new CPattern(oElement, m_pFontManager);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CPattern*)pObject)->GetContainer()), pFile);
pObject = CObject::Create<CMask>(oReader, pFile);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CMask*)pObject)->GetContainer()), pFile);
}
else if (L"clipPath" == wsElementName)
else if ("symbol" == sElementName)
{
pObject = new CClipPath(oElement);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CClipPath*)pObject)->GetContainer()), pFile);
}
else if (L"marker" == wsElementName)
{
pObject = new CMarker(oElement);
ReadChildrens(oElement, (CMarker*)pObject, pFile);
}
else if (L"mask" == wsElementName)
{
pObject = new CMask(oElement);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CMask*)pObject)->GetContainer()), pFile);
}
else if (L"symbol" == wsElementName)
{
pObject = new CSymbol(oElement);
if (ReadChildrens(oElement, (CSymbol*)pObject, pFile) && MarkObject(pObject, pFile))
pObject = CObject::Create<CSymbol>(oReader, pFile);
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile))
return true;
else
RELEASEOBJECT(pObject);
RELEASEINTERFACE(pObject);
}
else if (L"font" == wsElementName)
else if ("font" == sElementName)
{
pObject = new CFont(oElement);
pObject = CObject::Create<CFont>(oReader, pFile, pFile);
}
if (NULL != pObject)
{
if ((MarkObject(pObject, pFile) && (AppliedObject == pObject->GetType() || NULL == pContainer)) ||
(RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)))
{
UpdateStyles(pObject, pFile);
return true;
}
delete pObject;
}
return false;
}
void CSvgParser::UpdateStyles(CObject *pObject, CSvgFile *pFile) const
{
if (NULL == pObject || NULL == pFile)
return;
const CSvgCalculator *pSvgCalculator = pFile->GetSvgCalculator();
if (NULL != pSvgCalculator)
pSvgCalculator->SetData(pObject);
}
bool CSvgParser::MarkObject(CObject *pObject, CSvgFile *pFile) const
{
if (NULL == pObject || NULL == pFile)
if (NULL == pObject)
return false;
return pFile->MarkObject(pObject);
if ((RendererObject == pObject->GetType() && (AddObject((ObjectType*)pObject, pContainer) || pObject->Marked())) ||
AppliedObject == pObject->GetType())
return true;
RELEASEINTERFACE(pObject);
return false;
}
template <class ObjectType>
@ -382,18 +315,15 @@ namespace SVG
}
template <class ObjectType>
bool CSvgParser::ReadChildrens(XmlUtils::CXmlNode &oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject *pParent) const
bool CSvgParser::ReadChildrens(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject *pParent) const
{
std::vector<XmlUtils::CXmlNode> arChilds;
bool bResult = false;
oElement.GetChilds(arChilds);
WHILE_READ_NEXT_NODE(oReader)
if (ReadObject(oReader, pContainer, pFile, pParent))
bResult = true;
END_WHILE
if (arChilds.empty())
return false;
for (XmlUtils::CXmlNode& oChild : arChilds)
ReadObject(oChild, pContainer, pFile, pParent);
return true;
return bResult;
}
}

View File

@ -3,9 +3,9 @@
#include "../../../common/Directory.h"
#include "../../../graphics/pro/Fonts.h"
#include "../../../xml/include/xmlutils.h"
#include "SvgObjects/CContainer.h"
#include "SvgReader.h"
class CSvgFile;
@ -14,26 +14,23 @@ namespace SVG
class CSvgParser
{
public:
CSvgParser();
CSvgParser(NSFonts::IFontManager* pFontManager = NULL);
~CSvgParser();
void SetFontManager(NSFonts::IFontManager* pFontManager);
bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContentent, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromXmlNode(XmlUtils::CXmlNode& oElement, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer*& pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContent, CGraphicsContainer*& pContainer, CSvgFile* pFile) const;
template <class ObjectType>
bool ReadObject(XmlUtils::CXmlNode& oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ReadObject(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
private:
template <class ObjectType>
bool ReadChildrens(XmlUtils::CXmlNode& oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ReadChildrens(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ScanStyles(XmlUtils::CXmlNode& oElement, CSvgFile* pFile) const;
bool ScanStyles(CSvgReader& oReader, CSvgFile* pFile) const;
void ParseStyles(const std::wstring& wsStyles, CSvgFile *pFile) const;
void UpdateStyles(CObject* pObject, CSvgFile* pFile) const;
bool MarkObject(CObject* pObject, CSvgFile* pFile) const;
template <class ObjectType>
bool AddObject(ObjectType* pObject, CContainer<ObjectType>* pContainer) const;

View File

@ -1,16 +1,27 @@
#include "CCircle.h"
#include "CContainer.h"
#include "CStyle.h"
namespace SVG
{
CCircle::CCircle(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CRenderedObject(oNode, pParent)
CCircle::CCircle(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oR .SetValue(oNode.GetAttribute(L"r"));
START_READ_ATTRIBUTES(oReader)
SetAttribute(sAttributeName, oReader);
END_READ_ATTRIBUTES(oReader)
}
void CCircle::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("cx" == sName)
m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetText());
else if ("r" == sName)
m_oR.SetValue(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CCircle::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
@ -51,7 +62,7 @@ namespace SVG
nTypePath += c_nWindingFillMode;
}
TBounds CCircle::GetBounds() const
TBounds CCircle::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds;
@ -60,6 +71,16 @@ namespace SVG
oBounds.m_dRight = (m_oCx + m_oR).ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = (m_oCy + m_oR).ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds;
}

View File

@ -7,8 +7,10 @@ namespace SVG
{
class CCircle : public CRenderedObject
{
friend class CObject;
CCircle(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CCircle(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
@ -16,7 +18,7 @@ namespace SVG
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
SvgDigit m_oCx;
SvgDigit m_oCy;

View File

@ -2,13 +2,19 @@
namespace SVG
{
CClipPath::CClipPath(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode)
CClipPath::CClipPath(CSvgReader& oReader)
: CAppliedObject(oReader), m_enUnits(ClipU_ObjectBoundingBox)
{}
void CClipPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if (L"userSpaceOnUse" == oNode.GetAttribute(L"gradientUnits"))
m_enUnits = ClipU_UserSpaceOnUse;
if ("gradientUnits" == sName)
{
if ("userSpaceOnUse" == oReader.GetTextA())
m_enUnits = ClipU_UserSpaceOnUse;
}
else
m_enUnits = ClipU_ObjectBoundingBox;
CAppliedObject::SetAttribute(sName, oReader);
}
void CClipPath::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
@ -25,7 +31,7 @@ namespace SVG
ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oObjectBounds);
for (const CRenderedObject* pObject : m_oContainer.m_arObjects)
for (const CRenderedObject* pObject : m_oContainer)
pObject->Draw(pRenderer, pFile, CommandeModeClip);
return true;

View File

@ -13,8 +13,10 @@ namespace SVG
class CClipPath : public CAppliedObject
{
friend class CObject;
CClipPath(CSvgReader& oReader);
public:
CClipPath(XmlUtils::CXmlNode& oNode);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;

View File

@ -5,30 +5,23 @@
namespace SVG
{
CGraphicsContainer::CGraphicsContainer(const std::wstring &wsName)
: CRenderedObject(NSCSS::CNode(wsName, L"", L""))
CGraphicsContainer::CGraphicsContainer(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
CGraphicsContainer::~CGraphicsContainer()
void CGraphicsContainer::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
for (CRenderedObject* pObject : m_arObjects)
pObject->m_pParent = NULL;
}
void CGraphicsContainer::SetData(XmlUtils::CXmlNode &oNode)
{
SetNodeData(oNode);
m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"width"), 0, true);
m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"height"), 0, true);
const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox");
if (!wsViewBox.empty())
if ("x" == sName)
m_oWindow.m_oX.SetValue(oReader.GetText());
else if ("y" == sName)
m_oWindow.m_oY.SetValue(oReader.GetText());
else if ("width" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetText());
else if ("viewBox" == sName)
{
std::vector<double> arValues = StrUtils::ReadDoubleValues(wsViewBox);
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};
if (4 == arValues.size())
{
m_oViewBox.m_oX = arValues[0];
@ -38,19 +31,9 @@ namespace SVG
}
}
else
m_oViewBox = m_oWindow;
CRenderedObject::SetAttribute(sName, oReader);
}
CGraphicsContainer::CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
SetData(oNode);
}
CGraphicsContainer::CGraphicsContainer(double dWidth, double dHeight, XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent), m_oWindow{0, 0, dWidth, dHeight}
{}
bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
Aggplus::CMatrix oOldTransform;
@ -76,7 +59,7 @@ namespace SVG
return m_oViewBox;
}
TBounds CGraphicsContainer::GetBounds() const
TBounds CGraphicsContainer::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds, oTempBounds;
@ -85,15 +68,21 @@ namespace SVG
oBounds.m_dRight += m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom += m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
for (const CRenderedObject* pObject : m_arObjects)
{
oTempBounds = pObject->GetBounds();
oTempBounds = pObject->GetBounds(pTransform);
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft);
oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop);
oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight);
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom);
}
if (nullptr != pTransform)
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
return oBounds;
}

View File

@ -12,8 +12,9 @@ namespace SVG
template<typename TypeObject>
class CContainer
{
using const_iterator = typename std::vector<TypeObject*>::const_iterator;
public:
CContainer(){}
CContainer() = default;
virtual ~CContainer()
{
Clear();
@ -61,39 +62,35 @@ namespace SVG
return NULL;
}
private:
std::vector<TypeObject*> m_arObjects;
friend class CText;
friend class CMask;
friend class CTSpan;
friend class CMarker;
friend class CSwitch;
friend class CPattern;
friend class CGradient;
friend class CClipPath;
friend class CTextPath;
friend class CLinearGradient;
friend class CGraphicsContainer;
const_iterator begin() const
{
return m_arObjects.cbegin();
}
const_iterator end() const
{
return m_arObjects.cend();
}
protected:
std::vector<TypeObject*> m_arObjects;
};
class CGraphicsContainer : public CContainer<CRenderedObject>, public CRenderedObject
{
friend class CObject;
CGraphicsContainer(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer");
CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CGraphicsContainer(double dWidth, double dHeight, XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CGraphicsContainer() = default;
virtual ~CGraphicsContainer();
void SetData(XmlUtils::CXmlNode& oNode);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
TRect GetWindow() const;
TRect GetViewBox() const;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
private:
TBounds GetBounds() const override;
friend class CPattern;
friend class CMarker;

View File

@ -1,18 +1,12 @@
#include "CEllipse.h"
#include "CStyle.h"
#include "CContainer.h"
namespace SVG
{
CEllipse::CEllipse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oRx.SetValue(oNode.GetAttribute(L"rx"));
m_oRy.SetValue(oNode.GetAttribute(L"ry"));
}
CEllipse::CEllipse(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{}
void CEllipse::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
@ -22,6 +16,20 @@ namespace SVG
SetFill(mAttributes, ushLevel, bHardMode);
}
void CEllipse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("cx" == sName)
m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetText());
else if ("rx" == sName)
m_oRx.SetValue(oReader.GetText());
else if ("ry" == sName)
m_oRy.SetValue(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
}
bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
Aggplus::CMatrix oOldTransform;
@ -56,7 +64,7 @@ namespace SVG
nTypePath += c_nWindingFillMode;
}
TBounds CEllipse::GetBounds() const
TBounds CEllipse::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds;
@ -65,6 +73,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRx.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRy.ToDouble(NSCSS::Pixel);;
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds;
}
}

View File

@ -1,23 +1,24 @@
#ifndef CELLIPSE_H
#define CELLIPSE_H
#include "CObjectBase.h"
namespace SVG
{
class CEllipse : public CRenderedObject
{
friend class CObject;
CEllipse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CEllipse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
SvgDigit m_oCx;
SvgDigit m_oCy;

View File

@ -2,15 +2,23 @@
namespace SVG
{
CGlyph::CGlyph(XmlUtils::CXmlNode &oNode)
: CPath(oNode)
CGlyph::CGlyph(CSvgReader& oReader, CSvgFile* pFile)
: CPath(oReader)
{}
void CGlyph::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
std::wstring wsUnicode(oNode.GetAttribute(L"unicode"));
if ("unicode" == sName)
{
const std::wstring wsUnicode{oReader.GetText()};
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
}
else if ("horiz-adv-x" == sName)
m_oHorizAdvX.SetValue(oReader.GetText());
else
CPath::SetAttribute(sName, oReader);
}
wchar_t CGlyph::GetUnicode() const
@ -18,21 +26,13 @@ namespace SVG
return m_wchUnicode;
}
CFontFace::CFontFace(XmlUtils::CXmlNode &oNode)
CFontFace::CFontFace(CSvgReader& oReader)
{}
CFont::CFont(CSvgReader& oReader, CSvgFile* pFile)
: CAppliedObject(oReader), m_pMissingGlyph(NULL)
{
}
CFont::CFont(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode), m_pMissingGlyph(NULL)
{
ParseGlyphs(oNode);
m_oArguments.m_wsFontVariant = oNode.GetAttribute(L"font-variant");
m_oArguments.m_wsFontStyle = oNode.GetAttribute(L"font-style");
m_oArguments.m_wsFontWidght = oNode.GetAttribute(L"font-weight");
m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
ParseGlyphs(oReader, pFile);
}
CFont::~CFont()
@ -43,6 +43,20 @@ namespace SVG
RELEASEOBJECT(m_pMissingGlyph);
}
void CFont::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("font-variant" == sName)
m_oArguments.m_wsFontVariant = oReader.GetText();
else if ("font-style" == sName)
m_oArguments.m_wsFontStyle = oReader.GetText();
else if ("font-weight" == sName)
m_oArguments.m_wsFontWidght = oReader.GetText();
else if ("horiz-adv-x" == sName)
m_oHorizAdvX.SetValue(oReader.GetText());
else
CAppliedObject::SetAttribute(sName, oReader);
}
void CFont::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
}
@ -82,7 +96,7 @@ namespace SVG
{ \
oMatrix.Scale(1. / dGlyphScale, -1. / dGlyphScale); \
pRenderer->SetTransform(oMatrix.sx(), oMatrix.shy(), oMatrix.shx(), oMatrix.sy(), oMatrix.tx(), oMatrix.ty()); \
} \
}
for (wchar_t wchGlyph : wsText)
{
@ -115,18 +129,13 @@ namespace SVG
return true;
}
void CFont::ParseGlyphs(XmlUtils::CXmlNode &oNode)
void CFont::ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile)
{
std::vector<XmlUtils::CXmlNode> arChilds;
if (!oNode.GetChilds(arChilds) || arChilds.empty())
return;
for (XmlUtils::CXmlNode& oChild : arChilds)
WHILE_READ_NEXT_NODE_WITH_NAME(oReader)
{
if (L"glyph" == oChild.GetName())
if ("glyph" == sNodeName)
{
CGlyph *pGlyph = new CGlyph(oChild);
CGlyph *pGlyph = CObject::Create<CGlyph>(oReader, pFile, pFile);
if (NULL == pGlyph)
continue;
@ -136,22 +145,17 @@ namespace SVG
else
delete pGlyph;
}
else if (L"missing-glyph" == oChild.GetName())
else if ("missing-glyph" == sNodeName)
{
std::vector<XmlUtils::CXmlNode> arMissingGlyphChilds;
if (!oChild.GetChilds(arMissingGlyphChilds) || arMissingGlyphChilds.empty())
continue;
for (XmlUtils::CXmlNode& oChildMissingGlyph : arMissingGlyphChilds)
WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(oReader, Child, "path")
{
if (L"path" == oChildMissingGlyph.GetName())
{
m_pMissingGlyph = new CPath(oChildMissingGlyph);
if (NULL != m_pMissingGlyph)
break;
}
m_pMissingGlyph = new CPath(oReader);
if (NULL != m_pMissingGlyph)
break;
}
END_WHILE
}
}
END_WHILE
}
}

View File

@ -8,7 +8,9 @@ namespace SVG
class CGlyph : public CPath
{
public:
CGlyph(XmlUtils::CXmlNode& oNode);
CGlyph(CSvgReader& oReader, CSvgFile* pFile = nullptr);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
wchar_t GetUnicode() const;
private:
@ -21,7 +23,7 @@ namespace SVG
class CFontFace
{
public:
CFontFace(XmlUtils::CXmlNode& oNode);
CFontFace(CSvgReader& oReader);
private:
std::wstring m_wsSrcFaceName;
};
@ -36,16 +38,19 @@ namespace SVG
class CFont : public CAppliedObject
{
friend class CObject;
CFont(CSvgReader& oReader, CSvgFile* pFile = nullptr);
public:
CFont(XmlUtils::CXmlNode& oNode);
~CFont();
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
private:
void ParseGlyphs(XmlUtils::CXmlNode& oNode);
void ParseGlyphs(CSvgReader& oReader, CSvgFile* pFile = nullptr);
TFontArguments m_oArguments;

View File

@ -3,13 +3,13 @@
namespace SVG
{
CStopElement::CStopElement(XmlUtils::CXmlNode& oNode)
: CObject(oNode)
CStopElement::CStopElement(CSvgReader& oReader)
: CObject(oReader)
{}
ObjectType CStopElement::GetType() const
{
return AppliedObject;
return DataObject;
}
SvgDigit CStopElement::GetOffset() const
@ -34,20 +34,36 @@ namespace SVG
m_oColor.SetOpacity(mAttributes.at(L"stop-opacity"));
}
CGradient::CGradient(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode)
{
m_wsXlinkHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
m_oTransform.SetMatrix(oNode.GetAttribute(L"gradientTransform"), 0, true);
CGradient::CGradient(CSvgReader& oReader)
: CAppliedObject(oReader), m_enGradientUnits(GradU_ObjectBoundingBox)
{}
if (L"userSpaceOnUse" == oNode.GetAttribute(L"gradientUnits"))
m_enGradientUnits = GradU_UserSpaceOnUse;
void CGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("href" == sName || "xlink:href" == sName)
m_wsXlinkHref = oReader.GetText();
else if ("gradientTransform" == sName)
m_oTransform.SetMatrix(oReader.GetText(), 0, true);
else if ("gradientUnits" == sName)
{
if (L"userSpaceOnUse" == oReader.GetText())
m_enGradientUnits = GradU_UserSpaceOnUse;
}
else
m_enGradientUnits = GradU_ObjectBoundingBox;
CAppliedObject::SetAttribute(sName, oReader);
}
void CGradient::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
void CGradient::SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode)
{}
void CGradient::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
{
if (NULL == pSvgFile || NULL == pSvgFile->GetSvgCalculator())
return;
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "stop")
AddObject(CObject::Create<CStopElement>(oReader, pSvgFile));
END_WHILE
}
bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -117,13 +133,22 @@ namespace SVG
return pRefGradient->Apply(pRenderer, pFile, oObjectBounds);
}
CLinearGradient::CLinearGradient(XmlUtils::CXmlNode& oNode)
: CGradient(oNode)
CLinearGradient::CLinearGradient(CSvgReader& oReader)
: CGradient(oReader)
{}
void CLinearGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
m_oX1.SetValue(oNode.GetAttribute(L"x1"));
m_oY1.SetValue(oNode.GetAttribute(L"y1"));
m_oX2.SetValue(oNode.GetAttribute(L"x2"));
m_oY2.SetValue(oNode.GetAttribute(L"y2"));
if ("x1" == sName)
m_oX1.SetValue(oReader.GetText());
else if ("y1" == sName)
m_oY1.SetValue(oReader.GetText());
else if ("x2" == sName)
m_oX2.SetValue(oReader.GetText());
else if ("y2" == sName)
m_oY2.SetValue(oReader.GetText());
else
CGradient::SetAttribute(sName, oReader);
}
bool CLinearGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -169,12 +194,20 @@ namespace SVG
return true;
}
CRadialGradient::CRadialGradient(XmlUtils::CXmlNode& oNode)
: CGradient(oNode)
CRadialGradient::CRadialGradient(CSvgReader& oReader)
: CGradient(oReader)
{}
void CRadialGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oR.SetValue(oNode.GetAttribute(L"r"));
if ("cx" == sName)
m_oCx.SetValue(oReader.GetText());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetText());
else if ("r" == sName)
m_oR.SetValue(oReader.GetText());
else
CGradient::SetAttribute(sName, oReader);
}
bool CRadialGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)

View File

@ -22,7 +22,7 @@ namespace SVG
class CStopElement : public CObject
{
public:
CStopElement(XmlUtils::CXmlNode& oNode);
CStopElement(CSvgReader& oReader);
ObjectType GetType() const override;
@ -37,16 +37,18 @@ namespace SVG
class CGradient : public CContainer<CStopElement>, public CAppliedObject
{
friend class CLinearGradient;
friend class CRadialGradient;
protected:
CGradient(CSvgReader& oReader);
public:
CGradient(XmlUtils::CXmlNode& oNode);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
void ApplyTransform(IRenderer *pRenderer, const TBounds& oBounds, double& dAngle) const;
private:
protected:
CGradient* GetRefGradient(const CSvgFile *pFile) const;
bool ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const;
@ -58,8 +60,10 @@ namespace SVG
class CLinearGradient : public CGradient
{
friend class CObject;
CLinearGradient(CSvgReader& oReader);
public:
CLinearGradient(XmlUtils::CXmlNode& oNode);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:
@ -71,8 +75,10 @@ namespace SVG
class CRadialGradient : public CGradient
{
friend class CObject;
CRadialGradient(CSvgReader& oReader);
public:
CRadialGradient(XmlUtils::CXmlNode& oNode);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:

View File

@ -5,18 +5,29 @@
#include "../../../BgraFrame.h"
#include "../../../../common/Path.h"
#include "../../../../common/ProcessEnv.h"
#include "../../../../common/Base64.h"
#include "../../../../common/File.h"
namespace SVG
{
CImage::CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CRenderedObject(oNode, pParent)
{
m_oRect.m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oRect.m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oRect.m_oWidth .SetValue(oNode.GetAttribute(L"width"));
m_oRect.m_oHeight.SetValue(oNode.GetAttribute(L"height"));
CImage::CImage(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{}
m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href")); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
void CImage::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetText());
else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetText());
else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetText());
else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText(); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
else
CRenderedObject::SetAttribute(sName, oReader);
}
bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
@ -124,7 +135,7 @@ namespace SVG
return true;
}
TBounds CImage::GetBounds() const
TBounds CImage::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds;
@ -133,6 +144,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds;
}
}

View File

@ -7,12 +7,14 @@ namespace SVG
{
class CImage : public CRenderedObject
{
friend class CObject;
CImage(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private:
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
TRect m_oRect;
std::wstring m_wsHref;

View File

@ -2,21 +2,46 @@
namespace SVG
{
CLine::CLine(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPath(oNode, pParent, false)
{
SvgDigit oX1;
SvgDigit oY1;
SvgDigit oX2;
SvgDigit oY2;
CLine::CLine(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent)
{
AddElement(new CMoveElement(Point{0, 0}));
AddElement(new CLineElement(Point{0, 0}));
}
oX1.SetValue(oNode.GetAttribute(L"x1"));
oY1.SetValue(oNode.GetAttribute(L"y1"));
oX2.SetValue(oNode.GetAttribute(L"x2"));
oY2.SetValue(oNode.GetAttribute(L"y2"));
void CLine::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
//TODO:: не нравится, подумать как можно сделать иначе
if ("x1" == sName)
{
CMoveElement* pMoveElement{dynamic_cast<CMoveElement*>(operator[](0))};
AddElement(new CMoveElement(Point{oX1.ToDouble(NSCSS::Pixel), oY1.ToDouble(NSCSS::Pixel)}));
AddElement(new CLineElement(Point{oX2.ToDouble(NSCSS::Pixel), oY2.ToDouble(NSCSS::Pixel)}));
if (NULL != pMoveElement)
pMoveElement->m_oPoint.dX = oReader.GetDouble();
}
else if ("y1" == sName)
{
CMoveElement* pMoveElement{dynamic_cast<CMoveElement*>(operator[](0))};
if (NULL != pMoveElement)
pMoveElement->m_oPoint.dY = oReader.GetDouble();
}
else if ("x2" == sName)
{
CLineElement* pLineElement{dynamic_cast<CLineElement*>(operator[](1))};
if (NULL != pLineElement)
pLineElement->m_oPoint.dX = oReader.GetDouble();
}
else if ("y2" == sName)
{
CLineElement* pLineElement{dynamic_cast<CLineElement*>(operator[](1))};
if (NULL != pLineElement)
pLineElement->m_oPoint.dY = oReader.GetDouble();
}
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CLine::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)

View File

@ -7,8 +7,10 @@ namespace SVG
{
class CLine : public CPath
{
friend class CObject;
CLine(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CLine(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
private:

View File

@ -1,26 +1,35 @@
#include "CMarker.h"
#include "../../../graphics/pro/Graphics.h"
#include "../SvgUtils.h"
namespace SVG
{
CMarker::CMarker(XmlUtils::CXmlNode &oNode)
: CObject(oNode), m_dAngle(0.), m_oBounds{0., 0., 0., 0.}
CMarker::CMarker(CSvgReader& oReader)
: CObject(oReader), m_enUnits{EMarkerUnits::StrokeWidth}, m_enOrient{EMarkerOrient::Angle},
m_dAngle(0.), m_oBounds{0., 0., 0., 0.}
{
m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"refX"));
m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"refY"));
m_oWindow.m_oWidth.SetValue(3);
m_oWindow.m_oHeight.SetValue(3);
}
m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"markerWidth", L"3"));
m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"markerHeight", L"3"));
ObjectType CMarker::GetType() const
{
return AppliedObject;
}
m_oViewBox = m_oWindow;
const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox");
if (!wsViewBox.empty())
void CMarker::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("refX" == sName)
m_oWindow.m_oX.SetValue(oReader.GetText());
else if ("refY" == sName)
m_oWindow.m_oY.SetValue(oReader.GetText());
else if ("markerWidth" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetText());
else if ("markerHeight" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetText());
else if ("viewBox" == sName)
{
std::vector<double> arValues = StrUtils::ReadDoubleValues(wsViewBox);
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};
if (4 == arValues.size())
{
m_oViewBox.m_oX = arValues[0];
@ -29,35 +38,24 @@ namespace SVG
m_oViewBox.m_oHeight = arValues[3];
}
}
const std::wstring& wsUnits = oNode.GetAttribute(L"markerUnits");
if (L"userSpaceOnUse" == wsUnits)
m_enUnits = EMarkerUnits::UserSpaceOnUse;
else
m_enUnits = EMarkerUnits::StrokeWidth;
const std::wstring& wsOrient = oNode.GetAttribute(L"orient");
if (L"auto" == wsOrient)
m_enOrient = EMarkerOrient::Auto;
else if (L"auto-start-reverse" == wsOrient)
m_enOrient = EMarkerOrient::Auto_start_reverse;
else
else if ("markerUnits" == sName)
{
m_enOrient = EMarkerOrient::Angle;
if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
if (L"userSpaceOnUse" == oReader.GetText())
m_enUnits = EMarkerUnits::UserSpaceOnUse;
}
else if ("orient" == sName)
{
const std::wstring& wsOrient{oReader.GetText()};
if (L"auto" == wsOrient)
m_enOrient = EMarkerOrient::Auto;
else if (L"auto-start-reverse" == wsOrient)
m_enOrient = EMarkerOrient::Auto_start_reverse;
else if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
StrUtils::ReadDoubleValue(wsOrient, m_dAngle);
}
}
CMarker::~CMarker()
{
}
ObjectType CMarker::GetType() const
{
return AppliedObject;
else
CObject::SetAttribute(sName, oReader);
}
void CMarker::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
@ -68,7 +66,11 @@ namespace SVG
if (NULL == oExternalData.m_pPoints || oExternalData.m_pPoints->empty() || m_arObjects.empty() || (EMarkerUnits::StrokeWidth == m_enUnits && Equals(0., oExternalData.m_dStroke)))
return;
const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) * std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)), (m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel)));
const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) *
((!m_oViewBox.m_oWidth.Empty() && !m_oViewBox.m_oHeight.Empty()) ?
std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)),
(m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel))) :
1.);
double dM11, dM12, dM21, dM22, dDx, dDy;
pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);

View File

@ -45,12 +45,15 @@ namespace SVG
class CMarker : public CObject, public CContainer<CRenderedObject>
{
friend class CObject;
CMarker(CSvgReader& oReader);
public:
CMarker(XmlUtils::CXmlNode& oNode);
virtual ~CMarker();
virtual ~CMarker() = default;
ObjectType GetType() const override;
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
void Draw(IRenderer* pRenderer, const CSvgFile *pFile, const TMarkerExternData& oExternalData, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;

View File

@ -2,8 +2,8 @@
namespace SVG
{
CMask::CMask(XmlUtils::CXmlNode &oNode)
: CClipPath(oNode)
CMask::CMask(CSvgReader& oReader)
: CClipPath(oReader)
{}
bool CMask::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -14,7 +14,7 @@ namespace SVG
pRenderer->BeginCommand(c_nMaskType);
pRenderer->PathCommandStart();
for (const CRenderedObject* pObject : m_oContainer.m_arObjects)
for (const CRenderedObject* pObject : m_oContainer)
pObject->Draw(pRenderer, pFile, CommandeModeMask);
pRenderer->EndCommand(c_nMaskType);

View File

@ -7,9 +7,9 @@ namespace SVG
{
class CMask : public CClipPath
{
friend class CObject;
CMask(CSvgReader& oReader);
public:
CMask(XmlUtils::CXmlNode& oNode);
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
};
}

View File

@ -1,6 +1,8 @@
#include "CObjectBase.h"
#include "../CSvgFile.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
TSvgStyles &TSvgStyles::operator+=(const TSvgStyles &oSvgStyles)
@ -31,14 +33,42 @@ namespace SVG
: m_oXmlNode(oData)
{}
CObject::CObject(XmlUtils::CXmlNode &oNode)
CObject::CObject(CSvgReader& oReader)
{
SetNodeData(oNode);
m_oXmlNode.m_wsName = oReader.GetNameW();
}
CObject::~CObject()
CObject::CObject(const CObject& oObject)
: m_oXmlNode(oObject.m_oXmlNode), m_oTransformation(oObject.m_oTransformation)
{}
void CObject::Mark()
{
this->AddRef();
}
bool CObject::Marked() const
{
//Так как по логике кода объект может храниться только в одном контейнере и в списке маркированных элементов,
//то хватит и такой проверки
return 1 != m_lRef;
}
void CObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("class" == sName)
{
m_oXmlNode.m_wsClass = oReader.GetText();
std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower);
}
else if ("id" == sName)
m_oXmlNode.m_wsId = oReader.GetText();
else if ("style" == sName)
m_oXmlNode.m_wsStyle = oReader.GetText();
else
m_oXmlNode.m_mAttributes.insert({oReader.GetNameW(), oReader.GetText()});
}
void CObject::SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode)
{
if (wsStyles.empty())
@ -47,6 +77,11 @@ namespace SVG
SetData(NSCSS::NS_STATIC_FUNCTIONS::GetRules(wsStyles), ushLevel, bHardMode);
}
void CObject::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
{
//TODO:: реализовано в классах там, где нужно
}
void CObject::SetTransform(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
if (mAttributes.end() != mAttributes.find(L"transform"))
@ -153,33 +188,6 @@ namespace SVG
return pDefObject->Apply(pRenderer, pFile, oBounds);
}
void CObject::SetNodeData(XmlUtils::CXmlNode &oNode)
{
if (!oNode.IsValid())
return;
std::vector<std::wstring> arProperties, arValues;
oNode.GetAllAttributes(arProperties, arValues);
m_oXmlNode.m_wsName = oNode.GetName();
for (unsigned int unIndex = 0; unIndex < arProperties.size(); ++unIndex)
{
if (L"class" == arProperties[unIndex])
{
m_oXmlNode.m_wsClass = arValues[unIndex];
std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower);
}
else if (L"id" == arProperties[unIndex])
m_oXmlNode.m_wsId = arValues[unIndex];
else if (L"style" == arProperties[unIndex])
m_oXmlNode.m_wsStyle = arValues[unIndex];
else
m_oXmlNode.m_mAttributes.insert({arProperties[unIndex], arValues[unIndex]});
}
}
std::wstring CObject::GetId() const
{
return m_oXmlNode.m_wsId;
@ -193,16 +201,18 @@ namespace SVG
CRenderedObject::CRenderedObject(const NSCSS::CNode &oData, CRenderedObject *pParent)
: CObject(oData), m_pParent(pParent)
{
SetDefaultStyles();
SetDefaultData();
}
CRenderedObject::CRenderedObject(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CObject(oNode), m_pParent(pParent)
CRenderedObject::CRenderedObject(CSvgReader& oReader, CRenderedObject *pParent)
: CObject(oReader), m_pParent(pParent)
{
SetDefaultStyles();
SetDefaultData();
}
CRenderedObject::~CRenderedObject()
CRenderedObject::CRenderedObject(const CRenderedObject& oRenderedObject)
: CObject(oRenderedObject), m_oStyles(oRenderedObject.m_oStyles),
m_pParent(oRenderedObject.m_pParent)
{}
ObjectType CRenderedObject::GetType() const
@ -210,6 +220,11 @@ namespace SVG
return RendererObject;
}
void CRenderedObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CObject::SetAttribute(sName, oReader);
}
void CRenderedObject::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
SetTransform(mAttributes, ushLevel, bHardMode);
@ -229,20 +244,6 @@ namespace SVG
return arObjects;
}
void CRenderedObject::SetDefaultStyles()
{
m_oStyles.m_oStroke.m_oLineCap.SetMapping({std::make_pair(L"butt", Aggplus::LineCapFlat), std::make_pair(L"round", Aggplus::LineCapRound), std::make_pair(L"square", Aggplus::LineCapSquare)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineCapFlat;
m_oStyles.m_oStroke.m_oLineJoin.SetMapping({std::make_pair(L"arcs", Aggplus::LineJoinMiter), std::make_pair(L"bevel", Aggplus::LineJoinBevel), std::make_pair(L"miter", Aggplus::LineJoinMiter), std::make_pair(L"miter-clip", Aggplus::LineJoinMiterClipped), std::make_pair(L"round", Aggplus::LineJoinRound)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineJoinMiter;
m_oStyles.m_oStroke.m_oMiterlimit = 4.;
m_oTransformation.m_oOpacity = 1.;
m_oTransformation.m_bDraw = true;
}
void CRenderedObject::SetStroke(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
if (mAttributes.end() != mAttributes.find(L"stroke"))
@ -447,15 +448,27 @@ namespace SVG
return false;
}
CAppliedObject::CAppliedObject(XmlUtils::CXmlNode &oNode)
: CObject(oNode)
{}
void CRenderedObject::SetDefaultData()
{
m_oStyles.m_oStroke.m_oLineCap.SetMapping({std::make_pair(L"butt", Aggplus::LineCapFlat), std::make_pair(L"round", Aggplus::LineCapRound), std::make_pair(L"square", Aggplus::LineCapSquare)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineCapFlat;
CAppliedObject::~CAppliedObject()
m_oStyles.m_oStroke.m_oLineJoin.SetMapping({std::make_pair(L"arcs", Aggplus::LineJoinMiter), std::make_pair(L"bevel", Aggplus::LineJoinBevel), std::make_pair(L"miter", Aggplus::LineJoinMiter), std::make_pair(L"miter-clip", Aggplus::LineJoinMiterClipped), std::make_pair(L"round", Aggplus::LineJoinRound)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineJoinMiter;
m_oStyles.m_oStroke.m_oMiterlimit = 4.;
m_oTransformation.m_oOpacity = 1.;
m_oTransformation.m_bDraw = true;
}
CAppliedObject::CAppliedObject(CSvgReader& oReader)
: CObject(oReader)
{}
ObjectType CAppliedObject::GetType() const
{
return AppliedObject;
}
}

View File

@ -2,13 +2,14 @@
#define COBJECTBASE_H
#include "../../../../../Common/3dParty/html/css/src/CNode.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#include "../../../../xml/include/xmlutils.h"
#include "../../../../graphics/IRenderer.h"
#include "../../../../common/IGrObject.h"
#include "../SvgTypes.h"
class CSvgFile;
#include "../SvgTypes.h"
#include "../SvgReader.h"
#include "CStyle.h"
#include "../CSvgFile.h"
namespace SVG
{
@ -33,22 +34,34 @@ namespace SVG
enum ObjectType
{
RendererObject,
AppliedObject
AppliedObject,
DataObject
};
class CObject : public IGrObject
{
public:
protected:
CObject(const NSCSS::CNode& oData);
CObject(XmlUtils::CXmlNode& oNode);
virtual ~CObject();
CObject(CSvgReader& oReader);
CObject(const CObject& oObject);
public:
virtual ~CObject() = default;
virtual ObjectType GetType() const = 0;
void Mark();
bool Marked() const;
virtual void SetAttribute(const std::string& sName, CSvgReader& oReader);
void SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode = false);
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) = 0;
template <class T, typename... Args>
static T* Create(CSvgReader& oReader, CSvgFile* pSvgFile, Args&&... args);
virtual void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile);
void SetTransform(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
void SetClip(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
void SetMask(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
@ -57,37 +70,49 @@ namespace SVG
std::wstring GetId() const;
virtual std::vector<NSCSS::CNode> GetFullPath() const;
private:
protected:
bool ApplyTransform(IRenderer* pRenderer, const SvgTransform* pTransform, Aggplus::CMatrix& oOldMatrix) const;
bool ApplyClip(IRenderer* pRenderer, const TClip* pClip, const CSvgFile *pFile, const TBounds& oBounds) const;
bool ApplyMask(IRenderer* pRenderer, const SvgColor* pMask, const CSvgFile *pFile, const TBounds& oBounds) const;
bool ApplyDef(IRenderer* pRenderer, const CSvgFile *pFile, const std::wstring& wsUrl, const TBounds& oBounds) const;
void SetNodeData(XmlUtils::CXmlNode& oNode);
friend class CRenderedObject;
friend class CAppliedObject;
friend class CUse;
friend class CLine;
friend class CRect;
friend class CPath;
friend class CText;
friend class CTSpan;
friend class CImage;
friend class CCircle;
friend class CPolygon;
friend class CEllipse;
friend class CPolyline;
friend class CGraphicsContainer;
friend class CClipPath;
NSCSS::CNode m_oXmlNode;
TSvgTransformation m_oTransformation;
};
template<class T, typename... Args>
inline T* CObject::Create(CSvgReader& oReader, CSvgFile* pSvgFile, Args&&... args)
{
T* pObject = new T(oReader, std::forward<Args>(args)...);
if (NULL == pObject)
return NULL;
START_READ_ATTRIBUTES(oReader)
pObject->SetAttribute(sAttributeName, oReader);
END_READ_ATTRIBUTES(oReader)
if (NULL == pSvgFile)
return pObject;
if (DataObject != pObject->GetType() &&
(!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType()))
{
delete pObject;
return NULL;
}
const CSvgCalculator* pSvgCalculator{pSvgFile->GetSvgCalculator()};
if (NULL != pSvgCalculator)
pSvgCalculator->SetData(pObject);
pObject->ReadChildrens(oReader, pSvgFile);
return pObject;
}
enum CommandeMode
{
CommandeModeDraw,
@ -95,25 +120,28 @@ namespace SVG
CommandeModeMask
};
class CSvgCalculator;
class CRenderedObject : public CObject
{
public:
protected:
CRenderedObject(const NSCSS::CNode& oData, CRenderedObject* pParent = NULL);
CRenderedObject(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CRenderedObject();
CRenderedObject(CSvgReader& oReader, CRenderedObject* pParent = NULL);
CRenderedObject(const CRenderedObject& oRenderedObject);
public:
virtual ~CRenderedObject() = default;
ObjectType GetType() const override;
virtual void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0;
virtual TBounds GetBounds() const = 0;
virtual TBounds GetBounds(SvgMatrix* pTransform = nullptr) const = 0;
std::vector<NSCSS::CNode> GetFullPath() const override;
private:
void SetDefaultStyles();
void SetStroke(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
void SetFill(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
@ -126,6 +154,8 @@ namespace SVG
bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const;
bool ApplyOpacity(IRenderer* pRenderer, const SvgDigit* pOpacity) const;
void SetDefaultData();
friend class CUse;
friend class CLine;
friend class CRect;
@ -148,9 +178,10 @@ namespace SVG
class CAppliedObject : public CObject
{
protected:
CAppliedObject(CSvgReader& oReader);
public:
CAppliedObject(XmlUtils::CXmlNode& oNode);
virtual ~CAppliedObject();
virtual ~CAppliedObject() = default;
ObjectType GetType() const override;

View File

@ -8,49 +8,46 @@
namespace SVG
{
IPathElement::~IPathElement()
{
}
#define ISPATHCOMMAND(wchar) L'M' == wchar || L'm' == wchar || L'Z' == wchar || L'z' == wchar || L'L' == wchar || L'l' == wchar || L'H' == wchar || L'h' == wchar || L'V' == wchar || L'v' == wchar || L'C' == wchar || L'c' == wchar || L'S' == wchar || L's' == wchar || L'Q' == wchar || L'q' == wchar || L'T' == wchar || L't' == wchar || L'A' == wchar || L'a' == wchar
// IpathElement
TBounds IPathElement::GetBounds() const
{
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
for (const Point& oPoint : m_arPoints)
Point IPathElement::GetFirstPoint() const
{
switch (GetType())
{
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oPoint.dX);
oBounds.m_dTop = std::min(oBounds.m_dTop, oPoint.dY);
oBounds.m_dRight = std::max(oBounds.m_dRight, oPoint.dX);
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oPoint.dY);
case Move: return ((CMoveElement*)this)->m_oPoint;
case Line: return ((CLineElement*)this)->m_oPoint;
case CBezier:
case SBezier:
case QBezier:
case TBezier:
case Arc: return ((CCBezierElement*)this)->m_oPoint1;
case Close: return Point{0., 0.};
}
return oBounds;
return Point{0., 0.};
}
UINT IPathElement::GetPointCount() const
Point IPathElement::GetLastPoint() const
{
return m_arPoints.size();
}
switch (GetType())
{
case Move: return ((CMoveElement*)this)->m_oPoint;
case Line: return ((CLineElement*)this)->m_oPoint;
case CBezier:
case SBezier:
case QBezier:
case TBezier:
case Arc: return ((CCBezierElement*)this)->m_oPointE;
case Close: return Point{0., 0.};
}
Point IPathElement::operator[](int nIndex) const
{
if (m_arPoints.empty() || (nIndex > 0 && nIndex >= m_arPoints.size()) || (nIndex < 0 && -nIndex > m_arPoints.size()))
return Point{0., 0.};
return m_arPoints[(nIndex >= 0) ? nIndex : m_arPoints.size() + nIndex];
return Point{0., 0.};
}
//CMoveElement
CMoveElement::CMoveElement(const Point &oPoint)
{
m_arPoints.push_back(oPoint);
}
CMoveElement::~CMoveElement()
{
}
: m_oPoint(oPoint)
{}
EPathElement CMoveElement::GetType() const
{
@ -65,7 +62,7 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (bRelativeCoordinate && NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
CMoveElement *pMoveElement = new CMoveElement(Point{arValues[0], arValues[1]} + oTranslatePoint);
@ -76,19 +73,18 @@ namespace SVG
void CMoveElement::Draw(IRenderer *pRenderer) const
{
if (m_arPoints.empty())
return;
if (NULL != pRenderer)
pRenderer->PathCommandMoveTo(m_oPoint.dX, m_oPoint.dY);
}
pRenderer->PathCommandMoveTo(m_arPoints[0].dX, m_arPoints[0].dY);
TBounds CMoveElement::GetBounds() const
{
return TBounds{m_oPoint.dX, m_oPoint.dY, 1, 1};
}
//CLineElement
CLineElement::CLineElement(const Point &oPoint)
{
m_arPoints.push_back(oPoint);
}
CLineElement::~CLineElement()
: m_oPoint(oPoint)
{}
EPathElement CLineElement::GetType() const
@ -104,7 +100,7 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (bRelativeCoordinate && NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
CLineElement *pLineElement = new CLineElement(Point{arValues[0], arValues[1]} + oTranslatePoint);
@ -121,7 +117,7 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
CLineElement *pLineElement = new CLineElement(Point{oTranslatePoint.dX, arValues[0] + ((bRelativeCoordinate) ? oTranslatePoint.dY : 0)});
@ -138,7 +134,7 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
CLineElement *pLineElement = new CLineElement(Point{arValues[0] + ((bRelativeCoordinate) ? oTranslatePoint.dX : 0), oTranslatePoint.dY});
@ -149,23 +145,19 @@ namespace SVG
void CLineElement::Draw(IRenderer *pRenderer) const
{
if (m_arPoints.empty())
return;
if (NULL != pRenderer)
pRenderer->PathCommandLineTo(m_oPoint.dX, m_oPoint.dY);
}
pRenderer->PathCommandLineTo(m_arPoints[0].dX, m_arPoints[0].dY);
TBounds CLineElement::GetBounds() const
{
return TBounds{m_oPoint.dX, m_oPoint.dY, 1, 1};
}
//CCurveBezierElement
CCBezierElement::CCBezierElement(const Point &oPoint1, const Point &oPoint2, const Point &oPointE, EPathElement enType)
: m_enType(enType)
{
m_arPoints.push_back(oPoint1);
m_arPoints.push_back(oPoint2);
m_arPoints.push_back(oPointE);
}
CCBezierElement::~CCBezierElement()
{
}
: m_oPoint1(oPoint1), m_oPoint2(oPoint2), m_oPointE(oPointE), m_enType(enType)
{}
EPathElement CCBezierElement::GetType() const
{
@ -180,11 +172,11 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (bRelativeCoordinate && NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
CCBezierElement *pCBezierElement = new CCBezierElement(Point{arValues[0], arValues[1]} + oTranslatePoint,
Point{arValues[2], arValues[3]} + oTranslatePoint,
Point{arValues[4], arValues[5]} + oTranslatePoint);
Point{arValues[2], arValues[3]} + oTranslatePoint,
Point{arValues[4], arValues[5]} + oTranslatePoint);
arValues.erase(arValues.begin(), arValues.begin() + 6);
@ -200,14 +192,19 @@ namespace SVG
if (NULL != pPrevElement)
{
oFirstPoint = (*pPrevElement)[-1];
oFirstPoint = pPrevElement->GetLastPoint();
if (bRelativeCoordinate)
oTranslatePoint = oFirstPoint;
}
if (EPathElement::SBezier == pPrevElement->GetType() ||
EPathElement::CBezier == pPrevElement->GetType())
oFirstPoint += oFirstPoint - (*pPrevElement)[-2];
{
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
if (NULL != pBezierElement)
oFirstPoint += oFirstPoint - pBezierElement->m_oPoint2;
}
CCBezierElement *pCBezierElement = new CCBezierElement(oFirstPoint,
Point{arValues[0], arValues[1]} + oTranslatePoint,
@ -228,7 +225,7 @@ namespace SVG
if (NULL != pPrevElement)
{
oLastPoint = (*pPrevElement)[-1];
oLastPoint = pPrevElement->GetLastPoint();
if (bRelativeCoordinate)
oTranslatePoint = oLastPoint;
}
@ -240,6 +237,14 @@ namespace SVG
return pCBezierElement;
}
bool ItBezierType(EPathElement eType)
{
return EPathElement::CBezier == eType ||
EPathElement::SBezier == eType ||
EPathElement::QBezier == eType ||
EPathElement::TBezier == eType;
}
IPathElement *CCBezierElement::CreateFromTArray(std::vector<double> &arValues, bool bRelativeCoordinate, IPathElement *pPrevElement)
{
if (arValues.size() < 2)
@ -247,10 +252,29 @@ namespace SVG
Point oFirstPoint{0., 0.}, oSecondPoint{0., 0.}, oTranslatePoint{0., 0.};
if (EPathElement::SBezier == pPrevElement->GetType() ||
EPathElement::CBezier == pPrevElement->GetType())
{
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
if (NULL != pBezierElement)
oFirstPoint += oFirstPoint - pBezierElement->m_oPoint2;
}
if (NULL != pPrevElement)
{
oFirstPoint = (*pPrevElement)[-1];
oSecondPoint = (*pPrevElement)[-2];
oFirstPoint = pPrevElement->GetLastPoint();
if (ItBezierType(pPrevElement->GetType()))
{
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
if (NULL != pBezierElement)
oSecondPoint = pBezierElement->m_oPoint2;
}
else
oSecondPoint = oFirstPoint;
if (bRelativeCoordinate)
oTranslatePoint = oFirstPoint;
}
@ -282,9 +306,9 @@ namespace SVG
Point oTranslatePoint{0., 0.};
if (bRelativeCoordinate && NULL != pPrevElement)
oTranslatePoint = (*pPrevElement)[-1];
oTranslatePoint = pPrevElement->GetLastPoint();
Point oSrartPoint{(*pPrevElement)[-1]};
Point oSrartPoint{pPrevElement->GetLastPoint()};
Point oSecondPoint{arValues[5] + oTranslatePoint.dX, arValues[6] + oTranslatePoint.dY};
if (oSrartPoint == oSecondPoint)
@ -361,12 +385,26 @@ namespace SVG
void CCBezierElement::Draw(IRenderer *pRenderer) const
{
if (3 != m_arPoints.size())
return;
pRenderer->PathCommandCurveTo(m_oPoint1.dX, m_oPoint1.dY,
m_oPoint2.dX, m_oPoint2.dY,
m_oPointE.dX, m_oPointE.dY);
}
pRenderer->PathCommandCurveTo(m_arPoints[0].dX, m_arPoints[0].dY,
m_arPoints[1].dX, m_arPoints[1].dY,
m_arPoints[2].dX, m_arPoints[2].dY);
#define CHECK_BOUNDS(bounds, point)\
bounds.m_dLeft = std::min(oBounds.m_dLeft, point.dX);\
bounds.m_dTop = std::min(oBounds.m_dTop, point.dY);\
bounds.m_dRight = std::max(oBounds.m_dRight, point.dX);\
bounds.m_dBottom = std::max(oBounds.m_dBottom, point.dY)
TBounds CCBezierElement::GetBounds() const
{
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
CHECK_BOUNDS(oBounds, m_oPoint1);
CHECK_BOUNDS(oBounds, m_oPoint2);
CHECK_BOUNDS(oBounds, m_oPointE);
return oBounds;
}
inline double ClampSinCos(const double& d)
@ -422,13 +460,6 @@ namespace SVG
}
//CCloseElement
CCloseElement::CCloseElement()
{}
CCloseElement::~CCloseElement()
{
}
EPathElement CCloseElement::GetType() const
{
return EPathElement::Close;
@ -439,18 +470,20 @@ namespace SVG
pRenderer->PathCommandClose();
}
TBounds CCloseElement::GetBounds() const
{
return TBounds{0., 0., 0., 0.};
}
#define LASTELEMENT(array) (array.empty()) ? NULL : array.back()
#define RANGEALIGMENT(value, left, rigth) if (value < left) value = left; else if (value > rigth) value = rigth;
#define EPSILON 0.05
#define CURVESTEP 0.05
#define MINCURVESTEP 0.001
CPath::CPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, bool bChechCommands)
: CRenderedObject(oNode, pParent), m_bEvenOddRule(false)
{
if (bChechCommands)
ReadFromString(oNode.GetAttribute(L"d"));
}
CPath::CPath(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent), m_bEvenOddRule(false)
{}
CPath::~CPath()
{
@ -458,6 +491,14 @@ namespace SVG
delete pPathElement;
}
void CPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("d" == sName)
ReadFromString(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CPath::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);
@ -541,17 +582,22 @@ namespace SVG
{
const IPathElement* pFirstElement{m_arElements[unIndex]};
(*oExternalData.m_pPoints)[0].m_oPoint = (*pFirstElement)[0];
(*oExternalData.m_pPoints)[0].m_oPoint = pFirstElement->GetFirstPoint();
if (pStartMarker->NeedExternalAngle())
{
Point oCurent{(*pFirstElement)[0]};
Point oCurent{pFirstElement->GetFirstPoint()};
Point oNext;
if (pFirstElement->GetPointCount() > 1)
oNext = (*pFirstElement)[1];
if (ItBezierType(pFirstElement->GetType()))
{
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(pFirstElement)};
if (NULL != pBezierElement)
oNext = pBezierElement->m_oPoint2;
}
else if (unIndex < m_arElements.size() - 1 && EPathElement::Close != m_arElements[unIndex + 1]->GetType() && EPathElement::Move != m_arElements[unIndex + 1]->GetType())
oNext = (*m_arElements[unIndex + 1])[0];
oNext = m_arElements[unIndex + 1]->GetFirstPoint();
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oCurent, oNext);
@ -577,12 +623,12 @@ namespace SVG
for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex)
{
if (EPathElement::Close != m_arElements[unIndex]->GetType())
(*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = (*m_arElements[unIndex])[-1];
(*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = m_arElements[unIndex]->GetLastPoint();
if (pMidMarker->NeedExternalAngle())
{
const Point oCurrent{(*m_arElements[unIndex])[0]};
const Point oPrev{(*m_arElements[unIndex + 1])[-1]};
const Point oCurrent{m_arElements[unIndex]->GetFirstPoint()};
const Point oPrev{m_arElements[unIndex + 1]->GetLastPoint()};
(*oExternalData.m_pPoints)[unIndex - 1].m_dAngle = CALCULATE_ANGLE(oCurrent, oPrev);
}
@ -608,17 +654,22 @@ namespace SVG
{
const IPathElement* pLastElement{m_arElements[unIndex]};
(*oExternalData.m_pPoints)[0].m_oPoint = (*pLastElement)[-1];
(*oExternalData.m_pPoints)[0].m_oPoint = pLastElement->GetLastPoint();
if (pEndMarker->NeedExternalAngle())
{
Point oCurent{(*pLastElement)[-1]};
Point oCurent{pLastElement->GetLastPoint()};
Point oPrev;
if (pLastElement->GetPointCount() > 1)
oPrev = (*pLastElement)[-2];
else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType() && EPathElement::Move != m_arElements[unIndex - 1]->GetType())
oPrev = (*m_arElements[unIndex - 1])[0];
if (ItBezierType(pLastElement->GetType()))
{
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(pLastElement)};
if (NULL != pBezierElement)
oPrev = pBezierElement->m_oPoint2;
}
else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType())
oPrev = m_arElements[unIndex - 1]->GetFirstPoint();
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oPrev, oCurent);
}
@ -652,7 +703,7 @@ namespace SVG
}
}
TBounds CPath::GetBounds() const
TBounds CPath::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX}, oTempBounds;
@ -666,6 +717,16 @@ namespace SVG
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oTempBounds.m_dBottom);
}
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds;
}
@ -701,7 +762,7 @@ namespace SVG
if (NULL == pMoveElement)
return;
AddElement(new CCloseElement);
AddElement(new CCloseElement());
oSecondPos = ++oFirstPos;
continue;
}
@ -841,13 +902,13 @@ namespace SVG
case EPathElement::Move:
case EPathElement::Close:
{
m_oPosition = m_oLastPoint = (*m_pCurrentElement)[0];
m_oPosition = m_oLastPoint = m_pCurrentElement->GetFirstPoint();
m_pCurrentElement = (*m_pPath)[m_unIndexElement++];
return Move(dX);
}
case EPathElement::Line:
{
Point oPoint{(*m_pCurrentElement)[0]};
Point oPoint{m_pCurrentElement->GetFirstPoint()};
double dDx = oPoint.dX - m_oPosition.dX;
double dDy = oPoint.dY - m_oPosition.dY;
@ -874,6 +935,11 @@ namespace SVG
case EPathElement::QBezier:
case EPathElement::TBezier:
{
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(m_pCurrentElement)};
if (NULL == pBezierElement)
return false;
Point oCurvePoint{0., 0.};
double dPrevValue = dX;
@ -897,8 +963,8 @@ namespace SVG
RANGEALIGMENT(m_dCurveIndex, 0., 1.);
oCurvePoint.dX = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dX + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * (*m_pCurrentElement)[0].dX + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * (*m_pCurrentElement)[1].dX + std::pow(m_dCurveIndex, 3) * (*m_pCurrentElement)[2].dX;
oCurvePoint.dY = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dY + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * (*m_pCurrentElement)[0].dY + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * (*m_pCurrentElement)[1].dY + std::pow(m_dCurveIndex, 3) * (*m_pCurrentElement)[2].dY;
oCurvePoint.dX = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dX + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * pBezierElement->m_oPoint1.dX + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * pBezierElement->m_oPoint2.dX + std::pow(m_dCurveIndex, 3) * pBezierElement->m_oPointE.dX;
oCurvePoint.dY = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dY + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * pBezierElement->m_oPoint1.dY + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * pBezierElement->m_oPoint2.dY + std::pow(m_dCurveIndex, 3) * pBezierElement->m_oPointE.dY;
dPrevValue = dX;
@ -907,7 +973,7 @@ namespace SVG
m_dCurveStep = CURVESTEP;
return NextMove(dX, (*m_pCurrentElement)[-1]);
return NextMove(dX, m_pCurrentElement->GetLastPoint());
}
default: return false;
}
@ -922,7 +988,7 @@ namespace SVG
m_unIndexElement = 0;
m_pCurrentElement = (*m_pPath)[m_unIndexElement++];
m_oPosition = m_oLastPoint = (*m_pCurrentElement)[0];
m_oPosition = m_oLastPoint = m_pCurrentElement->GetFirstPoint();
m_dAngle = m_dCurveIndex = 0.;
m_dCurveStep = CURVESTEP;
}

View File

@ -30,57 +30,55 @@ namespace SVG
class IPathElement
{
public:
virtual ~IPathElement();
virtual ~IPathElement() = default;
virtual EPathElement GetType() const = 0;
virtual void Draw(IRenderer* pRenderer) const = 0;
virtual TBounds GetBounds() const = 0;
TBounds GetBounds() const;
UINT GetPointCount() const;
virtual Point operator[](int nIndex) const;
private:
friend class CMoveElement;
friend class CLineElement;
friend class CVLineElement;
friend class CHLineElement;
friend class CCBezierElement;
friend class CSBezierElement;
friend class CQBezierElement;
friend class CTBezierElement;
friend class CArcElement;
friend class CCloseElement;
friend class CMovingPath;
std::vector<Point> m_arPoints;
Point GetFirstPoint() const;
Point GetLastPoint() const;
};
class CMoveElement : public IPathElement
{
public:
CMoveElement(const Point& oPoint);
virtual ~CMoveElement();
virtual ~CMoveElement() = default;
EPathElement GetType() const override;
static CMoveElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
void Draw(IRenderer* pRenderer) const override;
TBounds GetBounds() const override;
private:
Point m_oPoint;
friend class IPathElement;
friend class CLine;
};
class CLineElement : public IPathElement
{
public:
CLineElement(const Point& oPoint);
virtual ~CLineElement();
virtual ~CLineElement() = default;
EPathElement GetType() const override;
static CLineElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
static CLineElement* CreateFromVArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
static CLineElement* CreateFromHArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
void Draw(IRenderer* pRenderer) const override;
TBounds GetBounds() const override;
Point GetPoint() const;
private:
Point m_oPoint;
friend class IPathElement;
friend class CLine;
};
class CCBezierElement : public IPathElement
{
public:
CCBezierElement(const Point& oPoint1, const Point& oPoint2, const Point& oPointE, EPathElement enType = CBezier);
virtual ~CCBezierElement();
virtual ~CCBezierElement() = default;
EPathElement GetType() const override;
static IPathElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
static IPathElement* CreateFromSArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
@ -88,27 +86,40 @@ namespace SVG
static IPathElement* CreateFromTArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
static std::vector<IPathElement*> CreateFromArc(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
void Draw(IRenderer* pRenderer) const override;
TBounds GetBounds() const override;
private:
static void CalculateArcData(const Point& oFirst, const Point& oSecond, Point& oRadius, Point& oCenter, double dAngle, bool bLargeArc, bool bSweep, double& dStartAngle, double& dSweep);
Point m_oPoint1;
Point m_oPoint2;
Point m_oPointE;
EPathElement m_enType;
friend class IPathElement;
friend class CMovingPath;
friend class CPath;
};
class CCloseElement : public IPathElement
{
public:
CCloseElement();
virtual ~CCloseElement();
CCloseElement() = default;
virtual ~CCloseElement() = default;
EPathElement GetType() const override;
void Draw(IRenderer* pRenderer) const override;
TBounds GetBounds() const override;
};
class CPath : public CRenderedObject
{
friend class CObject;
protected:
CPath(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, bool bChechCommands = true);
virtual ~CPath();
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
@ -118,24 +129,22 @@ namespace SVG
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
void SetMarker(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode);
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const;
void ReadFromString(const std::wstring& wsValue);
bool AddElement(IPathElement* pElement);
friend class CLine;
friend class CFont;
friend class CPolygon;
friend class CPolyline;
std::vector<IPathElement*> m_arElements;
TMarkers m_oMarkers;
bool m_bEvenOddRule;
friend class CFont;
protected:
bool AddElement(IPathElement* pElement);
void SetMarker(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode);
};
class CMovingPath

View File

@ -5,8 +5,9 @@
namespace SVG
{
CPattern::CPattern(XmlUtils::CXmlNode& oNode, NSFonts::IFontManager *pFontManager)
: CAppliedObject(oNode), m_oContainer(oNode), m_pFontManager(pFontManager), m_pImage(NULL), m_enPatternUnits(objectBoundingBox)
CPattern::CPattern(CSvgReader& oReader, NSFonts::IFontManager *pFontManager)
: CAppliedObject(oReader), m_oContainer(oReader), m_pFontManager(pFontManager),
m_pImage(NULL), m_enPatternUnits(objectBoundingBox)
{}
CPattern::~CPattern()

View File

@ -14,8 +14,9 @@ namespace SVG
class CPattern : public CAppliedObject
{
friend class CObject;
CPattern(CSvgReader& oReader, NSFonts::IFontManager *pFontManager = NULL);
public:
CPattern(XmlUtils::CXmlNode& oNode, NSFonts::IFontManager *pFontManager = NULL);
virtual ~CPattern();
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;

View File

@ -1,24 +1,38 @@
#include "CPolyline.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
CPolyline::CPolyline(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPath(oNode, pParent, false)
CPolyline::CPolyline(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent)
{}
void CPolyline::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
std::vector<double> arValues = NSCSS::NS_STATIC_FUNCTIONS::ReadDoubleValues(oNode.GetAttribute(L"points"));
if ("points" == sName)
{
const std::vector<double> arValues = NSCSS::NS_STATIC_FUNCTIONS::ReadDoubleValues(oReader.GetText());
if (arValues.size() < 4)
return;
if (arValues.size() < 4)
return;
AddElement(new CMoveElement(Point{arValues[0], arValues[1]}));
AddElement(new CMoveElement(Point{arValues[0], arValues[1]}));
for (unsigned int unIndex = 2; unIndex < arValues.size(); unIndex += 2)
AddElement(new CLineElement(Point{arValues[unIndex + 0], arValues[unIndex + 1]}));
for (unsigned int unIndex = 2; unIndex < arValues.size(); unIndex += 2)
AddElement(new CLineElement(Point{arValues[unIndex + 0], arValues[unIndex + 1]}));
}
else
CRenderedObject::SetAttribute(sName, oReader);
}
CPolygon::CPolygon(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPolyline(oNode, pParent)
CPolygon::CPolygon(CSvgReader& oReader, CRenderedObject* pParent)
: CPolyline(oReader, pParent)
{}
void CPolygon::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CPolyline::SetAttribute(sName, oReader);
AddElement(new CCloseElement());
}
}

View File

@ -7,14 +7,19 @@ namespace SVG
{
class CPolyline : public CPath
{
friend class CObject;
protected:
CPolyline(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPolyline(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
};
class CPolygon : public CPolyline
{
friend class CObject;
CPolygon(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPolygon(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
};
}

View File

@ -1,20 +1,32 @@
#include "CRect.h"
#include "CStyle.h"
#include "CContainer.h"
#include "../SvgTypes.h"
namespace SVG
{
CRect::CRect(XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
m_oRect.m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oRect.m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oRect.m_oWidth .SetValue(oNode.GetAttribute(L"width"));
m_oRect.m_oHeight.SetValue(oNode.GetAttribute(L"height"));
CRect::CRect(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
m_oRx.SetValue(oNode.GetAttribute(L"rx"));
m_oRy.SetValue(oNode.GetAttribute(L"ry"));
CRect::~CRect()
{}
void CRect::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetText());
else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetText());
else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetText());
else if ("rx" == sName)
m_oRx.SetValue(oReader.GetText());
else if ("ry" == sName)
m_oRy.SetValue(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
if (m_oRx.Empty() && !m_oRy.Empty())
m_oRx = m_oRy;
@ -22,9 +34,6 @@ namespace SVG
m_oRy = m_oRx;
}
CRect::~CRect()
{}
void CRect::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);
@ -94,7 +103,7 @@ namespace SVG
nTypePath += c_nWindingFillMode;
}
TBounds CRect::GetBounds() const
TBounds CRect::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds;
@ -103,6 +112,16 @@ namespace SVG
oBounds.m_dRight = oBounds.m_dLeft + m_oRect.m_oWidth.ToDouble(NSCSS::Pixel);
oBounds.m_dBottom = oBounds.m_dTop + m_oRect.m_oHeight.ToDouble(NSCSS::Pixel);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
}
return oBounds;
}
}

View File

@ -7,11 +7,13 @@ namespace SVG
{
class CRect : public CRenderedObject
{
friend class CObject;
CRect(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CRect(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CRect();
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
@ -19,7 +21,7 @@ namespace SVG
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
TRect m_oRect;

View File

@ -1,4 +1,5 @@
#include "CStyle.h"
#include "CObjectBase.h"
namespace SVG
{
@ -31,7 +32,7 @@ namespace SVG
const std::vector<NSCSS::CNode> arSelectors = pSvgObject->GetFullPath();
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors);
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors, 0, arSelectors.size());
std::vector<std::wstring> arPrevNodes;
for (size_t i = 0; i < arSelectors.size(); ++i)

View File

@ -3,12 +3,10 @@
#include <string>
#include "../../../../../Common/3dParty/html/css/src/CCssCalculator_Private.h"
#include "CObjectBase.h"
#include <numeric>
namespace SVG
{
class CObject;
class CSvgCalculator
{
NSCSS::CCssCalculator_Private *m_pInternal;

View File

@ -2,10 +2,9 @@
namespace SVG
{
CSwitch::CSwitch(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
}
CSwitch::CSwitch(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
bool CSwitch::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles, const CRenderedObject* pContexObject) const
{
@ -18,7 +17,7 @@ namespace SVG
return false;
}
TBounds CSwitch::GetBounds() const
TBounds CSwitch::GetBounds(SvgMatrix* pTransform) const
{
for (const CRenderedObject* pObject : m_arObjects)
if (NULL != pObject)

View File

@ -7,12 +7,12 @@ namespace SVG
{
class CSwitch : public CRenderedObject, public CContainer<CRenderedObject>
{
friend class CObject;
CSwitch(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CSwitch(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
};
}
#endif // CSWITCH_H

View File

@ -2,8 +2,8 @@
namespace SVG
{
CSymbol::CSymbol(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
: CGraphicsContainer(oNode)
CSymbol::CSymbol(CSvgReader& oReader, CRenderedObject *pParent)
: CGraphicsContainer(oReader)
{}
bool CSymbol::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const

View File

@ -2,15 +2,14 @@
#define CSYMBOL_H
#include "CContainer.h"
#include "../../../graphics/pro/Fonts.h"
namespace SVG
{
class CSymbol : public CGraphicsContainer
{
friend class CObject;
CSymbol(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CSymbol(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager *pFontManager = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
};
}

View File

@ -3,9 +3,13 @@
#include "../CSvgParser.h"
#include "../SvgUtils.h"
#include "../CSvgFile.h"
#include "CObjectBase.h"
#include "CContainer.h"
#include "CFont.h"
#include "CStyle.h"
#include "../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#include <cctype>
#ifndef MININT8
#define MAXUINT8 ((unsigned char)~((unsigned char)0))
@ -17,83 +21,39 @@
namespace SVG
{
#define DEFAULT_TSPAN_FONT_SIZE 16
#define DefaultFontFamily L"Times New Roman"
#define MIN_FONT_SIZE 5
#define MAX_FONT_SIZE 100
#define MIN_SCALE 0.05
#define MAX_SCALE 100
CTSpan::CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, bool bCheckText)
: CRenderedObject(oNode, pParent), m_pFontManager(pFontManager)
{
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE,DEFAULT_TSPAN_FONT_SIZE);
CTSpan::CTSpan(CSvgReader& oReader, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, const Point &oPosition)
: CRenderedObject(oReader, pParent), m_pFontManager(pFontManager),
m_oX(oPosition.dX), m_oY(oPosition.dY)
{}
if (bCheckText)
m_wsText = StrUtils::TrimExtraEnding(oNode.GetText());
else
m_wsText = oNode.GetText();
CTSpan::CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText)
: CRenderedObject(oTSpan), m_pFontManager(oTSpan.m_pFontManager),
m_oX(dX), m_oY(oTSpan.m_oY), m_wsText(wsText),
m_oFont(oTSpan.m_oFont), m_oText(oTSpan.m_oText)
{}
m_oX.SetValue(oNode.GetAttribute(L"x"));
m_oY.SetValue(oNode.GetAttribute(L"y"));
if (NULL != pParent)
{
TBounds oBounds = pParent->GetBounds();
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpan)
return;
m_oStyles = pTSpan->m_oStyles;
if (m_oX.Empty())
{
if (!pTSpan->m_arObjects.empty())
pTSpan = pTSpan->m_arObjects.back();
m_oX = pTSpan->m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft) + pTSpan->GetWidth();
}
if (m_oY.Empty())
m_oY = pTSpan->m_oY;
}
}
CTSpan::CTSpan(const std::wstring &wsText, const Point &oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText)
: CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager), m_wsText(wsText)
{
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
if (bCheckText)
m_wsText = StrUtils::TrimExtraEnding(m_wsText);
m_oX = oPosition.dX;
m_oY = oPosition.dY;
}
CTSpan::CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager)
: CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager),
m_oX(oPosition.dX), m_oY(oPosition.dY)
{}
CTSpan::~CTSpan()
{}
CTSpan *CTSpan::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
void CTSpan::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CTSpan *pTSpanParent = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpanParent)
return NULL;
return new CTSpan(oNode, pTSpanParent, pFontManager);
}
CTSpan *CTSpan::Create(const std::wstring &wsValue, const Point& oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText)
{
CTSpan *pTSpanParent = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpanParent || wsValue.empty())
return NULL;
return new CTSpan(wsValue, oPosition, pParent, pFontManager, bCheckText);
if ("x" == sName)
m_oX.SetValue(oReader.GetText());
else if ("y" == sName)
m_oY.SetValue(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CTSpan::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
@ -105,13 +65,22 @@ namespace SVG
//FONT
if (mAttributes.end() != mAttributes.find(L"font"))
{
m_oFont.SetValue(mAttributes.at(L"font"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-size"))
{
m_oFont.SetSize(mAttributes.at(L"font-size"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-size-adjust"))
{
m_oFont.SetSize(mAttributes.at(L"font-size-adjust"), ushLevel, bHardMode);
UpdateFontSize();
}
if (mAttributes.end() != mAttributes.find(L"font-stretch"))
m_oFont.SetStretch(mAttributes.at(L"font-stretch"), ushLevel, bHardMode);
@ -129,7 +98,10 @@ namespace SVG
m_oFont.SetFamily(mAttributes.at(L"font-family"), ushLevel, bHardMode);
if (mAttributes.end() != mAttributes.find(L"line-height"))
{
m_oFont.SetLineHeight(mAttributes.at(L"line-height"), ushLevel, bHardMode);
UpdateFontSize();
}
//TEXT
if (mAttributes.end() != mAttributes.find(L"text-anchor"))
@ -147,6 +119,57 @@ namespace SVG
}
}
void CTSpan::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
{
const int nDepth = oReader.GetDepth();
XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement;
while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType)
{
if (eNodeType == XmlUtils::XmlNodeType_Text ||
eNodeType == XmlUtils::XmlNodeType_Whitespace ||
eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE ||
eNodeType == XmlUtils::XmlNodeType_CDATA)
{
const char* pValue = oReader.GetTextChar();
if('\0' != pValue[0])
{
bool bFoundedSymbol = false;
const char* pCheckValue = pValue;
while ('\0' != *pCheckValue)
{
if (std::isprint(static_cast<unsigned char>(*pCheckValue++)))
{
bFoundedSymbol = true;
break;
}
}
if (!bFoundedSymbol)
continue;
if (m_wsText.empty())
{
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), m_wsText);
continue;
}
std::wstring wsValue;
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), wsValue);
AddObject(new CTSpan(*this, GetBounds().m_dRight, wsValue));
}
}
else if (eNodeType == XmlUtils::XmlNodeType_Element && "tspan" == oReader.GetName())
{
const TBounds oBounds{GetBounds()};
const Point oPoint{oBounds.m_dRight, oBounds.m_dBottom};
AddObject(CObject::Create<CTSpan>(oReader, pSvgFile, this, m_pFontManager, oPoint));
}
}
}
bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
if (NULL == pRenderer || (m_wsText.empty() && m_arObjects.empty()))
@ -164,8 +187,14 @@ namespace SVG
{
if (!m_wsText.empty())
{
ApplyFont(pRenderer, dX, dY);
Aggplus::CMatrix oCurrentMatrix;
ApplyFont(pRenderer, dX, dY, oCurrentMatrix);
pRenderer->CommandDrawText(m_wsText, dX, dY, 0, 0);
pRenderer->SetTransform(oCurrentMatrix.sx(), oCurrentMatrix.shy(),
oCurrentMatrix.shx(), oCurrentMatrix.sy(),
oCurrentMatrix.tx(), oCurrentMatrix.ty());
}
}
@ -207,12 +236,12 @@ namespace SVG
nTypePath += c_nWindingFillMode;
}
void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const
void CTSpan::ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const
{
std::wstring wsFontFamily = DefaultFontFamily;
double dFontSize = m_oFont.GetSize().ToDouble(NSCSS::Pixel) * 72. / 25.4;
double dFontSize = ((!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE) * 72. / 25.4;
Normalize(pRenderer, dX, dY, dFontSize);
Normalize(pRenderer, dX, dY, dFontSize, oOldMatrix);
if (!m_oFont.GetFamily().Empty())
{
@ -233,34 +262,37 @@ namespace SVG
if (m_oText.Underline())
nStyle |= (1 << 2);
// Вычиления размеров текста
m_pFontManager->LoadFontByName(wsFontFamily, dFontSize, nStyle, 72., 72.);
m_pFontManager->SetCharSpacing(0);
double dKoef = 25.4 / 72.;
float fW, fUndX1, fUndY1, fUndX2, fUndY2, fUndSize;
double dFHeight = dFontSize;
NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile();
if (NULL != m_pFontManager)
{
// Вычиления размеров текста
m_pFontManager->LoadFontByName(wsFontFamily, dFontSize, nStyle, 72., 72.);
m_pFontManager->SetCharSpacing(0);
if (pFontFile)
dFHeight *= pFontFile->GetHeight() / pFontFile->Units_Per_Em() * dKoef;
double dKoef = 25.4 / 72.;
float fW, fUndX1, fUndY1, fUndX2, fUndY2, fUndSize;
NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile();
m_pFontManager->LoadString1(m_wsText, 0, 0);
TBBox oBox = m_pFontManager->MeasureString2();
fW = (float)dKoef * (oBox.fMaxX - oBox.fMinX);
if (pFontFile)
dFHeight *= pFontFile->GetHeight() / pFontFile->Units_Per_Em() * dKoef;
// Просчитаем положение подчеркивания
m_pFontManager->GetUnderline(&fUndX1, &fUndY1, &fUndX2, &fUndY2, &fUndSize);
fUndX1 *= (float)dKoef;
fUndY1 *= (float)dKoef;
fUndX2 *= (float)dKoef;
fUndY2 *= (float)dKoef;
fUndSize *= (float)dKoef / 2;
m_pFontManager->LoadString1(m_wsText, 0, 0);
TBBox oBox = m_pFontManager->MeasureString2();
fW = (float)dKoef * (oBox.fMaxX - oBox.fMinX);
fUndY1 -= dFHeight / 4;
fUndY2 -= dFHeight / 4;
// Просчитаем положение подчеркивания
m_pFontManager->GetUnderline(&fUndX1, &fUndY1, &fUndX2, &fUndY2, &fUndSize);
fUndX1 *= (float)dKoef;
fUndY1 *= (float)dKoef;
fUndX2 *= (float)dKoef;
fUndY2 *= (float)dKoef;
fUndSize *= (float)dKoef / 2;
fUndY1 -= dFHeight / 4;
fUndY2 -= dFHeight / 4;
}
if (L"left" == m_oText.GetAlign().ToWString())
dX += -fW;
@ -303,7 +335,23 @@ namespace SVG
pRenderer->put_FontStyle(nStyle);
pRenderer->put_BrushType(c_BrushTypeSolid);
pRenderer->put_BrushColor1(m_oStyles.m_oFill.ToInt());
pRenderer->put_BrushAlpha1(255);
pRenderer->put_BrushAlpha1(255 * m_oStyles.m_oFill.GetOpacity());
}
void CTSpan::UpdateFontSize()
{
if (NULL != m_pParent)
{
const CTSpan* pParentTSpan{dynamic_cast<const CTSpan*>(m_pParent)};
if (NULL != pParentTSpan)
{
m_oFont.UpdateSize((!pParentTSpan->m_oFont.GetSize().Empty()) ? pParentTSpan->m_oFont.GetSize().ToDouble(NSCSS::Point) : DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
return;
}
}
m_oFont.UpdateSize(DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
}
bool CTSpan::UseExternalFont(const CSvgFile *pFile, double dX, double dY, IRenderer *pRenderer, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
@ -333,21 +381,30 @@ namespace SVG
return true;
}
TBounds CTSpan::GetBounds() const
TBounds CTSpan::GetBounds(SvgMatrix* pTransform) const
{
TBounds oBounds;
oBounds.m_dLeft = m_oX.ToDouble(NSCSS::Pixel);
oBounds.m_dTop = m_oY.ToDouble(NSCSS::Pixel);
oBounds.m_dRight = oBounds.m_dLeft + GetWidth();
oBounds.m_dBottom = oBounds.m_dTop + m_oFont.GetSize().ToDouble(NSCSS::Pixel) * 72. / 25.4;
oBounds.m_dBottom = m_oY.ToDouble(NSCSS::Pixel);
oBounds.m_dTop = oBounds.m_dBottom + ((!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE);
if (nullptr != pTransform)
{
*pTransform += m_oTransformation.m_oTransform.GetMatrix();
pTransform->GetFinalValue().TransformPoint(oBounds.m_dLeft, oBounds.m_dTop );
pTransform->GetFinalValue().TransformPoint(oBounds.m_dRight, oBounds.m_dBottom);
}
if (!m_arObjects.empty())
{
TBounds oTempBounds;
for (const CRenderedObject* pObject : m_arObjects)
{
oTempBounds = pObject->GetBounds();
oTempBounds = pObject->GetBounds(pTransform);
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oTempBounds.m_dLeft);
oBounds.m_dTop = std::min(oBounds.m_dTop, oTempBounds.m_dTop);
oBounds.m_dRight = std::max(oBounds.m_dRight, oTempBounds.m_dRight);
@ -355,6 +412,9 @@ namespace SVG
}
}
if (nullptr != pTransform)
*pTransform -= m_oTransformation.m_oTransform.GetMatrix();
return oBounds;
}
@ -364,7 +424,7 @@ namespace SVG
return 0.;
std::wstring wsName = DefaultFontFamily;
double dSize = m_oFont.GetSize().ToDouble(NSCSS::Pixel);
const double dSize = (!m_oFont.GetSize().Empty()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_FONT_SIZE;
if (!m_oFont.GetFamily().Empty())
{
@ -382,11 +442,15 @@ namespace SVG
if (m_oText.Underline())
nStyle |= (1 << 2);
m_pFontManager->LoadFontByName(wsName, dSize, nStyle, 72., 72.);
double dWidth = 0;
if (NULL != m_pFontManager)
{
m_pFontManager->LoadFontByName(wsName, dSize, nStyle, 72., 72.);
m_pFontManager->LoadString1(m_wsText, 0., 0.);
TBBox oBox = m_pFontManager->MeasureString2();
double dWidth = oBox.fMaxX - oBox.fMinX;
m_pFontManager->LoadString1(m_wsText, 0., 0.);
TBBox oBox = m_pFontManager->MeasureString2();
dWidth = oBox.fMaxX - oBox.fMinX;
}
for (const CTSpan* oTSpan : m_arObjects)
dWidth += oTSpan->GetWidth();
@ -420,7 +484,7 @@ namespace SVG
dY = m_oY.ToDouble(NSCSS::Pixel, oBounds.m_dBottom - oBounds.m_dTop);
}
void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight) const
void CTSpan::Normalize(IRenderer *pRenderer, double &dX, double &dY, double &dFontHeight, Aggplus::CMatrix& oOldMatrix) const
{
if (NULL == pRenderer)
return;
@ -463,6 +527,8 @@ namespace SVG
pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);
oOldMatrix.SetElements(dM11, dM12, dM21, dM22, dDx, dDy);
Aggplus::CMatrix oMatrix(dM11, dM12, dM21, dM22, dDx, dDy);
oMatrix.Scale(dXScale, dYScale);
@ -476,6 +542,33 @@ namespace SVG
m_oY = oPosition.dY;
}
void CTSpan::SetPositionFromParent(CRenderedObject* pParent)
{
if (NULL == pParent)
return;
const TBounds oBounds{pParent->GetBounds()};
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpan)
return;
m_oStyles = pTSpan->m_oStyles;
if (m_oX.Empty())
{
if (!pTSpan->m_arObjects.empty())
pTSpan = pTSpan->m_arObjects.back();
m_oX = pTSpan->m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft) + pTSpan->GetWidth();
}
if (m_oY.Empty())
m_oY = pTSpan->m_oY;
}
std::vector<CTSpan> CTSpan::Split() const
{
std::vector<CTSpan> arGlyphs;
@ -485,25 +578,17 @@ namespace SVG
for (unsigned int unIndex = 0; unIndex < m_wsText.length(); ++unIndex)
{
arGlyphs.push_back(CTSpan(std::wstring(1, m_wsText[unIndex]), oPosition, m_pParent, m_pFontManager, false));
arGlyphs.push_back(CTSpan(m_wsText[unIndex], oPosition, m_pParent, m_pFontManager));
oPosition.dX += arGlyphs[unIndex].GetWidth();
}
return arGlyphs;
}
CText::CText(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
: CTSpan(oNode, pParent, pFontManager)
{}
CText *CText::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
CText::CText(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
: CTSpan(oReader, pParent, pFontManager)
{
CTSpan* pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL != pTSpan)
return NULL;
return new CText(oNode, pParent, pFontManager);
m_oFont.UpdateSize(DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE);
}
bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
@ -516,20 +601,9 @@ namespace SVG
return true;
}
CTextPath::CTextPath(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, const CSvgFile* pFile)
: CText(oNode, pParent, pFontManager), m_pPath(NULL)
CTextPath::CTextPath(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
: CText(oReader, pParent, pFontManager)
{
if (NULL != pFile)
{
std::wstring wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
size_t unPosition = wsHref.find(L'#');
if (std::wstring::npos != unPosition)
wsHref.erase(0, unPosition + 1);
m_pPath = dynamic_cast<const CPath*>(pFile->GetMarkedObject(wsHref));
}
if (NULL != pParent)
{
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
@ -539,12 +613,32 @@ namespace SVG
}
}
void CTextPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("href" == sName || "xlink:href" == sName)
{
m_wsHref = oReader.GetText();
size_t unPosition = m_wsHref.find(L'#');
if (std::wstring::npos != unPosition)
m_wsHref.erase(0, unPosition + 1);
}
else
CText::SetAttribute(sName, oReader);
}
bool CTextPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
if (NULL == pRenderer || CommandeModeClip == oMode || NULL == m_pPath)
if (NULL == pRenderer || CommandeModeClip == oMode || m_wsHref.empty() || NULL == pFile)
return false;
CMovingPath oMovingPath(m_pPath);
const CPath* pPath = dynamic_cast<const CPath*>(pFile->GetMarkedObject(m_wsHref));
if (NULL == pPath)
return false;
CMovingPath oMovingPath(pPath);
oMovingPath.Move(m_oX.ToDouble(NSCSS::Pixel));
@ -566,16 +660,6 @@ namespace SVG
}
CTextPath* CTextPath::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, const CSvgFile* pFile)
{
CTSpan *pTSpan = dynamic_cast<CText*>(pParent);
if (NULL == pTSpan)
return NULL;
return new CTextPath(oNode, pTSpan, pFontManager, pFile);
}
void CTextPath::DrawGlyph(CTSpan* pTSpan, CMovingPath &oMovingPath, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const CRenderedObject* pContexObject) const
{
if (NULL == pTSpan)

View File

@ -12,16 +12,19 @@ namespace SVG
{
class CTSpan : public CRenderedObject, public CContainer<CTSpan>
{
friend class CObject;
protected:
CTSpan(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const Point& oPosition = {});
CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText);
CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
public:
CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
CTSpan(const std::wstring& wsText, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
virtual ~CTSpan();
static CTSpan* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
static CTSpan* Create(const std::wstring& wsValue, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile) override;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
bool AddObject(CTSpan* pObject) override;
@ -29,20 +32,23 @@ namespace SVG
void InheritStyles(const CTSpan* pTSpan);
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile* pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
void ApplyFont(IRenderer* pRenderer, double& dX, double& dY) const;
void ApplyFont(IRenderer* pRenderer, double& dX, double& dY, Aggplus::CMatrix& oOldMatrix) const;
void UpdateFontSize();
bool UseExternalFont(const CSvgFile* pFile, double dX, double dY, IRenderer* pRenderer, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
double GetWidth() const;
void CorrectFontFamily(std::wstring& wsFontFamily) const;
void CalculatePosition(double& dX, double& dY) const;
void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const;
void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight, Aggplus::CMatrix& oOldMatrix) const;
void SetPosition(const Point& oPosition);
void SetPositionFromParent(CRenderedObject* pParent);
std::vector<CTSpan> Split() const;
NSFonts::IFontManager* m_pFontManager;
@ -61,26 +67,25 @@ namespace SVG
class CText : public CTSpan
{
friend class CObject;
protected:
CText(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
public:
CText(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
static CText* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
};
class CTextPath : public CText
{
friend class CObject;
CTextPath(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
public:
CTextPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
static CTextPath* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL);
private:
void DrawGlyph(CTSpan* pTSpan, CMovingPath& oMovingPath, IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode, const CRenderedObject* pContexObject = NULL) const;
const CPath *m_pPath;
std::wstring m_wsHref;
};
}

View File

@ -3,20 +3,29 @@
namespace SVG
{
CUse::CUse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oWidth .SetValue(oNode.GetAttribute(L"width"));
m_oHeight.SetValue(oNode.GetAttribute(L"height"));
}
CUse::CUse(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
CUse::~CUse()
{}
void CUse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("x" == sName)
m_oX.SetValue(oReader.GetText());
else if ("y" == sName)
m_oY.SetValue(oReader.GetText());
else if ("width" == sName)
m_oWidth.SetValue(oReader.GetText());
else if ("height" == sName)
m_oHeight.SetValue(oReader.GetText());
else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText();
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CUse::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);
@ -64,7 +73,7 @@ namespace SVG
return bResult;
}
TBounds CUse::GetBounds() const
TBounds CUse::GetBounds(SvgMatrix* pTransform) const
{
return TBounds{0., 0., 0., 0.};
}

View File

@ -8,15 +8,18 @@ namespace SVG
{
class CUse : public CRenderedObject
{
friend class CObject;
CUse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CUse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CUse();
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private:
TBounds GetBounds() const override;
TBounds GetBounds(SvgMatrix* pTransform = nullptr) const override;
CRenderedObject *m_pUsedObject;

View File

@ -0,0 +1,353 @@
#include "SvgReader.h"
#include <cmath>
#include <cctype>
namespace SVG
{
int ConvertHexToInt(const std::string& sValue, const int& _default)
{
if (sValue.empty() || "none" == sValue)
return _default;
std::string::const_iterator itStart = sValue.cbegin();
if ('#' == *itStart)
++itStart;
if (sValue.cend() - itStart != 6)
return _default;
itStart = sValue.cend() - 6;
int nResult = 0;
while (itStart != sValue.cend())
{
if ('0' <= *itStart && *itStart <= '9')
nResult = (nResult << 4) | (*itStart++ - '0');
else if ('A' <= *itStart && *itStart <= 'F')
nResult = (nResult << 4) | (*itStart++ - 'A' + 10);
else if ('a' <= *itStart && *itStart <= 'f')
nResult = (nResult << 4) | (*itStart++ - 'a' + 10);
else
return _default;
}
return nResult;
}
CSvgReader::CSvgReader()
: m_pReader(new XmlUtils::CXmlLiteReader), m_bParseAttribute(false)
{}
CSvgReader::~CSvgReader()
{
if (nullptr != m_pReader)
delete m_pReader;
}
bool SVG::CSvgReader::ReadFromFile(const std::wstring& wsFilePath)
{
return (nullptr != m_pReader) ? m_pReader->FromFile(wsFilePath) : false;
}
bool SVG::CSvgReader::ReadFromString(const std::wstring& wsSvg)
{
if (nullptr != m_pReader && m_pReader->FromString(wsSvg))
return m_pReader->ReadNextNode();
return false;
}
// XmlUtils::CXmlLiteReader* CSvgReader::GetReader()
// {
// return m_pReader;
// }
unsigned int CSvgReader::GetDepth()
{
return (nullptr != m_pReader) ? m_pReader->GetDepth() : 0;
}
bool CSvgReader::IsEmptyNode()
{
return (nullptr != m_pReader) ? m_pReader->IsEmptyNode() : true;
}
bool CSvgReader::GetBool()
{
return "1" == GetTextAValue(*this) || "true" == GetTextAValue(*this);
}
int StringToInt(const std::string& sValue, const int& _default)
{
std::string::const_iterator itPos{sValue.cbegin()};
while (std::isspace(*itPos))
++itPos;
if (sValue.cend() == itPos)
return _default;
while (sValue.cend() != itPos && !std::isdigit(*itPos))
++itPos;
if (sValue.cend() == itPos)
return _default;
int nResult = 0;
while (itPos != sValue.cend() && std::isdigit(*itPos))
{
nResult = nResult * 10 + (*itPos - '0');
++itPos;
}
return ((nResult & 0xFF) << 16) | (((nResult >> 8) & 0xFF) << 8) | ((nResult >> 16) & 0xFF);
}
int CSvgReader::GetColor(const int& nDefault)
{
const std::string sValue{GetTextAValue(*this)};
if (sValue.empty())
return nDefault;
if ('#' == sValue[0])
return ConvertHexToInt(sValue, nDefault);
return StringToInt(sValue, nDefault);
}
int CSvgReader::GetInt()
{
return GetIntValue(*this);
}
double CSvgReader::GetDouble()
{
return GetDoubleValue(*this);
}
std::string CSvgReader::GetTextA()
{
if (nullptr == m_pReader)
return std::string();
return (m_bParseAttribute) ? m_pReader->GetTextA() : m_pReader->GetText2A();
}
std::wstring CSvgReader::GetText()
{
if (nullptr == m_pReader)
return std::wstring();
return (m_bParseAttribute) ? m_pReader->GetText() : m_pReader->GetText2();
}
const char* CSvgReader::GetTextChar()
{
if (nullptr == m_pReader)
return "";
return m_pReader->GetTextChar();
}
template<typename T>
T CSvgReader::GetAttribute(const std::string& sName, T _default, T (*GetValue)(CSvgReader&))
{
if (!MoveToFirstAttribute())
return _default;
T oValue = _default;
do
{
if (sName == m_pReader->GetNameA())
{
oValue = GetValue(*this);
break;
}
}while(m_pReader->MoveToNextAttribute());
MoveToElement();
return oValue;
}
int CSvgReader::GetAttributeInt(const std::string& sName, int nDefault)
{
return GetAttribute<int>(sName, nDefault, &GetIntValue);
}
bool CSvgReader::GetAttributeBool(const std::string& sName)
{
return GetAttribute<bool>(sName, false, &GetBoolValue);
}
double CSvgReader::GetAttributeDouble(const std::string& sName)
{
return GetAttribute<double>(sName, 0., &GetDoubleValue);
}
std::string CSvgReader::GetAttributeA(const std::string& sName)
{
return GetAttribute<std::string>(sName, "", &GetTextAValue);
}
std::wstring CSvgReader::GetAttribute(const std::string& sName)
{
return GetAttribute<std::wstring>(sName, L"", &GetTextValue);
}
bool CSvgReader::MoveToStart()
{
if (nullptr != m_pReader && m_pReader->MoveToStart())
return m_pReader->ReadNextNode();
return false;
}
bool CSvgReader::MoveToFirstAttribute()
{
if (nullptr == m_pReader || !m_pReader->MoveToFirstAttribute())
return false;
m_bParseAttribute = true;
return true;
}
bool CSvgReader::MoveToNextAttribute()
{
return (nullptr != m_pReader) ? m_pReader->MoveToNextAttribute() : false;
}
bool CSvgReader::MoveToElement()
{
if (nullptr == m_pReader || !m_pReader->MoveToElement())
return false;
m_bParseAttribute = false;
return true;
}
std::string CSvgReader::GetName()
{
return (nullptr != m_pReader) ? m_pReader->GetNameA() : std::string();
}
std::wstring CSvgReader::GetNameW()
{
return (nullptr != m_pReader) ? m_pReader->GetName() : std::wstring();
}
bool CSvgReader::ReadNextSiblingNode(unsigned int unDepth)
{
return (nullptr != m_pReader) ? m_pReader->ReadNextSiblingNode(unDepth) : false;
}
bool CSvgReader::ReadNextNode()
{
return (nullptr != m_pReader) ? m_pReader->ReadNextNode() : false;
}
bool CSvgReader::Read(XmlUtils::XmlNodeType& eNodeType)
{
return (nullptr != m_pReader) ? m_pReader->Read(eNodeType) : false;
}
int CSvgReader::GetIntValue(CSvgReader& oXmlReader)
{
return std::atoi(oXmlReader.GetTextA().c_str());
}
bool CSvgReader::GetBoolValue(CSvgReader& oXmlReader)
{
return "1" == oXmlReader.GetTextA();
}
double CSvgReader::GetDoubleValue(CSvgReader& oXmlReader)
{
const std::string sValue{oXmlReader.GetTextA()};
const char* pCur = sValue.c_str();
while (std::isspace(*pCur))
++pCur;
if (!pCur)
return 0.;
bool bNegative = false;
while ('-' == *pCur || '+' == *pCur)
{
if ('-' == *pCur)
bNegative = !bNegative;
++pCur;
}
if (!pCur)
return 0.;
double dResult = 0.;
while (std::isdigit(*pCur))
dResult = dResult * 10. + (*pCur++ - '0');
if (',' == *pCur || '.' == *pCur)
{
++pCur;
double dFraction = 0.0;
double dDivisor = 1.0;
while (std::isdigit(*pCur))
{
dFraction = dFraction * 10. + (*pCur++ - '0');
dDivisor *= 10;
}
dResult += dFraction / dDivisor;
}
if ('e' == *pCur || 'E' == *pCur)
{
++pCur;
bool bExpNegative = false;
while ('-' == *pCur || '+' == *pCur)
{
if ('-' == *pCur)
bExpNegative = !bExpNegative;
++pCur;
}
int nExponent = 0;
while (std::isdigit(*pCur))
nExponent = nExponent * 10 + (*pCur++ - '0');
if (bExpNegative)
nExponent = -nExponent;
dResult *= std::pow(10., nExponent);
}
return bNegative ? -dResult : dResult;
}
std::string CSvgReader::GetTextAValue(CSvgReader& oXmlReader)
{
return oXmlReader.GetTextA();
}
std::wstring CSvgReader::GetTextValue(CSvgReader& oXmlReader)
{
return oXmlReader.GetText();
}
}

View File

@ -0,0 +1,114 @@
#ifndef SVGREADER_H
#define SVGREADER_H
#include "../../../xml/include/xmlutils.h"
namespace SVG
{
class CSvgReader
{
XmlUtils::CXmlLiteReader *m_pReader;
bool m_bParseAttribute;
public:
CSvgReader();
~CSvgReader();
// XmlUtils::CXmlLiteReader* GetReader();
bool ReadFromFile(const std::wstring& wsFilePath);
bool ReadFromString(const std::wstring& wsSvg);
unsigned int GetDepth();
bool IsEmptyNode();
bool GetBool();
int GetColor(const int& nDefault = 0x000000);
int GetInt();
double GetDouble();
std::string GetTextA();
std::wstring GetText();
const char* GetTextChar();
int GetAttributeInt(const std::string& sName, int nDefault = 0);
bool GetAttributeBool(const std::string& sName);
double GetAttributeDouble(const std::string& sName);
std::string GetAttributeA(const std::string& sName);
std::wstring GetAttribute(const std::string& sName);
bool MoveToStart();
bool MoveToFirstAttribute();
bool MoveToNextAttribute();
bool MoveToElement();
std::string GetName();
std::wstring GetNameW();
bool ReadNextSiblingNode(unsigned int unDepth);
bool ReadNextNode();
bool Read(XmlUtils::XmlNodeType& eNodeType);
private:
static int GetIntValue(CSvgReader& oXmlReader);
static bool GetBoolValue(CSvgReader& oXmlReader);
static double GetDoubleValue(CSvgReader& oXmlReader);
static std::string GetTextAValue(CSvgReader& oXmlReader);
static std::wstring GetTextValue(CSvgReader& oXmlReader);
template<typename T>
T GetAttribute(const std::string& sName, T _default, T (*GetValue)(CSvgReader& oXmlReader));
};
#define WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, name_depth)\
if (!xml_reader.IsEmptyNode())\
{\
const int n##name_depth = xml_reader.GetDepth();\
while (xml_reader.ReadNextSiblingNode(n##name_depth))\
{
#define WHILE_READ_NEXT_NODE_WITH_DEPTH_AND_NAME(xml_reader, name_depth)\
if (!xml_reader.IsEmptyNode())\
{\
const int n##name_depth##Depth = xml_reader.GetDepth();\
std::string sNode##name_depth##Name;\
while (xml_reader.ReadNextSiblingNode(n##name_depth##Depth))\
{\
sNode##name_depth##Name = xml_reader.GetName();
#define WHILE_READ_NEXT_NODE(xml_reader) WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, Depth)
#define WHILE_READ_NEXT_NODE_WITH_NAME(xml_reader)\
if (!xml_reader.IsEmptyNode())\
{\
const int nDepth = xml_reader.GetDepth();\
std::string sNodeName;\
while (xml_reader.ReadNextSiblingNode(nDepth))\
{\
sNodeName = xml_reader.GetName();
#define WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(xml_reader, name_depth, node_name)\
WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, name_depth)\
if (node_name != xml_reader.GetName())\
continue;
#define WHILE_READ_NEXT_NODE_WITH_ONE_NAME(xml_reader, node_name) WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(xml_reader, Depth, node_name)
#define END_WHILE } }
#define ATTRIBUTE_NAME sAttributeName
#define START_READ_ATTRIBUTES(xml_reader)\
if (xml_reader.MoveToFirstAttribute())\
{\
std::string ATTRIBUTE_NAME;\
do\
{\
ATTRIBUTE_NAME = xml_reader.GetName();
#define END_READ_ATTRIBUTES(xml_reader)\
}\
while(xml_reader.MoveToNextAttribute());\
xml_reader.MoveToElement();\
}
}
#endif // SVGREADER_H

View File

@ -9,17 +9,21 @@
namespace SVG
{
#define MapCI std::map<std::wstring, std::wstring>::const_iterator
using MapCI = std::map<std::wstring, std::wstring>::const_iterator;
#define SvgDigit NSCSS::NSProperties::CDigit
#define SvgString NSCSS::NSProperties::CString
#define SvgColor NSCSS::NSProperties::CColor
#define SvgURL NSCSS::NSProperties::CURL
#define SvgEnum NSCSS::NSProperties::CEnum
using SvgDigit = NSCSS::NSProperties::CDigit;
using SvgString = NSCSS::NSProperties::CString;
using SvgColor = NSCSS::NSProperties::CColor;
using SvgURL = NSCSS::NSProperties::CURL;
using SvgEnum = NSCSS::NSProperties::CEnum;
#define SvgTransform NSCSS::NSProperties::CTransform
#define SvgFont NSCSS::NSProperties::CFont
#define SvgText NSCSS::NSProperties::CText
using SvgTransform = NSCSS::NSProperties::CTransform;
using SvgFont = NSCSS::NSProperties::CFont;
using SvgText = NSCSS::NSProperties::CText;
using SvgMatrix = NSCSS::NSProperties::CMatrix;
#define DEFAULT_FONT_SIZE 16
struct TStroke
{

View File

@ -5,7 +5,6 @@
#include <string>
#include <vector>
#include <regex>
#include <map>
#include <cfloat>
namespace SVG

View File

@ -203,6 +203,11 @@ bool TagIsUnprocessed(const std::wstring& wsTagName)
return L"xml" == wsTagName;
}
bool IsSVG(const std::wstring& wsExtention)
{
return L"svg" == wsExtention || L"svg+xml" == wsExtention;
}
static inline HtmlTag GetHtmlTag(const std::wstring& wsStrTag)
{
std::map<std::wstring, HtmlTag>::const_iterator oFound = m_HTML_TAGS.find(wsStrTag);
@ -265,7 +270,6 @@ struct CTextSettings
bool bMergeText; // Объединять подяр идущий текст в 1?
int nLi; // Уровень списка
bool bNumberingLi; // Является ли список нумерованным
bool bWritedLi; // Записан ли уже w:numPr
std::wstring sPStyle;
@ -279,12 +283,12 @@ struct CTextSettings
NSCSS::CCompiledStyle oAdditionalStyle;
CTextSettings()
: bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), bNumberingLi(false), bWritedLi(false), eTextMode(Normal)
: bBdo(false), bPre(false), bQ(false), bAddSpaces(true), bMergeText(false), nLi(-1), bNumberingLi(false), eTextMode(Normal)
{}
CTextSettings(const CTextSettings& oTS) :
bBdo(oTS.bBdo), bPre(oTS.bPre), bQ(oTS.bQ), bAddSpaces(oTS.bAddSpaces), bMergeText(oTS.bMergeText),
nLi(oTS.nLi), bNumberingLi(oTS.bNumberingLi), bWritedLi(oTS.bWritedLi), sPStyle(oTS.sPStyle), eTextMode(oTS.eTextMode)
nLi(oTS.nLi), bNumberingLi(oTS.bNumberingLi), sPStyle(oTS.sPStyle), eTextMode(oTS.eTextMode)
{}
void AddPStyle(const std::wstring& wsStyle)
@ -338,22 +342,6 @@ void WriteEmptyParagraph(NSStringUtils::CStringBuilder* pXml, bool bVahish = fal
pXml->WriteString(L"</w:pPr></w:p>");
}
void WriteLine(NSStringUtils::CStringBuilder* pXml, const std::wstring& wsAlign, const std::wstring& wsColor, bool bShade, double dSize, double dWidth)
{
if (dWidth < 0)
dWidth = -dWidth;
if (dSize < 0)
dSize = -dSize;
if (dWidth > 100)
dWidth = 0;
pXml->WriteNodeBegin(L"w:pict");
pXml->WriteString(L"<v:rect style=\"height:" + std::to_wstring(dSize) + L"pt\"" + ((0. != dWidth) ? (L" o:hrpct=\"" + std::to_wstring((int)(10. * dWidth)) + L"\"") : L"") + L" o:hralign=\"" + wsAlign + L"\" o:hrstd=\"t\" " + ((bShade) ? L"o:hrnoshade=\"t\" " : L"") + L"o:hr=\"t\" fillcolor=\"#" + wsColor + L"\" stroked=\"f\"/>");
pXml->WriteNodeEnd(L"w:pict");
}
bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors)
{
return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; });
@ -1248,7 +1236,7 @@ public:
bool ConvertToOOXML(NSStringUtils::CStringBuilder& oStringBuilder)
{
if (m_arRows.empty())
if (m_arRows.empty() && m_arHeaders.empty() && m_arFoother.empty())
return false;
oStringBuilder.WriteNodeBegin(L"w:tbl");
@ -1477,6 +1465,7 @@ private:
int m_nHyperlinkId; // ID ссылки
int m_nNumberingId; // ID списка
int m_nId; // ID остальные элементы
int m_nShapeId; // Id shape's
NSStringUtils::CStringBuilder m_oStylesXml; // styles.xml
NSStringUtils::CStringBuilder m_oDocXmlRels; // document.xml.rels
@ -1511,12 +1500,13 @@ private:
public:
CHtmlFile2_Private()
: m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), m_pFonts(NULL)
: m_nFootnoteId(1), m_nHyperlinkId(1), m_nNumberingId(1), m_nId(1), m_nShapeId(1), m_pFonts(NULL)
{
m_oPageData.SetSize (std::to_wstring(DEFAULT_PAGE_WIDTH) + L"tw " + std::to_wstring(DEFAULT_PAGE_HEIGHT) + L"tw", 0, true);
m_oPageData.SetMargin(L"1440tw 1440tw 1440tw 1440tw", 0, true);
m_oPageData.SetFooter(L"720tw", 0, true);
m_oPageData.SetHeader(L"720tw", 0, true);
m_oPageData.SetWidth (DEFAULT_PAGE_WIDTH, NSCSS::UnitMeasure::Twips, 0, true);
m_oPageData.SetHeight(DEFAULT_PAGE_HEIGHT, NSCSS::UnitMeasure::Twips, 0, true);
m_oPageData.SetMargin(1440, NSCSS::UnitMeasure::Twips, 0, true);
m_oPageData.SetFooter(720, NSCSS::UnitMeasure::Twips, 0, true);
m_oPageData.SetHeader(720, NSCSS::UnitMeasure::Twips, 0, true);
}
~CHtmlFile2_Private()
@ -2230,7 +2220,6 @@ private:
if (m_mDivs.empty())
pXml->WriteString(L"<w:divs>");
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
NSCSS::CCompiledStyle *pStyle = sSelectors.back().m_pCompiledStyle;
const bool bInTable = ElementInTable(sSelectors);
@ -2307,6 +2296,8 @@ private:
}
m_oLightReader.MoveToElement();
sSelectors.push_back(oNode);
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
return sNote;
}
@ -2390,8 +2381,6 @@ private:
if (sText.empty())
return false;
m_oStylesCalculator.CalculateCompiledStyle(arSelectors);
bool bPre = oTS.bPre;
if (!bPre && nullptr != arSelectors.back().m_pCompiledStyle)
@ -2584,7 +2573,6 @@ private:
if (m_oState.m_bInP)
{
OpenR(pXml);
m_oStylesCalculator.CalculateCompiledStyle(arSelectors);
if(arSelectors.back().m_pCompiledStyle->m_oText.GetAlign() == L"both")
pXml->WriteString(L"<w:tab/>");
pXml->WriteString(L"<w:br/>");
@ -2638,7 +2626,7 @@ private:
CTextSettings oTSR(oTS);
oTSR.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", UINT_MAX, true);
oTSR.oAdditionalStyle.m_oFont.SetSize(20, UINT_MAX, true);
oTSR.oAdditionalStyle.m_oFont.SetSize(20, NSCSS::UnitMeasure::Point, UINT_MAX, true);
oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
return readStream(pXml, arSelectors, oTSR);
@ -2697,7 +2685,7 @@ private:
if (nSize < 1 || nSize > 7)
nSize = 3;
oTSR.oAdditionalStyle.m_oFont.SetSize(HTML_FONTS[nSize - 1], UINT_MAX, true);
oTSR.oAdditionalStyle.m_oFont.SetSize(HTML_FONTS[nSize - 1], NSCSS::UnitMeasure::Point, UINT_MAX, true);
}
}
m_oLightReader.MoveToElement();
@ -2797,14 +2785,14 @@ private:
{
switch(NSStringFinder::ToInt(m_oLightReader.GetText(), 3))
{
case 1: oTS.oAdditionalStyle.m_oFont.SetSize(7.5, UINT_MAX, true); break;
case 2: oTS.oAdditionalStyle.m_oFont.SetSize(10, UINT_MAX, true); break;
case 1: oTS.oAdditionalStyle.m_oFont.SetSize(7.5, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
case 2: oTS.oAdditionalStyle.m_oFont.SetSize(10, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
default:
case 3: oTS.oAdditionalStyle.m_oFont.SetSize(12, UINT_MAX, true); break;
case 4: oTS.oAdditionalStyle.m_oFont.SetSize(13.5, UINT_MAX, true); break;
case 5: oTS.oAdditionalStyle.m_oFont.SetSize(18, UINT_MAX, true); break;
case 6: oTS.oAdditionalStyle.m_oFont.SetSize(24, UINT_MAX, true); break;
case 7: oTS.oAdditionalStyle.m_oFont.SetSize(36, UINT_MAX, true); break;
case 3: oTS.oAdditionalStyle.m_oFont.SetSize(12, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
case 4: oTS.oAdditionalStyle.m_oFont.SetSize(13.5, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
case 5: oTS.oAdditionalStyle.m_oFont.SetSize(18, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
case 6: oTS.oAdditionalStyle.m_oFont.SetSize(24, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
case 7: oTS.oAdditionalStyle.m_oFont.SetSize(36, NSCSS::UnitMeasure::Point, UINT_MAX, true); break;
}
}
else if (L"color" == m_oLightReader.GetName())
@ -2824,7 +2812,7 @@ private:
return false;
CTextSettings oTSP(oTS);
oTSP.oAdditionalStyle.m_oMargin.SetLeft(720, UINT_MAX, true);
oTSP.oAdditionalStyle.m_oMargin.SetLeft(720, NSCSS::UnitMeasure::Twips, UINT_MAX, true);
return readStream(pXml, arSelectors, oTSP);
}
@ -2888,68 +2876,100 @@ private:
if (NULL == pXml)
return false;
bool bPrint = true;
for (const NSCSS::CNode& item : arSelectors)
{
if (item.m_wsName == L"div" && item.m_wsStyle == L"mso-element:footnote-list")
{
bPrint = false;
break;
}
return false;
}
if (bPrint)
NSCSS::NSProperties::CDigit oSize, oWidth;
NSCSS::NSProperties::CColor oColor;
bool bShade = true;
std::wstring wsAlign{L"center"};
if (m_oLightReader.MoveToFirstAttribute())
{
NSCSS::NSProperties::CDigit oSize, oWidth;
NSCSS::NSProperties::CColor oColor;
bool bShade = false;
std::wstring wsAlign{L"center"};
if (m_oLightReader.MoveToFirstAttribute())
std::wstring wsAttributeName;
do
{
std::wstring wsAttributeName;
do
wsAttributeName = m_oLightReader.GetName();
if (L"align" == wsAttributeName)
{
wsAttributeName = m_oLightReader.GetName();
const std::wstring wsValue{m_oLightReader.GetText()};
if (L"align" == wsAttributeName)
{
const std::wstring wsValue{m_oLightReader.GetText()};
if (NSStringFinder::Equals(L"left", wsValue))
wsAlign = L"left";
else if (NSStringFinder::Equals(L"right", wsValue))
wsAlign = L"right";
else if (NSStringFinder::Equals(L"center", wsValue))
wsAlign = L"center";
}
if (L"color" == wsAttributeName)
oColor.SetValue(m_oLightReader.GetText());
else if (L"noshade" == wsAttributeName)
bShade = false;
else if (L"size" == wsAttributeName)
oSize.SetValue(m_oLightReader.GetText());
else if (L"width" == wsAttributeName)
oWidth.SetValue(m_oLightReader.GetText());
} while (m_oLightReader.MoveToNextAttribute());
if (NSStringFinder::Equals(L"left", wsValue))
wsAlign = L"left";
else if (NSStringFinder::Equals(L"right", wsValue))
wsAlign = L"right";
else if (NSStringFinder::Equals(L"center", wsValue))
wsAlign = L"center";
}
if (L"color" == wsAttributeName)
oColor.SetValue(m_oLightReader.GetText());
else if (L"noshade" == wsAttributeName)
bShade = true;
else if (L"size" == wsAttributeName)
oSize.SetValue(m_oLightReader.GetText());
else if (L"width" == wsAttributeName)
oWidth.SetValue(m_oLightReader.GetText());
} while (m_oLightReader.MoveToNextAttribute());
m_oLightReader.MoveToElement();
}
const bool bOpenedP = OpenP(pXml);
OpenR(pXml);
WriteLine(pXml, wsAlign, (!oColor.Empty()) ? oColor.ToWString() : L"a0a0a0", bShade, (!oSize.Empty()) ? oSize.ToDouble(NSCSS::Point) : 1.5, (NSCSS::UnitMeasure::Percent == oWidth.GetUnitMeasure()) ? oWidth.ToDouble() : 0);
CloseR(pXml);
if (bOpenedP)
CloseP(pXml, arSelectors);
return true;
m_oLightReader.MoveToElement();
}
return false;
OpenP(pXml);
pXml->WriteString(L"<w:pPr><w:jc w:val=\"" + wsAlign + L"\"/></w:pPr>");
OpenR(pXml);
const unsigned int unPageWidth{static_cast<unsigned int>((m_oPageData.GetWidth().ToDouble(NSCSS::Inch) - m_oPageData.GetMargin().GetLeft().ToDouble(NSCSS::Inch) - m_oPageData.GetMargin().GetRight().ToDouble(NSCSS::Inch)) * 914400.)};
std::wstring wsWidth;
// width измеряется в px или %
if (!oWidth.Empty())
wsWidth = std::to_wstring(static_cast<int>((NSCSS::UnitMeasure::Percent != oWidth.GetUnitMeasure()) ? (NSCSS::CUnitMeasureConverter::ConvertPx(oWidth.ToDouble(), NSCSS::Inch, 96) * 914400.) : oWidth.ToDouble(NSCSS::Inch, unPageWidth)));
else
wsWidth = std::to_wstring(unPageWidth);
std::wstring wsHeight{L"14288"};
// size измеряется только в px
if (!oSize.Empty())
wsHeight = std::to_wstring(static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(oSize.ToDouble(), NSCSS::Inch, 96) * 914400.));
pXml->WriteString(L"<w:rPr><w:noProof/></w:rPr>");
pXml->WriteString(L"<mc:AlternateContent><mc:Choice Requires=\"wps\"><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">");
pXml->WriteString(L"<wp:extent cx=\"" + wsWidth + L"\" cy=\"0\"/>");
pXml->WriteString(L"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>");
pXml->WriteString(L"<wp:docPr id=\"" + std::to_wstring(m_nShapeId) + L"\" name=\"Line " + std::to_wstring(m_nShapeId) + L"\"/>"
"<wp:cNvGraphicFramePr/>"
"<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
"<a:graphicData uri=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\">"
"<wps:wsp>"
"<wps:cNvSpPr/>"
"<wps:spPr>");
pXml->WriteString(L"<a:xfrm>"
"<a:off x=\"0\" y=\"0\"/>"
"<a:ext cx=\"" + wsWidth + L"\" cy=\"0\"/>"
"</a:xfrm>"
"<a:custGeom><a:pathLst><a:path>"
"<a:moveTo><a:pt x=\"0\" y=\"0\"/></a:moveTo>"
"<a:lnTo><a:pt x=\"" + wsWidth + L"\" y=\"0\"/></a:lnTo>"
"</a:path></a:pathLst></a:custGeom>"
"<a:ln w=\"" + wsHeight + L"\"><a:solidFill><a:srgbClr val=\"" + ((!oColor.Empty()) ? oColor.ToHEX() : L"808080") + L"\"/></a:solidFill></a:ln>");
if (bShade)
pXml->WriteString(L"<a:scene3d><a:camera prst=\"orthographicFront\"/><a:lightRig rig=\"threePt\" dir=\"t\"/></a:scene3d><a:sp3d><a:bevelT prst=\"angle\"/></a:sp3d>");
pXml->WriteString(L"</wps:spPr><wps:bodyPr/></wps:wsp></a:graphicData></a:graphic></wp:inline></w:drawing></mc:Choice></mc:AlternateContent>");
CloseP(pXml, arSelectors);
++m_nShapeId;
return true;
}
bool ReadPre(NSStringUtils::CStringBuilder* pXml, std::vector<NSCSS::CNode>& arSelectors, CTextSettings& oTS)
@ -2959,9 +2979,9 @@ private:
CTextSettings oTSPre(oTS);
oTSPre.oAdditionalStyle.m_oFont.SetFamily(L"Courier New", NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oFont.SetSize(20, NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oMargin.SetTop(0, NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oMargin.SetBottom(0, NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oFont.SetSize(20, NSCSS::UnitMeasure::Point, NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oMargin.SetTop(0, NSCSS::UnitMeasure::Twips, NEXT_LEVEL);
oTSPre.oAdditionalStyle.m_oMargin.SetBottom(0, NSCSS::UnitMeasure::Twips, NEXT_LEVEL);
oTSPre.bPre = true;
return readStream(pXml, arSelectors, oTSPre);
@ -3054,9 +3074,8 @@ private:
return false;
std::wstring sNote = GetSubClass(oXml, sSelectors);
bool bResult = true;
// Ссылка
// Область ссылки
const HtmlTag eHtmlTag{GetHtmlTag(sName)};
@ -3197,9 +3216,9 @@ private:
case HTML_TAG(STYLE):
case HTML_TAG(SCRIPT):
{
WriteEmptyParagraph(oXml, false, m_oState.m_bInP);
//Если встретили не обрабатываемые теги, то просто пропускаем
sSelectors.pop_back();
return true;
return false;
}
case HTML_TAG(SPAN):
{
@ -3294,12 +3313,21 @@ private:
bResult = ReadHr(&oXmlData, sSelectors, oTS);
break;
}
case HTML_TAG(LI):
{
bResult = ReadListElement(&oXmlData, sSelectors, oTS);
break;
}
case HTML_TAG(OL):
case HTML_TAG(UL):
{
bResult = ReadList(&oXmlData, sSelectors, oTS);
break;
}
case HTML_TAG(MENU):
case HTML_TAG(SELECT):
case HTML_TAG(DATALIST):
case HTML_TAG(DIR):
case HTML_TAG(OL):
{
bResult = readLi(&oXmlData, sSelectors, oTS, HTML_TAG(OL) != eHtmlTag);
break;
@ -3396,8 +3424,6 @@ private:
if (NULL == pCellStyle)
return;
m_oStylesCalculator.CalculateCompiledStyle(arSelectors);
pCellStyle->m_wsVAlign = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetVAlign().ToWString();
pCellStyle->m_wsHAlign = arSelectors.back().m_pCompiledStyle->m_oDisplay.GetHAlign().ToWString();
pCellStyle->m_oBackground = arSelectors.back().m_pCompiledStyle->m_oBackground.GetColor();
@ -3648,8 +3674,6 @@ private:
CTextSettings oNewSettings{oTS};
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
const std::wstring wsHighlight{sSelectors.back().m_pCompiledStyle->m_oBackground.GetColor()
.EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
{{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
@ -3688,7 +3712,6 @@ private:
if (0 != oRT.GetSize())
{
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
NSCSS::CCompiledStyle *pStyle = sSelectors.back().m_pCompiledStyle;
int nFontSize = 24;
@ -3736,7 +3759,6 @@ private:
CTextSettings oTextSettings{oTS};
oTextSettings.sPStyle.clear();
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
NSCSS::CCompiledStyle *pStyle = sSelectors.back().m_pCompiledStyle;
//Table styles
@ -3756,7 +3778,7 @@ private:
continue;
pStyle->m_oBorder.SetStyle(L"outset", 0, true);
pStyle->m_oBorder.SetWidth(nWidth, 0, true);
pStyle->m_oBorder.SetWidth(nWidth, NSCSS::UnitMeasure::Point, 0, true);
pStyle->m_oBorder.SetColor(L"auto", 0, true);
}
else if (pStyle->m_oBorder.Empty())
@ -3777,38 +3799,38 @@ private:
{
#define SetDefaultBorderSide(side) \
pStyle->m_oBorder.SetStyle##side(L"solid", 0, true); \
pStyle->m_oBorder.SetWidth##side(1, 0, true); \
pStyle->m_oBorder.SetColor##side(L"black", 0, true);
pStyle->m_oBorder.SetWidth##side(1, NSCSS::UnitMeasure::Point, 0, true); \
pStyle->m_oBorder.SetColor##side(L"black", 0, true)
if (NSStringFinder::Equals(L"border", wsFrame))
{
SetDefaultBorderSide()
SetDefaultBorderSide();
}
else if (NSStringFinder::Equals(L"above", wsFrame))
{
SetDefaultBorderSide(TopSide)
SetDefaultBorderSide(TopSide);
}
else if (NSStringFinder::Equals(L"below", wsFrame))
{
SetDefaultBorderSide(BottomSide)
SetDefaultBorderSide(BottomSide);
}
else if (NSStringFinder::Equals(L"hsides", wsFrame))
{
SetDefaultBorderSide(TopSide)
SetDefaultBorderSide(BottomSide)
SetDefaultBorderSide(TopSide);
SetDefaultBorderSide(BottomSide);
}
else if (NSStringFinder::Equals(L"vsides", wsFrame))
{
SetDefaultBorderSide(LeftSide)
SetDefaultBorderSide(RightSide)
SetDefaultBorderSide(LeftSide);
SetDefaultBorderSide(RightSide);
}
else if (NSStringFinder::Equals(L"rhs", wsFrame))
{
SetDefaultBorderSide(RightSide)
SetDefaultBorderSide(RightSide);
}
else if (NSStringFinder::Equals(L"lhs", wsFrame))
{
SetDefaultBorderSide(LeftSide)
SetDefaultBorderSide(LeftSide);
}
}
@ -3888,6 +3910,91 @@ private:
return readStream(oXml, sSelectors, oTS, ElementInTable(sSelectors));
}
bool ReadListElement(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& arSelectors, CTextSettings& oTS)
{
if (OpenP(oXml))
wrP(oXml, arSelectors, oTS);
const bool bResult{readStream(oXml, arSelectors, oTS)};
CloseP(oXml, arSelectors);
return bResult;
}
bool ReadList(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& arSelectors, CTextSettings& oTS)
{
if(m_oLightReader.IsEmptyNode())
return false;
GetSubClass(oXml, arSelectors);
CloseP(oXml, arSelectors);
CTextSettings oTSLi(oTS);
++oTSLi.nLi;
//Нумерованный список
if (L"ol" == arSelectors.back().m_wsName)
{
int nStart = 1;
while(m_oLightReader.MoveToNextAttribute())
if(m_oLightReader.GetName() == L"start")
nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
m_oLightReader.MoveToElement();
oTSLi.bNumberingLi = true;
const std::wstring wsStart(std::to_wstring(nStart));
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"");
m_oNumberXml.WriteString(std::to_wstring(m_nNumberingId++));
m_oNumberXml.WriteString(L"\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"709\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%2.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1429\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%3.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"2149\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%4.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2869\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3589\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%6.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"4309\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%7.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5029\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%8.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5749\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%9.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"6469\" w:hanging=\"180\"/></w:pPr></w:lvl></w:abstractNum>");
}
CTextSettings oTSList{oTSLi};
oTSList.oAdditionalStyle.m_oMargin.SetTop (100, NSCSS::UnitMeasure::Twips, 0, true);
oTSList.oAdditionalStyle.m_oMargin.SetBottom(100, NSCSS::UnitMeasure::Twips, 0, true);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode2(nDeath))
{
const std::wstring wsName = m_oLightReader.GetName();
if (L"li" == wsName)
ReadListElement(oXml, arSelectors, oTSList);
else
{
CloseP(oXml, arSelectors);
readInside(oXml, arSelectors, oTSLi, wsName);
}
}
CloseP(oXml, arSelectors);
arSelectors.pop_back();
return true;
}
bool readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, CTextSettings& oTS, bool bType)
{
if(m_oLightReader.IsEmptyNode())
@ -3963,7 +4070,6 @@ private:
m_oLightReader.MoveToElement();
oTSLiP.nLi++;
oTSLiP.bWritedLi = false;
if (!wsValue.empty())
{
@ -4167,7 +4273,7 @@ private:
if (!pImageData || FALSE == NSBase64::Base64Decode(sSrcM.c_str() + nOffset, nSrcLen, pImageData, &nDecodeLen))
return bRes;
if (L"svg" == sExtention || L"svg+xml" == sExtention)
if (IsSVG(sExtention))
{
std::wstring wsSvg(pImageData, pImageData + nDecodeLen);
bRes = readSVG(wsSvg);
@ -4212,8 +4318,8 @@ private:
{
return sExtention != L"bmp" && sExtention != L"emf" && sExtention != L"emz" && sExtention != L"eps" && sExtention != L"fpx" && sExtention != L"gif" &&
sExtention != L"jpe" && sExtention != L"jpeg" && sExtention != L"jpg" && sExtention != L"jfif" && sExtention != L"pct" && sExtention != L"pict" &&
sExtention != L"png" && sExtention != L"pntg" && sExtention != L"psd" && sExtention != L"qtif" && sExtention != L"sgi" && sExtention != L"svg" &&
sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && sExtention != L"wmz";
sExtention != L"png" && sExtention != L"pntg" && sExtention != L"psd" && sExtention != L"qtif" && sExtention != L"sgi" && sExtention != L"wmz" &&
sExtention != L"tga" && sExtention != L"tpic" && sExtention != L"tiff" && sExtention != L"tif" && sExtention != L"wmf" && !IsSVG(sExtention);
}
void ImageAlternative(NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, const CTextSettings& oTS, const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData)
@ -4268,6 +4374,29 @@ private:
}
m_oLightReader.MoveToElement();
if (NULL != sSelectors.back().m_pCompiledStyle)
{
const NSCSS::NSProperties::CDigit& oWidth {sSelectors.back().m_pCompiledStyle->m_oDisplay.GetWidth() };
const NSCSS::NSProperties::CDigit& oHeight{sSelectors.back().m_pCompiledStyle->m_oDisplay.GetHeight()};
if (0 == oImageData.m_unWidth && !oWidth.Empty())
{
if (NSCSS::UnitMeasure::None == oWidth.GetUnitMeasure())
oImageData.m_unWidth = static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(oWidth.ToDouble(), NSCSS::Inch, 96) * 914400);
else
oImageData.m_unWidth = static_cast<int>(oWidth.ToDouble(NSCSS::Inch) * 914400);
}
if (0 == oImageData.m_unHeight && !oHeight.Empty())
{
if (NSCSS::UnitMeasure::None == oHeight.GetUnitMeasure())
oImageData.m_unHeight = static_cast<int>(NSCSS::CUnitMeasureConverter::ConvertPx(oHeight.ToDouble(), NSCSS::Inch, 96) * 914400);
else
oImageData.m_unHeight = static_cast<int>(oHeight.ToDouble(NSCSS::Inch) * 914400);
}
}
if (sSrcM.empty())
{
ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
@ -4289,16 +4418,57 @@ private:
}
int nImageId = -1;
std::wstring sImageSrc, sExtention;
std::wstring sExtention;
// Предполагаем картинку в Base64
if (bIsBase64)
bRes = readBase64(sSrcM, sExtention);
// Проверка расширения
sExtention = NSFile::GetFileExtention(sSrcM);
std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
std::wstring::const_iterator itFound = std::find_if(sExtention.cbegin(), sExtention.cend(), [](wchar_t wChar){ return !iswalpha(wChar) && L'+' != wChar; });
if (sExtention.cend() != itFound)
sExtention.erase(itFound, sExtention.cend());
// Предполагаем картинку в сети
if (!bRes &&
((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") ||
(sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http")))
{
const std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + ((!sExtention.empty()) ? sExtention : L"png");
// Проверка gc_allowNetworkRequest предполагается в kernel_network
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false);
oDownloadImg.SetFilePath(wsDst);
bRes = oDownloadImg.DownloadSync();
if (!bRes)
{
ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
return true;
}
if (IsSVG(sExtention))
{
std::wstring wsFileData;
if (!NSFile::CFileBinary::ReadAllTextUtf8(wsDst, wsFileData) || !readSVG(wsFileData))
bRes = false;
NSFile::CFileBinary::Remove(wsDst);
sExtention = L"png";
}
else if (sExtention.empty())
{
//TODO:: лучше узнавать формат изображения из содержимого
sExtention = L"png";
}
}
if (!bRes)
{
// Проверка расширения
sExtention = NSFile::GetFileExtention(sSrcM);
std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
if (NotValidExtension(sExtention))
{
ImageAlternative(oXml, sSelectors, oTS, wsAlt, sSrcM, oImageData);
@ -4314,36 +4484,24 @@ private:
}
}
// Предполагаем картинку по локальному пути
if (!bRes)
{
sImageSrc = sSrcM;
std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + sExtention;
const std::wstring wsDst = m_sDst + L"/word/media/i" + std::to_wstring(m_arrImages.size()) + L'.' + sExtention;
// Предполагаем картинку по локальному пути
if (!((!m_sBase.empty() && m_sBase.length() > 4 && m_sBase.substr(0, 4) == L"http") || (sSrcM.length() > 4 && sSrcM.substr(0, 4) == L"http")))
if (!m_sBase.empty())
{
if (!m_sBase.empty())
{
if (!bRes)
bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles);
if (!bRes)
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles);
}
if (!bRes)
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles);
bRes = CopyImage(NSSystemPath::Combine(m_sBase, sSrcM), wsDst, bIsAllowExternalLocalFiles);
if (!bRes)
bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles);
if (!bRes)
bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles);
}
// Предполагаем картинку в сети
else
{
// Проверка gc_allowNetworkRequest предполагается в kernel_network
NSNetwork::NSFileTransport::CFileDownloader oDownloadImg(m_sBase + sSrcM, false);
oDownloadImg.SetFilePath(wsDst);
bRes = oDownloadImg.DownloadSync();
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, m_sBase + sSrcM), wsDst, bIsAllowExternalLocalFiles);
}
if (!bRes)
bRes = CopyImage(NSSystemPath::Combine(m_sSrc, sSrcM), wsDst, bIsAllowExternalLocalFiles);
if (!bRes)
bRes = CopyImage(m_sSrc + L"/" + NSFile::GetFileName(sSrcM), wsDst, bIsAllowExternalLocalFiles);
if (!bRes)
bRes = CopyImage(sSrcM, wsDst, bIsAllowExternalLocalFiles);
}
if (!bRes)
@ -4351,7 +4509,7 @@ private:
else
{
wrP(oXml, sSelectors, oTS);
ImageRels(oXml, nImageId, sImageSrc, sExtention, oImageData);
ImageRels(oXml, nImageId, sSrcM, sExtention, oImageData);
}
return true;
@ -4364,8 +4522,6 @@ private:
if (m_oState.m_bWasPStyle)
return L"";
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
std::wstring sPStyle = GetStyle(*sSelectors.back().m_pCompiledStyle, true);
if (sPStyle.empty() && !ElementInTable(sSelectors))
@ -4388,18 +4544,8 @@ private:
}
if (oTS.nLi >= 0)
{
if (!oTS.bWritedLi)
{
oXml->WriteString(L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(oTS.nLi) + L"\"/><w:numId w:val=\"" +
(!oTS.bNumberingLi ? L"1" : std::to_wstring(m_nNumberingId + 1)) + L"\"/></w:numPr>");
oTS.bWritedLi = true;
}
else if (sSelectors.back().m_pCompiledStyle->m_oText.GetIndent().Empty() &&
oTS.oAdditionalStyle.m_oText.GetIndent().Empty())
oXml->WriteString(L"<w:ind w:left=\"" + std::to_wstring(720 * (oTS.nLi + 1)) + L"\"/>");
}
oXml->WriteString(L"<w:numPr><w:ilvl w:val=\"" + std::to_wstring(oTS.nLi) + L"\"/><w:numId w:val=\"" +
(!oTS.bNumberingLi ? L"1" : std::to_wstring(m_nNumberingId)) + L"\"/></w:numPr>");
oXml->WriteString(oTS.sPStyle + sPSettings);
oXml->WriteNodeEnd(L"w:pPr");
@ -4413,8 +4559,6 @@ private:
if (!m_oState.m_bInP)
return L"";
m_oStylesCalculator.CalculateCompiledStyle(sSelectors);
std::wstring sRStyle = GetStyle(*sSelectors.back().m_pCompiledStyle, false);
m_oXmlStyle.WriteLiteRStyle(oTS.oAdditionalStyle);
@ -4558,8 +4702,9 @@ private:
if (bNew)
nImageId = m_arrImages.size();
std::wstring sImageId = std::to_wstring(nImageId);
std::wstring sImageName = sImageId + L'.' + sExtention;
const std::wstring sImageId = std::to_wstring(nImageId);
const std::wstring sImageName = sImageId + L'.' + sExtention;
CBgraFrame oBgraFrame;
if (!oBgraFrame.OpenFile(m_sDst + L"/word/media/i" + sImageName))
{
@ -4583,30 +4728,40 @@ private:
TImageData oNewImageData{oImageData};
// Получаем размеры картинки
oNewImageData.m_unWidth = oBgraFrame.get_Width();
oNewImageData.m_unHeight = oBgraFrame.get_Height();
if (oNewImageData.m_unWidth > oNewImageData.m_unHeight)
if (0 != oNewImageData.m_unWidth || 0 != oNewImageData.m_unHeight)
{
int nW = oNewImageData.m_unWidth * 9525;
nW = (nW > 7000000 ? 7000000 : nW);
oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth);
oNewImageData.m_unWidth = nW;
const double dMaxScale = std::max(oNewImageData.m_unWidth / oBgraFrame.get_Width(),
oNewImageData.m_unHeight / oBgraFrame.get_Height());
oNewImageData.m_unWidth = oBgraFrame.get_Width() * dMaxScale;
oNewImageData.m_unHeight = oBgraFrame.get_Height() * dMaxScale;
}
else
{
int nH = oNewImageData.m_unHeight * 9525;
nH = (nH > 8000000 ? 8000000 : nH);
int nW = (int)((double)oNewImageData.m_unWidth * (double)nH / (double)oNewImageData.m_unHeight);
if (nW > 7000000)
oNewImageData.m_unWidth = oBgraFrame.get_Width();
oNewImageData.m_unHeight = oBgraFrame.get_Height();
if (oNewImageData.m_unWidth > oNewImageData.m_unHeight)
{
nW = 7000000;
int nW = oNewImageData.m_unWidth * 9525;
nW = (nW > 7000000 ? 7000000 : nW);
oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth);
oNewImageData.m_unWidth = nW;
}
else
oNewImageData.m_unHeight = nH;
oNewImageData.m_unWidth = nW;
{
int nH = oNewImageData.m_unHeight * 9525;
nH = (nH > 8000000 ? 8000000 : nH);
int nW = (int)((double)oNewImageData.m_unWidth * (double)nH / (double)oNewImageData.m_unHeight);
if (nW > 7000000)
{
nW = 7000000;
oNewImageData.m_unHeight = (int)((double)oNewImageData.m_unHeight * (double)nW / (double)oNewImageData.m_unWidth);
}
else
oNewImageData.m_unHeight = nH;
oNewImageData.m_unWidth = nW;
}
}
WriteImage(oXml, oNewImageData, sImageId);
@ -4624,7 +4779,7 @@ private:
oXml->WriteString(L"\"/></w:r>");
m_oNoteXml.WriteString(L"<w:footnote w:id=\"");
m_oNoteXml.WriteString(std::to_wstring(m_nFootnoteId++));
m_oNoteXml.WriteString(L"\"><w:p><w:pPr><w:pStyle w:val=\"footnote-p\"/></w:pPr><w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr></w:r><w:r><w:t xml:space=\"preserve\">");
m_oNoteXml.WriteString(L"\"><w:p><w:pPr><w:pStyle w:val=\"footnote-p\"/></w:pPr><w:r><w:rPr><w:rStyle w:val=\"footnote\"/></w:rPr><w:footnoteRef/></w:r><w:r><w:t xml:space=\"preserve\"> </w:t></w:r><w:r><w:t xml:space=\"preserve\">");
m_oNoteXml.WriteEncodeXmlString(sNote);
m_oNoteXml.WriteString(L"</w:t></w:r></w:p></w:footnote>");
@ -4637,8 +4792,13 @@ private:
return false;
if (NULL == m_pFonts)
{
m_pFonts = NSFonts::NSApplication::Create();
if (NULL != m_pFonts)
m_pFonts->Initialize();
}
MetaFile::IMetaFile* pSvgReader = MetaFile::Create(m_pFonts);
if (!pSvgReader->LoadFromString(wsSvg))
{

View File

@ -2608,12 +2608,16 @@ void XlsConverter::convert(XLS::Obj * obj)
xlsx_context->get_drawing_context().set_object_x_max(obj->sbs.iMax);
xlsx_context->get_drawing_context().set_object_x_inc(obj->sbs.dInc);
xlsx_context->get_drawing_context().set_object_x_page(obj->sbs.dPage);
xlsx_context->get_drawing_context().set_object_3D(!obj->sbs.fNo3d);
xlsx_context->get_drawing_context().set_object_hscroll(obj->sbs.fHoriz);
xlsx_context->get_drawing_context().set_object_dx(obj->sbs.dxScroll);
}
if (obj->list.fExist)
{
xlsx_context->get_drawing_context().set_object_x_sel(obj->list.iSel);
xlsx_context->get_drawing_context().set_object_x_sel_type(obj->list.wListSelType);
xlsx_context->get_drawing_context().set_object_lct(obj->list.lct);
xlsx_context->get_drawing_context().set_object_3D(!obj->list.fNo3d);
if (obj->list.fmla.bFmlaExist)
{
@ -2628,9 +2632,9 @@ void XlsConverter::convert(XLS::Obj * obj)
}
if (obj->checkBox.fExist)
{
//unsigned short fChecked;
//unsigned short accel;
//bool fNo3d;
xlsx_context->get_drawing_context().set_object_checked(obj->checkBox.fChecked);
xlsx_context->get_drawing_context().set_object_3D(!obj->checkBox.fNo3d);
//unsigned short accel;
}
if (obj->radioButton.fExist)
{
@ -2639,10 +2643,10 @@ void XlsConverter::convert(XLS::Obj * obj)
}
if (obj->edit.fExist)
{
//unsigned short ivtEdit;
//Boolean<unsigned short> fMultiLine;
//unsigned short fVScroll;
//unsigned short id;
xlsx_context->get_drawing_context().set_object_multiLine(obj->edit.fMultiLine);
xlsx_context->get_drawing_context().set_object_vscroll(obj->edit.fVScroll);
//unsigned short ivtEdit;
//unsigned short id;
}
bool full_ref = false;
if (obj->cmo.ot > 0x06) full_ref = true;

View File

@ -793,6 +793,48 @@ void xlsx_drawing_context::set_object_drop_lines(int val)
current_drawing_states->back()->object.drop_lines = val;
}
void xlsx_drawing_context::set_object_dx(int val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.dx = val;
}
void xlsx_drawing_context::set_object_checked(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.checked = val;
}
void xlsx_drawing_context::set_object_multiLine(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.multiLine = val;
}
void xlsx_drawing_context::set_object_vscroll(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.vscroll = val;
}
void xlsx_drawing_context::set_object_hscroll(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object.hscroll = val;
}
void xlsx_drawing_context::set_object_3D(bool val)
{
if (current_drawing_states == NULL) return;
if (current_drawing_states->empty()) return;
current_drawing_states->back()->object._3D = val;
}
void xlsx_drawing_context::end_drawing()
{
if (current_drawing_states == NULL) return;
@ -1303,6 +1345,30 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat
{
CP_XML_NODE(L"x:DropLines"){CP_XML_CONTENT(*drawing_state->object.drop_lines);}
}
if (drawing_state->object.dx)
{
CP_XML_NODE(L"x:Dx") { CP_XML_CONTENT(*drawing_state->object.dx); }
}
if (drawing_state->object.checked)
{
CP_XML_NODE(L"x:Checked") { CP_XML_CONTENT(*drawing_state->object.checked); }
}
if (drawing_state->object._3D)
{
CP_XML_NODE(L"x:NoThreeD") { CP_XML_CONTENT(*drawing_state->object._3D ? L"False" : L"True"); }
}
if (drawing_state->object.multiLine)
{
CP_XML_NODE(L"x:Multiline") { CP_XML_CONTENT(*drawing_state->object.multiLine ? L"True" : L"False"); }
}
if (drawing_state->object.vscroll)
{
CP_XML_NODE(L"x:VScroll") { CP_XML_CONTENT(*drawing_state->object.vscroll ? L"True" : L"False"); }
}
if (drawing_state->object.hscroll)
{
CP_XML_NODE(L"x:Horiz") { CP_XML_CONTENT(*drawing_state->object.hscroll ? L"True" : L"False"); }
}
}
}
@ -2488,6 +2554,13 @@ void xlsx_drawing_context::serialize_bitmap_fill(std::wostream & stream, _drawin
CP_XML_ATTR(L"thresh", *fill.biLevel * 1000);
}
}
if (fill.color.opacity > 0.00001)
{
CP_XML_NODE(L"a:alphaModFix")
{
CP_XML_ATTR(L"amt", (int)(fill.color.opacity * 100000));
}
}
}
CP_XML_NODE(L"a:srcRect")
@ -2711,6 +2784,30 @@ void xlsx_drawing_context::serialize_control_props(std::wostream & strm, _drawin
{
CP_XML_ATTR(L"dropLines", *drawing_state->object.drop_lines);
}
if (drawing_state->object.dx)
{
CP_XML_ATTR(L"dx", *drawing_state->object.dx);
}
if (drawing_state->object.checked && (*drawing_state->object.checked))
{
CP_XML_ATTR(L"checked", L"Checked");
}
if (drawing_state->object._3D)
{
CP_XML_ATTR(L"noThreeD", !(*drawing_state->object._3D));
}
if (drawing_state->object.vscroll)
{
CP_XML_ATTR(L"verticalBar", *drawing_state->object.vscroll);
}
if (drawing_state->object.hscroll)
{
CP_XML_ATTR(L"horiz", *drawing_state->object.hscroll);
}
if (drawing_state->object.multiLine)
{
CP_XML_ATTR(L"multiLine", *drawing_state->object.multiLine);
}
}
}
}
@ -2832,10 +2929,10 @@ void xlsx_drawing_context::set_sheet_anchor(int colFrom, int xFrom, int rwFrom,
current_drawing_states->back()->sheet_anchor.colTo = colTo;
current_drawing_states->back()->sheet_anchor.rwFrom = rwFrom;
current_drawing_states->back()->sheet_anchor.rwTo = rwTo;
current_drawing_states->back()->sheet_anchor.xFrom = (std::min)(xFrom, xTo);
current_drawing_states->back()->sheet_anchor.yFrom = (std::min)(yFrom, yTo);
current_drawing_states->back()->sheet_anchor.xTo = (std::max)(xFrom, xTo);
current_drawing_states->back()->sheet_anchor.yTo = (std::max)(yFrom, yTo);
current_drawing_states->back()->sheet_anchor.xFrom = xFrom;
current_drawing_states->back()->sheet_anchor.yFrom = yFrom;
current_drawing_states->back()->sheet_anchor.xTo = xTo;
current_drawing_states->back()->sheet_anchor.yTo = yTo;
}
current_drawing_states->back()->sheet_anchor.absolute.x = x;

View File

@ -355,9 +355,15 @@ public:
_CP_OPT(int) x_sel;
_CP_OPT(int) x_sel_type;
_CP_OPT(int) lct ;
_CP_OPT(int) dx;
std::wstring fmlaRange;
_CP_OPT(int) drop_style;
_CP_OPT(int) drop_lines;
_CP_OPT(bool) checked;
_CP_OPT(bool) _3D;
_CP_OPT(bool) vscroll;
_CP_OPT(bool) hscroll;
_CP_OPT(bool) multiLine;
}object;
//for group
std::vector<_drawing_state_ptr> drawing_states;
@ -521,6 +527,12 @@ public:
void set_object_fmlaRange (const std::wstring & fmla);
void set_object_drop_style (int val);
void set_object_drop_lines (int val);
void set_object_dx (int dx);
void set_object_checked (bool val);
void set_object_multiLine (bool val);
void set_object_vscroll (bool val);
void set_object_hscroll (bool val);
void set_object_3D (bool val);
//---------------------------------------------------------------------------------------------
void set_custom_rect (_rect & rect);
void set_custom_verticles (std::vector<ODRAW::MSOPOINT> & points);

View File

@ -42,10 +42,12 @@ BiffStructurePtr FtCblsData::clone()
void FtCblsData::load(CFRecord& record)
{
//ft(2 bytes) : Reserved.MUST be 0x0012.
//cb(2 bytes) : Reserved.MUST be 0x0008.
unsigned short ft, cb;
record >> ft >> cb;
if ( ft != 0x000a && cb != 0x000c)
if ( ft != 0x0012 && cb != 0x0008)
{
record.RollRdPtrBack(4);
return;

View File

@ -42,6 +42,8 @@ BiffStructurePtr FtEdoData::clone()
void FtEdoData::load(CFRecord& record)
{
//ft(2 bytes) : Reserved.MUST be 0x0010.
//cb(2 bytes) : Reserved.MUST be 0x0008.
unsigned short ft, cb;
record >> ft >> cb;

View File

@ -42,6 +42,8 @@ BiffStructurePtr FtGboData::clone()
void FtGboData::load(CFRecord& record)
{
//ft(2 bytes) : Reserved.MUST be 0x000F.
//cb(2 bytes) : Reserved.MUST be 0x0006
unsigned short ft, cb;
record >> ft >> cb;

View File

@ -43,10 +43,13 @@ BiffStructurePtr FtRboData::clone()
void FtRboData::load(CFRecord& record)
{
//ft(2 bytes) : Reserved.MUST be 0x0011.
//cb(2 bytes) : Reserved.MUST be 0x0004.
unsigned short ft, cb;
record >> ft >> cb;
if ( ft != 0x000b && cb != 0x0006)
if ( ft != 0x00011 && cb != 0x0004)
{
record.RollRdPtrBack(4);
return;

View File

@ -183,7 +183,7 @@ void OfficeArtClientAnchorSheet::calculate_1()
else
_cy += 256 * kfRow * sheet_info.defaultRowHeight;
}
_cy += _dyT - _y;
_cy += _dyB - _y;
}

View File

@ -81,7 +81,12 @@ void PtgExtraArray::load(CFRecord& record)
for(int i = 0; i < (tempcols) * (temprows); ++i)
{
if (record.getRdPtr() >= record.getDataSize())
break;
{
unsigned char rec_type = SerAr::SerType::typeSerNil;
SerArPtr ser(SerAr::createSerAr(rec_type));
array_.push_back(ser);
continue;
}
unsigned char rec_type;
record >> rec_type;
if (record.getGlobalWorkbookInfo()->Version >= 0x0800)
@ -138,24 +143,31 @@ void PtgExtraArray::save(CFRecord& record)
const std::wstring PtgExtraArray::toString() const
{
std::wstring ret_val;
unsigned char col_cnt = cols + 1;
unsigned char col_cnt = cols;
if (array_.empty()) return L"";
for(std::vector<SerArPtr>::const_iterator it = array_.begin(), itEnd = --array_.end(); it != itEnd; ++it)
{
ret_val += (*it)->toString();
if(--col_cnt)
auto tempVal = (*it)->toString();
if(tempVal.empty())
tempVal = L"#N/A";
ret_val += tempVal;
if (col_cnt > 1)
{
ret_val += L',';
--col_cnt;
}
else
{
ret_val += L';';
col_cnt = cols + 1;
col_cnt = cols;
}
}
ret_val += array_.back()->toString();
auto tempVal = array_.back()->toString();
if(tempVal.empty())
tempVal = L"#N/A";
ret_val += tempVal;
return ret_val;
}

View File

@ -62,6 +62,16 @@ BiffStructurePtr SerNum::clone()
void SerNum::load(CFRecord& record)
{
record >> xnum;
// Excel limitations
constexpr double ExcelMinAbs = 2.229e-308;
constexpr double ExcelMax = 9.99999999999999e+307;
if(std::abs(xnum) < ExcelMinAbs && xnum != 0.0)
xnum = (xnum > 0) ? ExcelMinAbs : -ExcelMinAbs;
else if(xnum > ExcelMax)
xnum = ExcelMax;
else if(xnum < -ExcelMax)
xnum = -ExcelMax;
}
void SerNum::save(CFRecord& record)
@ -77,7 +87,10 @@ void SerNum::save(CFRecord& record)
const std::wstring SerNum::toString() const
{
return STR::double2str(xnum);
auto tempNum = STR::double2str(xnum);
if(tempNum == L"-nan")
tempNum = L"#NUM!";
return tempNum;
}

View File

@ -94,7 +94,11 @@ void SerStr::save(CFRecord& record)
const std::wstring SerStr::toString() const
{
return L"\"" + boost::algorithm::replace_all_copy(std::wstring(rgch), L"\"", L"\"\"") + L"\"";
std::wstring tempVal = rgch;
tempVal.erase(std::remove(tempVal.begin(), tempVal.end(), L'\0'), tempVal.end());
if(tempVal.size() > 255)
tempVal.resize(255);
return L"\"" + boost::algorithm::replace_all_copy(tempVal, L"\"", L"\"\"") + L"\"";
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More