Compare commits

...

340 Commits

Author SHA1 Message Date
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
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
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
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
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
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
7696541430 fix bug #72151 2024-12-20 17:33:11 +03:00
614156f575 fix bug #72170 2024-12-19 13:19:03 +03:00
397abd51a5 Fix bug 72159 2024-12-19 11:32:58 +03:00
d311090ced fix write empty custom 2024-12-18 19:44:06 +03:00
4a110d68c1 Fixed bugs in reading hwp format and added test example 2024-12-18 15:13:43 +03:00
505a3c6224 Merge pull request 'Fix bug 63154' (#140) from fix/bug-63154 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/140
2024-12-18 10:28:36 +00:00
75a21ee162 Fix bug 63154 2024-12-18 13:18:04 +03:00
440cf968d5 Fix bug 70708 2024-12-18 07:39:25 +00:00
3daa374a51 Compute text lines 2024-12-18 07:39:25 +00:00
5d83d912fc Fix bug 72142 2024-12-17 15:41:21 +00:00
695fd3ba1c Merge pull request 'Fix bug #69851' (#139) from fix/bug69851 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/139
2024-12-17 15:32:52 +00:00
75f68904f2 Merge branch 'release/v8.3.0' of git.onlyoffice.com:ONLYOFFICE/core into release/v8.3.0 2024-12-17 18:32:11 +03:00
b99badda9f fix bug #72057 2024-12-17 18:32:06 +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
dbd6be9520 Fix bug #69851 2024-12-17 15:48:38 +06:00
42ef948fcc Merge pull request 'Create Stamp Annot' (#131) from feature/pdf-new-stamp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/131
2024-12-17 09:23:32 +00:00
69f4ac3ed7 fix bug #71799 2024-12-17 10:14:47 +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
57ba4355f9 fix bug #72062 2024-12-16 15:22:04 +03:00
2eea44bc8c Merge pull request 'Fix int to double conversion' (#136) from fix/bug72062 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/136
2024-12-16 11:04:49 +00:00
cb982a1ad4 Fix int to double conversion 2024-12-16 15:28:15 +06:00
0aca0a0a5a fix bug #71977 2024-12-15 12:47:27 +03:00
0c1df859e2 The writing code for converting hwp format 2024-12-14 16:36:33 +03:00
7a153285c8 fix bug #72063 2024-12-14 12:56:00 +03:00
c2d00ee819 Merge pull request 'Fix bug #54422' (#135) from fix/bug54422 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/135
2024-12-14 09:01:38 +00:00
3603787df8 Merge pull request 'Fix bug #71477' (#134) from fix/bug71477 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/134
2024-12-14 08:58:29 +00: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
5483a8d36b Merge pull request 'Fix bug #72067' (#133) from fix/bug72067 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/133
2024-12-13 12:16:42 +00:00
80ac89f16b fix bug #72065 2024-12-13 15:12:49 +03:00
fcf9830aa6 Fix bug #72067 2024-12-13 17:53:06 +06:00
d7b435a446 Delete unused file 2024-12-13 12:28:13 +03:00
887d963d8d Fix bug 72045 2024-12-12 15:29:31 +03:00
bc4c39b7aa The writing code for converting hwp format 2024-12-11 21:34:46 +03:00
8d89026d19 Change path for pdf.bin 2024-12-11 17:44:48 +03:00
4e6e3ce5f0 Fix rotate double 2024-12-11 14:46:18 +03:00
3d7eced836 Fix Rotate 2024-12-11 14:34:26 +03:00
7130b1be34 [x2t] Rename draw->visio; For bug 72002 2024-12-11 12:25:47 +03:00
a5917c389f The writing code for converting hwp format 2024-12-10 22:19:37 +03:00
eee80b0f87 [x2t] Rename draw->visio; For bug 72002 2024-12-10 19:28:04 +03:00
35dff37820 Create Stamp Annot 2024-12-10 15:07:11 +03:00
2f45a87669 Remove HtmlRenderer library 2024-12-10 14:24:41 +03:00
185b3d54eb Merge pull request 'feature/docx-renderer' (#130) from feature/docx-renderer into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/130
2024-12-10 09:05:54 +00:00
f7f059b6c0 Merge pull request 'Feature pdf text' (#119) from feature/pdf-text into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/119
2024-12-10 09:04:32 +00:00
2a9044d066 No changes HtmlRenderer 2024-12-10 11:20:09 +03:00
a93f00d0af The writing code for converting hwp format 2024-12-09 22:18:04 +03:00
f9f4efc383 Fix statistics 2024-12-09 10:31:50 +03:00
12ad4e604b Add indents logic with bullets 2024-12-09 09:02:07 +03:00
e0ad062380 Add origin font 2024-12-09 08:00:17 +03:00
b72f678c1d Fix drop caps 2024-12-09 07:53:41 +03:00
59f41bcdec Fix bug 70699 2024-12-07 06:15:37 +03:00
e8aa709d4e Fix bug #54422 2024-12-07 01:35:12 +05:00
c4515aca3a Problem 2024-12-06 18:01:05 +03:00
b776b7b63f The writing code for converting hwp format 2024-12-06 15:18:32 +03:00
134a214a0b Refactoring 2024-12-06 10:45:06 +03:00
95f604ec68 Merge remote-tracking branch 'origin/release/v8.3.0' into feature/pdf-text 2024-12-06 10:33:37 +03:00
ecd71dd92a The writing code for converting hwp format 2024-12-05 21:27:21 +03:00
d8bd9ef845 Fix size of Line 2024-12-05 18:59:43 +03:00
bd3cabd236 Return to typed arrays 2024-12-04 18:45:59 +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
6b9fc964b9 Fix isSpace 2024-11-28 17:28:33 +03:00
9242ab9743 Merge remote-tracking branch 'origin/develop' into feature/pdf-text 2024-11-28 16:58:46 +03:00
e14cc2d5c5 HtmlRenderer to serialize 2024-11-28 12:29:24 +03:00
295dbbbb86 The writing code for converting hwp format 2024-11-27 20:45:00 +03:00
265db0216b Fix new word 2024-11-27 17:32:14 +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
2ba281a5ee Fix empty 2024-11-25 17:31:25 +03:00
ce0f8251d3 Fix bug #69238 2024-11-22 17:32:40 +05:00
f019dfbb07 Words with X and Width 2024-11-22 15:09:21 +03:00
c83a8a3a54 Serialization 2024-11-21 17:54:33 +03:00
1c362612e3 Refactoring HtmlRendererText 2024-11-20 18:52:06 +03:00
cf346bd535 CMetafile to NSWasm::CData 2024-11-19 17:41:32 +03:00
536dac5fc9 getSelectionQuads..
The function is called very often, and returns an array of borders for drawing the text selection. Therefore, frequent memory allocation for serialization of the result, frequent reading and freeing of memory. You will have to cache on JS
2024-11-19 15:17:57 +03:00
dc4074299c change CHtmlRendererText 2024-11-18 18:13:29 +03:00
caac75fcc1 Create struct for text 2024-11-15 16:36:59 +03:00
bb204098a1 Fix PDFCoordsToMM 2024-11-14 16:24:14 +03:00
1e9a63083b Read CHTMLRenderer 2024-11-11 17:28:58 +03:00
b3f5d84a51 Fix bug #71477 2024-11-07 18:26:12 +05:00
ec50e77695 HtmlRenderer research 2024-11-06 16:22:19 +03: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
3503eee5b6 Create GetGlyphs for PdfFile 2024-11-02 10:00:44 +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
450 changed files with 24393 additions and 18612 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;
@ -1371,6 +1375,7 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type)
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM:
return L".dotm";
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC:
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT:
return L".doc";
case AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT:
return L".odt";

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

@ -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;
}
@ -296,7 +304,7 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
else if (1 == m_nFileType)
pNative->m_strEditorType = L"presentation";
else if (7 == m_nFileType)
pNative->m_strEditorType = L"draw";
pNative->m_strEditorType = L"visio";
else
pNative->m_strEditorType = L"spreadsheet";

View File

@ -422,6 +422,7 @@ public:
int m_nFileType;
std::string m_sUtf8ArgumentJSON;
std::string m_sGlobalVariable;
std::string m_sJSCodeStart;
CJSContextData m_oContextData;
@ -455,7 +456,8 @@ namespace NSDoctRenderer
std::wstring m_sTmpFolder;
std::wstring m_sFileDir;
int m_nFileType;
bool m_bJavascriptBeforeEditor;
std::wstring m_sCommandsBeforeContextCreated;
std::wstring m_sX2tPath;
@ -478,7 +480,7 @@ namespace NSDoctRenderer
public:
CDocBuilder_Private() : CDoctRendererConfig(), m_sTmpFolder(NSFile::CFileBinary::GetTempPath()), m_nFileType(-1),
m_pWorker(NULL), m_pAdditionalData(NULL), m_bIsInit(false), m_bIsServerSafeVersion(false),
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_bJavascriptBeforeEditor(false)
m_sGlobalVariable(""), m_bIsGlobalVariableUse(false), m_pParent(NULL), m_sCommandsBeforeContextCreated(L"")
{
}
@ -639,9 +641,6 @@ namespace NSDoctRenderer
NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
}
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return bRet;
#else
std::wstring sPath = m_sX2tPath + L"/empty/new.";
@ -930,11 +929,7 @@ namespace NSDoctRenderer
LOGGER_SPEED_LAP("open_convert");
if (0 == nReturnCode)
{
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
return 0;
}
NSDirectory::DeleteDirectory(m_sFileDir);
m_sFileDir = L"";
@ -1220,36 +1215,27 @@ namespace NSDoctRenderer
{
if (NULL == m_pWorker)
{
m_pWorker = new CV8RealTimeWorker(m_pParent, GetEditorType(), this);
NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType();
if (NSDoctRenderer::DoctRendererEditorType::INVALID == editorType)
return false;
m_pWorker = new CV8RealTimeWorker(m_pParent, editorType, this);
m_pWorker->m_sUtf8ArgumentJSON = m_oParams.m_sArgumentJSON;
m_pWorker->m_sGlobalVariable = m_sGlobalVariable;
m_pWorker->m_sJSCodeStart = U_TO_UTF8(m_sCommandsBeforeContextCreated);
m_sCommandsBeforeContextCreated = L"";
return CheckWorkerAfterOpen();
m_pWorker->m_nFileType = m_nFileType;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, editorType, this, &oParams);
}
return true;
}
bool CheckWorkerAfterOpen()
{
if (!m_pWorker)
return false;
m_pWorker->m_nFileType = m_nFileType;
if (-1 == m_nFileType)
{
m_bJavascriptBeforeEditor = true;
return false;
}
m_bJavascriptBeforeEditor = false;
CV8Params oParams;
oParams.IsServerSaveVersion = m_bIsServerSafeVersion;
oParams.DocumentDirectory = m_sFileDir;
return m_pWorker->OpenFile(m_sX2tPath, m_sFileDir, GetEditorType(), this, &oParams);
}
int SaveFile(const std::wstring& ext, const std::wstring& path, const wchar_t* params = NULL)
{
int nType = GetFormatByTexExtention(ext);
@ -1261,21 +1247,26 @@ namespace NSDoctRenderer
if (command.length() < 7 && !retValue) // minimum command (!!!)
return true;
if (m_nFileType == -1)
{
m_sCommandsBeforeContextCreated += command;
return true;
}
Init();
bool bRes = CheckWorker();
if (CheckWorker())
return m_pWorker->ExecuteCommand(command, retValue);
if (!bRes && m_pWorker && m_bJavascriptBeforeEditor)
m_pWorker->InitVariables();
return m_pWorker->ExecuteCommand(command, retValue);
return false;
}
CDocBuilderContext GetContext(bool enterContext)
{
CDocBuilderContext ctx;
CheckWorker();
if (!CheckWorker())
return ctx;
ctx.m_internal->m_context = m_pWorker->m_context;
ctx.m_internal->m_context_data = &m_pWorker->m_oContextData;

View File

@ -986,7 +986,7 @@ namespace NSDoctRenderer
case DoctRendererFormat::IMAGE:
{
editorType = NSDoctRenderer::DoctRendererEditorType::VISIO;
m_pInternal->m_strEditorType = L"draw";
m_pInternal->m_strEditorType = L"visio";
break;
}
default:

View File

@ -121,7 +121,7 @@ drawingfile_support {
embed/DrawingFileEmbed.h
SOURCES += \
../../HtmlRenderer/src/HTMLRendererText.cpp \
../graphics/pro/js/wasm/src/HTMLRendererText.cpp \
embed/DrawingFileEmbed.cpp
ADD_FILES_FOR_EMBEDDED_CLASS_HEADER(embed/DrawingFileEmbed.h)

View File

@ -38,8 +38,8 @@
#include "../../PdfFile/PdfFile.h"
#include "../../XpsFile/XpsFile.h"
#include "../../DjVuFile/DjVu.h"
#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
#include "../../HtmlRenderer/include/HTMLRendererText.h"
#include "../graphics/pro/js/wasm/src/serialize.h"
#include "../graphics/pro/js/wasm/src/HTMLRendererText.h"
#include "../../DocxRenderer/DocxRenderer.h"
#define CHECKER_FILE_BUFFER_LEN 4096

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)
@ -100,12 +109,12 @@ namespace NSDoctRenderer
}
case DoctRendererEditorType::VISIO:
{
if (!NSFile::CFileBinary::Exists(config->m_strSdkPath + L"/draw/sdk-all-min.js"))
if (!NSFile::CFileBinary::Exists(config->m_strSdkPath + L"/visio/sdk-all-min.js"))
return L"";
AppendScript(builder, config->m_strSdkPath + L"/draw/sdk-all-min.js");
AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all-min.js");
AppendScript(builder, sFontsPath);
AppendScript(builder, config->m_strSdkPath + L"/draw/sdk-all.js");
sCachePath = config->m_strSdkPath + L"/draw/sdk-all";
AppendScript(builder, config->m_strSdkPath + L"/visio/sdk-all.js");
sCachePath = config->m_strSdkPath + L"/visio/sdk-all";
break;
}
case DoctRendererEditorType::PDF:
@ -114,6 +123,7 @@ namespace NSDoctRenderer
AppendScript(builder, sFontsPath);
AppendScript(builder, config->m_strSdkPath + L"/word/sdk-all.js");
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/engine/drawingfile_native.js");
AppendScript(builder, config->m_strSdkPath + L"/pdf/src/annotations/stamps.json", "window[\"native_pdf_stamps\"]=", ";");
sCachePath = config->m_strSdkPath + L"/pdf/sdk-all";
break;
}
@ -147,7 +157,7 @@ namespace NSDoctRenderer
}
case DoctRendererEditorType::VISIO:
{
return config->m_strSdkPath + L"/draw/sdk-all.bin";
return config->m_strSdkPath + L"/visio/sdk-all.bin";
}
case DoctRendererEditorType::PDF:
{

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

@ -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

@ -312,14 +312,14 @@ namespace Aggplus
agg::trans_affine& m1 = mm1->m_internal->m_agg_mtx;
agg::trans_affine& m2 = mm2->m_internal->m_agg_mtx;
bool bMain = (fabs(m1.sx - m2.sx) < eps &&
fabs(m1.sy - m2.sy) < eps &&
fabs(m1.shx - m2.shx) < eps &&
fabs(m1.shy - m2.shy) < eps) ? true : false;
bool bMain = fabs(m1.sx - m2.sx) < eps &&
fabs(m1.sy - m2.sy) < eps &&
fabs(m1.shx - m2.shx) < eps &&
fabs(m1.shy - m2.shy) < eps;
if (!bMain || bIsOnlyMain)
return bMain;
return (fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps) ? true : false;
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
}
}

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

@ -645,12 +645,17 @@ void CAnnotFieldInfo::CCaretAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
m_nSy = pReader->ReadByte();
}
int CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; }
double CAnnotFieldInfo::CStampAnnotPr::GetRotate() { return m_nRotate; }
const std::wstring& CAnnotFieldInfo::CStampAnnotPr::GetName() { return m_wsName; }
void CAnnotFieldInfo::CStampAnnotPr::GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dInRect[0]; dRD2 = m_dInRect[1]; dRD3 = m_dInRect[2]; dRD4 = m_dInRect[3]; }
void CAnnotFieldInfo::CStampAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
{
m_wsName = pReader->ReadString();
m_nRotate = pReader->ReadInt();
m_nRotate = pReader->ReadDouble();
m_dInRect[0] = pReader->ReadDouble();
m_dInRect[1] = pReader->ReadDouble();
m_dInRect[2] = pReader->ReadDouble();
m_dInRect[3] = pReader->ReadDouble();
}
bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; }

