Compare commits

..

431 Commits

Author SHA1 Message Date
1fc7ebed19 Fix indents and move operator for CImage 2025-04-08 11:17:12 +03:00
dbf89fcaa3 Add comments on brush classes 2025-04-02 20:48:16 +03:00
44c26bc020 Add test for hatch brush 2025-04-02 17:43:38 +03:00
a3a1c5fc3e Fix text test 2025-04-01 20:42:41 +03:00
e3968cec5b Add test for text 2025-04-01 14:50:04 +03:00
20ba78cd7c Fix copy operator for CMatrix 2025-04-01 02:14:57 +03:00
7043515089 Refactoring CBrush 2025-04-01 02:09:53 +03:00
68f070d073 Refactoring CMatrix 2025-04-01 02:09:15 +03:00
b2c6667823 Add clear cache to font manager 2025-03-31 00:39:52 +03:00
0e563c8461 fix metafile test 2025-03-24 20:38:43 +03:00
ee47ced36b Remove idential functions 2025-03-24 17:44:19 +03:00
efe6f4408b Add test for image files 2025-03-23 21:20:45 +03:00
b918f81c2b Add GUI to metafile test 2025-03-17 18:58:49 +03:00
204bc33610 Add documentation for meta file 2025-03-13 20:26:10 +03:00
db9fb871a1 Add Metafile Converter Test 2025-03-13 16:25:21 +03:00
ccad697cd8 Merge remote-tracking branch 'origin/hotfix/v8.3.1' into develop 2025-02-27 15:58:46 +03:00
dd60367d01 Fix building fonts module 2025-02-27 11:18:24 +03:00
54bbbbc3d7 Merge pull request 'fix bug #73349' (#241) from fix/bug73349 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/241
2025-02-26 19:29:42 +00:00
9b901f7834 fix bug #73349 2025-02-26 17:56:41 +03:00
4f59af17b8 Fix bug 72130 2025-02-26 15:08:48 +03:00
b9258429f6 Merge pull request 'Fix bug #73343' (#240) from fix/bug73343 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/240
2025-02-25 15:20:32 +00:00
e8f2c55ad4 Merge pull request 'Fix bug #72788' (#239) from fix/bug72788 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/239
2025-02-25 15:20:12 +00:00
46f6ba4d0a Fix for subsystem python module 2025-02-25 16:55:32 +03:00
09b55bd1f1 Merge pull request 'Fix bug 71688' (#238) from fix/bug-71688 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/238
2025-02-24 13:29:36 +00:00
176053e8d8 Fix bug 71688 2025-02-24 16:16:51 +03:00
01365f938c Fix bug 73299 2025-02-24 15:09:43 +03:00
d168e4594f Fix bug #73343 2025-02-24 17:09:36 +05:00
cad36a73be Merge remote-tracking branch 'origin/hotfix/v8.3.1' into develop 2025-02-24 12:14:01 +03:00
27d2e40da7 Merge pull request 'fix bug #73336' (#237) from fix/bug73336 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/237
2025-02-24 09:00:39 +00:00
14b09ce582 fix bug #73336 2025-02-24 11:49:41 +03:00
aeeab690b1 Fix builder bugs. Recteate context with snapshots if needed. 2025-02-24 01:10:39 +03:00
016a0a971b Fix bug #72788 2025-02-20 20:28:22 +05:00
afe55a456f Merge branch 'fix/bug70671' into hotfix/v8.3.1 2025-02-19 18:06:22 +03:00
a430ba92ad Merge pull request 'fix/odf_tests' (#125) from fix/odf_tests into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/125
2025-02-19 14:59:35 +00:00
efc1149235 Merge pull request 'Fix bug #70575' (#236) from fix/bug70575 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/236
2025-02-19 14:58:17 +00:00
567cc14bc7 Merge pull request 'Fix bug #72790' (#232) from fix/bug72790 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/232
2025-02-19 12:51:51 +00:00
0fc7f2a8b3 Merge remote-tracking branch 'origin/fix/bug73248' into develop 2025-02-19 15:36:32 +03:00
b14fa1c2a1 fix bug #73248 2025-02-19 15:35:55 +03:00
2c27cfc720 . 2025-02-19 15:32:12 +03:00
1d31e5836b fix fileFormatChecker 2025-02-18 20:23:49 +03:00
6adf65d3a8 fix bug #73221 2025-02-18 09:51:43 +03:00
093e1348fa Merge pull request 'Fix bug #71975' (#235) from fix/bug71975 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/235
2025-02-17 13:40:22 +00:00
b78157487a Merge pull request 'Fix bug #73238' (#233) from fix/bug73238 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/233
2025-02-17 13:37:03 +00:00
77b30109f0 Merge remote-tracking branch 'origin/hotfix/v8.3.1' into fix/bug71975 2025-02-17 18:33:19 +05:00
efd047be74 Fix bug #71975 2025-02-17 18:27:48 +05:00
61abfdb272 Merge pull request 'Fix bugs 73220, 73178' (#234) from fix/bug-73220 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/234
2025-02-17 11:16:05 +00:00
f5088f43d8 Fix bug 73178 2025-02-17 14:10:38 +03:00
6b3c395220 Fix bug 73220 2025-02-17 13:44:01 +03:00
67cb29652d Fix bug #73238 2025-02-15 17:41:26 +05:00
d0cb082b33 Fix bug #72790 2025-02-15 12:53:35 +05:00
2eff67efc3 Merge pull request 'Fix bug #73222' (#231) from fix/bug73222 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/231
2025-02-14 12:09:16 +00:00
84416ef5b6 Merge pull request 'Fix bug #72871' (#230) from fix/bug72871 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/230
2025-02-14 12:08:56 +00:00
447ade207f Fix bug #73222 2025-02-14 13:56:53 +05:00
ddd7628bbe fix bug #73097 2025-02-13 17:48:33 +03:00
1f86b0265a Fix bug #72871 2025-02-13 18:20:31 +05:00
e484db496b . 2025-02-13 15:14:51 +03:00
5bc1c8d860 fix bug #73215 2025-02-13 15:12:58 +03:00
dbdf4bd120 Merge pull request 'Fix Metafile conversion' (#228) from fix/bugs-metafile into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/228
2025-02-13 09:59:40 +00:00
a93db0e012 . 2025-02-12 18:15:00 +03:00
f145378002 fix additional sdtPr 2025-02-12 15:35:26 +03:00
4e800f6952 Merge remote-tracking branch 'origin/hotfix/v8.3.1' into develop 2025-02-12 11:19:53 +03:00
8098fec345 Merge pull request 'Fix bug #72825' (#227) from fix/bug72825 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/227
2025-02-11 18:11:08 +00:00
7bfcea0fff Merge pull request 'Fix bug #72875' (#226) from fix/bug72875 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/226
2025-02-11 18:10:41 +00:00
4b4845c558 Merge pull request 'Fix bug #72414' (#225) from fix/bug72414 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/225
2025-02-11 18:10:03 +00:00
b26e3e2fee Merge pull request 'fix/bug70675' (#224) from fix/bug70675 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/224
2025-02-11 18:09:33 +00:00
388951670c Merge pull request 'Fix bug #72790' (#223) from fix/bug72790 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/223
2025-02-11 18:08:55 +00:00
7d3488abc9 Merge pull request 'fix/bug-68408' (#229) from fix/bug-68408 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/229
2025-02-11 11:10:20 +00:00
fea3910254 adding reading attributes 2025-02-11 13:22:50 +03:00
2d58b08f0f Merge pull request 'PDF MovePage' (#222) from fix/pre8.3.1 into hotfix/v8.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/222
2025-02-11 09:06:33 +00:00
612142f0ae Refactoring 2025-02-11 11:24:08 +03:00
2a0c84513b For bug #72962 2025-02-11 11:24:07 +03:00
b7d3464609 Edited default mode ShapeRendering for metafile to svg conversion 2025-02-11 11:24:07 +03:00
beb8574dfd Fix bug #72962 2025-02-11 11:24:07 +03:00
c22cc89ef0 Merge remote-tracking branch 'origin/release/v8.3.0' into fix/bug71975 2025-02-11 13:10:43 +05:00
58255093bf Fix bug #70575 2025-02-11 05:49:33 +05:00
50846677d5 Add missed files 2025-02-10 13:30:46 +03:00
3b450306f1 Merge branch 'hotfix/v8.3.1' of git.onlyoffice.com:ONLYOFFICE/core into hotfix/v8.3.1 2025-02-10 12:07:58 +03:00
c67ec5f632 Add missed file 2025-02-10 11:20:06 +03:00
62450ee1fb add additional props sdt 2025-02-10 10:46:34 +03:00
ad301b6f50 Merge branch 'feature/docbuilder-license' into hotfix/v8.3.1 2025-02-09 00:46:23 +03:00
d251682639 Refactoring 2025-02-09 00:32:48 +03:00
896427db83 For bug 72964 2025-02-08 21:59:52 +03:00
e03f02103b For bug #70575 2025-02-07 18:22:26 +05:00
27c7920def Fix actual pos MovePage 2025-02-07 13:02:22 +03:00
a1b0421ec1 Fix MovePage 2025-02-07 13:02:21 +03:00
b7972ea391 Create MovePage 2025-02-07 13:02:21 +03:00
17840c5ed7 for bug #68408 2025-02-06 16:58:59 +03:00
ff4726e6ec for bug #68408 2025-02-06 15:53:53 +03:00
4e9cd74367 for bug #68408 2025-02-06 15:52:02 +03:00
b8737d2474 for bug #68408 2025-02-06 15:50:15 +03:00
2f4b7442c7 Fix CJSContext::GetCurrent method for jsc version 2025-02-06 12:44:39 +03:00
d97d2668d2 Merge branch release/v8.3.0 into master 2025-02-05 17:15:43 +00:00
45da53e9ae Refactoring standarttester 2025-02-04 20:12:07 +03:00
618a7ea09e Merge remote-tracking branch 'origin/release/v8.3.0' into fix/bug70675 2025-02-04 17:19:00 +05:00
a33743cff2 fix bug #73052 2025-02-04 13:44:41 +06:00
a83e19cbdf fix bug #72176 2025-02-03 16:35:23 +00:00
8a991ae24a Merge pull request 'Fix bug #72857' (#208) from fix/bug72857 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/208
2025-02-03 14:35:21 +00:00
6caca87b64 Merge pull request 'For bug #72496' (#207) from fix/bug72496 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/207
2025-02-03 14:35:10 +00:00
9ab884ae24 Merge pull request 'Fix hwp conversion' (#217) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/217
2025-02-03 14:15:54 +00:00
e493d976e3 Fix bug #73036 2025-02-03 16:59:47 +03:00
d75e7342cf Fix bug #73042 2025-02-03 15:45:09 +03:00
ddd750be9c Merge pull request 'Fix write base fonts' (#216) from fix/pdf-standart-fonts into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/216
2025-02-03 12:40:28 +00:00
79a4434583 Fix bug #73040 2025-02-03 15:35:39 +03:00
44ff2aff3c Fix empty FreeText AP 2025-02-03 15:32:41 +03:00
2f4b3e41b3 Fix write base fonts 2025-02-03 15:24:08 +03:00
fe208f5243 Merge pull request 'Fix bug #72961' (#215) from fix/bug-72961 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/215
2025-02-03 11:15:35 +00:00
e41c1d9703 Fix bug #72961 2025-02-03 14:12:29 +03:00
1cb56e532c Fix bug #72790 2025-02-03 15:39:18 +05:00
5c5f98a6e3 Fix bug 73014 2025-02-03 10:45:38 +03:00
f9dd82ad47 Merge pull request 'Fix HWP conversion' (#211) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/211
2025-02-03 06:43:31 +00:00
084c8f4b94 Fix bug #72999 2025-02-03 07:17:39 +03:00
bf15325a9e Fix bug #73000 2025-02-03 05:25:55 +03:00
1b50b3a53a Fix bug 72868 2025-02-01 17:39:08 +03:00
70b40c46d2 Fix bug #72721 2025-02-01 11:36:52 +03:00
23798f3c96 Fix ios build 2025-01-31 17:14:07 +03:00
d91c6ff830 Merge pull request 'fix/pivot-xlst-conversion' (#210) from fix/pivot-xlst-conversion into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/210
2025-01-31 10:05:08 +00:00
b75a577793 Merge branch 'develop' into fix/pivot-xlst-conversion 2025-01-31 13:40:45 +06:00
1e8d22080d Merge pull request 'Fix hwp bugs' (#209) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/209
2025-01-31 05:08:55 +00:00
90bcd47fb7 The conversion of the character spacing to hwp has been removed 2025-01-31 03:15:19 +03:00
c1adf0b30c Fix bug #72685 2025-01-31 03:15:12 +03:00
b65ed1ccb4 Fix bug #72825 2025-01-31 03:40:47 +05:00
8e4bbb5e27 Fix bug #72875 2025-01-30 22:13:22 +05:00
81a4d9ccd0 Fix bug 72936 2025-01-30 16:51:25 +03:00
a97014c173 Disable use filesystem in metafiles (js module) 2025-01-30 14:26:57 +03:00
b3951d083a Fix elements align in html conversion 2025-01-30 10:37:42 +00:00
7d78b37540 Fix bug #72932 2025-01-30 10:37:42 +00:00
ff162d451e Merge pull request 'Fix hwp bug' (#205) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/205
2025-01-30 10:33:13 +00:00
5dc6402006 Fix test file 2025-01-30 13:12:27 +03:00
fae17d9bfc Merge pull request 'For bug #72694' (#204) from fix/bug72694 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/204
2025-01-30 08:02:28 +00:00
931f4edae4 For bug #72694 2025-01-30 13:36:42 +06:00
3609cf1237 Fix bug #72933 2025-01-30 00:49:49 +03:00
cc8fa641aa Merge pull request 'Fix bug 72811' (#203) from fix/bug-72811 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/203
2025-01-29 16:20:19 +00:00
3b9a865d77 Fix bug 72811 2025-01-29 19:07:58 +03:00
f3b0a992bd Fix typo 2025-01-29 18:57:35 +03:00
74f3e7f279 Merge pull request 'Fix hwp conversion' (#202) from fix/hwp into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/202
2025-01-29 15:45:08 +00:00
d195aa4a79 Fix build 2025-01-29 18:31:12 +03:00
4a384edf08 For bug #72496 2025-01-29 20:23:33 +05:00
30f96cbc6c Fix bug #72705 2025-01-29 18:15:29 +03:00
007362d8be Fix bug #72780 2025-01-29 17:57:54 +03:00
f4aac048ea fix bug #72012 2025-01-29 17:44:17 +03:00
f815fec8ed Fix bug #72714 2025-01-29 17:14:53 +03:00
4ec217226d Fix bug #72721 2025-01-29 16:32:43 +03:00
3cef41e876 Added bookmark conversion, fix bugs, refactoring in hwp format 2025-01-29 16:22:03 +03:00
20bff1d6fe for bug #72794 2025-01-29 11:17:21 +00:00
8da1a109de Fix bug #72857 2025-01-29 02:28:47 +05:00
704cef604e fix bug #72496 2025-01-28 19:26:15 +03:00
3c850e2086 Fix bug #72667 2025-01-28 13:47:20 +00:00
ab660cb8a3 Merge pull request 'for bug #72496' (#198) from For/bug72496 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/198
2025-01-28 13:12:05 +00:00
af4343b1d8 for bug #72496 2025-01-28 16:06:39 +03:00
7e4fe558f4 Fix bug #72847 2025-01-28 15:17:08 +03:00
f942e56361 fix namespaces 2025-01-28 13:46:28 +03:00
8b85f6987f Merge pull request 'Fix bug #72839' (#197) from fix/bug-72839 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/197
2025-01-28 09:13:21 +00:00
cbe412d3c7 Fix bug #72839 2025-01-28 12:03:31 +03:00
6913cae8f3 Fix bug #72414 2025-01-28 06:09:12 +05:00
d3d9c8df94 Added text indent in hwp conversion 2025-01-27 22:14:25 +03:00
01b582c4b9 Added BorderFill in hwp conversion 2025-01-27 22:01:41 +03:00
4568144a22 Merge branch 'fix/bug72794' into release/v8.3.0 2025-01-27 20:38:15 +03:00
cc4df3726a fix bug #72745 2025-01-27 20:37:02 +03:00
696610862a . 2025-01-27 18:27:20 +03:00
da6a5e9e98 for binary 2025-01-27 15:30:56 +03:00
d395e63b80 Merge pull request 'Fix bug #72657' (#188) from fix/bug72657 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/188
2025-01-27 12:30:02 +00:00
0350675df6 Fix min version 2025-01-27 13:58:30 +03:00
aead2e9fb8 Merge pull request 'Fix bug#72779' (#196) from fix/bug72779 into release/v8.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/196
2025-01-27 10:03:20 +00:00
d12bad7bd1 Fix bug#72779 2025-01-27 15:58:25 +06:00
da2284fff6 Fix bug #72712 2025-01-26 18:26:03 +00:00
1382aa0b3d Fix bug #72780 2025-01-26 18:26:03 +00:00
8ba5df60d9 Fix bug #72705 2025-01-26 18:26:03 +00:00
5299872b17 Fixes for snapshots 2025-01-26 20:18:14 +03:00
e1757dd5d1 fix bug #72796 2025-01-26 12:10:44 +03:00
87dcea55b1 fix build 2025-01-26 11:58:12 +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
c2dc112949 Merge pull request 'release/v8.3.0' (#192) from release/v8.3.0 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/192
2025-01-25 10:45:02 +00: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
c85713d82a Merge branch 'develop' into fix/pivot-xlst-conversion 2025-01-21 17:44:15 +06:00
6d970d0706 Merge pull request 'feature/xlsb-worksheet-writing-optimization' (#178) from feature/xlsb-worksheet-writing-optimization into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/178
2025-01-21 10:13:50 +00: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
cf047defac Fix array formula conversion 2025-01-21 14:44:31 +06: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
aa72db079f Fix shared formulas conversion 2025-01-20 18:27:09 +06: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
483ead4243 Add pivot cache ext xlst writing 2025-01-20 14:20:47 +06: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
ddd92777b4 Restored pivotTable writing 2025-01-16 20:15:16 +06: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
07ab24638e fix utf8 cashes writing 2025-01-16 14:56:29 +06: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
ffe44155e2 Revert "add pivot cache defenition xlst reading&writing"
This reverts commit 9c70225a9e.
2025-01-15 21:39:48 +06:00
2ea586ec6f Fix bug #72414 2025-01-15 20:13:21 +05:00
7c2093a4c7 Add pivot cache records xlst writing 2025-01-15 21:12:17 +06:00
4f6fa2a15c Fix pivot cache definition xml writing 2025-01-15 19:38:31 +06: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
9c70225a9e add pivot cache defenition xlst reading&writing 2025-01-14 20:12:03 +06: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
b42e3ad01f Add pivot cache xlst conversion 2025-01-13 18:34:46 +06:00
07bf7a44aa Fix bug #72375 2025-01-13 17:08:46 +05:00
3a40dc1f8b Fix chart protection conversion 2025-01-13 14:54:15 +06: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
6952bedbc3 Add chartsheet binary writing 2025-01-10 21:49:03 +06:00
a7774a6bc3 fix bug #72395 2025-01-10 17:10:46 +03:00
bf299e82bb add worksheet ext conversion 2025-01-10 17:23:18 +06:00
915790e26e Revert "Add ext lst binary conversion optimization" 2025-01-10 17:06:08 +06:00
e18a26a252 Merge branch 'develop' into feature/xlsb-worksheet-writing-optimization 2025-01-10 13:11:26 +06:00
4d15b5c19d Improved conversion of shapes properties в hwp format 2025-01-10 00:50:11 +03:00
73ccefd720 Add ext lst binary conversion optimization 2025-01-09 22:03:52 +06:00
11385b946d Add picture worksheet xlsb conversion optimisation 2025-01-09 18:01:18 +06: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
7598e882b8 Merge pull request 'release/v8.3.0' (#150) from release/v8.3.0 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/150
2025-01-02 19:52:29 +00: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
08971025bd Added support for conversion of HWP tables, fixed bugs 2024-12-27 23:58:06 +03: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
7b03bcde89 Writing the HWP format conversion 2024-12-24 11:22:56 +03:00
51cc45d178 Refactoring AnnotField 2024-12-24 10:58:05 +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
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
9dc3d3ed82 Merge pull request 'release/v8.3.0' (#142) from release/v8.3.0 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/142
2024-12-23 07:15:49 +00: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
6fe92e1725 Fix table header columns conversion 2024-12-20 17:58:52 +05:00
e512ceedec Fix cell ref reading 2024-12-20 18:30:08 +06:00
d05a40389e Add activeX controls & listParts conversion optimisation 2024-12-20 14:50:18 +06:00
ea0494e8c2 Add autofilter conversion optimization 2024-12-19 18:52:50 +06:00
127680c988 Add dcon conversion optimization 2024-12-19 16:09:08 +06:00
cdbd9bdba3 Add protected ranges conversion optimisation 2024-12-19 15:03:59 +06:00
1910151224 Add legacy drawing && ole objects conversion optimization 2024-12-18 18:42:57 +06:00
4a110d68c1 Fixed bugs in reading hwp format and added test example 2024-12-18 15:13:43 +03:00
cd27981734 Add headfooter & pageSetup conversion optimization 2024-12-18 16:44:09 +06:00
9509d5e730 Add merge cells conversion optimisation 2024-12-18 14:51:48 +06:00
219733c437 Add dvals&hyperlinks conversion optimisation 2024-12-17 21:00:42 +06:00
48d86cb7ce Add base classes 2024-12-17 15:39:50 +03:00
9991cc8c03 Rewrite split lines logic 2024-12-17 15:13:53 +03:00
36a3b693d5 Update paragraph logic for enums 2024-12-17 13:44:31 +03:00
328e379ec2 The writing code for converting hwp format 2024-12-16 21:05:10 +03:00
ad4fee9581 Fix cond fmt conversion 2024-12-16 21:27:31 +06:00
2af29de849 Add condfmt conversion 2024-12-16 20:08:13 +06:00
0c1df859e2 The writing code for converting hwp format 2024-12-14 16:36:33 +03:00
d58424d089 Fix build 2024-12-14 11:38:11 +03:00
fe2ca8c566 Delete unused headers & add new files 2024-12-14 11:33:47 +03:00
20d2ff7954 Refactoring 2024-12-14 11:18:42 +03:00
b125c19d02 Remove useless call 2024-12-14 07:13:48 +03:00
2f2d11a5f6 Fix bug with recalc size of space 2024-12-14 06:51:59 +03:00
de4897fdef Add HorVerLinesCollector 2024-12-13 16:54:16 +03:00
f9952d0f94 Refactoring for future tables 2024-12-13 15:50:32 +03:00
0c847ce1d8 Fix worksheet protection conversion 2024-12-13 16:57:17 +06:00
f1905b524b Fix formula conversion 2024-12-13 16:00:00 +06:00
d7b435a446 Delete unused file 2024-12-13 12:28:13 +03:00
f742a0ef10 Add worksheet protection conversion 2024-12-12 21:01:16 +06:00
3547ad9c57 Add fmtinfo & colinfo conversion 2024-12-12 17:21:40 +06:00
0d2248352b Add worksheet views conversion 2024-12-12 14:40:55 +06:00
bc4c39b7aa The writing code for converting hwp format 2024-12-11 21:34:46 +03:00
012a724069 add sheet dimension binary writing 2024-12-11 20:54:38 +06:00
2e50a2ede4 Add compressed cells processing to xlsx->xlsb conversion 2024-12-11 17:23:50 +06:00
78d7d40c0a Add sheet property binary conversion 2024-12-11 15:54:15 +06:00
a5917c389f The writing code for converting hwp format 2024-12-10 22:19:37 +03:00
dac47c3214 Fix string cells conversion 2024-12-10 19:31:58 +06:00
be3a84dcf7 Add metadata binary writing 2024-12-10 18:19:06 +06:00
22a2079c5f Add datatable formula conversion 2024-12-10 17:25:53 +06:00
fe2bac216f Add array fmla conversion 2024-12-10 16:09:54 +06:00
d89e94bb8e Merge branch 'develop' into feature/xlsb-worksheet-writing-optimization 2024-12-10 13:03:42 +06:00
a95aba3ff4 Merge pull request 'release/v8.3.0' (#129) from release/v8.3.0 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/129
2024-12-10 04:18:28 +00:00
a93f00d0af The writing code for converting hwp format 2024-12-09 22:18:04 +03:00
a1ebcaea23 Merge branch hotfix/v8.2.2 into develop 2024-12-09 12:00:03 +00:00
ab10854dde Fix shared formula conversion 2024-12-09 17:50:36 +06:00
3f25120e04 Add shared formula conversion 2024-12-06 19:04:26 +06:00
b776b7b63f The writing code for converting hwp format 2024-12-06 15:18:32 +03:00
44d0a0ca23 Add normal formula conversion 2024-12-06 15:13:20 +06:00
ecd71dd92a The writing code for converting hwp format 2024-12-05 21:27:21 +03:00
ec645c0202 Add worksheet direct binary writing 2024-12-04 21:41:19 +06:00
63134aa586 Merge branch 'develop' into feature/xlsb-worksheet-writing-optimization 2024-12-04 21:01:44 +06:00
8489127f71 Merge pull request 'release/v8.3.0' (#114) from release/v8.3.0 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/114
2024-12-04 11:00:36 +00:00
e024463770 Merge branch 'develop' into feature/xlsb-worksheet-writing-optimization 2024-12-04 14:20:37 +06: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
25fa85c218 Merge branch 'develop' into feature/xlsb-worksheet-writing-optimization 2024-11-29 13:41:35 +06:00
6e20c656e7 Add pivot records reading memory optimisation 2024-11-28 20:42:58 +06:00
a158529c70 Add pivot cache records direct writing 2024-11-28 18:53:05 +06:00
87b5ae8f75 Merge branch hotfix/v8.2.2 into master 2024-11-28 12:16:10 +00:00
1c163421c7 Add stream cache writer getting 2024-11-28 15:25:59 +06:00
295dbbbb86 The writing code for converting hwp format 2024-11-27 20:45:00 +03:00
10ff332f4d Merge remote-tracking branch 'origin/develop' into fix/bug69238 2024-11-27 15:45:33 +05:00
d5e7ccac2d Add odf tests 2024-11-27 13:21:20 +05:00
f57179911f The beginning of writing code for converting hwp format 2024-11-26 20:52:11 +03:00
925f3614c7 Merge branch 'fix/bug69238' into fix/odf_tests 2024-11-22 17:36:10 +05:00
ce0f8251d3 Fix bug #69238 2024-11-22 17:32:40 +05:00
6b21323e8c Merge branch hotfix/v8.2.1 into master 2024-11-22 10:46:53 +00:00
42466cf648 Fix atan2 custom shape formula conversion 2024-10-31 18:08:36 +05:00
d21d0caa68 Fix bug #70675 2024-10-16 18:42:07 +05:00
63bf1797c0 Fix bug #70671 2024-10-14 17:57:28 +05:00
f8ba0c59a6 Add license check for onlyoffice docbuilder builds 2024-09-25 16:04:17 +04:00
0553db3a69 Merge branch 'fix/bug69957' into fix/odf_tests 2024-09-04 16:37:16 +05:00
a7ef6ea3be Merge branch 'fix/bug69988' into fix/odf_tests 2024-09-04 16:36:08 +05:00
d72b9b47ed Test docx to odt invisible symbols size 2024-08-30 16:49:22 +05:00
7e7186f068 Test odt to docx tab size conversion 2024-08-29 21:39:58 +05:00
2d61e8bbd2 Merge remote-tracking branch 'origin/fix/bug44363' into fix/odf_tests 2024-08-29 19:43:48 +05:00
c4c350f1aa Init testing document tab size conversion 2024-08-29 18:56:57 +05:00
2f382d21dc Test odt to docx page size conversion 2024-08-29 18:04:53 +05:00
a968a3a035 Merge remote-tracking branch 'origin/fix/bug44363' into fix/odf_tests 2024-08-28 17:08:54 +05:00
deb875337d Merge remote-tracking branch 'origin/release/v8.2.0' into fix/odf_tests 2024-08-28 16:54:23 +05:00
1b0791364b Refactor odf tests 2024-08-14 17:14:00 +03:00
d939aa7247 Fix build 2024-08-14 17:12:56 +03:00
543 changed files with 32630 additions and 4486 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

@ -63,6 +63,26 @@ namespace NSCSS
return m_pInternal->GetDpi();
}
void CCssCalculator::ClearPageData()
{
m_pInternal->ClearPageData();
}
void CCssCalculator::ClearEmbeddedStyles()
{
m_pInternal->ClearEmbeddedStyles();
}
void CCssCalculator::ClearAllowedStyleFiles()
{
m_pInternal->ClearAllowedStyleFiles();
}
void CCssCalculator::ClearStylesFromFile(const std::wstring& wsFilePath)
{
m_pInternal->ClearStylesFromFile(wsFilePath);
}
void CCssCalculator::Clear()
{
m_pInternal->Clear();

View File

@ -35,6 +35,10 @@ namespace NSCSS
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
void ClearPageData();
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFilePath);
void Clear();
};
}

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,58 +38,120 @@ bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vect
namespace NSCSS
{
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
CStyleStorage::CStyleStorage()
{}
CCssCalculator_Private::~CCssCalculator_Private()
CStyleStorage::~CStyleStorage()
{
m_arFiles.clear();
for (std::map<std::wstring, CElement*>::iterator oIter = m_mData.begin(); oIter != m_mData.end(); ++oIter)
if (oIter->second != NULL)
delete oIter->second;
m_mData.clear();
Clear();
}
inline void CCssCalculator_Private::GetOutputData(KatanaOutput *oOutput)
void CStyleStorage::Clear()
{
if ( NULL == oOutput )
return;
for (TStyleFileData* pStyleFileData : m_arStyleFiles)
{
if (nullptr == pStyleFileData)
continue;
switch (oOutput->mode) {
case KatanaParserModeStylesheet:
GetStylesheet(oOutput->stylesheet);
break;
case KatanaParserModeRule:
GetRule(oOutput->rule);
break;
case KatanaParserModeKeyframeRule:
case KatanaParserModeKeyframeKeyList:
case KatanaParserModeMediaList:
case KatanaParserModeValue:
case KatanaParserModeSelector:
case KatanaParserModeDeclarationList:
break;
for (std::map<std::wstring, CElement*>::iterator oIter = pStyleFileData->m_mStyleData.begin(); oIter != pStyleFileData->m_mStyleData.end(); ++oIter)
if (oIter->second != nullptr)
delete oIter->second;
delete pStyleFileData;
}
m_arStyleFiles.clear();
m_arEmptyStyleFiles.clear();
ClearEmbeddedStyles();
ClearAllowedStyleFiles();
#ifdef CSS_CALCULATOR_WITH_XHTML
ClearPageData();
#endif
}
void CStyleStorage::AddStyles(const std::string& sStyle)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output, m_mEmbeddedStyleData);
katana_destroy_output(output);
}
void CStyleStorage::AddStyles(const std::wstring& wsStyle)
{
if (wsStyle.empty())
return;
#ifdef CSS_CALCULATOR_WITH_XHTML
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
std::wsmatch oMatch;
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
{
AddPageData(oMatch[1].str(), oMatch[2].str());
oSearchStart = oMatch.suffix().first;
}
#endif
AddStyles(U_TO_UTF8(wsStyle));
}
void CStyleStorage::AddStylesFromFile(const std::wstring& wsFileName)
{
std::set<std::wstring>::const_iterator itEmptyFileFound = m_arEmptyStyleFiles.find(wsFileName);
if (m_arEmptyStyleFiles.cend() != itEmptyFileFound)
return;
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
[wsFileName](const TStyleFileData* pStyleFileData)
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
m_arAllowedStyleFiles.insert(wsFileName);
if (m_arStyleFiles.cend() != itFound)
return;
TStyleFileData *pStyleFileData = new TStyleFileData();
pStyleFileData->m_wsStyleFilepath = wsFileName;
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName), pStyleFileData->m_mStyleData);
if (!pStyleFileData->m_mStyleData.empty())
m_arStyleFiles.push_back(pStyleFileData);
else
{
m_arEmptyStyleFiles.insert(wsFileName);
delete pStyleFileData;
}
}
void CStyleStorage::ClearStylesFromFile(const std::wstring& wsFileName)
{
std::vector<TStyleFileData*>::const_iterator itFound = std::find_if(m_arStyleFiles.cbegin(), m_arStyleFiles.cend(),
[wsFileName](const TStyleFileData* pStyleFileData)
{ return wsFileName == pStyleFileData->m_wsStyleFilepath; });
if (m_arStyleFiles.cend() != itFound)
{
m_arStyleFiles.erase(itFound);
delete *itFound;
}
}
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
void CStyleStorage::AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles)
{
if (m_arPageDatas.empty())
return {};
for (const TPageData& oPageData : m_arPageDatas)
{
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
return oPageData.m_mData;
}
return {};
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageName), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
}
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
void CStyleStorage::SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode)
{
for (const std::pair<std::wstring, std::wstring> &oData : mData)
{
@ -107,149 +166,84 @@ namespace NSCSS
}
}
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
std::map<std::wstring, std::wstring> CStyleStorage::GetPageData(const std::wstring& wsPageName)
{
std::vector<std::wstring> arNodes;
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
{
if (!oNode->m_wsName.empty())
arNodes.push_back(oNode->m_wsName);
if (!oNode->m_wsClass.empty())
{
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
{
std::vector<std::wstring> arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arNodes.push_back(L'.' + oNode->m_wsClass);
}
if (!oNode->m_wsId.empty())
arNodes.push_back(L'#' + oNode->m_wsId);
}
return arNodes;
}
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
{
if (arNextNodes.empty())
return;
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
if (!arTempPrev.empty())
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
}
std::vector<CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
{
if (arNodes.empty())
if (m_arPageDatas.empty())
return {};
std::vector<CElement*> arFindedElements;
std::wstring wsName, wsId;
std::vector<std::wstring> arClasses;
if (!arNodes.empty() && arNodes.back()[0] == L'#')
for (const TPageData& oPageData : m_arPageDatas)
{
wsId = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsId);
if (std::find(oPageData.m_wsNames.begin(), oPageData.m_wsNames.end(), wsPageName) != oPageData.m_wsNames.end())
return oPageData.m_mData;
}
if (!arNodes.empty() && arNodes.back()[0] == L'.')
{
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
arNextNodes.push_back(arNodes.back());
arNodes.pop_back();
}
return {};
}
if (!arNodes.empty())
{
wsName = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsName);
}
const std::map<std::wstring, CElement*>::const_iterator oFindName = m_mData.find(wsName);
std::map<std::wstring, CElement*>::const_iterator oFindId;
if (!wsId.empty())
{
oFindId = m_mData.find(wsId);
if (m_mData.cend() != oFindId)
{
if (!oFindId->second->Empty())
arFindedElements.push_back(oFindId->second);
FindPrevAndKindElements(oFindId->second, arNextNodes, arFindedElements, wsName);
}
}
if (!arClasses.empty())
{
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
{
const std::map<std::wstring, CElement*>::const_iterator oFindClass = m_mData.find(*iClass);
if (oFindClass != m_mData.cend())
{
if (!oFindClass->second->Empty())
arFindedElements.push_back(oFindClass->second);
FindPrevAndKindElements(oFindClass->second, arNextNodes, arFindedElements, wsName);
}
}
}
if (oFindName != m_mData.cend())
{
if (!oFindName->second->Empty())
arFindedElements.push_back(oFindName->second);
FindPrevAndKindElements(oFindName->second, arNextNodes, arFindedElements, wsName, arClasses);
}
if (arFindedElements.size() > 1)
{
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
[](CElement* oFirstElement, CElement* oSecondElement)
{
return oFirstElement->GetWeight() > oSecondElement->GetWeight();
});
}
return arFindedElements;
void CStyleStorage::ClearPageData()
{
m_arPageDatas.clear();
}
#endif
void CCssCalculator_Private::AddPageData(const std::wstring &wsPageNames, const std::wstring &wsStyles)
const CElement* CStyleStorage::FindElement(const std::wstring& wsSelector)
{
m_arPageDatas.push_back({NS_STATIC_FUNCTIONS::GetWordsW(wsPageNames), NS_STATIC_FUNCTIONS::GetRules(wsStyles)});
if (wsSelector.empty())
return nullptr;
const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mEmbeddedStyleData);
if (nullptr != pFoundElement)
return pFoundElement;
for (std::vector<TStyleFileData*>::const_reverse_iterator itIter = m_arStyleFiles.crbegin(); itIter < m_arStyleFiles.crend(); ++itIter)
{
if (m_arAllowedStyleFiles.cend() == std::find(m_arAllowedStyleFiles.cbegin(), m_arAllowedStyleFiles.cend(), (*itIter)->m_wsStyleFilepath))
continue;
pFoundElement = FindSelectorFromStyleData(wsSelector, (*itIter)->m_mStyleData);
if (nullptr != pFoundElement)
return pFoundElement;
}
return nullptr;
}
inline void CCssCalculator_Private::GetStylesheet(const KatanaStylesheet *oStylesheet)
void CStyleStorage::AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output, mStyleData);
katana_destroy_output(output);
}
void CStyleStorage::ClearEmbeddedStyles()
{
for (std::map<std::wstring, CElement*>::iterator oIter = m_mEmbeddedStyleData.begin(); oIter != m_mEmbeddedStyleData.end(); ++oIter)
if (oIter->second != nullptr)
delete oIter->second;
m_mEmbeddedStyleData.clear();
}
void CStyleStorage::ClearAllowedStyleFiles()
{
m_arAllowedStyleFiles.clear();
}
void CStyleStorage::GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData)
{
for (size_t i = 0; i < oStylesheet->imports.length; ++i)
GetRule((KatanaRule*)oStylesheet->imports.data[i]);
GetRule((KatanaRule*)oStylesheet->imports.data[i], mStyleData);
for (size_t i = 0; i < oStylesheet->rules.length; ++i)
GetRule((KatanaRule*)oStylesheet->rules.data[i]);
GetRule((KatanaRule*)oStylesheet->rules.data[i], mStyleData);
}
inline void CCssCalculator_Private::GetRule(const KatanaRule *oRule)
void CStyleStorage::GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
{
if ( NULL == oRule )
return;
@ -257,7 +251,7 @@ namespace NSCSS
switch (oRule->type) {
case KatanaRuleStyle:
{
GetStyleRule((KatanaStyleRule*)oRule);
GetStyleRule((KatanaStyleRule*)oRule, mStyleData);
break;
}
default:
@ -265,7 +259,7 @@ namespace NSCSS
}
}
inline void CCssCalculator_Private::GetStyleRule(const KatanaStyleRule *oRule)
void CStyleStorage::GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData)
{
if (oRule->declarations->length == 0)
return;
@ -281,7 +275,7 @@ namespace NSCSS
for (std::vector<std::wstring>::reverse_iterator oWord = arWords.rbegin(); oWord != arWords.rend(); ++oWord)
{
const size_t posPoint = oWord->find(L'.');
const size_t posPoint = oWord->find(L'.');
const size_t posLattice = oWord->find(L'#');
const std::wstring sName = (posPoint != std::wstring::npos) ? oWord->substr(0, posPoint) : (posLattice != std::wstring::npos) ? oWord->substr(0, posLattice) : *oWord;
@ -297,8 +291,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindId = m_mData.find(sId);
if (oFindId != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindId = mStyleData.find(sId);
if (oFindId != mStyleData.end())
{
oIdElement = oFindId->second;
bCreateFirst = false;
@ -326,8 +320,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = m_mData.find(sClass);
if (oFindClass != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindClass = mStyleData.find(sClass);
if (oFindClass != mStyleData.end())
{
oClassElement = oFindClass->second;
bCreateFirst = false;
@ -359,8 +353,8 @@ namespace NSCSS
{
if (NULL == oFirstElement && bCreateFirst)
{
const std::map<std::wstring, CElement*>::const_iterator& oFindName = m_mData.find(sName);
if (oFindName != m_mData.end())
const std::map<std::wstring, CElement*>::const_iterator& oFindName = mStyleData.find(sName);
if (oFindName != mStyleData.end())
{
oNameElement = oFindName->second;
bCreateFirst = false;
@ -392,11 +386,16 @@ namespace NSCSS
oLastElement->AddProperties(mStyle);
if (NULL != oFirstElement)
m_mData[oFirstElement->GetSelector()] = oFirstElement;
mStyleData[oFirstElement->GetSelector()] = oFirstElement;
}
}
inline std::vector<std::wstring> CCssCalculator_Private::GetSelectorList(const KatanaArray* oSelectors) const
std::wstring CStyleStorage::GetValueList(const KatanaArray* oValues)
{
return StringifyValueList(oValues);
}
std::vector<std::wstring> CStyleStorage::GetSelectorList(const KatanaArray* oSelectors) const
{
if (oSelectors->length == 0)
return std::vector<std::wstring>();
@ -409,7 +408,7 @@ namespace NSCSS
return arSelectors;
}
inline std::wstring CCssCalculator_Private::GetSelector(const KatanaSelector *oSelector) const
std::wstring CStyleStorage::GetSelector(const KatanaSelector* oSelector) const
{
KatanaParser oParser;
oParser.options = &kKatanaDefaultOptions;
@ -428,7 +427,7 @@ namespace NSCSS
return wsText;
}
inline std::map<std::wstring, std::wstring> CCssCalculator_Private::GetDeclarationList(const KatanaArray* oDeclarations) const
std::map<std::wstring, std::wstring> CStyleStorage::GetDeclarationList(const KatanaArray* oDeclarations) const
{
if(oDeclarations->length == 0)
return std::map<std::wstring, std::wstring>();
@ -441,7 +440,7 @@ namespace NSCSS
return arDeclarations;
}
inline std::pair<std::wstring, std::wstring> CCssCalculator_Private::GetDeclaration(const KatanaDeclaration* oDecl) const
std::pair<std::wstring, std::wstring> CStyleStorage::GetDeclaration(const KatanaDeclaration* oDecl) const
{
std::wstring sValueList = StringifyValueList(oDecl->values);
@ -451,9 +450,184 @@ namespace NSCSS
return std::make_pair(UTF8_TO_U(std::string(oDecl->property)), sValueList);
}
inline std::wstring CCssCalculator_Private::GetValueList(const KatanaArray *oValues)
void CStyleStorage::GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData)
{
return StringifyValueList(oValues);
if ( NULL == oOutput )
return;
switch (oOutput->mode) {
case KatanaParserModeStylesheet:
GetStylesheet(oOutput->stylesheet, mStyleData);
break;
case KatanaParserModeRule:
GetRule(oOutput->rule, mStyleData);
break;
case KatanaParserModeKeyframeRule:
case KatanaParserModeKeyframeKeyList:
case KatanaParserModeMediaList:
case KatanaParserModeValue:
case KatanaParserModeSelector:
case KatanaParserModeDeclarationList:
break;
}
}
const CElement* CStyleStorage::FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData)
{
std::map<std::wstring, CElement*>::const_iterator itFound = mStyleData.find(wsSelector);
if (mStyleData.cend() != itFound)
return itFound->second;
return nullptr;
}
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
CCssCalculator_Private::~CCssCalculator_Private()
{}
#ifdef CSS_CALCULATOR_WITH_XHTML
void CCssCalculator_Private::SetPageData(NSProperties::CPage &oPage, const std::map<std::wstring, std::wstring> &mData, unsigned int unLevel, bool bHardMode)
{
//TODO:: пересмотреть данный метод
m_oStyleStorage.SetPageData(oPage, mData, unLevel, bHardMode);
}
std::map<std::wstring, std::wstring> CCssCalculator_Private::GetPageData(const std::wstring &wsPageName)
{
return m_oStyleStorage.GetPageData(wsPageName);
}
void CCssCalculator_Private::ClearPageData()
{
m_oStyleStorage.ClearPageData();
}
#endif
std::vector<std::wstring> CCssCalculator_Private::CalculateAllNodes(const std::vector<CNode> &arSelectors)
{
std::vector<std::wstring> arNodes;
for (std::vector<CNode>::const_reverse_iterator oNode = arSelectors.rbegin(); oNode != arSelectors.rend(); ++oNode)
{
if (!oNode->m_wsName.empty())
arNodes.push_back(oNode->m_wsName);
if (!oNode->m_wsClass.empty())
{
if (oNode->m_wsClass.find(L' ') != std::wstring::npos)
{
std::vector<std::wstring> arClasses = NS_STATIC_FUNCTIONS::GetWordsW(oNode->m_wsClass, false, L" ");
arNodes.push_back(std::accumulate(arClasses.begin(), arClasses.end(), std::wstring(),
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arNodes.push_back(L'.' + oNode->m_wsClass);
}
if (!oNode->m_wsId.empty())
arNodes.push_back(L'#' + oNode->m_wsId);
}
return arNodes;
}
void CCssCalculator_Private::FindPrevAndKindElements(const CElement *pElement, const std::vector<std::wstring> &arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring &wsName, const std::vector<std::wstring> &arClasses)
{
if (arNextNodes.empty())
return;
const std::vector<CElement*> arTempPrev = pElement->GetPrevElements(arNextNodes.crbegin() + 1, arNextNodes.crend());
const std::vector<CElement*> arTempKins = pElement->GetNextOfKin(wsName, arClasses);
if (!arTempPrev.empty())
arFindedElements.insert(arFindedElements.end(), arTempPrev.begin(), arTempPrev.end());
if (!arTempKins.empty())
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
}
std::vector<const CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
{
if (arNodes.empty())
return {};
std::vector<const CElement*> arFindedElements;
std::wstring wsName, wsId;
std::vector<std::wstring> arClasses;
if (!arNodes.empty() && arNodes.back()[0] == L'#')
{
wsId = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsId);
}
if (!arNodes.empty() && arNodes.back()[0] == L'.')
{
arClasses = NS_STATIC_FUNCTIONS::GetWordsW(arNodes.back(), false, L" ");
arNextNodes.push_back(arNodes.back());
arNodes.pop_back();
}
if (!arNodes.empty())
{
wsName = arNodes.back();
arNodes.pop_back();
arNextNodes.push_back(wsName);
}
if (!wsId.empty())
{
const CElement* pFoundId = m_oStyleStorage.FindElement(wsId);
if(nullptr != pFoundId)
{
if (!pFoundId->Empty())
arFindedElements.push_back(pFoundId);
FindPrevAndKindElements(pFoundId, arNextNodes, arFindedElements, wsName);
}
}
if (!arClasses.empty())
{
for (std::vector<std::wstring>::const_reverse_iterator iClass = arClasses.rbegin(); iClass != arClasses.rend(); ++iClass)
{
const CElement* pFoundClass = m_oStyleStorage.FindElement(*iClass);
if (nullptr != pFoundClass)
{
if (!pFoundClass->Empty())
arFindedElements.push_back(pFoundClass);
FindPrevAndKindElements(pFoundClass, arNextNodes, arFindedElements, wsName);
}
}
}
const CElement* pFoundName = m_oStyleStorage.FindElement(wsName);
if (nullptr != pFoundName)
{
if (!pFoundName->Empty())
arFindedElements.push_back(pFoundName);
FindPrevAndKindElements(pFoundName, arNextNodes, arFindedElements, wsName, arClasses);
}
if (arFindedElements.size() > 1)
{
std::sort(arFindedElements.rbegin(), arFindedElements.rend(),
[](const CElement* oFirstElement, const CElement* oSecondElement)
{ return oFirstElement->GetWeight() > oSecondElement->GetWeight(); });
}
return arFindedElements;
}
#ifdef CSS_CALCULATOR_WITH_XHTML
@ -566,42 +740,20 @@ namespace NSCSS
return true;
}
#endif
void CCssCalculator_Private::AddStyles(const std::string &sStyle)
{
if (sStyle.empty())
return;
KatanaOutput *output = katana_parse(sStyle.c_str(), sStyle.length(), KatanaParserModeStylesheet);
this->GetOutputData(output);
katana_destroy_output(output);
void CCssCalculator_Private::AddStyles(const std::string& sStyle)
{
m_oStyleStorage.AddStyles(sStyle);
}
void CCssCalculator_Private::AddStyles(const std::wstring &wsStyle)
void CCssCalculator_Private::AddStyles(const std::wstring& wsStyle)
{
if (wsStyle.empty())
return;
std::wregex oRegex(L"@page\\s*([^{]*)(\\{[^}]*\\})");
std::wsmatch oMatch;
std::wstring::const_iterator oSearchStart(wsStyle.cbegin());
while (std::regex_search(oSearchStart, wsStyle.cend(), oMatch, oRegex))
{
AddPageData(oMatch[1].str(), oMatch[2].str());
oSearchStart = oMatch.suffix().first;
}
AddStyles(U_TO_UTF8(wsStyle));
m_oStyleStorage.AddStyles(wsStyle);
}
void CCssCalculator_Private::AddStylesFromFile(const std::wstring& wsFileName)
{
if (std::find(m_arFiles.begin(), m_arFiles.end(), wsFileName) != m_arFiles.end())
return;
m_arFiles.push_back(wsFileName);
AddStyles(NS_STATIC_FUNCTIONS::GetContentAsUTF8(wsFileName));
m_oStyleStorage.AddStylesFromFile(wsFileName);
}
void CCssCalculator_Private::SetDpi(unsigned short int nValue)
@ -614,9 +766,23 @@ namespace NSCSS
return m_nDpi;
}
const std::map<std::wstring, CElement *> *CCssCalculator_Private::GetData() const
void CCssCalculator_Private::ClearEmbeddedStyles()
{
return &m_mData;
m_oStyleStorage.ClearEmbeddedStyles();
#ifdef CSS_CALCULATOR_WITH_XHTML
m_mUsedStyles.clear();
#endif
}
void CCssCalculator_Private::ClearAllowedStyleFiles()
{
m_oStyleStorage.ClearAllowedStyleFiles();
}
void CCssCalculator_Private::ClearStylesFromFile(const std::wstring& wsFilePath)
{
m_oStyleStorage.ClearStylesFromFile(wsFilePath);
}
std::wstring CCssCalculator_Private::GetEncoding() const
@ -629,10 +795,21 @@ namespace NSCSS
m_sEncoding = L"UTF-8";
m_nDpi = 96;
m_mData.clear();
m_arFiles.clear();
m_oStyleStorage.Clear();
#ifdef CSS_CALCULATOR_WITH_XHTML
m_mUsedStyles.clear();
#endif
}
bool IsTableElement(const std::wstring& wsNameTag)
{
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
L"th" == wsNameTag;
}
}
inline static std::wstring StringifyValueList(const KatanaArray* oValues)
{
if (NULL == oValues)
@ -733,11 +910,4 @@ inline static std::wstring StringifyValue(const KatanaValue* oValue)
return str;
}
inline static bool IsTableElement(const std::wstring& wsNameTag)
{
return L"td" == wsNameTag || L"tr" == wsNameTag || L"table" == wsNameTag ||
L"tbody" == wsNameTag || L"thead" == wsNameTag || L"tfoot" == wsNameTag ||
L"th" == wsNameTag;
}

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,15 +14,43 @@
namespace NSCSS
{
class CCssCalculator_Private
class CStyleStorage
{
unsigned short int m_nDpi;
unsigned short int m_nCountNodes;
public:
CStyleStorage();
~CStyleStorage();
std::list<std::wstring> m_arFiles;
void Clear();
std::map<std::wstring, CElement*> m_mData;
void AddStyles(const std::string& sStyle);
void AddStyles(const std::wstring& wsStyle);
void AddStylesFromFile(const std::wstring& wsFileName);
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFileName);
#ifdef CSS_CALCULATOR_WITH_XHTML
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
void ClearPageData();
#endif
const CElement* FindElement(const std::wstring& wsSelector);
private:
typedef struct
{
std::wstring m_wsStyleFilepath;
std::map<std::wstring, CElement*> m_mStyleData;
} TStyleFileData;
std::set<std::wstring> m_arEmptyStyleFiles;
std::set<std::wstring> m_arAllowedStyleFiles;
std::vector<TStyleFileData*> m_arStyleFiles;
std::map<std::wstring, CElement*> m_mEmbeddedStyleData;
#ifdef CSS_CALCULATOR_WITH_XHTML
typedef struct
{
std::vector<std::wstring> m_wsNames;
@ -32,27 +58,14 @@ namespace NSCSS
} TPageData;
std::vector<TPageData> m_arPageDatas;
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
std::map<std::wstring, std::wstring> GetPageData(const std::wstring& wsPageName);
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
std::vector<CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
#endif
private:
void AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData);
std::wstring m_sEncoding;
void GetStylesheet(const KatanaStylesheet* oStylesheet, std::map<std::wstring, CElement*>& mStyleData);
void GetRule(const KatanaRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
void AddPageData(const std::wstring& wsPageName, const std::wstring& wsStyles);
void GetStylesheet(const KatanaStylesheet* oStylesheet);
void GetRule(const KatanaRule* oRule);
void GetStyleRule(const KatanaStyleRule* oRule);
void GetStyleRule(const KatanaStyleRule* oRule, std::map<std::wstring, CElement*>& mStyleData);
std::wstring GetValueList(const KatanaArray* oValues);
@ -62,8 +75,28 @@ namespace NSCSS
std::map<std::wstring, std::wstring> GetDeclarationList(const KatanaArray* oDeclarations) const;
std::pair<std::wstring, std::wstring> GetDeclaration(const KatanaDeclaration* oDecl) const;
void GetOutputData(KatanaOutput* oOutput);
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData);
};
class CCssCalculator_Private
{
unsigned short int m_nDpi;
unsigned short int m_nCountNodes;
CStyleStorage m_oStyleStorage;
#ifdef CSS_CALCULATOR_WITH_XHTML
std::map<std::vector<CNode>, CCompiledStyle> m_mUsedStyles;
void SetPageData(NSProperties::CPage& oPage, const std::map<std::wstring, std::wstring>& mData, unsigned int unLevel, bool bHardMode = false);
std::map<std::wstring, std::wstring> GetPageData(const std::wstring &wsPageName);
#endif
void FindPrevAndKindElements(const CElement* pElement, const std::vector<std::wstring>& arNextNodes, std::vector<const CElement*>& arFindedElements, const std::wstring& wsName, const std::vector<std::wstring>& arClasses = {});
std::wstring m_sEncoding;
public:
CCssCalculator_Private();
~CCssCalculator_Private();
@ -74,8 +107,13 @@ namespace NSCSS
std::wstring CalculateStyleId(const CNode& oNode);
bool CalculatePageStyle(NSProperties::CPage& oPageData, const std::vector<CNode> &arSelectors);
void ClearPageData();
#endif
std::vector<std::wstring> CalculateAllNodes(const std::vector<CNode>& arSelectors);
std::vector<const CElement*> FindElements(std::vector<std::wstring>& arNodes, std::vector<std::wstring>& arNextNodes);
void AddStyles(const std::string& sStyle);
void AddStyles(const std::wstring& wsStyle);
void AddStylesFromFile(const std::wstring& wsFileName);
@ -85,10 +123,12 @@ namespace NSCSS
std::wstring GetEncoding() const;
unsigned short int GetDpi() const;
const std::map<std::wstring, CElement*>* GetData() const;
void ClearEmbeddedStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFilePath);
void Clear();
};
inline bool IsTableElement(const std::wstring& wsNameTag);
}
#endif // CCSSCALCULATOR_PRIVATE_H

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

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

@ -68,6 +68,7 @@ public:
bool isOOXFormatFile(const std::wstring& fileName, bool unpacked = false);
bool isOpenOfficeFormatFile(const std::wstring& fileName, std::wstring& documentID);
bool isOnlyOfficeFormatFile(const std::wstring& fileName);
bool isMacFormatFile(const std::wstring& fileName);
bool isDocFormatFile(const std::wstring& fileName);
bool isXlsFormatFile(const std::wstring& fileName);
@ -80,6 +81,7 @@ public:
bool isMS_MITCRYPTOFormatFile(POLE::Storage* storage, std::wstring& documentID);
bool isVbaProjectFile(POLE::Storage* storage);
bool isMS_OFFCRYPTOFormatFile(const std::wstring& fileName, std::wstring& documentID);
bool isHwpFile(POLE::Storage* storage);
bool iXmlFile(const std::wstring& fileName);

View File

@ -451,6 +451,20 @@ bool COfficeFileFormatChecker::isVbaProjectFile(POLE::Storage *storage)
}
return true;
}
bool COfficeFileFormatChecker::isHwpFile(POLE::Storage* storage)
{
if (storage == NULL)
return false;
unsigned char buffer[10];
POLE::Stream stream(storage, L"BodyText/Section0");
if (stream.read(buffer, 10) < 1)
{
return false;
}
return true;
}
bool COfficeFileFormatChecker::isXlsFormatFile(POLE::Storage *storage)
{
if (storage == NULL)
@ -721,6 +735,11 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName)
nFileType = AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT;
return true;
}
else if (isHwpFile(&storage))
{
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_HWP;
return true;
}
}
NSFile::CFileBinary file;
if (!file.OpenFile(fileName))
@ -767,6 +786,13 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName)
bufferDetect = NULL;
return true;
}
else if (isMacFormatFile(fileName))
{
if (bufferDetect)
delete[] bufferDetect;
bufferDetect = NULL;
return true;
}
}
//-----------------------------------------------------------------------------------------------
@ -905,6 +931,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;
@ -1129,6 +1159,58 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa
}
return false;
}
bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName)
{
COfficeUtils OfficeUtils(NULL);
ULONG nBufferSize = 0;
BYTE* pBuffer = NULL;
HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES;
delete[] pBuffer;
pBuffer = NULL;
hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Slide.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
delete[] pBuffer;
pBuffer = NULL;
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
return true;
}
hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Tables/DataList.iwa", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
delete[] pBuffer;
pBuffer = NULL;
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
return true;
}
std::wstring::size_type nExtPos = fileName.rfind(L'.');
std::wstring sExt = L"unknown";
if (nExtPos != std::wstring::npos)
sExt = fileName.substr(nExtPos);
std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower);
if (0 == sExt.compare(L".pages"))
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES;
else if (0 == sExt.compare(L".numbers"))
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS;
else if (0 == sExt.compare(L".key"))
nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY;
return true;
}
return false;
}
bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileName, std::wstring &documentID)
{
documentID.clear();

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

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

View File

@ -38,6 +38,9 @@
#include "../xml/include/xmlutils.h"
#include "../fontengine/TextHyphen.h"
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
namespace NSDoctRenderer
{
class CAdditionalData
@ -188,7 +191,7 @@ namespace NSDoctRenderer
m_strSdkPath = oNode.ReadNodeText(L"sdkjs");
if (!m_strSdkPath.empty())
{
if (!NSDirectory::Exists(m_strSdkPath))
if (0 == m_strSdkPath.find(L"./") || !NSDirectory::Exists(m_strSdkPath))
m_strSdkPath = sConfigDir + m_strSdkPath;
}
@ -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

@ -47,14 +47,6 @@ namespace NSDoctRenderer
RELEASEOBJECT(m_pInternal);
}
int CDocBuilder::OpenFile(const wchar_t* path, const wchar_t* params)
{
m_pInternal->m_nFileType = -1;
if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder))
NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder);
return m_pInternal->OpenFile(path, params);
}
int CDocBuilder::SaveFile(const int& type, const wchar_t* path, const wchar_t* params)
{
return m_pInternal->SaveFile(type, path, params);

View File

@ -526,6 +526,7 @@ namespace NSDoctRenderer
CDocBuilder_Private* m_pInternal;
friend class CBuilderDocumentEmbed;
friend class CBuilderEmbed;
};
/**

View File

@ -82,7 +82,7 @@ CV8RealTimeWorker::~CV8RealTimeWorker()
m_context->Dispose();
}
bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRenderer::CDocBuilderValue* retValue)
bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRenderer::CDocBuilderValue* retValue, const bool& isEnterContext)
{
LOGGER_SPEED_START();
@ -92,14 +92,20 @@ bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRender
std::string commandA = U_TO_UTF8(command);
//commandA = "Api." + commandA;
CJSContextScope scope(m_context);
if (isEnterContext)
m_context->Enter();
JSSmart<CJSTryCatch> try_catch = m_context->GetExceptions();
LOGGER_SPEED_LAP("compile_command");
JSSmart<CJSValue> retNativeVal = m_context->runScript(commandA, try_catch);
if(try_catch->Check())
{
if (isEnterContext)
m_context->Exit();
return false;
}
if (retValue)
{
@ -110,6 +116,9 @@ bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRender
LOGGER_SPEED_LAP("run_command");
if (isEnterContext)
m_context->Exit();
return true;
}
@ -240,6 +249,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;
}
@ -336,7 +353,17 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
return !bIsBreak;
}
bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams)
bool CV8RealTimeWorker::NewSimpleJSInstance()
{
return InitVariables();
}
bool CV8RealTimeWorker::IsSimpleJSInstance()
{
return (-1 == m_nFileType);
}
bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams, const bool& isEnterContext)
{
NSDoctRenderer::DoctRendererFormat::FormatFile _formatDst = NSDoctRenderer::DoctRendererFormat::DOCT;
if (type & AVS_OFFICESTUDIO_FILE_PRESENTATION)
@ -362,7 +389,9 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
}
}
CJSContextScope scope(m_context);
if (isEnterContext)
m_context->Enter();
JSSmart<CJSTryCatch> try_catch = m_context->GetExceptions();
NSNativeControl::CNativeControl* pNative = NULL;
@ -391,7 +420,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
bIsSilentMode = true;
if (bIsSilentMode)
this->ExecuteCommand(L"Api.asc_SetSilentMode(false);");
this->ExecuteCommand(L"Api.asc_SetSilentMode(false);", NULL, isEnterContext);
std::wstring strError;
bool bIsError = Doct_renderer_SaveFile_ForBuilder(_formatDst,
@ -403,7 +432,10 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
sJsonParams);
if (bIsSilentMode)
this->ExecuteCommand(L"Api.asc_SetSilentMode(true);");
this->ExecuteCommand(L"Api.asc_SetSilentMode(true);", NULL, isEnterContext);
if (isEnterContext)
m_context->Exit();
return bIsError;
}
@ -1231,8 +1263,29 @@ namespace NSDoctRenderer
nCount = nIndex;
}
int CDocBuilder::OpenFile(const wchar_t* path, const wchar_t* params)
{
if (m_pInternal->m_nFileType != -1 && m_pInternal->m_bIsOpenedFromSimpleJS)
{
m_pInternal->m_bIsOpenedFromSimpleJS = false;
return true;
}
m_pInternal->m_nFileType = -1;
if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder))
NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder);
return m_pInternal->OpenFile(path, params);
}
bool CDocBuilder::CreateFile(const int& type)
{
if (m_pInternal->m_nFileType != -1 && m_pInternal->m_bIsOpenedFromSimpleJS)
{
m_pInternal->m_bIsOpenedFromSimpleJS = false;
return true;
}
m_pInternal->m_nFileType = -1;
if (!NSDirectory::Exists(m_pInternal->m_sTmpFolder))
NSDirectory::CreateDirectory(m_pInternal->m_sTmpFolder);
@ -1391,7 +1444,7 @@ namespace NSDoctRenderer
if (!sJsCommands.empty())
{
std::wstring sUnicodeCommand = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sJsCommands.c_str(), (LONG)sJsCommands.length());
bIsNoError = this->ExecuteCommand(sUnicodeCommand.c_str());
bIsNoError = this->m_pInternal->ExecuteCommand(sUnicodeCommand.c_str(), NULL, bIsBuilderJSCloseFile);
sJsCommands = "";
if (!bIsNoError)
return false;
@ -1413,6 +1466,10 @@ namespace NSDoctRenderer
if (0 == _builder_params[nCheckParam].find(L"jsValue(") && _builder_params[nCheckParam].length() > 9)
{
std::wstring sParam = _builder_params[nCheckParam].substr(8, _builder_params[nCheckParam].length() - 9);
if (NULL == m_pInternal->m_pWorker)
m_pInternal->CheckWorker();
_builder_params[nCheckParam] = m_pInternal->m_pWorker->GetJSVariable(sParam);
}
}
@ -1478,7 +1535,7 @@ namespace NSDoctRenderer
{
// Такого быть не должно!!! Так как результат никуда не сохранится. пустое действие.
std::wstring sUnicodeCommand = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sJsCommands.c_str(), (LONG)sJsCommands.length());
bool bIsNoError = this->ExecuteCommand(sUnicodeCommand.c_str());
bool bIsNoError = this->m_pInternal->ExecuteCommand(sUnicodeCommand.c_str(), NULL, true);
sJsCommands = "";
if (!bIsNoError)
return false;

View File

@ -63,6 +63,8 @@
#include "../common/ProcessEnv.h"
#include "docbuilder_addon.h"
#ifdef CreateFile
#undef CreateFile
#endif
@ -422,6 +424,7 @@ public:
int m_nFileType;
std::string m_sUtf8ArgumentJSON;
std::string m_sGlobalVariable;
std::string m_sJSCodeStart;
CJSContextData m_oContextData;
@ -434,14 +437,17 @@ public:
static void _LOGGING_ERROR_(const std::wstring& strType, const std::wstring& strError);
bool ExecuteCommand(const std::wstring& command, NSDoctRenderer::CDocBuilderValue* retValue = NULL);
bool ExecuteCommand(const std::wstring& command, NSDoctRenderer::CDocBuilderValue* retValue = NULL, const bool& isEnterContext = true);
std::string GetGlobalVariable();
std::wstring GetJSVariable(std::wstring sParam);
bool OpenFile(const std::wstring& sBasePath, const std::wstring& path, const NSDoctRenderer::DoctRendererEditorType& editorType, NSDoctRenderer::CDoctRendererConfig* config, CV8Params* pParams = NULL);
bool SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams = L"");
bool SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams = L"", const bool& isEnterContext = true);
bool InitVariables();
bool NewSimpleJSInstance();
bool IsSimpleJSInstance();
};
namespace NSDoctRenderer
@ -455,7 +461,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;
@ -474,11 +481,13 @@ namespace NSDoctRenderer
NSDoctRenderer::CDocBuilder* m_pParent;
bool m_bIsOpenedFromSimpleJS;
static std::wstring m_sExternalDirectory;
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""), m_bIsOpenedFromSimpleJS(false)
{
}
@ -637,10 +646,14 @@ namespace NSDoctRenderer
{
NSDirectory::CreateDirectory(m_sFileDir + L"/media");
NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
}
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
if (m_pWorker && m_pWorker->IsSimpleJSInstance() && !m_bIsOpenedFromSimpleJS)
{
RELEASEOBJECT(m_pWorker);
CheckWorker();
}
return bRet;
}
return bRet;
#else
@ -931,8 +944,11 @@ namespace NSDoctRenderer
if (0 == nReturnCode)
{
if (m_bJavascriptBeforeEditor)
CheckWorkerAfterOpen();
if (m_pWorker && m_pWorker->IsSimpleJSInstance() && !m_bIsOpenedFromSimpleJS)
{
RELEASEOBJECT(m_pWorker);
CheckWorker();
}
return 0;
}
@ -981,10 +997,16 @@ namespace NSDoctRenderer
return _path;
}
int SaveFile(const int& type, const std::wstring& path, const wchar_t* params = NULL)
int SaveFile(const int& type, const std::wstring& path, const wchar_t* params = NULL, const bool& isEnterContext = true)
{
Init();
CDocBuilderAddon oSaveAddon(m_sX2tPath);
int nPreSaveError = oSaveAddon.GetX2tPreSaveError();
if (0 != nPreSaveError)
return nPreSaveError;
if (-1 == m_nFileType)
{
CV8RealTimeWorker::_LOGGING_ERROR_(L"error (save)", L"file not opened!");
@ -1023,7 +1045,7 @@ namespace NSDoctRenderer
}
}
this->m_pWorker->SaveFileWithChanges(type, m_sFileDir + L"/Editor2.bin", sJsonParams);
this->m_pWorker->SaveFileWithChanges(type, m_sFileDir + L"/Editor2.bin", sJsonParams, isEnterContext);
sFileBin = L"/Editor2.bin";
}
@ -1068,6 +1090,8 @@ namespace NSDoctRenderer
if (!sOptions.empty())
oBuilder.WriteString(UTF8_TO_U(sOptions));
oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon());
oBuilder.WriteString(L"</TaskQueueDataConvert>");
std::wstring sXmlConvert = oBuilder.GetData();
@ -1220,62 +1244,75 @@ namespace NSDoctRenderer
{
if (NULL == m_pWorker)
{
m_pWorker = new CV8RealTimeWorker(m_pParent, GetEditorType(), this);
NSDoctRenderer::DoctRendererEditorType editorType = GetEditorType();
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);
return CheckWorkerAfterOpen();
m_pWorker->m_nFileType = m_nFileType;
if (-1 != m_nFileType)
m_sCommandsBeforeContextCreated = L"";
else
{
m_pWorker->NewSimpleJSInstance();
return true;
}
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);
return SaveFile(nType, path, params);
}
bool ExecuteCommand(const std::wstring& command, CDocBuilderValue* retValue = NULL)
bool ExecuteCommand(const std::wstring& command, CDocBuilderValue* retValue = NULL, const bool& forceExecute = false)
{
if (command.length() < 7 && !retValue) // minimum command (!!!)
return true;
if (m_nFileType == -1 && !forceExecute)
{
m_sCommandsBeforeContextCreated += command;
return true;
}
Init();
bool bRes = CheckWorker();
if (CheckWorker())
{
bool bIsOpenedFromSimpleJSOld = m_bIsOpenedFromSimpleJS;
bool bResult = m_pWorker->ExecuteCommand(command, retValue);
if (!bResult && !bIsOpenedFromSimpleJSOld && m_bIsOpenedFromSimpleJS)
{
RELEASEOBJECT(m_pWorker);
CheckWorker();
return m_pWorker->ExecuteCommand(command, retValue);
}
else
{
return bResult;
}
}
if (!bRes && m_pWorker && m_bJavascriptBeforeEditor)
m_pWorker->InitVariables();
return m_pWorker->ExecuteCommand(command, retValue);
return false;
}
CDocBuilderContext GetContext(bool enterContext)
{
CDocBuilderContext ctx;
CheckWorker();
if (!CheckWorker())
return ctx;
ctx.m_internal->m_context = m_pWorker->m_context;
ctx.m_internal->m_context_data = &m_pWorker->m_oContextData;

View File

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

View File

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

View File

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

View File

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

View File

@ -160,16 +160,30 @@ void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage)
JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm)
{
NSNativeControl::CNativeControl* pControl = NULL;
if (!Native->isNull())
{
pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject();
JSSmart<CJSObject> pNativeObject = Native->toObject();
CJSEmbedObject* pNativeEmbedObject = pNativeObject->getNative();
if (m_pInternal->m_pAppImage)
delete m_pInternal->m_pAppImage;
m_pInternal->m_pAppImage = new CGraphicsAppImage();
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
if (pNativeEmbedObject)
{
NSNativeControl::CNativeControl* pControl = (NSNativeControl::CNativeControl*)pNativeEmbedObject->getObject();
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
}
else
{
JSSmart<CJSValue> checkResources = pNativeObject->get("isResourcesObject");
if (checkResources->isBool() && true == checkResources->toBool())
{
m_pInternal->m_pAppImage->SetFontsDirectory(pNativeObject->get("fontsDirectory")->toStringW());
m_pInternal->m_pAppImage->SetImagesDirectory(pNativeObject->get("imagesDirectory")->toStringW());
}
}
}
m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble());

View File

@ -8,7 +8,22 @@ JSSmart<CJSValue> CBuilderEmbed::OpenFile(JSSmart<CJSValue> sPath, JSSmart<CJSVa
{
std::wstring Path = sPath->toStringW();
std::wstring Params = sParams->toStringW();
// Since we now use snapshots, and we can't always determine which editor is needed
// (since the code may be BEFORE opening the file). And if the opening came from
// builderJS.OpenFile - in this case we skip reopening.
NSDoctRenderer::CDocBuilder_Private* pPrivate = GetPrivate();
if (pPrivate->m_pWorker->IsSimpleJSInstance())
pPrivate->m_bIsOpenedFromSimpleJS = true;
int ret = m_pBuilder->OpenFile(Path.c_str(), Params.c_str());
if (pPrivate->m_pWorker->IsSimpleJSInstance())
{
JSSmart<CJSContext> current = CJSContext::GetCurrent();
current->runScript("throw 0;");
}
return CJSContext::createInt(ret);
}
@ -20,7 +35,21 @@ JSSmart<CJSValue> CBuilderEmbed::CreateFile(JSSmart<CJSValue> type)
else
nFormat = type->toInt32();
// Since we now use snapshots, and we can't always determine which editor is needed
// (since the code may be BEFORE opening the file). And if the opening came from
// builderJS.OpenFile - in this case we skip reopening.
NSDoctRenderer::CDocBuilder_Private* pPrivate = GetPrivate();
if (pPrivate->m_pWorker->IsSimpleJSInstance())
pPrivate->m_bIsOpenedFromSimpleJS = true;
bool ret = m_pBuilder->CreateFile(nFormat);
if (pPrivate->m_pWorker->IsSimpleJSInstance())
{
JSSmart<CJSContext> current = CJSContext::GetCurrent();
current->runScript("throw 0;");
}
return CJSContext::createBool(ret);
}
@ -41,7 +70,7 @@ JSSmart<CJSValue> CBuilderEmbed::SaveFile(JSSmart<CJSValue> type, JSSmart<CJSVal
std::wstring sPath = path->toStringW();
std::wstring sParams = params->toStringW();
int ret = m_pBuilder->SaveFile(nFormat, sPath.c_str(), sParams.empty() ? NULL : sParams.c_str());
int ret = GetPrivate()->SaveFile(nFormat, sPath.c_str(), sParams.empty() ? NULL : sParams.c_str(), false);
return CJSContext::createInt(ret);
}

View File

@ -50,6 +50,7 @@ public:
~CBuilderEmbed() { if(m_pBuilder) RELEASEOBJECT(m_pBuilder); }
virtual void* getObject() { return (void*)m_pBuilder; }
NSDoctRenderer::CDocBuilder_Private* GetPrivate() { return m_pBuilder->GetPrivate(); }
public:
JSSmart<CJSValue> OpenFile(JSSmart<CJSValue> sPath, JSSmart<CJSValue> sParams);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -351,11 +351,17 @@ CFontManager::~CFontManager()
RELEASEINTERFACE(m_pFont);
RELEASEOBJECT(m_pOwnerCache);
}
void CFontManager::SetOwnerCache(NSFonts::IFontsCache* pCache)
{
m_pOwnerCache = (CFontsCache*)pCache;
}
void CFontManager::ClearOwnerCache()
{
m_pOwnerCache->Clear();
}
NSFonts::IFontsCache* CFontManager::GetCache() { return m_pOwnerCache; }
NSFonts::IApplicationFonts* CFontManager::GetApplication() { return m_pApplication; }
NSFonts::IFontFile* CFontManager::GetFile() { return m_pFont; }

View File

@ -132,6 +132,7 @@ public:
virtual void Initialize();
virtual void SetOwnerCache(NSFonts::IFontsCache* pCache);
virtual void ClearOwnerCache();
virtual NSFonts::IFontsCache* GetCache();
virtual NSFonts::IApplicationFonts* GetApplication();

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",
@ -259,10 +260,13 @@
"folder": "../../../OfficeUtils/js",
"files": ["../src/ZipBuffer.cpp", "wasm/src/base.cpp", "../src/zlib_addon.c"]
},
{
"folder": "../../",
"files": ["graphics/Image.cpp", "raster/BgraFrame.cpp", "raster/ImageFileFormatChecker.cpp"]
"files": ["graphics/Image.cpp", "raster/BgraFrame.cpp", "raster/ImageFileFormatChecker.cpp", "graphics/Matrix.cpp"]
},
{
"folder": "../../agg-2.4/src/",
"files": ["agg_trans_affine.cpp"]
},
{
"folder": "../../raster/",

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

@ -33,479 +33,647 @@
namespace Aggplus
{
////////////////////////////////////////////////////////////////////////////////
CBrush::CBrush(BrushType bType) : m_bType(bType)
CBrush::CBrush()
{
}
CBrush::CBrush(const BrushType& type)
: m_bType(type)
{
}
CBrush::~CBrush()
{
}
BrushType CBrush::GetType() const
{
return m_bType;
BrushType CBrush::GetType() const
{
return m_bType;
}
////////////////////////////////////////////////////////////////////////////////
CBrushSolid::CBrushSolid(CColor dwColor) : CBrush(BrushTypeSolidColor), m_dwColor(dwColor)
CBrushSolid::CBrushSolid() : CBrush()
{
}
CBrushSolid::~CBrushSolid()
CBrushSolid::CBrushSolid(CColor color)
: CBrush(),
m_dwColor(color)
{
}
CBrush* CBrushSolid::Clone() const
{
return new CBrushSolid(m_dwColor);
CBrushSolid::CBrushSolid(const CBrushSolid& other) : CBrush()
{
*this = other;
}
void CBrushSolid::GetColor(CColor* color) const { *color = m_dwColor; }
void CBrushSolid::SetColor(const CColor &color) { m_dwColor = color; }
////////////////////////////////////////////////////////////////////////////////
CBrushHatch::CBrushHatch() : CBrush(BrushTypeHatchFill)
CBrushSolid::~CBrushSolid()
{
}
CBrushHatch::~CBrushHatch()
void CBrushSolid::GetColor(CColor* color) const
{
*color = m_dwColor;
}
void CBrushSolid::SetColor(const CColor &color)
{
m_dwColor = color;
}
CBrushSolid& CBrushSolid::operator=(const CBrushSolid& other)
{
if (this == &other)
return *this;
m_dwColor = other.m_dwColor;
return *this;
}
CBrushHatch::CBrushHatch()
: CBrush(BrushTypeHatchFill)
{
}
CBrush* CBrushHatch::Clone() const
{
CBrushHatch* clone = new CBrushHatch();
clone->m_name = m_name;
clone->m_dwColor1 = m_dwColor1;
clone->m_dwColor2 = m_dwColor2;
return clone;
}
////////////////////////////////////////////////////////////////////////////////
CBrushLinearGradient::CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 )
CBrushHatch::CBrushHatch(const CBrushHatch& other)
: CBrush(BrushTypeHatchFill)
{
*this = other;
}
CBrushHatch::CBrushHatch(CBrushHatch&& other) noexcept
: CBrush(BrushTypeHatchFill)
{
*this = std::move(other);
}
CBrushHatch::~CBrushHatch()
{
}
void CBrushHatch::SetName(const std::wstring& name)
{
m_wsName = name;
}
std::wstring CBrushHatch::GetName() const
{
return m_wsName;
}
void CBrushHatch::SetColor1(const CColor& color)
{
m_dwColor1 = color;
}
CColor CBrushHatch::GetColor1() const
{
return m_dwColor1;
}
void CBrushHatch::SetColor2(const CColor& color)
{
m_dwColor2 = color;
}
CColor CBrushHatch::GetColor2() const
{
return m_dwColor2;
}
void CBrushHatch::SetBounds(const CDoubleRect& rect)
{
m_oBounds = rect;
}
CDoubleRect& CBrushHatch::GetBounds()
{
return m_oBounds;
}
CBrushHatch& CBrushHatch::operator=(const CBrushHatch& other)
{
if (this == &other)
return *this;
m_wsName = other.m_wsName;
m_dwColor1 = other.m_dwColor1;
m_dwColor2 = other.m_dwColor2;
return *this;
}
CBrushHatch& CBrushHatch::operator=(CBrushHatch&& other) noexcept
{
if (this == &other)
return *this;
m_wsName = std::move(other.m_wsName);
m_dwColor1 = other.m_dwColor1;
m_dwColor2 = other.m_dwColor2;
return *this;
}
CBrushLinearGradient::CBrushLinearGradient()
: CBrush(BrushTypeLinearGradient)
{
m_points[0] = p1;
m_points[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
}
CBrushLinearGradient::CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 )
CBrushLinearGradient::CBrushLinearGradient(const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)p1.X;
m_points[0].Y = (float)p1.Y;
m_points[1].X = (float)p2.X;
m_points[1].Y = (float)p2.Y;
m_arPoints[0] = p1;
m_arPoints[1] = p2;
m_colors[0] = c1;
m_colors[1] = c2;
m_angle = 0;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = FALSE;
m_bRectable = FALSE;
m_bRelativeCoords = FALSE;
m_arColors[0] = c1;
m_arColors[1] = c2;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
CBrushLinearGradient::CBrushLinearGradient(const Point& p1, const Point& p2, const CColor& c1, const CColor& c2)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_arPoints[0].X = static_cast<float>(p1.X);
m_arPoints[0].Y = static_cast<float>(p1.Y);
m_arPoints[1].X = static_cast<float>(p2.X);
m_arPoints[1].Y = static_cast<float>(p2.Y);
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
}
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
CBrushLinearGradient::CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable)
: CBrush(BrushTypeLinearGradient)
{
m_arPoints[0].X = rect.GetLeft();
m_arPoints[0].Y = rect.GetTop();
m_arPoints[1].X = rect.GetRight();
m_arPoints[1].Y = rect.GetBottom();
m_arColors[0] = c1;
m_arColors[1] = c2;
m_fAngle = angle;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable )
CBrushLinearGradient::CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (float)rect.GetLeft();
m_points[0].Y = (float)rect.GetTop();
m_points[1].X = (float)rect.GetRight();
m_points[1].Y = (float)rect.GetBottom();
m_arPoints[0].X = static_cast<float>(rect.GetLeft());
m_arPoints[0].Y = static_cast<float>(rect.GetTop());
m_arPoints[1].X = static_cast<float>(rect.GetRight());
m_arPoints[1].Y = static_cast<float>(rect.GetBottom());
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_angle = angle;
m_wrap = Aggplus::WrapModeTile;
m_fAngle = angle;
m_bAngleScalable = isAngleScalable;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
CBrushLinearGradient::CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = rect.GetLeft();
m_points[0].Y = rect.GetTop();
m_points[1].X = rect.GetRight();
m_points[1].Y = rect.GetBottom();
m_arPoints[0].X = rect.GetLeft();
m_arPoints[0].Y = rect.GetTop();
m_arPoints[1].X = rect.GetRight();
m_arPoints[1].Y = rect.GetBottom();
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
m_fAngle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
m_fAngle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
m_fAngle = 45;
break;
default:
m_angle = 315;
m_fAngle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bAngleScalable = true;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode )
CBrushLinearGradient::CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode)
: CBrush(BrushTypeLinearGradient)
{
m_points[0].X = (REAL)rect.GetLeft();
m_points[0].Y = (REAL)rect.GetTop();
m_points[1].X = (REAL)rect.GetRight();
m_points[1].Y = (REAL)rect.GetBottom();
m_arPoints[0].X = static_cast<float>(rect.GetLeft());
m_arPoints[0].Y = static_cast<float>(rect.GetTop());
m_arPoints[1].X = static_cast<float>(rect.GetRight());
m_arPoints[1].Y = static_cast<float>(rect.GetBottom());
switch( mode )
{
case LinearGradientModeHorizontal:
m_angle = 0;
m_fAngle = 0;
break;
case LinearGradientModeVertical:
m_angle = 90;
m_fAngle = 90;
break;
case LinearGradientModeForwardDiagonal:
m_angle = 45;
m_fAngle = 45;
break;
default:
m_angle = 315;
m_fAngle = 315;
}
m_colors[0] = c1;
m_colors[1] = c2;
m_arColors[0] = c1;
m_arColors[1] = c2;
m_wrap = Aggplus::WrapModeTile;
m_bAngleScalable = TRUE;
m_bRectable = TRUE;
m_bRelativeCoords = FALSE;
m_bAngleScalable = true;
m_bRectable = true;
}
CBrushLinearGradient::CBrushLinearGradient( const CBrushLinearGradient& out )
: CBrush(out.m_bType)
CBrushLinearGradient::CBrushLinearGradient(const CBrushLinearGradient& other)
: CBrush(other.m_bType)
{
m_colors[0] = out.m_colors[0];
m_colors[1] = out.m_colors[1];
m_points[0] = out.m_points[0];
m_points[1] = out.m_points[1];
m_subcolors = out.m_subcolors;
m_matrix = out.m_matrix;
m_angle = out.m_angle;
m_wrap = out.m_wrap;
m_bAngleScalable = out.m_bAngleScalable;
m_bRectable = out.m_bRectable;
m_bRelativeCoords = out.m_bRelativeCoords;
*this = other;
}
Status CBrushLinearGradient::GetLinearColors( CColor* colors ) const
CBrushLinearGradient::CBrushLinearGradient(CBrushLinearGradient&& other) noexcept
{
if( !colors )
*this = std::move(other);
}
CBrushLinearGradient::~CBrushLinearGradient()
{
}
Status CBrushLinearGradient::GetLinearColors(CColor* colors) const
{
if(!colors)
return InvalidParameter;
colors[0] = m_colors[0];
colors[1] = m_colors[1];
colors[0] = m_arColors[0];
colors[1] = m_arColors[1];
return Ok;
}
Status CBrushLinearGradient::GetRectangle( Rect *rect ) const
Status CBrushLinearGradient::GetRectangle(Rect *rect) const
{
if( !rect )
if(!rect)
return InvalidParameter;
rect->X = (int)( m_points[0].X );
rect->Y = (int)( m_points[0].Y );
rect->Width = (int)( m_points[1].X ) - rect->X;
rect->Height = (int)( m_points[1].Y ) - rect->Y;
rect->X = static_cast<int>((m_arPoints[0].X));
rect->Y = static_cast<int>((m_arPoints[0].Y));
rect->Width = static_cast<int>((m_arPoints[1].X) - rect->X);
rect->Height = static_cast<int>((m_arPoints[1].Y) - rect->Y);
return Ok;
}
Status CBrushLinearGradient::GetRectangle(RectF *rect) const
{
if(!rect)
return InvalidParameter;
rect->X = m_arPoints[0].X;
rect->Y = m_arPoints[0].Y;
rect->Width = m_arPoints[1].X - rect->X;
rect->Height = m_arPoints[1].Y - rect->Y;
return Ok;
}
Status CBrushLinearGradient::GetRectangle( RectF *rect ) const
Status CBrushLinearGradient::GetTransform(CMatrix* matrix) const
{
if( !rect )
if(!matrix)
return InvalidParameter;
rect->X = m_points[0].X;
rect->Y = m_points[0].Y;
rect->Width = m_points[1].X - rect->X;
rect->Height = m_points[1].Y - rect->Y;
*matrix = m_Matrix;
return Ok;
}
Status CBrushLinearGradient::GetTransform( CMatrix* matrix ) const
Status CBrushLinearGradient::MultiplyTransform(const CMatrix *matrix, MatrixOrder order)
{
if( !matrix )
return InvalidParameter;
*matrix = m_matrix;
return Ok;
}
Status CBrushLinearGradient::MultiplyTransform( const CMatrix *matrix, MatrixOrder order)
{
if( !matrix )
return InvalidParameter;
m_matrix.Multiply( matrix, order );
m_Matrix.Multiply(matrix, order);
return Ok;
}
Status CBrushLinearGradient::ResetTransform()
{
m_matrix.Reset();
m_Matrix.Reset();
return Ok;
}
Status CBrushLinearGradient::RotateTransform( REAL angle, MatrixOrder order )
Status CBrushLinearGradient::RotateTransform(float angle, MatrixOrder order)
{
m_matrix.Rotate( angle, order );
m_Matrix.Rotate(angle, order);
return Ok;
}
Status CBrushLinearGradient::ScaleTransform( REAL sx, REAL sy, MatrixOrder order )
Status CBrushLinearGradient::ScaleTransform(float sx, float sy, MatrixOrder order)
{
m_matrix.Scale( sx, sy, order );
m_Matrix.Scale(sx, sy, order);
return Ok;
}
void CBrushLinearGradient::SetWrapMode( WrapMode mode )
void CBrushLinearGradient::SetWrapMode(WrapMode mode)
{
m_wrap = mode;
m_eWrap = mode;
}
WrapMode CBrushLinearGradient::GetWrapMode() const
{
return m_wrap;
return m_eWrap;
}
CBrush* CBrushLinearGradient::Clone() const
Status CBrushLinearGradient::SetInterpolationColors(const CColor *presetColors, const float *blendPositions, int count)
{
return new CBrushLinearGradient( *this );
}
m_arSubColors.clear();
Status CBrushLinearGradient::SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count )
{
m_subcolors.clear();
if( count > 0 && presetColors && blendPositions )
if(count > 0 && presetColors && blendPositions)
{
m_subcolors.resize( count );
m_arSubColors.resize(count);
for( int i = 0; i < count; i++ )
for(int i = 0; i < count; i++)
{
m_subcolors[i].color = presetColors[i];
m_subcolors[i].position = blendPositions[i];
m_arSubColors[i].color = presetColors[i];
m_arSubColors[i].position = blendPositions[i];
}
}
return Ok;
}
Status CBrushLinearGradient::GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const
Status CBrushLinearGradient::GetInterpolationColors(CColor *presetColors, float *blendPositions, int count) const
{
if( count > 0 && count <= (INT)m_subcolors.size() && presetColors && blendPositions )
if( count > 0 && count <= (int)m_arSubColors.size() && presetColors && blendPositions )
{
for( int i = 0; i < count; i++ )
{
presetColors[i] = m_subcolors[i].color;
blendPositions[i] = m_subcolors[i].position;
presetColors[i] = m_arSubColors[i].color;
blendPositions[i] = m_arSubColors[i].position;
}
}
return Ok;
}
INT CBrushLinearGradient::GetInterpolationColorsCount() const
int CBrushLinearGradient::GetInterpolationColorsCount() const
{
return (INT)m_subcolors.size();
return static_cast<int>(m_arSubColors.size());
}
// additional methods
void CBrushLinearGradient::GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const
void CBrushLinearGradient::GetSubColor(int index, CColor* color, float* position) const
{
*pColor = m_subcolors[nIndex].color;
*pPosition = m_subcolors[nIndex].position;
*color = m_arSubColors[index].color;
*position = m_arSubColors[index].position;
}
void CBrushLinearGradient::SetRelativeCoords( INT bRelative )
void CBrushLinearGradient::SetRelativeCoords(bool relative)
{
m_bRelativeCoords = bRelative;
m_bRelativeCoords = relative;
}
INT CBrushLinearGradient::IsRelativeCoords() const
bool CBrushLinearGradient::IsRelativeCoords() const
{
return m_bRelativeCoords;
}
INT CBrushLinearGradient::IsAngleScalable() const
bool CBrushLinearGradient::IsAngleScalable() const
{
return m_bAngleScalable;
}
INT CBrushLinearGradient::IsRectable() const
bool CBrushLinearGradient::IsRectable() const
{
return m_bRectable;
}
float CBrushLinearGradient::GetAngle() const
{
return m_angle;
return m_fAngle;
}
////////////////////////////////////////////////////////////////////////////////
CBrushTexture::CBrushTexture() : CBrush(BrushTypeTextureFill)
void CBrushLinearGradient::SetBounds(const CDoubleRect& rect)
{
m_pImage = NULL;
m_bReleaseImage = FALSE;
Alpha = 255;
m_bUseBounds = false;
m_oBounds = rect;
}
CBrushTexture::CBrushTexture(const std::wstring& strName, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
CDoubleRect& CBrushLinearGradient::GetBounds()
{
m_pImage = new CImage(strName);
m_bReleaseImage = TRUE;
Alpha = 255;
m_bUseBounds = false;
return m_oBounds;
}
CBrushTexture::CBrushTexture(CImage *pImage, WrapMode wrapMode) : CBrush(BrushTypeTextureFill), m_wrapMode(wrapMode)
CBrushLinearGradient& CBrushLinearGradient::operator=(const CBrushLinearGradient& other)
{
m_pImage = pImage;
m_bReleaseImage = FALSE;
Alpha = 255;
m_bUseBounds = false;
if (this == &other)
return *this;
m_arColors[0] = other.m_arColors[0];
m_arColors[1] = other.m_arColors[1];
m_arPoints[0] = other.m_arPoints[0];
m_arPoints[1] = other.m_arPoints[1];
m_arSubColors = other.m_arSubColors;
m_Matrix = other.m_Matrix;
m_fAngle = other.m_fAngle;
m_eWrap = other.m_eWrap;
m_bAngleScalable = other.m_bAngleScalable;
m_bRectable = other.m_bRectable;
m_bRelativeCoords = other.m_bRelativeCoords;
return *this;
}
CBrushTexture::~CBrushTexture()
CBrushLinearGradient& CBrushLinearGradient::operator=(CBrushLinearGradient&& other) noexcept
{
if (this == &other)
return *this;
m_arColors[0] = other.m_arColors[0];
m_arColors[1] = other.m_arColors[1];
m_arPoints[0] = other.m_arPoints[0];
m_arPoints[1] = other.m_arPoints[1];
m_arSubColors = other.m_arSubColors;
m_Matrix = std::move(other.m_Matrix);
m_eWrap = other.m_eWrap;
m_bAngleScalable = other.m_bAngleScalable;
m_bRectable = other.m_bRectable;
m_bRelativeCoords = other.m_bRelativeCoords;
return *this;
}
CBrushTexture::CBrushTexture()
: CBrush(BrushTypeTextureFill)
{
}
CBrushTexture::CBrushTexture(const std::wstring& name, WrapMode mode)
: CBrush(BrushTypeTextureFill),
m_eWrapMode(mode)
{
m_pImage = new CImage(name);
m_bReleaseImage = true;
}
CBrushTexture::CBrushTexture(CImage *image, WrapMode mode)
: CBrush(BrushTypeTextureFill),
m_eWrapMode(mode)
{
m_pImage = image;
}
CBrushTexture::CBrushTexture(const CBrushTexture& other)
{
*this = other;
}
CBrushTexture::CBrushTexture(CBrushTexture&& other)
{
*this = std::move(other);
}
CBrushTexture::~CBrushTexture()
{
if (m_bReleaseImage)
{
RELEASEOBJECT(m_pImage);
}
}
CBrush* CBrushTexture::Clone() const
void CBrushTexture::TranslateTransform(double x, double y, MatrixOrder order)
{
CBrushTexture *pRet = new CBrushTexture(m_pImage, m_wrapMode);
if( pRet )
{
pRet->m_mtx = m_mtx;
}
return pRet;
m_Matrix.Translate(x, y, order);
}
void CBrushTexture::TranslateTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Translate(dX, dY, order);
}
void CBrushTexture::ScaleTransform(double dX, double dY, MatrixOrder order)
{
m_mtx.Scale(dX, dY, order);
}
void CBrushTexture::RotateTransform(double angle, MatrixOrder order)
{
m_mtx.Rotate(angle, order);
}
void CBrushTexture::GetTransform(CMatrix* matrix) const
{
*matrix = m_mtx;
}
void CBrushTexture::SetTransform(const CMatrix* matrix)
{
m_mtx = *matrix;
void CBrushTexture::ScaleTransform(double x, double y, MatrixOrder order)
{
m_Matrix.Scale(x, y, order);
}
void CBrushTexture::SetWrapMode(WrapMode wMode)
{
m_wrapMode = wMode;
void CBrushTexture::RotateTransform(double angle, MatrixOrder order)
{
m_Matrix.Rotate(angle, order);
}
WrapMode CBrushTexture::GetWrapMode() const
{
return(m_wrapMode);
void CBrushTexture::GetTransform(CMatrix* matrix) const
{
*matrix = m_Matrix;
}
void CBrushTexture::SetTransform(const CMatrix* matrix)
{
m_Matrix = *matrix;
}
void CBrushTexture::SetWrapMode(WrapMode mode)
{
m_eWrapMode = mode;
}
WrapMode CBrushTexture::GetWrapMode() const
{
return m_eWrapMode;
}
void CBrushTexture::SetBounds(const CDoubleRect& rect)
{
m_bUseBounds = true;
m_oBounds = rect;
}
CDoubleRect& CBrushTexture::GetBounds()
{
return m_oBounds;
}
void CBrushTexture::SetReleaseImage(bool isReleaseImage)
{
m_bReleaseImage = isReleaseImage;
}
bool CBrushTexture::IsReleaseImage() const
{
return m_bReleaseImage;
}
void CBrushTexture::SetAlpha(BYTE alpha)
{
m_Alpha = alpha;
}
BYTE CBrushTexture::GetAlpha() const
{
return m_Alpha;
}
void* CBrushTexture::GetData()
{
return m_pImage->m_pImgData;
}
void* CBrushTexture::PatternFinalize()
{
{
if (m_pImage->m_nStride < 0)
return m_pImage->m_pImgData - ((m_pImage->m_dwHeight - 1) * m_pImage->m_nStride);
return m_pImage->m_pImgData;
}
DWORD CBrushTexture::PatternGetWidth()
{
{
return m_pImage->m_dwWidth;
}
DWORD CBrushTexture::PatternGetHeight()
{
{
return m_pImage->m_dwHeight;
}
int CBrushTexture::PatternGetStride()
{
{
return m_pImage->m_nStride;
}
CBrushTexture& CBrushTexture::operator=(const CBrushTexture& other)
{
if (this == &other)
return *this;
m_pImage = new CImage(*other.m_pImage);
m_Matrix = other.m_Matrix;
m_eWrapMode = other.m_eWrapMode;
return *this;
}
CBrushTexture& CBrushTexture::operator=(CBrushTexture&& other)
{
if (this == &other)
return *this;
m_pImage = std::move(other.m_pImage);
m_Matrix = std::move(other.m_Matrix);
m_eWrapMode = other.m_eWrapMode;
return *this;
}
}

View File

@ -43,170 +43,256 @@
namespace Aggplus
{
class CBrush
{
friend class CGraphics;
protected:
CBrush(BrushType bType);
public:
virtual ~CBrush();
virtual CBrush* Clone() const = 0;
BrushType GetType() const;
public:
BrushType m_bType;
};
class CBrushSolid : public CBrush
{
public:
CBrushSolid(CColor dwColor);
virtual ~CBrushSolid();
virtual CBrush *Clone() const;
void GetColor(CColor* color) const;
void SetColor(const CColor &color);
protected:
CColor m_dwColor;
};
class CBrushHatch : public CBrush
{
public:
CBrushHatch();
virtual ~CBrushHatch();
virtual CBrush *Clone() const;
inline CDoubleRect& GetBounds() { return Bounds; }
public:
std::wstring m_name;
CColor m_dwColor1;
CColor m_dwColor2;
CDoubleRect Bounds;
};
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
public:
CBrushLinearGradient( const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const Point& p1, const Point& p2, const CColor& c1, const CColor& c2 );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, float angle, INT isAngleScalable );
CBrushLinearGradient( const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode );
CBrushLinearGradient( const CBrushLinearGradient& out );
Status GetLinearColors( CColor* colors ) const;
Status GetRectangle( Rect *rect ) const;
Status GetRectangle( RectF *rect ) const;
Status GetTransform( CMatrix* matrix ) const;
Status MultiplyTransform( const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend);
Status ResetTransform();
Status RotateTransform( REAL angle, MatrixOrder order = MatrixOrderPrepend );
Status ScaleTransform( REAL sx, REAL sy, MatrixOrder order = MatrixOrderPrepend );
void SetWrapMode( WrapMode mode );
WrapMode GetWrapMode() const;
virtual CBrush *Clone() const;
Status SetInterpolationColors( const CColor *presetColors, const REAL *blendPositions, INT count );
Status GetInterpolationColors( CColor *presetColors, REAL *blendPositions, INT count ) const;
INT GetInterpolationColorsCount() const;
// additional methods
void GetSubColor( int nIndex, CColor* pColor, float* pPosition ) const;
void SetRelativeCoords( INT bRelative );
INT IsRelativeCoords() const;
INT IsAngleScalable() const;
INT IsRectable() const;
float GetAngle() const;
inline void SetBounds(const CDoubleRect& oRect) { Bounds = oRect; }
inline CDoubleRect& GetBounds() { return Bounds; }
// info about gradient
NSStructures::GradientInfo m_oGradientInfo; // used in 60xx grad types
protected:
CColor m_colors[2];
PointF m_points[2];
struct TSubColor
/**
* @abstract CBrush
*
* Base class for brushes (by default a solid brush
* is created).
*/
class CBrush
{
CColor color;
float position;
friend class CGraphics;
protected:
CBrush();
CBrush(const BrushType& type);
public:
virtual ~CBrush();
BrushType GetType() const;
public:
BrushType m_bType = BrushTypeSolidColor;
};
std::vector<TSubColor> m_subcolors;
CMatrix m_matrix;
float m_angle; // угол поворота в градусах базовой линии p1 -> p2
/**
* @class CBrushSolid
*
* A single-color brush used to draw text, graphic paths,
* and fills with a single color.
*/
class CBrushSolid : public CBrush
{
public:
CBrushSolid();
CBrushSolid(CColor color);
virtual ~CBrushSolid();
CBrushSolid(const CBrushSolid& other);
CDoubleRect Bounds;
void GetColor(CColor* color) const;
void SetColor(const CColor &color);
Aggplus::WrapMode m_wrap;
CBrushSolid& operator=(const CBrushSolid& other);
protected:
CColor m_dwColor{};
};
INT m_bAngleScalable; // масштабировать угол поворота относительно заданных точек b = arctan( width / height * tan(angle) );
INT m_bRectable; // в качестве направляющей используется диагональ прямоугольника
INT m_bRelativeCoords; // координаты точек считаются относительно рисуемого примитива
};
/**
* @class CBrushHatch
*
* A two-color brush used to fill graphic paths using
* one of the hatch patterns
*/
class CBrushHatch : public CBrush
{
public:
CBrushHatch();
CBrushHatch(const CBrushHatch& other);
CBrushHatch(CBrushHatch&& other) noexcept;
virtual ~CBrushHatch();
class CBrushTexture : public CBrush
{
friend class CGraphics;
protected:
CBrushTexture();
void SetName(const std::wstring& name);
std::wstring GetName() const;
public:
CBrushTexture(const std::wstring& strName, WrapMode wrapMode = WrapModeTile);
CBrushTexture(CImage *pImage, WrapMode wrapMode = WrapModeTile);
virtual ~CBrushTexture();
virtual CBrush* Clone() const;
void SetColor1(const CColor& color);
CColor GetColor1() const;
void SetColor2(const CColor& color);
CColor GetColor2() const;
void TranslateTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void ScaleTransform(double dX, double dY, MatrixOrder order = MatrixOrderPrepend);
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend);
void GetTransform(CMatrix* matrix) const;
void SetTransform(const CMatrix* matrix);
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
void SetWrapMode(WrapMode wMode);
WrapMode GetWrapMode() const;
public:
CBrushHatch& operator=(const CBrushHatch& other);
CBrushHatch& operator=(CBrushHatch&& other) noexcept;
protected:
/**
* @brief m_wsName - hatch brush pattern name
* (as default - cross)
*
* See all patterns in agg_span_hatch.h, array -
* c_resource_hatches_names.
*/
std::wstring m_wsName;
CColor m_dwColor1{};
CColor m_dwColor2{};
void* GetData();
void* PatternFinalize();
DWORD PatternGetWidth();
DWORD PatternGetHeight();
int PatternGetStride();
public:
CImage* m_pImage;
INT m_bReleaseImage;
WrapMode m_wrapMode;
CMatrix m_mtx;
CDoubleRect m_oBounds{};
};
CColor m_colors[2];
/**
* @class CBrushLinearGradient
*
* brush for drawing gradients, stores information about the gradient.
* According to the pdf documentation, it stores the start and end point
* and color, as well as the linear interpolation of the colors.
*/
class CBrushLinearGradient : public CBrush
{
friend class CGraphics;
bool m_bUseBounds;
CDoubleRect m_oBounds;
public:
CBrushLinearGradient();
CBrushLinearGradient(const PointF& p1, const PointF& p2, const CColor& c1, const CColor& c2);
CBrushLinearGradient(const Point& p1, const Point& p2, const CColor& c1, const CColor& c2);
CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable);
CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, float angle, bool isAngleScalable);
CBrushLinearGradient(const RectF& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode);
CBrushLinearGradient(const Rect& rect, const CColor& c1, const CColor& c2, Aggplus::LinearGradientMode mode);
CBrushLinearGradient(const CBrushLinearGradient& other);
CBrushLinearGradient(CBrushLinearGradient&& other) noexcept;
virtual ~CBrushLinearGradient();
BYTE Alpha;
};
Status GetLinearColors(CColor* colors) const;
Status GetRectangle(Rect *rect) const;
Status GetRectangle(RectF *rect) const;
Status GetTransform(CMatrix* matrix) const;
Status MultiplyTransform(const CMatrix *matrix, MatrixOrder order = MatrixOrderPrepend);
Status ResetTransform();
Status RotateTransform(float angle, MatrixOrder order = MatrixOrderPrepend );
Status ScaleTransform(float sx, float sy, MatrixOrder order = MatrixOrderPrepend );
void SetWrapMode(WrapMode mode);
WrapMode GetWrapMode() const;
Status SetInterpolationColors(const CColor *presetColors, const float *blendPositions, int count);
Status GetInterpolationColors(CColor *presetColors, float *blendPositions, int count) const;
int GetInterpolationColorsCount() const;
void GetSubColor(int index, CColor* color, float* position) const;
void SetRelativeCoords(bool relative);
bool IsRelativeCoords() const;
bool IsAngleScalable() const;
bool IsRectable() const;
float GetAngle() const;
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
CBrushLinearGradient& operator=(const CBrushLinearGradient& other);
CBrushLinearGradient& operator=(CBrushLinearGradient&& other) noexcept;
NSStructures::GradientInfo m_oGradientInfo{};
protected:
CColor m_arColors[2];
PointF m_arPoints[2];
struct TSubColor
{
CColor color{};
float position = 0;
};
std::vector<TSubColor> m_arSubColors;
CMatrix m_Matrix{};
/**
* @brief m_angle - rotation angle of line p1 - p2 (measured in degrees)
*/
float m_fAngle = 0;
CDoubleRect m_oBounds{};
/**
* @brief m_eWrapMode - Used to determine the rotation of the image tiles
* (by default, we do not change the position).
*/
WrapMode m_eWrap = Aggplus::WrapModeTile;
/**
* @brief m_bAngleScalable - whether to scale the rotation angle relative
* to the given points
*
* calculated like this b = arctan(width / height * tan(angle));
*/
bool m_bAngleScalable = false;
/**
* @brief m_bRectable - is the diagonal of a rectangle a guide
*/
bool m_bRectable = false;
/**
* @brief m_bRelativeCoords - are the coordinates of the points calculated
* relative to the resulting primitive
*/
bool m_bRelativeCoords = false;
};
/**
* @class CBrushTexture
*
* A texture brush that is used to draw images on the renderer.
*/
class CBrushTexture : public CBrush
{
friend class CGraphics;
public:
CBrushTexture();
CBrushTexture(const std::wstring& name, WrapMode mode = WrapModeTile);
CBrushTexture(CImage *image, WrapMode mode = WrapModeTile);
CBrushTexture(const CBrushTexture& other);
CBrushTexture(CBrushTexture&& other);
virtual ~CBrushTexture();
void TranslateTransform(double x, double y, MatrixOrder order = MatrixOrderPrepend);
void ScaleTransform(double x, double y, MatrixOrder order = MatrixOrderPrepend);
void RotateTransform(double angle, MatrixOrder order = MatrixOrderPrepend);
void GetTransform(CMatrix* matrix) const;
void SetTransform(const CMatrix* matrix);
void SetWrapMode(WrapMode mode);
WrapMode GetWrapMode() const;
void SetBounds(const CDoubleRect& rect);
CDoubleRect& GetBounds();
void SetReleaseImage(bool isReleaseImage);
bool IsReleaseImage() const;
void SetAlpha(BYTE alpha);
BYTE GetAlpha() const;
void* GetData();
void* PatternFinalize();
DWORD PatternGetWidth();
DWORD PatternGetHeight();
int PatternGetStride();
CBrushTexture& operator=(const CBrushTexture& other);
CBrushTexture& operator=(CBrushTexture&& other);
protected:
CImage* m_pImage{nullptr};
bool m_bReleaseImage = false;
/**
* @brief m_eWrapMode - Used to determine the rotation of the image tiles
* (by default, we do not change the position).
*/
WrapMode m_eWrapMode = WrapModeTile;
CMatrix m_Matrix{};
bool m_bUseBounds = false;
CDoubleRect m_oBounds{};
BYTE m_Alpha = 255;
};
}
#endif // _BUILD_BRUSH_H_

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;
}
@ -978,7 +832,8 @@ namespace Aggplus
b = ptxBrush->m_oBounds.bottom;
}
CMatrix brushMatrix(ptxBrush->m_mtx);
CMatrix brushMatrix;
ptxBrush->GetTransform(&brushMatrix);
if (ptxBrush->GetWrapMode() == Aggplus::WrapModeClamp)
{
double dScaleX = (r - x) / dwPatternWidth;
@ -1798,11 +1653,11 @@ namespace Aggplus
m_rasterizer.gamma(1.0);
}
#else
agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetA());
agg::rgba8 c1 = agg::rgba8(pBrush->GetColor1().GetR(), pBrush->GetColor1().GetG(), pBrush->GetColor1().GetB(), pBrush->GetColor1().GetA());
agg::rgba8 c2 = agg::rgba8(pBrush->GetColor2().GetR(), pBrush->GetColor2().GetG(), pBrush->GetColor2().GetB(), pBrush->GetColor2().GetA());
BYTE* pPattern = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE * 4];
agg::GetHatchPattern(pBrush->m_name, (agg::rgba8*)pPattern, c1, c2);
agg::GetHatchPattern(pBrush->GetName(), (agg::rgba8*)pPattern, c1, c2);
agg::trans_affine mtx_Work(m_oTransform.m_internal->m_agg_mtx);
if (m_dDpiTile > 1)
@ -2195,22 +2050,22 @@ namespace Aggplus
if(pImgBuff && dwImgWidth && dwImgHeight)
{
Aggplus::WrapMode wrapmode = ptxBrush->m_wrapMode;
Aggplus::CMatrix matrix = ptxBrush->m_mtx;
Aggplus::WrapMode wrapmode = ptxBrush->m_eWrapMode;
Aggplus::CMatrix matrix = ptxBrush->m_Matrix;
if(wrapmode == WrapModeClamp)
{
DoFillPathTextureClampSz2( matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, ptxBrush->Alpha);
DoFillPathTextureClampSz2( matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, ptxBrush->m_Alpha);
}
else
{
if (!m_bSwapRGB)
{
DoFillPathTextureClampSz3<agg::pixfmt_bgra32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
DoFillPathTextureClampSz3<agg::pixfmt_bgra32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->m_Alpha);
}
else
{
DoFillPathTextureClampSz3<agg::pixfmt_rgba32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->Alpha);
DoFillPathTextureClampSz3<agg::pixfmt_rgba32>(matrix, pImgBuff, dwImgWidth, dwImgHeight, nImgStride, wrapmode, ptxBrush->m_Alpha);
}
}
}
@ -2243,6 +2098,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

@ -48,7 +48,7 @@ namespace Aggplus
CGraphicsPath::CGraphicsPath(CGraphicsPath&& other) noexcept
{
*this = other;
*this = std::move(other);
}
CGraphicsPath::CGraphicsPath(const std::vector<CGraphicsPath>& paths) noexcept : CGraphicsPath()

View File

@ -94,7 +94,7 @@ Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
Aggplus::CColor o1((BYTE)(pBrush->Alpha1 * m_dGlobalAlpha), pBrush->Color1, bIsSwappedRGB);
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient( Aggplus::RectF(0.0f, 0.0f, 1.0f, 1.0f), o1, o2, (float)pBrush->LinearAngle, TRUE );
Aggplus::CBrushLinearGradient* pNew = new Aggplus::CBrushLinearGradient(Aggplus::RectF(0.0f, 0.0f, 1.0f, 1.0f), o1, o2, (float)pBrush->LinearAngle, true);
if( pNew )
{
pNew->SetRelativeCoords( TRUE );
@ -180,11 +180,11 @@ Aggplus::CBrush* CGraphicsRenderer::CreateBrush(NSStructures::CBrush* pBrush)
Aggplus::CColor o2((BYTE)(pBrush->Alpha2 * m_dGlobalAlpha), pBrush->Color2, bIsSwappedRGB);
Aggplus::CBrushHatch* pNew = new Aggplus::CBrushHatch();
pNew->m_dwColor1 = o1;
pNew->m_dwColor2 = o2;
pNew->m_name = pBrush->TexturePath;
pNew->SetColor1(o1);
pNew->SetColor2(o2);
pNew->SetName(pBrush->TexturePath);
pNew->Bounds = pBrush->Bounds;
pNew->SetBounds(pBrush->Bounds);
return pNew;
}
@ -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;
@ -995,7 +996,7 @@ HRESULT CGraphicsRenderer::DrawPath(const LONG& nType)
pImage->Create(oFrame.get_Data(), oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride());
oFrame.ClearNoAttack();
pTextureBrush = new Aggplus::CBrushTexture(pImage, oMode);
pTextureBrush->m_bReleaseImage = TRUE;
pTextureBrush->SetReleaseImage(true);
}
else
RELEASEARRAYOBJECTS(pImageData);
@ -1017,15 +1018,14 @@ HRESULT CGraphicsRenderer::DrawPath(const LONG& nType)
{
pTextureBrush->SetTransform(&m_oBrush.Transform);
pTextureBrush->Alpha = (BYTE)m_oBrush.TextureAlpha;
pTextureBrush->SetAlpha(static_cast<BYTE>(m_oBrush.TextureAlpha));
if (m_oBrush.Rectable == 1)
{
pTextureBrush->m_bUseBounds = true;
pTextureBrush->m_oBounds.left = m_oBrush.Rect.X;
pTextureBrush->m_oBounds.top = m_oBrush.Rect.Y;
pTextureBrush->m_oBounds.right = pTextureBrush->m_oBounds.left + m_oBrush.Rect.Width;
pTextureBrush->m_oBounds.bottom = pTextureBrush->m_oBounds.top + m_oBrush.Rect.Height;
pTextureBrush->SetBounds({m_oBrush.Rect.X,
m_oBrush.Rect.Y,
m_oBrush.Rect.X + m_oBrush.Rect.Width,
m_oBrush.Rect.Y + m_oBrush.Rect.Height});
}
}

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

