Compare commits

...

318 Commits

Author SHA1 Message Date
c15098ed7b Added line stroke testing 2025-02-13 12:40:10 +03:00
a93db0e012 . 2025-02-12 18:15:00 +03:00
f145378002 fix additional sdtPr 2025-02-12 15:35:26 +03:00
8098fec345 Merge pull request 'Fix bug #72825' (#227) from fix/bug72825 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/227
2025-02-11 18:11:08 +00:00
7bfcea0fff Merge pull request 'Fix bug #72875' (#226) from fix/bug72875 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/226
2025-02-11 18:10:41 +00:00
4b4845c558 Merge pull request 'Fix bug #72414' (#225) from fix/bug72414 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/225
2025-02-11 18:10:03 +00:00
b26e3e2fee Merge pull request 'fix/bug70675' (#224) from fix/bug70675 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/224
2025-02-11 18:09:33 +00:00
388951670c Merge pull request 'Fix bug #72790' (#223) from fix/bug72790 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/223
2025-02-11 18:08:55 +00:00
7d3488abc9 Merge pull request 'fix/bug-68408' (#229) from fix/bug-68408 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/229
2025-02-11 11:10:20 +00:00
fea3910254 adding reading attributes 2025-02-11 13:22:50 +03:00
2d58b08f0f Merge pull request 'PDF MovePage' (#222) from fix/pre8.3.1 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/222
2025-02-11 09:06:33 +00:00
50846677d5 Add missed files 2025-02-10 13:30:46 +03:00
3b450306f1 Merge branch 'hotfix/v8.3.1' of git.onlyoffice.com:ONLYOFFICE/core into hotfix/v8.3.1 2025-02-10 12:07:58 +03:00
c67ec5f632 Add missed file 2025-02-10 11:20:06 +03:00
62450ee1fb add additional props sdt 2025-02-10 10:46:34 +03:00
ad301b6f50 Merge branch 'feature/docbuilder-license' into hotfix/v8.3.1 2025-02-09 00:46:23 +03:00
d251682639 Refactoring 2025-02-09 00:32:48 +03:00
27c7920def Fix actual pos MovePage 2025-02-07 13:02:22 +03:00
a1b0421ec1 Fix MovePage 2025-02-07 13:02:21 +03:00
b7972ea391 Create MovePage 2025-02-07 13:02:21 +03:00
17840c5ed7 for bug #68408 2025-02-06 16:58:59 +03:00
ff4726e6ec for bug #68408 2025-02-06 15:53:53 +03:00
4e9cd74367 for bug #68408 2025-02-06 15:52:02 +03:00
b8737d2474 for bug #68408 2025-02-06 15:50:15 +03:00
2f4b7442c7 Fix CJSContext::GetCurrent method for jsc version 2025-02-06 12:44:39 +03:00
d97d2668d2 Merge branch release/v8.3.0 into master 2025-02-05 17:15:43 +00:00
45da53e9ae Refactoring standarttester 2025-02-04 20:12:07 +03:00
618a7ea09e Merge remote-tracking branch 'origin/release/v8.3.0' into fix/bug70675 2025-02-04 17:19:00 +05:00
a33743cff2 fix bug #73052 2025-02-04 13:44:41 +06:00
a83e19cbdf fix bug #72176 2025-02-03 16:35:23 +00:00
8a991ae24a Merge pull request 'Fix bug #72857' (#208) from fix/bug72857 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/208
2025-02-03 14:35:21 +00:00
6caca87b64 Merge pull request 'For bug #72496' (#207) from fix/bug72496 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/207
2025-02-03 14:35:10 +00:00
9ab884ae24 Merge pull request 'Fix hwp conversion' (#217) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/217
2025-02-03 14:15:54 +00:00
e493d976e3 Fix bug #73036 2025-02-03 16:59:47 +03:00
d75e7342cf Fix bug #73042 2025-02-03 15:45:09 +03:00
ddd750be9c Merge pull request 'Fix write base fonts' (#216) from fix/pdf-standart-fonts into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/216
2025-02-03 12:40:28 +00:00
79a4434583 Fix bug #73040 2025-02-03 15:35:39 +03:00
44ff2aff3c Fix empty FreeText AP 2025-02-03 15:32:41 +03:00
2f4b3e41b3 Fix write base fonts 2025-02-03 15:24:08 +03:00
fe208f5243 Merge pull request 'Fix bug #72961' (#215) from fix/bug-72961 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/215
2025-02-03 11:15:35 +00:00
e41c1d9703 Fix bug #72961 2025-02-03 14:12:29 +03:00
1cb56e532c Fix bug #72790 2025-02-03 15:39:18 +05:00
5c5f98a6e3 Fix bug 73014 2025-02-03 10:45:38 +03:00
f9dd82ad47 Merge pull request 'Fix HWP conversion' (#211) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/211
2025-02-03 06:43:31 +00:00
084c8f4b94 Fix bug #72999 2025-02-03 07:17:39 +03:00
bf15325a9e Fix bug #73000 2025-02-03 05:25:55 +03:00
1b50b3a53a Fix bug 72868 2025-02-01 17:39:08 +03:00
70b40c46d2 Fix bug #72721 2025-02-01 11:36:52 +03:00
23798f3c96 Fix ios build 2025-01-31 17:14:07 +03:00
1e8d22080d Merge pull request 'Fix hwp bugs' (#209) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/209
2025-01-31 05:08:55 +00:00
90bcd47fb7 The conversion of the character spacing to hwp has been removed 2025-01-31 03:15:19 +03:00
c1adf0b30c Fix bug #72685 2025-01-31 03:15:12 +03:00
b65ed1ccb4 Fix bug #72825 2025-01-31 03:40:47 +05:00
8e4bbb5e27 Fix bug #72875 2025-01-30 22:13:22 +05:00
81a4d9ccd0 Fix bug 72936 2025-01-30 16:51:25 +03:00
a97014c173 Disable use filesystem in metafiles (js module) 2025-01-30 14:26:57 +03:00
b3951d083a Fix elements align in html conversion 2025-01-30 10:37:42 +00:00
7d78b37540 Fix bug #72932 2025-01-30 10:37:42 +00:00
ff162d451e Merge pull request 'Fix hwp bug' (#205) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/205
2025-01-30 10:33:13 +00:00
5dc6402006 Fix test file 2025-01-30 13:12:27 +03:00
fae17d9bfc Merge pull request 'For bug #72694' (#204) from fix/bug72694 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/204
2025-01-30 08:02:28 +00:00
931f4edae4 For bug #72694 2025-01-30 13:36:42 +06:00
3609cf1237 Fix bug #72933 2025-01-30 00:49:49 +03:00
cc8fa641aa Merge pull request 'Fix bug 72811' (#203) from fix/bug-72811 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/203
2025-01-29 16:20:19 +00:00
3b9a865d77 Fix bug 72811 2025-01-29 19:07:58 +03:00
f3b0a992bd Fix typo 2025-01-29 18:57:35 +03:00
74f3e7f279 Merge pull request 'Fix hwp conversion' (#202) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/202
2025-01-29 15:45:08 +00:00
d195aa4a79 Fix build 2025-01-29 18:31:12 +03:00
4a384edf08 For bug #72496 2025-01-29 20:23:33 +05:00
30f96cbc6c Fix bug #72705 2025-01-29 18:15:29 +03:00
007362d8be Fix bug #72780 2025-01-29 17:57:54 +03:00
f4aac048ea fix bug #72012 2025-01-29 17:44:17 +03:00
f815fec8ed Fix bug #72714 2025-01-29 17:14:53 +03:00
4ec217226d Fix bug #72721 2025-01-29 16:32:43 +03:00
3cef41e876 Added bookmark conversion, fix bugs, refactoring in hwp format 2025-01-29 16:22:03 +03:00
20bff1d6fe for bug #72794 2025-01-29 11:17:21 +00:00
8da1a109de Fix bug #72857 2025-01-29 02:28:47 +05:00
704cef604e fix bug #72496 2025-01-28 19:26:15 +03:00
3c850e2086 Fix bug #72667 2025-01-28 13:47:20 +00:00
ab660cb8a3 Merge pull request 'for bug #72496' (#198) from For/bug72496 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/198
2025-01-28 13:12:05 +00:00
af4343b1d8 for bug #72496 2025-01-28 16:06:39 +03:00
7e4fe558f4 Fix bug #72847 2025-01-28 15:17:08 +03:00
f942e56361 fix namespaces 2025-01-28 13:46:28 +03:00
8b85f6987f Merge pull request 'Fix bug #72839' (#197) from fix/bug-72839 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/197
2025-01-28 09:13:21 +00:00
cbe412d3c7 Fix bug #72839 2025-01-28 12:03:31 +03:00
6913cae8f3 Fix bug #72414 2025-01-28 06:09:12 +05:00
d3d9c8df94 Added text indent in hwp conversion 2025-01-27 22:14:25 +03:00
01b582c4b9 Added BorderFill in hwp conversion 2025-01-27 22:01:41 +03:00
4568144a22 Merge branch 'fix/bug72794' into release/v8.3.0 2025-01-27 20:38:15 +03:00
cc4df3726a fix bug #72745 2025-01-27 20:37:02 +03:00
696610862a . 2025-01-27 18:27:20 +03:00
da6a5e9e98 for binary 2025-01-27 15:30:56 +03:00
d395e63b80 Merge pull request 'Fix bug #72657' (#188) from fix/bug72657 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/188
2025-01-27 12:30:02 +00:00
0350675df6 Fix min version 2025-01-27 13:58:30 +03:00
aead2e9fb8 Merge pull request 'Fix bug#72779' (#196) from fix/bug72779 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/196
2025-01-27 10:03:20 +00:00
d12bad7bd1 Fix bug#72779 2025-01-27 15:58:25 +06:00
da2284fff6 Fix bug #72712 2025-01-26 18:26:03 +00:00
1382aa0b3d Fix bug #72780 2025-01-26 18:26:03 +00:00
8ba5df60d9 Fix bug #72705 2025-01-26 18:26:03 +00:00
5299872b17 Fixes for snapshots 2025-01-26 20:18:14 +03:00
e1757dd5d1 fix bug #72796 2025-01-26 12:10:44 +03:00
b5c5a5f1ed Fix bug #72781 2025-01-25 17:56:11 +00:00
6979e17c3d Added polygon and curve conversion in hwp format 2025-01-25 17:56:11 +00:00
c43fb92860 Fixed the correction of large text size in svg 2025-01-25 18:27:22 +03:00
63887c95b6 Use wmf&emf instead conversion to svg in zip images (for native convertations) 2025-01-25 13:39:35 +03:00
d3d4e86925 Merge pull request 'Fix bug #72365' (#179) from fix/bug72365 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/179
2025-01-25 09:25:56 +00:00
f6383571eb fix bug #72794 2025-01-25 12:18:30 +03:00
a6f6a67aed Fix prev commit 2025-01-24 23:30:51 +03:00
f9543ef9de Year Up 2025-01-24 23:03:42 +03:00
bb58be4f18 Add new method for images inside zip 2025-01-24 22:51:04 +03:00
40efe7dabc Fix build 2025-01-24 18:10:29 +00:00
80b7caaf7a Fix bug #72721 2025-01-24 18:10:29 +00:00
08e3dfb061 Fix bug #72772 2025-01-24 18:10:29 +00:00
3a9d91b291 Fix bug #72719 2025-01-24 18:10:29 +00:00
45b26554b2 Merge pull request 'Fix bug #72175' (#191) from fix/bug72175 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/191
2025-01-24 16:19:30 +00:00
09c4df8e05 Fix remove AP when transform 2025-01-24 17:53:23 +03:00
85533a6553 fix bug #72768 2025-01-24 17:35:53 +03:00
65898a94ad Merge pull request 'Fix hwp bugs' (#187) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/187
2025-01-24 11:31:39 +00:00
86009ff6fa Fix bug #72175 2025-01-24 12:46:02 +03:00
b91dfb075e Fix bug #72657 2025-01-24 13:42:37 +06:00
f057a16bc1 Fix bug #72700 2025-01-24 04:32:32 +03:00
bd76adc97f Fix bug #72714 2025-01-23 23:36:47 +03:00
27b5dbf15e Fix bad conversion hwp to ooxml 2025-01-23 23:08:52 +03:00
58a7c7cd9d Merge branch 'release/v8.3.0' of git.onlyoffice.com:ONLYOFFICE/core into release/v8.3.0 2025-01-23 15:12:51 +03:00
18fa4639b0 fix convert to ooxml 2025-01-23 15:12:43 +03:00
389e5314df Fix bug #72692 2025-01-23 15:03:17 +03:00
42636a8ab1 Merge pull request 'Fix bug #72173' (#185) from fix/bug72173 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/185
2025-01-23 11:45:45 +00:00
a3c87e7119 Fix crash with fonts with symbol > 0x10FFFF and wirh \n in name 2025-01-23 14:41:39 +03:00
2115371c0c Fix bug #72173 2025-01-23 13:17:46 +03:00
bd95478d77 Fix build 2025-01-22 19:40:15 +03:00
965680de23 Fix build 2025-01-22 19:32:31 +03:00
ad44ddf682 Fix build 2025-01-22 18:55:57 +03:00
06386d5458 Fix build 2025-01-22 18:25:41 +03:00
ffda83848d Fix bug 70819 2025-01-22 15:48:26 +03:00
55dc0b789f Merge remote-tracking branch 'origin/feature/hwpx' into release/v8.3.0 2025-01-22 14:28:50 +03:00
53e3f8c561 Merge pull request 'feature/docx-renderer' (#183) from feature/docx-renderer into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/183
2025-01-22 11:25:17 +00:00
731a7addee Comment logic 2025-01-22 12:57:21 +03:00
36b82c1ef9 add default font size on odf math 2025-01-22 12:42:46 +03:00
229a8f9dad . 2025-01-22 12:14:08 +03:00
5f5d74df92 . 2025-01-22 12:13:15 +03:00
66ea88bf14 fix bug #72043 2025-01-22 12:08:39 +03:00
3953044063 Add clearing 2025-01-22 11:36:13 +03:00
9a4a1546cb Fix bug #72655 2025-01-21 23:19:08 +03:00
4085ee5002 Merge pull request 'Fix bug #69572' (#180) from fix/bug69572 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/180
2025-01-21 15:03:02 +00:00
f6ef582658 Merge pull request 'Fix bug#72187' (#176) from fix/bug72187 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/176
2025-01-21 15:02:15 +00:00
7b62295149 Fix bug 72544 2025-01-21 17:38:05 +03:00
421dcd780d Fix bug #69572 2025-01-21 20:17:24 +06:00
b9e7a3143c Fix bug 72595 2025-01-21 15:57:35 +03:00
6026841c00 Refactoring 2025-01-21 13:01:02 +03:00
1e6d0a9f25 fix text entry 2025-01-21 12:14:13 +03:00
adad3a05ba Fix build 2025-01-21 11:51:14 +03:00
99fa27e693 Merge branch 'release/v8.3.0' into feature/hwpx 2025-01-21 11:50:09 +03:00
6b66c8fb50 Merge pull request 'Fix bug#72189' (#177) from fix/bug72189 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/177
2025-01-21 07:49:05 +00:00
9faa7fb69d Added hwpx format to ASCConverter 2025-01-21 02:49:51 +03:00
84042360ab Fixed bugs in hwpx conversion 2025-01-21 02:49:10 +03:00
8a8a6e78eb fix bug #72578 2025-01-20 21:49:25 +03:00
8bd655dd17 fix bug #72611 2025-01-20 21:22:45 +03:00
34ecf84835 Merge pull request 'Fix bug #72414' (#161) from fix/bug72414 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/161
2025-01-20 18:05:36 +00:00
4cf79c985d Merge pull request 'Fix bug #72432' (#162) from fix/bug72432 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/162
2025-01-20 18:05:05 +00:00
18e359c1a6 Merge pull request 'Fix bug #72375' (#163) from fix/bug72375 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/163
2025-01-20 18:04:21 +00:00
dc777f43d9 Merge pull request 'Fix bug #72264' (#164) from fix/bug72264 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/164
2025-01-20 18:03:52 +00:00
8cd7ca9731 Merge pull request 'Fix bug #72039' (#165) from fix/bug72039 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/165
2025-01-20 18:03:13 +00:00
8f91c47178 Merge pull request 'Fix bug #69238' (#166) from fix/bug69238 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/166
2025-01-20 18:02:44 +00:00
fdac954df5 Add main logic of tables (in developing) 2025-01-20 16:14:28 +03:00
70c98eb9f3 Fix build 2025-01-20 15:42:37 +03:00
024efd2e35 Fix bug #72535 2025-01-20 11:12:14 +00:00
da252bfa5e Fix bug #72589 2025-01-20 11:05:28 +00:00
c9ce68eab3 Improved work with external style files in html 2025-01-20 11:05:28 +00:00
3af549a158 Fix bug #72586 2025-01-20 11:05:28 +00:00
34627ff1c5 Fix bug #72519 2025-01-20 11:05:28 +00:00
0c2b49af11 Fix build for win XP 2025-01-20 10:53:51 +03:00
4324ea847c Reafactoring and fixed bugs in hwp conversion 2025-01-19 20:06:41 +03:00
df76ff3778 Fix bug 72537 2025-01-17 20:11:47 +03:00
172bb09305 Fix bug 72484 2025-01-17 20:07:45 +03:00
aa0ba83d32 Fix bug#72189 2025-01-17 18:44:27 +03:00
fb934ef527 Fix bug #72558 2025-01-17 15:18:52 +03:00
a2b817bbc2 Merge pull request 'for bug #72486' (#169) from fix/bug72486 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/169
2025-01-17 09:29:25 +00:00
ecd80408e2 for bug #72486 2025-01-17 15:23:28 +06:00
b78e2cb33c Adding parsing of hwpx format elements 2025-01-17 02:42:21 +03:00
f0c52d2e81 Merge pull request 'Fixed html bugs' (#168) from fix/html into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/168
2025-01-16 12:24:11 +00:00
23ac269339 Fix bug #72533 2025-01-16 15:02:32 +03:00
8239d6f51d Fix bug 72529 2025-01-16 10:42:07 +03:00
3adf336384 For bug #72519 2025-01-15 22:42:28 +03:00
8e1810697f Fix bug #72519 2025-01-15 20:34:02 +03:00
7c2105b613 Fix bug #72365 2025-01-15 22:13:04 +05:00
2027defafb Fix bug #69238
Merge remote-tracking branch 'origin/release/v8.3.0' into fix/bug69238
2025-01-15 21:11:24 +05:00
2ea586ec6f Fix bug #72414 2025-01-15 20:13:21 +05:00
a6940c42ac Obtain builder's version from INTVER 2025-01-15 13:16:59 +00:00
6ed1cb60d6 Merge pull request 'Fixed bugs in hwp format' (#159) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/159
2025-01-15 12:55:20 +00:00
2c9e58280b Fixed the bug of missing bmp images in hwp format 2025-01-15 15:09:24 +03:00
f18b50cd4f Fix typo 2025-01-15 14:37:45 +03:00
aa2af5d280 [android] Add new formats 2025-01-15 14:29:38 +03:00
dde69ba65f Fix typo 2025-01-15 13:09:45 +03:00
f51b58c927 [android] Add HWPFile 2025-01-15 09:36:16 +03:00
43f1ac0596 Adding parsing of hwpx format elements 2025-01-15 01:28:37 +03:00
321e0de9f3 Merge pull request 'Fix bug 72489' (#158) from fix/bug-72489 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/158
2025-01-14 14:33:32 +00:00
ca77113e79 . 2025-01-14 17:21:16 +03:00
2098c72a35 Fix bug 72489 2025-01-14 17:11:23 +03:00
06e34fc303 Merge pull request 'Fix bug 71493' (#154) from fix/bug-71493 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/154
2025-01-14 14:09:00 +00:00
7b56d56c0e [android] Add new formats 2025-01-14 15:17:17 +03:00
aa90104b18 Fix build 2025-01-14 13:03:28 +03:00
98b285ab64 Merge pull request 'Added HWP format' (#155) from feature/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/155
2025-01-14 09:43:21 +00:00
cbd7e8ee7b Refactoring 2025-01-14 09:40:42 +00:00
b76235d4fc For bug #72413 2025-01-14 09:40:42 +00:00
b9e1d77038 Fix bug #72353 2025-01-14 09:40:42 +00:00
8f448d3842 For bug #72318 2025-01-14 09:40:42 +00:00
89d7242d21 Fix bug #72386 2025-01-14 09:39:27 +00:00
9aaa241523 fix bug #72328 2025-01-14 11:01:03 +03:00
02bd5c4b0b Fix bug#72187 2025-01-14 10:17:09 +03:00
4003a39ef9 Fix typo 2025-01-14 01:42:46 +03:00
a5fed4af70 Fix build and refactoring 2025-01-14 01:41:13 +03:00
a9d8cbbc57 Fix bug 71493
Also fix bug 57854, 55429
2025-01-13 17:27:54 +03:00
6c79ab37fa Fix bug 72193 2025-01-13 17:16:52 +03:00
17762b71db Unused files have been deleted 2025-01-13 16:53:14 +03:00
be2f142fd3 Fix build 2025-01-13 16:52:45 +03:00
fdcb2cf7ba Fix bug #72432 2025-01-13 18:19:42 +05:00
07bf7a44aa Fix bug #72375 2025-01-13 17:08:46 +05:00
a2bfbd8368 Adding parsing of hwpx format elements 2025-01-13 01:12:37 +03:00
25553904df Adding parsing of hwpx format elements 2025-01-12 17:25:13 +03:00
954ef08975 Adding parsing of hwpx format elements 2025-01-12 00:34:45 +03:00
aea8b7873c Refactoring and fix bugs 2025-01-11 01:18:41 +03:00
a7774a6bc3 fix bug #72395 2025-01-10 17:10:46 +03:00
4d15b5c19d Improved conversion of shapes properties в hwp format 2025-01-10 00:50:11 +03:00
e230fa1d43 fix bug #53173 2025-01-09 14:02:46 +03:00
3d30144ebb Merge pull request 'Fix scientific numbers csv reading' (#153) from fix/scientific-scv-reading into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/153
2025-01-09 09:54:03 +00:00
3365ca15d6 Fix scientific numbers csv reading 2025-01-09 15:47:22 +06:00
c0debdfe39 Improved conversion of shape styles, fix bugs, refactoring in hwp format 2025-01-09 01:27:30 +03:00
f7d55d48fe Remove depends to CSvgFile from CConverter2OOXML in hwp format 2025-01-08 23:16:37 +03:00
f2510a9410 Merge branch 'release/v8.3.0' into feature/hwp 2025-01-08 23:09:44 +03:00
f2a8a9878b Added partial web video conversion in hwp format 2025-01-08 23:05:19 +03:00
39adc06921 Fixed the merge obstacle 2025-01-08 22:59:00 +03:00
64af642c40 Added AutoNumber conversion in hwp conversion 2025-01-08 01:12:03 +03:00
ef26ac732e Added columns conversion in hwp format 2025-01-08 00:19:57 +03:00
8bbaaf4cef Added header and footer conversion in hwp format, fix bugs and refactoring 2025-01-07 23:14:04 +03:00
de821b73c8 Added endnotes conversion in hwp format and fixed bugs 2025-01-05 23:44:46 +03:00
a7d5fe3994 Added footnotes conversion in hwp format 2025-01-05 23:13:24 +03:00
7deeefbcf4 Added chart conversion in hwp format 2025-01-05 01:48:16 +03:00
3666bdf6fc Fixed bugs in the parse and improved shapes conversion 2025-01-04 16:49:45 +03:00
eaa7bb30db Added rectangle conversion in hwp format 2025-01-03 23:04:36 +03:00
d4619c5786 Added hwp format to x2t 2025-01-03 21:16:03 +03:00
0f3852ab1e Refactoring 2025-01-03 21:14:30 +03:00
fb5b1c5a6e Added conversion of a numbered list in hwp format 2025-01-02 23:20:43 +03:00
cef8ac9fd9 Remove depends to CSvgFile from HtmlFile2. Add initialize fontsfor svg. 2025-01-02 22:36:18 +03:00
45aa5df267 Fix build 2025-01-02 21:50:30 +03:00
e8c94aa103 Improved text conversion in hwp format 2024-12-31 13:48:26 +03:00
aa5b7e1276 Improved conversion of styles in hwp format 2024-12-31 01:08:15 +03:00
dd98d0c11d Merge pull request 'Fix bug 72344' (#149) from fix/bug-72344 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/149
2024-12-28 11:00:20 +00:00
08971025bd Added support for conversion of HWP tables, fixed bugs 2024-12-27 23:58:06 +03:00
00f6a823d6 Fix bug 72344 2024-12-27 20:13:44 +03:00
b4f4da26d6 Mark files as debug 2024-12-27 17:54:45 +03:00
1c9f7ac597 . 2024-12-27 16:16:42 +03:00
673139f5a9 Merge pull request 'Fix Metafile conversion' (#148) from fix/Metafile into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/148
2024-12-27 11:57:39 +00:00
4bf0cee034 Added image conversion to hwp, bug fixes, and refactoring 2024-12-26 20:51:15 +03:00
00abbab370 Fix bug #72264 2024-12-26 17:52:59 +05:00
3125a7a928 fix bug #72263 2024-12-25 20:23:53 +03:00
f20c944c72 Merge pull request 'Fix bug 72273' (#146) from fix/bug-72273 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/146
2024-12-25 08:28:41 +00:00
6d7dc6517b fix bug #70653 2024-12-24 18:28:53 +03:00
6fd84c6c8c [android] Enable minify and update agp 2024-12-24 14:16:53 +03:00
d37f31208c Merge pull request 'Update branch' (#147) from release/v8.3.0 into fix/Metafile
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/147
2024-12-24 10:18:44 +00:00
c472b19e0d Fix bug#72243 2024-12-24 13:07:45 +03:00
7b03bcde89 Writing the HWP format conversion 2024-12-24 11:22:56 +03:00
03a7eb0fd4 Fix bug 72273 2024-12-24 10:45:29 +03:00
c0a779727e Merge pull request 'Fix bug #72173' (#145) from fix/bug72173 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/145
2024-12-24 07:20:13 +00:00
52d3f0bc19 Merge pull request 'Fix bug #72187' (#144) from fix/bug72187 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/144
2024-12-24 07:19:52 +00:00
c17497e304 Merge pull request 'Fix bug #72048' (#143) from fix/bug72048 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/143
2024-12-24 07:19:10 +00:00
6bc4ecbc73 Fix bug #72173 2024-12-24 10:10:08 +03:00
2246077589 Fix bug #72187 2024-12-24 09:57:00 +03:00
91eb74773b Merge branch 'fix/bug72039' of git.onlyoffice.com:ONLYOFFICE/core into fix/bug72039
# Conflicts:
#	OdfFile/Reader/Format/draw_shapes_docx.cpp
2024-12-23 20:31:41 +05:00
5b8d2660aa Fix bug #72039 2024-12-23 20:24:05 +05:00
60ad1c10fd fix bug #72196 2024-12-23 17:29:40 +03:00
36b0cc524e Fix bug #72039 2024-12-23 17:33:13 +05:00
bb33e70b3e The writing code for converting hwp format and fixed bugs 2024-12-23 15:15:24 +03:00
5f2d7b2f5a Add base xml for tables 2024-12-20 19:27:23 +03:00
02aeaa6a64 Fix bug with ascent/descent 2024-12-20 17:38:56 +03:00
4a110d68c1 Fixed bugs in reading hwp format and added test example 2024-12-18 15:13:43 +03:00
48d86cb7ce Add base classes 2024-12-17 15:39:50 +03:00
9991cc8c03 Rewrite split lines logic 2024-12-17 15:13:53 +03:00
36a3b693d5 Update paragraph logic for enums 2024-12-17 13:44:31 +03:00
328e379ec2 The writing code for converting hwp format 2024-12-16 21:05:10 +03:00
7d65d4b11a Fix bug #72048 2024-12-16 16:30:44 +03:00
0c1df859e2 The writing code for converting hwp format 2024-12-14 16:36:33 +03:00
d58424d089 Fix build 2024-12-14 11:38:11 +03:00
fe2ca8c566 Delete unused headers & add new files 2024-12-14 11:33:47 +03:00
20d2ff7954 Refactoring 2024-12-14 11:18:42 +03:00
b125c19d02 Remove useless call 2024-12-14 07:13:48 +03:00
2f2d11a5f6 Fix bug with recalc size of space 2024-12-14 06:51:59 +03:00
de4897fdef Add HorVerLinesCollector 2024-12-13 16:54:16 +03:00
f9952d0f94 Refactoring for future tables 2024-12-13 15:50:32 +03:00
d7b435a446 Delete unused file 2024-12-13 12:28:13 +03:00
bc4c39b7aa The writing code for converting hwp format 2024-12-11 21:34:46 +03:00
a5917c389f The writing code for converting hwp format 2024-12-10 22:19:37 +03:00
a93f00d0af The writing code for converting hwp format 2024-12-09 22:18:04 +03:00
b776b7b63f The writing code for converting hwp format 2024-12-06 15:18:32 +03:00
ecd71dd92a The writing code for converting hwp format 2024-12-05 21:27:21 +03:00
7e11af5553 The writing code for converting hwp format 2024-12-03 20:12:50 +03:00
168dc1ddb8 Merge remote-tracking branch 'origin/develop' into fix/bug69238 2024-12-03 13:27:22 +05:00
8918b7fae0 Fix formula conversion order 2024-12-03 13:26:51 +05:00
d20d1af154 The writing code for converting hwp format 2024-11-29 21:46:53 +03:00
925ffa09e2 Merge remote-tracking branch 'origin/develop' into fix/bug69238 2024-11-29 19:33:13 +05:00
87b5ae8f75 Merge branch hotfix/v8.2.2 into master 2024-11-28 12:16:10 +00:00
295dbbbb86 The writing code for converting hwp format 2024-11-27 20:45:00 +03:00
10ff332f4d Merge remote-tracking branch 'origin/develop' into fix/bug69238 2024-11-27 15:45:33 +05:00
f57179911f The beginning of writing code for converting hwp format 2024-11-26 20:52:11 +03:00
ce0f8251d3 Fix bug #69238 2024-11-22 17:32:40 +05:00
6b21323e8c Merge branch hotfix/v8.2.1 into master 2024-11-22 10:46:53 +00:00
cc2867e292 Fixed calculation of the conversion matrix in media file conversion 2024-11-05 18:05:09 +03:00
92b0f4e654 Updated calculation of line width in metafile conversion 2024-11-05 17:09:20 +03:00
cebc04b852 Unused functionality has been removed 2024-11-02 00:11:02 +03:00
dbfdffd0c5 Fixed missing text in the specified font in the metafile 2024-11-01 23:28:42 +03:00
b8d2cba3ae Refactoring 2024-11-01 22:15:03 +03:00
b56d62442d Added the ability to set shape-rendering in metafile to svg conversion 2024-11-01 21:21:44 +03:00
50fec65617 Added support for custom markers in metafile to svg conversion 2024-11-01 10:48:36 +03:00
42466cf648 Fix atan2 custom shape formula conversion 2024-10-31 18:08:36 +05:00
b4bb20bea7 Fixed a bug with dotted lines in metafiles 2024-10-30 14:53:25 +03:00
2ce37e34c4 Fixed a bug with incorrect positioning in EmfPlus 2024-10-30 14:06:12 +03:00
c8b8462d31 Support for embedded WMFs in emf is disabled 2024-10-29 12:15:50 +03:00
d21d0caa68 Fix bug #70675 2024-10-16 18:42:07 +05:00
f8ba0c59a6 Add license check for onlyoffice docbuilder builds 2024-09-25 16:04:17 +04:00
399 changed files with 23851 additions and 2842 deletions

View File

@ -25,7 +25,7 @@ namespace NSCSS
m_arParentsStyles(oStyle.m_arParentsStyles), m_sId(oStyle.m_sId),
m_nDpi(oStyle.m_nDpi), m_UnitMeasure(oStyle.m_UnitMeasure), m_dCoreFontSize(oStyle.m_dCoreFontSize),
m_oFont(oStyle.m_oFont), m_oMargin(oStyle.m_oMargin), m_oPadding(oStyle.m_oPadding), m_oBackground(oStyle.m_oBackground),
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay){}
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform){}
CCompiledStyle::~CCompiledStyle()
{
@ -44,6 +44,7 @@ namespace NSCSS
m_oPadding += oElement.m_oPadding;
m_oText += oElement.m_oText;
m_oDisplay += oElement.m_oDisplay;
m_oTransform += oElement.m_oTransform;
if (!oElement.m_sId.empty())
m_sId += L'+' + oElement.m_sId;
@ -66,6 +67,7 @@ namespace NSCSS
m_oPadding = oElement.m_oPadding;
m_oText = oElement.m_oText;
m_oDisplay = oElement.m_oDisplay;
m_oTransform = oElement.m_oTransform;
return *this;
}
@ -78,7 +80,8 @@ namespace NSCSS
m_oMargin == oStyle.m_oMargin &&
m_oPadding == oStyle.m_oPadding &&
m_oText == oStyle.m_oText &&
m_oDisplay == oStyle.m_oDisplay;
m_oDisplay == oStyle.m_oDisplay &&
m_oTransform == oStyle.m_oTransform;
}
void CCompiledStyle::StyleEquation(CCompiledStyle &oFirstStyle, CCompiledStyle &oSecondStyle)
@ -90,6 +93,7 @@ namespace NSCSS
NSProperties::CText ::Equation(oFirstStyle.m_oText, oSecondStyle.m_oText);
NSProperties::CBorder ::Equation(oFirstStyle.m_oBorder, oSecondStyle.m_oBorder);
NSProperties::CDisplay ::Equation(oFirstStyle.m_oDisplay, oSecondStyle.m_oDisplay);
NSProperties::CTransform ::Equation(oFirstStyle.m_oTransform, oSecondStyle.m_oTransform);
}
void CCompiledStyle::SetDpi(const unsigned short &uiDpi)
@ -431,6 +435,12 @@ namespace NSCSS
m_oDisplay.SetVAlign(pPropertie.second, unLevel, bHardMode);
break;
}
//TRANSFORM
CASE(L"transform"):
{
m_oTransform.SetMatrix(pPropertie.second, unLevel, bHardMode);
break;
}
default: AddOtherStyle(pPropertie, unLevel, bHardMode);
}
}

View File

@ -31,11 +31,12 @@ namespace NSCSS
NSProperties::CText m_oText;
NSProperties::CBorder m_oBorder;
NSProperties::CDisplay m_oDisplay;
NSProperties::CTransform m_oTransform;
CCompiledStyle();
CCompiledStyle(const CCompiledStyle& oStyle);
~CCompiledStyle();
virtual ~CCompiledStyle();
void SetDpi(const unsigned short& uiDpi);
void SetUnitMeasure(const UnitMeasure& enUnitMeasure);

View File

@ -13,14 +13,14 @@ namespace NSCSS
delete m_pInternal;
}
CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure) const
CCompiledStyle CCssCalculator::GetCompiledStyle(const std::vector<CNode> &arSelectors) const
{
return m_pInternal->GetCompiledStyle(arSelectors, bIsSettings, unitMeasure);
return m_pInternal->GetCompiledStyle(arSelectors);
}
bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure) const
bool CCssCalculator::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors) const
{
return m_pInternal->GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure);
return m_pInternal->GetCompiledStyle(oStyle, arSelectors);
}
std::wstring CCssCalculator::CalculateStyleId(const CNode& oNode)
@ -48,26 +48,11 @@ namespace NSCSS
m_pInternal->AddStylesFromFile(wsFileName);
}
void CCssCalculator::SetUnitMeasure(const UnitMeasure& nType)
{
m_pInternal->SetUnitMeasure(nType);
}
void CCssCalculator::SetDpi(const unsigned short int& nValue)
{
m_pInternal->SetDpi(nValue);
}
void CCssCalculator::SetBodyTree(const CTree &oTree)
{
m_pInternal->SetBodyTree(oTree);
}
UnitMeasure CCssCalculator::GetUnitMeasure() const
{
return m_pInternal->GetUnitMeasure();
}
std::wstring CCssCalculator::GetEncoding() const
{
return m_pInternal->GetEncoding();
@ -78,6 +63,26 @@ namespace NSCSS
return m_pInternal->GetDpi();
}
void CCssCalculator::ClearPageData()
{
m_pInternal->ClearPageData();
}
void CCssCalculator::ClearEmbeddedStyles()
{
m_pInternal->ClearEmbeddedStyles();
}
void CCssCalculator::ClearAllowedStyleFiles()
{
m_pInternal->ClearAllowedStyleFiles();
}
void CCssCalculator::ClearStylesFromFile(const std::wstring& wsFilePath)
{
m_pInternal->ClearStylesFromFile(wsFilePath);
}
void CCssCalculator::Clear()
{
m_pInternal->Clear();

View File

@ -19,8 +19,8 @@ namespace NSCSS
CCssCalculator();
~CCssCalculator();
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point) const;
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors) const;
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors) const;
std::wstring CalculateStyleId(const CNode& oNode);
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector<CNode> &arSelectors);
@ -30,14 +30,15 @@ namespace NSCSS
void AddStyles (const std::wstring& wsStyle);
void AddStylesFromFile(const std::wstring& wsFileName);
void SetUnitMeasure(const UnitMeasure& nType);
void SetDpi(const unsigned short int& nValue);
void SetBodyTree(const CTree &oTree);
UnitMeasure GetUnitMeasure() const;
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
void ClearPageData();
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFilePath);
void Clear();
};
}

View File

@ -5,12 +5,9 @@
#include <fstream>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <numeric>
#include "../../katana-parser/src/selector.h"
#include "../../../../../UnicodeConverter/UnicodeConverter.h"
#include "ConstValues.h"
#include "../../../../../DesktopEditor/common/File.h"
#include "StaticFunctions.h"
@ -41,61 +38,120 @@ bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vect
namespace NSCSS
{
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_UnitMeasure(Point), m_mStatictics(NULL), m_sEncoding(L"UTF-8"){}
CStyleStorage::CStyleStorage()
{}
CCssCalculator_Private::~CCssCalculator_Private()
CStyleStorage::~CStyleStorage()
{
m_arFiles.clear();
for (std::map<std::wstring, CElement*>::iterator oIter = m_mData.begin(); oIter != m_mData.end(); ++oIter)
if (oIter->second != NULL)
delete oIter->second;
m_mData.clear();
if (NULL != m_mStatictics)
delete m_mStatictics;
Clear();
}
inline void CCssCalculator_Private::GetOutputData(KatanaOutput *oOutput)
void CStyleStorage::Clear()
{
if ( NULL == oOutput )
return;
for (TStyleFileData* pStyleFileData : m_arStyleFiles)
{
if (nullptr == pStyleFileData)
continue;
switch (oOutput->mode) {
case KatanaParserModeStylesheet:
GetStylesheet(oOutput->stylesheet);
break;
case KatanaParserModeRule:
GetRule(oOutput->rule);
break;
case KatanaParserModeKeyframeRule:
case KatanaParserModeKeyframeKeyList:
case KatanaParserModeMediaList:
case KatanaParserModeValue:
case KatanaParserModeSelector:
case KatanaParserModeDeclarationList:
break;
for (std::map<std::wstring, CElement*>::iterator oIter = pStyleFileData->m_mStyleData.begin(); oIter != pStyleFileData->m_mStyleData.end(); ++oIter)
if (oIter->second != nullptr)
delete oIter->second;
delete pStyleFileData;
}
m_arStyleFiles.clear();
m_arEmptyStyleFiles.clear();
ClearEmbeddedStyles();
ClearAllowedStyleFiles();
#ifdef CSS_CALCULATOR_WITH_XHTML
ClearPageData();
#endif
}
void CStyleStorage::AddStyles(const std::string& sStyle)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output, m_mEmbeddedStyleData);
katana_destroy_output(output);
}
void CStyleStorage::AddStyles(const std::wstring& wsStyle)
{
if (wsStyle.empty())
return;
#ifdef CSS_CALCULATOR_WITH_XHTML
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
std::wsmatch oMatch;
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
{
AddPageData(oMatch[1].str(), oMatch[2].str());
oSearchStart = oMatch.suffix().first;
}
#endif
AddStyles(U_TO_UTF8(wsStyle));
}
void CStyleStorage::AddStylesFromFile(const std::wstring& wsFileName)
{
std::set<std::wstring>::const_iterator itEmptyFileFound = m_arEmptyStyleFiles.find(wsFileName);
if (m_arEmptyStyleFiles.cend() != itEmptyFileFound)
return;
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
[wsFileName](const TStyleFileData* pStyleFileData)
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
m_arAllowedStyleFiles.insert(wsFileName);
if (m_arStyleFiles.cend() != itFound)
return;
TStyleFileData *pStyleFileData = new TStyleFileData();
pStyleFileData->m_wsStyleFilepath = wsFileName;
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName), pStyleFileData->m_mStyleData);
if (!pStyleFileData->m_mStyleData.empty())
m_arStyleFiles.push_back(pStyleFileData);
else
{
m_arEmptyStyleFiles.insert(wsFileName);
delete pStyleFileData;
}
}
void CStyleStorage::ClearStylesFromFile(const std::wstring& wsFileName)
{
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
[wsFileName](const TStyleFileData* pStyleFileData)
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
if (m_arStyleFiles.cend() != itFound)
{
m_arStyleFiles.erase(itFound);
delete *itFound;
}
}
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles)
{
if (m_arPageDatas.empty())
return {};
for (const TPageData& oPageData : m_arPageDatas)
{
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
return oPageData.m_mData;
}
return {};
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
}
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode)
{
for (const std::pair<std::wstring, std::wstring> &oData : mData)
{
@ -110,162 +166,84 @@ namespace NSCSS
}
}
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
std::map<std::wstring, std::wstring> CStyleStorage::GetPageData(const std::wstring& wsPageName)
{
std::vector<std::wstring> arNodes;
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
{
if (!oNode->m_wsName.empty())
arNodes.push_back(oNode->m_wsName);
if (!oNode->m_wsClass.empty())
{
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
{
std::vector<std::wstring> arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arNodes.push_back(L'.' + oNode->m_wsClass);
}
if (!oNode->m_wsId.empty())
arNodes.push_back(L'#' + oNode->m_wsId);
}
return arNodes;
}
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
{
if (arNextNodes.empty())
return;
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
if (!arTempPrev.empty())
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
}
std::vector<CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes, bool bIsSettings)
{
if (arNodes.empty())
if (m_arPageDatas.empty())
return {};
std::vector<CElement*> arFindedElements;
std::wstring wsName, wsId;
std::vector<std::wstring> arClasses;
if (!arNodes.empty() && arNodes.back()[0] == L'#')
for (const TPageData& oPageData : m_arPageDatas)
{
wsId = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsId);
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
return oPageData.m_mData;
}
if (!arNodes.empty() && arNodes.back()[0] == L'.')
{
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
arNextNodes.push_back(arNodes.back());
arNodes.pop_back();
}
return {};
}
if (!arNodes.empty())
{
wsName = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsName);
}
const std::map<std::wstring, CElement*>::const_iterator oFindName = m_mData.find(wsName);
std::map<std::wstring, CElement*>::const_iterator oFindId;
if (!wsId.empty())
{
oFindId = m_mData.find(wsId);
if (oFindId != m_mData.end() && NULL != m_mStatictics)
{
std::map<StatistickElement, unsigned int>::const_iterator oFindCountId = m_mStatictics->find(StatistickElement{StatistickElement::IsId, wsId});
if ((m_mStatictics->end() != oFindCountId) &&
(((bIsSettings && oFindCountId->second < MaxNumberRepetitions) ||
(!bIsSettings && oFindCountId->second >= MaxNumberRepetitions))))
{
if (!oFindId->second->Empty())
arFindedElements.push_back(oFindId->second);
}
FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName);
}
}
if (!arClasses.empty())
{
if (!bIsSettings)
{
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
{
const std::map<std::wstring, CElement*>::const_iterator oFindClass = m_mData.find(*iClass);
if (oFindClass != m_mData.end())
{
if (!oFindClass->second->Empty())
arFindedElements.push_back(oFindClass->second);
FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName);
}
}
}
}
if (oFindName != m_mData.end())
{
if (!bIsSettings)
{
if (!oFindName->second->Empty())
arFindedElements.push_back(oFindName->second);
FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses);
}
}
if (arFindedElements.size() > 1)
{
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
[](CElement* oFirstElement, CElement* oSecondElement)
{
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
});
}
return arFindedElements;
void CStyleStorage::ClearPageData()
{
m_arPageDatas.clear();
}
#endif
void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles)
const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector)
{
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
if (wsSelector.empty())
return nullptr;
const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mEmbeddedStyleData);
if (nullptr != pFoundElement)
return pFoundElement;
for (std::vector<TStyleFileData*>::const_reverse_iterator itIter = m_arStyleFiles.crbegin(); itIter < m_arStyleFiles.crend(); ++itIter)
{
if (m_arAllowedStyleFiles.cend() == std::find(m_arAllowedStyleFiles.cbegin(), m_arAllowedStyleFiles.cend(), (*itIter)->m_wsStyleFilepath))
continue;
pFoundElement = FindSelectorFromStyleData(wsSelector, (*itIter)->m_mStyleData);
if (nullptr != pFoundElement)
return pFoundElement;
}
return nullptr;
}
inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet)
void CStyleStorage::AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output, mStyleData);
katana_destroy_output(output);
}
void CStyleStorage::ClearEmbeddedStyles()
{
for (std::map<std::wstring, CElement*>::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter)
if (oIter->second != nullptr)
delete oIter->second;
m_mEmbeddedStyleData.clear();
}
void CStyleStorage::ClearAllowedStyleFiles()
{
m_arAllowedStyleFiles.clear();
}
void CStyleStorage::GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData)
{
for (size_t i = 0; i < oStylesheet->imports.length; ++i)
GetRule((KatanaRule*)oStylesheet->imports.data[i]);
GetRule((KatanaRule*)oStylesheet->imports.data[i], mStyleData);
for (size_t i = 0; i < oStylesheet->rules.length; ++i)
GetRule((KatanaRule*)oStylesheet->rules.data[i]);
GetRule((KatanaRule*)oStylesheet->rules.data[i], mStyleData);
}
inline void CCssCalculator_Private::GetRule(const KatanaRule *oRule)
void CStyleStorage::GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
{
if ( NULL == oRule )
return;
@ -273,7 +251,7 @@ namespace NSCSS
switch (oRule->type) {
case KatanaRuleStyle:
{
GetStyleRule((KatanaStyleRule*)oRule);
GetStyleRule((KatanaStyleRule*)oRule, mStyleData);
break;
}
default:
@ -281,7 +259,7 @@ namespace NSCSS
}
}
inline void CCssCalculator_Private::GetStyleRule(const KatanaStyleRule *oRule)
void CStyleStorage::GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
{
if (oRule->declarations->length == 0)
return;
@ -297,7 +275,7 @@ namespace NSCSS
for (std::vector<std::wstring>::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord)
{
const size_t posPoint = oWord->find(L'.');
const size_t posPoint = oWord->find(L'.');
const size_t posLattice = oWord->find(L'#');
const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord;
@ -313,8 +291,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindId = m_mData.find(sId);
if (oFindId != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindId = mStyleData.find(sId);
if (oFindId != mStyleData.end())
{
oIdElement = oFindId->second;
bCreateFirst = false;
@ -342,8 +320,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = m_mData.find(sClass);
if (oFindClass != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = mStyleData.find(sClass);
if (oFindClass != mStyleData.end())
{
oClassElement = oFindClass->second;
bCreateFirst = false;
@ -375,8 +353,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindName = m_mData.find(sName);
if (oFindName != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindName = mStyleData.find(sName);
if (oFindName != mStyleData.end())
{
oNameElement = oFindName->second;
bCreateFirst = false;
@ -408,11 +386,16 @@ namespace NSCSS
oLastElement->AddProperties(mStyle);
if (NULL != oFirstElement)
m_mData[oFirstElement->GetSelector()] = oFirstElement;
mStyleData[oFirstElement->GetSelector()] = oFirstElement;
}
}
inline std::vector<std::wstring> CCssCalculator_Private::GetSelectorList(const KatanaArray* oSelectors) const
std::wstring CStyleStorage::GetValueList(const KatanaArray* oValues)
{
return StringifyValueList(oValues);
}
std::vector<std::wstring> CStyleStorage::GetSelectorList(const KatanaArray* oSelectors) const
{
if (oSelectors->length == 0)
return std::vector<std::wstring>();
@ -425,7 +408,7 @@ namespace NSCSS
return arSelectors;
}
inline std::wstring CCssCalculator_Private::GetSelector(const KatanaSelector *oSelector) const
std::wstring CStyleStorage::GetSelector(const KatanaSelector* oSelector) const
{
KatanaParser oParser;
oParser.options = &kKatanaDefaultOptions;
@ -444,7 +427,7 @@ namespace NSCSS
return wsText;
}
inline std::map<std::wstring, std::wstring> CCssCalculator_Private::GetDeclarationList(const KatanaArray* oDeclarations) const
std::map<std::wstring, std::wstring> CStyleStorage::GetDeclarationList(const KatanaArray* oDeclarations) const
{
if(oDeclarations->length == 0)
return std::map<std::wstring, std::wstring>();
@ -457,7 +440,7 @@ namespace NSCSS
return arDeclarations;
}
inline std::pair<std::wstring, std::wstring> CCssCalculator_Private::GetDeclaration(const KatanaDeclaration* oDecl) const
std::pair<std::wstring, std::wstring> CStyleStorage::GetDeclaration(const KatanaDeclaration* oDecl) const
{
std::wstring sValueList = StringifyValueList(oDecl->values);
@ -467,52 +450,213 @@ namespace NSCSS
return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList);
}
inline std::wstring CCssCalculator_Private::GetValueList(const KatanaArray *oValues)
void CStyleStorage::GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData)
{
return StringifyValueList(oValues);
if ( NULL == oOutput )
return;
switch (oOutput->mode) {
case KatanaParserModeStylesheet:
GetStylesheet(oOutput->stylesheet, mStyleData);
break;
case KatanaParserModeRule:
GetRule(oOutput->rule, mStyleData);
break;
case KatanaParserModeKeyframeRule:
case KatanaParserModeKeyframeKeyList:
case KatanaParserModeMediaList:
case KatanaParserModeValue:
case KatanaParserModeSelector:
case KatanaParserModeDeclarationList:
break;
}
}
const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData)
{
std::map<std::wstring, CElement*>::const_iterator itFound = mStyleData.find(wsSelector);
if (mStyleData.cend() != itFound)
return itFound->second;
return nullptr;
}
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
CCssCalculator_Private::~CCssCalculator_Private()
{}
#ifdef CSS_CALCULATOR_WITH_XHTML
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
{
//TODO:: пересмотреть данный метод
m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode);
}
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
{
return m_oStyleStorage.GetPageData(wsPageName);
}
void CCssCalculator_Private::ClearPageData()
{
m_oStyleStorage.ClearPageData();
}
#endif
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
{
std::vector<std::wstring> arNodes;
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
{
if (!oNode->m_wsName.empty())
arNodes.push_back(oNode->m_wsName);
if (!oNode->m_wsClass.empty())
{
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
{
std::vector<std::wstring> arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arNodes.push_back(L'.' + oNode->m_wsClass);
}
if (!oNode->m_wsId.empty())
arNodes.push_back(L'#' + oNode->m_wsId);
}
return arNodes;
}
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
{
if (arNextNodes.empty())
return;
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
if (!arTempPrev.empty())
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
}
std::vector<const CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
{
if (arNodes.empty())
return {};
std::vector<const CElement*> arFindedElements;
std::wstring wsName, wsId;
std::vector<std::wstring> arClasses;
if (!arNodes.empty() && arNodes.back()[0] == L'#')
{
wsId = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsId);
}
if (!arNodes.empty() && arNodes.back()[0] == L'.')
{
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
arNextNodes.push_back(arNodes.back());
arNodes.pop_back();
}
if (!arNodes.empty())
{
wsName = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsName);
}
if (!wsId.empty())
{
const CElement* pFoundId = m_oStyleStorage.FindElement(wsId);
if(nullptr != pFoundId)
{
if (!pFoundId->Empty())
arFindedElements.push_back(pFoundId);
FindPrevAndKindElements(pFoundId, arNextNodes, arFindedElements, wsName);
}
}
if (!arClasses.empty())
{
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
{
const CElement* pFoundClass = m_oStyleStorage.FindElement(*iClass);
if (nullptr != pFoundClass)
{
if (!pFoundClass->Empty())
arFindedElements.push_back(pFoundClass);
FindPrevAndKindElements(pFoundClass, arNextNodes, arFindedElements, wsName);
}
}
}
const CElement* pFoundName = m_oStyleStorage.FindElement(wsName);
if (nullptr != pFoundName)
{
if (!pFoundName->Empty())
arFindedElements.push_back(pFoundName);
FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses);
}
if (arFindedElements.size() > 1)
{
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
[](const CElement* oFirstElement, const CElement* oSecondElement)
{ return oFirstElement->GetWeight() > oSecondElement->GetWeight(); });
}
return arFindedElements;
}
#ifdef CSS_CALCULATOR_WITH_XHTML
CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector<CNode>& arSelectors, const bool& bIsSettings, const UnitMeasure& unitMeasure)
CCompiledStyle CCssCalculator_Private::GetCompiledStyle(const std::vector<CNode>& arSelectors)
{
if (arSelectors.empty())
return CCompiledStyle();
CCompiledStyle oStyle;
GetCompiledStyle(oStyle, arSelectors, bIsSettings, unitMeasure);
GetCompiledStyle(oStyle, arSelectors);
return oStyle;
}
bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors, const bool &bIsSettings, const UnitMeasure &unitMeasure)
bool CCssCalculator_Private::GetCompiledStyle(CCompiledStyle &oStyle, const std::vector<CNode> &arSelectors)
{
if (arSelectors.empty())
return false;
SetUnitMeasure(unitMeasure);
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
if (!bIsSettings)
if (oItem != m_mUsedStyles.end())
{
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
if (oItem != m_mUsedStyles.end())
{
oStyle = oItem->second;
return true;
}
}
else if (NULL == m_mStatictics || m_mStatictics->empty())
{
oStyle.SetDpi(m_nDpi);
oStyle.SetUnitMeasure(m_UnitMeasure);
oStyle.SetID(arSelectors.back().m_wsName + ((!arSelectors.back().m_wsClass.empty()) ? L'.' + arSelectors.back().m_wsClass : L"") + ((arSelectors.back().m_wsId.empty()) ? L"" : L'#' + arSelectors.back().m_wsId) + L'-' + std::to_wstring(++m_nCountNodes));
return false;
oStyle = oItem->second;
return true;
}
oStyle.SetDpi(m_nDpi);
oStyle.SetUnitMeasure(m_UnitMeasure);
std::vector<std::wstring> arNodes = CalculateAllNodes(arSelectors);
std::vector<std::wstring> arPrevNodes;
@ -535,25 +679,10 @@ namespace NSCSS
oTempStyle.AddStyle(arSelectors[i].m_mAttributes, i + 1);
for (const CElement* oElement : FindElements(arNodes, arPrevNodes, bIsSettings))
for (const CElement* oElement : FindElements(arNodes, arPrevNodes))
oTempStyle.AddStyle(oElement->GetStyle(), i + 1);
if (NULL != m_mStatictics)
{
std::map<StatistickElement, unsigned int>::const_iterator oFindCountStyle = m_mStatictics->find(StatistickElement{StatistickElement::IsStyle, arSelectors[i].m_wsStyle});
if (oFindCountStyle != m_mStatictics->end())
{
if ((bIsSettings && oFindCountStyle->second < MaxNumberRepetitions) ||
(!bIsSettings && oFindCountStyle->second >= MaxNumberRepetitions))
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
else if (!bIsSettings)
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
}
else /*if (bIsSettings)*/
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
}
else
if (!arSelectors[i].m_wsStyle.empty())
oTempStyle.AddStyle(arSelectors[i].m_wsStyle, i + 1, true);
oStyle += oTempStyle;
@ -569,7 +698,7 @@ namespace NSCSS
oStyle.SetID(CalculateStyleId(arSelectors.back()));
if (!bIsSettings && !oStyle.Empty())
if (!oStyle.Empty())
m_mUsedStyles[arSelectors] = oStyle;
return true;
@ -597,7 +726,7 @@ namespace NSCSS
SetPageData(oPageData, GetPageData(mRules[L"page"]), i + 1, true);
}
for (const CElement* oElement : FindElements(arNodes, arNextNodes, false))
for (const CElement* oElement : FindElements(arNodes, arNextNodes))
{
std::map<std::wstring, std::wstring> mRules = oElement->GetStyle();
if (mRules.end() != mRules.find(L"page"))
@ -611,42 +740,20 @@ namespace NSCSS
return true;
}
#endif
void CCssCalculator_Private::AddStyles(const std::string &sStyle)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output);
katana_destroy_output(output);
void CCssCalculator_Private::AddStyles(const std::string& sStyle)
{
m_oStyleStorage.AddStyles(sStyle);
}
void CCssCalculator_Private::AddStyles(const std::wstring &wsStyle)
void CCssCalculator_Private::AddStyles(const std::wstring& wsStyle)
{
if (wsStyle.empty())
return;
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
std::wsmatch oMatch;
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
{
AddPageData(oMatch[1].str(), oMatch[2].str());
oSearchStart = oMatch.suffix().first;
}
AddStyles(U_TO_UTF8(wsStyle));
m_oStyleStorage.AddStyles(wsStyle);
}
void CCssCalculator_Private::AddStylesFromFile(const std::wstring& wsFileName)
{
if (std::find(m_arFiles.begin(), m_arFiles.end(), wsFileName) != m_arFiles.end())
return;
m_arFiles.push_back(wsFileName);
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName));
m_oStyleStorage.AddStylesFromFile(wsFileName);
}
void CCssCalculator_Private::SetDpi(unsigned short int nValue)
@ -654,32 +761,28 @@ namespace NSCSS
m_nDpi = nValue;
}
void CCssCalculator_Private::SetBodyTree(const CTree &oTree)
{
if (NULL == m_mStatictics)
m_mStatictics = new std::map<StatistickElement, unsigned int>();
CTree::CountingNumberRepetitions(oTree, *m_mStatictics);
}
void CCssCalculator_Private::SetUnitMeasure(const UnitMeasure& nType)
{
m_UnitMeasure = nType;
}
unsigned short int CCssCalculator_Private::GetDpi() const
{
return m_nDpi;
}
const std::map<std::wstring, CElement *> *CCssCalculator_Private::GetData() const
void CCssCalculator_Private::ClearEmbeddedStyles()
{
return &m_mData;
m_oStyleStorage.ClearEmbeddedStyles();
#ifdef CSS_CALCULATOR_WITH_XHTML
m_mUsedStyles.clear();
#endif
}
UnitMeasure CCssCalculator_Private::GetUnitMeasure() const
void CCssCalculator_Private::ClearAllowedStyleFiles()
{
return m_UnitMeasure;
m_oStyleStorage.ClearAllowedStyleFiles();
}
void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath)
{
m_oStyleStorage.ClearStylesFromFile(wsFilePath);
}
std::wstring CCssCalculator_Private::GetEncoding() const
@ -691,12 +794,22 @@ namespace NSCSS
{
m_sEncoding = L"UTF-8";
m_nDpi = 96;
m_UnitMeasure = Point;
m_mData.clear();
m_arFiles.clear();
m_oStyleStorage.Clear();
#ifdef CSS_CALCULATOR_WITH_XHTML
m_mUsedStyles.clear();
#endif
}
bool IsTableElement(const std::wstring& wsNameTag)
{
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
L"th" == wsNameTag;
}
}
inline static std::wstring StringifyValueList(const KatanaArray* oValues)
{
if (NULL == oValues)
@ -797,11 +910,4 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue)
return str;
}
inline static bool IsTableElement(const std::wstring& wsNameTag)
{
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
L"th" == wsNameTag;
}

View File

@ -3,11 +3,9 @@
#include <vector>
#include <map>
#include <list>
#include <functional>
#include <set>
#include "CElement.h"
#include "ConstValues.h"
#include "CUnitMeasureConverter.h"
#include "StyleProperties.h"
#include "../../katana-parser/src/katana.h"
#ifdef CSS_CALCULATOR_WITH_XHTML
@ -16,16 +14,43 @@
namespace NSCSS
{
class CCssCalculator_Private
class CStyleStorage
{
unsigned short int m_nDpi;
unsigned short int m_nCountNodes;
UnitMeasure m_UnitMeasure;
public:
CStyleStorage();
~CStyleStorage();
std::list<std::wstring> m_arFiles;
void Clear();
std::map<std::wstring, CElement*> m_mData;
void AddStyles(const std::string& sStyle);
void AddStyles(const std::wstring& wsStyle);
void AddStylesFromFile(const std::wstring& wsFileName);
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFileName);
#ifdef CSS_CALCULATOR_WITH_XHTML
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
void ClearPageData();
#endif
const CElement* FindElement(const std::wstring& wsSelector);
private:
typedef struct
{
std::wstring m_wsStyleFilepath;
std::map<std::wstring, CElement*> m_mStyleData;
} TStyleFileData;
std::set<std::wstring> m_arEmptyStyleFiles;
std::set<std::wstring> m_arAllowedStyleFiles;
std::vector<TStyleFileData*> m_arStyleFiles;
std::map<std::wstring, CElement*> m_mEmbeddedStyleData;
#ifdef CSS_CALCULATOR_WITH_XHTML
typedef struct
{
std::vector<std::wstring> m_wsNames;
@ -33,29 +58,14 @@ namespace NSCSS
} TPageData;
std::vector<TPageData> m_arPageDatas;
std::map<StatistickElement, unsigned int> *m_mStatictics; // Количество повторений свойств id и style у селекторов
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
std::vector<CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes, bool bIsSettings);
#endif
private:
void AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData);
std::wstring m_sEncoding;
void GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData);
void GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
void GetStylesheet(const KatanaStylesheet* oStylesheet);
void GetRule(const KatanaRule* oRule);
void GetStyleRule(const KatanaStyleRule* oRule);
void GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
std::wstring GetValueList(const KatanaArray* oValues);
@ -65,36 +75,60 @@ namespace NSCSS
std::map<std::wstring, std::wstring> GetDeclarationList(const KatanaArray* oDeclarations) const;
std::pair<std::wstring, std::wstring> GetDeclaration(const KatanaDeclaration* oDecl) const;
void GetOutputData(KatanaOutput* oOutput);
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData);
};
class CCssCalculator_Private
{
unsigned short int m_nDpi;
unsigned short int m_nCountNodes;
CStyleStorage m_oStyleStorage;
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::map<std::wstring, std::wstring> GetPageData(const std::wstring &wsPageName);
#endif
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
std::wstring m_sEncoding;
public:
CCssCalculator_Private();
~CCssCalculator_Private();
#ifdef CSS_CALCULATOR_WITH_XHTML
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors, const bool& bIsSettings = false, const UnitMeasure& unitMeasure = Point);
CCompiledStyle GetCompiledStyle(const std::vector<CNode> &arSelectors);
bool GetCompiledStyle(CCompiledStyle& oStyle, const std::vector<CNode> &arSelectors);
std::wstring CalculateStyleId(const CNode& oNode);
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector<CNode> &arSelectors);
void ClearPageData();
#endif
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
std::vector<const CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
void AddStyles(const std::string& sStyle);
void AddStyles(const std::wstring& wsStyle);
void AddStylesFromFile(const std::wstring& wsFileName);
void SetUnitMeasure(const UnitMeasure& nType);
void SetDpi(unsigned short int nValue);
void SetBodyTree(const CTree &oTree);
UnitMeasure GetUnitMeasure() const;
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
const std::map<std::wstring, CElement*>* GetData() const;
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFilePath);
void Clear();
};
inline bool IsTableElement(const std::wstring& wsNameTag);
}
#endif // CCSSCALCULATOR_PRIVATE_H