View File

@ -408,14 +408,16 @@ public:
class GRAPHICS_DECL CStampAnnotPr
{
public:
int GetRotate();
double GetRotate();
const std::wstring& GetName();
void GetInRect(double& dRD1, double& dRD2, double& dRD3, double& dRD4);
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
private:
int m_nRotate;
double m_nRotate;
std::wstring m_wsName;
double m_dInRect[4]{};
};
CAnnotFieldInfo();

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

@ -135,7 +135,7 @@
},
{
"folder": "./wasm/src/",
"files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp"]
"files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp", "HTMLRendererText.cpp"]
},
{
"folder": "freetype-2.10.4/src/",
@ -201,10 +201,6 @@
"folder": "../",
"files": ["officedrawingfile.cpp"]
},
{
"folder": "../../../../HtmlRenderer/src/",
"files": ["HTMLRendererText.cpp"]
},
{
"folder": "../../../../UnicodeConverter/",
"files": ["UnicodeConverter.cpp"]
@ -227,7 +223,7 @@
},
{
"folder": "../../../../DocxRenderer/src/logic/elements",
"files": ["BaseItem.cpp", "ContText.cpp", "DropCap.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp"]
"files": ["BaseItem.cpp", "ContText.cpp", "Paragraph.cpp", "Shape.cpp", "TextLine.cpp", "Table.cpp"]
},
{
"folder": "../../../common",

View File

@ -19,7 +19,7 @@ include($$CORE_ROOT_DIR/Common/base.pri)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)
include(../../freetype.pri)
ADD_DEPENDENCY(UnicodeConverter, kernel, HtmlRenderer)
ADD_DEPENDENCY(UnicodeConverter, kernel)
INCLUDEPATH += \
$$CORE_ROOT_DIR/DesktopEditor/agg-2.4/include \
@ -704,7 +704,6 @@ HEADERS += \
SOURCES += \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/BaseItem.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \
@ -720,14 +719,15 @@ SOURCES += \
$$DOCX_RENDERER_ROOT_DIR/DocxRenderer.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/resources/resources.cpp
HEADERS += $$CORE_ROOT_DIR/HtmlRenderer/include/HTMLRendererText.h
SOURCES += $$CORE_ROOT_DIR/HtmlRenderer/src/HTMLRendererText.cpp
HEADERS += $$CORE_ROOT_DIR/DesktopEditor/doctrenderer/drawingfile.h
HEADERS += \
../wasm/src/drawingfile.h \
../wasm/src/serialize.h
../wasm/src/serialize.h \
../wasm/src/HTMLRendererText.h \
../wasm/src/Text.h
SOURCES += \
../wasm/src/pdfwriter.cpp \
../wasm/src/HTMLRendererText.cpp \
../wasm/src/drawingfile.cpp \
../wasm/src/drawingfile_test.cpp

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