@ -51,6 +51,16 @@ namespace Aggplus
Create(filename);
}
CImage::CImage(const CImage& other)
{
*this = other;
}
CImage::CImage(CImage&& other)
{
*this = std::move(other);
}
CImage::~CImage()
{
Destroy();
@ -136,6 +146,46 @@ namespace Aggplus
m_bExternalBuffer = false;
}
CImage& CImage::operator=(const CImage& other)
{
if (this == &other)
return *this;
m_Status = other.m_Status;
m_dwHeight = other.m_dwHeight;
m_dwWidth = other.m_dwWidth;
m_nStride = other.m_nStride;
m_bExternalBuffer = other.m_bExternalBuffer;
size_t size_of_data = m_dwHeight * m_nStride > 0 ? m_nStride : -m_nStride;
m_pImgData = new BYTE[size_of_data];
memcpy(m_pImgData, other.m_pImgData, size_of_data);
return *this;
}
CImage& CImage::operator=(CImage&& other)
{
if (this == &other)
return *this;
m_Status = other.m_Status;
m_dwHeight = other.m_dwHeight;
m_dwWidth = other.m_dwWidth;
m_nStride = other.m_nStride;
m_bExternalBuffer = other.m_bExternalBuffer;
m_pImgData = other.m_pImgData;
other.m_pImgData = nullptr;
return *this;
}
DWORD CImage::GetWidth() const { return(m_dwWidth); }
DWORD CImage::GetHeight() const { return(m_dwHeight); }
long CImage::GetStride() const { return(m_nStride); }
@ -146,10 +196,10 @@ namespace Aggplus
////////////////////////////////////////////////////////////////////////////////////////
CBitmap::CBitmap(LONG width, LONG height, PixelFormat format) : CImage()
{
if(width <= 0 || height <= 0)
{
m_Status=InvalidParameter;
return;
if(width <= 0 || height <= 0)
{
m_Status=InvalidParameter;
return;
}
LONG lSize = 4 * width * height;
@ -168,15 +218,15 @@ namespace Aggplus
CBitmap::CBitmap(LONG width, LONG height, LONG stride, PixelFormat format, BYTE* scan0) : CImage()
{
//Warning! This is not Gdiplus behavior; it returns Ok!
if(width <= 0 || height <= 0 || stride == 0)
{
m_Status = InvalidParameter;
return;
if(width <= 0 || height <= 0 || stride == 0)
{
m_Status = InvalidParameter;
return;
}
m_bExternalBuffer = true;
if (stride > 0)
if (stride > 0)
{
m_pImgData = scan0;
}
@ -184,7 +234,7 @@ namespace Aggplus
{
m_pImgData = scan0 + (height - 1) * (-stride);
}
m_dwWidth = width;
m_dwHeight = height;
m_nStride = stride;

View File

@ -49,6 +49,8 @@ public:
public:
CImage();
CImage(const std::wstring& filename);
CImage(const CImage& other);
CImage(CImage&& other);
virtual ~CImage();
DWORD GetWidth() const;
@ -64,6 +66,9 @@ public:
bool SaveFile(const std::wstring& strFileName, UINT nFileType);
void Destroy();
CImage& operator=(const CImage& other);
CImage& operator=(CImage&& other);
protected:
Status m_Status;

View File

@ -30,127 +30,133 @@
*
*/
#include "Matrix_private.h"
#include <utility>
namespace Aggplus
{
CMatrix::CMatrix(double m11, double m12, double m21, double m22, double dx, double dy)
CMatrix::CMatrix(double m11, double m12, double m21, double m22, double dx, double dy)
{
m_internal = new CMatrix_private();
m_internal->m_agg_mtx.sx = m11;
m_internal->m_agg_mtx.shy = m12;
m_internal->m_agg_mtx.shx = m21;
m_internal->m_agg_mtx.sy = m22;
m_internal->m_agg_mtx.tx = dx;
m_internal->m_agg_mtx.ty = dy;
m_internal = new CMatrix_private();
m_internal->m_agg_mtx.sx = m11;
m_internal->m_agg_mtx.shy = m12;
m_internal->m_agg_mtx.shx = m21;
m_internal->m_agg_mtx.sy = m22;
m_internal->m_agg_mtx.tx = dx;
m_internal->m_agg_mtx.ty = dy;
}
CMatrix::CMatrix(const CMatrix& oSrc)
{
m_internal = new CMatrix_private();
m_internal->m_agg_mtx = oSrc.m_internal->m_agg_mtx;
}
CMatrix::CMatrix()
CMatrix::CMatrix()
{
m_internal = new CMatrix_private();
m_internal = new CMatrix_private();
}
CMatrix::CMatrix(const CMatrix& other)
{
*this = other;
}
CMatrix::CMatrix(CMatrix&& other)
{
*this = std::move(other);
}
CMatrix::~CMatrix()
{
RELEASEOBJECT(m_internal);
RELEASEOBJECT(m_internal);
}
void CMatrix::Translate(double offsetX, double offsetY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_translation(offsetX, offsetY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_translation(offsetX, offsetY));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_translation(offsetX, offsetY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_translation(offsetX, offsetY));
}
void CMatrix::Scale(double scaleX, double scaleY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_scaling(scaleX, scaleY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_scaling(scaleX, scaleY));
}
{
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_scaling(scaleX, scaleY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_scaling(scaleX, scaleY));
}
void CMatrix::Shear(double shearX, double shearY, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_skewing(shearX, shearY));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_skewing(shearX, shearY));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_skewing(shearX, shearY));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_skewing(shearX, shearY));
}
double CMatrix::Determinant() const
{
return m_internal->m_agg_mtx.determinant();
}
void CMatrix::TransformVectors(PointF* pts, int count) const
{
// Store matrix to an array [6] of double
double M[6]; m_internal->m_agg_mtx.store_to(M);
double M[6];
m_internal->m_agg_mtx.store_to(M);
for (int i = 0; i < count; ++i)
for (int i = 0; i < count; ++i)
{
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = (float)(x-M[4]);
pts[i].Y = (float)(y-M[5]);
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = static_cast<float>(x-M[4]);
pts[i].Y = static_cast<float>(y-M[5]);
}
}
void CMatrix::TransformPoints(PointF* pts, int count) const
{
for (int i = 0; i < count; ++i)
for (int i = 0; i < count; ++i)
{
double x = pts[i].X;
double y = pts[i].Y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = (float)x;
pts[i].Y = (float)y;
m_internal->m_agg_mtx.transform(&x, &y);
pts[i].X = static_cast<float>(x);
pts[i].Y = static_cast<float>(y);
}
}
void CMatrix::TransformPoint(double& x, double& y) const
{
m_internal->m_agg_mtx.transform(&x, &y);
m_internal->m_agg_mtx.transform(&x, &y);
}
void CMatrix::TransformPoints(PointF* dst, const PointF* src, int count) const
{
agg::trans_affine& m = m_internal->m_agg_mtx;
for(int i = 0; i < count; ++i)
{
double x = src[i].X * m.sx + src[i].Y * m.shx + m.tx;
double y = src[i].Y * m.sy + src[i].X * m.shy + m.ty;
dst[i].X = static_cast<float>(x);
dst[i].Y = static_cast<float>(y);
}
}
void CMatrix::Rotate(double angle, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
void CMatrix::RotateAt(double angle, const PointF &center, MatrixOrder order)
{
Translate(-center.X, -center.Y, order);
if(order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if(order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
Translate(center.X, center.Y, order);
return;
}
@ -158,168 +164,169 @@ namespace Aggplus
void CMatrix::RotateAt(double angle, double x, double y, MatrixOrder order)
{
Translate(-x, -y, order);
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
else
{
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
else
m_internal->m_agg_mtx.multiply(agg::trans_affine_rotation(agg::deg2rad(angle)));
Translate(x, y, order);
}
void CMatrix::Multiply(const CMatrix* matrix, MatrixOrder order)
{
if (order == MatrixOrderPrepend)
{
m_internal->m_agg_mtx.premultiply(matrix->m_internal->m_agg_mtx);
}
if (order == MatrixOrderPrepend)
m_internal->m_agg_mtx.premultiply(matrix->m_internal->m_agg_mtx);
else
{
m_internal->m_agg_mtx.multiply(matrix->m_internal->m_agg_mtx);
}
m_internal->m_agg_mtx.multiply(matrix->m_internal->m_agg_mtx);
}
double CMatrix::OffsetX() const
{
return m_internal->m_agg_mtx.tx;
return m_internal->m_agg_mtx.tx;
}
double CMatrix::OffsetY() const
{
return m_internal->m_agg_mtx.ty;
return m_internal->m_agg_mtx.ty;
}
double CMatrix::sx() const
{
return m_internal->m_agg_mtx.sx;
}
double CMatrix::sy() const
{
return m_internal->m_agg_mtx.sy;
}
double CMatrix::shx() const
{
return m_internal->m_agg_mtx.shx;
}
double CMatrix::shy() const
{
return m_internal->m_agg_mtx.shy;
}
double CMatrix::tx() const
{
return m_internal->m_agg_mtx.tx;
}
double CMatrix::ty() const
{
return m_internal->m_agg_mtx.ty;
}
double CMatrix::rotation()
{
return m_internal->m_agg_mtx.rotation();
}
void CMatrix::SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx, const double& ty)
{
m_internal->m_agg_mtx.sx = sx;
m_internal->m_agg_mtx.shy = shy;
m_internal->m_agg_mtx.shx = shx;
m_internal->m_agg_mtx.sy = sy;
m_internal->m_agg_mtx.tx = tx;
m_internal->m_agg_mtx.ty = ty;
}
Status CMatrix::GetElements(REAL* m) const
double CMatrix::sx() const
{
double M[6]; m_internal->m_agg_mtx.store_to(M);
m[0]=(REAL)M[0];
m[1]=(REAL)M[1];
m[2]=(REAL)M[2];
m[3]=(REAL)M[3];
m[4]=(REAL)M[4];
m[5]=(REAL)M[5];
return m_internal->m_agg_mtx.sx;
}
double CMatrix::sy() const
{
return m_internal->m_agg_mtx.sy;
}
double CMatrix::shx() const
{
return m_internal->m_agg_mtx.shx;
}
double CMatrix::shy() const
{
return m_internal->m_agg_mtx.shy;
}
double CMatrix::tx() const
{
return m_internal->m_agg_mtx.tx;
}
double CMatrix::ty() const
{
return m_internal->m_agg_mtx.ty;
}
double CMatrix::rotation()
{
return m_internal->m_agg_mtx.rotation();
}
void CMatrix::SetElements(const double& sx, const double& shy, const double& shx,
const double& sy, const double& tx, const double& ty)
{
m_internal->m_agg_mtx.sx = sx;
m_internal->m_agg_mtx.shy = shy;
m_internal->m_agg_mtx.shx = shx;
m_internal->m_agg_mtx.sy = sy;
m_internal->m_agg_mtx.tx = tx;
m_internal->m_agg_mtx.ty = ty;
}
Status CMatrix::GetElements(float* m) const
{
double M[6];
m_internal->m_agg_mtx.store_to(M);
m[0] = static_cast<float>(M[0]);
m[1] = static_cast<float>(M[1]);
m[2] = static_cast<float>(M[2]);
m[3] = static_cast<float>(M[3]);
m[4] = static_cast<float>(M[4]);
m[5] = static_cast<float>(M[5]);
return Ok;
}
Status CMatrix::GetElements(double* m) const
{
m_internal->m_agg_mtx.store_to(m);
m_internal->m_agg_mtx.store_to(m);
return Ok;
}
void CMatrix::Reset()
{
m_internal->m_agg_mtx.reset();
m_internal->m_agg_mtx.reset();
}
double CMatrix::Determinant() const
bool CMatrix::IsIdentity(const double& eps) const
{
return m_internal->m_agg_mtx.determinant();
}
return m_internal->m_agg_mtx.is_identity(eps);
}
const CMatrix& CMatrix::operator=(const CMatrix& Src)
bool CMatrix::IsIdentity2(const double& eps) const
{
m_internal->m_agg_mtx = Src.m_internal->m_agg_mtx;
return *this;
agg::trans_affine& m = m_internal->m_agg_mtx;
return agg::is_equal_eps(m.sx, 1.0, eps) &&
agg::is_equal_eps(m.shy, 0.0, eps) &&
agg::is_equal_eps(m.shx, 0.0, eps) &&
agg::is_equal_eps(m.sy, 1.0, eps);
}
bool CMatrix::IsEqual(const CMatrix* mm1, const CMatrix* mm2, const double& eps, bool bIsOnlyMain)
{
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;
if (!bMain || bIsOnlyMain)
return bMain;
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
}
Status CMatrix::Invert()
{
double d = m_internal->m_agg_mtx.determinant();
if (0.0001 >= fabs(d))
double d = m_internal->m_agg_mtx.determinant();
if (0.0001 >= fabs(d))
return InvalidParameter;
m_internal->m_agg_mtx.invert();
m_internal->m_agg_mtx.invert();
return Ok;
}
//Temp
//Used in X_BrushLinearGradient constructor
double CMatrix::z_Rotation() const
{
return agg::rad2deg(m_internal->m_agg_mtx.rotation());
}
void CMatrix::TransformPoints( PointF* dst, const PointF* src, int count ) const
double CMatrix::z_Rotation() const
{
agg::trans_affine& m = m_internal->m_agg_mtx;
for(int i = 0; i < count; ++i)
{
double x = src[i].X * m.sx + src[i].Y * m.shx + m.tx;
double y = src[i].Y * m.sy + src[i].X * m.shy + m.ty;
dst[i].X = (float)x;
dst[i].Y = (float)y;
}
return agg::rad2deg(m_internal->m_agg_mtx.rotation());
}
bool CMatrix::IsIdentity(const double& eps) const
const CMatrix& CMatrix::operator=(const CMatrix& other)
{
return m_internal->m_agg_mtx.is_identity(eps);
if (this == &other)
return *this;
m_internal = new CMatrix_private();
m_internal->m_agg_mtx = other.m_internal->m_agg_mtx;
return *this;
}
bool CMatrix::IsIdentity2(const double& eps) const
CMatrix& CMatrix::operator=(CMatrix&& other)
{
agg::trans_affine& m = m_internal->m_agg_mtx;
return agg::is_equal_eps(m.sx, 1.0, eps) &&
agg::is_equal_eps(m.shy, 0.0, eps) &&
agg::is_equal_eps(m.shx, 0.0, eps) &&
agg::is_equal_eps(m.sy, 1.0, eps);
if (this == &other)
return *this;
m_internal = other.m_internal;
other.m_internal = nullptr;
return *this;
}
bool CMatrix::IsEqual(const CMatrix* mm1, const CMatrix* mm2, const double& eps, bool bIsOnlyMain)
{
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;
if (!bMain || bIsOnlyMain)
return bMain;
return fabs(m1.tx - m2.tx) < eps && fabs(m1.ty - m2.ty) < eps;
}
}

View File

@ -37,62 +37,62 @@
namespace Aggplus
{
class CMatrix_private;
class GRAPHICS_DECL CMatrix
{
public:
CMatrix(double m11, double m12, double m21, double m22, double dx, double dy);
CMatrix();
CMatrix(const CMatrix& oSrc);
class CMatrix_private;
class GRAPHICS_DECL CMatrix
{
public:
CMatrix();
CMatrix(double m11, double m12, double m21, double m22, double dx, double dy);
CMatrix(const CMatrix& other);
CMatrix(CMatrix&& other);
~CMatrix();
~CMatrix();
void Translate(double offsetX, double offsetY, MatrixOrder order = MatrixOrderPrepend);
void Scale(double scaleX, double scaleY, MatrixOrder order = MatrixOrderPrepend);
void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
double Determinant() const;
void Translate(double offsetX, double offsetY, MatrixOrder order = MatrixOrderPrepend);
void Scale(double scaleX, double scaleY, MatrixOrder order = MatrixOrderPrepend);
void Shear(double shearX, double shearY, MatrixOrder order = MatrixOrderPrepend);
double Determinant() const;
void TransformVectors(PointF* pts, int count) const;
void TransformPoints(PointF* pts, int count) const;
void TransformPoint(double& x, double& y) const;
void TransformPoints(PointF* dst, const PointF* src, int count) const;
void TransformVectors(PointF* pts, int count) const;
void TransformPoints(PointF* pts, int count) const;
void TransformPoint(double& x, double& y) const;
void TransformPoints(PointF* dst, const PointF* src, int count) const;
void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, const PointF &center, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, double x, double y, MatrixOrder order = MatrixOrderPrepend);
void Rotate(double angle, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, const PointF &center, MatrixOrder order = MatrixOrderPrepend);
void RotateAt(double angle, double x, double y, MatrixOrder order = MatrixOrderPrepend);
void Multiply(const CMatrix* matrix, MatrixOrder order = MatrixOrderPrepend);
void Multiply(const CMatrix* matrix, MatrixOrder order = MatrixOrderPrepend);
double OffsetX() const;
double OffsetY() const;
double OffsetX() const;
double OffsetY() const;
double sx() const;
double sy() const;
double shx() const;
double shy() const;
double tx() const;
double ty() const;
double rotation();
double sx() const;
double sy() const;
double shx() const;
double shy() const;
double tx() const;
double ty() const;
double rotation();
void SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx = 0, const double& ty = 0);
void SetElements(const double& sx, const double& shy, const double& shx, const double& sy, const double& tx = 0, const double& ty = 0);
Status GetElements(float* m) const;
Status GetElements(double* m) const;
Status GetElements(float* m) const;
Status GetElements(double* m) const;
void Reset();
bool IsIdentity(const double& eps = 0.00001) const;
bool IsIdentity2(const double& eps = 0.00001) const;
void Reset();
bool IsIdentity(const double& eps = 0.00001) const;
bool IsIdentity2(const double& eps = 0.00001) const;
static bool IsEqual(const CMatrix* m1, const CMatrix* m2, const double& eps = 0.001, bool bIsOnlyMain = false);
static bool IsEqual(const CMatrix* m1, const CMatrix* m2, const double& eps = 0.001, bool bIsOnlyMain = false);
Status Invert();
const CMatrix& operator=(const CMatrix& Src);
double z_Rotation() const;
Status Invert();
const CMatrix& operator=(const CMatrix& other);
CMatrix& operator=(CMatrix&& other);
double z_Rotation() const;
public:
CMatrix_private* m_internal;
};
public:
CMatrix_private* m_internal;
};
}
#endif // _BUILD_MATRIX_H_

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