View File

@ -40,6 +40,7 @@ namespace NSCSS
{
m_sSelector = sSelector;
m_sFullSelector = m_sSelector;
UpdateWeight();
}
void NSCSS::CElement::AddPropertie(const std::wstring &sName, const std::wstring& sValue)
@ -67,6 +68,7 @@ namespace NSCSS
m_arPrevElements.push_back(oPrevElement);
oPrevElement->m_sFullSelector += L' ' + m_sFullSelector;
UpdateWeight();
}
void CElement::AddKinElement(CElement *oKinElement)
@ -76,6 +78,7 @@ namespace NSCSS
m_arKinElements.push_back(oKinElement);
oKinElement->m_sFullSelector += m_sFullSelector;
oKinElement->UpdateWeight();
}
std::map<std::wstring, std::wstring> CElement::GetStyle() const
@ -230,11 +233,14 @@ namespace NSCSS
return NULL;
}
std::vector<unsigned short> CElement::GetWeight()
void CElement::UpdateWeight()
{
if (m_arWeight.empty())
m_arWeight = NS_STATIC_FUNCTIONS::GetWeightSelector(m_sFullSelector);
}
std::vector<unsigned short> CElement::GetWeight() const
{
return m_arWeight;
}

View File

@ -44,7 +44,8 @@ namespace NSCSS
CElement *FindPrevElement(const std::wstring& sSelector) const;
std::vector<unsigned short int> GetWeight();
void UpdateWeight();
std::vector<unsigned short int> GetWeight() const;
void IncreasedWeight();
};
}