@ -68,16 +68,6 @@ CFile.prototype.unlockPageNumForFontsLoader = function()
drawingFile.fontPageUpdateType = UpdateFontsSource.Undefined;
};
CFile.prototype.getOriginPage = function(originIndex)
{
for (let i = 0; i < this.pages.length; ++i)
{
if (this.pages[i]["originIndex"] == originIndex)
return i;
}
return -1;
};
CFile.prototype["getPages"] = function()
{
return this.pages;
@ -241,18 +231,17 @@ CFile.prototype["getLinks"] = function(pageIndex)
// TEXT
CFile.prototype["getGlyphs"] = function(pageIndex)
{
let i = this.getOriginPage(pageIndex);
if (i < 0)
return null;
let page = this.pages[i];
if (!page || page.fonts.length > 0)
let page = this.pages[pageIndex];
if (page.originIndex == undefined)
return [];
if (page.fonts.length > 0)
{
// waiting fonts
return null;
}
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
let res = this._getGlyphs(pageIndex);
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
let res = this._getGlyphs(page.originIndex);
// there is no need to delete the result; this buffer is used as a text buffer
// for text commands on other pages. After receiving ALL text pages,
// you need to call destroyTextInfo()
@ -1290,7 +1279,7 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex)
else if (rec["Type"] == 12)
{
rec["Icon"] = reader.readString();
rec["Rotate"] = reader.readInt();
rec["Rotate"] = reader.readDouble2();
rec["InRect"] = [];
for (let i = 0; i < 8; ++i)
rec["InRect"].push(reader.readDouble2());
@ -1391,18 +1380,17 @@ CFile.prototype["free"] = function(pointer)
// PIXMAP
CFile.prototype["getPagePixmap"] = function(pageIndex, width, height, backgroundColor)
{
let i = this.getOriginPage(pageIndex);
if (i < 0)
let page = this.pages[pageIndex];
if (page.originIndex == undefined)
return null;
let page = this.pages[i];
if (!page || page.fonts.length > 0)
if (page.fonts.length > 0)
{
// waiting fonts
return null;
}
this.lockPageNumForFontsLoader(i, UpdateFontsSource.Page);
let ptr = this._getPixmap(pageIndex, width, height, backgroundColor);
this.lockPageNumForFontsLoader(pageIndex, UpdateFontsSource.Page);
let ptr = this._getPixmap(page.originIndex, width, height, backgroundColor);
this.unlockPageNumForFontsLoader();
if (page.fonts.length > 0)

View File

@ -29,8 +29,8 @@
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "../include/HTMLRendererText.h"
#include "./Text.h"
#include "HTMLRendererText.h"
#include "Text.h"
namespace NSHtmlRenderer
{
@ -40,52 +40,35 @@ namespace NSHtmlRenderer
double m_dWidth;
double m_dHeght;
NSStructures::CBrush m_oBrush;
NSStructures::CBrush m_oLastBrush;
NSStructures::CFont m_oFont;
NSStructures::CFont* m_pFont;
NSStructures::CFont m_oInstalledFont;
LONG m_lCurrentFont;
double m_dCurrentFontSize;
Aggplus::CMatrix m_oTransform;
Aggplus::CMatrix m_oLastTransform;
bool m_bIsChangedFontParamBetweenDrawText;
LONG m_lCurrentCommandType;
LONG m_lSrcFileType;
CHText m_oSmartText;
CMetafile m_oPage;
NSWasm::CData m_oPage;
int* m_pTempUnicodes;
int m_nTempUnicodesAlloc;
int m_nTempUnicodesLen;
int* m_pTempUnicodes; // массив юникодов
int m_nTempUnicodesAlloc; // размер выделенной памяти
int m_nTempUnicodesLen; // размер используемой памяти
bool m_bIsFontsInit;
public:
CHTMLRendererText_Private()
{
m_bIsChangedFontParamBetweenDrawText = true;
m_lSrcFileType = 0;
m_pTempUnicodes = NULL;
m_nTempUnicodesLen = 0;
m_nTempUnicodesAlloc = 0;
m_bIsFontsInit = false;
m_lCurrentFont = 0;
m_dCurrentFontSize = 0;
m_pFont = &m_oFont;
}
~CHTMLRendererText_Private()
{
RELEASEARRAYOBJECTS(m_pTempUnicodes);
}
public:
void GetUnicodes(const std::wstring& sText)
{
int nLen = (int)sText.length();
@ -101,7 +84,7 @@ namespace NSHtmlRenderer
if (sizeof(wchar_t) == 2)
{
for (int nIndex = 0, nGlyphIndex = 0; nIndex < nLen; ++nIndex, ++nGlyphIndex)
for (int nIndex = 0; nIndex < nLen; ++nIndex)
{
int code = (int)pWchars[nIndex];
if (code >= 0xD800 && code <= 0xDFFF && (nIndex + 1) < nLen)
@ -109,32 +92,25 @@ namespace NSHtmlRenderer
++nIndex;
code = 0x10000 + (((code & 0x3FF) << 10) | (0x03FF & pWchars[nIndex]));
}
m_pTempUnicodes[m_nTempUnicodesLen++] = code;
}
}
else
{
for ( int nIndex = 0; nIndex < nLen; ++nIndex )
{
for (int nIndex = 0; nIndex < nLen; ++nIndex)
m_pTempUnicodes[m_nTempUnicodesLen++] = (int)pWchars[nIndex];
}
}
}
void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y,
const double& width, const double& height, const bool& bIsChangedFontParamBetweenDrawText)
void WriteText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y)
{
bool bIsDumpFont = false;
if (!m_oInstalledFont.IsEqual(&m_oFont))
{
m_oInstalledFont = m_oFont;
bIsDumpFont = true;
m_dCurrentFontSize = m_oInstalledFont.Size;
}
m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, width, height, bIsDumpFont, this);
m_oSmartText.CommandText(pUnicodes, pGids, nCount, x, y, bIsDumpFont);
}
};
@ -149,9 +125,6 @@ namespace NSHtmlRenderer
void CHTMLRendererText::Init(IOfficeDrawingFile* pFile, int nCacheSize)
{
m_pInternal->m_oBrush.SetDefaultParams();
m_pInternal->m_oLastBrush.SetDefaultParams();
m_pInternal->m_oFont.SetDefaultParams();
m_pInternal->m_oInstalledFont.SetDefaultParams();
m_pInternal->m_oInstalledFont.Name = L"";
@ -159,87 +132,38 @@ namespace NSHtmlRenderer
m_pInternal->m_oTransform.Reset();
m_pInternal->m_oLastTransform.Reset();
m_pInternal->m_oLastBrush.Color1 = -1;
m_pInternal->m_dCurrentFontSize = 0.0;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
m_pInternal->m_lCurrentCommandType = -1;
m_pInternal->m_oSmartText.NewPage();
if (!m_pInternal->m_bIsFontsInit)
{
m_pInternal->m_oSmartText.m_oFontManager.m_pFont = &m_pInternal->m_oFont;
m_pInternal->m_oSmartText.m_pLastBrush = &m_pInternal->m_oLastBrush;
m_pInternal->m_oSmartText.m_pBrush = &m_pInternal->m_oBrush;
m_pInternal->m_oSmartText.m_pFont = &m_pInternal->m_oFont;
m_pInternal->m_oSmartText.m_oFontManager.Init(pFile->GetFonts(), nCacheSize);
m_pInternal->m_oSmartText.m_pTransform = &m_pInternal->m_oTransform;
m_pInternal->m_oSmartText.m_pLastTransform = &m_pInternal->m_oLastTransform;
m_pInternal->m_oSmartText.m_pPageMeta = &m_pInternal->m_oPage;
OfficeDrawingFileType eType = pFile->GetType();
switch (eType)
{
case odftPDF:
{
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF;
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
break;
}
case odftDJVU:
{
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU;
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
break;
}
case odftXPS:
{
m_pInternal->m_lSrcFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS;
m_pInternal->m_oSmartText.m_dTextSpaceEps = 0.1;
break;
}
default:
break;
}
m_pInternal->m_bIsFontsInit = true;
m_pInternal->m_oSmartText.Init(pFile->GetFonts(), nCacheSize);
}
m_pInternal->m_oPage.ClearNoAttack();
m_pInternal->m_oPage.WriteLONG(0);
m_pInternal->m_oPage.SkipLen();
// статистика
m_pInternal->m_oPage.WriteLONG(0);
m_pInternal->m_oPage.WriteLONG(0);
m_pInternal->m_oPage.WriteLONG(0);
m_pInternal->m_oPage.WriteLONG(0);
m_pInternal->m_oPage.AddInt(0);
m_pInternal->m_oPage.AddInt(0);
m_pInternal->m_oPage.AddInt(0);
m_pInternal->m_oPage.AddInt(0);
}
BYTE* CHTMLRendererText::GetBuffer()
{
m_pInternal->m_oSmartText.ClosePage();
LONG lPos = m_pInternal->m_oPage.GetPosition();
m_pInternal->m_oPage.Seek(0);
// len
m_pInternal->m_oPage.WriteLONG(lPos);
// stat
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountParagraphs);
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountWords);
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSymbols);
m_pInternal->m_oPage.WriteLONG(m_pInternal->m_oSmartText.m_lCountSpaces);
// seek to end
m_pInternal->m_oPage.Seek(lPos);
m_pInternal->m_oPage.WriteLen();
// статистика
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountParagraphs, 4);
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountWords, 8);
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSymbols, 12);
m_pInternal->m_oPage.AddInt(m_pInternal->m_oSmartText.m_nCountSpaces, 16);
m_pInternal->m_oSmartText.ClearStatistics();
return m_pInternal->m_oPage.GetData();
return m_pInternal->m_oPage.GetBuffer();
}
HRESULT CHTMLRendererText::get_Type(LONG* lType)
{
*lType = c_nHtmlRendrererText;
@ -247,10 +171,7 @@ namespace NSHtmlRenderer
}
//-------- Функции для работы со страницей --------------------------------------------------
HRESULT CHTMLRendererText::NewPage()
{
return S_OK;
}
HRESULT CHTMLRendererText::NewPage() { return S_OK; }
HRESULT CHTMLRendererText::get_Height(double* dHeight)
{
*dHeight = m_pInternal->m_dHeght;
@ -311,36 +232,12 @@ namespace NSHtmlRenderer
HRESULT CHTMLRendererText::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { return S_OK; }
// brush ------------------------------------------------------------------------------------
HRESULT CHTMLRendererText::get_BrushType(LONG* lType)
{
*lType = m_pInternal->m_oBrush.Type;
return S_OK;
}
HRESULT CHTMLRendererText::put_BrushType(const LONG& lType)
{
m_pInternal->m_oBrush.Type = lType;
return S_OK;
}
HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor)
{
*lColor = m_pInternal->m_oBrush.Color1;
return S_OK;
}
HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor)
{
m_pInternal->m_oBrush.Color1 = lColor;
return S_OK;
}
HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha)
{
*lAlpha = m_pInternal->m_oBrush.Alpha1;
return S_OK;
}
HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha)
{
m_pInternal->m_oBrush.Alpha1 = lAlpha;
return S_OK;
}
HRESULT CHTMLRendererText::get_BrushType(LONG* lType) { return S_OK; }
HRESULT CHTMLRendererText::put_BrushType(const LONG& lType) { return S_OK; }
HRESULT CHTMLRendererText::get_BrushColor1(LONG* lColor) { return S_OK; }
HRESULT CHTMLRendererText::put_BrushColor1(const LONG& lColor) { return S_OK; }
HRESULT CHTMLRendererText::get_BrushAlpha1(LONG* lAlpha) { return S_OK; }
HRESULT CHTMLRendererText::put_BrushAlpha1(const LONG& lAlpha) { return S_OK; }
HRESULT CHTMLRendererText::get_BrushColor2(LONG* lColor) { return S_OK; }
HRESULT CHTMLRendererText::put_BrushColor2(const LONG& lColor) { return S_OK; }
HRESULT CHTMLRendererText::get_BrushAlpha2(LONG* lAlpha) { return S_OK; }
@ -366,7 +263,6 @@ namespace NSHtmlRenderer
HRESULT CHTMLRendererText::put_FontName(const std::wstring& bsName)
{
m_pInternal->m_oFont.Name = bsName;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
return S_OK;
}
HRESULT CHTMLRendererText::get_FontPath(std::wstring* bsName)
@ -377,7 +273,6 @@ namespace NSHtmlRenderer
HRESULT CHTMLRendererText::put_FontPath(const std::wstring& bsName)
{
m_pInternal->m_oFont.Path = bsName;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
return S_OK;
}
HRESULT CHTMLRendererText::get_FontSize(double* dSize)
@ -387,11 +282,7 @@ namespace NSHtmlRenderer
}
HRESULT CHTMLRendererText::put_FontSize(const double& dSize)
{
if (m_pInternal->m_oFont.Size != dSize)
{
m_pInternal->m_oFont.Size = dSize;
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
}
m_pInternal->m_oFont.Size = dSize;
return S_OK;
}
HRESULT CHTMLRendererText::get_FontStyle(LONG* lStyle)
@ -401,12 +292,7 @@ namespace NSHtmlRenderer
}
HRESULT CHTMLRendererText::put_FontStyle(const LONG& lStyle)
{
LONG lOld = m_pInternal->m_oFont.GetStyle();
if (lOld != lStyle)
{
m_pInternal->m_oFont.SetStyle(lStyle);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = true;
}
m_pInternal->m_oFont.SetStyle(lStyle);
return S_OK;
}
HRESULT CHTMLRendererText::get_FontStringGID(INT* bGID)
@ -443,58 +329,34 @@ namespace NSHtmlRenderer
//-------- Функции для вывода текста --------------------------------------------------------
HRESULT CHTMLRendererText::CommandDrawTextCHAR(const LONG& c, const double& x, const double& y, const double& w, const double& h)
{
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
int _c = (int)c;
m_pInternal->WriteText(&_c, NULL, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
m_pInternal->WriteText(&_c, NULL, 1, x, y);
return S_OK;
}
HRESULT CHTMLRendererText::CommandDrawText(const std::wstring& bsText, const double& x, const double& y, const double& w, const double& h)
{
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
m_pInternal->GetUnicodes(bsText);
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y);
return S_OK;
}
HRESULT CHTMLRendererText::CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h)
{
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
int _c = (int)c;
int _g = (int)gid;
m_pInternal->WriteText(&_c, &_g, 1, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
m_pInternal->WriteText(&_c, &_g, 1, x, y);
return S_OK;
}
HRESULT CHTMLRendererText::CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h)
{
if (c_nHyperlinkType == m_pInternal->m_lCurrentCommandType)
return S_OK;
m_pInternal->GetUnicodes(bsUnicodeText);
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y, w, h, m_pInternal->m_bIsChangedFontParamBetweenDrawText);
m_pInternal->m_bIsChangedFontParamBetweenDrawText = false;
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, (const int*)pGids, m_pInternal->m_nTempUnicodesLen, x, y);
return S_OK;
}
//-------- Маркеры для команд ---------------------------------------------------------------
HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType)
{
m_pInternal->m_lCurrentCommandType = lType;
return S_OK;
}
HRESULT CHTMLRendererText::EndCommand(const DWORD& lType)
{
m_pInternal->m_lCurrentCommandType = -1;
return S_OK;
}
HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType) { return S_OK; }
HRESULT CHTMLRendererText::EndCommand(const DWORD& lType) { return S_OK; }
//-------- Функции для работы с Graphics Path -----------------------------------------------
HRESULT CHTMLRendererText::PathCommandMoveTo(const double& x, const double& y) { return S_OK; }