@ -48,7 +48,7 @@
CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotaion)
{
m_nType = -1;
m_nType = EAnnotType::Unknown;
m_nFlag = 0;
m_nID = 0;
@ -94,118 +94,108 @@ CAnnotFieldInfo::~CAnnotFieldInfo()
RELEASEOBJECT(m_pWidgetPr);
}
void CAnnotFieldInfo::CreateMarkup()
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
}
void CAnnotFieldInfo::SetType(int nType)
{
m_nType = nType;
switch (nType)
m_nType = static_cast<EAnnotType>(nType);
switch (m_nType)
{
case 0:
case EAnnotType::Text:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pTextPr);
m_pTextPr = new CAnnotFieldInfo::CTextAnnotPr();
break;
}
case 2:
case EAnnotType::FreeText:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pFreeTextPr);
m_pFreeTextPr = new CAnnotFieldInfo::CFreeTextAnnotPr();
break;
}
case 3:
case EAnnotType::Line:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pLinePr);
m_pLinePr = new CAnnotFieldInfo::CLineAnnotPr();
break;
}
case 4:
case 5:
case EAnnotType::Square:
case EAnnotType::Circle:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pSquareCirclePr);
m_pSquareCirclePr = new CAnnotFieldInfo::CSquareCircleAnnotPr();
break;
}
case 6:
case 7:
case EAnnotType::PolygonLine:
case EAnnotType::PolyLine:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pPolygonLinePr);
m_pPolygonLinePr = new CAnnotFieldInfo::CPolygonLineAnnotPr();
break;
}
case 8:
case 9:
case 10:
case 11:
case EAnnotType::Highlight:
case EAnnotType::Underline:
case EAnnotType::Squiggly:
case EAnnotType::Strikeout:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pTextMarkupPr);
m_pTextMarkupPr = new CAnnotFieldInfo::CTextMarkupAnnotPr();
break;
}
case 12:
case EAnnotType::Stamp:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pStampPr);
m_pStampPr = new CAnnotFieldInfo::CStampAnnotPr();
break;
}
case 13:
case EAnnotType::Caret:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pCaretPr);
m_pCaretPr = new CAnnotFieldInfo::CCaretAnnotPr();
break;
}
case 14:
case EAnnotType::Ink:
{
RELEASEOBJECT(m_pMarkupPr);
m_pMarkupPr = new CAnnotFieldInfo::CMarkupAnnotPr();
CreateMarkup();
RELEASEOBJECT(m_pInkPr);
m_pInkPr = new CAnnotFieldInfo::CInkAnnotPr();
break;
}
case 15:
case EAnnotType::Popup:
{
RELEASEOBJECT(m_pPopupPr);
m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr();
break;
}
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
case EAnnotType::Widget:
case EAnnotType::WidgetPushButton:
case EAnnotType::WidgetRadioButton:
case EAnnotType::WidgetCheckBox:
case EAnnotType::WidgetText:
case EAnnotType::WidgetCombobox:
case EAnnotType::WidgetListbox:
case EAnnotType::WidgetSignature:
{
RELEASEOBJECT(m_pWidgetPr);
m_pWidgetPr = new CAnnotFieldInfo::CWidgetAnnotPr(nType);
break;
}
default:
break;
}
}
CAnnotFieldInfo::EAnnotType CAnnotFieldInfo::GetType() { return m_nType; }
void CAnnotFieldInfo::GetBounds(double& dX1, double& dY1, double& dX2, double& dY2)
{
@ -343,6 +333,7 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
if (nFlags & (1 << 3))
{
int n = pReader->ReadInt();
m_arrC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrC.push_back(pReader->ReadDouble());
}
@ -353,6 +344,7 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
if (m_oBorder.nType == 2)
{
int n = pReader->ReadInt();
m_oBorder.arrDash.reserve(n);
for (int i = 0; i < n; ++i)
m_oBorder.arrDash.push_back(pReader->ReadDouble());
}
@ -428,6 +420,7 @@ void CAnnotFieldInfo::CMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
if (nFlags & (1 << 3))
{
int nFont = pReader->ReadInt();
m_arrRC.reserve(nFont);
for (int i = 0; i < nFont; ++i)
{
CFontData* pFont = new CFontData();
@ -480,6 +473,7 @@ void CAnnotFieldInfo::CInkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* p
{
std::vector<double> arrLine;
int m = pReader->ReadInt();
arrLine.reserve(m);
for (int j = 0; j < m; ++j)
arrLine.push_back(pReader->ReadDouble());
if (!arrLine.empty())
@ -512,6 +506,7 @@ void CAnnotFieldInfo::CLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
if (nFlags & (1 << 16))
{
int n = pReader->ReadInt();
m_arrIC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrIC.push_back(pReader->ReadDouble());
}
@ -539,6 +534,7 @@ void CAnnotFieldInfo::CTextMarkupAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRe
{
m_nSubtype = nType;
int n = pReader->ReadInt();
m_arrQuadPoints.reserve(n);
for (int i = 0; i < n; ++i)
m_arrQuadPoints.push_back(pReader->ReadDouble());
}
@ -559,6 +555,7 @@ void CAnnotFieldInfo::CSquareCircleAnnotPr::Read(NSOnlineOfficeBinToPdf::CBuffer
if (nFlags & (1 << 16))
{
int n = pReader->ReadInt();
m_arrIC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrIC.push_back(pReader->ReadDouble());
}
@ -572,6 +569,7 @@ const std::vector<double>& CAnnotFieldInfo::CPolygonLineAnnotPr::GetVertices() {
void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, BYTE nType, int nFlags)
{
int n = pReader->ReadInt();
m_arrVertices.reserve(n);
for (int i = 0; i < n; ++i)
m_arrVertices.push_back(pReader->ReadDouble());
@ -584,6 +582,7 @@ void CAnnotFieldInfo::CPolygonLineAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferR
if (nFlags & (1 << 16))
{
int n = pReader->ReadInt();
m_arrIC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrIC.push_back(pReader->ReadDouble());
}
@ -613,6 +612,7 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead
if (nFlags & (1 << 16))
{
int n = pReader->ReadInt();
m_arrCL.reserve(n);
for (int i = 0; i < n; ++i)
m_arrCL.push_back(pReader->ReadDouble());
}
@ -625,6 +625,7 @@ void CAnnotFieldInfo::CFreeTextAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferRead
if (nFlags & (1 << 21))
{
int n = pReader->ReadInt();
m_arrIC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrIC.push_back(pReader->ReadDouble());
}
@ -814,6 +815,7 @@ CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPd
{
pRes->nKind = pReader->ReadByte();
int n = pReader->ReadInt();
pRes->arrStr.reserve(n);
for (int i = 0; i < n; ++i)
pRes->arrStr.push_back(pReader->ReadString());
break;
@ -822,6 +824,7 @@ CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* ReadAction(NSOnlineOfficeBinToPd
{
pRes->nInt1 = pReader->ReadInt();
int n = pReader->ReadInt();
pRes->arrStr.reserve(n);
for (int i = 0; i < n; ++i)
pRes->arrStr.push_back(pReader->ReadString());
break;
@ -841,6 +844,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
m_nFontStyle = pReader->ReadInt();
int n = pReader->ReadInt();
m_arrTC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrTC.push_back(pReader->ReadDouble());
@ -863,6 +867,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
if (nFlags & (1 << 5))
{
int n = pReader->ReadInt();
m_arrBC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrBC.push_back(pReader->ReadDouble());
}
@ -871,6 +876,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader
if (nFlags & (1 << 7))
{
int n = pReader->ReadInt();
m_arrBG.reserve(n);
for (int i = 0; i < n; ++i)
m_arrBG.push_back(pReader->ReadDouble());
}
@ -1006,6 +1012,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToP
if (nFlags & (1 << 10))
{
int n = pReader->ReadInt();
m_arrOpt.reserve(n);
for (int i = 0; i < n; ++i)
{
std::wstring s1 = pReader->ReadString();
@ -1020,12 +1027,14 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr::Read(NSOnlineOfficeBinToP
if (nFlags & (1 << 13))
{
int n = pReader->ReadInt();
m_arrV.reserve(n);
for (int i = 0; i < n; ++i)
m_arrV.push_back(pReader->ReadString());
}
if (nFlags & (1 << 14))
{
int n = pReader->ReadInt();
m_arrI.reserve(n);
for (int i = 0; i < n; ++i)
m_arrI.push_back(pReader->ReadInt());
}
@ -1058,10 +1067,12 @@ const std::vector<CWidgetsInfo::CParent*>& CWidgetsInfo::GetParents() { return m
bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
{
int n = pReader->ReadInt();
m_arrCO.reserve(n);
for (int i = 0; i < n; ++i)
m_arrCO.push_back(pReader->ReadInt());
n = pReader->ReadInt();
m_arrParents.reserve(n);
for (int i = 0; i < n; ++i)
{
CParent* pParent = new CParent();
@ -1077,6 +1088,7 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil
if (nFlags & (1 << 3))
{
int n = pReader->ReadInt();
pParent->arrI.reserve(n);
for (int i = 0; i < n; ++i)
pParent->arrI.push_back(pReader->ReadInt());
}
@ -1085,6 +1097,7 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil
if (nFlags & (1 << 5))
{
int n = pReader->ReadInt();
pParent->arrV.reserve(n);
for (int i = 0; i < n; ++i)
pParent->arrV.push_back(pReader->ReadString());
}
@ -1092,6 +1105,7 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil
}
n = pReader->ReadInt();
m_arrButtonImg.reserve(n);
for (int i = 0; i < n; ++i)
{
std::string sImagePath = pReader->ReadStringA();

View File

@ -39,6 +39,36 @@ class IMetafileToRenderter;
class GRAPHICS_DECL CAnnotFieldInfo : public IAdvancedCommand
{
public:
enum EAnnotType
{
Unknown = -1,
Text = 0,
Link = 1,
FreeText = 2,
Line = 3,
Square = 4,
Circle = 5,
PolygonLine = 6,
PolyLine = 7,
Highlight = 8,
Underline = 9,
Squiggly = 10,
Strikeout = 11,
Stamp = 12,
Caret = 13,
Ink = 14,
Popup = 15,
FileAttachment = 16,
Widget = 26,
WidgetPushButton = 27,
WidgetRadioButton = 28,
WidgetCheckBox = 29,
WidgetText = 30,
WidgetCombobox = 31,
WidgetListbox = 32,
WidgetSignature = 33
};
class GRAPHICS_DECL CWidgetAnnotPr
{
public:
@ -423,7 +453,9 @@ public:
CAnnotFieldInfo();
virtual ~CAnnotFieldInfo();
void CreateMarkup();
void SetType(int nType);
EAnnotType GetType();
void GetBounds(double& dX1, double& dY1, double& dX2, double& dY2);
void GetBorder(BYTE& nType, double& dWidth, std::vector<double>& arrDash);
@ -479,7 +511,7 @@ private:
std::vector<double> arrDash;
};
int m_nType;
EAnnotType m_nType;
double m_dX1;
double m_dY1;
double m_dX2;

View File

@ -701,6 +701,7 @@ namespace NSFonts
virtual void Initialize() = 0;
virtual void SetOwnerCache(IFontsCache* pCache) = 0;
virtual void CreateOwnerCache(const int& nCacheSize = -1);
virtual void ClearOwnerCache() = 0;
virtual void AfterLoad() = 0;

View File

@ -110,11 +110,20 @@ namespace NSImages
#ifndef GRAPHICS_DISABLE_METAFILE
namespace MetaFile
{
const int c_lMetaWmf = 0x01;
const int c_lMetaEmf = 0x02;
const int c_lMetaSvg = 0x04;
const int c_lMetaSvm = 0x05;
/**
* @brief Meta file extension constants
*/
const long c_lMetaWmf = 0x0001;
const long c_lMetaEmf = 0x0002;
const long c_lMetaSvg = 0x0004;
const long c_lMetaSvm = 0x0005;
/**
* @interface IMetaFile
*
* The interface provides various options for loading a metafile and saving it
* in another format.
*/
class GRAPHICS_DECL IMetaFile : public NSBase::CBaseRefCounter
{
public:
@ -124,23 +133,20 @@ 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 bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY,
double dWidth, double dHeight, const wchar_t* wsXmlFilePath = NULL) = 0;
virtual void Close() = 0;
virtual void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH) = 0;
virtual int GetType() = 0;
virtual void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) = 0;
virtual void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1, const wchar_t* wsXmlOutFile = NULL) = 0;
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
virtual void ConvertToXml(const wchar_t *wsFilePath) = 0;
virtual void ConvertToXmlAndRaster(const wchar_t *wsXmlFilePath, const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1) = 0;
virtual bool LoadFromXmlFile(const wchar_t* wsFilePath) = 0;
virtual void ConvertToXml(const wchar_t *wsFilePath) = 0;
virtual void ConvertToEmf(const wchar_t *wsFilePath) = 0;
#endif
};
GRAPHICS_DECL IMetaFile* Create(NSFonts::IApplicationFonts *pAppFonts);

View File

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

View File

@ -682,6 +682,7 @@ HEADERS += \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Table.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \
@ -706,6 +707,7 @@ SOURCES += \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.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/Table.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.cpp \
$$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.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

@ -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,11 +0,0 @@
#include <codecvt>
#include "../../pro/Graphics.h"
int main(int argc, char *argv[])
{
Aggplus::CImage Cimg(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(argv[1]));
Cimg.SaveFile(std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(argv[2]), 1);
return 0;
}

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,182 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QImage>
#include <QPixmap>
#include <QSpinBox>
#include <QComboBox>
#include <QStringList>
#include "../../pro/Graphics.h"
static constexpr double rectangle[4] = {
10.0, 10.0, 80.0, 80.0,
};
static const QStringList patterns = {
"cross",
"dashDnDiag",
"dashHorz",
"dashUpDiag",
"dashVert",
"diagBrick",
"diagCross",
"divot",
"dkDnDiag",
"dkHorz",
"dkUpDiag",
"dkVert",
"dnDiag",
"dotDmnd",
"dotGrid",
"horz",
"horzBrick",
"lgCheck",
"lgConfetti",
"lgGrid",
"ltDnDiag",
"ltHorz",
"ltUpDiag",
"ltVert",
"narHorz",
"narVert",
"openDmnd",
"pct10",
"pct20",
"pct25",
"pct30",
"pct40",
"pct5",
"pct50",
"pct60",
"pct70",
"pct75",
"pct80",
"pct90",
"plaid",
"shingle",
"smCheck",
"smConfetti",
"smGrid",
"solidDmnd",
"sphere",
"trellis",
"upDiag",
"vert",
"wave",
"wdDnDiag",
"wdUpDiag",
"weave",
"zigZag"
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->SetColor(Qt::red);
ui->pushButton_2->SetColor(Qt::blue);
ui->comboBox->addItems(patterns);
connect(ui->pushButton, &CColorButton::ColorChanged, this, &MainWindow::Draw);
connect(ui->pushButton_2, &CColorButton::ColorChanged, this, &MainWindow::Draw);
connect(ui->spinBox, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->spinBox_2, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::Draw);
connect(ui->radioButton, &QRadioButton::clicked, this, &MainWindow::Draw);
connect(ui->radioButton_2, &QRadioButton::clicked, this, &MainWindow::Draw);
m_oPathRectangle.StartFigure();
m_oPathRectangle.MoveTo(rectangle[0], rectangle[1]);
m_oPathRectangle.LineTo(rectangle[0] + rectangle[2], rectangle[1]);
m_oPathRectangle.LineTo(rectangle[0] + rectangle[2], rectangle[1] + rectangle[3]);
m_oPathRectangle.LineTo(rectangle[0], rectangle[1] + rectangle[3]);
m_oPathRectangle.LineTo(rectangle[0], rectangle[1]);
m_oPathRectangle.CloseFigure();
m_oPathEllisps.StartFigure();
m_oPathEllisps.AddEllipse(rectangle[0], rectangle[1], rectangle[2], rectangle[3]);
m_oPathEllisps.CloseFigure();
Draw();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::Draw()
{
NSGraphics::IGraphicsRenderer *renderer = NSGraphics::Create();
int width = ui->label->width(),
height = ui->label->height();
BYTE* data = new BYTE[4 * width * height];
CBgraFrame frame;
frame.put_Data(data);
frame.put_Width(width);
frame.put_Height(height);
frame.put_Stride(4 * width);
renderer->put_Width(100);
renderer->put_Height(100);
renderer->CreateFromBgraFrame(&frame);
renderer->SetSwapRGB(false);
renderer->put_BrushType(c_BrushTypeHatch1);
renderer->put_BrushTexturePath(ui->comboBox->currentText().toStdWString());
renderer->put_BrushColor1(ui->pushButton->GetColor().rgb());
renderer->put_BrushAlpha1(ui->spinBox->value());
renderer->put_BrushColor2(ui->pushButton_2->GetColor().rgb());
renderer->put_BrushAlpha2(ui->spinBox->value());
std::vector<Aggplus::PointD> points;
unsigned length;
bool is_rectangle = ui->radioButton->isChecked();
if (is_rectangle)
{
length = m_oPathRectangle.GetPointCount();
points = m_oPathRectangle.GetPoints(0, length);
}
else
{
length = m_oPathEllisps.GetPointCount();
points = m_oPathEllisps.GetPoints(0, length);
}
renderer->BeginCommand(c_nPathType);
renderer->PathCommandStart();
for (unsigned i = 0; i < length; i++)
{
if (is_rectangle ? m_oPathRectangle.IsCurvePoint(i) : m_oPathEllisps.IsCurvePoint(i))
{
renderer->PathCommandCurveTo(points[i].X, points[i].Y,
points[i + 1].X, points[i + 1].Y,
points[i + 2].X, points[i + 2].Y);
i += 2;
}
else if (is_rectangle ? m_oPathRectangle.IsMovePoint(i) : m_oPathEllisps.IsMovePoint(i))
renderer->PathCommandMoveTo(points[i].X, points[i].Y);
else if (is_rectangle ? m_oPathRectangle.IsLinePoint(i) : m_oPathEllisps.IsLinePoint(i))
renderer->PathCommandLineTo(points[i].X, points[i].Y);
}
renderer->PathCommandClose();
renderer->Fill();
renderer->EndCommand(c_nPathType);
renderer->PathCommandEnd();
auto img = QImage(data, width, height, QImage::Format_RGBA8888, [](void *data){
delete[] (BYTE*)data;
});
ui->label->setPixmap(QPixmap::fromImage(img));
RELEASEOBJECT(renderer);
}

View File

@ -0,0 +1,81 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QColor>
#include <QColorDialog>
#include <QPalette>
#include "../../GraphicsPath.h"
class CColorButton final : public QPushButton
{
Q_OBJECT
public:
CColorButton(QWidget *parent = nullptr) : QPushButton(parent)
{
connect(this, &QPushButton::clicked, this, &CColorButton::onClicked);
}
~CColorButton() {}
QColor GetColor() const
{
return m_oColor;
}
void SetColor(const QColor& color)
{
if (color == m_oColor)
return;
m_oColor = color;
setStyleSheet("QPushButton { background-color : " + m_oColor.name()
+ "; border: 1px solid black; padding 10px;}");
emit ColorChanged();
}
signals:
void ColorChanged();
public slots:
void onClicked()
{
QColorDialog color_dialog;
auto color = color_dialog.getColor();
if (color.isValid())
SetColor(color);
}
private:
QColor m_oColor;
};
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void Draw();
private:
Aggplus::CGraphicsPath m_oPathRectangle;
Aggplus::CGraphicsPath m_oPathEllisps;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>538</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>190</y>
<width>300</width>
<height>300</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>321</width>
<height>151</height>
</rect>
</property>
<property name="title">
<string>Hatch brush parametrs</string>
</property>
<widget class="CColorButton" name="pushButton">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="CColorButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>110</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>First color:</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>110</x>
<y>20</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Second color:</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>110</x>
<y>70</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Second alpha:</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
</widget>
<widget class="QSpinBox" name="spinBox_2">
<property name="geometry">
<rect>
<x>110</x>
<y>90</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>255</number>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Type:</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>200</x>
<y>40</y>
<width>110</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>200</x>
<y>70</y>
<width>110</width>
<height>70</height>
</rect>
</property>
<property name="title">
<string>Path:</string>
</property>
<widget class="QRadioButton" name="radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Rectangle</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_2">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Circle</string>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>First alpha:</string>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>160</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Output:</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>368</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>CColorButton</class>
<extends>QPushButton</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,20 @@
QT += core gui widgets
QMAKE_CXXFLAGS += /permissive-
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,62 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QLabel>
#include <QSizePolicy>
#include <QDir>
#include "../../../../UnicodeConverter/UnicodeConverter.h"
#include "../../pro/Graphics.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->label->setFixedWidth(310);
ui->comboBox->addItems(m_arExtensions);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_arFileNames = QFileDialog::getOpenFileNames(this,
"Select one or more images",
"",
"*.bmp *.gif *.jpg *.png *.ico "
"*.tif *.tga *.pcx *.wbmp *.jp2 "
"*.jpc *.pgx *.pnm *.ras *.jbg "
"*.mng *.ska *.raw *.psd *.pic");
if (!m_arFileNames.empty())
ui->label->setText("File:" + m_arFileNames[0]);
}
void MainWindow::on_pushButton_2_clicked()
{
auto save_dir = QFileDialog::getExistingDirectory(this,
"Open Directory",
"",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
auto ext = ui->comboBox->currentText();
NSUnicodeConverter::CUnicodeConverter converter;
for (const auto& f : m_arFileNames)
{
ui->label->setText("File:" + f);
Aggplus::CImage img(converter.toUnicode(f.toStdString(), 1));
img.SaveFile(converter.toUnicode(QDir(save_dir).filePath("res." + ext).toStdString(), 1),
m_mapExtensionCodes.value(ext));
}
}

View File

@ -0,0 +1,75 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QStringList>
#include <QMap>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
QStringList m_arFileNames;
QStringList m_arExtensions = {
"bmp",
"gif",
"jpg",
"png",
"ico",
"tif",
"tga",
"pcx",
"wbmp",
"jp2",
"jpc",
"pgx",
"pnm",
"ras",
"mng",
"ska",
"raw",
"psd",
"pic",
};
QMap<QString, int> m_mapExtensionCodes = {
{"bmp", 1},
{"gif", 2},
{"jpg", 3},
{"png", 4},
{"ico", 5},
{"tif", 6},
{"tga", 7},
{"pcx", 8},
{"wbmp", 9},
{"jp2", 11},
{"jpc", 12},
{"pgx", 13},
{"pnm", 14},
{"ras", 15},
{"mng", 17},
{"ska", 18},
{"raw", 19},
{"psd", 20},
{"pic", 25},
};
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>196</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>40</x>
<y>20</y>
<width>121</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Choose img file</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>40</x>
<y>50</y>
<width>310</width>
<height>91</height>
</rect>
</property>
<property name="text">
<string>File:</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>270</x>
<y>20</y>
<width>80</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Convert</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>180</x>
<y>20</y>
<width>72</width>
<height>24</height>
</rect>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>385</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,13 +1,8 @@
#CONFIG += c++11 cmdline
CONFIG += c++11
#SOURCES += \
QT -= core
QMAKE_CXXFLAGS += /permissive-
QT -= gui
TARGET = test
CONFIG += console
TEMPLATE = app
QT += core gui widgets
CORE_ROOT_DIR = $$PWD/../../../..
PWD_ROOT_DIR = $$PWD
@ -21,6 +16,13 @@ GRAPHICS_AGG_PATH = $$PWD/../../../agg-2.4
INCLUDEPATH += \
$$GRAPHICS_AGG_PATH/include
SOURCES += main.cpp
SOURCES += main.cpp \
mainwindow.cpp
DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX
FORMS += \
mainwindow.ui
HEADERS += \
mainwindow.h

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,76 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QLabel>
#include <QSizePolicy>
#include <QDir>
#include "../../../../UnicodeConverter/UnicodeConverter.h"
#include "../../pro/Graphics.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
ui->label->setFixedWidth(160);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_arFileNames = QFileDialog::getOpenFileNames(this,
"Select one or more metafiles to convert",
"",
"*.emf *.wmf *.svm *.svg");
if (!m_arFileNames.empty())
ui->label->setText("File:" + m_arFileNames[0]);
}
void MainWindow::on_pushButton_2_clicked()
{
auto save_dir = QFileDialog::getExistingDirectory(this,
"Open Directory",
"",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
NSUnicodeConverter::CUnicodeConverter converter;
for (const auto& f : m_arFileNames)
{
ui->label->setText("File:" + f);
NSFonts::IApplicationFonts* app_fonts = NSFonts::NSApplication::Create();
app_fonts->Initialize();
MetaFile::IMetaFile* meta_file = MetaFile::Create(app_fonts);
if (!meta_file->LoadFromFile(converter.toUnicode(f.toStdString(), 1).c_str()))
return;
double x, y, w, h;
meta_file->GetBounds(&x, &y, &w, &h);
if (ui->radioButton->isChecked())
meta_file->ConvertToRaster(converter.toUnicode(QDir(save_dir).filePath("res.bmp").toStdString(), 1).c_str(), 1,
static_cast<int>(w) + 1, static_cast<int>(h) + 1);
else if (ui->radioButton_2->isChecked())
meta_file->ConvertToXml(converter.toUnicode(QDir(save_dir).filePath("res.xml").toStdString(), 1).c_str());
else if (ui->radioButton_3->isChecked())
meta_file->ConvertToRaster(converter.toUnicode(QDir(save_dir).filePath("res.bmp").toStdString(), 1).c_str(), 1,
static_cast<int>(w) + 1, static_cast<int>(h) + 1,
converter.toUnicode(QDir(save_dir).filePath("res.xml").toStdString(), 1).c_str());
else if (ui->radioButton_4->isChecked())
meta_file->ConvertToSvg(static_cast<int>(w) + 1, static_cast<int>(h) + 1);
else if (ui->radioButton_5->isChecked())
meta_file->ConvertToEmf(converter.toUnicode(QDir(save_dir).filePath("res.emf").toStdString(), 1).c_str());
RELEASEOBJECT(app_fonts);
RELEASEOBJECT(meta_file);
}
}

View File

@ -0,0 +1,32 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include <QStringList>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
QStringList m_arFileNames;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>211</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>161</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Choose Metafile</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>250</x>
<y>0</y>
<width>151</width>
<height>131</height>
</rect>
</property>
<property name="title">
<string>Choose to convert</string>
</property>
<widget class="QRadioButton" name="radioButton">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Raster(.bmp)</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_2">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Xml</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_3">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>131</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Raster(.bmp) + Xml</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_4">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Svg</string>
</property>
</widget>
<widget class="QRadioButton" name="radioButton_5">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<width>91</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Emf</string>
</property>
</widget>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>450</x>
<y>60</y>
<width>80</width>
<height>24</height>
</rect>
</property>
<property name="text">
<string>Convert</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>60</x>
<y>90</y>
<width>151</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string>File: </string>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,23 @@
CONFIG += c++11
QMAKE_CXXFLAGS += /permissive-
QT += core gui widgets
SOURCES += \
main.cpp\
mainwindow.cpp
FORMS += \
mainwindow.ui
HEADERS += \
mainwindow.h
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

View File

@ -0,0 +1,97 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iterator>
#include <QImage>
#include <QPixmap>
#include <QString>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->SetColor(Qt::black);
m_oAppFonts = NSFonts::NSApplication::Create();
m_oAppFonts->Initialize();
m_oFontManager = m_oAppFonts->GenerateFontManager();
NSFonts::IFontsCache* fonts_cache = NSFonts::NSFontCache::Create();
fonts_cache->SetStreams(m_oAppFonts->GetStreams());
m_oFontManager->SetOwnerCache(fonts_cache);
for (auto it = m_oAppFonts->GetList()->GetFonts()->cbegin(); it != m_oAppFonts->GetList()->GetFonts()->cend(); it++)
ui->comboBox->addItem(QString::fromWCharArray((*it)->m_wsFontName.c_str()));
connect(ui->textEdit, &QTextEdit::textChanged, this, &MainWindow::Draw);
connect(ui->spinBox, &QSpinBox::valueChanged, this, &MainWindow::Draw);
connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::Draw);
connect(ui->checkBox, &QCheckBox::stateChanged, this, &MainWindow::Draw);
connect(ui->checkBox_2, &QCheckBox::stateChanged, this, &MainWindow::Draw);
connect(ui->pushButton, &CColorButton::ColorChanged, this, &MainWindow::Draw);
}
MainWindow::~MainWindow()
{
RELEASEOBJECT(m_oAppFonts);
RELEASEOBJECT(m_oFontManager);
delete ui;
}
void MainWindow::Draw()
{
NSGraphics::IGraphicsRenderer* renderer = NSGraphics::Create();
renderer->SetFontManager(m_oFontManager);
int width = ui->label->width(),
height = ui->label->height();
BYTE* data = new BYTE[4 * width * height];
CBgraFrame frame;
frame.put_Data(data);
frame.put_Width(width);
frame.put_Height(height);
frame.put_Stride(4 * width);
renderer->put_Width(100);
renderer->put_Height(100);
renderer->CreateFromBgraFrame(&frame);
renderer->SetSwapRGB(false);
renderer->put_FontName(ui->comboBox->currentText().toStdWString());
renderer->put_FontSize(ui->spinBox->value());
long font_style = 0;
if (ui->checkBox->isChecked())
font_style |= 0x01;
if (ui->checkBox_2->isChecked())
font_style |= 0x02;
renderer->put_FontStyle(font_style);
renderer->put_BrushColor1(ui->pushButton->GetColor().rgb());
auto lines = ui->textEdit->toPlainText().split('\n');
double x = 1.0;
double y = (ui->spinBox->value() * 25.4 / 96.0) + 3.0;
double scale_y = y;
renderer->BeginCommand(c_nTextGraphicType);
for (auto it = lines.cbegin(); it != lines.cend(); it++)
{
renderer->CommandDrawText((*it).toStdWString(), x, y, 0.0, 0.0);
y += scale_y;
}
renderer->EndCommand(c_nTextGraphicType);
QImage img = QImage(data, width, height, QImage::Format_RGBA8888, [](void *data){
delete[] (BYTE*)data;
});
ui->label->setPixmap(QPixmap::fromImage(img));
RELEASEOBJECT(renderer);
}

View File

@ -0,0 +1,80 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "../../pro/Graphics.h"
#include <QMainWindow>
#include <QPushButton>
#include <QColor>
#include <QColorDialog>
#include <QPalette>
class CColorButton final : public QPushButton
{
Q_OBJECT
public:
CColorButton(QWidget *parent = nullptr) : QPushButton(parent)
{
connect(this, &QPushButton::clicked, this, &CColorButton::onClicked);
}
~CColorButton() {}
QColor GetColor() const
{
return m_oColor;
}
void SetColor(const QColor& color)
{
if (color == m_oColor)
return;
m_oColor = color;
setStyleSheet("QPushButton { background-color : " + m_oColor.name()
+ "; border: 1px solid black; padding 10px;}");
emit ColorChanged();
}
signals:
void ColorChanged();
public slots:
void onClicked()
{
QColorDialog color_dialog;
auto color = color_dialog.getColor();
if (color.isValid())
SetColor(color);
}
private:
QColor m_oColor;
};
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void Draw();
private:
Ui::MainWindow *ui;
NSFonts::IApplicationFonts* m_oAppFonts;
NSFonts::IFontManager* m_oFontManager;
};
#endif // MAINWINDOW_H

View File

@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>390</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>130</y>
<width>450</width>
<height>200</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QTextEdit" name="textEdit">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>180</width>
<height>70</height>
</rect>
</property>
<property name="placeholderText">
<string>Hello</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>61</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Text input:</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>200</x>
<y>0</y>
<width>261</width>
<height>91</height>
</rect>
</property>
<property name="title">
<string>Brush</string>
</property>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>140</x>
<y>40</y>
<width>42</width>
<height>25</height>
</rect>
</property>
<property name="value">
<number>30</number>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>140</x>
<y>20</y>
<width>49</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Font size:</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>51</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Bold</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_2">
<property name="geometry">
<rect>
<x>60</x>
<y>70</y>
<width>51</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Italic</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>41</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Color:</string>
</property>
</widget>
<widget class="CColorButton" name="pushButton">
<property name="geometry">
<rect>
<x>200</x>
<y>40</y>
<width>31</width>
<height>24</height>
</rect>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Font:</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>121</width>
<height>24</height>
</rect>
</property>
<property name="duplicatesEnabled">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>100</y>
<width>71</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Text output:</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>CColorButton</class>
<extends>QPushButton</extends>
<header>mainwindow.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,20 @@
QT += core gui widgets
QMAKE_CXXFLAGS += /permissive-
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
PWD_ROOT_DIR = $$PWD
CORE_ROOT_DIR = $$PWD/../../../../../core
include($$CORE_ROOT_DIR/Common/base.pri)
ADD_DEPENDENCY(kernel, graphics, UnicodeConverter)
include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri)

View File

@ -33,6 +33,7 @@
#define _METAFILE_COMMON_METAFILEOBJECTS_H
#include <string>
#include <vector>
namespace MetaFile
{
@ -70,6 +71,8 @@ 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;
};

View File

@ -100,8 +100,6 @@ 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);
@ -1109,12 +1107,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 ||
@ -1219,7 +1216,41 @@ namespace MetaFile
else if (PS_JOIN_MITER == ulPenJoin)
nJoinStyle = Aggplus::LineJoinMiter;
const double dWidth = pPen->GetWidth() * m_dScaleX;
double dWidth = pPen->GetWidth();
// Повторение кода из Graphics для вычисления минимальной ширины пера
double dM11, dM12, dM21, dM22, dDx, dDy;
m_pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);
Aggplus::CMatrix oMatrix;
oMatrix.SetElements(dM11, dM12, dM21, dM22, dDx, dDy);
oMatrix.Scale(1. / m_dScaleX, 1. / m_dScaleY);
// Вычисление минимально возможной ширины пера
// # Код явялется дублированным из Graphics
const double dSqrtDet = sqrt(abs(oMatrix.Determinant()));
const double dWidthMinSize = (dSqrtDet != 0) ? (1.0 / dSqrtDet) : dWidth;
if (0 == pPen->GetWidth())
{
double dX = 0.72, dY = 0.72;
oMatrix.Invert();
oMatrix.TransformPoint(dX, dY);
dX -= oMatrix.OffsetX();
dY -= oMatrix.OffsetY();
dWidth = std::min(abs(dX), abs(dY));
}
//------------------------
else
{
dWidth *= m_dScaleX;
if (dWidth < dWidthMinSize)
dWidth = dWidthMinSize;
}
const double dMiterLimit = (0 != pPen->GetMiterLimit()) ? pPen->GetMiterLimit() : m_pFile->GetMiterLimit() * m_dScaleX;
BYTE nDashStyle = Aggplus::DashStyleSolid;
@ -1229,79 +1260,83 @@ namespace MetaFile
pPen->GetDashData(pDataDash, unSizeDash);
if (NULL != pDataDash && 0 != unSizeDash)
if ((NULL != pDataDash && 0 != unSizeDash) || PS_SOLID != ulPenStyle)
{
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
// Дублированный код из Graphics
// Без этого используется оригинальный код в Graphics, который отрисовывает уже неверно
double dDashWidth{dWidth};
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] * dNewWidth;
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
nDashStyle = Aggplus::DashStyleCustom;
}
else if (PS_SOLID != ulPenStyle)
{
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)
if (!Equals(dWidthMinSize, dWidth))
{
case PS_DASH:
{
arDashPattern.push_back(9 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
double dDet = oMatrix.Determinant();
break;
}
case PS_DOT:
{
arDashPattern.push_back(3 * dNewWidth);
arDashPattern.push_back(3 * dNewWidth);
break;
}
case PS_DASHDOT:
{
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 * 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;
}
if (fabs(dDet) < 0.0001)
dDashWidth *= dSqrtDet;
}
// -----------------------------
if (!arDashPattern.empty())
if (NULL != pDataDash && 0 != unSizeDash)
{
m_pRenderer->PenDashPattern(arDashPattern.data(), arDashPattern.size());
m_pRenderer->put_PenDashOffset(pPen->GetDashOffset());
std::vector<double> arDashes(unSizeDash);
for (unsigned int unIndex = 0; unIndex < unSizeDash; ++unIndex)
arDashes[unIndex] = pDataDash[unIndex] * dDashWidth;
m_pRenderer->PenDashPattern(arDashes.data(), unSizeDash);
nDashStyle = Aggplus::DashStyleCustom;
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
nJoinStyle = Aggplus::LineJoinMiter;
}
else
{
std::vector<double> arDashPattern;
switch (ulPenStyle)
{
case PS_DASH:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
break;
}
case PS_DOT:
{
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
break;
}
case PS_DASHDOT:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
break;
}
case PS_DASHDOTDOT:
{
arDashPattern.push_back(9 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
arDashPattern.push_back(3 * dDashWidth);
arDashPattern.push_back(6 * dDashWidth);
break;
}
}
if (!arDashPattern.empty())
{
m_pRenderer->PenDashPattern(arDashPattern.data(), arDashPattern.size());
nDashStyle = Aggplus::DashStyleCustom;
nStartCapStyle = nEndCapStyle = Aggplus::LineCapFlat;
nJoinStyle = Aggplus::LineJoinMiter;
}
}
}

View File

@ -44,7 +44,8 @@ namespace MetaFile
: r(_r), g(_g), b(_b), a(_a)
{}
TRGBA::TRGBA(int nValue) : r((nValue >> 0) & 0xFF), g((nValue >> 8) & 0xFF), b((nValue >> 16) & 0xFF), a((nValue >> 24) & 0xFF)
TRGBA::TRGBA(int nValue)
: r((nValue >> 0) & 0xFF), g((nValue >> 8) & 0xFF), b((nValue >> 16) & 0xFF), a((nValue >> 24) & 0xFF)
{}
void TRGBA::Set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a)
@ -94,7 +95,18 @@ namespace MetaFile
return a;
}
TXForm::TXForm() : M11(1), M12(0), M21(0), M22(1), Dx(0), Dy(0)
TRGBA& TRGBA::operator=(const TRGBA& oRGBA)
{
r = oRGBA.r;
g = oRGBA.g;
b = oRGBA.b;
a = oRGBA.a;
return *this;
}
TXForm::TXForm()
: M11(1), M12(0), M21(0), M22(1), Dx(0), Dy(0)
{}
TXForm::TXForm(const TXForm &oXForm)

View File

@ -558,6 +558,8 @@ namespace MetaFile
unsigned char GetGreen() const;
unsigned char GetBlue() const;
unsigned char GetAlpha() const;
TRGBA& operator=(const TRGBA& oRGBA);
};
struct TXForm

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;
@ -233,7 +237,9 @@ namespace MetaFile
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
// int nByte = *pBuffer;
++pBuffer;
--lBufLen;
}
}
}
@ -267,7 +273,9 @@ namespace MetaFile
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
// int nByte = *pBuffer;
++pBuffer;
--lBufLen;
}
}
}
@ -486,7 +494,12 @@ namespace MetaFile
}
if (lBufLen < (nWidth + nAdd) * abs(nHeight))
{
if (pUncompressedBuffer)
delete[] pUncompressedBuffer;
return false;
}
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
@ -639,7 +652,7 @@ namespace MetaFile
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return false;
return true;
}
else if (BI_BITCOUNT_5 == ushBitCount)
{
@ -986,29 +999,6 @@ namespace MetaFile
}
}
std::wstring ascii_to_unicode(const char *src)
{
size_t nSize = mbstowcs(0, src, 0);
wchar_t* pBuffer = new wchar_t[nSize];
nSize = mbstowcs(pBuffer, src, nSize);
std::wstring sRes;
if (nSize != (size_t)-1)
sRes = std::wstring(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}
std::string unicode_to_ascii(const wchar_t *src)
{
size_t nSize = wcstombs(0, src, 0);
char* pBuffer = new char[nSize];
nSize = wcstombs(pBuffer, src, nSize);
std::string sRes;
if (nSize != (size_t)-1)
sRes = std::string(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}
std::wstring GetTempFilename(const std::wstring& sFolder)
{
std::wstring sTmpFile = NSFile::CFileBinary::CreateTempFileWithUniqueName(sFolder.empty() ? NSFile::CFileBinary::GetTempPath() : sFolder, L"wmf");

View File

@ -380,16 +380,23 @@ 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}};
@ -1505,26 +1512,5 @@ namespace MetaFile
std::swap(oFirstClip, oSecondClip);
}
TRectD CEmfInterpretatorSvg::TranslateRect(const TRectL &oRect) const
{
TRectD oNewRect(oRect.Left, oRect.Top, oRect.Right, oRect.Bottom);
if (oNewRect.Right < oNewRect.Left)
{
double dTempValue = oNewRect.Left;
oNewRect.Left = oNewRect.Right;
oNewRect.Right = dTempValue;
}
if (oNewRect.Bottom < oNewRect.Top)
{
double dTempValue = oNewRect.Top;
oNewRect.Top = oNewRect.Bottom;
oNewRect.Bottom = dTempValue;
}
return oNewRect;
}
}