View File

@ -2,29 +2,6 @@
namespace NSCSS
{
bool StatistickElement::operator<(const StatistickElement &oStatistickElement) const
{
return sValue < oStatistickElement.sValue;
}
void CTree::Clear()
{
m_arrChild.clear();
m_oNode.Clear();
}
void CTree::CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics)
{
if (!oTree.m_oNode.m_wsId.empty())
++mStatictics[StatistickElement{StatistickElement::IsId, L'#' + oTree.m_oNode.m_wsId}];
if (!oTree.m_oNode.m_wsStyle.empty())
++mStatictics[StatistickElement{StatistickElement::IsStyle, oTree.m_oNode.m_wsStyle}];
if (!oTree.m_arrChild.empty())
for (const CTree& oChildren : oTree.m_arrChild)
CountingNumberRepetitions(oChildren, mStatictics);
}
namespace NSConstValues
{
const std::map<std::wstring, std::wstring> COLORS

View File

@ -16,28 +16,6 @@ namespace NSCSS
ScalingDirectionY = 2
} ScalingDirection;
struct StatistickElement
{
enum TypeElement
{
IsStyle = 0,
IsId
} m_enType;
std::wstring sValue;
bool operator<(const StatistickElement& oStatistickElement) const;
};
struct CTree
{
NSCSS::CNode m_oNode;
std::vector<CTree> m_arrChild;
void Clear();
static void CountingNumberRepetitions(const CTree &oTree, std::map<StatistickElement, unsigned int> &mStatictics);
};
namespace NSConstValues
{
extern const std::map<std::wstring, std::wstring> COLORS;

View File

@ -48,7 +48,6 @@ namespace NS_STATIC_FUNCTIONS
if (sEncoding.empty())
sEncoding = "utf-8";
if (!sEncoding.empty() && sEncoding != "utf-8" && sEncoding != "UTF-8")
{
NSUnicodeConverter::CUnicodeConverter oConverter;

View File

@ -513,6 +513,9 @@ namespace NSCSS
return (*static_cast<std::wstring*>(m_oValue)) == (*static_cast<std::wstring*>(oColor.m_oValue));
case ColorUrl:
return (*static_cast<CURL*>(m_oValue)) == (*static_cast<CURL*>(oColor.m_oValue));
case ColorContextStroke:
case ColorContextFill:
return false;
}
}
@ -532,6 +535,9 @@ namespace NSCSS
return (*static_cast<std::wstring*>(m_oValue)) != (*static_cast<std::wstring*>(oColor.m_oValue));
case ColorUrl:
return (*static_cast<CURL*>(m_oValue)) != (*static_cast<CURL*>(oColor.m_oValue));
case ColorContextStroke:
case ColorContextFill:
return false;
}
}
@ -561,6 +567,9 @@ namespace NSCSS
m_oValue = new CURL(*static_cast<CURL*>(oColor.m_oValue));
break;
}
case ColorContextStroke:
case ColorContextFill:
break;
}
return *this;
@ -580,6 +589,39 @@ namespace NSCSS
: CValue(NULL, 0, false), m_oOpacity(1.), m_enType(ColorEmpty)
{}
CColor::CColor(const CColor& oColor)
: CValue(NULL, 0, false), m_oOpacity(oColor.m_oOpacity), m_enType(oColor.m_enType)
{
switch (m_enType)
{
case ColorRGB:
{
TRGB *pRGB = static_cast<TRGB*>(oColor.m_oValue);
m_oValue = new TRGB(*pRGB);
break;
}
case ColorHEX:
{
std::wstring* pValue = static_cast<std::wstring*>(oColor.m_oValue);
m_oValue = new std::wstring(*pValue);
break;
}
case ColorUrl:
{
CURL *pURL = static_cast<CURL*>(oColor.m_oValue);
m_oValue = new CURL(*pURL);
break;
}
default:
break;
}
}
CColor::~CColor()
{
Clear();
}
void CColor::SetEmpty(unsigned int unLevel)
{
Clear();
@ -875,6 +917,25 @@ namespace NSCSS
}
}
std::wstring CColor::ToHEX() const
{
switch(m_enType)
{
case ColorRGB:
{
TRGB* pRGB = static_cast<TRGB*>(m_oValue);
return ConvertRGBtoHEX(*pRGB);
}
case ColorHEX:
{
std::wstring *pValue = static_cast<std::wstring*>(m_oValue);
return *pValue;
}
default:
return std::wstring();
}
}
std::wstring CColor::EquateToColor(const std::vector<std::pair<TRGB, std::wstring>> &arColors) const
{
if (arColors.empty())

View File

@ -224,6 +224,8 @@ namespace NSCSS
{
public:
CColor();
CColor(const CColor& oColor);
~CColor();
bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override;
bool SetOpacity(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true);
@ -240,6 +242,7 @@ namespace NSCSS
int ToInt() const override;
double ToDouble() const override;
std::wstring ToWString() const override;
std::wstring ToHEX() const;
std::wstring EquateToColor(const std::vector<std::pair<TRGB, std::wstring>>& arColors) const;
TRGB ToRGB() const;

View File

@ -316,7 +316,7 @@ namespace NSCSS
std::wstring wsTextAlign{oStyle.m_oText.GetAlign().ToWString()};
if (wsTextAlign.empty() && bInTable)
if (wsTextAlign.empty())
wsTextAlign = oStyle.m_oDisplay.GetHAlign().ToWString();
oXmlElement.AddPropertiesInP(PProperties::P_Jc, wsTextAlign);
@ -485,7 +485,7 @@ namespace NSCSS
return;
if (!oStyle.m_oFont.GetSize().Empty())
oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast<int>(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. + 0.5))); // Значения шрифта увеличивает на 2
oXmlElement.AddPropertiesInR(RProperties::R_Sz, std::to_wstring(static_cast<int>(oStyle.m_oFont.GetSize().ToDouble(NSCSS::Point) * 2. * oStyle.m_oTransform.GetMatrix().GetFinalValue().sy() + 0.5))); // Значения шрифта увеличивает на 2
if (oStyle.m_oText.GetDecoration().m_oLine.Underline())
oXmlElement.AddPropertiesInR(RProperties::R_U, (!oStyle.m_oText.GetDecoration().m_oStyle.Empty()) ? oStyle.m_oText.GetDecoration().m_oStyle.ToWString() : L"single");

View File

@ -905,6 +905,10 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName)
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
else if (0 == sExt.compare(L".key"))
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
else if (0 == sExt.compare(L".hwp"))
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP;
else if (0 == sExt.compare(L".hwpx"))
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX;
if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN)
return true;

View File

@ -57,6 +57,8 @@
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0016
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM_PDF AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0017
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0018
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0019
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HWPX AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0020
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_XML AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0030

View File

@ -4,6 +4,7 @@
#include <stdio.h>
#define LOG_BUFFER_SIZE 1000
// not intended for use in production. only for testing/debugging purposes
namespace Logging
{
void logBytes(char* name, unsigned char* str, int len)

View File

@ -0,0 +1,60 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef DOC_BUILDER_ADDON_PRIVATE
#define DOC_BUILDER_ADDON_PRIVATE
#include <string>
namespace NSDoctRenderer
{
class CDocBuilderAddon
{
private:
std::wstring m_sWorkDirectory;
public:
CDocBuilderAddon(const std::wstring& sWorkDir)
{
m_sWorkDirectory = sWorkDir;
}
public:
std::wstring GetX2tSaveAddon()
{
return L"";
}
int GetX2tPreSaveError()
{
return 0;
}
};
}
#endif // DOC_BUILDER_ADDON_PRIVATE

View File

@ -38,6 +38,9 @@
#include "../xml/include/xmlutils.h"
#include "../fontengine/TextHyphen.h"
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
namespace NSDoctRenderer
{
class CAdditionalData
@ -203,28 +206,14 @@ namespace NSDoctRenderer
char* GetVersion()
{
std::wstring sFile = m_strSdkPath + L"/word/sdk-all-min.js";
std::string sVersion = VALUE(INTVER);
std::string sData;
if (!NSFile::CFileBinary::ReadAllTextUtf8A(sFile, sData))
return NULL;
std::string::size_type startPos = sData.find("Version:");
if (std::string::npos == startPos)
return NULL;
startPos += 8;
std::string::size_type endPos = sData.find(')', startPos);
if (std::string::npos == endPos)
return NULL;
size_t sSrcLen = endPos - startPos + 1;
size_t sSrcLen = sVersion.size();
if (sSrcLen == 0)
return NULL;
char* sRet = new char[sSrcLen + 1];
memcpy(sRet, sData.c_str() + startPos, sSrcLen);
memcpy(sRet, sVersion.c_str(), sSrcLen);
sRet[sSrcLen] = '\0';
return sRet;
}

View File

@ -240,6 +240,14 @@ bool CV8RealTimeWorker::InitVariables()
if (try_catch->Check())
return false;
}
if (!m_sJSCodeStart.empty())
{
m_context->runScript(m_sJSCodeStart, try_catch);
if (try_catch->Check())
return false;
}
return true;
}

View File

@ -63,6 +63,8 @@
#include "../common/ProcessEnv.h"
#include "docbuilder_addon.h"
#ifdef CreateFile
#undef CreateFile
#endif
@ -422,6 +424,7 @@ public:
int m_nFileType;
std::string m_sUtf8ArgumentJSON;
std::string m_sGlobalVariable;
std::string m_sJSCodeStart;
CJSContextData m_oContextData;
@ -455,7 +458,8 @@ namespace NSDoctRenderer
std::wstring m_sTmpFolder;
std::wstring m_sFileDir;
int m_nFileType;
bool m_bJavascriptBeforeEditor;
std::wstring m_sCommandsBeforeContextCreated;
std::wstring m_sX2tPath;
@ -478,7 +482,7 @@ namespace NSDoctRenderer
public:
CDocBuilder_Private() : CDoctRendererConfig(), m_sTmpFolder(NSFile::CFileBinary::GetTempPath()), m_nFileType(-1),
m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsServerSafeVersion(false),
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_bJavascriptBeforeEditor(false)
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_sCommandsBeforeContextCreated(L"")
{
}
@ -639,9 +643,6 @@ namespace NSDoctRenderer
NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
}
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return bRet;
#else
std::wstring sPath = m_sX2tPath + L"/empty/new.";
@ -930,11 +931,7 @@ namespace NSDoctRenderer
LOGGER_SPEED_LAP("open_convert");
if (0 == nReturnCode)
{
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return 0;
}
NSDirectory::DeleteDirectory(m_sFileDir);
m_sFileDir = L"";
@ -985,6 +982,12 @@ namespace NSDoctRenderer
{
Init();
CDocBuilderAddon oSaveAddon(m_sX2tPath);
int nPreSaveError = oSaveAddon.GetX2tPreSaveError();
if (0 != nPreSaveError)
return nPreSaveError;
if (-1 == m_nFileType)
{
CV8RealTimeWorker::_LOGGING_ERROR_(L"error (save)", L"file not opened!");
@ -1068,6 +1071,8 @@ namespace NSDoctRenderer
if (!sOptions.empty())
oBuilder.WriteString(UTF8_TO_U(sOptions));
oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon());
oBuilder.WriteString(L"</TaskQueueDataConvert>");
std::wstring sXmlConvert = oBuilder.GetData();
@ -1220,36 +1225,27 @@ namespace NSDoctRenderer
{
if (NULL == m_pWorker)
{
m_pWorker = new CV8RealTimeWorker(m_pParent, GetEditorType(), this);
NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType();
if (NSDoctRenderer::DoctRendererEditorType::INVALID == editorType)
return false;
m_pWorker = new CV8RealTimeWorker(m_pParent, editorType, this);
m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON;
m_pWorker->m_sGlobalVariable = m_sGlobalVariable;
m_pWorker->m_sJSCodeStart = U_TO_UTF8(m_sCommandsBeforeContextCreated);
m_sCommandsBeforeContextCreated = L"";
return CheckWorkerAfterOpen();
m_pWorker->m_nFileType = m_nFileType;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, editorType, this, &oParams);
}
return true;
}
bool CheckWorkerAfterOpen()
{
if (!m_pWorker)
return false;
m_pWorker->m_nFileType = m_nFileType;
if (-1 == m_nFileType)
{
m_bJavascriptBeforeEditor = true;
return false;
}
m_bJavascriptBeforeEditor = false;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetEditorType(), this, &oParams);
}
int SaveFile(const std::wstring& ext, const std::wstring& path, const wchar_t* params = NULL)
{
int nType = GetFormatByTexExtention(ext);
@ -1261,21 +1257,26 @@ namespace NSDoctRenderer
if (command.length() < 7 && !retValue) // minimum command (!!!)
return true;
if (m_nFileType == -1)
{
m_sCommandsBeforeContextCreated += command;
return true;
}
Init();
bool bRes = CheckWorker();
if (CheckWorker())
return m_pWorker->ExecuteCommand(command, retValue);
if (!bRes && m_pWorker && m_bJavascriptBeforeEditor)
m_pWorker->InitVariables();
return m_pWorker->ExecuteCommand(command, retValue);
return false;
}
CDocBuilderContext GetContext(bool enterContext)
{
CDocBuilderContext ctx;
CheckWorker();
if (!CheckWorker())
return ctx;
ctx.m_internal->m_context = m_pWorker->m_context;
ctx.m_internal->m_context_data = &m_pWorker->m_oContextData;

View File

@ -0,0 +1,130 @@
QT -= core
QT -= gui
VERSION = 1.0.0.3
TARGET = doctrenderer
TEMPLATE = lib
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
PWD_CUR = $$PWD
include($$PWD_CUR/../../Common/base.pri)
DEFINES += DOCTRENDERER_USE_DYNAMIC_LIBRARY_BUILDING
DEFINES += JSBASE_USE_DYNAMIC_LIBRARY_BUILDING
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network)
#CONFIG += build_xp
#CONFIG += v8_version_60
core_android:DEFINES += DISABLE_MEMORY_LIMITATION
HEADERS += \
$$PWD_CUR/config.h \
$$PWD_CUR/editors.h \
$$PWD_CUR/doctrenderer.h \
$$PWD_CUR/docbuilder.h
SOURCES += \
$$PWD_CUR/editors.cpp \
$$PWD_CUR/nativecontrol.cpp \
$$PWD_CUR/doctrenderer.cpp \
$$PWD_CUR/docbuilder.cpp \
$$PWD_CUR/docbuilder_p.cpp \
$$PWD_CUR/graphics.cpp \
$$PWD_CUR/hash.cpp
SOURCES += \
$$PWD_CUR/../../Common/OfficeFileFormatChecker2.cpp \
$$PWD_CUR/../../Common/3dParty/pole/pole.cpp \
$$PWD_CUR/../../OOXML/Base/unicode_util.cpp
HEADERS += \
$$PWD_CUR/docbuilder_p.h \
$$PWD_CUR/nativecontrol.h \
$$PWD_CUR/graphics.h \
$$PWD_CUR/hash.h \
$$PWD_CUR/server.h
HEADERS += \
$$PWD_CUR/embed/PointerEmbed.h \
$$PWD_CUR/embed/ZipEmbed.h \
$$PWD_CUR/embed/GraphicsEmbed.h \
$$PWD_CUR/embed/MemoryStreamEmbed.h \
$$PWD_CUR/embed/NativeControlEmbed.h \
$$PWD_CUR/embed/NativeBuilderEmbed.h \
$$PWD_CUR/embed/NativeBuilderDocumentEmbed.h \
$$PWD_CUR/embed/TextMeasurerEmbed.h \
$$PWD_CUR/embed/HashEmbed.h \
$$PWD_CUR/embed/Default.h \
$$PWD_CUR/js_internal/js_base.h
SOURCES += \
$$PWD_CUR/embed/PointerEmbed.cpp \
$$PWD_CUR/embed/ZipEmbed.cpp \
$$PWD_CUR/embed/GraphicsEmbed.cpp \
$$PWD_CUR/embed/MemoryStreamEmbed.cpp \
$$PWD_CUR/embed/NativeControlEmbed.cpp \
$$PWD_CUR/embed/NativeBuilderEmbed.cpp \
$$PWD_CUR/embed/NativeBuilderDocumentEmbed.cpp \
$$PWD_CUR/embed/TextMeasurerEmbed.cpp \
$$PWD_CUR/embed/HashEmbed.cpp \
$$PWD_CUR/embed/Default.cpp
# Serialize objects to JS
HEADERS += \
$$PWD_CUR/json/json.h \
$$PWD_CUR/json/json_p.h \
$$PWD_CUR/json/json_values.h \
$$PWD_CUR/json/serialization.h
SOURCES += \
$$PWD_CUR/json/json.cpp \
$$PWD_CUR/json/json_values.cpp
include($$PWD_CUR/js_internal/js_base.pri)
!use_javascript_core {
build_xp:DESTDIR=$$DESTDIR/xp
}
use_javascript_core {
OBJECTIVE_SOURCES += $$PWD_CUR/../common/Mac/NSString+StringUtils.mm
}
# files for embedded classes
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/GraphicsEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/HashEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/MemoryStreamEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/NativeBuilderEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/NativeBuilderDocumentEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/NativeControlEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/PointerEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/TextMeasurerEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/ZipEmbed.h)
include($$PWD_CUR/../graphics/pro/textshaper.pri)
include($$PWD_CUR/../../Common/3dParty/openssl/openssl.pri)
# downloader
DEFINES += BUIDLER_OPEN_DOWNLOAD_ENABLED
DEFINES += BUIDLER_OPEN_BASE64_ENABLED
CONFIG += drawingfile_support
drawingfile_support {
DEFINES += WASM_SERIALIZER_USE_ALLOCATOR
ADD_DEPENDENCY(PdfFile, XpsFile, DjVuFile, DocxRenderer)
HEADERS += \
$$PWD_CUR/drawingfile.h \
$$PWD_CUR/embed/DrawingFileEmbed.h
SOURCES += \
$$PWD_CUR/../graphics/pro/js/wasm/src/HTMLRendererText.cpp \
$$PWD_CUR/embed/DrawingFileEmbed.cpp
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER($$PWD_CUR/embed/DrawingFileEmbed.h)
}

View File

@ -1,128 +1,3 @@
QT -= core
QT -= gui
INCLUDEPATH += $$PWD/addon
VERSION = 1.0.0.3
TARGET = doctrenderer
TEMPLATE = lib
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/../..
PWD_ROOT_DIR = $$PWD
include(../../Common/base.pri)
DEFINES += DOCTRENDERER_USE_DYNAMIC_LIBRARY_BUILDING
DEFINES += JSBASE_USE_DYNAMIC_LIBRARY_BUILDING
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network)
#CONFIG += build_xp
#CONFIG += v8_version_60
core_android:DEFINES += DISABLE_MEMORY_LIMITATION
HEADERS += \
config.h \
editors.h \
doctrenderer.h \
docbuilder.h
SOURCES += \
editors.cpp \
nativecontrol.cpp \
doctrenderer.cpp \
docbuilder.cpp \
docbuilder_p.cpp \
graphics.cpp \
hash.cpp
SOURCES += \
../../Common/OfficeFileFormatChecker2.cpp \
../../Common/3dParty/pole/pole.cpp \
../../OOXML/Base/unicode_util.cpp
HEADERS += \
docbuilder_p.h \
nativecontrol.h \
graphics.h \
hash.h \
server.h
HEADERS += \
embed/PointerEmbed.h \
embed/ZipEmbed.h \
embed/GraphicsEmbed.h \
embed/MemoryStreamEmbed.h \
embed/NativeControlEmbed.h \
embed/NativeBuilderEmbed.h \
embed/NativeBuilderDocumentEmbed.h \
embed/TextMeasurerEmbed.h \
embed/HashEmbed.h \
embed/Default.h \
js_internal/js_base.h
SOURCES += \
embed/PointerEmbed.cpp \
embed/ZipEmbed.cpp \
embed/GraphicsEmbed.cpp \
embed/MemoryStreamEmbed.cpp \
embed/NativeControlEmbed.cpp \
embed/NativeBuilderEmbed.cpp \
embed/NativeBuilderDocumentEmbed.cpp \
embed/TextMeasurerEmbed.cpp \
embed/HashEmbed.cpp \
embed/Default.cpp
# Serialize objects to JS
HEADERS += \
json/json.h \
json/json_p.h \
json/json_values.h \
json/serialization.h
SOURCES += \
json/json.cpp \
json/json_values.cpp
include($$PWD/js_internal/js_base.pri)
!use_javascript_core {
build_xp:DESTDIR=$$DESTDIR/xp
}
use_javascript_core {
OBJECTIVE_SOURCES += ../common/Mac/NSString+StringUtils.mm
}
# files for embedded classes
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/GraphicsEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/HashEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/MemoryStreamEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/NativeBuilderEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/NativeBuilderDocumentEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/NativeControlEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/PointerEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/TextMeasurerEmbed.h)
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/ZipEmbed.h)
include(../graphics/pro/textshaper.pri)
include(../../Common/3dParty/openssl/openssl.pri)
# downloader
DEFINES += BUIDLER_OPEN_DOWNLOAD_ENABLED
DEFINES += BUIDLER_OPEN_BASE64_ENABLED
CONFIG += drawingfile_support
drawingfile_support {
DEFINES += WASM_SERIALIZER_USE_ALLOCATOR
ADD_DEPENDENCY(PdfFile, XpsFile, DjVuFile, DocxRenderer)
HEADERS += \
drawingfile.h \
embed/DrawingFileEmbed.h
SOURCES += \
../graphics/pro/js/wasm/src/HTMLRendererText.cpp \
embed/DrawingFileEmbed.cpp
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/DrawingFileEmbed.h)
}
include(doctrenderer.pri)

View File

@ -6,16 +6,16 @@ namespace NSDoctRenderer
{
namespace
{
void AppendScript(NSStringUtils::CStringBuilderA* builder, const std::wstring& path)
bool AppendScript(NSStringUtils::CStringBuilderA* builder, const std::wstring& path, const std::string& header = "", const std::string& footer = "")
{
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(path))
return;
return false;
int size = (int)oFile.GetFileSize();
if (size < 3)
return;
return false;
BYTE* pData = new BYTE[size];
DWORD dwReadSize = 0;
@ -26,9 +26,18 @@ namespace NSDoctRenderer
if (pData[0] == 0xEF && pData[1] == 0xBB && pData[2] == 0xBF)
nOffset = 3;
if (!header.empty())
builder->WriteString(header);
builder->WriteString((char*)(pData + nOffset), size - nOffset);
if (!footer.empty())
builder->WriteString(footer);
builder->WriteString("\n\n");
RELEASEARRAYOBJECTS(pData);
return true;
}
bool RunScript(JSSmart<NSJSBase::CJSContext>& context, JSSmart<NSJSBase::CJSTryCatch>& try_catch, const std::wstring& path)
@ -114,6 +123,7 @@ namespace NSDoctRenderer
AppendScript(builder, sFontsPath);
AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all.js");
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/engine/drawingfile_native.js");
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/annotations/stamps.json", "window[\"native_pdf_stamps\"]=", ";");
sCachePath = config->m_strSdkPath + L"/pdf/sdk-all";
break;
}

View File