View File

@ -32,8 +32,8 @@
#ifndef _ASC_HTMLRENDERER3_TEXT_H_
#define _ASC_HTMLRENDERER3_TEXT_H_
#include "../../DesktopEditor/graphics/IRenderer.h"
#include "../../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../../../../IRenderer.h"
#include "../../../officedrawingfile.h"
#ifndef HTMLRENDERER_USE_DYNAMIC_LIBRARY
#define HTMLRENDERER_DECL_EXPORT

View File

@ -0,0 +1,409 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#ifndef _ASC_HTMLRENDERER_TEXT_H_
#define _ASC_HTMLRENDERER_TEXT_H_
#include <algorithm>
#include "serialize.h"
#include "../../../../structures.h"
#include "../../../Fonts.h"
namespace NSHtmlRenderer
{
struct CHFontInfo
{
int m_lAscent;
int m_lDescent;
int m_lUnitsPerEm;
CHFontInfo() : m_lAscent(0), m_lDescent(0), m_lUnitsPerEm(0) {}
CHFontInfo(const CHFontInfo& oSrc) : m_lAscent(oSrc.m_lAscent), m_lDescent(oSrc.m_lDescent), m_lUnitsPerEm(oSrc.m_lUnitsPerEm) {}
CHFontInfo& operator=(const CHFontInfo& oSrc)
{
m_lAscent = oSrc.m_lAscent;
m_lDescent = oSrc.m_lDescent;
m_lUnitsPerEm = oSrc.m_lUnitsPerEm;
return *this;
}
};
class CFontManagerWrapper
{
private:
NSFonts::IFontManager* m_pManager;
public:
NSStructures::CFont* m_pFont;
CHFontInfo m_oCurrentInfo;
public:
CFontManagerWrapper() : m_pManager(NULL) {}
virtual ~CFontManagerWrapper()
{
RELEASEOBJECT(m_pManager);
}
void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0)
{
RELEASEOBJECT(m_pManager);
m_pManager = pApplicationFonts->GenerateFontManager();
if (nCacheSize)
{
NSFonts::IFontsCache* pFontCache = NSFonts::NSFontCache::Create();
pFontCache->SetStreams(pApplicationFonts->GetStreams());
pFontCache->SetCacheSize(nCacheSize);
m_pManager->SetOwnerCache(pFontCache);
}
}
void SetStringGID(INT bGid)
{
m_pManager->SetStringGID(bGid);
}
void LoadCurrentFont()
{
if (m_pFont->Path.empty())
LoadFontByName(m_pFont->Name, m_pFont->Size, m_pFont->GetStyle());
else
LoadFontByFile(m_pFont->Path, m_pFont->Size);
}
double MeasureString(const unsigned int* symbols, const int& count, double x, double y)
{
if (!m_pManager)
return 0;
m_pManager->LoadString1(symbols, count, (float)x, (float)y);
TBBox _box = m_pManager->MeasureString2();
return abs((_box.fMaxX - _box.fMinX) * 25.4 / 72.0);
}
private:
inline void LoadFontByName(const std::wstring& strName, const double& dSize, const LONG& lStyle)
{
m_pManager->LoadFontByName(strName, dSize, lStyle, 72.0, 72.0);
LoadFontMetrics();
}
inline void LoadFontByFile(const std::wstring& strPath, const double& dSize)
{
m_pManager->LoadFontFromFile(strPath, 0, dSize, 72.0, 72.0);
LoadFontMetrics();
}
void LoadFontMetrics()
{
m_pManager->AfterLoad();
m_oCurrentInfo.m_lAscent = abs(m_pManager->GetAscender());
m_oCurrentInfo.m_lDescent = abs(m_pManager->GetDescender());
m_oCurrentInfo.m_lUnitsPerEm = abs(m_pManager->GetUnitsPerEm());
}
};
struct CHText
{
CFontManagerWrapper m_oFontManager;
Aggplus::CMatrix* m_pTransform;
Aggplus::CMatrix* m_pLastTransform;
NSWasm::CHLine m_oLine;
NSWasm::CData* m_pPageMeta;
LONG m_nCountParagraphs;
LONG m_nCountWords;
LONG m_nCountSymbols;
LONG m_nCountSpaces;
CHText() : m_oFontManager(), m_oLine()
{
m_nCountParagraphs = 0;
m_nCountWords = 0;
m_nCountSymbols = 0;
m_nCountSpaces = 0;
}
void ClearStatistics()
{
m_nCountParagraphs = 0;
m_nCountWords = 0;
m_nCountSymbols = 0;
m_nCountSpaces = 0;
}
void ClosePage()
{
if (m_oLine.GetCountChars())
DumpLine();
}
void CommandText(const int* pUnicodes, const int* pGids, const int& nCount, const double& x, const double& y, bool bIsDumpFont)
{
// 1) сначала определяем точку отсчета и направление baseline
double _x1 = x;
double _y1 = y;
double _x2 = x + 1;
double _y2 = y;
m_pTransform->TransformPoint(_x1, _y1);
m_pTransform->TransformPoint(_x2, _y2);
double _k = 0;
double _b = 0;
bool _isConstX = false;
if (fabs(_x1 - _x2) < 0.001)
{
_isConstX = true;
_b = _x1;
}
else
{
_k = (_y1 - _y2) / (_x1 - _x2);
_b = _y1 - _k * _x1;
}
double dAbsVec = sqrt((_x1 - _x2) * (_x1 - _x2) + (_y1 - _y2) * (_y1 - _y2));
if (dAbsVec == 0)
dAbsVec = 1;
bool bIsNewLine = true;
if (m_oLine.GetCountChars())
{
if (_isConstX && m_oLine.m_bIsConstX && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
else if (!_isConstX && !m_oLine.m_bIsConstX && fabs(_k - m_oLine.m_dK) < 0.001 && fabs(_b - m_oLine.m_dB) < 0.001)
bIsNewLine = false;
if (bIsNewLine) // не совпала baseline. поэтому просто скидываем линию в поток
DumpLine();
}
// теперь нужно определить сдвиг по baseline относительно destination точки
double dOffsetX = 0;
LONG nCountChars = m_oLine.GetCountChars();
if (0 == nCountChars)
{
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
else
{
double sx = _x1 - m_oLine.m_dEndX;
double sy = _y1 - m_oLine.m_dEndY;
double len = sqrt(sx*sx + sy*sy);
if (sx * m_oLine.m_ex >= 0 && sy * m_oLine.m_ey >= 0)
{
// продолжаем линию
dOffsetX = len;
// теперь посмотрим, может быть нужно вставить пробел??
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
if (dOffsetX > (pLastChar->width + 0.5))
{
// вставляем пробел. Пробел у нас будет не совсем пробел. А специфический
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
pLastChar = &m_oLine.m_pChars[m_oLine.m_lCharsTail - 2];
pSpaceChar->x = pLastChar->width;
pSpaceChar->width = dOffsetX - pLastChar->width;
pSpaceChar->unicode = 0xFFFF;
dOffsetX -= pLastChar->width;
}
}
else
{
// буква сдвинута влево относительно предыдущей буквы
// на такую ситуацию реагируем просто - просто начинаем новую линию,
// предварительно сбросив старую
DumpLine();
m_oLine.m_bIsConstX = _isConstX;
m_oLine.m_dX = _x1;
m_oLine.m_dY = _y1;
m_oLine.m_dK = _k;
m_oLine.m_dB = _b;
m_oLine.m_ex = (_x2 - _x1) / dAbsVec;
m_oLine.m_ey = (_y2 - _y1) / dAbsVec;
}
m_oLine.m_dEndX = _x1;
m_oLine.m_dEndY = _y1;
}
if (!Aggplus::CMatrix::IsEqual(m_pLastTransform, m_pTransform, 0.001, true))
{ // смотрим, совпадает ли главная часть матрицы
bIsDumpFont = true;
*m_pLastTransform = *m_pTransform;
m_oLine.m_bIsSetUpTransform = true;
m_oLine.m_sx = m_pTransform->sx();
m_oLine.m_shx = m_pTransform->shx();
m_oLine.m_shy = m_pTransform->shy();
m_oLine.m_sy = m_pTransform->sy();
}
// все, baseline установлен. теперь просто продолжаем линию
if (bIsDumpFont)
m_oFontManager.LoadCurrentFont();
double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm);
double dAscender = m_oFontManager.m_oCurrentInfo.m_lAscent * dKoef * dAbsVec;
double dDescender = m_oFontManager.m_oCurrentInfo.m_lDescent * dKoef * dAbsVec;
if (m_oLine.m_dAscent < dAscender)
m_oLine.m_dAscent = dAscender;
if (m_oLine.m_dDescent < dDescender)
m_oLine.m_dDescent = dDescender;
const int* input = NULL;
if (NULL != pGids)
{
input = pGids;
m_oFontManager.SetStringGID(TRUE);
}
else
{
input = pUnicodes;
m_oFontManager.SetStringGID(FALSE);
}
double dPlusOffset = 0;
double dPrevW = dOffsetX;
for (int i = 0; i < nCount; ++i)
{
double dW = m_oFontManager.MeasureString((const unsigned int*)(input + i), 1, 0, 0);
NSWasm::CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pUnicodes[i];
pChar->x = dPrevW;
if (i)
dPlusOffset += dPrevW;
dPrevW = dW;
pChar->width = dW * dAbsVec;
if (i == nCount - 1)
{
m_oLine.m_dEndX += dPlusOffset * m_oLine.m_ex;
m_oLine.m_dEndY += dPlusOffset * m_oLine.m_ey;
}
}
}
void DumpLine()
{
LONG nCount = m_oLine.GetCountChars();
if (!nCount)
{
m_oLine.Clear();
return;
}
if (m_oLine.m_bIsSetUpTransform)
{
// выставится трансформ!!!
// cравнивать нужно с ним!!!
m_pLastTransform->SetElements(m_oLine.m_sx, m_oLine.m_shy, m_oLine.m_shx, m_oLine.m_sy);
}
// скидываем линию в поток pMeta
m_pPageMeta->WriteDouble(m_oLine.m_dX);
m_pPageMeta->WriteDouble(m_oLine.m_dY);
bool bHorizontal = false;
if (fabs(m_oLine.m_ex - 1.0) < 0.001 && fabs(m_oLine.m_ey) < 0.001)
bHorizontal = true;
m_pPageMeta->WriteBYTE(!bHorizontal ? 1 : 0);
if (!bHorizontal)
{
m_pPageMeta->WriteDouble(m_oLine.m_ex);
m_pPageMeta->WriteDouble(m_oLine.m_ey);
}
m_pPageMeta->WriteDouble(m_oLine.m_dAscent);
m_pPageMeta->WriteDouble(m_oLine.m_dDescent);
m_nCountParagraphs++;
// width
LONG _position = m_pPageMeta->GetSize();
m_pPageMeta->AddInt(0);
double dWidthLine = 0;
double dCurrentGlyphLineOffset = 0;
m_pPageMeta->AddInt(nCount);
NSWasm::CHChar* pChar = NULL;
bool bIsLastSymbol = false;
for (LONG lIndexChar = 0; lIndexChar < nCount; ++lIndexChar)
{
pChar = &m_oLine.m_pChars[lIndexChar];
if (lIndexChar)
{
m_pPageMeta->WriteDouble(pChar->x);
dCurrentGlyphLineOffset += pChar->x;
}
if (pChar->unicode == 0xFFFF || pChar->unicode == 32 || pChar->unicode == 9)
{
m_nCountSpaces++;
if (bIsLastSymbol)
{
bIsLastSymbol = false;
m_nCountWords++;
}
}
else
{
m_nCountSymbols++;
bIsLastSymbol = true;
}
m_pPageMeta->AddInt(pChar->unicode); // юникодное значение
m_pPageMeta->WriteDouble(pChar->width); // ширина буквы
}
if (bIsLastSymbol)
m_nCountWords++;
if (pChar)
dWidthLine = dCurrentGlyphLineOffset + pChar->width;
m_pPageMeta->AddInt((int)(dWidthLine * 10000.0), _position);
m_oLine.Clear();
}
};
}
#endif // _ASC_HTMLRENDERER_TEXT_H_