View File

@ -227,8 +227,6 @@ namespace MetaFile
void GetTransform(double* pdM11, double* pdM12, double* pdM21, double* pdM22, double* pdX, double* pdY) override {};
void SwapClips(CSvgClip& oFirstClip, CSvgClip& oSecondClip);
TRectD TranslateRect(const TRectL &oRect) const;
};
}

View File

@ -30,7 +30,6 @@
*
*/
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../graphics/Image.h"
#include "../Common/MetaFileUtils.h"
@ -155,6 +154,11 @@ namespace MetaFile
unHeight = unDibHeigth;
}
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)

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;

View File

@ -593,6 +593,8 @@ namespace MetaFile
if (!BanEMFProcesses())
HANDLE_EMR_CREATEBRUSHINDIRECT(ulBrushIndex, pBrush);
else
delete pBrush;
}
void CEmfParser::Read_EMR_SETTEXTCOLOR()
@ -630,6 +632,8 @@ namespace MetaFile
if (!BanEMFProcesses())
HANDLE_EMR_EXTCREATEFONTINDIRECTW(ulIndex, pFont);
else
delete pFont;
}
void CEmfParser::Read_EMR_SETTEXTALIGN()
@ -722,6 +726,8 @@ namespace MetaFile
if (!BanEMFProcesses())
HANDLE_EMR_EXTCREATEPEN(ulPenIndex, pPen, arUnused);
else
delete pPen;
}
void CEmfParser::Read_EMR_CREATEPEN()
@ -744,6 +750,8 @@ namespace MetaFile
if (!BanEMFProcesses())
HANDLE_EMR_CREATEPEN(ulPenIndex, widthX, pPen);
else
delete pPen;
}
void CEmfParser::Read_EMR_SETPOLYFILLMODE()
@ -1011,6 +1019,8 @@ namespace MetaFile
if (!BanEMFProcesses())
HANDLE_EMR_CREATEPALETTE(ulPaletteIndex, pPalette);
else
delete pPalette;
}
void CEmfParser::Read_EMR_SELECTPALETTE()