@ -1,5 +1,6 @@
#include "DrawingFileEmbed.h"
#include "../drawingfile.h"
#include "../../raster/BgraFrame.h"
JSSmart<CJSValue> WasmMemoryToJS(BYTE* pWasmData)
{

View File

@ -258,3 +258,64 @@ JSSmart<CJSValue> CZipEmbed::getImageType(JSSmart<CJSValue> typedArray)
oBuffer.Free();
return CJSContext::createInt(bIsImageFile ? oChecker.eFileType : 0);
}
JSSmart<CJSValue> CZipEmbed::getImageBuffer(JSSmart<CJSValue> filePath)
{
if (!m_pFolder || !filePath->isString())
return CJSContext::createNull();
std::wstring sFilePath = filePath->toStringW();
IFolder::CBuffer* pBuffer;
if (!m_pFolder->read(sFilePath, pBuffer))
return CJSContext::createNull();
size_t nBufferSize = (size_t)pBuffer->Size;
CImageFileFormatChecker oChecker;
bool bIsImageFile = oChecker.isImageFile(pBuffer->Buffer, (DWORD)pBuffer->Size);
if (!bIsImageFile)
{
RELEASEOBJECT(pBuffer);
return CJSContext::createNull();
}
bool bIsNeedConvertMetfileToSvg = false;
// Make as wasm module
if (oChecker.eFileType == _CXIMAGE_FORMAT_WMF || oChecker.eFileType == _CXIMAGE_FORMAT_EMF)
oChecker.eFileType = _CXIMAGE_FORMAT_SVG;
else
bIsNeedConvertMetfileToSvg = false;
if (!bIsNeedConvertMetfileToSvg)
{
BYTE* pMemory = NSJSBase::NSAllocator::Alloc(nBufferSize);
memcpy(pMemory, pBuffer->Buffer, nBufferSize);
RELEASEOBJECT(pBuffer);
JSSmart<CJSObject> retObject = CJSContext::createObject();
retObject->set("type", CJSContext::createInt(oChecker.eFileType));
retObject->set("data", NSJSBase::CJSContext::createUint8Array(pMemory, (int)nBufferSize, false));
return retObject->toValue();
}
#ifndef GRAPHICS_DISABLE_METAFILE
MetaFile::IMetaFile* pMetaFile = MetaFile::Create(NULL);
pMetaFile->LoadFromBuffer(pBuffer->Buffer, (unsigned int)pBuffer->Size);
std::wstring wsSvg = pMetaFile->ConvertToSvg();
std::string sSvg = U_TO_UTF8(wsSvg);
pMetaFile->Release();
RELEASEOBJECT(pBuffer);
BYTE* pData = NSAllocator::Alloc(sSvg.length());
memcpy(pData, sSvg.c_str(), sSvg.length());
JSSmart<CJSObject> retObject = CJSContext::createObject();
retObject->set("type", CJSContext::createInt(24));
retObject->set("data", NSJSBase::CJSContext::createUint8Array(pData, sSvg.length(), false));
return retObject->toValue();
#else
return CJSContext::createNull();
#endif
}

View File

@ -36,6 +36,7 @@ public:
JSSmart<CJSValue> encodeImageData(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> w, JSSmart<CJSValue> h, JSSmart<CJSValue> stride, JSSmart<CJSValue> format, JSSmart<CJSValue> isRgba);
JSSmart<CJSValue> encodeImage(JSSmart<CJSValue> typedArray, JSSmart<CJSValue> format);
JSSmart<CJSValue> getImageType(JSSmart<CJSValue> typedArray);
JSSmart<CJSValue> getImageBuffer(JSSmart<CJSValue> path);
DECLARE_EMBED_METHODS
};

View File

@ -17,6 +17,7 @@
-(JSValue*) encodeImageData : (JSValue*)typedArray : (JSValue*)w : (JSValue*)h : (JSValue*)stride : (JSValue*)format : (JSValue*)isRgba;
-(JSValue*) encodeImage : (JSValue*)typedArray : (JSValue*)format;
-(JSValue*) getImageType : (JSValue*)typedArray;
-(JSValue*) getImageBuffer : (JSValue*)path;
@end
@interface CJSCZipEmbed : NSObject<IJSCZipEmbed, JSEmbedObjectProtocol>
@ -41,6 +42,7 @@ FUNCTION_WRAPPER_JS_2(decodeImage, decodeImage)
FUNCTION_WRAPPER_JS_6(encodeImageData, encodeImageData)
FUNCTION_WRAPPER_JS_2(encodeImage, encodeImage)
FUNCTION_WRAPPER_JS_1(getImageType, getImageType)
FUNCTION_WRAPPER_JS_1(getImageBuffer, getImageBuffer)
@end
class CZipEmbedAdapter : public CJSEmbedObjectAdapterJSC

View File

@ -20,6 +20,7 @@ namespace NSZipEmbed
FUNCTION_WRAPPER_V8_6(_encodeImageData, encodeImageData)
FUNCTION_WRAPPER_V8_2(_encodeImage, encodeImage)
FUNCTION_WRAPPER_V8_1(_getImageType, getImageType)
FUNCTION_WRAPPER_V8_1(_getImageBuffer, getImageBuffer)
v8::Handle<v8::ObjectTemplate> CreateTemplate(v8::Isolate* isolate)
{
@ -39,6 +40,7 @@ namespace NSZipEmbed
NSV8Objects::Template_Set(result, "encodeImageData", _encodeImageData);
NSV8Objects::Template_Set(result, "encodeImage", _encodeImage);
NSV8Objects::Template_Set(result, "getImageType", _getImageType);
NSV8Objects::Template_Set(result, "getImageBuffer", _getImageBuffer);
return handle_scope.Escape(result);
}

View File

@ -374,7 +374,7 @@ namespace NSJSBase
JSSmart<CJSContext> CJSContext::GetCurrent()
{
CJSContext* ret = new CJSContext();
CJSContext* ret = new CJSContext(false);
ret->m_internal->context = NSJSBase::CJSContextPrivate::GetCurrentContext();
return ret;
}

View File