View File

@ -10,6 +10,10 @@ unsigned char READ_BYTE(BYTE* x)
{
return x ? x[0] : 1;
}
unsigned short READ_SHORT(BYTE* x)
{
return x ? (x[0] | x[1] << 8) : 2;
}
unsigned int READ_INT(BYTE* x)
{
return x ? (x[0] | x[1] << 8 | x[2] << 16 | x[3] << 24) : 4;
@ -1086,15 +1090,82 @@ int main(int argc, char* argv[])
}
// GLYPHS
if (false && nPagesCount > 0)
if (true && nPagesCount > 0)
{
// TODO:
BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage);
nLength = READ_INT(pGlyphs);
int i = 4;
nLength -= 20;
int nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << "Stats Paragraphs " << nPathLength;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Words " << nPathLength;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Symbols " << nPathLength;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Spaces " << nPathLength << std::endl;
while (i < nLength)
{
int nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << "Line X " << (double)nPathLength / 10000.0;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Y " << (double)nPathLength / 10000.0;
nPathLength = READ_BYTE(pGlyphs + i);
i += 1;
if (nPathLength)
{
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Ex " << (double)nPathLength / 10000.0;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Ey " << (double)nPathLength / 10000.0;
}
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Ascent " << (double)nPathLength / 10000.0;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Descent " << (double)nPathLength / 10000.0;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " LineWidth " << (double)nPathLength / 10000.0;
int nCharLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Chars:" << std::endl;
for (int j = 0; j < nCharLength; ++j)
{
int nCharX = 0;
if (j)
{
nCharX = READ_INT(pGlyphs + i);
i += 4;
}
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " Unicode " << nPathLength;
nPathLength = READ_INT(pGlyphs + i);
i += 4;
std::cout << " width " << (double)nPathLength / 10000.0;
if (nCharX)
std::cout << " charX " << (double)nCharX / 10000.0;
std::cout << std::endl;
}
}
DestroyTextInfo(pGrFile);
}
// INTERACTIVE FORMS
if (true)
if (false)
{
ReadInteractiveFormsFonts(pGrFile, 1);
ReadInteractiveFormsFonts(pGrFile, 2);
@ -1799,7 +1870,7 @@ int main(int argc, char* argv[])
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "Rotate " << nPathLength << ", ";
std::cout << "Rotate " << nPathLength / 10000.0 << ", ";
nPathLength = READ_INT(pAnnots + i);
i += 4;
@ -1855,7 +1926,7 @@ int main(int argc, char* argv[])
}
// SCAN PAGE
if (true)
if (false)
{
BYTE* pScan = ScanPage(pGrFile, nTestPage, 1);
if (pScan)

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

@ -1,10 +1,7 @@
#ifndef _WASM_SERIALIZE_H
#define _WASM_SERIALIZE_H
#include "../../../../../common/StringExt.h"
#include "../../../../../common/StringUTF32.h"
#include "../../../../../graphics/IRenderer.h"
#include "../../../../../graphics/pro/Fonts.h"
#include <vector>
#include "../../../../../common/File.h"
namespace NSWasm
@ -208,58 +205,32 @@ namespace NSWasm
}
};
class CHChar
struct CHChar
{
public:
int unicode; // юникодное значение
int gid; // индекс глифа в файле
double x; // сдвиг по baseline
double width; // ширина символа (сдвиг до след буквы)
double* matrix; // матрица преобразования (!!! без сдвига)
int unicode; // юникодное значение
double x; // сдвиг по baseline
double width; // ширина символа (сдвиг до след буквы)
public:
CHChar()
{
unicode = 0;
gid = 0;
width = 0;
matrix = NULL;
}
CHChar(const CHChar& oSrc)
{
*this = oSrc;
}
CHChar() : unicode(0), x(0), width(0) {}
CHChar(const CHChar& oSrc) { *this = oSrc; }
CHChar& operator=(const CHChar& oSrc)
{
unicode = oSrc.unicode;
gid = oSrc.gid;
x = oSrc.x;
width = oSrc.width;
matrix = NULL;
if (NULL != oSrc.matrix)
{
matrix = new double[4];
memcpy(matrix, oSrc.matrix, 4 * sizeof(double));
}
return *this;
}
~CHChar()
{
RELEASEARRAYOBJECTS(matrix);
}
inline void Clear()
{
unicode = 0;
gid = 0;
x = 0;
width = 0;
RELEASEARRAYOBJECTS(matrix);
}
};
class CHLine
struct CHLine
{
public:
double m_dAscent;
double m_dDescent;
double m_dX;
@ -288,7 +259,6 @@ namespace NSWasm
double m_shx;
double m_shy;
public:
CHLine()
{
m_dAscent = 0;
@ -374,9 +344,7 @@ namespace NSWasm
{
CHChar* pNews = new CHChar[2 * m_lSizeChars];
for (LONG i = 0; i < m_lSizeChars; ++i)
{
pNews[i] = m_pChars[i];
}
RELEASEARRAYOBJECTS(m_pChars);
m_pChars = pNews;
@ -392,10 +360,18 @@ namespace NSWasm
inline CHChar* GetTail()
{
if (0 == m_lCharsTail)
return NULL;
if (m_lCharsTail >= m_lSizeChars)
{
CHChar* pNews = new CHChar[2 * m_lSizeChars];
for (LONG i = 0; i < m_lSizeChars; ++i)
pNews[i] = m_pChars[i];
return &m_pChars[m_lCharsTail - 1];
RELEASEARRAYOBJECTS(m_pChars);
m_pChars = pNews;
m_lSizeChars *= 2;
}
return m_lCharsTail ? &m_pChars[m_lCharsTail - 1] : NULL;
}
inline LONG GetCountChars()

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

@ -36,7 +36,6 @@
#include "../../common/Directory.h"
#include "../../fontengine/ApplicationFonts.h"
#include "../../../HtmlRenderer/include/ASCSVGWriter.h"
#include "MetaFile.h"
#if defined(_WIN64)

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

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

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