View File

@ -763,7 +763,7 @@ namespace MetaFile
if (InterpretatorType::Svg == oInterpretatorType)
{
CEmfInterpretatorSvg *pEmfInterpretatorSvg = new CEmfInterpretatorSvg(this, dWidth, dHeight);
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::CrispEdges);
pEmfInterpretatorSvg->SetShapeRendering(EShapeRendering::OptimizeSpeed);
m_pInterpretator = pEmfInterpretatorSvg;
}
}
@ -1509,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

@ -1,10 +1,6 @@
#ifndef CEMFPARSERBASE_H
#define CEMFPARSERBASE_H
//#include "../EmfTypes.h"
//#include "../EmfObjects.h"
//#include "../../Common/MetaFileUtils.h"
#include "../EmfPlayer.h"
#include "../../Common/MetaFile.h"

View File

@ -67,15 +67,11 @@
#define EMFPLUS_TRANSLATEWORLDTRANSFORM 0x402D
#include <map>
#include <iostream>
#include "CEmfParser.h"
#include "../../Wmf/WmfFile.h"
#include "../../Wmf/WmfInterpretator/CWmfInterpretatorSvg.h"
#include "../EmfInterpretator/CEmfInterpretator.h"
#include "../EmfInterpretator/CEmfInterpretatorSvg.h"
#include "../EmfInterpretator/CEmfInterpretatorArray.h"
#include "../EmfInterpretator/CEmfInterpretatorRender.h"
#ifdef METAFILE_SUPPORT_WMF_EMF_XML
@ -655,20 +651,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.back() .first;
pEmfPlusBrush->oColorBack = pEmfPlusBrush->arGradientColors.front().first;
}
}
@ -679,13 +673,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:
@ -750,7 +771,7 @@ namespace MetaFile
switch (nEndCap)
{
case 0: pEmfPlusPen->unStyle |= PS_ENDCAP_MASK & PS_ENDCAP_FLAT; break;
case 0: pEmfPlusPen->unStyle |= PS_ENDCAP_MASK & PS_ENDCAP_FLAT; break;
case 1: pEmfPlusPen->unStyle |= PS_ENDCAP_MASK & PS_ENDCAP_SQUARE; break;
case 2: pEmfPlusPen->unStyle |= PS_ENDCAP_MASK & PS_ENDCAP_ROUND; break;
}
@ -763,7 +784,7 @@ namespace MetaFile
switch (nJoin)
{
case 0: pEmfPlusPen->unStyle |= PS_JOIN_MASK & PS_JOIN_MITER; break;
case 0: pEmfPlusPen->unStyle |= PS_JOIN_MASK & PS_JOIN_MITER; break;
case 1: pEmfPlusPen->unStyle |= PS_JOIN_MASK & PS_JOIN_BEVEL; break;
case 2: pEmfPlusPen->unStyle |= PS_JOIN_MASK & PS_ENDCAP_ROUND; break;
}
@ -849,7 +870,7 @@ namespace MetaFile
m_oStream >> *pLineCapData;
if (CustomLineCapDataFillPath == pLineCapData->unCustomLineCapDataFlags ||
CustomLineCapDataLinePath == pLineCapData->unCustomLineCapDataFlags)
CustomLineCapDataLinePath == pLineCapData->unCustomLineCapDataFlags)
{
m_oStream.Skip(4); // FillPathLength or LinePathLength
pLineCapData->pPath = ReadPath();
@ -1321,7 +1342,7 @@ namespace MetaFile
if (oImageAttributes.eWrapMode == WrapModeClamp)
{
if (oRectangle.dX < 0 || oRectangle.dX < 0 ||
oRectangle.dX >= oRectangle.dWidth || oRectangle.dY >= oRectangle.dHeight)
oRectangle.dX >= oRectangle.dWidth || oRectangle.dY >= oRectangle.dHeight)
return oImageAttributes.oClampColor;
}
@ -1519,14 +1540,10 @@ namespace MetaFile
case MetafileDataTypeEmf:
case MetafileDataTypeEmfPlusOnly:
case MetafileDataTypeEmfPlusDual:
{
return DrawMetafile<CEmfParser>(pBuffer, unSizeBuffer, oSrcRect, arPoints);
}
case MetafileDataTypeWmf:
case MetafileDataTypeWmfPlaceable:
{
return DrawMetafile<CWmfParser>(pBuffer, unSizeBuffer, oSrcRect, arPoints);
}
}
}
}
@ -1639,7 +1656,7 @@ namespace MetaFile
BYTE* pNewBuffer = GetClipedImage(pPixels, nWidth, nHeight, oClipRect, nW, nH);
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X - m_pDC->GetPixelWidth(), arPoints[2].Y - arPoints[0].Y - m_pDC->GetPixelHeight(),
(NULL != pNewBuffer) ? pNewBuffer : pPixels, nW, nH);
(NULL != pNewBuffer) ? pNewBuffer : pPixels, nW, nH);
RELEASEINTERFACE(pGrRenderer);
RELEASEARRAYOBJECTS(pNewBuffer);
@ -1718,7 +1735,7 @@ namespace MetaFile
BYTE* pNewBuffer = GetClipedImage(pBytes, unWidth, unHeight, oClipRect, nW, nH);
m_pInterpretator->DrawBitmap(arPoints[0].X, arPoints[0].Y, arPoints[1].X - arPoints[0].X, arPoints[2].Y - arPoints[0].Y,
(NULL != pNewBuffer) ? pNewBuffer : pBytes, nW, nH);
(NULL != pNewBuffer) ? pNewBuffer : pBytes, nW, nH);
if (!bExternalBuffer)
RELEASEARRAYOBJECTS(pBytes);
@ -1781,17 +1798,15 @@ namespace MetaFile
m_pDC->SetPen(pPen);
if (AD_COUNTERCLOCKWISE != m_pDC->GetArcDirection())
{
dSweepAngle = dSweepAngle - 360;
}
TEmfPlusRectF oConvertedRect = GetConvertedRectangle(oRect);
MoveTo(oConvertedRect.dX, oConvertedRect.dY);
ArcTo(oConvertedRect.dX, oConvertedRect.dY,
oConvertedRect.dX + oConvertedRect.dWidth,
oConvertedRect.dY + oConvertedRect.dHeight,
dStartAngle, dSweepAngle);
oConvertedRect.dX + oConvertedRect.dWidth,
oConvertedRect.dY + oConvertedRect.dHeight,
dStartAngle, dSweepAngle);
DrawPath(true, false);
if (NULL != m_pInterpretator)
@ -2268,13 +2283,13 @@ namespace MetaFile
if (NULL != m_pInterpretator)
{
CPathConverter oPathConverter;
CPath oNewPath, oLineCapPath;
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
if (InterpretatorType::Render == m_pInterpretator->GetType())
{
CPathConverter oPathConverter;
CPath oNewPath, oLineCapPath;
oPathConverter.GetUpdatedPath(oNewPath, oLineCapPath, *pPath, *pEmfPlusPen);
oNewPath.DrawOn(m_pInterpretator, true, false);
oLineCapPath.DrawOn(m_pInterpretator, false, true);
}
@ -2811,7 +2826,7 @@ namespace MetaFile
void CEmfPlusParser::Read_EMFPLUS_FILLREGION(unsigned short unShFlags)
{
short shOgjectIndex = ExpressValue(unShFlags, 0, 7);
// short shOgjectIndex = ExpressValue(unShFlags, 0, 7);
unsigned int unBrushId;
m_oStream >> unBrushId;
@ -2970,34 +2985,34 @@ namespace MetaFile
void CEmfPlusParser::Read_EMFPLUS_SETANTIALIASMODE(unsigned short unShFlags)
{
short shSmoothingMode = ExpressValue(unShFlags, 1, 7);
// short shSmoothingMode = ExpressValue(unShFlags, 1, 7);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMFPLUS_SETCOMPOSITINGMODE(unsigned short unShFlags)
{
short shCompositingMode = ExpressValue(unShFlags, 0, 7);
// short shCompositingMode = ExpressValue(unShFlags, 0, 7);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMFPLUS_SETCOMPOSITINGQUALITY(unsigned short unShFlags)
{
short shCompositingQuality = ExpressValue(unShFlags, 0, 7);
// short shCompositingQuality = ExpressValue(unShFlags, 0, 7);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMFPLUS_SETINTERPOLATIONMODE(unsigned short unShFlags)
{
short shInterpolationMode = ExpressValue(unShFlags, 0, 7);
// short shInterpolationMode = ExpressValue(unShFlags, 0, 7);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMFPLUS_SETPIXELOFFSETMODE(unsigned short unShFlags)
{
short shPixelOffsetMode = ExpressValue(unShFlags, 0, 7);
// short shPixelOffsetMode = ExpressValue(unShFlags, 0, 7);
//TODO: реализовать
}
@ -3014,20 +3029,20 @@ namespace MetaFile
void CEmfPlusParser::Read_EMFPLUS_SETTEXTCONTRAST(unsigned short unShFlags)
{
short shTextContrast = ExpressValue(unShFlags, 0, 11);
// short shTextContrast = ExpressValue(unShFlags, 0, 11);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMRPLUS_SETTEXTRENDERINGHINT(unsigned short unShFlags)
{
short shTextRenderingHint = ExpressValue(unShFlags, 0, 7);
// short shTextRenderingHint = ExpressValue(unShFlags, 0, 7);
//TODO: реализовать
}
void CEmfPlusParser::Read_EMFPLUS_BEGINCONTAINER(unsigned short unShFlags)
{
short shPageUnit = ExpressValue(unShFlags, 8, 15);
// short shPageUnit = ExpressValue(unShFlags, 8, 15);
TEmfPlusRectF oDestRect, oSrcRect;
unsigned int unStackIndex;

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