@ -356,6 +356,8 @@ public:
virtual void Check(const int& nCode, const unsigned int& nIndex)
{
if (nCode > m_nMaxSymbols)
return;
if (nCode > m_nMax)
m_nMax = nCode;
if (nCode < m_nMin)
@ -794,6 +796,8 @@ public:
std::wstring sNameCorrect = pPair->second.m_sName;
NSStringUtils::string_replace(sNameCorrect, L"\\", L"\\\\");
NSStringUtils::string_replace(sNameCorrect, L"\"", L"\\\"");
NSStringUtils::string_replace(sNameCorrect, L"\n", L"");
NSStringUtils::string_replace(sNameCorrect, L"\r", L"");
oWriterJS += sNameCorrect;
oWriterJS.AddSize(120);

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
@ -531,6 +531,45 @@ ZLib.prototype.getImageAsSvg = function(path)
return string;
};
/**
* Get image file raw data. this memory was copied and detach from archive.
* @returns {Uint8Array}
*/
ZLib.prototype.getImageBuffer = function(path)
{
let result = {
type : 0,
data : null
};
result.type = this.getImageType(path);
if (result.type === 0)
return null;
let fileData = this.getFile(path);
result.data = new Uint8Array(fileData.length);
result.data.set(fileData);
if (result.type != 10 &&
result.type != 21)
{
return result;
}
result.type = 24;
// Source was saved as result.data for using original image in native convertations.
// But for js we need svg for metafiles.
let encodedData = Module["_Raster_Encode"](this.files[path].p + 4, fileData.length, 24);
let encodedSize = Module["_Raster_GetEncodedSize"](encodedData);
let encodedBuffer = Module["_Raster_GetEncodedBuffer"](encodedData);
let fileDataEnc = new Uint8Array(Module["HEAP8"].buffer, encodedBuffer, encodedSize);
result.dataBlob = new Uint8Array(fileDataEnc.length);
result.dataBlob.set(fileDataEnc);
Module["_Raster_DestroyEncodedData"](encodedData);
return result;
};
/**
* Get image blob for browser
* @returns {Blob}

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
@ -35,7 +35,7 @@
window['AscFonts'] = window['AscFonts'] || {};
var AscFonts = window['AscFonts'];
var g_native_engine = CreateEmbedObject("CTextMeasurerEmbed");
var g_native_engine = null;
function CReturnObject()
{
@ -236,4 +236,6 @@ AscFonts.Hyphen_Word = function(lang, word)
AscFonts.onLoadModule();
AscFonts.onLoadModule();
window["InitNativeTextMeasurer"] = function() { g_native_engine = CreateEmbedObject("CTextMeasurerEmbed"); };
})(window, undefined);

View File

@ -100,6 +100,7 @@
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
"GRAPHICS_NO_USE_DYNAMIC_LIBRARY",
"HYPHEN_ENGINE_DISABLE_FILESYSTEM",
"METAFILE_DISABLE_FILESYSTEM",
"HAVE_UNISTD_H", "HAVE_FCNTL_H", "_ARM_ALIGN_",
"METAFILE_SUPPORT_WMF_EMF",

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
@ -761,6 +761,14 @@ function onLoadFontsModule(window, undefined)
{
return this.engine["getImageBlob"](path);
};
/**
* Get image file raw data. this memory was copied and detach from archive.
* @returns {Uint8Array}
*/
ZLib.prototype.getImageBuffer = function(path)
{
return this.engine["getImageBuffer"](path);
};
/**
* Get all file paths in archive
* @returns {Array}
@ -772,10 +780,84 @@ function onLoadFontsModule(window, undefined)
AscCommon.ZLib = ZLib;
function ZlibImageBlobs()
{
this.url2BlobUrl = {};
this.blobUrl2Data = {};
this.url2Base64 = {};
this.nativeBlobCounter = 1;
}
ZlibImageBlobs.prototype.getBlobUrl = function(path, zip)
{
if (this.url2BlobUrl[path])
return this.url2BlobUrl[path];
let result = zip.getImageBuffer(path);
if (result == null)
return "";
let blobUrl = "";
let blobType = AscCommon.openXml.GetMimeType((24 !== result["type"]) ? AscCommon.GetFileExtension(path) : "svg");
if (window["NATIVE_EDITOR_ENJINE"])
{
blobUrl = "blob:internal-image" + this.nativeBlobCounter++;
}
else
{
try
{
let blob = new Blob([result["dataBlob"] ? result["dataBlob"] : result["data"]], {type: blobType});
blobUrl = window.URL.createObjectURL(blob);
}
catch (e)
{
blobUrl = "error";
AscCommon.consoleLog("ERROR: Image blob was not loaded");
}
}
this.blobUrl2Data[blobUrl] = result;
this.url2BlobUrl[path] = blobUrl;
return blobUrl;
};
ZlibImageBlobs.prototype.getImageBase64 = function(url)
{
if (this.url2Base64[url])
return this.url2Base64[url];
let obj = this.blobUrl2Data[url];
if (!obj)
return url;
let header = "";
switch (obj.type)
{
case 3:
header = "data:image/jpeg;base64,";
break;
case 24:
header = "data:image/svg+xml;base64,";
break;
case 4:
default:
header = "data:image/png;base64,";
}
this.url2Base64[url] = header + AscCommon.Base64.encode(obj.data);
return this.url2Base64[url];
};
window["AscCommon"].g_oDocumentBlobUrls = new ZlibImageBlobs();
if (AscCommon["CZLibEngineJS"])
AscCommon["CZLibEngineJS"].prototype["isModuleInit"] = true;
window.nativeZlibEngine = new ZLib();
if (window["NATIVE_EDITOR_ENJINE"])
window["InitNativeZLib"] = function() { window.nativeZlibEngine = new ZLib(); };
else
window.nativeZlibEngine = new ZLib();
function Hyphenation()
{

View File

@ -191,6 +191,16 @@ namespace Aggplus
{
}
CClipMulti::clip_rasterizer* CClipMulti::GetRasterizer()
{
if (!m_bIsClip)
{
m_rasterizer.reset();
return &m_rasterizer;
}
return NULL;
}
void CClipMulti::Create(LONG width, LONG height)
{
m_lWidth = width;
@ -212,62 +222,52 @@ namespace Aggplus
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
m_rasterizer.add_path(c_c_path);
m_rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
GenerateClip2(pPath->m_internal->m_bEvenOdd);
}
void CClipMulti::GenerateClip2(bool bEvenOdd)
{
m_rasterizer.filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
m_bIsClip = true;
m_bIsClip2 = false;
}
void CClipMulti::Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op)
void CClipMulti::Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer)
{
if (!pRasterizer)
return;
if (!m_bIsClip)
return GenerateClip(pPath, pMatrix);
return GenerateClip2(bEvenOdd);
if (!m_bIsClip2)
{
// смешивать надо с растерайзером
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
rasterizer.clip_box(0, 0, m_lWidth, m_lHeight);
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
rasterizer.add_path(c_c_path);
rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, m_rasterizer, rasterizer, sl1, sl2, sl, m_storage1);
agg::sbool_combine_shapes_aa(op, m_rasterizer, *pRasterizer, sl1, sl2, sl, m_storage1);
m_lCurStorage = 1;
}
else
{
// надо смешивать со стораджем
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
rasterizer.clip_box(0, 0, m_lWidth, m_lHeight);
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_internal->m_agg_ps, pMatrix->m_internal->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
rasterizer.add_path(c_c_path);
rasterizer.filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
pRasterizer->filling_rule(op ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, rasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
agg::sbool_combine_shapes_aa(op, *pRasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
(m_lCurStorage == 1) ? m_storage2 : m_storage1);
if (1 == m_lCurStorage)

View File

@ -138,10 +138,11 @@ public:
class CClipMulti
{
typedef agg::scanline_p8 scanline_type;
public:
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> m_rasterizer;
typedef agg::scanline_p8 scanline_type;
typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> clip_rasterizer;
clip_rasterizer m_rasterizer;
agg::scanline_storage_aa8 m_storage1;
agg::scanline_storage_aa8 m_storage2;
@ -158,10 +159,13 @@ public:
CClipMulti();
~CClipMulti();
clip_rasterizer* GetRasterizer();
void Create(LONG width, LONG height);
void GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix);
void GenerateClip2(bool bEvenOdd);
void Combine(CGraphicsPath* pPath, CMatrix* pMatrix, agg::sbool_op_e op);
void Combine(bool bEvenOdd, agg::sbool_op_e op, clip_rasterizer* pRasterizer);
bool IsClip();
bool IsClip2();

View File

@ -502,18 +502,41 @@ namespace Aggplus
return Ok;
}
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op)
Status CGraphics::CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen)
{
Aggplus::CMatrix m;
return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op);
return InternalClip(pPath, (m_bIntegerGrid || pPath->m_internal->m_pTransform != NULL) ? &m : &m_oFullTransform, op, pPen);
}
Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op)
Status CGraphics::InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen)
{
if (NULL == pPath)
return InvalidParameter;
m_oClip.Combine(pPath, pTransform, op);
bool bTempRasterizer = false;
CClipMulti::clip_rasterizer* pRasterizer = m_oClip.GetRasterizer();
if (!pRasterizer)
{
pRasterizer = new CClipMulti::clip_rasterizer();
pRasterizer->clip_box(0, 0, m_oClip.m_lWidth, m_oClip.m_lHeight);
bTempRasterizer = true;
}
agg::trans_affine* pAffine = NULL;
if (pPen)
pAffine = DoStrokePath(pPen, pPath, pRasterizer);
else
{
typedef agg::conv_transform<agg::path_storage> trans_type;
trans_type trans(pPath->m_internal->m_agg_ps, pTransform->m_internal->m_agg_mtx);
typedef agg::conv_curve<trans_type> conv_crv_type;
conv_crv_type c_c_path(trans);
pRasterizer->add_path(c_c_path);
}
m_oClip.Combine(pPath->m_internal->m_bEvenOdd, op, pRasterizer);
// write to clips history
CGraphics_ClipStateRecord* pRecord = new CGraphics_ClipStateRecord();
@ -522,6 +545,11 @@ namespace Aggplus
pRecord->Operation = op;
m_oClipState.AddRecord(pRecord);
if (pAffine)
delete pAffine;
if (bTempRasterizer)
delete pRasterizer;
return Ok;
}
@ -610,180 +638,7 @@ namespace Aggplus
m_rasterizer.get_rasterizer().reset();
agg::line_join_e LineJoin = agg::round_join;
switch(pPen->LineJoin)
{
case LineJoinMiter : LineJoin = agg::miter_join_revert; break;
case LineJoinBevel : LineJoin = agg::bevel_join; break;
case LineJoinRound : LineJoin = agg::round_join; break;
case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break;
default: break;
}
agg::line_cap_e LineCap = agg::round_cap;
switch(pPen->LineStartCap)
{
case LineCapFlat : LineCap = agg::butt_cap; break;
case LineCapRound : LineCap = agg::round_cap; break;
case LineCapSquare : LineCap = agg::square_cap; break;
default: break;
}
double dWidth = pPen->Size;
if (!m_bIntegerGrid && m_bIs0PenWidthAs1px)
{
double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant()));
if (0 == dWidth)
{
double dX = 0.72, dY = 0.72;
agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx;
invert.transform_2x2(&dX, &dY);
dWidth = std::min(abs(dX), abs(dY));
}
else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet))
dWidth = dWidthMinSize;
}
double dblMiterLimit = pPen->MiterLimit;
agg::path_storage path_copy(pPath->m_internal->m_agg_ps);
bool bIsUseIdentity = m_bIntegerGrid;
if (!bIsUseIdentity)
{
agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx;
double dDet = full_trans->determinant();
if (fabs(dDet) < 0.0001)
{
path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx);
dWidth *= sqrt(fabs(dDet));
bIsUseIdentity = true;
}
}
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
conv_crv_type c_c_path(path_copy);
c_c_path.approximation_scale(25.0);
c_c_path.approximation_method(agg::curve_inc);
DashStyle eStyle = (DashStyle)pPen->DashStyle;
if (DashStyleCustom == eStyle)
{
if (0 == pPen->Count || NULL == pPen->DashPattern)
{
eStyle = DashStyleSolid;
}
else
{
bool bFoundNormal = false;
for (int i = 0; i < pPen->Count; i++)
{
if (fabs(pPen->DashPattern[i]) > 0.0001)
{
bFoundNormal = true;
break;
}
}
if (!bFoundNormal)
eStyle = DashStyleSolid;
}
}
agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx;
if (bIsUseIdentity)
pAffine = new agg::trans_affine();
if (DashStyleSolid == eStyle)
{
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
Path_Conv_StrokeN pgN(c_c_path);
//pgN.line_join(agg::miter_join_revert);
pgN.line_cap(LineCap);
pgN.line_join(LineJoin);
pgN.inner_join(agg::inner_round);
pgN.miter_limit(dblMiterLimit);
pgN.width(dWidth);
pgN.approximation_scale(25.0);
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
transStroke trans(pgN, *pAffine);
m_rasterizer.get_rasterizer().add_path(trans);
}
else
{
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
Path_Conv_Dash poly2_dash(c_c_path);
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
Path_Conv_StrokeD pgD(poly2_dash);
switch (eStyle)
{
case DashStyleDash:
poly2_dash.add_dash(3.00*dWidth, dWidth);
break;
case DashStyleDot:
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDotDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
default:
case DashStyleCustom:
{
double offset = pPen->DashOffset;
double* params = pPen->DashPattern;
LONG lCount = pPen->Count;
LONG lCount2 = lCount / 2;
double dKoef = 1.0;
for (LONG i = 0; i < lCount2; ++i)
{
if (0 == i)
{
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
}
else
{
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
}
}
if (1 == (lCount % 2))
{
poly2_dash.add_dash(params[lCount - 1] * dKoef, 0);
}
poly2_dash.dash_start(offset * dKoef);
break;
}
}
double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant()));
if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize)
dWidth = dWidthMinSize;
pgD.line_cap(LineCap);
pgD.line_join(LineJoin);
pgD.miter_limit(dblMiterLimit);
pgD.width(dWidth);
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, *pAffine);
m_rasterizer.get_rasterizer().add_path(trans);
}
agg::trans_affine* pAffine = DoStrokePath(pPen, pPath, &m_rasterizer.get_rasterizer());
CColor oColor((BYTE)(pPen->Alpha * m_dGlobalAlpha), pPen->Color, m_bSwapRGB);
CBrushSolid oBrush(oColor);
@ -798,8 +653,7 @@ namespace Aggplus
if (gamma >= 0)
m_rasterizer.gamma(1.0);
if (bIsUseIdentity)
RELEASEOBJECT(pAffine);
RELEASEOBJECT(pAffine);
return Ok;
}
@ -2243,6 +2097,186 @@ namespace Aggplus
break;
}
}
template<class Rasterizer>
agg::trans_affine* CGraphics::DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* pRasterizer)
{
agg::line_join_e LineJoin = agg::round_join;
switch(pPen->LineJoin)
{
case LineJoinMiter : LineJoin = agg::miter_join_revert; break;
case LineJoinBevel : LineJoin = agg::bevel_join; break;
case LineJoinRound : LineJoin = agg::round_join; break;
case LineJoinMiterClipped : LineJoin = agg::miter_join_revert; break;
default: break;
}
agg::line_cap_e LineCap = agg::round_cap;
switch(pPen->LineStartCap)
{
case LineCapFlat : LineCap = agg::butt_cap; break;
case LineCapRound : LineCap = agg::round_cap; break;
case LineCapSquare : LineCap = agg::square_cap; break;
default: break;
}
double dWidth = pPen->Size;
if (!m_bIntegerGrid && m_bIs0PenWidthAs1px)
{
double dWidthMinSize, dSqrtDet = sqrt(abs(m_oFullTransform.m_internal->m_agg_mtx.determinant()));
if (0 == dWidth)
{
double dX = 0.72, dY = 0.72;
agg::trans_affine invert = ~m_oFullTransform.m_internal->m_agg_mtx;
invert.transform_2x2(&dX, &dY);
dWidth = std::min(abs(dX), abs(dY));
}
else if (0 != dSqrtDet && dWidth < (dWidthMinSize = 1.0 / dSqrtDet))
dWidth = dWidthMinSize;
}
double dblMiterLimit = pPen->MiterLimit;
agg::path_storage path_copy(pPath->m_internal->m_agg_ps);
bool bIsUseIdentity = m_bIntegerGrid;
if (!bIsUseIdentity)
{
agg::trans_affine* full_trans = &m_oFullTransform.m_internal->m_agg_mtx;
double dDet = full_trans->determinant();
if (fabs(dDet) < 0.0001)
{
path_copy.transform_all_paths(m_oFullTransform.m_internal->m_agg_mtx);
dWidth *= sqrt(fabs(dDet));
bIsUseIdentity = true;
}
}
typedef agg::conv_curve<agg::path_storage> conv_crv_type;
conv_crv_type c_c_path(path_copy);
c_c_path.approximation_scale(25.0);
c_c_path.approximation_method(agg::curve_inc);
DashStyle eStyle = (DashStyle)pPen->DashStyle;
if (DashStyleCustom == eStyle)
{
if (0 == pPen->Count || NULL == pPen->DashPattern)
{
eStyle = DashStyleSolid;
}
else
{
bool bFoundNormal = false;
for (int i = 0; i < pPen->Count; i++)
{
if (fabs(pPen->DashPattern[i]) > 0.0001)
{
bFoundNormal = true;
break;
}
}
if (!bFoundNormal)
eStyle = DashStyleSolid;
}
}
agg::trans_affine* pAffine = &m_oFullTransform.m_internal->m_agg_mtx;
if (bIsUseIdentity)
pAffine = new agg::trans_affine();
if (DashStyleSolid == eStyle)
{
typedef agg::conv_stroke<conv_crv_type> Path_Conv_StrokeN;
Path_Conv_StrokeN pgN(c_c_path);
//pgN.line_join(agg::miter_join_revert);
pgN.line_cap(LineCap);
pgN.line_join(LineJoin);
pgN.inner_join(agg::inner_round);
pgN.miter_limit(dblMiterLimit);
pgN.width(dWidth);
pgN.approximation_scale(25.0);
typedef agg::conv_transform<Path_Conv_StrokeN> transStroke;
transStroke trans(pgN, *pAffine);
pRasterizer->add_path(trans);
}
else
{
typedef agg::conv_dash<conv_crv_type> Path_Conv_Dash;
Path_Conv_Dash poly2_dash(c_c_path);
typedef agg::conv_stroke<Path_Conv_Dash> Path_Conv_StrokeD;
Path_Conv_StrokeD pgD(poly2_dash);
switch (eStyle)
{
case DashStyleDash:
poly2_dash.add_dash(3.00*dWidth, dWidth);
break;
case DashStyleDot:
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
case DashStyleDashDotDot:
poly2_dash.add_dash(3.00*dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
poly2_dash.add_dash(dWidth, dWidth);
break;
default:
case DashStyleCustom:
{
double offset = pPen->DashOffset;
double* params = pPen->DashPattern;
LONG lCount = pPen->Count;
LONG lCount2 = lCount / 2;
double dKoef = 1.0;
for (LONG i = 0; i < lCount2; ++i)
{
if (0 == i)
{
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
}
else
{
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
}
}
if (1 == (lCount % 2))
{
poly2_dash.add_dash(params[lCount - 1] * dKoef, 0);
}
poly2_dash.dash_start(offset * dKoef);
break;
}
}
double dWidthMinSize = 1.0 / sqrt(abs(m_oCoordTransform.m_internal->m_agg_mtx.determinant()));
if ((0 == dWidth && !m_bIntegerGrid) || dWidth < dWidthMinSize)
dWidth = dWidthMinSize;
pgD.line_cap(LineCap);
pgD.line_join(LineJoin);
pgD.miter_limit(dblMiterLimit);
pgD.width(dWidth);
agg::conv_transform<Path_Conv_StrokeD> trans(pgD, *pAffine);
pRasterizer->add_path(trans);
}
return bIsUseIdentity ? pAffine : NULL;
}
// text methods
int CGraphics::FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush)
{

View File

@ -360,8 +360,8 @@ public:
Status SetClip(CGraphicsPath* pPath);
Status ResetClip();
Status ExclugeClip(CGraphicsPath* pPath);
Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op);
Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op);
Status CombineClip(CGraphicsPath* pPath, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL);
Status InternalClip(CGraphicsPath* pPath, CMatrix* pTransform, agg::sbool_op_e op, NSStructures::CPen* pPen = NULL);
// измерение текста
INT MeasureString(const std::wstring& strText, CFontManager* pManager, double* lWidth, double* lHeight);
@ -453,6 +453,8 @@ protected:
void DoFillPathTextureClampSz3(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, Aggplus::WrapMode wrapmode, BYTE Alpha = 255);
void DoFillPath(const CBrush* Brush);
template<class Rasterizer>
agg::trans_affine* DoStrokePath(NSStructures::CPen* pPen, CGraphicsPath* pPath, Rasterizer* ras);
// text methods
int FillGlyph2(int nX, int nY, TGlyph* pGlyph, Aggplus::CBrush* pBrush);

View File

@ -822,7 +822,8 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType)
m_pPath->SetRuler(bIsIn ? false : true);
INT bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode));
m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or);
INT bIsStrokePath = (c_nClipToStrokePath == (0x0010 & m_lCurrentClipMode));
m_pRenderer->CombineClip(m_pPath, bIsIntersect ? agg::sbool_and : agg::sbool_or, bIsStrokePath ? &m_oPen : NULL);
//m_pRenderer->SetClip(m_pPath);
break;

View File

@ -96,6 +96,9 @@ const long c_nBaselineShift = 0xa041;
// типы клипа
const long c_nClipRegionTypeWinding = 0x0000;
const long c_nClipRegionTypeEvenOdd = 0x0001;
// тип преобразования пути для клипов
const long c_nClipToPath = 0x0000;
const long c_nClipToStrokePath = 0x0010;
// тип объединения клипов
const long c_nClipRegionIntersect = 0x0000;
const long c_nClipRegionUnion = 0x0100;

View File

@ -153,13 +153,6 @@ IMetafileToRenderter::IMetafileToRenderter(IRenderer* pRenderer)
}
IMetafileToRenderter::~IMetafileToRenderter()
{
for (std::vector<std::wstring>::iterator i = m_arTempFiles.begin(); i != m_arTempFiles.end(); i++)
{
std::wstring sPath = *i;
if (NSFile::CFileBinary::Exists(sPath))
NSFile::CFileBinary::Remove(sPath);
}
if (m_pPicker)
{
CMetafileFontPicker* pPicker = (CMetafileFontPicker*)m_pPicker;
@ -234,8 +227,6 @@ std::wstring IMetafileToRenderter::GetImagePath(const std::wstring& sPath)
oFrame.put_Data(NULL);
sImagePath = sTempFile;
}
m_arTempFiles.push_back(sTempFile);
}
RELEASEARRAYOBJECTS(pImageBuffer);

View File

@ -49,7 +49,6 @@ public:
protected:
std::wstring m_sTempDir;
std::vector<std::wstring> m_arTempFiles;
std::wstring m_sThemesDir;
std::wstring m_sMediaDir;

View File

@ -123,6 +123,7 @@ namespace MetaFile
virtual bool LoadFromFile(const wchar_t* wsFilePath) = 0;
virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) = 0;
virtual bool LoadFromString(const std::wstring& data) = 0;
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) = 0;
virtual void Close() = 0;
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) = 0;
@ -131,6 +132,7 @@ namespace MetaFile
virtual NSFonts::IFontManager* get_FontManager() = 0;
virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) = 0;
virtual void SetTempDirectory(const std::wstring& dir) = 0;
//Для тестов
#ifdef METAFILE_SUPPORT_WMF_EMF

View File

@ -223,7 +223,7 @@
},
{
"folder": "../../../../DocxRenderer/src/logic/elements",
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp"]
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"]
},
{
"folder": "../../../common",

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)

View File

@ -1,5 +1,5 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)

View File

@ -42,6 +42,7 @@ namespace MetaFile
virtual void SetImageSize(int nWidth, int nHeight) {}
virtual bool LoadFromFile(const wchar_t* wsFilePath) { return false; }
virtual bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize) { return false; }
virtual bool LoadFromString(const std::wstring& data) { return false; }
virtual bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight) { return false; }
virtual void Close() {}
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) {}
@ -50,6 +51,7 @@ namespace MetaFile
virtual NSFonts::IFontManager* get_FontManager() { return NULL; }
virtual std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0) { return L""; }
virtual void SetTempDirectory(const std::wstring& dir) {}
virtual void ConvertToXml(const wchar_t* wsFilePath) {}
virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) {}

View File

@ -19,6 +19,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
\
$$METAFILE_PATH/Emf/EmfTypes.h \
$$METAFILE_PATH/Emf/EmfObjects.h \
$$METAFILE_PATH/Emf/EmfPlusObjects.h \
$$METAFILE_PATH/Emf/EmfPlayer.h \
$$METAFILE_PATH/Emf/EmfFile.h \
$$METAFILE_PATH/Wmf/WmfObjects.h \

View File

@ -327,6 +327,13 @@ namespace MetaFile
if (NULL == pCommand)
return false;
if (PATH_COMMAND_MOVETO == pCommand->GetType() && !m_arCommands.empty() && PATH_COMMAND_MOVETO == m_arCommands.back()->GetType())
{
CPathCommandBase* pLastCommand = m_arCommands.back();
m_arCommands.pop_back();
delete pLastCommand;
}
m_arCommands.push_back(pCommand);
return true;
}

View File

@ -59,7 +59,7 @@ namespace MetaFile
{
CPathCommandArcTo *pCommandArcTo = (CPathCommandArcTo*)pCommand;
oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(),
oNewPath.ArcTo(pCommandArcTo->GetLeft(), pCommandArcTo->GetTop(),
pCommandArcTo->GetRight(), pCommandArcTo->GetBottom(),
pCommandArcTo->GetStartAngle(), pCommandArcTo->GetSweepAngle());

View File

@ -33,6 +33,7 @@
#define _METAFILE_COMMON_METAFILEOBJECTS_H
#include <string>
#include <vector>
namespace MetaFile
{
@ -70,22 +71,33 @@ namespace MetaFile
virtual void GetBounds(double& left, double& top, double& width, double& height) const = 0;
virtual void GetCenterPoint(double& dX, double& dY) const = 0;
virtual void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const = 0;
virtual void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const = 0;
};
class ILineCap
{
public:
ILineCap(){}
virtual ~ILineCap(){}
};
class IPen
{
public:
IPen(){}
virtual ~IPen(){}
virtual int GetColor() const = 0;
virtual unsigned int GetStyle() const = 0;
virtual double GetWidth() const = 0;
virtual unsigned int GetAlpha() const = 0;
virtual double GetMiterLimit() const = 0;
virtual double GetDashOffset() const = 0;
virtual void GetDashData(double*&, unsigned int&) const = 0;
virtual int GetColor() const = 0;
virtual unsigned int GetStyle() const = 0;
virtual double GetWidth() const = 0;
virtual unsigned int GetAlpha() const = 0;
virtual double GetMiterLimit() const = 0;
virtual double GetDashOffset() const = 0;
virtual void GetDashData(double*&, unsigned int&) const = 0;
virtual const ILineCap* GetStartLineCap() const = 0;
virtual const ILineCap* GetEndLineCap() const = 0;
};
class IRegion

View File

@ -100,6 +100,8 @@ namespace MetaFile
m_bStartedPath = false;
m_bUpdatedClip = true;
m_pRenderer->CommandLong(c_nPenWidth0As1px, 1);
//int alpha = 0xff;
//m_pRenderer->put_BrushAlpha1(alpha);
//m_pRenderer->put_BrushType(c_BrushTypeSolid);
@ -1107,12 +1109,11 @@ namespace MetaFile
m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx());
long Colors[2];
Colors[0] = pBrush->GetColor() + (pBrush->GetAlpha() << 24);
Colors[1] = pBrush->GetColor2() + (pBrush->GetAlpha2() << 24);
double Position[2] = {0, 1};
std::vector<long> arColors;
std::vector<double> arPositions;
m_pRenderer->put_BrushGradientColors(Colors,Position,2);
pBrush->GetGradientColors(arColors, arPositions);
m_pRenderer->put_BrushGradientColors(arColors.data(), arPositions.data(), arColors.size());
}
else if ( BS_RADIALGRADIENT == unBrushStyle ||
@ -1180,7 +1181,6 @@ namespace MetaFile
return false;
unsigned int unMetaPenStyle = pPen->GetStyle();
unsigned int ulPenStyle = unMetaPenStyle & PS_STYLE_MASK;
if (PS_NULL == ulPenStyle)
@ -1218,22 +1218,8 @@ namespace MetaFile
else if (PS_JOIN_MITER == ulPenJoin)
nJoinStyle = Aggplus::LineJoinMiter;
double dWidth = pPen->GetWidth();
if (Equals(0, dWidth) || (Equals(1, dWidth) && PS_COSMETIC == ulPenType))
{
double dRendererDpiX;
m_pRenderer->get_DpiX(&dRendererDpiX);
dWidth = 25.4 / 96. * m_pFile->GetDpi() / dRendererDpiX;
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
nJoinStyle = Aggplus::LineJoinMiter;
}
else
dWidth *= m_dScaleX;
double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;
const double dWidth = pPen->GetWidth() * m_dScaleX;
const double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;
BYTE nDashStyle = Aggplus::DashStyleSolid;
@ -1246,10 +1232,16 @@ namespace MetaFile
{
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
double dM11, dTemp;
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
double dDpi;
m_pRenderer->get_DpiX(&dDpi);
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
std::vector<double> arDashes(unSizeDash);
for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
arDashes[unIndex] = pDataDash[unIndex] * dWidth;
arDashes[unIndex] = pDataDash[unIndex] * dNewWidth;
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
@ -1259,39 +1251,45 @@ namespace MetaFile
{
std::vector<double> arDashPattern;
double dM11, dTemp;
m_pRenderer->GetTransform(&dM11, &dTemp, &dTemp, &dTemp, &dTemp, &dTemp);
double dDpi;
m_pRenderer->get_DpiX(&dDpi);
const double dNewWidth{dWidth * dM11 * dDpi / 25.4};
switch (ulPenStyle)
{
case PS_DASH:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}
case PS_DOT:
{
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}
case PS_DASHDOT:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}
case PS_DASHDOTDOT:
{
arDashPattern.push_back(9 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(3 * dWidth);
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}

View File

@ -349,6 +349,8 @@ typedef unsigned char BYTE;
namespace MetaFile
{
#define DEFAULT_FONT_SIZE 14
enum InterpretatorType
{
Emf,

View File

@ -147,6 +147,10 @@ namespace MetaFile
if (BI_JPEG != unCompression || BI_PNG != unCompression)
return false;
#ifdef METAFILE_DISABLE_FILESYSTEM
return false;
#endif
std::wstring wsTempFileName = GetTempFilename();
if (wsTempFileName.empty())
return false;

View File

@ -48,6 +48,8 @@ namespace MetaFile
{
bool Equals(double dFirst, double dSecond, double dEpsilon = DBL_EPSILON);
std::wstring ConvertToUnicode(const unsigned char* pText, unsigned long unLength, unsigned short uchCharSet);
std::wstring ConvertToWString(double dValue, int nAccuracy = -1);
std::wstring ConvertToWString(const std::vector<double>& arValues, int nAccuracy = -1);
struct TRgbQuad
{
@ -88,13 +90,34 @@ namespace MetaFile
};
typedef std::pair<const std::wstring, std::wstring> NodeAttribute;
typedef std::vector<NodeAttribute> NodeAttributes;
// typedef std::vector<NodeAttribute> NodeAttributes;
class NodeAttributes : public std::vector<NodeAttribute>
{
public:
using std::vector<NodeAttribute>::vector;
void Add(const std::wstring& wsNameArgument, const std::wstring& wsValueArgument)
{
emplace_back(NodeAttribute{wsNameArgument, wsValueArgument});
}
void Add(const std::wstring& wsNameArgument, const double& dValueArgument, int nAccuracy = -1)
{
emplace_back(NodeAttribute{wsNameArgument, ConvertToWString(dValueArgument, nAccuracy)});
}
void Add(const std::wstring& wsNameArgument, const int& nValueArgument)
{
emplace_back(NodeAttribute{wsNameArgument, std::to_wstring(nValueArgument)});
}
};
class CDataStream
{
public:
CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pEnd(NULL), pCur(NULL)
CDataStream() : pBuffer(NULL), pBufferEnd(NULL), pCur(NULL), pEnd(NULL)
{
}
@ -1159,8 +1182,5 @@ namespace MetaFile
std::wstring StringNormalization(const std::wstring& wsString);
bool StringEquals(const std::wstring& wsFirstString, const std::wstring& wsSecondString);
std::wstring ConvertToWString(double dValue, int nAccuracy = -1);
std::wstring ConvertToWString(const std::vector<double>& arValues, int nAccuracy = -1);
};
#endif // _METAFILE_COMMON_METAFILEUTILS_H

View File

@ -41,7 +41,7 @@ namespace MetaFile
}
void CEmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx,
int iGraphicsMode, double dXScale, double dYScale)
int iGraphicsMode, double dXScale, double dYScale)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);

View File

@ -33,7 +33,8 @@ namespace MetaFile
return;
std::swap(m_pParser, m_oSecondConditional.m_pParser);
std::swap(m_oClip, m_oSecondConditional.m_oClip);
SwapClips(m_oClip, m_oSecondConditional.m_oClip);
}
InterpretatorType CEmfInterpretatorSvg::GetType() const
@ -107,7 +108,7 @@ namespace MetaFile
if (NULL == pPath)
return;
const std::wstring wsValue = CreatePath(*pPath);
if (wsValue.empty())
@ -117,6 +118,7 @@ namespace MetaFile
AddClip();
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
WriteNode(L"path" , arAttributes);
@ -175,6 +177,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
{
@ -238,6 +241,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
{
@ -292,6 +296,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
{
@ -325,6 +330,7 @@ namespace MetaFile
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -365,6 +371,7 @@ namespace MetaFile
{L"y2", ConvertToWString(oPoint.Y)}};
AddStroke(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -373,21 +380,29 @@ namespace MetaFile
void CEmfInterpretatorSvg::HANDLE_EMR_PIE(const TRectL &oBox, const TPointL &oStart, const TPointL &oEnd)
{
short shCenterX = (oBox.Left + oBox.Right) / 2;
short shCenterY = (oBox.Top + oBox.Bottom) / 2;
int nCenterX = (oBox.Left + oBox.Right) / 2;
int nCenterY = (oBox.Top + oBox.Bottom) / 2;
short shRadiusX = std::abs(oBox.Right - oBox.Left) / 2;
short shRadiusY = std::abs(oBox.Bottom - oBox.Top) / 2;
std::wstring wsPath = L'M' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L' ' +
double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX);
double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX);
if (dEndAngle > dStartAngle)
dEndAngle -= 2 * M_PI;
std::wstring wsPath = L'M' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L' ' +
L'L' + ConvertToWString(oStart.X)+ L' ' + ConvertToWString(oStart.Y)+ L' ' +
L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0, 0, 0, " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' +
L'L' + ConvertToWString(shCenterX) + L' ' + ConvertToWString(shCenterY) + L" Z";
L'A' + ConvertToWString(shRadiusX) + L' ' + ConvertToWString(shRadiusY) + L" 0 " +
((std::abs(dEndAngle - dStartAngle) > M_PI) ? L'1' : L'0') + L" 0 " + ConvertToWString(oEnd.X) + L' ' + ConvertToWString(oEnd.Y) + L' ' +
L'L' + ConvertToWString(nCenterX) + L' ' + ConvertToWString(nCenterY) + L" Z";
NodeAttributes arAttributes = {{L"d", wsPath}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -402,14 +417,15 @@ namespace MetaFile
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -424,14 +440,15 @@ namespace MetaFile
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -446,14 +463,15 @@ namespace MetaFile
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -468,14 +486,15 @@ namespace MetaFile
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -509,9 +528,9 @@ namespace MetaFile
wsValue += L" C ";
oLastType = 0x04;
}
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
unIndex += 3;
}
@ -526,6 +545,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -559,9 +579,9 @@ namespace MetaFile
wsValue += L" C ";
oLastType = 0x04;
}
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L',' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L',' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L',' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
unIndex += 3;
}
@ -576,6 +596,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -596,6 +617,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -616,6 +638,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -636,6 +659,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -658,6 +682,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -680,6 +705,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -702,6 +728,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -729,10 +756,11 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
arAttributes.push_back({L"fill-rule", L"evenodd"});
arAttributes.Add(L"fill-rule", L"evenodd");
WriteNode(L"path", arAttributes);
}
@ -758,10 +786,11 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
arAttributes.push_back({L"fill-rule", L"evenodd"});
arAttributes.Add(L"fill-rule", L"evenodd");
WriteNode(L"path", arAttributes);
}
@ -787,10 +816,11 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
arAttributes.push_back({L"fill-rule", L"evenodd"});
arAttributes.Add(L"fill-rule", L"evenodd");
WriteNode(L"path", arAttributes);
}
@ -816,10 +846,11 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
arAttributes.push_back({L"fill-rule", L"evenodd"});
arAttributes.Add(L"fill-rule", L"evenodd");
WriteNode(L"path", arAttributes);
}
@ -828,13 +859,14 @@ namespace MetaFile
{
TRectD oNewRect = TranslateRect(oBox);
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
AddStroke(arAttributes);
AddFill(arAttributes, oNewRect.Right - oNewRect.Left, oNewRect.Bottom - oNewRect.Top);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -845,15 +877,16 @@ namespace MetaFile
{
TRectD oNewRect = TranslateRect(oBox);
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
{L"rx", ConvertToWString((double)oCorner.X / 2.)},
{L"ry", ConvertToWString((double)oCorner.Y / 2.)}};
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
{L"rx", ConvertToWString((double)oCorner.X / 2.)},
{L"ry", ConvertToWString((double)oCorner.Y / 2.)}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -889,6 +922,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes, std::fabs(oBounds.Right - oBounds.Left), std::fabs(oBounds.Bottom - oBounds.Top));
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -914,6 +948,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -928,15 +963,16 @@ namespace MetaFile
NodeAttributes arAttributes;
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
if (4 == arVertex.size())
{
arAttributes.push_back({L"x", ConvertToWString(std::min(arVertex[0].nX, arVertex[1].nX))});
arAttributes.push_back({L"y", ConvertToWString(std::min(arVertex[0].nY, arVertex[2].nY))});
arAttributes.push_back({L"width", ConvertToWString(std::abs(arVertex[1].nX - arVertex[0].nX))});
arAttributes.push_back({L"height", ConvertToWString(std::abs(arVertex[2].nY - arVertex[0].nY))});
arAttributes.Add(L"x", std::min(arVertex[0].nX, arVertex[1].nX));
arAttributes.Add(L"y", std::min(arVertex[0].nY, arVertex[2].nY));
arAttributes.Add(L"width", std::abs(arVertex[1].nX - arVertex[0].nX));
arAttributes.Add(L"height", std::abs(arVertex[2].nY - arVertex[0].nY));
WriteNode(L"rect" , arAttributes);
}
else if (3 == arVertex.size())
@ -950,7 +986,7 @@ namespace MetaFile
std::wstring wsValue = CreatePath(oPath);
if (!wsValue.empty())
arAttributes.push_back({L"d", wsValue});
arAttributes.Add(L"d", wsValue);
WriteNode(L"path" , arAttributes);
}
@ -969,16 +1005,17 @@ namespace MetaFile
{
oTempRect = TranslateRect(oRect);
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
}
NodeAttributes arAttributes = {{L"d", wsValue}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -998,16 +1035,17 @@ namespace MetaFile
{
oTempRect = TranslateRect(oRect);
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
L"L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
}
NodeAttributes arAttributes = {{L"d", wsValue}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1016,6 +1054,7 @@ namespace MetaFile
void CEmfInterpretatorSvg::HANDLE_EMR_FRAMERGN(const TRectL &oBounds, unsigned int unIhBrush, int nWidth, int nHeight, const TRegionDataHeader &oRegionDataHeader, const std::vector<TRectL> &arRects)
{
m_bUpdatedClip = false;
}
void CEmfInterpretatorSvg::HANDLE_EMFPLUS_OFFSETCLIP(double dX, double dY)
@ -1085,6 +1124,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
if (AD_COUNTERCLOCKWISE == m_pParser->GetArcDirection())
{
@ -1111,14 +1151,15 @@ namespace MetaFile
std::wstring wsValue = L"M " + ConvertToWString(arPoints[0].X) + L' ' + ConvertToWString(arPoints[0].Y) + L" C ";
for (unsigned int unIndex = 1; unIndex + 2 < arPoints.size(); unIndex += 3)
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
wsValue += ConvertToWString(arPoints[unIndex].X) + L' ' + ConvertToWString(arPoints[unIndex].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 1].X) + L' ' + ConvertToWString(arPoints[unIndex + 1].Y) + L' ' +
ConvertToWString(arPoints[unIndex + 2].X) + L' ' + ConvertToWString(arPoints[unIndex + 2].Y) + L' ';
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1158,14 +1199,14 @@ namespace MetaFile
int nColor = m_pParser->GetTextColor();
if (0 != nColor)
arNodeAttributes.push_back({L"fill", CalculateColor(nColor, 255)});
arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255));
double dFontHeight = std::fabs(pFont->GetHeight());
if (dFontHeight < 0.01)
dFontHeight = 18;
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
arNodeAttributes.Add(L"font-size", dFontHeight);
NSStringUtils::CStringBuilder oFontName;
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
@ -1188,21 +1229,21 @@ namespace MetaFile
oFontName.WriteEncodeXmlString(L"\'");
}
#endif
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
arNodeAttributes.Add(L"font-family", oFontName.GetData());
}
if (pFont->GetWeight() > 550)
arNodeAttributes.push_back({L"font-weight", L"bold"});
arNodeAttributes.Add(L"font-weight", L"bold");
if (pFont->IsItalic())
arNodeAttributes.push_back({L"font-style", L"italic"});
arNodeAttributes.Add(L"font-style", L"italic");
if (pFont->IsUnderline() && pFont->IsStrikeOut())
arNodeAttributes.push_back({L"text-decoration", L"underline line-through"});
arNodeAttributes.Add(L"text-decoration", L"underline line-through");
else if (pFont->IsUnderline())
arNodeAttributes.push_back({L"text-decoration", L"underline"});
arNodeAttributes.Add(L"text-decoration", L"underline");
else if (pFont->IsStrikeOut())
arNodeAttributes.push_back({L"text-decoration", L"line-through"});
arNodeAttributes.Add(L"text-decoration", L"line-through");
AddTransform(arNodeAttributes);
AddClip();
@ -1218,8 +1259,8 @@ namespace MetaFile
wsX.pop_back();
wsY.pop_back();
arNodeAttributes.push_back({L"x", wsX});
arNodeAttributes.push_back({L"y", wsY});
arNodeAttributes.Add(L"x", wsX);
arNodeAttributes.Add(L"y", wsY);
WriteNode(L"text", arNodeAttributes, wsText);
}
@ -1234,6 +1275,7 @@ namespace MetaFile
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1254,6 +1296,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1273,7 +1316,9 @@ namespace MetaFile
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddLineCaps(arAttributes, pPath);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1295,17 +1340,18 @@ namespace MetaFile
{
oTempRect = oRect.ToRectD();
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
}
NodeAttributes arAttributes = {{L"d", wsValue}};
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1332,6 +1378,7 @@ namespace MetaFile
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1353,6 +1400,7 @@ namespace MetaFile
TRectD oPathRect = pPath->GetBounds();
AddFill(arAttributes, std::fabs(oPathRect.Right - oPathRect.Left), std::fabs(oPathRect.Bottom - oPathRect.Top));
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -1377,6 +1425,7 @@ namespace MetaFile
NodeAttributes arAttributes = {{L"points", wsValue}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
NodeAttributes arGAttributes;
@ -1387,17 +1436,18 @@ namespace MetaFile
void CEmfInterpretatorSvg::HANDLE_EMFPLUS_FILLRECTS(unsigned int unBrushId, const std::vector<TEmfPlusRectF> &arRects)
{
if (arRects.empty())
return;
std::wstring wsValue;
TRectD oTempRect;
TXForm oFileTransform(m_pParser->GetTransform());
for (const TEmfPlusRectF& oRect : arRects)
{
oTempRect = oRect.ToRectD();
m_pParser->GetTransform().Apply(oTempRect.Left, oTempRect.Top);
m_pParser->GetTransform().Apply(oTempRect.Right, oTempRect.Bottom);
wsValue += L"M " + ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) +
L" L " + ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Top) + L' ' +
ConvertToWString(oTempRect.Right) + L',' + ConvertToWString(oTempRect.Bottom) + L' ' +
@ -1405,9 +1455,13 @@ namespace MetaFile
ConvertToWString(oTempRect.Left) + L',' + ConvertToWString(oTempRect.Top) + L' ';
}
wsValue.pop_back();
NodeAttributes arAttributes = {{L"d", wsValue}};
AddTransform(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddClip();
WriteNode(L"path", arAttributes);
@ -1448,25 +1502,15 @@ namespace MetaFile
CInterpretatorSvgBase::PathClip(oPath, nClipMode, pTransform);
}
TRectD CEmfInterpretatorSvg::TranslateRect(const TRectL &oRect) const
void CEmfInterpretatorSvg::SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip)
{
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
if (oFirstClip.StartedClip())
WriteNodeEnd(L"g");
if (oNewRect.Right < oNewRect.Left)
{
double dTempValue = oNewRect.Left;
oNewRect.Left = oNewRect.Right;
oNewRect.Right = dTempValue;
}
if (oSecondClip.StartedClip())
WriteNodeBegin(L"g", {{L"clip-path", L"url(#" + oSecondClip.GetClipId() + L')'}});
if (oNewRect.Bottom < oNewRect.Top)
{
double dTempValue = oNewRect.Top;
oNewRect.Top = oNewRect.Bottom;
oNewRect.Bottom = dTempValue;
}
return oNewRect;
std::swap(oFirstClip, oSecondClip);
}
}

View File

@ -226,7 +226,7 @@ namespace MetaFile
void SetTransform(double& dM11, double& dM12, double& dM21, double& dM22, double& dX, double& dY) override {};
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
TRectD TranslateRect(const TRectL &oRect) const;
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);
};
}

View File

@ -155,9 +155,38 @@ namespace MetaFile
unHeight = unDibHeigth;
}
CEmfLogFont::CEmfLogFont(bool bFixedLength) : m_bFixedLength(bFixedLength)
void CEmfLogBrushEx::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
{
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
arPositions = {0., 1.};
}
CEmfLogFont::CEmfLogFont(bool bFixedLength)
: m_bFixedLength(bFixedLength)
{
oDesignVector.pValues = NULL;
oLogFontEx.oLogFont.nHeight = DEFAULT_FONT_SIZE;
oLogFontEx.oLogFont.nWidth = 0;
oLogFontEx.oLogFont.nEscapement = 0;
oLogFontEx.oLogFont.nOrientation = 0;
oLogFontEx.oLogFont.nWeight = 400;
oLogFontEx.oLogFont.uchItalic = 0x00;
oLogFontEx.oLogFont.uchUnderline = 0x00;
oLogFontEx.oLogFont.uchStrikeOut = 0x00;
oLogFontEx.oLogFont.uchCharSet = 0x01;
oLogFontEx.oLogFont.uchOutPrecision = 0x00;
oLogFontEx.oLogFont.uchClipPrecision = 0x00;
oLogFontEx.oLogFont.uchQuality = 0x00;
oLogFontEx.oLogFont.uchPitchAndFamily = 0x00;
memset(oLogFontEx.oLogFont.ushFaceName, 0x00, 32);
oLogFontEx.oLogFont.ushFaceName[0] = 'A';
oLogFontEx.oLogFont.ushFaceName[1] = 'r';
oLogFontEx.oLogFont.ushFaceName[2] = 'i';
oLogFontEx.oLogFont.ushFaceName[3] = 'a';
oLogFontEx.oLogFont.ushFaceName[4] = 'l';
}
CEmfLogFont::~CEmfLogFont()
@ -271,6 +300,16 @@ namespace MetaFile
unSize = 0;
}
const ILineCap* CEmfLogPen::GetStartLineCap() const
{
return NULL;
}
const ILineCap* CEmfLogPen::GetEndLineCap() const
{
return NULL;
}
CEmfLogPalette::CEmfLogPalette() : ushNumberOfEntries(0), pPaletteEntries(NULL)
{}

View File

@ -77,6 +77,8 @@ namespace MetaFile
void GetBounds(double& left, double& top, double& width, double& height) const override;
void GetCenterPoint(double& dX, double& dY) const override;
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
public:
unsigned int unBrushStyle;
TRGBA oColor;
@ -122,13 +124,15 @@ namespace MetaFile
virtual EEmfObjectType GetType() const override;
// IPen
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
const ILineCap* GetStartLineCap() const override;
const ILineCap* GetEndLineCap() const override;
public:
unsigned int unPenStyle;
unsigned int unWidth;

View File

@ -1659,13 +1659,15 @@ namespace MetaFile
RestoreDC(-1);
}
else if (sType == "GDIC")
else if (sType == "GDIC" && NULL != m_pInterpretator)
{
unsigned int unPublicCommentIdentifier;
m_oStream >> unPublicCommentIdentifier;
if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier)
// At the moment, we are disabling support for embedded MWF files (in bug #71100 - The plus-minus symbol is not displayed correctly)
// From the tests, it became clear that the embedded WMF files are ignored
if (EMR_COMMENT_WINDOWS_METAFILE == unPublicCommentIdentifier && false)
{
m_oStream.Skip(12); // Version, Reserved, Checksum, Flags

View File

@ -78,8 +78,8 @@ namespace MetaFile
unsigned int ulWidth, ulHeight;
if (ReadImage(oTEmfStretchDIBITS.unOffBmiSrc, oTEmfStretchDIBITS.unCbBmiSrc,
oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc,
sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight))
oTEmfStretchDIBITS.unOffBitsSrc, oTEmfStretchDIBITS.unCbBitsSrc,
sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight))
{
if (m_pInterpretator)
{
@ -761,7 +761,11 @@ namespace MetaFile
RELEASEOBJECT(m_pInterpretator);
if (InterpretatorType::Svg == oInterpretatorType)
m_pInterpretator = new CEmfInterpretatorSvg(this, dWidth, dHeight);
{
CEmfInterpretatorSvg *pEmfInterpretatorSvg = new CEmfInterpretatorSvg(this, dWidth, dHeight);
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
m_pInterpretator = pEmfInterpretatorSvg;
}
}
CEmfInterpretatorBase* CEmfParserBase::GetInterpretator()
@ -1505,11 +1509,19 @@ namespace MetaFile
if (NULL != m_pInterpretator && (NULL == m_pPath || Svg != m_pInterpretator->GetType()))
m_pInterpretator->HANDLE_EMR_PIE(oBox, oStart, oEnd);
double dStartAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oStart.X, oStart.Y);
double dSweepAngle = GetEllipseAngle(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, oEnd.X, oEnd.Y) - dStartAngle;
const int nCenterX = (oBox.Left + oBox.Right) / 2;
const int nCenterY = (oBox.Top + oBox.Bottom) / 2;
ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle, dSweepAngle);
LineTo((oBox.Left + oBox.Right) / 2, (oBox.Top + oBox.Bottom) / 2);
double dStartAngle = std::atan2(oStart.Y - nCenterY, oStart.X - nCenterX);
double dEndAngle = std::atan2(oEnd.Y - nCenterY, oEnd.X - nCenterX);
if (dEndAngle > dStartAngle)
dEndAngle -= 2 * M_PI;
MoveTo(nCenterX, nCenterY);
LineTo(oStart.X, oStart.Y);
ArcTo(oBox.Left, oBox.Top, oBox.Right, oBox.Bottom, dStartAngle * 180. / M_PI, (dEndAngle - dStartAngle) * 180. / M_PI);
LineTo(nCenterX, nCenterY);
ClosePath();
DrawPath(true, true);
}

View File

@ -25,7 +25,7 @@
#include <algorithm>
#include <cstdlib>
#define LOG_EMF_RECORDS 0
#define LOG_EMF_RECORDS 1
#ifdef LOG_EMF_RECORDS
#if 1 == LOG_EMF_RECORDS

View File

@ -655,20 +655,18 @@ namespace MetaFile
m_oStream >> unPositionCount;
std::vector<double> arBlendPositions(unPositionCount);
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
m_oStream >> arBlendPositions[unIndex];
std::vector<TEmfPlusARGB> arBlendColors(unPositionCount);
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
m_oStream >> arBlendColors[unIndex];
if (1 < unPositionCount)
if (unPositionCount > 1)
{
pEmfPlusBrush->oColorBack = arBlendColors[0];
pEmfPlusBrush->oColor = arBlendColors.back();
pEmfPlusBrush->arGradientColors.resize(unPositionCount);
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second;
for (unsigned int unIndex = 0; unIndex < unPositionCount; ++unIndex)
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
pEmfPlusBrush->oColor = pEmfPlusBrush->arGradientColors[unPositionCount - 1].first;
pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors[0].first;
}
}
@ -679,13 +677,40 @@ namespace MetaFile
//TODO: реализовать
pEmfPlusBrush->unStyle = BS_LINEARGRADIENT;
m_oStream.Skip(8); // BrushDataFlags, WrapMode
int nBrushDataFlags;
m_oStream >> nBrushDataFlags;
m_oStream.Skip(4); // WrapMode
// m_oStream >> pEmfPlusBrush->RectF;
m_oStream.Skip(16);
m_oStream >> pEmfPlusBrush->oColor;
m_oStream >> pEmfPlusBrush->oColorBack;
m_oStream.Skip(8); // Reserved1, Reserved2
if (BrushDataTransform & nBrushDataFlags)
{
m_oStream.Skip(24);
}
if (BrushDataPresetColors & nBrushDataFlags)
{
int nPositionCount;
m_oStream >> nPositionCount;
if (nPositionCount > 1)
{
pEmfPlusBrush->arGradientColors.resize(nPositionCount);
for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex)
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].second;
for (unsigned int unIndex = 0; unIndex < nPositionCount; ++unIndex)
m_oStream >> pEmfPlusBrush->arGradientColors[unIndex].first;
}
}
break;
}
default:
@ -2266,16 +2291,21 @@ namespace MetaFile
if (NULL != pEmfPlusPen->pBrush)
m_pDC->SetBrush(pEmfPlusPen->pBrush);
CPathConverter oPathConverter;
CPath oNewPath, oLineCapPath;
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
oNewPath.DrawOn(m_pInterpretator, true, false);
oLineCapPath.DrawOn(m_pInterpretator, false, true);
if (NULL != m_pInterpretator)
m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, &oNewPath);
{
CPathConverter oPathConverter;
CPath oNewPath, oLineCapPath;
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
if (InterpretatorType::Render == m_pInterpretator->GetType())
{
oNewPath.DrawOn(m_pInterpretator, true, false);
oLineCapPath.DrawOn(m_pInterpretator, false, true);
}
else
m_pInterpretator->HANDLE_EMFPLUS_DRAWPATH(shOgjectIndex, unPenId, pPath);
}
if (NULL != pEmfPlusPen->pBrush)
m_pDC->RemoveBrush(pEmfPlusPen->pBrush);
@ -3126,7 +3156,6 @@ namespace MetaFile
m_oStream >> oMatrix;
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_RESETWORLDTRANSFORM()
@ -3134,7 +3163,6 @@ namespace MetaFile
m_bBanEmfProcessing = true;
m_pDC->ResetTransform();
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_ROTATEWORLDTRANSFORM(unsigned short unShFlags)
@ -3153,7 +3181,6 @@ namespace MetaFile
TEmfPlusXForm oMatrix(dCosTheta, dSinTheta, -dSinTheta, dCosTheta, 0, 0);
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_SCALEWORLDTRANSFORM(unsigned short unShFlags)
@ -3168,7 +3195,6 @@ namespace MetaFile
TEmfPlusXForm oMatrix(dSx, 0, 0, dSy, 0, 0);
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_SETPAGETRANSFORM(unsigned short unShFlags)
@ -3185,8 +3211,6 @@ namespace MetaFile
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_SETWORLDTRANSFORM()
@ -3196,11 +3220,8 @@ namespace MetaFile
m_oStream >> oMatrix;
m_pDC->MultiplyTransform(oMatrix, MWT_SET);
TEmfPlusXForm oUnitKoefMatrix(m_dPageTransformX, 0, 0, m_dPageTransformY, 0, 0);
m_pDC->MultiplyTransform(oUnitKoefMatrix, MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_TRANSLATEWORLDTRANSFORM(unsigned short unShFlags)
@ -3213,7 +3234,6 @@ namespace MetaFile
TEmfPlusXForm oMatrix(1, 0, 0, 1, dX, dY);
m_pDC->MultiplyTransform(oMatrix, (unShFlags & 0x2000) ? MWT_RIGHTMULTIPLY : MWT_LEFTMULTIPLY);
UpdateOutputDC();
}
void CEmfPlusParser::Read_EMFPLUS_ENDOFFILE()

View File

@ -27,7 +27,6 @@ namespace MetaFile
void SetStream(BYTE *pBytes, unsigned int unSize);
bool GetBanEMFProcesses();
private:
void RegisterObject(CEmfPlusObject* pObject, unsigned int unIndex);

View File

@ -728,7 +728,7 @@ namespace MetaFile
m_oFinalTransform.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
m_oFinalTransform2.Init();
m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
// m_oFinalTransform2.Multiply(m_oTransform, MWT_RIGHTMULTIPLY);
m_oFinalTransform2.Multiply(oViewportXForm, MWT_RIGHTMULTIPLY);
m_oFinalTransform2.Multiply(oWindowXForm, MWT_RIGHTMULTIPLY);
}

View File

@ -79,6 +79,26 @@ namespace MetaFile
height = oRectF.dHeight;
}
void CEmfPlusBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
{
if (arGradientColors.empty())
{
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
arPositions = {0., 1.};
return;
}
arColors.resize(arGradientColors.size());
arPositions.resize(arGradientColors.size());
for (unsigned int unIndex = 0; unIndex < arGradientColors.size(); ++unIndex)
{
arColors[unIndex] = METAFILE_RGBA(arGradientColors[unIndex].first.chRed, arGradientColors[unIndex].first.chGreen, arGradientColors[unIndex].first.chBlue, arGradientColors[unIndex].first.chAlpha);
arPositions[unIndex] = arGradientColors[unIndex].second;
}
}
CEmfPlusPen::CEmfPlusPen()
: unStyle(PS_SOLID | PS_GEOMETRIC | PS_STARTCAP_FLAT | PS_ENDCAP_FLAT | PS_JOIN_MITER), dWidth(1), oColor(0, 0, 0),
pBrush(NULL), dMiterLimit(0), dDashOffset(0),
@ -90,7 +110,7 @@ namespace MetaFile
RELEASEOBJECT(pBrush)
RELEASEARRAYOBJECTS(pDataDash)
RELEASEOBJECT(pLineStartCapData)
RELEASEOBJECT(pLineEndCapData)
RELEASEOBJECT(pLineEndCapData)
}
EEmfObjectType CEmfPlusPen::GetType() const
@ -148,6 +168,16 @@ namespace MetaFile
unSize = unSizeDash;
}
const ILineCap* CEmfPlusPen::GetStartLineCap() const
{
return pLineStartCapData;
}
const ILineCap* CEmfPlusPen::GetEndLineCap() const
{
return pLineEndCapData;
}
CEmfPlusFont::CEmfPlusFont()
: m_dEmSize(18), m_unSizeUnit(0), m_bBold(false),
m_bItalic(false), m_bUnderline(false), m_bStrikeout(false),

View File

@ -189,6 +189,7 @@ namespace MetaFile
void GetCenterPoint(double& dX, double& dY) const override;
void GetBounds(double& left, double& top, double& width, double& height) const override;
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
public:
TEmfPlusARGB oColor;
TEmfPlusARGB oColorBack;
@ -198,6 +199,8 @@ namespace MetaFile
TEmfPlusPointF oCenterPoint;
unsigned int unAngle;
std::wstring wsDibPatternPath;
std::vector<std::pair<TEmfPlusARGB, double>> arGradientColors;
};
class CEmfPlusPen: public CEmfPlusObject, public IPen
@ -209,14 +212,15 @@ namespace MetaFile
virtual EEmfPlusObjectType GetObjectType() const override;
// IPen
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
const ILineCap* GetStartLineCap() const override;
const ILineCap* GetEndLineCap() const override;
public:
unsigned int unStyle;
double dWidth;

View File

@ -2,6 +2,7 @@
#define EMFPLUSTYPES_H
#include "EmfTypes.h"
#include "../Common/MetaFileObjects.h"
namespace MetaFile
{
@ -243,7 +244,7 @@ namespace MetaFile
CustomLineCapDataLinePath = 0x00000002
} CustomLineCapDataFlags;
class CLineCapData
class CLineCapData : public ILineCap
{
public:
CLineCapData() {};

View File

@ -448,6 +448,37 @@ namespace MetaFile
return false;
}
bool CMetaFile::LoadFromString(const std::wstring& data)
{
#ifdef METAFILE_SUPPORT_SVG
RELEASEINTERFACE(m_pFontManager);
if (m_pAppFonts)
{
m_pFontManager = m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
}
m_oSvgFile.SetFontManager(m_pFontManager);
if (m_oSvgFile.ReadFromWString(data) == true)
{
m_lType = c_lMetaSvg;
return true;
}
#endif
return false;
}
void CMetaFile::SetTempDirectory(const std::wstring& dir)
{
#ifdef METAFILE_SUPPORT_SVG
m_oSvgFile.SetWorkingDirectory(dir);
#endif
}
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer)

View File

@ -64,6 +64,7 @@ namespace MetaFile
bool LoadFromFile(const wchar_t* wsFilePath);
bool LoadFromBuffer(BYTE* pBuffer, unsigned int unSize);
bool LoadFromString(const std::wstring& data);
bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
void Close();
void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH);
@ -75,6 +76,8 @@ namespace MetaFile
//конвертация в Svg
std::wstring ConvertToSvg(unsigned int unWidth = 0, unsigned int unHeight = 0);
void SetTempDirectory(const std::wstring& dir);
//Для тестов
#ifdef METAFILE_SUPPORT_WMF_EMF
void ConvertToXml(const wchar_t *wsFilePath);

View File

@ -358,6 +358,12 @@ void CSvmBrush::GetBounds(double& left, double& top, double& width, double& heig
void CSvmBrush::GetDibPattern(unsigned char **pBuffer, unsigned int &unWidth, unsigned int &unHeight) const
{}
void CSvmBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
{
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
arPositions = {0., 1.};
}
int CSvmPen::GetColor() const
{
return METAFILE_RGBA(Color.r, Color.g, Color.b, 0);

View File

@ -300,6 +300,7 @@ public:
void GetBounds(double& left, double& top, double& width, double& height) const override;
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
public:
unsigned short BrushStyleEx; //angle, or ....
unsigned short BrushStyle;
@ -448,6 +449,14 @@ public:
arDatas = NULL;
unSize = 0;
}
const ILineCap* GetStartLineCap() const override
{
return NULL;
}
const ILineCap* GetEndLineCap() const override
{
return NULL;
}
public:
unsigned short PenStyle;
int Width;

View File

@ -75,7 +75,8 @@ namespace MetaFile
};
CInterpretatorSvgBase::CInterpretatorSvgBase(IMetaFileBase *pParser, double dWidth, double dHeight)
: m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()), m_bExternXmlWriter(false), m_bUpdatedClip(true)
: m_oSizeWindow(dWidth, dHeight), m_unNumberDefs(0), m_pParser(pParser), m_pXmlWriter(new XmlUtils::CXmlWriter()),
m_bExternXmlWriter(false), m_bUpdatedClip(true), m_eShapeRendering(EShapeRendering::Auto)
{}
CInterpretatorSvgBase::~CInterpretatorSvgBase()
@ -127,6 +128,11 @@ namespace MetaFile
return m_pXmlWriter;
}
void CInterpretatorSvgBase::SetShapeRendering(EShapeRendering eShapeRenderingType)
{
m_eShapeRendering = eShapeRenderingType;
}
std::wstring CInterpretatorSvgBase::GetFile()
{
return m_pXmlWriter->GetXmlString();
@ -211,16 +217,6 @@ namespace MetaFile
m_pXmlWriter->WriteNodeEnd(wsNodeName, false, false);
}
static void EraseWords(std::wstring& wsString, const std::vector<std::wstring>& arWords)
{
size_t unBegin = 0;
for (const std::wstring& wsWord : arWords)
{
while (std::wstring::npos != (unBegin = wsString.find(wsWord)))
wsString.erase(unBegin, wsWord.length());
}
}
void CInterpretatorSvgBase::WriteText(const std::wstring &wsText, const TPointD &oCoord, const TRectL &oBounds, const TPointD &oScale, const std::vector<double>& arDx)
{
if (NULL == m_pParser || NULL == m_pParser->GetFont())
@ -256,30 +252,31 @@ namespace MetaFile
WriteNodeBegin(L"g", {});
bWriteG = true;
WriteNode(L"rect", {{L"x", ConvertToWString(oBounds.Left)},
{L"y", ConvertToWString(oBounds.Top)},
{L"width", ConvertToWString(oBounds.Right - oBounds.Left)},
{L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)},
{L"fill", wsFillRect},
{L"stroke", L"none"}});
NodeAttributes arRectAttributes{{L"x", ConvertToWString(oBounds.Left)},
{L"y", ConvertToWString(oBounds.Top)},
{L"width", ConvertToWString(oBounds.Right - oBounds.Left)},
{L"height", ConvertToWString(oBounds.Bottom - oBounds.Top)},
{L"fill", wsFillRect},
{L"stroke", L"none"}};
AddShapeRendering(arRectAttributes);
WriteNode(L"rect", arNodeAttributes);
}
int nColor = m_pParser->GetTextColor();
if (0 != nColor)
arNodeAttributes.push_back({L"fill", CalculateColor(nColor, 255)});
arNodeAttributes.Add(L"fill", CalculateColor(nColor, 255));
const IFont *pFont = m_pParser->GetFont();
if (NULL == pFont)
return;
double dFontHeight = std::fabs(pFont->GetHeight());
if (dFontHeight < 0.01)
dFontHeight = 18;
dFontHeight = DEFAULT_FONT_SIZE;
arNodeAttributes.push_back({L"font-size", ConvertToWString(dFontHeight)});
arNodeAttributes.Add(L"font-size", dFontHeight);
NSStringUtils::CStringBuilder oFontName;
oFontName.WriteEncodeXmlString(pFont->GetFaceName());
@ -302,21 +299,21 @@ namespace MetaFile
oFontName.WriteEncodeXmlString(L"\'");
}
#endif
arNodeAttributes.push_back({L"font-family", oFontName.GetData()});
arNodeAttributes.Add(L"font-family", oFontName.GetData());
}
if (pFont->GetWeight() > 550)
arNodeAttributes.push_back({L"font-weight", L"bold"});
arNodeAttributes.Add(L"font-weight", L"bold");
if (pFont->IsItalic())
arNodeAttributes.push_back({L"font-style", L"italic"});
arNodeAttributes.Add(L"font-style", L"italic");
if (pFont->IsUnderline() && pFont->IsStrikeOut())
arNodeAttributes.push_back({L"text-decoration", L"underline line-through"});
arNodeAttributes.Add(L"text-decoration", L"underline line-through");
else if (pFont->IsUnderline())
arNodeAttributes.push_back({L"text-decoration", L"underline"});
arNodeAttributes.Add(L"text-decoration", L"underline");
else if (pFont->IsStrikeOut())
arNodeAttributes.push_back({L"text-decoration", L"line-through"});
arNodeAttributes.Add(L"text-decoration", L"line-through");
//TODO:: разобраться для корректной работы
// double dFontCharSpace = pFont->GetCharSet();
@ -338,14 +335,14 @@ namespace MetaFile
}
else if (ulTextAlign & TA_BOTTOM || ulVTextAlign == VTA_BOTTOM)
{
arNodeAttributes.push_back({L"dominant-baseline", L"auto"});
arNodeAttributes.Add(L"dominant-baseline", L"auto");
if (ulVTextAlign != VTA_BOTTOM)
ulTextAlign -= TA_BOTTOM;
}
else if (ulVTextAlign == VTA_CENTER)
{
arNodeAttributes.push_back({L"dominant-baseline", L"middle"});
arNodeAttributes.Add(L"dominant-baseline", L"middle");
}
else // if (ulTextAlign & TA_TOP)
{
@ -355,14 +352,14 @@ namespace MetaFile
if (ulTextAlign == TA_RIGHT)
{
if (arDx.empty())
arNodeAttributes.push_back({L"text-anchor", L"end"});
arNodeAttributes.Add(L"text-anchor", L"end");
else
dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0);
}
else if (ulTextAlign == TA_CENTER)
{
if (arDx.empty())
arNodeAttributes.push_back({L"text-anchor", L"middle"});
arNodeAttributes.Add(L"text-anchor", L"middle");
else
dXCoord -= std::accumulate(arDx.begin(), arDx.end(), 0.0) / 2;
}
@ -394,7 +391,7 @@ namespace MetaFile
if (oScale.Y < -0.00001)
dXCoord -= dFontHeight * dSin;
arNodeAttributes.push_back({L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')'});
arNodeAttributes.Add(L"transform", L"rotate(" + ConvertToWString(dEscapement) + L' ' + ConvertToWString(dXCoord) + L' ' + ConvertToWString(dYCoord) + L')');
if (oScale.Y > 0.00001)
dXCoord -= dFontHeight * dSin;
@ -402,7 +399,7 @@ namespace MetaFile
AddTransform(arNodeAttributes, &oTransform);
arNodeAttributes.push_back({L"xml:space", L"preserve"});
arNodeAttributes.Add(L"xml:space", L"preserve");
size_t unPosLineBreak = wsNormalizedText.find(L"\n");
@ -424,8 +421,8 @@ namespace MetaFile
if (std::wstring::npos == unPosLineBreak)
{
arNodeAttributes.push_back({L"x", wsXCoord});
arNodeAttributes.push_back({L"y", ConvertToWString(dYCoord)});
arNodeAttributes.Add(L"x", wsXCoord);
arNodeAttributes.Add(L"y", dYCoord);
WriteNode(L"text", arNodeAttributes, wsNormalizedText);
}
@ -439,7 +436,7 @@ namespace MetaFile
do
{
WriteNode(L"tspan", {{L"x", wsXCoord},
{L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart));
{L"y", ConvertToWString(dYNewCoord)}}, wsNormalizedText.substr(unStart, unPosLineBreak - unStart));
dYNewCoord += dFontHeight * 1.6;
unStart = wsNormalizedText.find_first_not_of(L"\n", unPosLineBreak);
@ -499,6 +496,7 @@ namespace MetaFile
{L"height", ConvertToWString(dH)},
{L"fill", CalculateColor(pBuffer[2], pBuffer[1], pBuffer[0], 255)}};
AddShapeRendering(arAttributes);
AddTransform(arAttributes, &oTransform);
AddClip();
@ -562,16 +560,18 @@ namespace MetaFile
void CInterpretatorSvgBase::IntersectClip(const TRectD &oClip)
{
double dLeft = oClip.Left;
double dTop = oClip.Top;
double dRight = oClip.Right;
double dBottom = oClip.Bottom;
TRectD oUpdatedClip{oClip};
m_pParser->GetTransform().Apply(dLeft, dTop);
m_pParser->GetTransform().Apply(dRight, dBottom);
NormalizeRect(oUpdatedClip);
m_pParser->GetTransform().Apply(oUpdatedClip.Left, oUpdatedClip.Top);
m_pParser->GetTransform().Apply(oUpdatedClip.Right, oUpdatedClip.Bottom);
const std::wstring wsId = L"INTERSECTCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
const std::wstring wsValue = L"<rect x=\"" + ConvertToWString(dLeft, 0) + L"\" y=\"" + ConvertToWString(dTop, 0) + L"\" width=\"" + ConvertToWString(dRight - dLeft, 0) + L"\" height=\"" + ConvertToWString(dBottom - dTop, 0) + L"\"/>";
const std::wstring wsValue = L"<rect x=\"" + ConvertToWString(oUpdatedClip.Left, 0) +
L"\" y=\"" + ConvertToWString(oUpdatedClip.Top, 0) +
L"\" width=\"" + ConvertToWString(oUpdatedClip.Right - oUpdatedClip.Left, 0) +
L"\" height=\"" + ConvertToWString(oUpdatedClip.Bottom - oUpdatedClip.Top, 0) + L"\"/>";
m_oClip.AddClipValue(wsId, wsValue);
}
@ -579,28 +579,24 @@ namespace MetaFile
void CInterpretatorSvgBase::ExcludeClip(const TRectD &oClip, const TRectD &oBB)
{
const TXForm &oTransform{m_pParser->GetTransform()};
double dClipLeft = oClip.Left;
double dClipTop = oClip.Top;
double dClipRight = oClip.Right;
double dClipBottom = oClip.Bottom;
oTransform.Apply(dClipLeft, dClipTop);
oTransform.Apply(dClipRight, dClipBottom);
TRectD oUpdatedClip{oClip};
NormalizeRect(oUpdatedClip);
double dBBLeft = oBB.Left;
double dBBTop = oBB.Top;
double dBBRight = oBB.Right;
double dBBBottom = oBB.Bottom;
oTransform.Apply(oUpdatedClip.Left, oUpdatedClip.Top);
oTransform.Apply(oUpdatedClip.Right, oUpdatedClip.Bottom);
oTransform.Apply(dBBLeft, dBBTop);
oTransform.Apply(dBBRight, dBBBottom);
TRectD oBBRect{oBB};
NormalizeRect(oBBRect);
oTransform.Apply(oBBRect.Left, oBBRect.Top);
oTransform.Apply(oBBRect.Right, oBBRect.Bottom);
const std::wstring wsId = L"EXCLUDECLIP_" + ConvertToWString(++m_unNumberDefs, 0);
const std::wstring wsValue = L"<path d=\"M" + ConvertToWString(dBBLeft) + L' ' + ConvertToWString(dBBTop) + L", L" + ConvertToWString(dBBRight) + L' ' + ConvertToWString(dBBTop) + L", " +
ConvertToWString(dBBRight) + L' ' + ConvertToWString(dBBBottom) + L", " + ConvertToWString(dBBLeft ) + L' ' + ConvertToWString(dBBBottom) + L", M" +
ConvertToWString(dClipLeft) + L' ' + ConvertToWString(dClipTop) + L", L" + ConvertToWString(dClipRight) + L' ' + ConvertToWString(dClipTop) + L", " +
ConvertToWString(dClipRight) + L' ' + ConvertToWString(dClipBottom) + L", " + ConvertToWString(dClipLeft) + L' ' + ConvertToWString(dClipLeft ) + L"\" clip-rule=\"evenodd\"/>";
const std::wstring wsValue = L"<path d=\"M" + ConvertToWString(oBBRect.Left) + L' ' + ConvertToWString(oBBRect.Top) + L", L" + ConvertToWString(oBBRect.Right) + L' ' + ConvertToWString(oBBRect.Top) + L", " +
ConvertToWString(oBBRect.Right) + L' ' + ConvertToWString(oBBRect.Bottom) + L", " + ConvertToWString(oBBRect.Left) + L' ' + ConvertToWString(oBBRect.Bottom) + L", Z M" +
ConvertToWString(oUpdatedClip.Left) + L' ' + ConvertToWString(oUpdatedClip.Top) + L", L" + ConvertToWString(oUpdatedClip.Right) + L' ' + ConvertToWString(oUpdatedClip.Top) + L", " +
ConvertToWString(oUpdatedClip.Right) + L' ' + ConvertToWString(oUpdatedClip.Bottom) + L", " + ConvertToWString(oUpdatedClip.Left) + L' ' + ConvertToWString(oUpdatedClip.Bottom) + L" Z\" clip-rule=\"evenodd\"/>";
m_oClip.AddClipValue(wsId, wsValue);
}
@ -630,10 +626,10 @@ namespace MetaFile
switch (m_pParser->GetRop2Mode())
{
case R2_BLACK: arAttributes.push_back({L"stroke", L"rgb(0, 0, 0)"}); break;
case R2_BLACK: arAttributes.Add(L"stroke", L"rgb(0, 0, 0)"); break;
case R2_NOP: return;
case R2_WHITE: arAttributes.push_back({L"stroke", L"rgb(255, 255, 255)"}); break;
default: arAttributes.push_back({L"stroke", CalculateColor(pPen->GetColor(), pPen->GetAlpha())}); break;
case R2_WHITE: arAttributes.Add(L"stroke", L"rgb(255, 255, 255)"); break;
default: arAttributes.Add(L"stroke", CalculateColor(pPen->GetColor(), pPen->GetAlpha())); break;
}
unsigned int unMetaPenStyle = pPen->GetStyle();
@ -668,19 +664,16 @@ namespace MetaFile
double dStrokeWidth = std::fabs(m_pParser->GetPen()->GetWidth());
if (Equals(0, dStrokeWidth) || (Equals(1, dStrokeWidth) && PS_COSMETIC == (m_pParser->GetPen()->GetStyle() & PS_TYPE_MASK)))
if (Equals(0., dStrokeWidth))
{
dStrokeWidth = 1;
arAttributes.push_back({L"vector-effect", L"non-scaling-stroke"});
wsLineCap = L"butt";
wsLineJoin = L"miter";
dStrokeWidth = 1.;
arAttributes.Add(L"vector-effect", L"non-scaling-stroke");
}
arAttributes.push_back({L"stroke-width", ConvertToWString(dStrokeWidth)});
arAttributes.push_back({L"stroke-miterlimit", ConvertToWString(pPen->GetMiterLimit())});
arAttributes.push_back({L"stroke-linecap", wsLineCap});
arAttributes.push_back({L"stroke-linejoin", wsLineJoin});
arAttributes.Add(L"stroke-width", dStrokeWidth);
arAttributes.Add(L"stroke-miterlimit", pPen->GetMiterLimit());
arAttributes.Add(L"stroke-linecap", wsLineCap);
arAttributes.Add(L"stroke-linejoin", wsLineJoin);
double* arDatas = NULL;
unsigned int unDataSize = 0;
@ -700,23 +693,23 @@ namespace MetaFile
}
wsDashArray.pop_back();
arAttributes.push_back({L"stroke-dasharray", wsDashArray});
arAttributes.Add(L"stroke-dasharray", wsDashArray);
}
else if (PS_DASH == ulPenStyle)
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2)});
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2));
else if (PS_DOT == ulPenStyle)
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth)});
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth));
else if (PS_DASHDOT == ulPenStyle)
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)});
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2));
else if (PS_DASHDOTDOT == ulPenStyle)
arAttributes.push_back({L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2)});
arAttributes.Add(L"stroke-dasharray", ConvertToWString(dStrokeWidth * 4) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2) + L' ' + ConvertToWString(dStrokeWidth) + L' ' + ConvertToWString(dStrokeWidth * 2));
}
void CInterpretatorSvgBase::AddFill(NodeAttributes &arAttributes, double dWidth, double dHeight)
{
if (NULL == m_pParser)
{
arAttributes.push_back({L"fill", L"none"});
arAttributes.Add(L"fill", L"none");
return;
}
@ -735,7 +728,7 @@ namespace MetaFile
if (NULL == pBrush || BS_NULL == pBrush->GetStyle())
{
arAttributes.push_back({L"fill", L"none"});
arAttributes.Add(L"fill", L"none");
return;
}
@ -743,7 +736,7 @@ namespace MetaFile
{
case BS_SOLID:
{
arAttributes.push_back({L"fill", CalculateColor(pBrush->GetColor(), pBrush->GetAlpha())});
arAttributes.Add(L"fill", CalculateColor(pBrush->GetColor(), pBrush->GetAlpha()));
return;
}
case BS_HATCHED:
@ -752,7 +745,7 @@ namespace MetaFile
if (!wsStyleId.empty())
{
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
return;
}
@ -764,7 +757,7 @@ namespace MetaFile
if (!wsStyleId.empty())
{
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
return;
}
}
@ -774,7 +767,7 @@ namespace MetaFile
if (!wsStyleId.empty())
{
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
return;
}
}
@ -788,12 +781,12 @@ namespace MetaFile
if (!wsStyleId.empty())
{
arAttributes.push_back({L"fill", L"url(#" + wsStyleId + L")"});
arAttributes.Add(L"fill", L"url(#" + wsStyleId + L")");
return;
}
}
default:
arAttributes.push_back({L"fill", L"none"});
arAttributes.Add(L"fill", L"none");
}
}
@ -832,7 +825,7 @@ namespace MetaFile
if (bScale && !bTranslate)
{
wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')';
wsValue = L"scale(" + ConvertToWString(oOldTransform.M11) + L',' + ConvertToWString(oOldTransform.M22) + L')';
}
else if (bTranslate && !bScale)
{
@ -840,18 +833,18 @@ namespace MetaFile
}
else if (bScale && bTranslate)
{
wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' +
ConvertToWString(oOldTransform.M12) + L',' +
ConvertToWString(oOldTransform.M21) + L',' +
ConvertToWString(oOldTransform.M22) + L',' +
ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')';
wsValue = L"matrix(" + ConvertToWString(oOldTransform.M11) + L',' +
ConvertToWString(oOldTransform.M12) + L',' +
ConvertToWString(oOldTransform.M21) + L',' +
ConvertToWString(oOldTransform.M22) + L',' +
ConvertToWString(oOldTransform.Dx) + L',' + ConvertToWString(oOldTransform.Dy) + L')';
}
else return;
if (NULL != pFoundTransform)
pFoundTransform->second.insert(0, wsValue + L' ');
else
arAttributes.push_back({L"transform", wsValue});
arAttributes.Add(L"transform", wsValue);
}
void CInterpretatorSvgBase::AddClip()
@ -891,7 +884,101 @@ namespace MetaFile
void CInterpretatorSvgBase::AddNoneFill(NodeAttributes &arAttributes) const
{
arAttributes.push_back({L"fill", L"none"});
arAttributes.Add(L"fill", L"none");
}
void CInterpretatorSvgBase::AddShapeRendering(NodeAttributes& arAttributes) const
{
switch (m_eShapeRendering)
{
case EShapeRendering::OptimizeSpeed:
{
arAttributes.Add(L"shape-rendering", L"optimizeSpeed");
break;
}
case EShapeRendering::CrispEdges:
{
arAttributes.Add(L"shape-rendering", L"crispEdges");
break;
}
case EShapeRendering::GeometricPrecision:
{
arAttributes.Add(L"shape-rendering", L"geometricPrecision");
break;
}
default:
break;
}
}
TPointD GetFirstPoint(const CPathCommandBase* pPathCommand)
{
if (NULL == pPathCommand)
return {0., 0.};
switch (pPathCommand->GetType())
{
case EPathCommandType::PATH_COMMAND_MOVETO:
{
CPathCommandMoveTo* pMoveTo{(CPathCommandMoveTo*)pPathCommand};
return {pMoveTo->GetX(), pMoveTo->GetY()};
}
case EPathCommandType::PATH_COMMAND_LINETO:
{
CPathCommandLineTo* pLineTo{(CPathCommandLineTo*)pPathCommand};
return {pLineTo->GetX(), pLineTo->GetY()};
}
default:
return {0., 0.};
}
}
void CInterpretatorSvgBase::AddLineCaps(NodeAttributes& arAttributes, const CPath* pMainPath)
{
if (NULL == m_pParser || NULL == m_pParser->GetPen() || NULL == pMainPath)
return;
const IPen *pPen = m_pParser->GetPen();
const std::vector<CPathCommandBase *> arCommands{pMainPath->GetCommands()};
const CLineCapData* pStartLineCap = dynamic_cast<const CLineCapData*>(pPen->GetStartLineCap());
if (NULL != pStartLineCap)
{
double dAngle = 0.;
if (arCommands.size() > 1)
{
const TPointD oFirstPoint {GetFirstPoint(arCommands[0])};
const TPointD oSecondPoint{GetFirstPoint(arCommands[1])};
dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.;
}
const std::wstring wsStartLineCapId{CreateLineCap(pStartLineCap, dAngle)};
if (!wsStartLineCapId.empty())
arAttributes.Add(L"marker-start", L"url(#" + wsStartLineCapId + L')');
}
const CLineCapData* pEndLineCap = dynamic_cast<const CLineCapData*>(pPen->GetEndLineCap());
if (NULL != pEndLineCap)
{
double dAngle = 0.;
if (arCommands.size() > 1)
{
const TPointD oFirstPoint {GetFirstPoint(arCommands[arCommands.size() - 1])};
const TPointD oSecondPoint{GetFirstPoint(arCommands[arCommands.size() - 2])};
dAngle = (atan2((oSecondPoint.Y - oFirstPoint.Y), (oSecondPoint.X - oFirstPoint.X))) / M_PI * 180. + 90.;
}
const std::wstring wsEndLineCapId{CreateLineCap(pEndLineCap, dAngle)};
if (!wsEndLineCapId.empty())
arAttributes.Add(L"marker-end", L"url(#" + wsEndLineCapId + L')');
}
}
TPointD CInterpretatorSvgBase::GetCutPos() const
@ -902,7 +989,7 @@ namespace MetaFile
return TPointD(m_oViewport.dLeft, m_oViewport.dRight);
}
std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform)
std::wstring CInterpretatorSvgBase::CreatePath(const CPath& oPath, const TXForm *pTransform) const
{
if (NULL == m_pParser || oPath.Empty())
return std::wstring();
@ -969,9 +1056,9 @@ namespace MetaFile
oTransform.Apply(oPoint2.X, oPoint2.Y);
oTransform.Apply(oPointE.X, oPointE.Y);
wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' +
ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' +
ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' ';
wsValue += ConvertToWString(oPoint1.X) + L',' + ConvertToWString(oPoint1.Y) + L' ' +
ConvertToWString(oPoint2.X) + L',' + ConvertToWString(oPoint2.Y) + L' ' +
ConvertToWString(oPointE.X) + L',' + ConvertToWString(oPointE.Y) + L' ';
break;
}
@ -1187,16 +1274,23 @@ namespace MetaFile
std::wstring wsStyleId;
if (BS_LINEARGRADIENT == pBrush->GetStyle() ||
BS_RECTGRADIENT == pBrush->GetStyle() ||
BS_PATHGRADIENT == pBrush->GetStyle())
if (BS_LINEARGRADIENT == pBrush->GetStyle() ||
BS_RECTGRADIENT == pBrush->GetStyle() ||
BS_PATHGRADIENT == pBrush->GetStyle())
{
wsStyleId = L"LINEARGRADIENT_" + ConvertToWString(++m_unNumberDefs, 0);
m_wsDefs += L"<linearGradient id=\"" + wsStyleId + L"\">" +
L"<stop offset=\"0%\" stop-color=\"" + CalculateColor(pBrush->GetColor(), pBrush->GetAlpha()) + L"\"/>" +
L"<stop offset=\"100%\" stop-color=\"" + CalculateColor(pBrush->GetColor2(), pBrush->GetAlpha2()) + L"\"/>" +
L"</linearGradient>";
m_wsDefs += L"<linearGradient id=\"" + wsStyleId + L"\">";
std::vector<long> arColors;
std::vector<double> arPositions;
pBrush->GetGradientColors(arColors, arPositions);
for (unsigned int unIndex = 0; unIndex < arColors.size(); ++unIndex)
m_wsDefs += L"<stop offset=\"" + ConvertToWString(arPositions[unIndex], 2) +
L"\" stop-color=\"" + CalculateColor(arColors[unIndex]) + L"\"/>";
m_wsDefs += L"</linearGradient>";
return wsStyleId;
}
@ -1237,6 +1331,46 @@ namespace MetaFile
return std::wstring();
}
std::wstring CInterpretatorSvgBase::CreateLineCap(const CLineCapData* pLineCap, const double& dAngle)
{
if (NULL == pLineCap)
return std::wstring();
CustomLineCapDataType enLineCapDataType = pLineCap->GetType();
if (CustomLineCapDataType::CustomLineCapDataTypeDefault == enLineCapDataType)
{
const TEmfPlusCustomLineCapData* pCustomLineCap = dynamic_cast<const TEmfPlusCustomLineCapData*>(pLineCap);
if (NULL == pCustomLineCap)
return std::wstring();
const std::wstring wsPath = CreatePath(*pCustomLineCap->pPath);
if (wsPath.empty())
return std::wstring();
const std::wstring wsMarkerId {L"CUSTOM_MARKER_" + std::to_wstring(++m_unNumberDefs)};
const TRectD oPathBounds{pCustomLineCap->pPath->GetBounds()};
const double dWidth {std::abs(oPathBounds.Right - oPathBounds.Left)};
const double dHeight {std::abs(oPathBounds.Bottom - oPathBounds.Top)};
const std::wstring wsWidth {ConvertToWString(dWidth)};
const std::wstring wsHeight {ConvertToWString(dHeight)};
const std::wstring wsViewBox {L"viewBox=\"" + ConvertToWString(oPathBounds.Left) + L' ' + ConvertToWString(oPathBounds.Top) +
L' ' + wsWidth + L' ' + wsHeight + L'\"'};
const double dRefY = -dHeight * (std::min)(3. / dWidth, 3. / dHeight);
m_wsDefs += L"<marker id=\"" + wsMarkerId + L"\" " + wsViewBox + L" markerWidth=\"" +
wsWidth + L"\" markerHeight=\"" + wsHeight + L"\" refY=\"" + ConvertToWString(dRefY) +
L"\" orient=\"" + std::to_wstring(dAngle) + L"\"><path d=\"" + wsPath + L"\"/></marker>";
return wsMarkerId;
}
return std::wstring();
}
CHatchGenerator::CHatchGenerator()
: m_nHatchStyle(-1), m_unNumber(0), m_chStrokeAlpha(255), m_nBackgroundColor(-1), m_chBackgroundAlpha(255)
{}
@ -1936,4 +2070,29 @@ namespace MetaFile
return L"rgba(" + std::to_wstring(uchRed) + L", " + std::to_wstring(uchGreen) + L", " + std::to_wstring(uchBlue) + L", " + ConvertToWString((double)uchAlpha / 255., 3) + L')';
}
std::wstring CalculateColor(unsigned int unColor)
{
BYTE chAlpha = unColor >> 24;
return CalculateColor(unColor, chAlpha);
}
void NormalizeRect(TRectD& oRect)
{
if (oRect.Right < oRect.Left)
std::swap(oRect.Right, oRect.Left);
if (oRect.Bottom < oRect.Top)
std::swap(oRect.Bottom, oRect.Top);
}
TRectD TranslateRect(const TRectL& oRect)
{
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
NormalizeRect(oNewRect);
return oNewRect;
}
}

View File

@ -62,8 +62,8 @@ namespace MetaFile
void AddClipValue(const std::wstring& wsId, const std::wstring& wsValue, int nClipMode = RGN_AND);
inline std::wstring GetClip() const;
inline std::wstring GetClipId() const;
std::wstring GetClip() const;
std::wstring GetClipId() const;
private:
struct TClipValue
{
@ -77,6 +77,14 @@ namespace MetaFile
bool m_bStartClip;
};
enum class EShapeRendering
{
Auto,
OptimizeSpeed,
CrispEdges,
GeometricPrecision
};
class CInterpretatorSvgBase : public IOutputDevice
{
public:
@ -90,6 +98,8 @@ namespace MetaFile
void SetXmlWriter(XmlUtils::CXmlWriter* pXmlWriter);
XmlUtils::CXmlWriter* GetXmlWriter();
void SetShapeRendering(EShapeRendering eShapeRenderingType);
std::wstring GetFile();
void IncludeSvg(const std::wstring& wsSvg, const TRectD& oRect, const TRectD& oClipRect, TXForm *pTransform);
private:
@ -115,14 +125,18 @@ namespace MetaFile
void CloseClip();
void AddNoneFill(NodeAttributes &arAttributes) const;
void AddShapeRendering(NodeAttributes &arAttributes) const;
void AddLineCaps(NodeAttributes &arAttributes, const CPath* pMainPath);
TPointD GetCutPos() const;
std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL);
std::wstring CreatePath(const CPath& oPath, const TXForm* pTransform = NULL) const;
std::wstring CreateHatchStyle(unsigned int unHatchStyle, double dWidth, double dHeight);
std::wstring CreateDibPatternStyle(const IBrush* pBrush);
std::wstring CreatePatternStyle(const IBrush* pBrush);
std::wstring CreateGradient(const IBrush *pBrush);
std::wstring CreateLineCap(const CLineCapData* pLineCap, const double& dAngle);
private:
TSvgViewport m_oViewport;
TPointD m_oSizeWindow;
@ -138,12 +152,17 @@ namespace MetaFile
bool m_bUpdatedClip;
CSvgClip m_oClip;
EShapeRendering m_eShapeRendering;
friend class CEmfInterpretatorSvg;
friend class CWmfInterpretatorSvg;
};
std::wstring CalculateColor(unsigned int unColor);
std::wstring CalculateColor(unsigned int unColor, BYTE uchAlpha);
std::wstring CalculateColor(BYTE uchRed, BYTE uchGreen, BYTE uchBlue, BYTE uchAlpha);
void NormalizeRect(TRectD& oRect);
TRectD TranslateRect(const TRectL &oRect);
}
#endif // CINTERPRETATORSVGBASE_H

View File

@ -29,7 +29,7 @@ namespace MetaFile
}
void CWmfInterpretatorRender::DrawString(std::wstring &wsText, unsigned int unCharsCount, double dX, double dY, double *pDx,
int iGraphicsMode, double dXScale, double dYScale)
int iGraphicsMode, double dXScale, double dYScale)
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->DrawString(wsText, unCharsCount, dX, dY, pDx, iGraphicsMode, dXScale, dYScale);

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) override;
void DrawString(std::wstring& wsText, unsigned int unCharsCount, double dX, double dY, double* pDx,
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override;
int iGraphicsMode = 1, double dXScale = 1, double dYScale = 1) override;
void DrawDriverString(const std::wstring& wsString, const std::vector<TPointD>& arPoints) override;

View File

@ -110,6 +110,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -136,6 +137,7 @@ namespace MetaFile
{L"ry", ConvertToWString((oNewRect.Bottom - oNewRect.Top) / 2)}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -189,6 +191,7 @@ namespace MetaFile
NodeAttributes arAttributes = {{L"d", wsValue}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -215,6 +218,7 @@ namespace MetaFile
{L"y2", ConvertToWString(shY)}};
AddStroke(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -230,12 +234,13 @@ namespace MetaFile
{
TRectD oNewRect;
NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)},
{L"y", ConvertToWString(shY)},
{L"width", ConvertToWString(shW)},
{L"height", ConvertToWString(shH)}};
NodeAttributes arAttributes = {{L"x", ConvertToWString(shX)},
{L"y", ConvertToWString(shY)},
{L"width", ConvertToWString(shW)},
{L"height", ConvertToWString(shH)}};
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -260,6 +265,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -280,6 +286,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddNoneFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -300,6 +307,7 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -327,30 +335,27 @@ namespace MetaFile
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
arAttributes.push_back({L"fill-rule", L"evenodd"});
arAttributes.Add(L"fill-rule", L"evenodd");
WriteNode(L"path", arAttributes);
}
void CWmfInterpretatorSvg::HANDLE_META_RECTANGLE(short shB, short shR, short shT, short shL)
{
TRectD oNewRect;
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
oNewRect.Left = shL;
oNewRect.Top = shT;
oNewRect.Right = shR;
oNewRect.Bottom = shB;
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();
@ -359,22 +364,18 @@ namespace MetaFile
void CWmfInterpretatorSvg::HANDLE_META_ROUNDRECT(short shH, short shW, short shB, short shR, short shT, short shL)
{
TRectD oNewRect;
TRectD oNewRect = TranslateRect({shL, shT, shR, shB});
oNewRect.Left = shL;
oNewRect.Top = shT;
oNewRect.Right = shR;
oNewRect.Bottom = shB;
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
{L"rx", ConvertToWString((double)shW / 2.)},
{L"ry", ConvertToWString((double)shH / 2.)}};
NodeAttributes arAttributes = {{L"x", ConvertToWString(oNewRect.Left)},
{L"y", ConvertToWString(oNewRect.Top)},
{L"width", ConvertToWString(oNewRect.Right - oNewRect.Left)},
{L"height", ConvertToWString(oNewRect.Bottom - oNewRect.Top)},
{L"rx", ConvertToWString((double)shW / 2.)},
{L"ry", ConvertToWString((double)shH / 2.)}};
AddStroke(arAttributes);
AddFill(arAttributes);
AddShapeRendering(arAttributes);
AddTransform(arAttributes);
AddClip();

View File

@ -162,9 +162,24 @@ namespace MetaFile
unHeight = unDibHeigth;
}
void CWmfBrush::GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const
{
arColors = {(long)(GetColor() + (GetAlpha() << 24)), (long)(GetColor2() + (GetAlpha2() << 24))};
arPositions = {0., 1.};
}
CWmfFont::CWmfFont()
: shHeight(DEFAULT_FONT_SIZE), shWidth(0), shEscapement(0), shOrientation(0), shWeight(400),
uchItalic(0x00), uchUnderline(0x00), uchStrikeOut(0x00), uchCharSet(0x01), uchOutPrecision(0x00),
uchClipPrecision(0x00), uchQuality(0x00), uchPitchAndFamily(0x00)
{
memset(uchFacename, 0x00, 32);
uchFacename[0] = 'A';
uchFacename[1] = 'r';
uchFacename[2] = 'i';
uchFacename[3] = 'a';
uchFacename[4] = 'l';
}
CWmfFont::~CWmfFont()
@ -281,6 +296,16 @@ namespace MetaFile
unSize = 0;
}
const ILineCap* CWmfPen::GetStartLineCap() const
{
return NULL;
}
const ILineCap* CWmfPen::GetEndLineCap() const
{
return NULL;
}
CWmfRegion::CWmfRegion() : pScans(NULL)
{}

View File

@ -82,6 +82,8 @@ namespace MetaFile
void GetBounds(double& left, double& top, double& width, double& height) const override;
void GetCenterPoint(double& dX, double& dY) const override;
void GetDibPattern(unsigned char** pBuffer, unsigned int &unWidth, unsigned int &unHeight) const override;
void GetGradientColors(std::vector<long>& arColors, std::vector<double>& arPositions) const override;
public:
unsigned short ushBrushStyle;
@ -146,13 +148,15 @@ namespace MetaFile
virtual EWmfObjectType GetType() const override;
// IPen
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
int GetColor() const override;
unsigned int GetStyle() const override;
double GetWidth() const override;
unsigned int GetAlpha() const override;
double GetMiterLimit() const override;
double GetDashOffset() const override;
void GetDashData(double*& arDatas, unsigned int& unSize) const override;
const ILineCap* GetStartLineCap() const override;
const ILineCap* GetEndLineCap() const override;
public:
unsigned short ushPenStyle;
TPointS oWidth;

View File

@ -194,7 +194,11 @@ namespace MetaFile
RELEASEOBJECT(m_pInterpretator);
if (InterpretatorType::Svg == oInterpretatorType)
m_pInterpretator = new CWmfInterpretatorSvg(this, unWidth, unHeight);
{
CWmfInterpretatorSvg *pWmfInterpretatorSvg = new CWmfInterpretatorSvg(this, unWidth, unHeight);
pWmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
m_pInterpretator = pWmfInterpretatorSvg;
}
}
void CWmfParserBase::SetInterpretator(IOutputDevice *pOutput, const wchar_t *wsFilePath)
@ -233,12 +237,9 @@ namespace MetaFile
m_oDCRect = m_oPlaceable.oBoundingBox;
const USHORT ushFileDpi = GetDpi();
const USHORT ushRendererDpi = 96;
if (ushFileDpi != ushRendererDpi && 0 != ushFileDpi)
if (96 != m_oPlaceable.ushInch)
{
const double dKoef = (double)ushRendererDpi / (double)ushFileDpi;
const double dKoef = 96. / (double)m_oPlaceable.ushInch;
m_oDCRect.Left = std::round(m_oDCRect.Left * dKoef);
m_oDCRect.Top = std::round(m_oDCRect.Top * dKoef);
@ -685,8 +686,8 @@ namespace MetaFile
{
TRectL oClip = oSrcRect;
oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth ) - 1;
oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight) - 1;
oClip.Right = oClip.Left + (std::min)(oClip.Right - oClip.Left, (int)unWidth );
oClip.Bottom = oClip.Top + (std::min)(oClip.Bottom - oClip.Top, (int)unHeight);
BYTE* pNewBuffer = ClipBuffer(pBgra, unWidth, unHeight, oClip);
@ -787,6 +788,8 @@ namespace MetaFile
if (NULL != m_pInterpretator)
{
UpdateDCRect();
m_pDC->SetWindowOrg(m_oDCRect.Left, m_oDCRect.Top);
m_pDC->SetWindowExt(m_oDCRect.Right - m_oDCRect.Left, m_oDCRect.Bottom - m_oDCRect.Top);
m_pDC->SetViewportOrg(m_oDCRect.Left, m_oDCRect.Top);

View File

@ -236,8 +236,8 @@ namespace MetaFile
{
m_pBrush = &m_oDefaultBrush;
m_pPen = &m_oDefaultPen;
m_pFont = &m_oDefaultFont;
m_pPalette = NULL;
m_pFont = NULL;
m_pRegion = NULL;
m_ushMapMode = MM_TEXT;
m_dPixelWidth = 1;
@ -350,7 +350,7 @@ namespace MetaFile
}
const CWmfFont* CWmfDC::GetFont() const
{
return m_pFont;
return (NULL != m_pFont) ? m_pFont : &m_oDefaultFont;
}
void CWmfDC::SetRegion(CWmfRegion* pRegion)
{
@ -609,6 +609,7 @@ namespace MetaFile
if (!m_oViewport.h) m_oViewport.h = nMinCy;
}
}
void CWmfDC::SetTextColor(TRGBA& oColor)
{
m_oTextColor = oColor;

View File

@ -147,6 +147,7 @@ namespace MetaFile
CClip m_oClip;
CWmfBrush m_oDefaultBrush;
CWmfFont m_oDefaultFont;
CWmfPen m_oDefaultPen;
CWmfBrush* m_pBrush;
CWmfPen* m_pPen;

View File

@ -7,15 +7,13 @@
#include "CSvgParser.h"
#include "SvgObjects/CStyle.h"
#define SVG_DECL_IMPORT Q_DECL_IMPORT
namespace SVG
{
struct TFontArguments;
class CFont;
}
class SVG_DECL_IMPORT CSvgFile
class CSvgFile
{
public:
CSvgFile();

View File

@ -6,7 +6,6 @@ namespace SVG
: m_pInternal(new NSCSS::CCssCalculator_Private)
{
m_pInternal->SetDpi(96);
m_pInternal->SetUnitMeasure(NSCSS::UnitMeasure::Pixel);
}
CSvgCalculator::~CSvgCalculator()
@ -30,139 +29,22 @@ namespace SVG
if (NULL == pSvgObject)
return;
const std::map<std::wstring, NSCSS::CElement *> *pData = m_pInternal->GetData();
const std::vector<NSCSS::CNode> arSelectors = pSvgObject->GetFullPath();
if ((NULL == pData || pData->empty()) && arSelectors.empty())
return;
std::vector<std::wstring> arWords;
arWords.reserve(arSelectors.size() * 2);
std::vector<std::wstring> arNextNodes;
arNextNodes.reserve(arSelectors.size() * 2);
for (std::vector<NSCSS::CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
{
arWords.push_back(oNode->m_wsName);
if (!oNode->m_wsClass.empty())
{
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
{
std::vector<std::wstring> arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
if (arClasses.size() > 1)
arClasses.resize(unique(arClasses.begin(),arClasses.end()) - arClasses.begin());
arWords.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arWords.push_back(L'.' + oNode->m_wsClass);
}
if (!oNode->m_wsId.empty())
arWords.push_back(L'#' + oNode->m_wsId);
}
std::vector<NSCSS::CElement*> arElements;
std::vector<std::wstring> arNodes = m_pInternal->CalculateAllNodes(arSelectors);
std::vector<std::wstring> arPrevNodes;
for (size_t i = 0; i < arSelectors.size(); ++i)
{
std::wstring sName, sId;
std::vector<std::wstring> arClasses;
if (arWords.back()[0] == L'#')
{
sId = arWords.back();
arWords.pop_back();
arNextNodes.push_back(sId);
}
if (arWords.back()[0] == L'.')
{
arClasses = NSCSS::NS_STATIC_FUNCTIONS::GetWordsW(arWords.back(), false, L" ");
arNextNodes.push_back(arWords.back());
arWords.pop_back();
}
sName = arWords.back();
arWords.pop_back();
arNextNodes.push_back(sName);
const std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindName = pData->find(sName);
std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindId;
std::vector<NSCSS::CElement*> arFindElements;
if (!sId.empty())
{
oFindId = pData->find(sId);
if (oFindId != std::end(*pData))
{
if (!oFindId->second->Empty())
arFindElements.push_back(oFindId->second);
const std::vector<NSCSS::CElement*> arTempPrev = oFindId->second->GetPrevElements(arNextNodes.rbegin() + ((arClasses.empty()) ? 1 : 2), arNextNodes.rend());
if (!arTempPrev.empty())
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
}
}
if (!arClasses.empty())
{
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
{
const std::map<std::wstring, NSCSS::CElement*>::const_iterator oFindClass = pData->find(*iClass);
if (oFindClass != std::end(*pData))
{
if (!oFindClass->second->Empty())
arFindElements.push_back(oFindClass->second);
const std::vector<NSCSS::CElement*> arTempPrev = oFindClass->second->GetPrevElements(arNextNodes.rbegin() + 2, arNextNodes.rend());
const std::vector<NSCSS::CElement*> arTempKins = oFindClass->second->GetNextOfKin(sName);
if (!arTempPrev.empty())
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end());
}
}
}
if (oFindName != std::end(*pData))
{
if (!oFindName->second->Empty())
arFindElements.push_back(oFindName->second);
const std::vector<NSCSS::CElement*> arTempPrev = oFindName->second->GetPrevElements(arNextNodes.rbegin() + 1, arNextNodes.rend());
const std::vector<NSCSS::CElement*> arTempKins = oFindName->second->GetNextOfKin(sName, arClasses);
if (!arTempPrev.empty())
arFindElements.insert(arFindElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindElements.insert(arFindElements.end(), arTempKins.begin(), arTempKins.end());
}
if (arFindElements.size() > 1)
{
std::sort(arFindElements.rbegin(), arFindElements.rend(),
[](NSCSS::CElement* oFirstElement, NSCSS::CElement* oSecondElement)
{
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
});
}
pSvgObject->SetData(arSelectors[i].m_mAttributes, i + 1);
pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true);
for (const NSCSS::CElement* oElement : arFindElements)
for (const NSCSS::CElement* oElement : m_pInternal->FindElements(arNodes, arPrevNodes))
pSvgObject->SetData(oElement->GetStyle(), i + 1);
if (!arSelectors[i].m_wsStyle.empty())
pSvgObject->SetData(arSelectors[i].m_wsStyle, i + 1, true);
}
return;
}
}

View File

@ -45,21 +45,23 @@ namespace SVG
const CRenderedObject *pFoundObj = dynamic_cast<CRenderedObject*>(pFile->GetMarkedObject(m_wsHref));
if (NULL != pFoundObj)
bool bResult = false;
if (NULL != pFoundObj && this != pFoundObj)
{
if (NULL != pOtherStyles)
{
TSvgStyles oNewStyles(m_oStyles);
oNewStyles += *pOtherStyles;
pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this);
bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &oNewStyles, this);
}
else
pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this);
bResult = pFoundObj->Draw(pRenderer, pFile, oMode, &m_oStyles, this);
}
EndPath(pRenderer, pFile, oOldTransform);
return true;
return bResult;
}
TBounds CUse::GetBounds() const

View File

@ -0,0 +1,91 @@
#include "../../../../graphics/pro/Graphics.h"
#include "../../../../../raster/BgraFrame.h"
#include "../../../../../common/Directory.h"
#define RGB_TO_INT(r, g, b) ((long)( ( (unsigned char)(r) )| ( ( (unsigned char)(g) ) << 8 ) | ( ( (unsigned char)(b) ) << 16 ) | ( (unsigned char)(255) << 24 ) ) )
void DrawLine(IRenderer* pRenderer, unsigned int unX1, unsigned int unY1, unsigned int unX2, unsigned int unY2)
{
pRenderer->BeginCommand(c_nPathType);
pRenderer->PathCommandMoveTo(unX1, unY1);
pRenderer->PathCommandLineTo(unX2, unY2);
pRenderer->DrawPath(c_nStroke);
pRenderer->EndCommand(c_nPathType);
}
void DrawEquilateralPolygon(IRenderer* pRenderer, unsigned int unCenterX, unsigned int unCenterY, unsigned int unRadius, unsigned int unCountCorners)
{
if (nullptr == pRenderer)
return;
unsigned int unX1, unY1, unX2, unY2;
for (unsigned int unIndex = 1; unIndex < unCountCorners; ++unIndex)
{
unX1 = (unsigned int)(unRadius * sin(2 * (unIndex - 1) * M_PI / unCountCorners) + 0.5);
unY1 = (unsigned int)(unRadius * cos(2 * (unIndex - 1) * M_PI / unCountCorners) + 0.5);
unX2 = (unsigned int)(unRadius * sin(2 * (unIndex - 0) * M_PI / unCountCorners) + 0.5);
unY2 = (unsigned int)(unRadius * cos(2 * (unIndex - 0) * M_PI / unCountCorners) + 0.5);
DrawLine(pRenderer, unCenterX + unX1, unCenterY + unY1, unCenterX + unX2, unCenterY + unY2);
}
unX1 = unX2;
unY1 = unY2;
unX2 = (unsigned int)(unRadius * sin(0) + 0.5);
unY2 = (unsigned int)(unRadius * cos(0) + 0.5);
DrawLine(pRenderer, unCenterX + unX1, unCenterY + unY1, unCenterX + unX2, unCenterY + unY2);
}
int main(int argc, char *argv[])
{
NSGraphics::IGraphicsRenderer* pRasterRenderer = NSGraphics::Create();
unsigned int unWidth = 521;
unsigned int unHeight = 172;
BYTE* pData = new BYTE[4 * unWidth * unHeight];
for (unsigned long unIndex = 0; unIndex < unWidth * unHeight; ++unIndex)
((unsigned int*)pData)[unIndex] = 0xffffff;
CBgraFrame oFrame;
oFrame.put_Data(pData);
oFrame.put_Width(unWidth);
oFrame.put_Height(unHeight);
oFrame.put_Stride(4 * unWidth);
pRasterRenderer->CreateFromBgraFrame(&oFrame);
pRasterRenderer->SetSwapRGB(false);
double dW_MM = unWidth * 25.4 / 96.;
double dH_MM = unHeight * 25.4 / 96.;
pRasterRenderer->put_Width(dW_MM);
pRasterRenderer->put_Height(dH_MM);
pRasterRenderer->put_PenColor(RGB_TO_INT(255, 0, 0));
pRasterRenderer->put_PenSize(15);
Aggplus::CMatrix oTransform(0.13338, 0, 0, 0.13395, 0, 0);
const double dScale = 0.4;
oTransform.Scale(dScale, dScale);
pRasterRenderer->SetTransform(oTransform.sx(), oTransform.shy(), oTransform.shx(), oTransform.sy(), oTransform.tx(), oTransform.ty());
// Рисуем многоугольник
// Видим, что появля.тся практически черные точки (на самом деле это очень темный красный цвет)
// Если же хотя бы чуть-чуть сместим местоположение отрисовки, то проблемные пиксели будут уже в других местах
DrawEquilateralPolygon(pRasterRenderer, 1000, 410, 400, 6);
// Если ещё что-то нарисуем, то некоторые проблемные места пропадут (у 6-угольника например нормализуются левая и правая стороны)
// DrawLine(pRasterRenderer, 100, 0, 100, 300);
oFrame.SaveFile(L"test-line-stroke.png", 4);
RELEASEINTERFACE(pRasterRenderer);
return 0;
}

View File

@ -0,0 +1,17 @@
QT -= gui
TARGET = test
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
CORE_ROOT_DIR = $$PWD/../../../../..
PWD_ROOT_DIR = $$PWD
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
SOURCES += main.cpp
DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX

View File

@ -126,20 +126,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz
DrawPage(pFile, nPage);
std::vector<std::wstring> xml_shapes;
for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes)
{
if (!shape) continue;
auto writer = new NSStringUtils::CStringBuilder();
shape->ToXml(*writer);
xml_shapes.push_back(writer->GetData());
delete writer;
}
std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml;
if (!arComleteObjects.empty())
xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end());
auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapes();
m_pInternal->m_oDocument.Clear();
return xml_shapes;
}
@ -154,23 +141,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile,
DrawPage(pFile, nPage);
// for drawingml is no tag behind-doc - so we need to reorder shapes
m_pInternal->m_oDocument.m_oCurrentPage.ReorderShapesForPptx();
std::vector<std::wstring> xml_shapes;
for (const auto& shape : m_pInternal->m_oDocument.m_oCurrentPage.m_arShapes)
{
if (!shape) continue;
auto writer = new NSStringUtils::CStringBuilder();
shape->ToXmlPptx(*writer);
xml_shapes.push_back(writer->GetData());
delete writer;
}
std::vector<std::wstring>& arComleteObjects = m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml;
if (!arComleteObjects.empty())
xml_shapes.insert(xml_shapes.end(), arComleteObjects.begin(), arComleteObjects.end());
auto xml_shapes = m_pInternal->m_oDocument.m_oCurrentPage.GetXmlShapesPptx();
m_pInternal->m_oDocument.Clear();
return xml_shapes;
}
@ -241,7 +212,7 @@ HRESULT CDocxRenderer::AdvancedCommand(IAdvancedCommand* command)
std::string sNewId = "r:embed=\"rId" + std::to_string(pInfo->m_nId + c_iStartingIdForImages) + "\"";
NSStringUtils::string_replaceA(sUtf8Shape, "r:embed=\"\"", sNewId);
}
m_pInternal->m_oDocument.m_oCurrentPage.m_arCompleteObjectsXml.push_back(UTF8_TO_U(sUtf8Shape));
m_pInternal->m_oDocument.m_oCurrentPage.AddCompleteXml(UTF8_TO_U(sUtf8Shape));
return S_OK;
}
case IAdvancedCommand::AdvancedCommandType::ShapeEnd:

View File

@ -32,6 +32,7 @@ HEADERS += \
src/logic/elements/ContText.h \
src/logic/elements/Paragraph.h \
src/logic/elements/Shape.h \
src/logic/elements/Table.h \
src/logic/elements/TextLine.h \
src/logic/managers/ExternalImageStorage.h \
src/logic/managers/FontStyleManager.h \
@ -56,6 +57,7 @@ SOURCES += \
src/logic/elements/ContText.cpp \
src/logic/elements/Paragraph.cpp \
src/logic/elements/Shape.cpp \
src/logic/elements/Table.cpp \
src/logic/elements/TextLine.cpp \
src/logic/managers/FontManager.cpp \
src/logic/managers/FontStyleManager.cpp \

View File

@ -1,126 +0,0 @@
#include "BaseItem.h"
#include "../resources/Constants.h"
#include <math.h>
namespace NSDocxRenderer
{
CBaseItem& CBaseItem::operator=(const CBaseItem& oSrc)
{
if (this == &oSrc)
{
return *this;
}
m_eType = oSrc.m_eType;
m_bIsNotNecessaryToUse = oSrc.m_bIsNotNecessaryToUse;
m_dLeft = oSrc.m_dLeft;
m_dTop = oSrc.m_dTop;
m_dWidth = oSrc.m_dWidth;
m_dHeight = oSrc.m_dHeight;
m_dBaselinePos = oSrc.m_dBaselinePos;
m_dRight = oSrc.m_dRight;
return *this;
}
bool CBaseItem::IsBigger(const CBaseItem* oSrc)
{
return (m_dLeft > oSrc->m_dLeft) ? true : false;
}
bool CBaseItem::IsBiggerOrEqual(const CBaseItem* oSrc)
{
return (m_dLeft >= oSrc->m_dLeft) ? true : false;
}
eVerticalCrossingType CBaseItem::GetVerticalCrossingType(const CBaseItem* oSrc)
{
if (m_dTop > oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctCurrentInsideNext;
}
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctCurrentOutsideNext;
}
else if (m_dTop < oSrc->m_dTop && m_dBaselinePos < oSrc->m_dBaselinePos && m_dBaselinePos > oSrc->m_dTop)
{
return eVerticalCrossingType::vctCurrentAboveNext;
}
else if (m_dTop > oSrc->m_dTop && m_dBaselinePos > oSrc->m_dBaselinePos && m_dTop < oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctCurrentBelowNext;
}
else if (m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos &&
m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight)
{
return eVerticalCrossingType::vctDublicate;
}
else if (fabs(m_dTop - oSrc->m_dTop) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eVerticalCrossingType::vctTopBordersMatch;
}
else if (fabs(m_dBaselinePos - oSrc->m_dBaselinePos) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eVerticalCrossingType::vctBottomBordersMatch;
}
else if (m_dBaselinePos < oSrc->m_dTop)
{
return eVerticalCrossingType::vctNoCrossingCurrentAboveNext;
}
else if (m_dTop > oSrc->m_dBaselinePos)
{
return eVerticalCrossingType::vctNoCrossingCurrentBelowNext;
}
else
{
return eVerticalCrossingType::vctUnknown;
}
}
eHorizontalCrossingType CBaseItem::GetHorizontalCrossingType(const CBaseItem* oSrc)
{
if (m_dLeft > oSrc->m_dLeft && m_dRight < oSrc->m_dRight)
{
return eHorizontalCrossingType::hctCurrentInsideNext;
}
else if (m_dLeft < oSrc->m_dLeft && m_dRight > oSrc->m_dRight)
{
return eHorizontalCrossingType::hctCurrentOutsideNext;
}
else if (m_dLeft < oSrc->m_dLeft && m_dRight < oSrc->m_dRight && m_dRight > oSrc->m_dLeft)
{
return eHorizontalCrossingType::hctCurrentLeftOfNext;
}
else if (m_dLeft > oSrc->m_dLeft && m_dRight > oSrc->m_dRight && m_dLeft < oSrc->m_dRight)
{
return eHorizontalCrossingType::hctCurrentRightOfNext;
}
else if (m_dLeft == oSrc->m_dLeft && m_dRight == oSrc->m_dRight &&
m_dTop == oSrc->m_dTop && m_dBaselinePos == oSrc->m_dBaselinePos)
{
return eHorizontalCrossingType::hctDublicate;
}
else if (fabs(m_dLeft - oSrc->m_dLeft) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eHorizontalCrossingType::hctLeftBordersMatch;
}
else if (fabs(m_dRight - oSrc->m_dRight) < c_dTHE_SAME_STRING_Y_PRECISION_MM)
{
return eHorizontalCrossingType::hctRightBordersMatch;
}
else if (m_dRight < oSrc->m_dLeft)
{
return eHorizontalCrossingType::hctNoCrossingCurrentLeftOfNext;
}
else if (m_dLeft > oSrc->m_dRight)
{
return eHorizontalCrossingType::hctNoCrossingCurrentRightOfNext;
}
else
{
return eHorizontalCrossingType::hctUnknown;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
#pragma once
#include "elements/Paragraph.h"
#include "elements/Table.h"
#include "elements/Shape.h"
#include "managers/ImageManager.h"
#include "managers/FontStyleManager.h"
@ -18,47 +19,34 @@ namespace NSDocxRenderer
CManagers(const CManagers& other) = default;
~CManagers() = default;
CImageManager* pImageManager;
CFontStyleManager* pFontStyleManager;
CParagraphStyleManager* pParagraphStyleManager;
CFontManager* pFontManager;
CFontSelector* pFontSelector;
CImageManager* pImageManager;
CFontStyleManager* pFontStyleManager;
CParagraphStyleManager* pParagraphStyleManager;
CFontManager* pFontManager;
CFontSelector* pFontSelector;
};
double m_dWidth {0.0};
double m_dHeight {0.0};
double m_dHeight{0.0};
LONG m_lCurrentCommand{0};
LONG m_lClipMode{0};
LONG m_lClipMode {0};
TextAssociationType m_eTextAssociationType{TextAssociationType::tatPlainParagraph};
TextAssociationType m_eTextAssociationType{TextAssociationType::tatPlainParagraph};
NSFonts::IApplicationFonts* m_pAppFonts{nullptr};
NSStructures::CFont m_oFont;
NSStructures::CPen m_oPen;
NSStructures::CBrush m_oBrush;
NSStructures::CShadow m_oShadow;
NSStructures::CEdgeText m_oEdgeText;
Aggplus::CMatrix m_oTransform;
CManagers m_oManagers;
CVectorGraphics m_oCurrVectorGraphics, m_oClipVectorGraphics;
CContTextBuilder m_oContBuilder;
std::vector<std::shared_ptr<CContText>> m_arConts;
std::vector<std::shared_ptr<CTextLine>> m_arTextLines;
std::vector<std::shared_ptr<CContText>> m_arDiacriticalSymbols;
std::vector<std::shared_ptr<CShape>> m_arShapes;
std::vector<std::wstring> m_arCompleteObjectsXml;
std::vector<std::shared_ptr<CBaseItem>> m_arOutputObjects;
NSStructures::CFont m_oFont{};
NSStructures::CPen m_oPen{};
NSStructures::CBrush m_oBrush{};
NSStructures::CShadow m_oShadow{};
NSStructures::CEdgeText m_oEdgeText{};
Aggplus::CMatrix m_oTransform{};
bool m_bIsDeleteTextClipPage{true};
bool m_bIsRecalcFontSize {true};
bool m_bIsGradient {false};
bool m_bUseDefaultFont {false};
bool m_bWriteStyleRaw {false};
bool m_bIsBuildTables {false};
CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers);
~CPage();
@ -67,7 +55,6 @@ namespace NSDocxRenderer
void EndCommand(DWORD lType);
void Clear();
void DeleteTextClipPage();
void WriteImage(const std::shared_ptr<CImageInfo> pInfo, double& fX, double& fY, double& fWidth, double& fHeight);
@ -77,8 +64,8 @@ namespace NSDocxRenderer
void PathStart();
void PathEnd();
void PathClose();
void DrawPath(LONG lType, const std::shared_ptr<CImageInfo> pInfo);
void AddText(
const PUINT pUnicodes,
const PUINT pGids,
@ -91,50 +78,134 @@ namespace NSDocxRenderer
void Analyze();
void Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage);
void ReorderShapesForPptx();
std::vector<std::wstring> GetXmlShapes();
std::vector<std::wstring> GetXmlShapesPptx();
void AddCompleteXml(const std::wstring oXml);
private:
void BuildDiacriticalSymbols();
void BuildTextLines();
using shape_ptr_t = std::shared_ptr<CShape>;
using cont_ptr_t = std::shared_ptr<CContText>;
using line_ptr_t = std::shared_ptr<CTextLine>;
using item_ptr_t = std::shared_ptr<CBaseItem>;
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
using table_ptr_t = std::shared_ptr<CTable>;
// returns std::vector of conts with diac. symbols and remove it from m_arConts
std::vector<cont_ptr_t> MoveDiacriticalSymbols();
// returns std::vector of text lines builded from m_arConts
std::vector<line_ptr_t> BuildTextLines();
// returns std::vector of paragraphs builded from m_arTextLines
std::vector<paragraph_ptr_t> BuildParagraphs();
// returns std::vector of tables builded from shapes and paragraphes
std::vector<table_ptr_t> BuildTables();
// returns std::vector of cells for tables
std::vector<CTable::cell_ptr_t> BuildCells();
// returns std::vector of rows for tables
std::vector<CTable::row_ptr_t> BuildRows(std::vector<CTable::cell_ptr_t>& arCells);
// returns std::vector of base items builded from m_arParagraphs
std::vector<item_ptr_t> BuildOutputObjects();
// analyze shapes (set lines type)
void AnalyzeShapes();
// analyze type of lines (double, wave, etc.)
void AnalyzeLinesType();
// analyze m_arTextLines and add effects, adds diac, super-sub scripts etc.
void AnalyzeTextLines();
void SplitLines();
void CalcSelected();
void BuildParagraphes();
std::vector<std::vector<std::shared_ptr<CTextLine>>> GetLinesByGroups();
// analyze drop caps (creates shapes)
void AnalyzeDropCaps();
void MergeShapes();
void CalcShapesRotation();
// analyze conts in text lines
void AnalyzeConts();
// strikeouts, underlines, highlights, outline
void AnalyzeEffects();
bool IsLineCrossingText(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
bool IsLineBelowText(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
bool IsHighlight(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
bool IsOutline(std::shared_ptr<CShape> pShape, std::shared_ptr<CContText> pCont);
void AnalyzeDropCaps();
void AnalyzeConts();
// adds diacritical symbols in conts
void AddDiacriticalSymbols();
void MergeLinesByVertAlignType();
void AnalyzeShapes();
void DetermineLinesType();
// super-sub scripts line merge
void MergeTextLinesByVatType();
// remove out of bounds text lines
void DeleteTextClipPage();
// merging conts in text lines
void MergeConts();
// get horizontal and vertical lines from shapes
void GetHorVerLines();
// set dominant shapes
void DetermineDominantGraphics();
bool IsShapeBorderBetweenVertical(std::shared_ptr<CTextLine> pFirst, std::shared_ptr<CTextLine> pSecond) const noexcept;
bool IsShapeBorderBetweenHorizontal(std::shared_ptr<CTextLine> pFirst, std::shared_ptr<CTextLine> pSecond) const noexcept;
bool IsShapeBorderTrough(std::shared_ptr<CContText> pItem, double& dXCrossing, double& dYCrossing) const noexcept;
// split lines by graphics
void SplitLines();
std::shared_ptr<CShape> CreateSingleLineShape(std::shared_ptr<CTextLine>& pLine);
std::shared_ptr<CShape> CreateSingleParagraphShape(std::shared_ptr<CParagraph>& pParagraph);
// creates shapes from overlapping text lines
void AnalyzeOverlapLines();
// конвертим m_arImages, m_arShapes, m_arParagraphs в xml-строку
void ToXml(NSStringUtils::CStringBuilder& oWriter);
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter);
// calc selected sizes of conts
void CalcSelected();
// merge shapes with each other
void MergeShapes();
// calc true shapes rotation for ooxml format
void CalcShapesRotation();
// for drawingml is no tag behind-doc - so we need to reorder shapes
void ReorderShapesForPptx();
// get lines by groups by X
std::vector<std::vector<line_ptr_t>> GetLinesByGroups();
bool IsLineCrossingText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsLineBelowText(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsHighlight(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsOutline(shape_ptr_t pShape, cont_ptr_t pCont) const noexcept;
bool IsVerticalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(item_ptr_t pFirst, item_ptr_t pSecond) const noexcept;
bool IsVerticalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
bool IsHorizontalLineBetween(line_ptr_t pFirst, line_ptr_t pSecond) const noexcept;
bool IsVerticalLineTrough(item_ptr_t pFirst) const noexcept;
bool IsHorizontalLineTrough(item_ptr_t pFirst) const noexcept;
void ToXml(NSStringUtils::CStringBuilder& oWriter) const noexcept;
void WriteSectionToFile(bool bLastPage, NSStringUtils::CStringBuilder& oWriter) const noexcept;
static shape_ptr_t CreateSingleLineShape(line_ptr_t& pLine);
static shape_ptr_t CreateSingleParagraphShape(paragraph_ptr_t& pParagraph);
CManagers m_oManagers;
CVectorGraphics m_oCurrVectorGraphics;
CVectorGraphics m_oClipVectorGraphics;
CContTextBuilder m_oContBuilder;
CHorVerLinesCollector m_oHorVerLinesCollector;
std::vector<cont_ptr_t> m_arConts;
std::vector<line_ptr_t> m_arTextLines;
std::vector<cont_ptr_t> m_arDiacriticalSymbols;
std::vector<shape_ptr_t> m_arShapes;
std::vector<paragraph_ptr_t> m_arParagraphs;
std::vector<table_ptr_t> m_arTables;
std::vector<item_ptr_t> m_arOutputObjects;
std::vector<std::wstring> m_arCompleteObjectsXml;
size_t m_nShapeOrder = 0;
};

View File

@ -1,6 +1,4 @@
#pragma once
#include <vector>
#include <memory>
#include "../../../../DesktopEditor/common/StringBuilder.h"

View File

@ -6,18 +6,6 @@
namespace NSDocxRenderer
{
bool IsTextOnlySpaces(const NSStringUtils::CStringUTF32& oText)
{
bool only_spaces = true;
for (size_t j = 0; j < oText.length(); ++j)
if (!CContText::IsUnicodeSpace(oText.at(j)))
{
only_spaces = false;
break;
}
return only_spaces;
}
CSelectedSizes::CSelectedSizes(const CSelectedSizes& oSelectedSizes)
{
*this = oSelectedSizes;
@ -108,8 +96,13 @@ namespace NSDocxRenderer
double dBoxWidth;
double dBoxHeight;
m_pManager->SetStringGid(0);
m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition);
if (m_oText.ToStdWString() == L" ")
dBoxWidth = m_pManager->GetSpaceWidthMM();
else
{
m_pManager->SetStringGid(0);
m_pManager->MeasureString(m_oText.ToStdWString(), 0, 0, dBoxX, dBoxY, dBoxWidth, dBoxHeight, CFontManager::mtPosition);
}
m_oSelectedSizes.dWidth = dBoxWidth;
m_oSelectedSizes.dHeight = dBoxHeight;
@ -544,7 +537,19 @@ namespace NSDocxRenderer
bool CContText::IsOnlySpaces() const
{
return IsTextOnlySpaces(m_oText);
bool only_spaces = true;
for (size_t j = 0; j < m_oText.length(); ++j)
if (!CContText::IsUnicodeSpace(m_oText.at(j)))
{
only_spaces = false;
break;
}
return only_spaces;
}
bool CContText::IsDiacritical() const noexcept
{
const auto& text = GetText();
return text.length() == 1 && CContText::IsUnicodeDiacriticalMark(text.at(0));
}
void CContText::AddTextBack(const NSStringUtils::CStringUTF32& oText, const std::vector<double>& arSymWidths)
@ -831,7 +836,14 @@ namespace NSDocxRenderer
return is_bullet || is_another;
}
bool CContText::IsUnicodeEnumEnd(uint32_t cSym)
{
return cSym == 0x29 || cSym == 0x2e;
}
bool CContText::IsUnicodeNumber(uint32_t cSym)
{
return cSym >= 0x30 && cSym <= 0x39;
}
bool CContText::IsUnicodeSpace(uint32_t cSym)
{
return (0x20 == cSym || 0xA0 == cSym || 0x2003 == cSym);

View File

@ -117,6 +117,7 @@ namespace NSDocxRenderer
bool IsDuplicate(CContText* pCont, eVerticalCrossingType eVType, eHorizontalCrossingType eHType) const noexcept;
bool IsOnlySpaces() const;
bool IsDiacritical() const noexcept;
double CalculateSpace() const noexcept;
// check font effect and delete not needed cont
@ -135,6 +136,8 @@ namespace NSDocxRenderer
static bool IsUnicodeRtl(uint32_t cSym);
static bool IsUnicodeBullet(uint32_t cSym);
static bool IsUnicodeEnumEnd(uint32_t cSym);
static bool IsUnicodeNumber(uint32_t cSym);
static bool IsUnicodeSpace(uint32_t c);
static bool IsUnicodeSymbol(uint32_t symbol);
static bool IsUnicodeDiacriticalMark(uint32_t symbol);
@ -154,7 +157,7 @@ namespace NSDocxRenderer
CContTextBuilder(CFontStyleManager* pFontStyleManager, CFontSelector* pFontSelector);
~CContTextBuilder() = default;
// after call CContTextBuilder is empty.
// after call CContTextBuilder is empty
std::vector<cont_ptr_t> GetConts();
void AddUnicode(
double dTop,

View File

@ -9,6 +9,15 @@ namespace NSDocxRenderer
{
UINT CShape::m_gRelativeHeight = c_iStandartRelativeHeight;
unsigned int ClampUIntSign(const double& value)
{
if (value < 0)
return 0;
if (value > 0x7FFFFFFF)
return 0x7FFFFFFF;
return (unsigned int)value;
}
CShape::CShape()
{
m_nRelativeHeight = m_gRelativeHeight;
@ -234,69 +243,49 @@ namespace NSDocxRenderer
void CShape::DetermineGraphicsType(double dWidth, double dHeight,size_t nPeacks, size_t nCurves) noexcept
{
//note параллельно для каждой текстовой строки создается шейп, который содержит цвет фона для данного текста.
if ((m_bIsNoStroke && m_bIsNoFill) ||
(m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor))
{
if ((m_bIsNoStroke && m_bIsNoFill) || (m_oBrush.Color1 == c_iWhiteColor && m_oPen.Color == c_iWhiteColor))
m_eGraphicsType = eGraphicsType::gtNoGraphics;
}
else if ((nPeacks == 5 || nPeacks == 2) && !nCurves) //1 move + 4 Peacks или 2 Peacks
{
m_eGraphicsType = eGraphicsType::gtRectangle;
if (dHeight < 0.7)
{
if (dWidth > 2.0) //note длинное тире - 2.8mm у times new roman
{
if (dWidth > 2.0) // длинное тире - 2.8mm у times new roman
m_eSimpleLineType = eSimpleLineType::sltHLongDash;
}
else if (dWidth > 0.7) //минимальное тире - 0.75mm у dotDotDash
{
else if (dWidth > 0.7) // минимальное тире - 0.75mm у dotDotDash
m_eSimpleLineType = eSimpleLineType::sltHDash;
}
else //максимальная точка - 0.5mm
{
m_eSimpleLineType = eSimpleLineType::sltHDot;
}
else
m_eSimpleLineType = eSimpleLineType::sltHDot; // максимальная точка - 0.5mm
}
else if (dWidth < 0.7)
{
if (dHeight > 2.0) //note длинное тире - 2.8mm у times new roman
{
if (dHeight > 2.0) // длинное тире - 2.8mm у times new roman
m_eSimpleLineType = eSimpleLineType::sltVLongDash;
}
else if (dHeight > 0.7) //минимальное тире - 0.75mm у dotDotDash
{
else if (dHeight > 0.7) // минимальное тире - 0.75mm у dotDotDash
m_eSimpleLineType = eSimpleLineType::sltVDash;
}
else //максимальна точка - 0.5mm
{
m_eSimpleLineType = eSimpleLineType::sltVDot;
}
else
m_eSimpleLineType = eSimpleLineType::sltVDot; // максимальна точка - 0.5mm
}
}
else if (nCurves > 0 && nPeacks <= 1) //1 move
else if (nCurves > 0 && nPeacks <= 1) // 1 move
{
m_eGraphicsType = eGraphicsType::gtCurve;
if (dHeight < dWidth)
{
m_eSimpleLineType = eSimpleLineType::sltHWave;
}
else
{
m_eSimpleLineType = eSimpleLineType::sltVWave;
}
}
else if (nCurves > 0 && nPeacks > 1)
{
m_eGraphicsType = eGraphicsType::gtComplicatedFigure;
}
}
bool CShape::IsItFitLine() const noexcept
{
return (m_eGraphicsType == eGraphicsType::gtRectangle && (m_eSimpleLineType == eSimpleLineType::sltHDot || m_eSimpleLineType == eSimpleLineType::sltHDash || m_eSimpleLineType == eSimpleLineType::sltHLongDash)) ||
(m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave);
return (m_eGraphicsType == eGraphicsType::gtRectangle && (
m_eSimpleLineType == eSimpleLineType::sltHDot ||
m_eSimpleLineType == eSimpleLineType::sltHDash ||
m_eSimpleLineType == eSimpleLineType::sltHLongDash)) ||
(m_eGraphicsType == eGraphicsType::gtCurve && m_eSimpleLineType == eSimpleLineType::sltHWave);
}
bool CShape::IsCorrelated(std::shared_ptr<const CShape> pShape) const noexcept
@ -323,7 +312,7 @@ namespace NSDocxRenderer
void CShape::CheckLineType(std::shared_ptr<CShape>& pFirstShape)
{
if(!pFirstShape)
if (!pFirstShape)
return;
if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
@ -338,103 +327,68 @@ namespace NSDocxRenderer
return;
if (!pFirstShape->IsItFitLine() || !pSecondShape->IsItFitLine() || !pFirstShape->IsCorrelated(pSecondShape) ||
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM) // линия должна быть одного размера по высоте
fabs(pFirstShape->m_dHeight - pSecondShape->m_dHeight) > c_dGRAPHICS_ERROR_IN_LINES_MM)
{
return; // линия должна быть одного размера по высоте
}
auto set_line_type = [] (std::shared_ptr<CShape>& master, std::shared_ptr<CShape>& slave, eLineType type) {
master->m_eLineType = type;
master->RecalcWithNewItem(slave.get());
master->m_oVector.Join(std::move(slave->m_oVector));
slave = nullptr;
};
// проверка на двойную линию
if (pFirstShape->m_eLineType == eLineType::ltDouble)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble);
else
set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble);
return;
}
if (pFirstShape->m_eLineType == eLineType::ltWavyDouble)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble);
else
set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble);
return;
}
// проверка на двойную линию
if (pFirstShape->m_eLineType == eLineType::ltDouble || pFirstShape->m_eLineType == eLineType::ltWavyDouble)
{
if (pFirstShape->m_eLineType == eLineType::ltDouble)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
{
pFirstShape->m_eLineType = eLineType::ltDouble;
pFirstShape->RecalcWithNewItem(pSecondShape.get());
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
pSecondShape = nullptr;
}
else
{
pSecondShape->m_eLineType = eLineType::ltDouble;
pSecondShape->RecalcWithNewItem(pFirstShape.get());
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
pFirstShape = nullptr;
}
}
else if (pFirstShape->m_eLineType == eLineType::ltWavyDouble)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
{
pFirstShape->m_eLineType = eLineType::ltWavyDouble;
pFirstShape->RecalcWithNewItem(pSecondShape.get());
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
pSecondShape = nullptr;
}
else
{
pSecondShape->m_eLineType = eLineType::ltWavyDouble;
pSecondShape->RecalcWithNewItem(pFirstShape.get());
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
pFirstShape = nullptr;
}
}
return;
}
else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) < c_dGRAPHICS_ERROR_IN_LINES_MM * 5 &&
fabs(pFirstShape->m_dWidth - pSecondShape->m_dWidth) < c_dGRAPHICS_ERROR_IN_LINES_MM &&
fabs(pFirstShape->m_dLeft - pSecondShape->m_dLeft) < c_dGRAPHICS_ERROR_IN_LINES_MM)
{
//Условие первого определения
// условие первого определения
if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
{
pFirstShape->m_eLineType = eLineType::ltDouble;
pFirstShape->RecalcWithNewItem(pSecondShape.get());
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
pSecondShape = nullptr;
}
set_line_type(pFirstShape, pSecondShape, eLineType::ltDouble);
else
{
pSecondShape->m_eLineType = eLineType::ltDouble;
pSecondShape->RecalcWithNewItem(pFirstShape.get());
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
pFirstShape = nullptr;
}
set_line_type(pSecondShape, pFirstShape, eLineType::ltDouble);
}
else if (pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave && pSecondShape->m_eSimpleLineType == eSimpleLineType::sltHWave)
{
if (pFirstShape->m_dTop < pSecondShape->m_dTop)
{
pFirstShape->m_eLineType = eLineType::ltWavyDouble;
pFirstShape->RecalcWithNewItem(pSecondShape.get());
pFirstShape->m_oVector.Join(std::move(pSecondShape->m_oVector));
pSecondShape = nullptr;
}
set_line_type(pFirstShape, pSecondShape, eLineType::ltWavyDouble);
else
{
pSecondShape->m_eLineType = eLineType::ltWavyDouble;
pSecondShape->RecalcWithNewItem(pFirstShape.get());
pSecondShape->m_oVector.Join(std::move(pFirstShape->m_oVector));
pFirstShape = nullptr;
}
set_line_type(pSecondShape, pFirstShape, eLineType::ltWavyDouble);
}
return;
}
else if (fabs(pFirstShape->m_dTop - pSecondShape->m_dTop) > c_dGRAPHICS_ERROR_IN_LINES_MM)
{
// все должно быть на одной линии
return;
}
return; // все должно быть на одной линии
// теперь считаем, что графика находится на одной линии
if (fabs(pFirstShape->m_dLeft +pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5)
// расстояние между объектами на одной линии должно быть небольшим
if (fabs(pFirstShape->m_dLeft + pFirstShape->m_dWidth - pSecondShape->m_dLeft) > c_dGRAPHICS_ERROR_IN_LINES_MM * 5)
{
// расстояние между объектами на одной линии должно быть небольшим
if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHLongDash)
pFirstShape->m_eLineType =pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle;
pFirstShape->m_eLineType = pFirstShape-> m_dHeight > 0.3 ? eLineType::ltThick : eLineType::ltSingle;
else if (pFirstShape->m_eLineType == eLineType::ltUnknown && pFirstShape->m_eSimpleLineType == eSimpleLineType::sltHWave)
pFirstShape->m_eLineType = pFirstShape->m_oPen.Size > 0.3 ? eLineType::ltWavyHeavy : eLineType::ltWave;
@ -924,6 +878,27 @@ namespace NSDocxRenderer
}
oWriter.WriteString(L"</a:solidFill>");
if (m_oPen.DashStyle == Aggplus::DashStyleCustom)
{
// dash pattern
std::vector<double> dash_pattern(m_oPen.Count);
long count = m_oPen.Count;
m_oPen.GetDashPattern(dash_pattern.data(), count);
oWriter.WriteString(L"<a:custDash>");
for (size_t i = 0; i < count; i+= 2)
{
double to_percentage = 100.0 * 1000.0 / m_oPen.Size;
oWriter.WriteString(L"<a:ds d=\"");
oWriter.AddUInt(ClampUIntSign(dash_pattern[i] * to_percentage));
oWriter.WriteString(L"\" ");
oWriter.WriteString(L"sp=\"");
oWriter.AddUInt(ClampUIntSign(dash_pattern[i + 1] * to_percentage));
oWriter.WriteString(L"\" />");
}
oWriter.WriteString(L"</a:custDash>");
}
// Aggplus::DashStyleSolid
oWriter.WriteString(L"</a:ln>");
}
}
@ -1072,6 +1047,4 @@ namespace NSDocxRenderer
}
oWriter.WriteString(L"</p:sp>");
}
}; // namespace NSDocxRenderer

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