Compare commits

...

287 Commits

Author SHA1 Message Date
211557cc7a delayed binary 2026-03-25 19:32:33 +03:00
9a4f929510 fix build 2026-03-25 19:02:05 +03:00
206ee9c976 Transparency Group for stamp 2026-03-25 14:41:43 +03:00
7a8669d7f8 Merge remote-tracking branch 'origin/feature/pdf-annots' into develop 2026-03-25 13:42:10 +03:00
ea28ff69a9 Write stamp opacity to AP 2026-03-25 13:28:44 +03:00
88626378a7 Create IgnoreStampOpacity for drawingfile 2026-03-25 12:52:31 +03:00
23e736051f Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-03-24 15:06:48 +03:00
8870516a8a Fix bug 68012 2026-03-23 16:07:38 +03:00
dbe56878b1 fix drawing conversion 2026-03-23 18:18:23 +06:00
84aa409b1e Merge branch 'develop' into feature/add-xls-writing 2026-03-23 13:06:49 +06:00
8fa5f8944e Fix bug 56081 2026-03-20 14:56:53 +03:00
27dc6403d7 add several image conversion 2026-03-20 17:50:25 +06:00
ecaef0fbed fix drawing group pict conversion 2026-03-19 20:48:49 +06:00
2addc5a3d8 fix bstoreContainer size 2026-03-19 18:21:34 +06:00
4e1afe5c55 add file blip store entry writin 2026-03-19 16:49:36 +06:00
9ae5855ed0 refactor drawing generation methods 2026-03-18 16:26:40 +06:00
8d4e216852 Link RD read and write 2026-03-18 10:42:20 +03:00
866bf08da3 Merge pull request 'Fix bug 80655' (#727) from fix/bug-80655 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/727
2026-03-17 18:36:25 +00:00
9e1bb2cd22 Fix bug 80655 2026-03-17 21:30:04 +03:00
bb97d00ae7 add imageWriting 2026-03-17 18:51:26 +06:00
66eaed4f18 Merge remote-tracking branch 'origin/feature/pdf-screen' into develop 2026-03-16 15:55:29 +03:00
4739b9f9dd Merge remote-tracking branch 'origin/develop' into feature/pdf-screen 2026-03-16 15:54:10 +03:00
e8f1691348 Write FileAttachment annot 2026-03-16 15:48:12 +03:00
0b42267c43 Merge pull request 'fix bug #68331' (#726) from fix/bug68331 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/726
2026-03-16 12:20:22 +00:00
6f1bfc3064 Merge pull request 'fix/bug79255' (#725) from fix/bug79255 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/725
2026-03-16 12:19:35 +00:00
f57f573ac4 fix bug #79471 2026-03-16 14:20:41 +03:00
0579b93796 fix bug #79255 2026-03-16 14:10:11 +03:00
2074785963 add cell anchor writing for pics 2026-03-13 21:55:00 +06:00
ed697edba2 add pic conversion method 2026-03-13 20:43:39 +06:00
686c72a1c8 Write Screen annot 2026-03-13 15:21:54 +03:00
41124d3301 pdf write Screen and FileAttachment annots 2026-03-13 13:37:33 +03:00
95d6c6c927 Merge branch 'release/v9.4.0' into feature/add-xls-writing 2026-03-13 14:22:03 +06:00
9ae76b07a1 fix bug #79246 2026-03-13 10:39:01 +03:00
da769a642b Merge branch hotfix/v9.3.1 into release/v9.4.0 2026-03-12 15:19:51 +00:00
0d7e535114 Merge branch hotfix/v9.3.1 into develop 2026-03-12 15:19:49 +00:00
e0af1357e5 Merge pull request 'for bug #80497' (#723) from fix/bmpConversion into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/723
2026-03-12 13:58:54 +00:00
d4f80ea036 for bug #80497 2026-03-12 19:55:56 +06:00
8e90fbac69 pdf read Screen annots 2026-03-12 15:31:41 +03:00
12083ae8c9 Merge pull request 'Fix bugs 75897, 80163' (#722) from fix/pdf-bug into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/722
2026-03-12 12:29:03 +00:00
322fda0e07 fix bug #71064 2026-03-12 15:28:28 +03:00
b0d70ff38a Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-03-12 14:34:08 +03:00
2a409336a3 fix multiple comment writing 2026-03-12 17:15:03 +06:00
6819a41452 Fix bug 75897 2026-03-12 14:06:57 +03:00
4cdc416e0b fix bug #79301 2026-03-12 12:34:51 +03:00
5d5732161a Fix bug 80163 2026-03-12 11:11:32 +03:00
7046f1d465 Merge pull request 'fix/bug73640' (#721) from fix/bug73640 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/721
2026-03-11 15:17:16 +00:00
61f25af847 fix/bug73640
fix bug #73640
2026-03-11 18:13:45 +03:00
9304d10674 Merge remote-tracking branch 'origin/release/v9.4.0' into develop 2026-03-11 18:12:11 +03:00
21dd6c2a61 Merge pull request 'fix prev hr' (#720) from fix/fix-bugs into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/720
2026-03-11 15:11:31 +00:00
278dffc7c7 fix bug #80491 2026-03-11 18:11:16 +03:00
b607aeb4c6 fix prev hr 2026-03-11 18:08:12 +03:00
bd7aa2df96 Add multiple comment writing 2026-03-11 19:17:02 +06:00
3d4dc3116e fix comment conversion 2026-03-11 18:14:51 +06:00
f2fdcf4efd Merge branch 'develop' into fix/bug73640 2026-03-11 11:51:07 +03:00
ae7dbf291f Merge remote-tracking branch 'origin/release/v9.4.0' into develop 2026-03-10 19:49:07 +03:00
cb0176ecca add comment writing 2026-03-10 21:00:46 +06:00
e1b3fe270a Merge pull request 'fix/fix-bugs' (#719) from fix/fix-bugs into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/719
2026-03-10 12:33:19 +00:00
615cf0982d fix hr in odf 2026-03-10 10:52:20 +03:00
b75afead99 Merge pull request 'fix/bug59695' (#717) from fix/bug45616 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/717
2026-03-10 07:12:08 +00:00
290a134cdb Reapply "fix/bug59695"
This reverts commit 6d9a2e0d09.
2026-03-10 10:06:11 +03:00
6d9a2e0d09 Revert "fix/bug59695"
This reverts commit 32c4964cca.
2026-03-10 10:05:45 +03:00
32c4964cca fix/bug59695
fix bug #59695
2026-03-10 10:01:08 +03:00
a027644bf0 fix hr 2026-03-09 21:51:31 +03:00
9983161e3d Merge branch 'hotfix/v9.3.1' of https://git.onlyoffice.com/ONLYOFFICE/core into hotfix/v9.3.1 2026-03-09 21:14:43 +03:00
33c4b5130e Revert missed file 2026-03-09 21:14:26 +03:00
c2dd7b5108 fix bug #68331 2026-03-09 19:06:21 +03:00
0101774675 Fix safeUrl method 2026-03-09 13:35:40 +03:00
de9709ea50 Fix fromUnicode on ios 2026-03-09 13:35:02 +03:00
22e7c5bed4 Change download method 2026-03-06 23:25:00 +03:00
11000aa465 Merge pull request 'fix/bug79974' (#715) from fix/bug79974 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/715
2026-03-05 19:59:28 +00:00
eada4b4ebe Merge pull request 'fix/bug79818' (#714) from fix/bug79818 into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/714
2026-03-05 14:51:33 +00:00
6630a882ed Merge remote-tracking branch 'origin/release/v9.4.0' into develop 2026-03-05 17:23:02 +03:00
e20143fa2e for bug #66794 2026-03-05 17:17:18 +03:00
57ca5da2c0 fix/bug79818
fix bug #79818
2026-03-05 13:36:32 +03:00
08bad0753a Merge pull request 'Fix bug 80374' (#713) from fix/bug80374 into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/713
2026-03-05 10:11:56 +00:00
6224b6384d Fix prev 2026-03-05 12:59:26 +03:00
be1aed4cae Fix bug 80374 2026-03-05 12:27:40 +03:00
e40603df61 add chart file check 2026-03-05 15:22:33 +06:00
6d0db29975 Merge remote-tracking branch 'origin/develop' into fix/bug80407 2026-03-05 11:26:26 +03:00
a43af51577 . 2026-03-04 20:16:08 +03:00
cf0f2be204 fix axis conversion 2026-03-04 20:09:47 +06:00
44e3e77631 refactoring 2026-03-04 16:59:25 +03:00
e4df8df318 fix drawing conversion 2026-03-04 15:18:34 +06:00
3676400e66 Merge branch release/v9.3.0 into release/v9.4.0 2026-03-04 09:17:05 +00:00
573b85932f Merge branch release/v9.3.0 into hotfix/v9.3.1 2026-03-04 09:17:03 +00:00
eca98f612c Merge branch release/v9.3.0 into develop 2026-03-04 09:17:01 +00:00
3b0c9cea7e Merge pull request 'Fix swap rgba for djvu' (#711) from fix/bug-75351 into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/711
2026-03-03 13:34:27 +00:00
3dc0f482c8 Fix swap rgba for djvu 2026-03-03 16:21:20 +03:00
e429ff685f Merge branch 'release/v9.4.0' into feature/add-xls-writing 2026-03-03 17:14:06 +06:00
03334267c9 fix table conversion 2026-03-03 16:54:16 +06:00
417c3a55ec Merge branch 'hotfix/v9.3.1' into develop 2026-03-03 11:07:46 +03:00
90eb06ac20 fix/bug73635
fix bug #73635

(cherry picked from commit 84b2849f53730af5f544c8245800da4478e95463)
2026-03-02 20:58:39 +03:00
031c1c91e6 fix bug #80407 2026-03-02 18:31:45 +03:00
d17c22772f Merge pull request 'Fix bug 80395' (#708) from fix/bug-80395 into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/708
2026-03-02 14:21:35 +00:00
2a09f9da90 Fix bug 80395 2026-03-02 17:05:50 +03:00
8a8e17562b fix defined names conversion 2026-03-02 19:17:40 +06:00
52f8640b10 Merge pull request 'fix prev' (#707) from fix/fix-bugs into hotfix/v9.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/707
2026-03-02 10:46:12 +00:00
9f36c04d33 fix title pos 2026-03-02 15:56:10 +06:00
8a1a45f403 fix prev 2026-03-02 10:04:34 +03:00
7dffc8245a Merge remote-tracking branch 'origin/hotfix/v9.3.1' into develop 2026-02-28 11:07:16 +03:00
869774bcc1 fix/bug79974
fix bug #79974
2026-02-27 18:59:52 +03:00
27103958fe add default theme clrs to chart 2026-02-27 20:44:47 +06:00
2b46e0251f Merge pull request 'fix for prev binary' (#705) from fix/fix-bugs into hotfix/v9.3.1
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/705
2026-02-27 13:42:47 +00:00
078a58772c fix for prev binary 2026-02-27 16:37:30 +03:00
95c9c95a2e fix chartsheet conversion 2026-02-27 17:43:23 +06:00
1753007900 Merge pull request 'Fix bug 80293' (#704) from fix/bug80293 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/704
2026-02-27 08:55:33 +00:00
f43230dcaf Fix bug 80293 2026-02-27 11:45:55 +03:00
df576b6e99 Merge pull request 'fix/fix-bugs' (#703) from fix/fix-bugs into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/703
2026-02-26 15:23:19 +00:00
bb7d2ce8ee Merge pull request 'fix/bug79307' (#702) from fix/bug79307 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/702
2026-02-26 14:57:59 +00:00
ed8a47cbb7 fix/bug79307
fix bug #79307
2026-02-26 17:27:18 +03:00
3c707ebbf4 Fix bug 78204 2026-02-26 15:44:32 +03:00
3b2721e2da fix/bug79307
fix bug #79307
2026-02-26 15:15:23 +03:00
b430c3f296 fix bug #78514 2026-02-26 14:26:41 +03:00
c21827825b fix bug #79266 2026-02-26 13:22:58 +03:00
19c66750a8 fix/bug79307
fix bug #79307
2026-02-25 23:09:05 +03:00
0424c73db0 Merge pull request 'fix/fix-bugs' (#700) from fix/fix-bugs into release/v9.4.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/700
2026-02-25 16:54:14 +00:00
dc6a72892c Merge branch 'release/v9.4.0' into fix/fix-bugs 2026-02-25 19:47:12 +03:00
4b61f6e62a Merge branch 'release/v9.4.0' into feature/add-xls-writing 2026-02-25 22:36:59 +06:00
927f49291a Merge branch release/v9.3.0 into develop 2026-02-25 15:14:16 +00:00
72b57be353 fix numFmt conversion 2026-02-25 18:01:46 +06:00
ef295fc115 fix aboveAverage condFmt conversion 2026-02-25 16:36:39 +06:00
a62528e90e fix category axis conversion 2026-02-24 20:59:14 +06:00
d54f0326cd Merge branch release/v9.3.0 into master 2026-02-24 14:07:21 +00:00
269dd9b8bc Merge pull request 'Fix bugs 80287, 80300, 80281' (#699) from fix/bug-80287 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/699
2026-02-24 14:00:15 +00:00
9da0b82ead Fix bug 80281 2026-02-24 16:45:55 +03:00
e3334cbea5 Fix bug 80300 2026-02-24 14:27:45 +03:00
01c928c724 Fix bug 80287 2026-02-24 13:41:01 +03:00
cf72c836a1 fix bug #79708 2026-02-24 12:33:36 +03:00
b9a905f6b2 fix bug #80221 2026-02-24 11:37:37 +03:00
644ec4e651 fix separate chart conversion 2026-02-24 14:05:03 +06:00
e5c1dc4bc3 Merge pull request 'fix bug #79951' (#698) from fix/fix_bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/698
2026-02-23 16:20:47 +00:00
2c5cd93ac5 fix bug #79951 2026-02-23 19:14:03 +03:00
1ff1334746 Merge pull request 'Fix bugs 80285, 80286' (#697) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/697
2026-02-23 15:13:03 +00:00
de096d4229 Fix bug 80286 2026-02-23 17:58:42 +03:00
6c9d795167 Fix bug 80285 2026-02-23 15:39:09 +03:00
8116322018 Fix build on windows 2026-02-23 08:18:44 +03:00
5428c28874 Fix bug 80220 2026-02-23 02:50:05 +03:00
e389b4d799 Merge pull request 'Fix memory init' (#696) from fix/pict into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/696
2026-02-22 19:59:27 +00:00
8c607a429a Fix memory init 2026-02-22 22:55:54 +03:00
00e80b68f6 Merge pull request 'For bug 79086' (#695) from fix/pict into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/695
2026-02-22 19:46:58 +00:00
377317892d For bug 79086 2026-02-22 22:41:43 +03:00
ef77688ea2 Merge pull request 'For bug 80280' (#694) from fix/bug-80280 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/694
2026-02-22 17:26:59 +00:00
eb756fab5c For bug 80280 2026-02-22 20:20:53 +03:00
2d2bb7cee7 Merge pull request 'Fix stroke with images' (#693) from fix/docx-renderer into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/693
2026-02-20 17:25:52 +00:00
1abe5b2dcc Fix stroke with images 2026-02-20 20:22:03 +03:00
2b4bdfdc05 Merge pull request 'Fix paragraph line spacing' (#692) from fix/docx-renderer into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/692
2026-02-20 16:13:46 +00:00
007c70bcc0 Fix paragraph line spacing 2026-02-20 19:11:20 +03:00
017b43dd66 Merge pull request 'fix bug #80155' (#691) from fix/fix-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/691
2026-02-20 14:40:36 +00:00
88a6760086 fix bug #80155 2026-02-20 17:39:07 +03:00
98a0551123 Merge pull request 'fix/bug80153' (#690) from fix/bug80153 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/690
2026-02-20 14:36:15 +00:00
6ca34d9c69 fix several charts conversion 2026-02-20 19:20:59 +06:00
49cb1cdbca fix/bug80153
fix bug #80153 and #80152
2026-02-20 14:39:17 +03:00
73e00a5096 Merge pull request 'fix bug #80011' (#689) from fix/bug80011 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/689
2026-02-20 11:11:46 +00:00
462eeda60c fix bug #80011 2026-02-20 12:22:26 +03:00
e1f81b6830 Merge pull request 'Fix bug 80240' (#688) from fix/bug-80240 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/688
2026-02-20 08:39:06 +00:00
d63a6e2ba4 Fix buf 80240 2026-02-20 11:35:44 +03:00
b9cf1bd204 Merge pull request 'Fix bug #80228' (#687) from fix/bug-80228 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/687
2026-02-20 08:04:03 +00:00
81ec569f59 Fix bug #80228 2026-02-20 03:55:40 +03:00
236913f902 Merge pull request 'Fix default CheckBox border style' (#686) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/686
2026-02-19 14:52:53 +00:00
2a6d9faaf8 Fix default CheckBox border style 2026-02-19 17:49:30 +03:00
7a78e1bbc6 Merge pull request 'Fix bug 80175' (#685) from fix/bug-80175 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/685
2026-02-19 14:30:24 +00:00
f2db0df9f5 Fix bug 80175 2026-02-19 17:26:01 +03:00
c2dfac0d27 Merge pull request 'Fix bug 77348' (#684) from fix/bug-77348 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/684
2026-02-19 11:55:58 +00:00
902497b299 Fix CropBox offset 2026-02-19 14:38:33 +03:00
473f6aef1e add several chart conversion 2026-02-19 16:58:22 +06:00
35aa329619 Fix MediaBox offset 2026-02-19 13:10:45 +03:00
6ace9b1cc5 Fix bug 77348 2026-02-19 13:09:50 +03:00
f6bc46c551 Merge pull request 'fix/bug80151' (#680) from fix/bug80151 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/680
2026-02-18 16:44:28 +00:00
790049d14a Merge pull request 'fix/bug79610' (#682) from fix/bug79610 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/682
2026-02-18 15:27:50 +00:00
ccc9f8f91f Merge pull request 'Fix bug 78772' (#681) from fix/bug78772 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/681
2026-02-18 15:05:22 +00:00
f2eace2b53 Merge pull request 'fix/bug80009' (#679) from fix/bug80009 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/679
2026-02-18 15:04:52 +00:00
dfe7a64e1a fix/bug79610 2026-02-18 16:33:49 +03:00
65f89c1e4b fix/bug79610
fix bug #79610
2026-02-18 16:32:15 +03:00
ea7ff62816 Fix bug 78772 2026-02-18 16:08:04 +03:00
4ac45f41cb fix bug #80011 2026-02-18 15:32:27 +03:00
947e5a1f5d fix bug #80151 2026-02-18 15:31:35 +03:00
3e724e6164 fix/bug80009
fix bug #80009
2026-02-18 11:59:26 +03:00
8ef0713adc Merge pull request 'fix bug #80172' (#678) from fix/fix-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/678
2026-02-18 07:37:33 +00:00
2f74b3b69b fix bug #80172 2026-02-18 10:30:46 +03:00
7ce71b6f5d Merge pull request 'fix/fix-bugs' (#677) from fix/fix-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/677
2026-02-18 06:28:02 +00:00
9b5847e653 for bug #76556 2026-02-17 22:36:15 +03:00
d81e26eff7 fix bug #80155 2026-02-17 22:11:25 +03:00
67e987e389 Merge pull request 'Fix bug 80103' (#676) from fix/bug80103 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/676
2026-02-17 15:08:26 +00:00
bc91106ea4 Merge pull request 'Fix right postiton via width in font' (#675) from fix/docx-renderer into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/675
2026-02-17 13:44:18 +00:00
d91a19cbc2 Fix right postiton via width in font 2026-02-17 16:17:26 +03:00
970720575a Fix bug 80103 2026-02-17 14:51:18 +03:00
85027065e6 Add drawing group conversion 2026-02-17 15:01:53 +06:00
f11045c87f Merge pull request 'Fix bugs in html to md conversion' (#674) from fix/html2md into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/674
2026-02-17 07:14:42 +00:00
70e819c56b Added a new constructor to CStringBuilder 2026-02-17 01:52:35 +03:00
5a662b3567 Fix bug #80116 2026-02-17 01:51:21 +03:00
0f920531ac Fix bugs in html2md conversion 2026-02-16 22:25:31 +03:00
84d3ea7a21 Fix bug #80121 2026-02-16 20:16:50 +03:00
4893ff96fd Fix bug in html2md conversion 2026-02-16 18:45:44 +03:00
6a7791ae0a Fix bug #80119 2026-02-16 18:23:37 +03:00
78ac7bb427 Refactoring 2026-02-16 17:50:54 +03:00
8180a20cb8 Fix bug #80112 2026-02-16 17:37:59 +03:00
eb51861f39 fix bug #80117 2026-02-16 17:36:32 +03:00
e4cc737c38 . 2026-02-16 16:14:00 +03:00
f66c646c2c add drawingGroup writing 2026-02-16 19:00:09 +06:00
6c89a66b3d Merge pull request 'Fix set Kids for widget Parents' (#672) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/672
2026-02-16 12:49:12 +00:00
b127bd3ac1 Fix set Kids for widget Parents 2026-02-16 15:42:50 +03:00
0cca75b662 fix build 2026-02-16 15:39:29 +03:00
08dc0c99cf Merge pull request 'for bug #54521' (#579) from fix/bug54521 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/579
2026-02-16 09:47:25 +00:00
d2af89a2f6 Merge pull request 'fix bug #80011' (#670) from fix/bug80011 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/670
2026-02-16 09:46:48 +00:00
836787f151 fix bug #80012 2026-02-16 12:18:20 +03:00
eb78332705 Merge pull request 'Fix bug 80093' (#671) from fix/bug-80093 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/671
2026-02-16 09:17:27 +00:00
f232d0ca51 Fix bug 80093 2026-02-16 12:11:25 +03:00
24d436fb9c fix bug #80011 2026-02-15 20:48:31 +03:00
1d362cf69a Merge remote-tracking branch 'origin/feature/add-xls-writing' into release/v9.3.0 2026-02-15 16:45:38 +03:00
6c0326d660 Merge pull request 'fix/bug79610' (#669) from fix/bug79610 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/669
2026-02-14 19:23:55 +00:00
4400c9d4f4 Api => Asc.editor 2026-02-14 00:07:22 +03:00
71c7d25c9e fix/bug79610
fix bug #79610
2026-02-13 22:41:51 +03:00
ab1dd7a48b fix/bug79610
fix bug #79610
2026-02-13 22:34:41 +03:00
6e3d625420 Merge pull request 'fix/docx-renderer' (#668) from fix/docx-renderer into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/668
2026-02-13 16:11:11 +00:00
ebb0eb8136 Merge pull request 'Add signature info' (#667) from fix/pdf-signature into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/667
2026-02-13 15:24:55 +00:00
10f34fb67d Add signature info 2026-02-13 18:17:25 +03:00
98d2f62f9e Fix paragraphs splits with overlapping text lines 2026-02-13 18:07:58 +03:00
096df8fc31 Fix logic with paragraph lines 2026-02-13 16:48:47 +03:00
a7886c5cd6 Fix bugs 2026-02-13 15:27:18 +03:00
ee6ea683d1 Added definition of md text styles from html styles 2026-02-13 15:06:39 +03:00
9343f73818 Merge pull request 'Fix bug 80055' (#666) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/666
2026-02-13 11:53:56 +00:00
61aeb6f386 Fixed a bug with the initial number of the list element 2026-02-13 14:41:10 +03:00
06e8d136bf Merge pull request 'To Markdown conversion' (#660) from feature/html2md into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/660
2026-02-13 11:28:47 +00:00
c1d649b506 Fix bug 80055 2026-02-13 14:23:53 +03:00
4386e9c794 Fix shape merging 2026-02-12 23:12:00 +03:00
4900305b4a Merge branch 'release/v9.3.0' of https://git.onlyoffice.com/ONLYOFFICE/core into release/v9.3.0 2026-02-12 18:32:29 +03:00
e1f923c593 fix bug #79470 2026-02-12 18:32:03 +03:00
07ef2269ac Merge pull request 'For bug 80007' (#665) from fix/bug-80007 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/665
2026-02-12 15:31:48 +00:00
cf44441645 For bug 80007 2026-02-12 18:29:43 +03:00
7157d209d7 add worksheet drawing conversion 2026-02-12 20:02:41 +06:00
64a560679c add cell anchor pos getter 2026-02-12 18:29:29 +06:00
2682e49090 fix drawing conversion 2026-02-12 18:28:28 +06:00
7fd4219ff4 add clientAnchorSheet writing 2026-02-12 16:35:48 +06:00
4f9c229f77 Merge pull request 'Fix bug 79949' (#664) from fix/bug-79949 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/664
2026-02-12 09:10:37 +00:00
6d8454c39d Fix bug 79949 2026-02-12 12:03:08 +03:00
58deecba88 Merge pull request 'Fix bug #79894' (#663) from fix/bug-79894 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/663
2026-02-11 16:06:57 +00:00
1940bc53f7 Fix bug #79894 2026-02-11 18:58:35 +03:00
a6ac765676 add office art client data writing 2026-02-11 21:24:12 +06:00
08624e8334 Merge pull request 'Fix bug 79999' (#662) from fix/pdf-bugs into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/662
2026-02-11 14:59:29 +00:00
1f078c8c49 Merge pull request 'Fix bug 79885' (#661) from fix/bug-79885 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/661
2026-02-11 14:53:51 +00:00
e6036b37be Fix bug 79885 2026-02-11 17:51:17 +03:00
04f1c30036 The possible md conversion formats have been expanded 2026-02-11 17:44:05 +03:00
86f84f89de Fix bugs in html2md conversion 2026-02-11 17:30:42 +03:00
17b80ac96e fix bug #79968 2026-02-11 17:00:25 +03:00
710bfef301 Add clientAnchor writing 2026-02-11 17:32:08 +06:00
aa75825a73 Fix bug 79999 2026-02-11 13:53:29 +03:00
f74caacbd0 Merge pull request 'fix/bug56564' (#659) from fix/bug56564 into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/659
2026-02-11 10:50:48 +00:00
4d903b58b8 fix/bug56564
fix bug #56564
2026-02-11 13:45:41 +03:00
6434965f09 Merge pull request 'Fix pdf signature' (#658) from fix/pdf-signature into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/658
2026-02-11 09:03:17 +00:00
f60f957d00 Fix comment 2026-02-11 11:58:04 +03:00
bad5b172d5 Fix x2t 2026-02-11 11:37:55 +03:00
7b6f29a5f0 Merge pull request 'HTML to Markdown' (#657) from feature/html2md into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/657
2026-02-11 07:59:58 +00:00
b5e1cf9d06 Change PrepareSignature 2026-02-11 10:03:50 +03:00
0f73b2aa8b Added html to md conversion in x2t 2026-02-10 22:34:04 +03:00
e3b5d72ec8 add client anchor writing 2026-02-10 21:43:50 +06:00
1417b4bbd4 add embedded chartsheet substream writing 2026-02-10 18:26:39 +06:00
b850450c25 Fix build 2026-02-10 03:42:13 +03:00
098d40d44f Modification of the html converter 2026-02-10 02:18:38 +03:00
8a406c9612 fix value axis conversion 2026-02-09 19:44:40 +06:00
3a004e8495 fix scatter chart conversion 2026-02-09 17:47:16 +06:00
404748ec5a fix axis conversion 2026-02-09 14:46:19 +06:00
3b10e1a0f3 add axis hiding 2026-02-06 21:13:12 +06:00
70aa8c7e64 add val axis style conversion 2026-02-06 17:13:37 +06:00
bff86db600 Merge branch 'develop' into feature/add-xls-writing 2026-02-06 14:05:44 +06:00
56b8e41875 Added some alternative tags 2026-02-05 23:38:21 +03:00
565b2ec494 Fix bugs 2026-02-05 23:09:46 +03:00
a243e60e5a add axis line format conversion 2026-02-05 22:00:39 +06:00
6c95810f63 add chart gridlines 2026-02-05 21:25:54 +06:00
d9260e5eee Fix bug with heading styles 2026-02-05 17:26:33 +03:00
e612306d75 fix chart size 2026-02-04 19:54:10 +06:00
2f34fd917e Refactoring 2026-02-04 16:30:08 +03:00
71b21ea79d add window conversion for chartsheet 2026-02-03 21:42:48 +06:00
22eaf8241b fix legend pos conversion 2026-02-03 15:18:46 +06:00
64c7b7a3fd handout binary 2026-02-02 22:36:39 +03:00
90b329e06c fix sheet ref conversion 2026-02-02 20:34:04 +06:00
65a4fa90a5 Fixed bugs 2026-02-01 23:53:35 +03:00
92ec3d854e Added html to md conversion for some tags 2026-01-29 23:19:02 +03:00
5e58298d1e Migrated most of the html conversion to the new architecture 2026-01-29 00:38:08 +03:00
a9dc790f92 Migrated most of the html conversion to the new architecture 2026-01-26 19:03:34 +03:00
14bb45d2fe Migrated most of the html conversion to the new architecture 2026-01-25 22:53:08 +03:00
347c1f82a9 Migrated most of the html conversion to the new architecture 2026-01-25 01:39:48 +03:00
e32b48524e Migrated most of the html conversion to the new architecture 2026-01-22 20:16:47 +03:00
79f8e14d07 The division of the html converter into components has begun 2026-01-20 20:22:40 +03:00
7d06219664 Merge branch hotfix/v9.2.1 into master 2025-12-26 16:24:51 +00:00
e936b0e4e7 Merge branch hotfix/v9.2.1 into master 2025-12-25 10:57:58 +00:00
dde96288ed for bug #54521 2025-12-19 16:21:52 +06:00
a22f0bfb60 Merge branch hotfix/v9.2.1 into master 2025-12-17 11:33:19 +00:00
328 changed files with 15480 additions and 2963 deletions

View File

@ -7,7 +7,6 @@
#include <iterator>
#include <map>
#include <iostream>
#include "../../../../../DesktopEditor/common/File.h"
#include "StaticFunctions.h"
#include "ConstValues.h"
@ -18,14 +17,16 @@ namespace NSCSS
{
typedef std::map<std::wstring, std::wstring>::const_iterator styles_iterator;
CCompiledStyle::CCompiledStyle() : m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE)
CCompiledStyle::CCompiledStyle()
: m_nDpi(96), m_UnitMeasure(Point), m_dCoreFontSize(DEFAULT_FONT_SIZE)
{}
CCompiledStyle::CCompiledStyle(const CCompiledStyle& oStyle) :
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_oTransform(oStyle.m_oTransform){}
m_oText(oStyle.m_oText), m_oBorder(oStyle.m_oBorder), m_oDisplay(oStyle.m_oDisplay), m_oTransform(oStyle.m_oTransform)
{}
CCompiledStyle::~CCompiledStyle()
{
@ -34,6 +35,8 @@ namespace NSCSS
CCompiledStyle& CCompiledStyle::operator+= (const CCompiledStyle &oElement)
{
m_arParentsStyles.insert(oElement.m_arParentsStyles.begin(), oElement.m_arParentsStyles.end());
if (oElement.Empty())
return *this;
@ -49,8 +52,6 @@ namespace NSCSS
if (!oElement.m_sId.empty())
m_sId += L'+' + oElement.m_sId;
m_arParentsStyles.insert(oElement.m_arParentsStyles.begin(), oElement.m_arParentsStyles.end());
return *this;
}

View File

@ -15,29 +15,33 @@ inline static std::wstring StringifyValueList(const KatanaArray* oValues);
inline static std::wstring StringifyValue(const KatanaValue* oValue);
inline static bool IsTableElement(const std::wstring& wsNameTag);
bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vector<NSCSS::CNode> &arRightSelectors)
{
const size_t& sizeLeftSelectors = arLeftSelectors.size();
const size_t& sizeRightSelectors = arRightSelectors.size();
if (sizeLeftSelectors < sizeRightSelectors)
return true;
else if (sizeLeftSelectors > sizeRightSelectors)
return false;
for (size_t i = 0; i < arLeftSelectors.size(); ++i)
{
if (arLeftSelectors[i] < arRightSelectors[i])
return true;
}
return false;
}
namespace NSCSS
{
bool operator<(const std::vector<NSCSS::CNode> &arLeftSelectors, const std::vector<NSCSS::CNode> &arRightSelectors)
{
if (arLeftSelectors.size() < arRightSelectors.size())
return true;
else if (arLeftSelectors.size() > arRightSelectors.size())
return false;
for (size_t i = 0; i < arLeftSelectors.size(); ++i)
{
if (arLeftSelectors[i] == arRightSelectors[i])
continue;
if (arLeftSelectors[i] < arRightSelectors[i])
return true;
else if (arRightSelectors[i] < arLeftSelectors[i])
return false;
}
return false;
}
CStyleStorage::CStyleStorage()
{}
{
InitDefaultStyles();
}
CStyleStorage::~CStyleStorage()
{
@ -62,6 +66,7 @@ namespace NSCSS
m_arEmptyStyleFiles.clear();
ClearEmbeddedStyles();
ClearDefaultStyles();
ClearAllowedStyleFiles();
#ifdef CSS_CALCULATOR_WITH_XHTML
@ -208,6 +213,16 @@ namespace NSCSS
return nullptr;
}
const CElement* CStyleStorage::FindDefaultElement(const std::wstring& wsSelector) const
{
if (wsSelector.empty())
return nullptr;
const CElement* pFoundElement = FindSelectorFromStyleData(wsSelector, m_mDefaultStyleData);
return (nullptr != pFoundElement) ? pFoundElement : nullptr;
}
void CStyleStorage::AddStyles(const std::string& sStyle, std::map<std::wstring, CElement*>& mStyleData)
{
if (sStyle.empty())
@ -227,6 +242,15 @@ namespace NSCSS
m_mEmbeddedStyleData.clear();
}
void CStyleStorage::ClearDefaultStyles()
{
for (std::map<std::wstring, CElement*>::iterator oIter = m_mDefaultStyleData.begin(); oIter != m_mDefaultStyleData.end(); ++oIter)
if (oIter->second != nullptr)
delete oIter->second;
m_mDefaultStyleData.clear();
}
void CStyleStorage::ClearAllowedStyleFiles()
{
m_arAllowedStyleFiles.clear();
@ -480,7 +504,33 @@ namespace NSCSS
return nullptr;
}
CCssCalculator_Private::CCssCalculator_Private() : m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8"){}
void CStyleStorage::InitDefaultStyles()
{
m_mDefaultStyleData[L"b"] = new CElement(L"b", {{L"font-weight", L"bold"}});
m_mDefaultStyleData[L"center"] = new CElement(L"center", {{L"text-align", L"center"}});
m_mDefaultStyleData[L"i"] = new CElement(L"i", {{L"font-style", L"italic"}});
m_mDefaultStyleData[L"code"] = new CElement(L"code", {{L"font-family", L"Courier New"}});
m_mDefaultStyleData[L"kbd"] = new CElement(L"kbd", {{L"font-family", L"Courier New"},
{L"font_weight", L"bold"}});
m_mDefaultStyleData[L"s"] = new CElement(L"s", {{L"text-decoration", L"line-through"}});
m_mDefaultStyleData[L"u"] = new CElement(L"u", {{L"text-decoration", L"underline"}});
m_mDefaultStyleData[L"mark"] = new CElement(L"mark", {{L"background-color", L"yellow"}});
m_mDefaultStyleData[L"sup"] = new CElement(L"sup", {{L"vertical-align", L"top"}});
m_mDefaultStyleData[L"sub"] = new CElement(L"sub", {{L"vertical-align", L"bottom"}});
m_mDefaultStyleData[L"dd"] = new CElement(L"dd", {{L"margin-left", L"720tw"}});
m_mDefaultStyleData[L"pre"] = new CElement(L"pre", {{L"font-family", L"Courier New"},
{L"margin-top", L"0"},
{L"margin-bottom", L"0"}});
m_mDefaultStyleData[L"blockquote"] = new CElement(L"blockquote", {{L"margin", L"0px"}});
m_mDefaultStyleData[L"ul"] = new CElement(L"ul", {{L"margin-top", L"100tw"},
{L"margin-bottom", L"100tw"}});
m_mDefaultStyleData[L"textarea"] = new CElement(L"textarea", {{L"border", L"1px solid black"}});
}
CCssCalculator_Private::CCssCalculator_Private()
: m_nDpi(96), m_nCountNodes(0), m_sEncoding(L"UTF-8")
{
}
CCssCalculator_Private::~CCssCalculator_Private()
{}
@ -503,12 +553,17 @@ namespace NSCSS
arSelectors.back().m_pCompiledStyle->m_oBorder.Clear();
}
if (arSelectors.size() > 1)
arSelectors.back().m_pCompiledStyle->AddParent(arSelectors[arSelectors.size() - 2].m_wsName);
arSelectors.back().m_pCompiledStyle->SetID(L"text-" + std::to_wstring(++m_nCountNodes));
return true;
}
const std::map<std::vector<CNode>, CCompiledStyle>::iterator oItem = m_mUsedStyles.find(arSelectors);
const std::map<std::vector<CNode>, CCompiledStyle>::const_iterator oItem = m_mUsedStyles.find(arSelectors);
if (oItem != m_mUsedStyles.end())
if (oItem != m_mUsedStyles.cend() && (arSelectors.back().m_wsId.empty() || !HaveStylesById(arSelectors.back().m_wsId)))
{
arSelectors.back().SetCompiledStyle(new CCompiledStyle(oItem->second));
return true;
@ -542,7 +597,8 @@ namespace NSCSS
if (0 != i)
*arSelectors[i].m_pCompiledStyle += *arSelectors[i - 1].m_pCompiledStyle;
arSelectors[i].m_pCompiledStyle->AddParent(arSelectors[i].m_wsName);
if (i != arSelectors.size() - 1)
arSelectors[i].m_pCompiledStyle->AddParent(arSelectors[i].m_wsName);
if (!bInTable)
bInTable = IsTableElement(arSelectors[i].m_wsName);
@ -615,8 +671,8 @@ namespace NSCSS
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' ';}));
[](std::wstring sRes, const std::wstring& sClass)
{return sRes += L'.' + sClass + L' ';}));
}
else
arNodes.push_back(L'.' + oNode->m_wsClass);
@ -644,6 +700,36 @@ namespace NSCSS
arFindedElements.insert(arFindedElements.end(), arTempKins.begin(), arTempKins.end());
}
inline std::wstring GetAlternativeDefaultNodeName(const std::wstring& wsNodeName)
{
if (L"strong" == wsNodeName)
return L"b";
if (L"cite" == wsNodeName || L"dfn" == wsNodeName || L"em" == wsNodeName ||
L"var" == wsNodeName || L"adress" == wsNodeName)
return L"i";
if (L"tt" == wsNodeName || L"samp" == wsNodeName)
return L"code";
if (L"strike" == wsNodeName || L"del" == wsNodeName)
return L"s";
if (L"ins" == wsNodeName)
return L"u";
if (L"xmp" == wsNodeName || L"nobr" == wsNodeName)
return L"pre";
if (L"ol" == wsNodeName)
return L"ul";
if (L"fieldset" == wsNodeName)
return L"textarea";
return wsNodeName;
}
std::vector<const CElement*> CCssCalculator_Private::FindElements(std::vector<std::wstring> &arNodes, std::vector<std::wstring> &arNextNodes)
{
if (arNodes.empty())
@ -702,6 +788,11 @@ namespace NSCSS
}
}
const CElement* pFoundDefault = m_oStyleStorage.FindDefaultElement(GetAlternativeDefaultNodeName(wsName));
if (nullptr != pFoundDefault)
arFindedElements.push_back(pFoundDefault);
const CElement* pFoundName = m_oStyleStorage.FindElement(wsName);
if (nullptr != pFoundName)

View File

@ -27,6 +27,7 @@ namespace NSCSS
void AddStylesFromFile(const std::wstring& wsFileName);
void ClearEmbeddedStyles();
void ClearDefaultStyles();
void ClearAllowedStyleFiles();
void ClearStylesFromFile(const std::wstring& wsFileName);
@ -38,6 +39,7 @@ namespace NSCSS
#endif
const CElement* FindElement(const std::wstring& wsSelector) const;
const CElement* FindDefaultElement(const std::wstring& wsSelector) const;
private:
typedef struct
{
@ -49,6 +51,7 @@ namespace NSCSS
std::set<std::wstring> m_arAllowedStyleFiles;
std::vector<TStyleFileData*> m_arStyleFiles;
std::map<std::wstring, CElement*> m_mEmbeddedStyleData;
std::map<std::wstring, CElement*> m_mDefaultStyleData;
#ifdef CSS_CALCULATOR_WITH_XHTML
typedef struct
@ -78,6 +81,8 @@ namespace NSCSS
void GetOutputData(KatanaOutput* oOutput, std::map<std::wstring, CElement*>& mStyleData);
const CElement* FindSelectorFromStyleData(const std::wstring& wsSelector, const std::map<std::wstring, CElement*>& mStyleData) const;
void InitDefaultStyles();
};
class CCssCalculator_Private

View File

@ -9,6 +9,13 @@ namespace NSCSS
CElement::CElement()
{
}
CElement::CElement(const std::wstring& wsSelector, std::map<std::wstring, std::wstring> mStyle)
: m_mStyle(mStyle), m_sSelector(wsSelector), m_sFullSelector(wsSelector)
{
UpdateWeight();
}
CElement::~CElement()
{
for (CElement* oElement : m_arPrevElements)
@ -18,7 +25,6 @@ namespace NSCSS
continue;
m_mStyle.clear();
}
std::wstring CElement::GetSelector() const

View File

@ -22,6 +22,7 @@ namespace NSCSS
public:
CElement();
CElement(const std::wstring& wsSelector, std::map<std::wstring, std::wstring> mStyle);
~CElement();
std::wstring GetSelector() const;

View File

@ -17,8 +17,7 @@ namespace NSCSS
m_wsStyle(oNode.m_wsStyle), m_mAttributes(oNode.m_mAttributes)
{
#ifdef CSS_CALCULATOR_WITH_XHTML
m_pCompiledStyle = new CCompiledStyle();
*m_pCompiledStyle = *oNode.m_pCompiledStyle;
m_pCompiledStyle = new CCompiledStyle(*oNode.m_pCompiledStyle);
#endif
}
@ -42,6 +41,23 @@ namespace NSCSS
return m_wsName.empty() && m_wsClass.empty() && m_wsId.empty() && m_wsStyle.empty();
}
bool CNode::GetAttributeValue(const std::wstring& wsAttributeName, std::wstring& wsAttributeValue) const
{
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mAttributes.find(wsAttributeName)};
if (m_mAttributes.cend() == itFound)
return false;
wsAttributeValue = itFound->second;
return true;
}
std::wstring CNode::GetAttributeValue(const std::wstring& wsAttributeName) const
{
const std::map<std::wstring, std::wstring>::const_iterator itFound{m_mAttributes.find(wsAttributeName)};
return (m_mAttributes.cend() != itFound) ? itFound->second : std::wstring();
}
#ifdef CSS_CALCULATOR_WITH_XHTML
void CNode::SetCompiledStyle(CCompiledStyle* pCompiledStyle)
{
@ -86,6 +102,9 @@ namespace NSCSS
if(m_wsStyle != oNode.m_wsStyle)
return m_wsStyle < oNode.m_wsStyle;
if (m_mAttributes.size() != oNode.m_mAttributes.size())
return m_mAttributes.size() < oNode.m_mAttributes.size();
if (m_mAttributes != oNode.m_mAttributes)
return m_mAttributes < oNode.m_mAttributes;
@ -94,10 +113,9 @@ namespace NSCSS
bool CNode::operator==(const CNode& oNode) const
{
return((m_wsId == oNode.m_wsId) &&
(m_wsName == oNode.m_wsName) &&
(m_wsClass == oNode.m_wsClass) &&
(m_wsStyle == oNode.m_wsStyle) &&
(m_mAttributes == oNode.m_mAttributes));
return((m_wsName == oNode.m_wsName) &&
(m_wsClass == oNode.m_wsClass) &&
(m_wsStyle == oNode.m_wsStyle) &&
(m_mAttributes == oNode.m_mAttributes));
}
}

View File

@ -31,6 +31,9 @@ namespace NSCSS
bool Empty() const;
bool GetAttributeValue(const std::wstring& wsAttributeName, std::wstring& wsAttributeValue) const;
std::wstring GetAttributeValue(const std::wstring& wsAttributeName) const;
#ifdef CSS_CALCULATOR_WITH_XHTML
void SetCompiledStyle(CCompiledStyle* pCompiledStyle);
#endif

View File

@ -70,7 +70,9 @@ namespace NSCSS
R_Shd,
R_SmallCaps,
R_Kern,
R_Vanish
R_Vanish,
R_Strike,
R_VertAlign
} RunnerProperties;
typedef enum

View File

@ -22,6 +22,11 @@ namespace NSCSS
: m_oStyle(oStyle), m_bIsPStyle(bIsPStyle)
{}
void CStyleUsed::SetFinalId(const std::wstring& wsFinalId)
{
m_wsFinalId = wsFinalId;
}
bool CheckArrays(const std::vector<std::wstring>& arInitial, const std::set<std::wstring>& arFirst, const std::set<std::wstring>& arSecond)
{
std::unordered_set<std::wstring> arInitialSet(arInitial.begin(), arInitial.end());
@ -57,19 +62,14 @@ namespace NSCSS
m_oStyle == oUsedStyle.m_oStyle;
}
std::wstring CStyleUsed::getId()
std::wstring CStyleUsed::GetId() const
{
if (m_bIsPStyle)
return m_oStyle.GetId();
return m_oStyle.GetId() + L"-c";
return m_wsFinalId;
}
CDocumentStyle::CDocumentStyle() : m_arStandardStyles(Names_Standard_Styles)
{
for (const std::wstring& oNameStandardStyle : Names_Standard_Styles)
m_arStandardStyles.push_back(oNameStandardStyle + L"-c");
}
CDocumentStyle::CDocumentStyle()
: m_arStandardStyles(Names_Standard_Styles)
{}
CDocumentStyle::~CDocumentStyle()
{
@ -85,7 +85,7 @@ namespace NSCSS
std::wstring CDocumentStyle::GetIdAndClear()
{
std::wstring sId = m_sId;
const std::wstring sId = m_sId;
Clear();
return sId;
}
@ -110,10 +110,10 @@ namespace NSCSS
m_sId = sId;
}
void CDocumentStyle::CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement)
bool CDocumentStyle::CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement)
{
if (arStandartedStyles.empty())
return;
return false;
std::vector<std::wstring> arStyles;
for (const std::wstring& sStyleName : arStandartedStyles)
@ -123,7 +123,7 @@ namespace NSCSS
}
if (arStyles.empty())
return;
return false;
std::wstring sId;
for (std::vector<std::wstring>::const_reverse_iterator iStyleName = arStyles.rbegin(); iStyleName != arStyles.rend(); ++iStyleName)
@ -142,18 +142,25 @@ namespace NSCSS
oElement.AddBasicProperties(BProperties::B_Name, sId);
oElement.AddBasicProperties(BProperties::B_StyleId, sId);
return true;
}
void CDocumentStyle::CreateStandardStyle(const std::wstring& sNameStyle, CXmlElement& oElement)
bool CDocumentStyle::CreateStandardStyle(const std::wstring& sNameStyle, CXmlElement& oElement)
{
if (std::find(m_arStandardStyles.begin(), m_arStandardStyles.end(), sNameStyle) != m_arStandardStyles.end())
{
oElement.CreateDefaultElement(sNameStyle);
return true;
}
return false;
}
void CDocumentStyle::ConvertStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle)
bool CDocumentStyle::ConvertStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle)
{
if (oStyle.GetId().empty())
return;
return false;
std::wstring sName = oStyle.GetId();
const size_t posPoint = sName.find(L'.');
@ -183,25 +190,25 @@ namespace NSCSS
for (std::wstring& sParentName : arParentsName)
sParentName += L"-c";
bool bResult{false};
if (!arParentsName.empty())
{
CombineStandardStyles(arParentsName, oParentStyle);
bResult = CombineStandardStyles(arParentsName, oParentStyle);
if (!oParentStyle.Empty())
{
oParentStyle.AddBasicProperties(BProperties::B_BasedOn, L"normal");
oParentStyle.AddBasicProperties(BProperties::B_StyleId, L"(" + oParentStyle.GetStyleId() + L")");
oParentStyle.AddBasicProperties(BProperties::B_StyleId, oParentStyle.GetStyleId());
if (!bIsPStyle)
{
oParentStyle.AddBasicProperties(BProperties::B_StyleId, oParentStyle.GetStyleId() + L"-c");
oParentStyle.AddBasicProperties(BProperties::B_Type, L"character");
}
}
}
CXmlElement oStandardXmlElement;
if (std::find(m_arStandardStyles.begin(), m_arStandardStyles.end(), sName) != m_arStandardStyles.end())
CreateStandardStyle(sName, oStandardXmlElement);
if (CreateStandardStyle(sName, oStandardXmlElement))
bResult = true;
if (oStandardXmlElement.Empty() && !oParentStyle.Empty())
{
@ -221,7 +228,7 @@ namespace NSCSS
if (oStyle.Empty())
{
m_sId = sParentsStyleID;
return;
return true;
}
oElement.AddBasicProperties(BProperties::B_BasedOn, sParentsStyleID);
@ -234,7 +241,7 @@ namespace NSCSS
if (oStyle.Empty())
{
m_sId = sStandPlusParent;
return;
return true;
}
oElement.AddBasicProperties(BProperties::B_BasedOn, sStandPlusParent);
}
@ -258,7 +265,7 @@ namespace NSCSS
if (oStyle.Empty())
{
m_sId = sStandPlusParent;
return;
return true;
}
oElement.AddBasicProperties(BProperties::B_BasedOn, oTempElement.GetStyleId());
}
@ -281,7 +288,7 @@ namespace NSCSS
if (oStyle.Empty())
{
m_sId = sStandartStyleID;
return;
return true;
}
oElement.AddBasicProperties(BProperties::B_BasedOn, sStandartStyleID);
}
@ -289,7 +296,7 @@ namespace NSCSS
if (oStyle.Empty() && oElement.Empty())
{
m_sId = L"normal";
return;
return true;
}
m_sId = oStyle.GetId();
@ -302,15 +309,19 @@ namespace NSCSS
oElement.AddBasicProperties(BProperties::B_Name, m_sId);
oElement.AddBasicProperties(BProperties::B_Type, bIsPStyle ? L"paragraph" : L"character");
oElement.AddBasicProperties(BProperties::B_CustomStyle, L"1");
return bResult;
}
void CDocumentStyle::SetPStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
bool CDocumentStyle::SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
{
bool bResult{false};
if (!bIsLite)
ConvertStyle(oStyle, oXmlElement, true);
bResult = ConvertStyle(oStyle, oXmlElement, true);
if (oStyle.Empty())
return;
return bResult;
const bool bInTable{oStyle.HaveThisParent(L"table")};
@ -390,6 +401,8 @@ namespace NSCSS
SetBorderStyle(oStyle, oXmlElement, PProperties::P_LeftBorder);
}
}
return bResult || !oXmlElement.Empty();
}
void CDocumentStyle::SetBorderStyle(const CCompiledStyle &oStyle, CXmlElement &oXmlElement, const PProperties &enBorderProperty)
@ -473,13 +486,15 @@ namespace NSCSS
return L"w:val=\"" + wsStyle + L"\" w:sz=\"" + std::to_wstring(nWidth) + + L"\" w:space=\"" + std::to_wstring(nSpace) + L"\" w:color=\"" + wsColor + L"\"";
}
void CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
bool CDocumentStyle::SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite)
{
bool bResult{false};
if (!bIsLite)
ConvertStyle(oStyle, oXmlElement, false);
bResult = ConvertStyle(oStyle, oXmlElement, false);
if (oStyle.Empty() && oXmlElement.Empty())
return;
return bResult;
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. * oStyle.m_oTransform.GetMatrix().GetFinalValue().sy() + 0.5))); // Значения шрифта увеличивает на 2
@ -516,6 +531,18 @@ namespace NSCSS
oXmlElement.AddPropertiesInR(RProperties::R_I, oStyle.m_oFont.GetStyle().ToWString());
oXmlElement.AddPropertiesInR(RProperties::R_B, oStyle.m_oFont.GetWeight().ToWString());
oXmlElement.AddPropertiesInR(RProperties::R_SmallCaps, oStyle.m_oFont.GetVariant().ToWString());
if (oStyle.m_oText.LineThrough())
{
if (L"double" == oStyle.m_oText.GetDecoration().m_oStyle.ToWString())
oXmlElement.AddPropertiesInR(RProperties::R_Strike, L"dstrike");
else
oXmlElement.AddPropertiesInR(RProperties::R_Strike, L"strike");
}
oXmlElement.AddPropertiesInR(RProperties::R_VertAlign, oStyle.m_oDisplay.GetVAlign().ToWString());
return bResult || !oXmlElement.Empty();
}
bool CDocumentStyle::WriteRStyle(const NSCSS::CCompiledStyle& oStyle)
@ -531,16 +558,16 @@ namespace NSCSS
if (oItem != m_arStyleUsed.end())
{
m_sId = (*oItem).getId();
m_sId = (*oItem).GetId();
return true;
}
CXmlElement oXmlElement;
SetRStyle(oStyle, oXmlElement);
if (oXmlElement.Empty())
if (!SetRStyle(oStyle, oXmlElement))
return false;
structStyle.SetFinalId(m_sId);
m_arStyleUsed.push_back(structStyle);
m_sStyle += oXmlElement.GetRStyle();
@ -593,16 +620,16 @@ namespace NSCSS
if (oItem != m_arStyleUsed.end())
{
m_sId = (*oItem).getId();
m_sId = (*oItem).GetId();
return true;
}
CXmlElement oXmlElement;
SetPStyle(oStyle, oXmlElement);
if (oXmlElement.Empty())
if (!SetPStyle(oStyle, oXmlElement))
return false;
structStyle.SetFinalId(m_sId);
m_arStyleUsed.push_back(structStyle);
m_sStyle += oXmlElement.GetPStyle();

View File

@ -12,16 +12,19 @@ namespace NSCSS
{
CCompiledStyle m_oStyle;
bool m_bIsPStyle;
std::wstring m_wsFinalId;
public:
CStyleUsed(const CCompiledStyle& oStyle, bool bIsPStyle);
void SetFinalId(const std::wstring& wsFinalId);
bool operator==(const CStyleUsed& oUsedStyle) const;
std::wstring getId();
std::wstring GetId() const;
};
static const std::vector<std::wstring> Names_Standard_Styles = {L"a", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6",L"p", L"div"};
static const std::vector<std::wstring> Names_Standard_Styles = {L"a", L"a-c", L"li", L"h1", L"h2", L"h3", L"h4", L"h5", L"h6", L"h1-c", L"h2-c", L"h3-c", L"h4-c", L"h5-c", L"h6-c"};
class CSSCALCULATOR_EXPORT CDocumentStyle
{
@ -36,12 +39,12 @@ namespace NSCSS
std::wstring m_sStyle;
std::wstring m_sId;
void CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement);
void CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement);
void ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle);
bool CombineStandardStyles(const std::vector<std::wstring>& arStandartedStyles, CXmlElement& oElement);
bool CreateStandardStyle (const std::wstring& sNameStyle, CXmlElement& oElement);
bool ConvertStyle (const NSCSS::CCompiledStyle& oStyle, CXmlElement& oElement, bool bIsPStyle);
void SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
void SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
bool SetRStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
bool SetPStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, bool bIsLite = false);
void SetBorderStyle(const NSCSS::CCompiledStyle& oStyle, CXmlElement& oXmlElement, const PProperties& enBorderProperty);
public:

View File

@ -5,7 +5,6 @@
#include <cwctype>
#include <functional>
#include <iostream>
#include "../ConstValues.h"
#define DEFAULTFONTNAME L"Times New Roman"
@ -67,7 +66,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"0");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h2")
{
@ -78,7 +77,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h2-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"1");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h3")
{
@ -89,7 +88,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h3-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"2");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h4")
{
@ -100,7 +99,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h4-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"3");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h5")
{
@ -111,7 +110,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h5-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"4");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h6")
@ -123,13 +122,13 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h6-c");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_OutlineLvl, L"5");
// AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
AddPropertiesInP(CSSProperties::ParagraphProperties::P_Spacing, L"w:before=\"100\" w:beforeAutospacing=\"1\" w:after=\"100\" w:afterAutospacing=\"1\"");
}
else if (sNameDefaultElement == L"h1-c")
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h1-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 1 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 1 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_Link, L"h1");
@ -142,7 +141,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h2-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 2 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 2 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
@ -155,7 +154,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h3-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 3 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 3 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
@ -168,7 +167,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h4-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 4 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 4 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
@ -181,7 +180,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h5-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 5 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 5 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
@ -194,7 +193,7 @@ void CXmlElement::CreateDefaultElement(const std::wstring& sNameDefaultElement)
{
AddBasicProperties(CSSProperties::BasicProperties::B_Type, L"character");
AddBasicProperties(CSSProperties::BasicProperties::B_StyleId, L"h6-c");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Title 6 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_Name, L"Heading 6 Sign");
AddBasicProperties(CSSProperties::BasicProperties::B_CustomStyle, L"1");
AddBasicProperties(CSSProperties::BasicProperties::B_UiPriority, L"9");
AddBasicProperties(CSSProperties::BasicProperties::B_UnhideWhenUsed, L"true");
@ -479,6 +478,19 @@ std::wstring CXmlElement::ConvertRStyle(bool bIsLite) const
sRStyle += L"<w:vanish/>";
break;
}
case CSSProperties::RunnerProperties::R_Strike:
{
sRStyle += L"<w:" + oItem.second + L"/>";
break;
}
case CSSProperties::RunnerProperties::R_VertAlign:
{
if (L"top" == oItem.second)
sRStyle += L"<w:vertAlign w:val=\"superscript\"/>";
else if (L"bottom" == oItem.second)
sRStyle += L"<w:vertAlign w:val=\"subscript\"/>";
break;
}
default:
break;
}

View File

@ -7,4 +7,5 @@ core_windows:INCLUDEPATH += $$PWD/gumbo-parser/visualc/include
HEADERS += $$files($$PWD/gumbo-parser/src/*.h, true) \
$$PWD/htmltoxhtml.h
SOURCES += $$files($$PWD/gumbo-parser/src/*.c, true)
SOURCES += $$files($$PWD/gumbo-parser/src/*.c, true) \
$$PWD/htmltoxhtml.cpp

View File

@ -0,0 +1,657 @@
#include "htmltoxhtml.h"
#include <map>
#include <cctype>
#include <vector>
#include <algorithm>
#include "gumbo-parser/src/gumbo.h"
#include "../../../DesktopEditor/common/File.h"
#include "../../../DesktopEditor/common/Directory.h"
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../../../UnicodeConverter/UnicodeConverter.h"
#include "../../../HtmlFile2/src/StringFinder.h"
namespace HTML
{
#if defined(CreateDirectory)
#undef CreateDirectory
#endif
static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|";
static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|";
static std::string preserve_whitespace = "|pre|textarea|script|style|";
static std::string special_handling = "|html|body|";
static std::string treat_like_inline = "|p|";
static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6",
"ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th",
"br","form","input","button","section","nav","header","footer",
"main","figure","figcaption","strong","em","i", "b", "u","pre",
"code","blockquote","hr","script","link","meta","style","title",
"head","body","html","legend","optgroup","option","select","dl",
"dt","dd","time","data","abbr","address","area","base","bdi",
"bdo","cite","col","iframe","video","source","track","textarea",
"label","fieldset","colgroup","del","ins","details","summary",
"dialog","embed","kbd","map","mark","menu","meter","object",
"output","param","progress","q","samp","small","sub","sup","var",
"wbr","acronym","applet","article","aside","audio","basefont",
"bgsound","big","blink","canvas","caption","center","command",
"comment","datalist","dfn","dir","font","frame","frameset",
"hgroup","isindex","keygen","marquee","nobr","noembed","noframes",
"noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"};
static std::vector<std::string> unchecked_nodes_new = {"svg"};
static void replace_all(std::string& s, const std::string& s1, const std::string& s2)
{
size_t pos = s.find(s1);
while(pos != std::string::npos)
{
s.replace(pos, s1.length(), s2);
pos = s.find(s1, pos + s2.length());
}
}
static bool NodeIsUnprocessed(const std::string& sTagName)
{
return "xml" == sTagName;
}
static bool IsUnckeckedNodes(const std::string& sValue)
{
return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue);
}
static std::string Base64ToString(const std::string& sContent, const std::string& sCharset)
{
std::string sRes;
int nSrcLen = (int)sContent.length();
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
BYTE* pData = new BYTE[nDecodeLen];
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
{
std::wstring sConvert;
if(!sCharset.empty() && NSStringFinder::Equals<std::string>("utf-8", sCharset))
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sConvert = oConverter.toUnicode(reinterpret_cast<char *>(pData), (unsigned)nDecodeLen, sCharset.data());
}
sRes = sConvert.empty() ? std::string(reinterpret_cast<char *>(pData), nDecodeLen) : U_TO_UTF8(sConvert);
}
RELEASEARRAYOBJECTS(pData);
return sRes;
}
static std::string QuotedPrintableDecode(const std::string& sContent, std::string& sCharset)
{
NSStringUtils::CStringBuilderA sRes;
size_t ip = 0;
size_t i = sContent.find('=');
if(i == 0)
{
size_t nIgnore = 12;
std::string charset = sContent.substr(0, nIgnore);
if(charset == "=00=00=FE=FF")
sCharset = "UTF-32BE";
else if(charset == "=FF=FE=00=00")
sCharset = "UTF-32LE";
else if(charset == "=2B=2F=76=38" || charset == "=2B=2F=76=39" ||
charset == "=2B=2F=76=2B" || charset == "=2B=2F=76=2F")
sCharset = "UTF-7";
else if(charset == "=DD=73=66=73")
sCharset = "UTF-EBCDIC";
else if(charset == "=84=31=95=33")
sCharset = "GB-18030";
else
{
nIgnore -= 3;
charset.erase(nIgnore);
if(charset == "=EF=BB=BF")
sCharset = "UTF-8";
else if(charset == "=F7=64=4C")
sCharset = "UTF-1";
else if(charset == "=0E=FE=FF")
sCharset = "SCSU";
else if(charset == "=FB=EE=28")
sCharset = "BOCU-1";
else
{
nIgnore -= 3;
charset.erase(nIgnore);
if(charset == "=FE=FF")
sCharset = "UTF-16BE";
else if(charset == "=FF=FE")
sCharset = "UTF-16LE";
else
nIgnore -= 6;
}
}
ip = nIgnore;
i = sContent.find('=', ip);
}
while(i != std::string::npos && i + 2 < sContent.length())
{
sRes.WriteString(sContent.c_str() + ip, i - ip);
std::string str = sContent.substr(i + 1, 2);
if(str.front() == '\n' || str.front() == '\r')
{
char ch = str[1];
if(ch != '\n' && ch != '\r')
sRes.WriteString(&ch, 1);
}
else
{
char* err;
char ch = (int)strtol(str.data(), &err, 16);
if(*err)
sRes.WriteString('=' + str);
else
sRes.WriteString(&ch, 1);
}
ip = i + 3;
i = sContent.find('=', ip);
}
if(ip != std::string::npos)
sRes.WriteString(sContent.c_str() + ip);
return sRes.GetData();
}
static std::string mhtTohtml(const std::string& sFileContent);
static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes)
{
size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos;
NSStringFinder::TFoundedData<char> oData;
// Content-Type
oData = NSStringFinder::FindProperty(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"});
const std::string sContentType{oData.m_sValue};
if (sContentType.empty())
return;
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
{
oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition)));
return;
}
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetBegin = oData.m_unEndPosition;
// name
// std::string sName = NSStringFinder::FindProperty(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition);
// unContentPosition = std::max(unContentPosition, unLastPosition);
// Content-Location
oData = NSStringFinder::FindProperty(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"});
std::string sContentLocation{oData.m_sValue};
if (!oData.Empty())
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
// Content-ID
oData = NSStringFinder::FindProperty(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"});
std::string sContentID{oData.m_sValue};
if (!oData.Empty())
{
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
NSStringFinder::CutInside<std::string>(sContentID, "<", ">");
}
if (sContentLocation.empty() && !sContentID.empty())
sContentLocation = "cid:" + sContentID;
// Content-Transfer-Encoding
oData = NSStringFinder::FindProperty(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"});
const std::string sContentEncoding{oData.m_sValue};
if (!oData.Empty())
{
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
}
// charset
std::string sCharset = "utf-8";
if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd)
{
sCharset = NSStringFinder::FindProperty(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue;
NSStringFinder::CutInside<std::string>(sCharset, "\"");
}
// Content
std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition);
// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName));
// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
// Основной документ
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
oRes.WriteString(mhtTohtml(sContent));
else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/)
|| (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css")))
{
// Стили заключаются в тэг <style>
const bool bAddTagStyle = NSStringFinder::Equals(sContentType, "text/css") /*|| NSStringFinder::Equals(sExtention, L"css")*/ || NSStringFinder::Find(sContentLocation, "css");
if (bAddTagStyle)
oRes.WriteString("<style>");
if (NSStringFinder::Equals(sContentEncoding, "base64"))
sContent = Base64ToString(sContent, sCharset);
else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty())
{
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
}
}
else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable"))
{
sContent = QuotedPrintableDecode(sContent, sCharset);
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
}
}
if (NSStringFinder::Equals(sContentType, "text/html"))
sContent = U_TO_UTF8(htmlToXhtml(sContent, false));
oRes.WriteString(sContent);
if(bAddTagStyle)
oRes.WriteString("</style>");
}
// Картинки
else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) &&
NSStringFinder::Equals(sContentEncoding, "base64"))
{
// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico"))
// sContentType = "image/jpg";
// else if(NSStringFinder::Equals(sExtention, L"gif"))
// sContentType = "image/gif";
int nSrcLen = (int)sContent.length();
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
BYTE* pData = new BYTE[nDecodeLen];
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
sRes.insert(std::make_pair(sContentLocation, "data:" + sContentType + ";base64," + sContent));
RELEASEARRAYOBJECTS(pData);
}
}
static std::string mhtTohtml(const std::string& sFileContent)
{
std::map<std::string, std::string> sRes;
NSStringUtils::CStringBuilderA oRes;
// Поиск boundary
NSStringFinder::TFoundedData<char> oData{NSStringFinder::FindProperty(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})};
size_t nFound{oData.m_unEndPosition};
std::string sBoundary{oData.m_sValue};
if (sBoundary.empty())
{
size_t nFoundEnd = sFileContent.length();
nFound = 0;
ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes);
return oRes.GetData();
}
NSStringFinder::CutInside<std::string>(sBoundary, "\"");
size_t nFoundEnd{nFound};
sBoundary = "--" + sBoundary;
size_t nBoundaryLength = sBoundary.length();
nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength;
// Цикл по boundary
while(nFound != std::string::npos)
{
nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength);
if(nFoundEnd == std::string::npos)
break;
ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes);
nFound = sFileContent.find(sBoundary, nFoundEnd);
}
std::string sFile = oRes.GetData();
for(const std::pair<std::string, std::string>& item : sRes)
{
std::string sName = item.first;
size_t found = sFile.find(sName);
size_t sfound = sName.rfind('/');
if(found == std::string::npos && sfound != std::string::npos)
found = sFile.find(sName.erase(0, sfound + 1));
while(found != std::string::npos)
{
size_t fq = sFile.find_last_of("\"\'>=", found);
if (std::string::npos == fq)
break;
char ch = sFile[fq];
if(ch != '\"' && ch != '\'')
fq++;
size_t tq = sFile.find_first_of("\"\'<> ", found) + 1;
if (std::string::npos == tq)
break;
if(sFile[tq] != '\"' && sFile[tq] != '\'')
tq--;
if(ch != '>')
{
std::string is = '\"' + item.second + '\"';
sFile.replace(fq, tq - fq, is);
found = sFile.find(sName, fq + is.length());
}
else
found = sFile.find(sName, tq);
}
}
return sFile;
}
// Заменяет сущности &,<,> в text
static void substitute_xml_entities_into_text(std::string& text)
{
// replacing & must come first
replace_all(text, "&", "&amp;");
replace_all(text, "<", "&lt;");
replace_all(text, ">", "&gt;");
}
// After running through Gumbo, the values of type "&#1;" are replaced with the corresponding code '0x01'
// Since the attribute value does not use control characters (value <= 0x09),
// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them.
// bug#73486
static void remove_control_symbols(std::string& text)
{
std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
while (itFound != text.end())
{
itFound = text.erase(itFound);
itFound = std::find_if(itFound, text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
}
}
// Заменяет сущности " в text
static void substitute_xml_entities_into_attributes(std::string& text)
{
remove_control_symbols(text);
substitute_xml_entities_into_text(text);
replace_all(text, "\"", "&quot;");
}
static std::string handle_unknown_tag(GumboStringPiece* text)
{
if (text->data == NULL)
return "";
GumboStringPiece gsp = *text;
gumbo_tag_from_original_text(&gsp);
std::string sAtr = std::string(gsp.data, gsp.length);
size_t found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}");
while(found != std::string::npos)
{
sAtr.erase(found, 1);
found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}", found);
}
return sAtr;
}
static std::string get_tag_name(GumboNode* node)
{
std::string tagname = (node->type == GUMBO_NODE_DOCUMENT ? "document" : gumbo_normalized_tagname(node->v.element.tag));
if (tagname.empty())
tagname = handle_unknown_tag(&node->v.element.original_tag);
return tagname;
}
static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder)
{
if (node->v.document.has_doctype)
{
oBuilder.WriteString("<!DOCTYPE ");
oBuilder.WriteString(node->v.document.name);
std::string pi(node->v.document.public_identifier);
remove_control_symbols(pi);
if ((node->v.document.public_identifier != NULL) && !pi.empty())
{
oBuilder.WriteString(" PUBLIC \"");
oBuilder.WriteString(pi);
oBuilder.WriteString("\" \"");
oBuilder.WriteString(node->v.document.system_identifier);
oBuilder.WriteString("\"");
}
oBuilder.WriteString(">");
}
}
static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts)
{
std::vector<std::string> arrRepeat;
for (size_t i = 0; i < attribs->length; ++i)
{
GumboAttribute* at = static_cast<GumboAttribute*>(attribs->data[i]);
std::string sVal(at->value);
std::string sName(at->name);
remove_control_symbols(sVal);
remove_control_symbols(sName);
atts.WriteString(" ");
bool bCheck = false;
size_t nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}");
while(nBad != std::string::npos)
{
sName.erase(nBad, 1);
nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}", nBad);
if(sName.empty())
break;
bCheck = true;
}
if(sName.empty())
continue;
while(sName.front() >= '0' && sName.front() <= '9')
{
sName.erase(0, 1);
if(sName.empty())
break;
bCheck = true;
}
if(bCheck)
{
GumboAttribute* check = gumbo_get_attribute(attribs, sName.c_str());
if(check || std::find(arrRepeat.begin(), arrRepeat.end(), sName) != arrRepeat.end())
continue;
else
arrRepeat.push_back(sName);
}
if(sName.empty())
continue;
atts.WriteString(sName);
// determine original quote character used if it exists
std::string qs ="\"";
atts.WriteString("=");
atts.WriteString(qs);
substitute_xml_entities_into_attributes(sVal);
atts.WriteString(sVal);
atts.WriteString(qs);
}
}
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true);
static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode)
{
std::string key = "|" + get_tag_name(node) + "|";
bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos;
bool is_inline = nonbreaking_inline.find(key) != std::string::npos;
bool is_like_inline = treat_like_inline.find(key) != std::string::npos;
GumboVector* children = &node->v.element.children;
for (size_t i = 0; i < children->length; i++)
{
GumboNode* child = static_cast<GumboNode*> (children->data[i]);
if (child->type == GUMBO_NODE_TEXT)
{
std::string val(child->v.text.text);
remove_control_symbols(val);
substitute_xml_entities_into_text(val);
// Избавление от FF
size_t found = val.find_first_of("\014");
while(found != std::string::npos)
{
val.erase(found, 1);
found = val.find_first_of("\014", found);
}
contents.WriteString(val);
}
else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE))
prettyprint(child, contents, bCheckValidNode);
else if (child->type == GUMBO_NODE_WHITESPACE)
{
if (keep_whitespace || is_inline || is_like_inline)
contents.WriteString(child->v.text.text);
}
else if (child->type != GUMBO_NODE_COMMENT)
{
// Сообщение об ошибке
// Does this actually exist: (child->type == GUMBO_NODE_CDATA)
// fprintf(stderr, "unknown element of type: %d\n", child->type);
}
}
}
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode)
{
// special case the document node
if (node->type == GUMBO_NODE_DOCUMENT)
{
build_doctype(node, oBuilder);
prettyprint_contents(node, oBuilder, bCheckValidNode);
return;
}
std::string tagname = get_tag_name(node);
remove_control_symbols(tagname);
if (NodeIsUnprocessed(tagname))
return;
if (bCheckValidNode)
bCheckValidNode = !IsUnckeckedNodes(tagname);
if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname))
{
prettyprint_contents(node, oBuilder, bCheckValidNode);
return;
}
std::string close = "";
std::string closeTag = "";
std::string key = "|" + tagname + "|";
bool is_empty_tag = empty_tags.find(key) != std::string::npos;
// determine closing tag type
if (is_empty_tag)
close = "/";
else
closeTag = "</" + tagname + ">";
// build results
oBuilder.WriteString("<" + tagname);
// build attr string
const GumboVector* attribs = &node->v.element.attributes;
build_attributes(attribs, oBuilder);
oBuilder.WriteString(close + ">");
// prettyprint your contents
prettyprint_contents(node, oBuilder, bCheckValidNode);
oBuilder.WriteString(closeTag);
}
std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert)
{
if (bNeedConvert)
{ // Определение кодировки
std::string sEncoding = NSStringFinder::FindProperty(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\"", "'"}).m_sValue;
if (sEncoding.empty())
sEncoding = NSStringFinder::FindProperty(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue;
if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding))
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str()));
}
}
// Избавляемся от лишних символов до <...
boost::regex oRegex("<[a-zA-Z]");
boost::match_results<typename std::string::const_iterator> oResult;
if (boost::regex_search(sFileContent, oResult, oRegex))
sFileContent.erase(0, oResult.position());
//Избавление от <a ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "a"));
//Избавление от <title ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "title"));
//Избавление от <script ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "script"));
// Gumbo
GumboOptions options = kGumboDefaultOptions;
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
// prettyprint
NSStringUtils::CStringBuilderA oBuilder;
prettyprint(output->document, oBuilder);
// Конвертирование из string utf8 в wstring
return UTF8_TO_U(oBuilder.GetData());
}
std::wstring mhtToXhtml(std::string& sFileContent)
{
sFileContent = mhtTohtml(sFileContent);
// Gumbo
GumboOptions options = kGumboDefaultOptions;
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
// prettyprint
NSStringUtils::CStringBuilderA oBuilder;
prettyprint(output->document, oBuilder);
// Конвертирование из string utf8 в wstring
return UTF8_TO_U(oBuilder.GetData());
}
}

View File

@ -2,658 +2,11 @@
#define HTMLTOXHTML_H
#include <string>
#include <map>
#include <cctype>
#include <vector>
#include <algorithm>
#include "gumbo-parser/src/gumbo.h"
#include "../../../DesktopEditor/common/File.h"
#include "../../../DesktopEditor/common/Directory.h"
#include "../../../DesktopEditor/common/StringBuilder.h"
#include "../../../DesktopEditor/xml/include/xmlutils.h"
#include "../../../UnicodeConverter/UnicodeConverter.h"
#include "../../../HtmlFile2/src/StringFinder.h"
#if defined(CreateDirectory)
#undef CreateDirectory
#endif
static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|img|kbd|nobr|s|small|span|strike|strong|sub|sup|tt|";
static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|";
static std::string preserve_whitespace = "|pre|textarea|script|style|";
static std::string special_handling = "|html|body|";
static std::string treat_like_inline = "|p|";
static std::vector<std::string> html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6",
"ul", "ol", "li","td","tr","table","thead","tbody","tfoot","th",
"br","form","input","button","section","nav","header","footer",
"main","figure","figcaption","strong","em","i", "b", "u","pre",
"code","blockquote","hr","script","link","meta","style","title",
"head","body","html","legend","optgroup","option","select","dl",
"dt","dd","time","data","abbr","address","area","base","bdi",
"bdo","cite","col","iframe","video","source","track","textarea",
"label","fieldset","colgroup","del","ins","details","summary",
"dialog","embed","kbd","map","mark","menu","meter","object",
"output","param","progress","q","samp","small","sub","sup","var",
"wbr","acronym","applet","article","aside","audio","basefont",
"bgsound","big","blink","canvas","caption","center","command",
"comment","datalist","dfn","dir","font","frame","frameset",
"hgroup","isindex","keygen","marquee","nobr","noembed","noframes",
"noscript","plaintext","rp","rt","ruby","s","strike","tt","xmp"};
static std::vector<std::string> unchecked_nodes_new = {"svg"};
static void prettyprint(GumboNode*, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode = true);
static std::string mhtTohtml(const std::string &sFileContent);
// Заменяет в строке s все символы s1 на s2
static void replace_all(std::string& s, const std::string& s1, const std::string& s2)
namespace HTML
{
size_t pos = s.find(s1);
while(pos != std::string::npos)
{
s.replace(pos, s1.length(), s2);
pos = s.find(s1, pos + s2.length());
}
}
static bool NodeIsUnprocessed(const std::string& wsTagName)
{
return "xml" == wsTagName;
}
static bool IsUnckeckedNodes(const std::string& sValue)
{
return unchecked_nodes_new.end() != std::find(unchecked_nodes_new.begin(), unchecked_nodes_new.end(), sValue);
}
static std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert)
{
if (bNeedConvert)
{ // Определение кодировки
std::string sEncoding = NSStringFinder::FindProperty(sFileContent, "charset", {"="}, {";", "\\n", "\\r", " ", "\"", "'"}).m_sValue;
if (sEncoding.empty())
sEncoding = NSStringFinder::FindProperty(sFileContent, "encoding", {"="}, {";", "\\n", "\\r", " "}).m_sValue;
if (!sEncoding.empty() && !NSStringFinder::Equals("utf-8", sEncoding))
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sFileContent = U_TO_UTF8(oConverter.toUnicode(sFileContent, sEncoding.c_str()));
}
}
// Избавляемся от лишних символов до <...
boost::regex oRegex("<[a-zA-Z]");
boost::match_results<typename std::string::const_iterator> oResult;
if (boost::regex_search(sFileContent, oResult, oRegex))
sFileContent.erase(0, oResult.position());
//Избавление от <a ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "a"));
//Избавление от <title ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "title"));
//Избавление от <script ... />
while (NSStringFinder::RemoveEmptyTag(sFileContent, "script"));
// Gumbo
GumboOptions options = kGumboDefaultOptions;
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
// prettyprint
NSStringUtils::CStringBuilderA oBuilder;
prettyprint(output->document, oBuilder);
// Конвертирование из string utf8 в wstring
return UTF8_TO_U(oBuilder.GetData());
}
static std::string Base64ToString(const std::string& sContent, const std::string& sCharset)
{
std::string sRes;
int nSrcLen = (int)sContent.length();
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
BYTE* pData = new BYTE[nDecodeLen];
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
{
std::wstring sConvert;
if(!sCharset.empty() && NSStringFinder::Equals<std::string>("utf-8", sCharset))
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sConvert = oConverter.toUnicode(reinterpret_cast<char *>(pData), (unsigned)nDecodeLen, sCharset.data());
}
sRes = sConvert.empty() ? std::string(reinterpret_cast<char *>(pData), nDecodeLen) : U_TO_UTF8(sConvert);
}
RELEASEARRAYOBJECTS(pData);
return sRes;
}
static std::string QuotedPrintableDecode(const std::string& sContent, std::string& sCharset)
{
NSStringUtils::CStringBuilderA sRes;
size_t ip = 0;
size_t i = sContent.find('=');
if(i == 0)
{
size_t nIgnore = 12;
std::string charset = sContent.substr(0, nIgnore);
if(charset == "=00=00=FE=FF")
sCharset = "UTF-32BE";
else if(charset == "=FF=FE=00=00")
sCharset = "UTF-32LE";
else if(charset == "=2B=2F=76=38" || charset == "=2B=2F=76=39" ||
charset == "=2B=2F=76=2B" || charset == "=2B=2F=76=2F")
sCharset = "UTF-7";
else if(charset == "=DD=73=66=73")
sCharset = "UTF-EBCDIC";
else if(charset == "=84=31=95=33")
sCharset = "GB-18030";
else
{
nIgnore -= 3;
charset.erase(nIgnore);
if(charset == "=EF=BB=BF")
sCharset = "UTF-8";
else if(charset == "=F7=64=4C")
sCharset = "UTF-1";
else if(charset == "=0E=FE=FF")
sCharset = "SCSU";
else if(charset == "=FB=EE=28")
sCharset = "BOCU-1";
else
{
nIgnore -= 3;
charset.erase(nIgnore);
if(charset == "=FE=FF")
sCharset = "UTF-16BE";
else if(charset == "=FF=FE")
sCharset = "UTF-16LE";
else
nIgnore -= 6;
}
}
ip = nIgnore;
i = sContent.find('=', ip);
}
while(i != std::string::npos && i + 2 < sContent.length())
{
sRes.WriteString(sContent.c_str() + ip, i - ip);
std::string str = sContent.substr(i + 1, 2);
if(str.front() == '\n' || str.front() == '\r')
{
char ch = str[1];
if(ch != '\n' && ch != '\r')
sRes.WriteString(&ch, 1);
}
else
{
char* err;
char ch = (int)strtol(str.data(), &err, 16);
if(*err)
sRes.WriteString('=' + str);
else
sRes.WriteString(&ch, 1);
}
ip = i + 3;
i = sContent.find('=', ip);
}
if(ip != std::string::npos)
sRes.WriteString(sContent.c_str() + ip);
return sRes.GetData();
}
static void ReadMht(const std::string& sMhtContent, std::map<std::string, std::string>& sRes, NSStringUtils::CStringBuilderA& oRes)
{
size_t unContentPosition = 0, unCharsetBegin = 0, unCharsetEnd = std::string::npos;
NSStringFinder::TFoundedData<char> oData;
// Content-Type
oData = NSStringFinder::FindProperty(sMhtContent, "content-type", {":"}, {";", "\\n", "\\r"});
const std::string sContentType{oData.m_sValue};
if (sContentType.empty())
return;
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
{
oRes.WriteString(mhtTohtml(sMhtContent.substr(oData.m_unEndPosition, sMhtContent.length() - oData.m_unEndPosition)));
return;
}
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetBegin = oData.m_unEndPosition;
// name
// std::string sName = NSStringFinder::FindProperty(sMhtContent, "name", {"="}, {";", "\\n", "\\r"}, 0, unLastPosition);
// unContentPosition = std::max(unContentPosition, unLastPosition);
// Content-Location
oData = NSStringFinder::FindProperty(sMhtContent, "content-location", {":"}, {";", "\\n", "\\r"});
std::string sContentLocation{oData.m_sValue};
if (!oData.Empty())
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
// Content-ID
oData = NSStringFinder::FindProperty(sMhtContent, "content-id", {":"}, {";", "\\n", "\\r"});
std::string sContentID{oData.m_sValue};
if (!oData.Empty())
{
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
NSStringFinder::CutInside<std::string>(sContentID, "<", ">");
}
if (sContentLocation.empty() && !sContentID.empty())
sContentLocation = "cid:" + sContentID;
// Content-Transfer-Encoding
oData = NSStringFinder::FindProperty(sMhtContent, "content-transfer-encoding", {":"}, {";", "\\n", "\\r"});
const std::string sContentEncoding{oData.m_sValue};
if (!oData.Empty())
{
unContentPosition = std::max(unContentPosition, oData.m_unEndPosition);
unCharsetEnd = std::min(unCharsetEnd, oData.m_unBeginPosition);
}
// charset
std::string sCharset = "utf-8";
if (std::string::npos != unCharsetEnd && unCharsetBegin < unCharsetEnd)
{
sCharset = NSStringFinder::FindProperty(sMhtContent.substr(unCharsetBegin, unCharsetEnd - unCharsetBegin), "charset", {"="}, {";", "\\n", "\\r"}).m_sValue;
NSStringFinder::CutInside<std::string>(sCharset, "\"");
}
// Content
std::string sContent = sMhtContent.substr(unContentPosition, sMhtContent.length() - unContentPosition);
// std::wstring sExtention = NSFile::GetFileExtention(UTF8_TO_U(sName));
// std::transform(sExtention.begin(), sExtention.end(), sExtention.begin(), tolower);
// Основной документ
if (NSStringFinder::Equals(sContentType, "multipart/alternative"))
oRes.WriteString(mhtTohtml(sContent));
else if ((NSStringFinder::Find(sContentType, "text") /*&& (sExtention.empty() || NSStringFinder::EqualOf(sExtention, {L"htm", L"html", L"xhtml", L"css"}))*/)
|| (NSStringFinder::Equals(sContentType, "application/octet-stream") && NSStringFinder::Find(sContentLocation, "css")))
{
// Стили заключаются в тэг <style>
const bool bAddTagStyle = NSStringFinder::Equals(sContentType, "text/css") /*|| NSStringFinder::Equals(sExtention, L"css")*/ || NSStringFinder::Find(sContentLocation, "css");
if (bAddTagStyle)
oRes.WriteString("<style>");
if (NSStringFinder::Equals(sContentEncoding, "base64"))
sContent = Base64ToString(sContent, sCharset);
else if (NSStringFinder::EqualOf(sContentEncoding, {"8bit", "7bit"}) || sContentEncoding.empty())
{
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
}
}
else if (NSStringFinder::Equals(sContentEncoding, "quoted-printable"))
{
sContent = QuotedPrintableDecode(sContent, sCharset);
if (!NSStringFinder::Equals(sCharset, "utf-8") && !sCharset.empty())
{
NSUnicodeConverter::CUnicodeConverter oConverter;
sContent = U_TO_UTF8(oConverter.toUnicode(sContent, sCharset.data()));
}
}
if (NSStringFinder::Equals(sContentType, "text/html"))
sContent = U_TO_UTF8(htmlToXhtml(sContent, false));
oRes.WriteString(sContent);
if(bAddTagStyle)
oRes.WriteString("</style>");
}
// Картинки
else if ((NSStringFinder::Find(sContentType, "image") /*|| NSStringFinder::Equals(sExtention, L"gif")*/ || NSStringFinder::Equals(sContentType, "application/octet-stream")) &&
NSStringFinder::Equals(sContentEncoding, "base64"))
{
// if (NSStringFinder::Equals(sExtention, L"ico") || NSStringFinder::Find(sContentType, "ico"))
// sContentType = "image/jpg";
// else if(NSStringFinder::Equals(sExtention, L"gif"))
// sContentType = "image/gif";
int nSrcLen = (int)sContent.length();
int nDecodeLen = NSBase64::Base64DecodeGetRequiredLength(nSrcLen);
BYTE* pData = new BYTE[nDecodeLen];
if (TRUE == NSBase64::Base64Decode(sContent.c_str(), nSrcLen, pData, &nDecodeLen))
sRes.insert(std::make_pair(sContentLocation, "data:" + sContentType + ";base64," + sContent));
RELEASEARRAYOBJECTS(pData);
}
}
static std::string mhtTohtml(const std::string& sFileContent)
{
std::map<std::string, std::string> sRes;
NSStringUtils::CStringBuilderA oRes;
// Поиск boundary
NSStringFinder::TFoundedData<char> oData{NSStringFinder::FindProperty(sFileContent, "boundary", {"="}, {"\\r", "\\n", "\""})};
size_t nFound{oData.m_unEndPosition};
std::string sBoundary{oData.m_sValue};
if (sBoundary.empty())
{
size_t nFoundEnd = sFileContent.length();
nFound = 0;
ReadMht(sFileContent.substr(nFound, nFoundEnd), sRes, oRes);
return oRes.GetData();
}
NSStringFinder::CutInside<std::string>(sBoundary, "\"");
size_t nFoundEnd{nFound};
sBoundary = "--" + sBoundary;
size_t nBoundaryLength = sBoundary.length();
nFound = sFileContent.find(sBoundary, nFound) + nBoundaryLength;
// Цикл по boundary
while(nFound != std::string::npos)
{
nFoundEnd = sFileContent.find(sBoundary, nFound + nBoundaryLength);
if(nFoundEnd == std::string::npos)
break;
ReadMht(sFileContent.substr(nFound, nFoundEnd - nFound), sRes, oRes);
nFound = sFileContent.find(sBoundary, nFoundEnd);
}
std::string sFile = oRes.GetData();
for(const std::pair<std::string, std::string>& item : sRes)
{
std::string sName = item.first;
size_t found = sFile.find(sName);
size_t sfound = sName.rfind('/');
if(found == std::string::npos && sfound != std::string::npos)
found = sFile.find(sName.erase(0, sfound + 1));
while(found != std::string::npos)
{
size_t fq = sFile.find_last_of("\"\'>=", found);
if (std::string::npos == fq)
break;
char ch = sFile[fq];
if(ch != '\"' && ch != '\'')
fq++;
size_t tq = sFile.find_first_of("\"\'<> ", found) + 1;
if (std::string::npos == tq)
break;
if(sFile[tq] != '\"' && sFile[tq] != '\'')
tq--;
if(ch != '>')
{
std::string is = '\"' + item.second + '\"';
sFile.replace(fq, tq - fq, is);
found = sFile.find(sName, fq + is.length());
}
else
found = sFile.find(sName, tq);
}
}
return sFile;
}
static std::wstring mhtToXhtml(std::string& sFileContent)
{
sFileContent = mhtTohtml(sFileContent);
// Gumbo
GumboOptions options = kGumboDefaultOptions;
GumboOutput* output = gumbo_parse_with_options(&options, sFileContent.data(), sFileContent.length());
// prettyprint
NSStringUtils::CStringBuilderA oBuilder;
prettyprint(output->document, oBuilder);
// Конвертирование из string utf8 в wstring
return UTF8_TO_U(oBuilder.GetData());
}
// Заменяет сущности &,<,> в text
static void substitute_xml_entities_into_text(std::string& text)
{
// replacing & must come first
replace_all(text, "&", "&amp;");
replace_all(text, "<", "&lt;");
replace_all(text, ">", "&gt;");
}
// After running through Gumbo, the values of type "&#1;" are replaced with the corresponding code '0x01'
// Since the attribute value does not use control characters (value <= 0x09),
// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them.
// bug#73486
static void remove_control_symbols(std::string& text)
{
std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
while (itFound != text.end())
{
itFound = text.erase(itFound);
itFound = std::find_if(itFound, text.end(), [](unsigned char chValue){ return chValue <= 0x09; });
}
}
// Заменяет сущности " в text
static void substitute_xml_entities_into_attributes(std::string& text)
{
remove_control_symbols(text);
substitute_xml_entities_into_text(text);
replace_all(text, "\"", "&quot;");
}
static std::string handle_unknown_tag(GumboStringPiece* text)
{
if (text->data == NULL)
return "";
GumboStringPiece gsp = *text;
gumbo_tag_from_original_text(&gsp);
std::string sAtr = std::string(gsp.data, gsp.length);
size_t found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}");
while(found != std::string::npos)
{
sAtr.erase(found, 1);
found = sAtr.find_first_of("-'+,./=?;!*#@$_%<>&;\"\'()[]{}", found);
}
return sAtr;
}
static std::string get_tag_name(GumboNode* node)
{
std::string tagname = (node->type == GUMBO_NODE_DOCUMENT ? "document" : gumbo_normalized_tagname(node->v.element.tag));
if (tagname.empty())
tagname = handle_unknown_tag(&node->v.element.original_tag);
return tagname;
}
static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder)
{
if (node->v.document.has_doctype)
{
oBuilder.WriteString("<!DOCTYPE ");
oBuilder.WriteString(node->v.document.name);
std::string pi(node->v.document.public_identifier);
remove_control_symbols(pi);
if ((node->v.document.public_identifier != NULL) && !pi.empty())
{
oBuilder.WriteString(" PUBLIC \"");
oBuilder.WriteString(pi);
oBuilder.WriteString("\" \"");
oBuilder.WriteString(node->v.document.system_identifier);
oBuilder.WriteString("\"");
}
oBuilder.WriteString(">");
}
}
static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts)
{
std::vector<std::string> arrRepeat;
for (size_t i = 0; i < attribs->length; ++i)
{
GumboAttribute* at = static_cast<GumboAttribute*>(attribs->data[i]);
std::string sVal(at->value);
std::string sName(at->name);
remove_control_symbols(sVal);
remove_control_symbols(sName);
atts.WriteString(" ");
bool bCheck = false;
size_t nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}");
while(nBad != std::string::npos)
{
sName.erase(nBad, 1);
nBad = sName.find_first_of("+,.=?#%<>&;\"\'()[]{}", nBad);
if(sName.empty())
break;
bCheck = true;
}
if(sName.empty())
continue;
while(sName.front() >= '0' && sName.front() <= '9')
{
sName.erase(0, 1);
if(sName.empty())
break;
bCheck = true;
}
if(bCheck)
{
GumboAttribute* check = gumbo_get_attribute(attribs, sName.c_str());
if(check || std::find(arrRepeat.begin(), arrRepeat.end(), sName) != arrRepeat.end())
continue;
else
arrRepeat.push_back(sName);
}
if(sName.empty())
continue;
atts.WriteString(sName);
// determine original quote character used if it exists
std::string qs ="\"";
atts.WriteString("=");
atts.WriteString(qs);
substitute_xml_entities_into_attributes(sVal);
atts.WriteString(sVal);
atts.WriteString(qs);
}
}
static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode)
{
std::string key = "|" + get_tag_name(node) + "|";
bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos;
bool is_inline = nonbreaking_inline.find(key) != std::string::npos;
bool is_like_inline = treat_like_inline.find(key) != std::string::npos;
GumboVector* children = &node->v.element.children;
for (size_t i = 0; i < children->length; i++)
{
GumboNode* child = static_cast<GumboNode*> (children->data[i]);
if (child->type == GUMBO_NODE_TEXT)
{
std::string val(child->v.text.text);
remove_control_symbols(val);
substitute_xml_entities_into_text(val);
// Избавление от FF
size_t found = val.find_first_of("\014");
while(found != std::string::npos)
{
val.erase(found, 1);
found = val.find_first_of("\014", found);
}
contents.WriteString(val);
}
else if ((child->type == GUMBO_NODE_ELEMENT) || (child->type == GUMBO_NODE_TEMPLATE))
prettyprint(child, contents, bCheckValidNode);
else if (child->type == GUMBO_NODE_WHITESPACE)
{
if (keep_whitespace || is_inline || is_like_inline)
contents.WriteString(child->v.text.text);
}
else if (child->type != GUMBO_NODE_COMMENT)
{
// Сообщение об ошибке
// Does this actually exist: (child->type == GUMBO_NODE_CDATA)
// fprintf(stderr, "unknown element of type: %d\n", child->type);
}
}
}
static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilder, bool bCheckValidNode)
{
// special case the document node
if (node->type == GUMBO_NODE_DOCUMENT)
{
build_doctype(node, oBuilder);
prettyprint_contents(node, oBuilder, bCheckValidNode);
return;
}
std::string tagname = get_tag_name(node);
remove_control_symbols(tagname);
if (NodeIsUnprocessed(tagname))
return;
if (bCheckValidNode)
bCheckValidNode = !IsUnckeckedNodes(tagname);
if (bCheckValidNode && html_tags.end() == std::find(html_tags.begin(), html_tags.end(), tagname))
{
prettyprint_contents(node, oBuilder, bCheckValidNode);
return;
}
std::string close = "";
std::string closeTag = "";
std::string key = "|" + tagname + "|";
bool is_empty_tag = empty_tags.find(key) != std::string::npos;
// determine closing tag type
if (is_empty_tag)
close = "/";
else
closeTag = "</" + tagname + ">";
// build results
oBuilder.WriteString("<" + tagname);
// build attr string
const GumboVector* attribs = &node->v.element.attributes;
build_attributes(attribs, oBuilder);
oBuilder.WriteString(close + ">");
// prettyprint your contents
prettyprint_contents(node, oBuilder, bCheckValidNode);
oBuilder.WriteString(closeTag);
std::wstring htmlToXhtml(std::string& sFileContent, bool bNeedConvert);
std::wstring mhtToXhtml(std::string& sFileContent);
}
#endif // HTMLTOXHTML_H

View File

@ -0,0 +1,5 @@
<<<<<<<
if((c >= 'a' && c <= 'z') || (c>= 'A' && c<= 'Z') || (c >= '0' && c<= '9')){
=======
if((c >= 'a' && c <= 'z') || (c>= 'A' && c<= 'Z') || (c >= '0' && c<= '9') || ('-' == c) || ('_' == c) || ('.' == c) || ('~' == c)){
>>>>>>>

View File

@ -105,11 +105,37 @@ namespace NSNetwork
{
static NSString* StringWToNSString ( const std::wstring& Str )
{
// Returns +1 retained NSString (alloc/init). Caller must release in non-ARC.
NSString* pString = [ [ NSString alloc ]
initWithBytes : (char*)Str.data() length : Str.size() * sizeof(wchar_t)
encoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE ) ];
initWithBytes : (char*)Str.data() length : Str.size() * sizeof(wchar_t)
encoding : CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingUTF32LE ) ];
return pString;
}
// NSURLComponents correctly handles mixed input (already-encoded + raw characters)
// without double-encoding, but normalises unreserved percent-sequences (%5F → _).
// If preserving the exact encoding is required, use [NSURL URLWithString:] instead.
static NSURL* SafeURLFromString(NSString* urlString)
{
if (!urlString || urlString.length == 0)
return nil;
NSURL* url = [NSURL URLWithString:urlString];
if (url)
return url;
// Fallback: the string contains unencoded characters (spaces, cyrillic,
// brackets, etc.). URLFragmentAllowedCharacterSet includes '%', so
// existing percent-sequences won't be double-encoded.
NSString* encoded =
[urlString stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLFragmentAllowedCharacterSet]];
if (!encoded)
return nil;
return [NSURL URLWithString:encoded];
}
class CFileTransporterBaseCocoa : public CFileTransporterBase
{
public :
@ -145,83 +171,162 @@ namespace NSNetwork
return 0;
#endif
// stringURL: +1 retained (alloc/init). Must be released on all exit paths in non-ARC.
NSString* stringURL = StringWToNSString(m_sDownloadFileUrl);
NSString* escapedURL = [stringURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL* url = SafeURLFromString(stringURL);
int nResult = 1;
if (m_pSession)
if (!url)
{
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:escapedURL]];
__block NSData* result = nil;
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
NSURLSession* _session = ((CSessionMAC*)m_pSession->m_pInternal)->m_session;
if (nil == _session)
_session = [NSURLSession sharedSession];
[[_session dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse* response, NSError *error) {
if (error == nil)
result = data;
dispatch_semaphore_signal(sem);
}] resume];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if (result)
{
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
[result writeToFile:filePath atomically:YES];
nResult = 0;
}
else
{
nResult = 1;
}
return nResult;
}
else
{
NSURL* url = [NSURL URLWithString:escapedURL];
NSData* urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
[urlData writeToFile:filePath atomically:YES];
#if defined(_IOS)
return 0;
#else
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
{
[stringURL release];
//[url release];
[urlData release];
}
#endif
#endif
return 0;
}
#if defined(_IOS)
NSLog(@"[DownloadFile] Invalid URL: %@", stringURL);
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
[stringURL release];
#endif
#endif
return 1;
#else
#ifndef _ASC_USE_ARC_
}
// Select session. If the caller provided one, prefer it; fall back to the shared
// singleton. [NSURLSession sharedSession] is a singleton -- never retain/release it.
NSURLSession* session = nil;
if (m_pSession && m_pSession->m_pInternal)
{
CSessionMAC* sessionInternal = (CSessionMAC*)m_pSession->m_pInternal;
session = sessionInternal->m_session;
}
if (!session)
session = [NSURLSession sharedSession];
// NSData initWithContentsOfURL / dataWithContentsOfURL must NOT be used for HTTP:
// - Fails silently on CDN responses with Transfer-Encoding: chunked
// (returns NSCocoaErrorDomain Code=256 on some iOS versions)
// - Does not follow HTTP redirects reliably
// - Ignores Content-Encoding (gzip, br)
// - Has no timeout, can block indefinitely
// NSURLSession handles all of the above correctly on all supported iOS/macOS versions.
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
// In non-ARC, __block variables are NOT automatically retained by the block.
// |data| passed to the completion handler is autoreleased; without an explicit
// retain it may be deallocated before semaphore_wait returns on the calling thread.
// We therefore retain inside the block and release after use below.
__block NSData* resultData = nil;
NSURLSessionDataTask* task =
[session dataTaskWithRequest:urlRequest
completionHandler:^(NSData* data, NSURLResponse* response, NSError* error)
{
if (error)
{
NSLog(@"[DownloadFile] Network error: %@, URL: %@", error, url);
}
else if ([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSInteger status = [(NSHTTPURLResponse*)response statusCode];
if (status >= 200 && status < 300)
{
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
resultData = [data retain];
else
#endif
#endif
resultData = data;
}
else
{
NSLog(@"[DownloadFile] HTTP %ld, URL: %@", (long)status, url);
}
}
else
{
// Non-HTTP scheme (e.g. file://) -- accept unconditionally.
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
resultData = [data retain];
else
#endif
#endif
resultData = data;
}
dispatch_semaphore_signal(sem);
}];
[task resume];
// 60-second hard timeout. DISPATCH_TIME_FOREVER must not be used: if the network
// stack silently drops the connection the completion handler may never fire,
// leaving this thread suspended indefinitely (deadlock).
const int64_t kTimeoutSeconds = 60;
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, kTimeoutSeconds * NSEC_PER_SEC);
long waitResult = dispatch_semaphore_wait(sem, timeout);
// dispatch_semaphore_create returns a +1 object. Release it in non-ARC.
// In ARC (including all iOS targets) GCD objects are managed automatically.
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
dispatch_release(sem);
#endif
#endif
if (waitResult != 0)
{
// Timeout expired. Cancel the in-flight task so that the completion handler
// is called with NSURLErrorCancelled (data == nil), preventing it from writing
// to resultData after we return and corrupting memory in non-ARC.
[task cancel];
NSLog(@"[DownloadFile] Timeout after %llds, URL: %@", (long long)kTimeoutSeconds, url);
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
{
// resultData could theoretically be non-nil if the completion handler
// raced with the timeout check on a multicore device before cancel ran.
[resultData release];
[stringURL release];
//[url release];
}
#endif
#endif
#endif
#endif
return 1;
}
if (!resultData)
{
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
[stringURL release];
#endif
#endif
return 1;
}
// filePath: +1 retained (alloc/init). Must be released in non-ARC.
NSString* filePath = StringWToNSString(m_sDownloadFilePath);
BOOL written = [resultData writeToFile:filePath atomically:YES];
if (!written)
NSLog(@"[DownloadFile] Failed to write file: %@", filePath);
#if !defined(_IOS)
#ifndef _ASC_USE_ARC_
if (!GetARCEnabled())
{
[resultData release];
[filePath release];
[stringURL release];
}
#endif
#endif
return written ? 0 : 1;
}
virtual int UploadData() override

View File

@ -478,6 +478,15 @@ core_android {
!core_android_no_unistd {
DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H
}
core_release {
QMAKE_CFLAGS += -g0
QMAKE_CXXFLAGS += -g0
QMAKE_LFLAGS += -Wl,-s
QMAKE_CFLAGS -= -fno-limit-debug-info
QMAKE_CXXFLAGS -= -fno-limit-debug-info
}
}
core_debug {

View File

@ -140,8 +140,14 @@ namespace NSStringUtils
AddSize(1);
*m_pDataCur++ = _c;
++m_lSizeCur;
}
}
void CStringBuilderA::AddChar2Safe(const char& _c1, const char& _c2)
{
AddSize(2);
*m_pDataCur++ = _c1;
*m_pDataCur++ = _c2;
m_lSizeCur += 2;
}
size_t CStringBuilderA::GetCurSize()
{
return m_lSizeCur;
@ -195,6 +201,16 @@ namespace NSStringUtils
m_pDataCur = m_pData;
m_lSizeCur = m_lSize;
}
CStringBuilder::CStringBuilder(size_t nSize)
{
m_lSize = nSize;
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
m_lSizeCur = 0;
m_pDataCur = m_pData;
return;
}
CStringBuilder::~CStringBuilder()
{
if (NULL != m_pData)

View File

@ -63,6 +63,7 @@ namespace NSStringUtils
void AddCharNoSafe(const char& _c);
void AddCharSafe(const char& _c);
void AddChar2Safe(const char& _c1, const char& _c2);
size_t GetCurSize();
void SetCurSize(size_t lCurSize);
@ -86,6 +87,7 @@ namespace NSStringUtils
public:
CStringBuilder();
CStringBuilder(size_t nSize);
virtual ~CStringBuilder();
virtual void AddSize(size_t nSize);

View File

@ -415,6 +415,34 @@ bool CxImageBMP::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
bihtoh(pdib);
if (pdib->biSize < sizeof(BITMAPCOREHEADER))
return false;
if (pdib->biBitCount != 0 && pdib->biBitCount != 1 &&
pdib->biBitCount != 4 && pdib->biBitCount != 8 &&
pdib->biBitCount != 16 && pdib->biBitCount != 24 &&
pdib->biBitCount != 32)
return false;
unsigned long long stride = ((unsigned long long)pdib->biWidth * pdib->biBitCount + 31) / 32 * 4;
unsigned long long height = std::llabs((long long)pdib->biHeight);
unsigned long long expected = stride * height;
unsigned long long num_colors = 0;
if (pdib->biBitCount > 0 && pdib->biBitCount <= 8) {
num_colors = (pdib->biClrUsed != 0)
? pdib->biClrUsed
: (1ULL << pdib->biBitCount);
} else if (pdib->biClrUsed > 0) {
num_colors = pdib->biClrUsed;
}
unsigned long long palette_size = num_colors * 4;
unsigned long long masks_size = (pdib->biCompression == BI_BITFIELDS) ? 12ULL : 0ULL;
unsigned long long fileSize = fh->Size();
if ((unsigned long long)pdib->biSize + palette_size + masks_size + expected > fileSize)
return false;
switch (pdib->biSize) // what type of bitmap info is this?
{
case sizeof(BITMAPINFOHEADER):

View File

@ -347,11 +347,11 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
}
if (!bIsBreak)
bIsBreak = !this->ExecuteCommand(L"Api.asc_nativeInitBuilder();");
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_nativeInitBuilder();");
if (!bIsBreak)
bIsBreak = !this->ExecuteCommand(L"Api.asc_SetSilentMode(true);");
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(true);");
if (!bIsBreak)
bIsBreak = !this->ExecuteCommand(L"Api.asc_showComments();");
bIsBreak = !this->ExecuteCommand(L"Asc.editor.asc_showComments();");
LOGGER_SPEED_LAP("open");
@ -425,7 +425,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
bIsSilentMode = true;
if (bIsSilentMode)
this->ExecuteCommand(L"Api.asc_SetSilentMode(false);", NULL, isEnterContext);
this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(false);", NULL, isEnterContext);
std::wstring strError;
bool bIsError = Doct_renderer_SaveFile_ForBuilder(_formatDst,
@ -437,7 +437,7 @@ bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path,
sJsonParams);
if (bIsSilentMode)
this->ExecuteCommand(L"Api.asc_SetSilentMode(true);", NULL, isEnterContext);
this->ExecuteCommand(L"Asc.editor.asc_SetSilentMode(true);", NULL, isEnterContext);
if (isEnterContext)
m_context->Exit();
@ -1507,7 +1507,7 @@ namespace NSDoctRenderer
if (m_pInternal->m_oParams.m_bSaveWithDoctrendererMode)
{
// перед сохранением в такой схеме нужно скинуть изменения
this->ExecuteCommand(L"Api.asc_Save();");
this->ExecuteCommand(L"Asc.editor.asc_Save();");
}
const wchar_t* sParams = NULL;

View File

@ -287,7 +287,10 @@ namespace NSDoctRenderer
JSSmart<CJSObject> js_objectApi = api_js_maybe_null;
if (!js_objectApi.IsInit() || js_objectApi->isUndefined())
js_objectApi = global_js->get("Api")->toObject();
{
JSSmart<CJSObject> js_objectAsc = global_js->get("Asc")->toObject();
js_objectApi = js_objectAsc->get("editor")->toObject();
}
bool bIsBreak = false;
if (js_objectApi->isUndefined() || !js_objectApi->isObject())
@ -687,7 +690,8 @@ namespace NSDoctRenderer
bIsBreak = true;
}
js_objectApi = global_js->get("Api")->toObject();
JSSmart<CJSObject> js_objectAsc = global_js->get("Asc")->toObject();
js_objectApi = js_objectAsc->get("editor")->toObject();
if (try_catch->Check())
{
strError = L"code=\"open\"";

View File

@ -1374,6 +1374,25 @@ namespace Aggplus
}
}
template<class span_gen_type>
void CGraphics::render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha)
{
if (m_nBlendMode != agg::comp_op_src_over)
{
typedef agg::renderer_scanline_aa<comp_renderer_type, span_alloc_type, span_gen_type> aa_renderer_type;
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
comp_renderer_type ren_base(pixfmt);
aa_renderer_type ri(ren_base, span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
}
else
{
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
}
}
template<class Renderer>
void CGraphics::render_scanlines(Renderer& ren)
{
@ -1417,12 +1436,9 @@ namespace Aggplus
if (m_nBlendMode != agg::comp_op_src_over)
{
typedef agg::renderer_scanline_aa_solid<comp_renderer_type> solid_comp_renderer_type;
solid_comp_renderer_type ren_solid;
comp_renderer_type ren_base;
pixfmt_type_comp pixfmt(m_frame_buffer.ren_buf(), m_nBlendMode);
ren_base.attach(pixfmt);
ren_solid.attach(ren_base);
comp_renderer_type ren_base(pixfmt);
solid_comp_renderer_type ren_solid(ren_base);
ren_solid.color(dwColor.GetAggColor());
render_scanlines(ren_solid);
@ -1727,6 +1743,70 @@ namespace Aggplus
}
}
template<typename pixfmt>
void CGraphics::DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha)
{
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
span_gen_type sg(img_src, interpolator);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
span_gen_type sg(img_src, interpolator);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
render_blendmode(sg, span_allocator, Alpha);
break;
}
default:
break;
}
}
void CGraphics::DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha)
{
span_alloc_type span_allocator;
@ -1738,158 +1818,11 @@ namespace Aggplus
PatRendBuff.attach((BYTE*)pImgBuff, dwImgWidth, dwImgHeight, nImgStride);
int nCurrentMode = 255;
if (!m_bSwapRGB)
{
typedef agg::pixfmt_bgra32 pixfmt;
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
default:
break;
}
}
DoFillPathTextureClampSz2_Impl<agg::pixfmt_bgra32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
else
{
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::image_accessor_clone<pixfmt> img_source_type;
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
switch (nCurrentMode)
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 1:
{
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 2:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 3:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 4:
{
typedef agg::span_image_filter_rgba_2x2<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
case 255:
{
typedef agg::span_image_resample_rgba_affine_for_draw<img_source_type> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
default:
break;
}
}
DoFillPathTextureClampSz2_Impl<agg::pixfmt_rgba32>(PatRendBuff, interpolator, span_allocator, nCurrentMode, Alpha);
}
template<class ColorSpacePix>

View File

@ -430,6 +430,9 @@ public:
protected:
template<class span_gen_type>
void render_blendmode(span_gen_type& sg, span_alloc_type& span_allocator, BYTE Alpha);
template<class Renderer>
void render_scanlines(Renderer& ren);
template<class Rasterizer, class Renderer>
@ -447,6 +450,9 @@ protected:
//--test
void DoFillPathHatch(CBrushHatch *pBrush);
void DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride);
template<typename pixfmt>
void DoFillPathTextureClampSz2_Impl(agg::rendering_buffer& PatRendBuff, interpolator_type_linear& interpolator, span_alloc_type& span_allocator, int nCurrentMode, BYTE Alpha);
void DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride, BYTE Alpha = 255);
template<class ColorSpacePix>

View File

@ -481,6 +481,8 @@ namespace NSOnlineOfficeBinToPdf
double m3 = oReader.ReadDouble();
double m4 = oReader.ReadDouble();
clipRect = Aggplus::RectF_T<double>(m1, m2, m3, m4);
long type;
pRenderer->get_BrushTextureMode(&type);
if (type != c_BrushTextureModeStretch)
@ -489,7 +491,6 @@ namespace NSOnlineOfficeBinToPdf
m2 = 0.0;
}
clipRect = Aggplus::RectF_T<double>(m1, m2, m3, m4);
pRenderer->BrushRect(bIsEnableBrushRect ? 1 : 0, m1, m2, m3, m4);
break;
}

View File

@ -151,20 +151,22 @@ CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annot
m_oBorder.nType = 0;
m_oBorder.dWidth = 0.0;
m_pMarkupPr = NULL;
m_pTextPr = NULL;
m_pInkPr = NULL;
m_pLinePr = NULL;
m_pTextMarkupPr = NULL;
m_pSquareCirclePr = NULL;
m_pPolygonLinePr = NULL;
m_pPopupPr = NULL;
m_pFreeTextPr = NULL;
m_pCaretPr = NULL;
m_pStampPr = NULL;
m_pRedactPr = NULL;
m_pLinkPr = NULL;
m_pWidgetPr = NULL;
m_pMarkupPr = NULL;
m_pTextPr = NULL;
m_pInkPr = NULL;
m_pLinePr = NULL;
m_pTextMarkupPr = NULL;
m_pSquareCirclePr = NULL;
m_pPolygonLinePr = NULL;
m_pPopupPr = NULL;
m_pFreeTextPr = NULL;
m_pCaretPr = NULL;
m_pStampPr = NULL;
m_pRedactPr = NULL;
m_pLinkPr = NULL;
m_pFileAttachmentPr = NULL;
m_pScreenPr = NULL;
m_pWidgetPr = NULL;
}
CAnnotFieldInfo::~CAnnotFieldInfo()
{
@ -181,6 +183,8 @@ CAnnotFieldInfo::~CAnnotFieldInfo()
RELEASEOBJECT(m_pStampPr);
RELEASEOBJECT(m_pRedactPr);
RELEASEOBJECT(m_pLinkPr);
RELEASEOBJECT(m_pFileAttachmentPr);
RELEASEOBJECT(m_pScreenPr);
RELEASEOBJECT(m_pWidgetPr);
}
@ -274,6 +278,18 @@ void CAnnotFieldInfo::SetType(int nType)
m_pPopupPr = new CAnnotFieldInfo::CPopupAnnotPr();
break;
}
case EAnnotType::FileAttachment:
{
RELEASEOBJECT(m_pFileAttachmentPr);
m_pFileAttachmentPr = new CAnnotFieldInfo::CFileAttachmentAnnotPr();
break;
}
case EAnnotType::Screen:
{
RELEASEOBJECT(m_pScreenPr);
m_pScreenPr = new CAnnotFieldInfo::CScreenAnnotPr();
break;
}
case EAnnotType::Redact:
{
CreateMarkup();
@ -403,21 +419,31 @@ bool CAnnotFieldInfo::IsLink() const
{
return (m_nType == 1);
}
bool CAnnotFieldInfo::IsFileAttachment() const
{
return (m_nType == 16);
}
bool CAnnotFieldInfo::IsScreen() const
{
return (m_nType == 20);
}
CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; }
CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; }
CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; }
CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; }
CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; }
CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; }
CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; }
CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; }
CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; }
CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; }
CAnnotFieldInfo::CStampAnnotPr* CAnnotFieldInfo::GetStampAnnotPr() { return m_pStampPr; }
CAnnotFieldInfo::CRedactAnnotPr* CAnnotFieldInfo::GetRedactAnnotPr() { return m_pRedactPr; }
CAnnotFieldInfo::CLinkAnnotPr* CAnnotFieldInfo::GetLinkAnnotPr() { return m_pLinkPr; }
CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; }
CAnnotFieldInfo::CMarkupAnnotPr* CAnnotFieldInfo::GetMarkupAnnotPr() { return m_pMarkupPr; }
CAnnotFieldInfo::CTextAnnotPr* CAnnotFieldInfo::GetTextAnnotPr() { return m_pTextPr; }
CAnnotFieldInfo::CInkAnnotPr* CAnnotFieldInfo::GetInkAnnotPr() { return m_pInkPr; }
CAnnotFieldInfo::CLineAnnotPr* CAnnotFieldInfo::GetLineAnnotPr() { return m_pLinePr; }
CAnnotFieldInfo::CTextMarkupAnnotPr* CAnnotFieldInfo::GetTextMarkupAnnotPr() { return m_pTextMarkupPr; }
CAnnotFieldInfo::CSquareCircleAnnotPr* CAnnotFieldInfo::GetSquareCircleAnnotPr() { return m_pSquareCirclePr; }
CAnnotFieldInfo::CPolygonLineAnnotPr* CAnnotFieldInfo::GetPolygonLineAnnotPr() { return m_pPolygonLinePr; }
CAnnotFieldInfo::CPopupAnnotPr* CAnnotFieldInfo::GetPopupAnnotPr() { return m_pPopupPr; }
CAnnotFieldInfo::CFreeTextAnnotPr* CAnnotFieldInfo::GetFreeTextAnnotPr() { return m_pFreeTextPr; }
CAnnotFieldInfo::CCaretAnnotPr* CAnnotFieldInfo::GetCaretAnnotPr() { return m_pCaretPr; }
CAnnotFieldInfo::CStampAnnotPr* CAnnotFieldInfo::GetStampAnnotPr() { return m_pStampPr; }
CAnnotFieldInfo::CRedactAnnotPr* CAnnotFieldInfo::GetRedactAnnotPr() { return m_pRedactPr; }
CAnnotFieldInfo::CLinkAnnotPr* CAnnotFieldInfo::GetLinkAnnotPr() { return m_pLinkPr; }
CAnnotFieldInfo::CFileAttachmentAnnotPr* CAnnotFieldInfo::GetFileAttachmentAnnotPr() { return m_pFileAttachmentPr; }
CAnnotFieldInfo::CScreenAnnotPr* CAnnotFieldInfo::GetScreenAnnotPr() { return m_pScreenPr; }
CAnnotFieldInfo::CWidgetAnnotPr* CAnnotFieldInfo::GetWidgetAnnotPr() { return m_pWidgetPr; }
bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
{
@ -506,6 +532,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
m_pStampPr->Read(pReader, nFlags);
else if (IsRedact())
m_pRedactPr->Read(pReader, nFlags);
else if (IsFileAttachment())
m_pFileAttachmentPr->Read(pReader, nFlags);
}
else if (IsPopup())
m_pPopupPr->Read(pReader);
@ -513,6 +541,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta
m_pWidgetPr->Read(pReader, nType);
else if (IsLink())
m_pLinkPr->Read(pReader);
else if (IsScreen())
m_pScreenPr->Read(pReader);
return m_nType != -1;
}
@ -834,6 +864,7 @@ CAnnotFieldInfo::CLinkAnnotPr::~CLinkAnnotPr()
}
BYTE CAnnotFieldInfo::CLinkAnnotPr::GetH() const { return m_nH; }
int CAnnotFieldInfo::CLinkAnnotPr::GetFlags() const { return m_nFlags; }
void CAnnotFieldInfo::CLinkAnnotPr::GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4) { dRD1 = m_dRD[0]; dRD2 = m_dRD[1]; dRD3 = m_dRD[2]; dRD4 = m_dRD[3]; }
const std::vector<double>& CAnnotFieldInfo::CLinkAnnotPr::GetQuadPoints() { return m_arrQuadPoints; }
CAnnotFieldInfo::CActionFieldPr* CAnnotFieldInfo::CLinkAnnotPr::GetA() { return m_pAction; }
CAnnotFieldInfo::CActionFieldPr* CAnnotFieldInfo::CLinkAnnotPr::GetPA() { return m_pPA; }
@ -859,6 +890,126 @@ void CAnnotFieldInfo::CLinkAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader*
for (int i = 0; i < n; ++i)
m_arrQuadPoints.push_back(pReader->ReadDouble());
}
if (m_nFlags & (1 << 4))
{
m_dRD[0] = pReader->ReadDouble();
m_dRD[1] = pReader->ReadDouble();
m_dRD[2] = pReader->ReadDouble();
m_dRD[3] = pReader->ReadDouble();
}
}
CAnnotFieldInfo::CFileAttachmentAnnotPr::CFileAttachmentAnnotPr()
{
}
CAnnotFieldInfo::CFileAttachmentAnnotPr::~CFileAttachmentAnnotPr()
{
}
int CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileFlag() const { return m_nFileFlag; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetName() { return m_wsName; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFS() { return m_wsFS; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetF() { return m_wsF; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetUF() { return m_wsUF; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetDOS() { return m_wsDOS; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetMac() { return m_wsMac; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetUnix() { return m_wsUnix; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetDesc() { return m_wsDesc; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileF() { return m_wsFileF; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileUF() { return m_wsFileUF; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileDOS() { return m_wsFileDOS; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileMac() { return m_wsFileMac; }
const std::wstring& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetFileUnix() { return m_wsFileUnix; }
const std::pair<std::wstring, std::wstring>& CAnnotFieldInfo::CFileAttachmentAnnotPr::GetID() { return m_wsID; }
void CAnnotFieldInfo::CFileAttachmentAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags)
{
if (nFlags & (1 << 15))
m_wsName = pReader->ReadString();
if (nFlags & (1 << 16))
m_wsFS = pReader->ReadString();
if (nFlags & (1 << 17))
m_wsF = pReader->ReadString();
if (nFlags & (1 << 18))
m_wsUF = pReader->ReadString();
if (nFlags & (1 << 19))
m_wsDOS = pReader->ReadString();
if (nFlags & (1 << 20))
m_wsMac = pReader->ReadString();
if (nFlags & (1 << 21))
m_wsUnix = pReader->ReadString();
if (nFlags & (1 << 22))
{
m_wsID.first = pReader->ReadString();
m_wsID.second = pReader->ReadString();
}
if (nFlags & (1 << 24))
{
m_nFileFlag = pReader->ReadInt();
if (m_nFileFlag & (1 << 0))
m_wsFileF = pReader->ReadString();
if (m_nFileFlag & (1 << 1))
m_wsFileUF = pReader->ReadString();
if (m_nFileFlag & (1 << 2))
m_wsFileDOS = pReader->ReadString();
if (m_nFileFlag & (1 << 3))
m_wsFileMac = pReader->ReadString();
if (m_nFileFlag & (1 << 4))
m_wsFileUnix = pReader->ReadString();
}
if (nFlags & (1 << 26))
m_wsDesc = pReader->ReadString();
}
CAnnotFieldInfo::CScreenAnnotPr::CScreenAnnotPr()
{
}
CAnnotFieldInfo::CScreenAnnotPr::~CScreenAnnotPr()
{
}
int CAnnotFieldInfo::CScreenAnnotPr::GetR() const { return m_nR; }
int CAnnotFieldInfo::CScreenAnnotPr::GetFlags() const { return m_nFlags; }
const std::wstring& CAnnotFieldInfo::CScreenAnnotPr::GetT() { return m_wsT; }
const std::vector<double>& CAnnotFieldInfo::CScreenAnnotPr::GetBC() { return m_arrBC; }
const std::vector<double>& CAnnotFieldInfo::CScreenAnnotPr::GetBG() { return m_arrBG; }
const std::vector<CAnnotFieldInfo::CActionFieldPr*>& CAnnotFieldInfo::CScreenAnnotPr::GetActions() { return m_arrAction; }
void CAnnotFieldInfo::CScreenAnnotPr::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader)
{
m_nFlags = pReader->ReadInt();
if (m_nFlags & (1 << 0))
m_wsT = pReader->ReadString();
if (m_nFlags & (1 << 1))
{
int n = pReader->ReadInt();
m_arrBC.reserve(n);
for (int i = 0; i < n; ++i)
m_arrBC.push_back(pReader->ReadDouble());
}
if (m_nFlags & (1 << 2))
m_nR = pReader->ReadInt();
if (m_nFlags & (1 << 3))
{
int n = pReader->ReadInt();
m_arrBG.reserve(n);
for (int i = 0; i < n; ++i)
m_arrBG.push_back(pReader->ReadDouble());
}
if (m_nFlags & (1 << 4))
{
int nAction = pReader->ReadInt();
for (int i = 0; i < nAction; ++i)
{
std::wstring wsType = pReader->ReadString();
CAnnotFieldInfo::CActionFieldPr* pA = ReadAction(pReader);
if (pA)
{
pA->wsType = wsType;
m_arrAction.push_back(pA);
}
}
}
}
bool CAnnotFieldInfo::CPopupAnnotPr::IsOpen() const { return m_bOpen; }

View File

@ -59,6 +59,7 @@ public:
Ink = 14,
Popup = 15,
FileAttachment = 16,
Screen = 20,
Redact = 25,
Widget = 26,
WidgetPushButton = 27,
@ -488,6 +489,7 @@ public:
BYTE GetH() const;
int GetFlags() const;
void GetRD(double& dRD1, double& dRD2, double& dRD3, double& dRD4);
const std::vector<double>& GetQuadPoints();
CActionFieldPr* GetA();
CActionFieldPr* GetPA();
@ -497,11 +499,78 @@ public:
private:
BYTE m_nH;
int m_nFlags;
double m_dRD[4]{};
std::vector<double> m_arrQuadPoints;
CActionFieldPr* m_pAction;
CActionFieldPr* m_pPA;
};
class GRAPHICS_DECL CFileAttachmentAnnotPr
{
public:
CFileAttachmentAnnotPr();
~CFileAttachmentAnnotPr();
int GetFileFlag() const;
const std::wstring& GetName();
const std::wstring& GetFS();
const std::wstring& GetF();
const std::wstring& GetUF();
const std::wstring& GetDOS();
const std::wstring& GetMac();
const std::wstring& GetUnix();
const std::wstring& GetDesc();
const std::wstring& GetFileF();
const std::wstring& GetFileUF();
const std::wstring& GetFileDOS();
const std::wstring& GetFileMac();
const std::wstring& GetFileUnix();
const std::pair<std::wstring, std::wstring>& GetID();
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, int nFlags);
private:
int m_nFileFlag;
std::wstring m_wsName;
std::wstring m_wsFS;
std::wstring m_wsF;
std::wstring m_wsUF;
std::wstring m_wsDOS;
std::wstring m_wsMac;
std::wstring m_wsUnix;
std::wstring m_wsDesc;
std::wstring m_wsFileF;
std::wstring m_wsFileUF;
std::wstring m_wsFileDOS;
std::wstring m_wsFileMac;
std::wstring m_wsFileUnix;
std::pair<std::wstring, std::wstring> m_wsID;
};
class GRAPHICS_DECL CScreenAnnotPr
{
public:
CScreenAnnotPr();
~CScreenAnnotPr();
int GetR() const;
int GetFlags() const;
const std::wstring& GetT();
const std::vector<double>& GetBC();
const std::vector<double>& GetBG();
const std::vector<CActionFieldPr*>& GetActions();
void Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader);
private:
int m_nR;
int m_nFlags;
std::wstring m_wsT;
std::vector<double> m_arrBC;
std::vector<double> m_arrBG;
std::vector<CActionFieldPr*> m_arrAction;
};
CAnnotFieldInfo();
virtual ~CAnnotFieldInfo();
@ -543,21 +612,25 @@ public:
bool IsStamp() const;
bool IsRedact() const;
bool IsLink() const;
bool IsFileAttachment() const;
bool IsScreen() const;
CMarkupAnnotPr* GetMarkupAnnotPr();
CTextAnnotPr* GetTextAnnotPr();
CInkAnnotPr* GetInkAnnotPr();
CLineAnnotPr* GetLineAnnotPr();
CTextMarkupAnnotPr* GetTextMarkupAnnotPr();
CSquareCircleAnnotPr* GetSquareCircleAnnotPr();
CPolygonLineAnnotPr* GetPolygonLineAnnotPr();
CPopupAnnotPr* GetPopupAnnotPr();
CFreeTextAnnotPr* GetFreeTextAnnotPr();
CCaretAnnotPr* GetCaretAnnotPr();
CStampAnnotPr* GetStampAnnotPr();
CRedactAnnotPr* GetRedactAnnotPr();
CLinkAnnotPr* GetLinkAnnotPr();
CWidgetAnnotPr* GetWidgetAnnotPr();
CMarkupAnnotPr* GetMarkupAnnotPr();
CTextAnnotPr* GetTextAnnotPr();
CInkAnnotPr* GetInkAnnotPr();
CLineAnnotPr* GetLineAnnotPr();
CTextMarkupAnnotPr* GetTextMarkupAnnotPr();
CSquareCircleAnnotPr* GetSquareCircleAnnotPr();
CPolygonLineAnnotPr* GetPolygonLineAnnotPr();
CPopupAnnotPr* GetPopupAnnotPr();
CFreeTextAnnotPr* GetFreeTextAnnotPr();
CCaretAnnotPr* GetCaretAnnotPr();
CStampAnnotPr* GetStampAnnotPr();
CRedactAnnotPr* GetRedactAnnotPr();
CLinkAnnotPr* GetLinkAnnotPr();
CFileAttachmentAnnotPr* GetFileAttachmentAnnotPr();
CScreenAnnotPr* GetScreenAnnotPr();
CWidgetAnnotPr* GetWidgetAnnotPr();
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector);
@ -590,20 +663,22 @@ private:
LONG m_nRenderLen;
BYTE* m_pRender;
CMarkupAnnotPr* m_pMarkupPr;
CTextAnnotPr* m_pTextPr;
CInkAnnotPr* m_pInkPr;
CLineAnnotPr* m_pLinePr;
CTextMarkupAnnotPr* m_pTextMarkupPr;
CSquareCircleAnnotPr* m_pSquareCirclePr;
CPolygonLineAnnotPr* m_pPolygonLinePr;
CPopupAnnotPr* m_pPopupPr;
CFreeTextAnnotPr* m_pFreeTextPr;
CCaretAnnotPr* m_pCaretPr;
CStampAnnotPr* m_pStampPr;
CRedactAnnotPr* m_pRedactPr;
CLinkAnnotPr* m_pLinkPr;
CWidgetAnnotPr* m_pWidgetPr;
CMarkupAnnotPr* m_pMarkupPr;
CTextAnnotPr* m_pTextPr;
CInkAnnotPr* m_pInkPr;
CLineAnnotPr* m_pLinePr;
CTextMarkupAnnotPr* m_pTextMarkupPr;
CSquareCircleAnnotPr* m_pSquareCirclePr;
CPolygonLineAnnotPr* m_pPolygonLinePr;
CPopupAnnotPr* m_pPopupPr;
CFreeTextAnnotPr* m_pFreeTextPr;
CCaretAnnotPr* m_pCaretPr;
CStampAnnotPr* m_pStampPr;
CRedactAnnotPr* m_pRedactPr;
CLinkAnnotPr* m_pLinkPr;
CFileAttachmentAnnotPr* m_pFileAttachmentPr;
CScreenAnnotPr* m_pScreenPr;
CWidgetAnnotPr* m_pWidgetPr;
};
class GRAPHICS_DECL CAnnotFieldDelete : public IAdvancedCommand

View File

@ -936,7 +936,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF
rec["ID"].push(readStringFunc.call(reader));
rec["ID"].push(readStringFunc.call(reader));
}
rec["V"] = flags & (1 << 23);
rec["V"] = flags & (1 << 23) ? true : false;
if (flags & (1 << 24))
{
if (isRead)
@ -1085,6 +1085,48 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF
for (let i = 0; i < n; ++i)
rec["QuadPoints"].push(readDoubleFunc.call(reader));
}
// Rect and RD differenses
if (flags & (1 << 4))
{
rec["RD"] = [];
for (let i = 0; i < 4; ++i)
rec["RD"].push(readDoubleFunc.call(reader));
}
}
// Screen
else if (rec["type"] == 20)
{
flags = reader.readInt();
if (flags & (1 << 0))
rec["T"] = readStringFunc.call(reader);
if (flags & (1 << 1))
{
let n = reader.readInt();
rec["BC"] = [];
for (let i = 0; i < n; ++i)
rec["BC"].push(readDouble2Func.call(reader));
}
if (flags & (1 << 2))
rec["rotate"] = reader.readInt();
if (flags & (1 << 3))
{
let n = reader.readInt();
rec["BG"] = [];
for (let i = 0; i < n; ++i)
rec["BG"].push(readDouble2Func.call(reader));
}
if (flags & (1 << 4))
{
let nAction = reader.readInt();
if (nAction > 0)
rec["AA"] = {};
for (let i = 0; i < nAction; ++i)
{
let AAType = readStringFunc.call(reader);
rec["AA"][AAType] = {};
readAction(reader, rec["AA"][AAType], readDoubleFunc, readStringFunc);
}
}
}
}
function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false)

View File

@ -1,7 +1,7 @@
#include <iostream>
#include "../../../../raster/BgraFrame.h"
#include "../../../../raster/ImageFileFormatChecker.h"
#include "../../../../../raster/BgraFrame.h"
#include "../../../../../raster/ImageFileFormatChecker.h"
#include "../../../../../common/File.h"
#include "../../../../../common/StringBuilder.h"
#include "drawingfile.cpp"
@ -958,7 +958,7 @@ void ReadInteractiveFormsFonts(CDrawingFile* pGrFile, int nType)
if (pFont)
free(pFont);
if (false)
if (true)
continue;
pFont = GetGIDByUnicode(pGrFile, (char*)sFontName.c_str());
@ -2228,6 +2228,79 @@ int main(int argc, char* argv[])
}
std::cout << ", ";
}
if (nFlags & (1 << 4))
{
std::cout << "RD";
for (int j = 0; j < 4; ++j)
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << " " << (double)nPathLength / 100.0;
}
std::cout << ", ";
}
}
else if (sType == "Screen")
{
nFlags = READ_INT(pAnnots + i);
i += 4;
if (nFlags & (1 << 0))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "T " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
}
if (nFlags & (1 << 1))
{
int nBCLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "BC ";
for (int j = 0; j < nBCLength; ++j)
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << (double)nPathLength / 10000.0 << " ";
}
std::cout << ", ";
}
if (nFlags & (1 << 2))
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "R " << nPathLength << ", ";
}
if (nFlags & (1 << 3))
{
int nBCLength = READ_INT(pAnnots + i);
i += 4;
std::cout << "BG ";
for (int j = 0; j < nBCLength; ++j)
{
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << (double)nPathLength / 10000.0 << " ";
}
std::cout << ", ";
}
if (nFlags & (1 << 4))
{
int nActLength = READ_INT(pAnnots + i);
i += 4;
for (int j = 0; j < nActLength; ++j)
{
std::cout << std::endl;
nPathLength = READ_INT(pAnnots + i);
i += 4;
std::cout << std::to_string(j) << " Action " << std::string((char*)(pAnnots + i), nPathLength) << ", ";
i += nPathLength;
ReadAction(pAnnots, i);
}
std::cout << std::endl;
}
}
std::cout << std::endl << "]" << std::endl;

View File

@ -863,17 +863,12 @@ namespace MetaFile
void PathClip(const CPath& oPath, int nClipMode, TXForm *pTransform = NULL)
{
double dM11, dM12, dM21, dM22, dX, dY;
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
if (NULL != pTransform)
SetTransform(pTransform->M11, pTransform->M12,
pTransform->M21, pTransform->M22,
pTransform->Dx - m_pFile->GetDCBounds().Left,
pTransform->Dy - m_pFile->GetDCBounds().Top);
else
SetTransform(dM11, dM12, dM21, dM22,
dX - m_pFile->GetDCBounds().Left,
dY - m_pFile->GetDCBounds().Top);
{
GetTransform(&dM11, &dM12, &dM21, &dM22, &dX, &dY);
SetTransform(pTransform->M11, pTransform->M12, pTransform->M21, pTransform->M22, pTransform->Dx, pTransform->Dy);
}
oPath.DrawOn(this, false, false, nClipMode);

View File

@ -18,8 +18,8 @@ namespace MetaFile
void CEmfInterpretatorRender::ChangeConditional()
{
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->ChangeConditional();
if (NULL != m_pMetaFileRenderer)
m_pMetaFileRenderer->ChangeConditional();
}
void CEmfInterpretatorRender::Begin()

View File

@ -1264,7 +1264,11 @@ namespace MetaFile
if (NULL != m_pPath)
{
m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, m_pDC->GetFinalTransform(GM_ADVANCED));
TEmfXForm oTransform{m_pDC->GetFinalTransform(GM_ADVANCED)};
oTransform.Dx -= GetDCBounds().Left;
oTransform.Dy -= GetDCBounds().Top;
m_pDC->GetClip()->SetPath(*m_pPath, unRegionMode, oTransform);
RELEASEOBJECT(m_pPath);
UpdateOutputDC();
}

View File

@ -3284,6 +3284,10 @@ namespace MetaFile
void CEmfPlusParser::Read_EMFPLUS_SETCLIPRECT(unsigned short unShFlags)
{
short shCM = ExpressValue(unShFlags, 8, 11);
if (0 == shCM)
shCM = RGN_COPY;
TEmfPlusRectF oRect;
m_oStream >> oRect;

View File

@ -632,18 +632,8 @@ namespace MetaFile
if (wsPath.empty())
return;
const std::wstring wsClipId = L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0);
std::wstring wsValue = L"<path d=\"" + wsPath + L"\"";
const int nOffsetLeft{-m_pParser->GetDCBounds().Left};
const int nOffsetTop {-m_pParser->GetDCBounds().Top};
if (0 != nOffsetLeft || 0 != nOffsetTop)
wsValue += L" transform=\"translate(" + std::to_wstring(nOffsetLeft) + L',' + std::to_wstring(nOffsetTop) + L")\"";
wsValue += L"/>";
m_oClip.AddClipValue(wsClipId, wsValue, nClipMode);
m_oClip.AddClipValue(L"PATHCLIP_" + ConvertToWString(++m_unNumberDefs, 0),
L"<path d=\"" + wsPath + L"\"/>", nClipMode);
}
void CInterpretatorSvgBase::AddStroke(NodeAttributes &arAttributes) const

View File

@ -985,6 +985,8 @@ bool CPictFile::DecodeData()
m_oImgData.m_pPixelData = (BYTE*)malloc(4 * m_oImgData.m_nHeight * m_oImgData.m_nWidth);
if (m_oFrame.get_Data())
memcpy(m_oImgData.m_pPixelData, m_oFrame.get_Data(), 4 * m_oImgData.m_nHeight * m_oImgData.m_nWidth);
else
memset(m_oImgData.m_pPixelData, 255, m_oImgData.m_nWidth * m_oImgData.m_nHeight * 4);
}
return true;
@ -1717,6 +1719,12 @@ void CPictFile::InitializeRenderer()
return;
m_pFrameData = new BYTE[4 * m_oImgData.m_nWidth * m_oImgData.m_nHeight];
unsigned int back = 0xffffff;
unsigned int *pData32 = (unsigned int*)m_pFrameData;
unsigned int *pData32End = pData32 + m_oImgData.m_nWidth * m_oImgData.m_nHeight;
while (pData32 < pData32End)
*pData32++ = back;
m_oFrame.put_Data(m_pFrameData);
m_oFrame.put_Width(m_oImgData.m_nWidth);
m_oFrame.put_Height(m_oImgData.m_nHeight);

View File

@ -116,6 +116,7 @@ namespace XmlUtils
void GetTextWithHHHH(bool bPreserve, wchar_t*& sBuffer, long& nSize, long& nLen);
std::wstring GetTextWithHHHH(bool bPreserve);
std::string GetOuterXmlA();
std::wstring GetOuterXml();
std::wstring GetInnerXml();

View File

@ -206,8 +206,11 @@ namespace XmlUtils
std::wstring CXmlLiteReader::GetTextWithHHHH(bool bPreserve)
{
return m_pInternal->GetTextWithHHHH(bPreserve);
}
}
std::string CXmlLiteReader::GetOuterXmlA()
{
return m_pInternal->GetOuterXmlA();
}
std::wstring CXmlLiteReader::GetOuterXml()
{
return m_pInternal->GetOuterXml();

View File

@ -635,6 +635,10 @@ namespace XmlUtils
GetTextWithHHHH(bPreserve, pUnicodes, nSize, nLen);
return std::wstring(pUnicodes, nLen);
}
inline std::string GetOuterXmlA()
{
return GetXmlA(false);
}
inline std::wstring GetOuterXml()
{
return GetXml(false);
@ -700,6 +704,64 @@ namespace XmlUtils
}
private:
inline std::string GetXmlA(bool bInner)
{
if (!IsValid())
return "";
NSStringUtils::CStringBuilderA oResult;
if (false == bInner)
WriteElement(oResult);
int nDepth = GetDepth();
if (0 == xmlTextReaderIsEmptyElement(reader))
{
XmlNodeType eNodeType = XmlNodeType_None;
int nCurDepth = -1;
while (true)
{
if (1 != xmlTextReaderRead(reader))
break;
int nTempType = xmlTextReaderNodeType(reader);
if (-1 == nTempType)
break;
eNodeType = (XmlNodeType)nTempType;
nCurDepth = GetDepth();
if (eNodeType == XmlNodeType_Text ||
eNodeType == XmlNodeType_Whitespace ||
eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE ||
eNodeType == XmlNodeType_CDATA)
{
oResult.WriteString(GetTextA().c_str());
}
else if (eNodeType == XmlNodeType_Element)
{
WriteElement(oResult);
}
else if (eNodeType == XmlNodeType_EndElement)
{
if (false == bInner || nCurDepth != nDepth)
{
oResult.AddChar2Safe(char('<'), char('/'));
oResult.WriteString(GetNameA().c_str());
oResult.AddCharSafe(char('>'));
}
}
nCurDepth = GetDepth();
if (nCurDepth < nDepth)
break;
if (XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth)
break;
}
}
return oResult.GetData();
}
inline std::wstring GetXml(bool bInner)
{
if (!IsValid())
@ -781,6 +843,33 @@ namespace XmlUtils
else
oResult.AddCharSafe(wchar_t('>'));
}
void WriteElement(NSStringUtils::CStringBuilderA& oResult)
{
oResult.AddCharSafe((char)'<');
oResult.WriteString(GetNameA().c_str());
if (GetAttributesCount() > 0)
{
MoveToFirstAttribute();
std::wstring sName = GetName();
while (!sName.empty())
{
oResult.AddCharSafe(char(' '));
oResult.WriteString(GetNameA().c_str());
oResult.AddChar2Safe(char('='), char('\"'));
oResult.WriteString(GetTextA().c_str());
oResult.AddCharSafe(char('\"'));
if (!MoveToNextAttribute())
break;
sName = GetName();
}
MoveToElement();
}
if (IsEmptyNode())
oResult.AddChar2Safe(char('/'), char('>'));
else
oResult.AddCharSafe(char('>'));
}
};
}

View File

@ -726,7 +726,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, int nRas
GP<DjVuImage> pPage = m_pDoc->get_page(nPageIndex);
//pPage->wait_for_complete_decode();
pPage->set_rotate(0);
return ConvertToPixels(pPage, nRasterW, nRasterH, bIsFlip);
return ConvertToPixels(pPage, nRasterW, nRasterH, bIsFlip, true);
}
catch (...)
{
@ -734,11 +734,11 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(int nPageIndex, int nRas
return NULL;
}
unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, int nImageW, int nImageH, bool bFlip)
unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, int nImageW, int nImageH, bool bFlip, bool bIsSwapRGB)
{
BYTE* pBufferDst = NULL;
auto processPixmap = [&](GP<GPixmap> pImage, bool bFlip = false)
auto processPixmap = [&](GP<GPixmap> pImage, bool bFlip = false, bool bIsSwapRGB = false)
{
pBufferDst = new BYTE[4 * nImageW * nImageH];
@ -749,7 +749,10 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
GPixel* pLine = pImage->operator[](nRow);
for (int i = 0; i < nImageW; ++i)
{
*pBuffer++ = 0xFF000000 | pLine->r << 16 | pLine->g << 8 | pLine->b;
if (bIsSwapRGB)
*pBuffer++ = 0xFF000000 | pLine->b << 16 | pLine->g << 8 | pLine->r;
else
*pBuffer++ = 0xFF000000 | pLine->r << 16 | pLine->g << 8 | pLine->b;
++pLine;
}
}
@ -790,7 +793,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
if (pPage->is_legal_photo() || pPage->is_legal_compound())
{
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
processPixmap(pImage, bFlip);
processPixmap(pImage, bFlip, bIsSwapRGB);
}
else if (pPage->is_legal_bilevel())
{
@ -802,7 +805,7 @@ unsigned char* CDjVuFileImplementation::ConvertToPixels(GP<DjVuImage>& pPage, in
GP<GPixmap> pImage = pPage->get_pixmap(oRectAll, oRectAll);
if (pImage)
{
processPixmap(pImage, bFlip);
processPixmap(pImage, bFlip, bIsSwapRGB);
}
else
{

View File

@ -83,7 +83,7 @@ public:
private:
unsigned char* ConvertToPixels(GP<DjVuImage>& pPage, int nRasterW, int nRasterH, bool bIsFlip = false);
unsigned char* ConvertToPixels(GP<DjVuImage>& pPage, int nRasterW, int nRasterH, bool bIsFlip = false, bool bIsSwapRGB = false);
void CreateFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);
void CreatePdfFrame(IRenderer* pRenderer, GP<DjVuImage>& pImage, int nPage, XmlUtils::CXmlNode& oText);

View File

@ -93,6 +93,7 @@ int CDocxRenderer::Convert(IOfficeDrawingFile* pFile, const std::wstring& sDst,
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = false;
m_pInternal->m_bIsSupportShapeCommands = false;
m_pInternal->m_oDocument.m_bIsRecord = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
if (bIsOutCompress)
m_pInternal->m_oDocument.m_strTempDirectory = NSDirectory::CreateDirectoryWithUniqueName(m_pInternal->m_sTempDirectory);
@ -130,6 +131,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPage(IOfficeDrawingFile* pFile, siz
m_pInternal->m_oDocument.Init(false);
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
m_pInternal->m_bIsSupportShapeCommands = false;
m_pInternal->m_oDocument.m_bIsRecord = false;
@ -147,6 +149,7 @@ std::vector<std::wstring> CDocxRenderer::ScanPagePptx(IOfficeDrawingFile* pFile,
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bCollectMetaInfo = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
m_pInternal->m_bIsSupportShapeCommands = true;
m_pInternal->m_oDocument.m_bIsRecord = false;
@ -165,6 +168,7 @@ NSWasm::CData CDocxRenderer::ScanPageBin(IOfficeDrawingFile* pFile, size_t nPage
m_pInternal->m_oDocument.m_oCurrentPage.m_bUseDefaultFont = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bWriteStyleRaw = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bCollectMetaInfo = true;
m_pInternal->m_oDocument.m_oCurrentPage.m_bFirstParagraphLineCorrection = true;
m_pInternal->m_oDocument.m_bIsRecord = false;
m_pInternal->m_bIsSupportShapeCommands = true;
m_pInternal->m_oDocument.m_oFontStyleManager.Clear();

View File

@ -195,12 +195,14 @@ namespace NSDocxRenderer
if (!m_arShapes.empty())
{
auto& last_shape = m_arShapes.back();
if (last_shape->IsEqual(top, bot, left, right) && rotation == last_shape->m_dRotation && lType != m_lLastType && m_lLastType != 0)
auto& last_shape = m_arShapes.back();
bool is_type_diff = lType == c_nStroke && (m_lLastType == c_nWindingFillMode || m_lLastType == c_nEvenOddFillMode);
is_type_diff = is_type_diff || (m_lLastType == c_nStroke && (lType == c_nWindingFillMode || m_lLastType == c_nEvenOddFillMode));
if (last_shape->IsEqual(top, bot, left, right) && rotation == last_shape->m_dRotation && is_type_diff && m_lLastType != 0)
{
set_fill_mode(last_shape);
// Reset stroke/fill logic
m_lLastType = 0;
if (pInfo) DrawImage(last_shape, pInfo, image_vector);
m_lLastType = 0; // reset stroke/fill logic
return;
}
}
@ -341,10 +343,7 @@ namespace NSDocxRenderer
double top = baseline - _h;
double left = dTextX;
double right = dTextR;
if (left == right) // XPS
right = left + _w;
double right = left + _w;
// use forced fold option
const auto& oParams = m_oManagers.pFontManager->GetFontSelectParams();
@ -517,7 +516,7 @@ namespace NSDocxRenderer
cont->CalculateSpace() * c_dSPACE_WIDTH_COEF;
if (curr_line && fabs(curr_line->m_dBot - cont->m_dBot) <= c_dTHE_SAME_STRING_Y_PRECISION_MM &&
fabs(curr_line->m_dRight - cont->m_dLeft) <= 3 * space_width)
fabs(curr_line->m_dRight - cont->m_dLeft) <= 4 * space_width)
{
curr_line->AddCont(cont);
continue;
@ -581,7 +580,7 @@ namespace NSDocxRenderer
shape_ref_ptr_t val = m_arShapes[i];
shape_ref_ptr_t next_val = m_arShapes[i + 1];
if (!val.get() || ! next_val.get())
if (!val.get() || !next_val.get() || next_val.get()->m_nOrder - val.get()->m_nOrder != 1)
continue;
next_val.get()->TryMergeShape(val.get());
@ -1410,14 +1409,10 @@ namespace NSDocxRenderer
}
bool CPage::IsTextLineTrough(base_item_ptr_t pFirst) const noexcept
{
const auto width = pFirst->m_dRight - pFirst->m_dLeft;
const auto center = pFirst->m_dLeft + width / 2;
for (const auto& text_line : m_arShapes)
if (text_line && text_line->m_eType == CShape::eShapeType::stTextBox && text_line->m_dBot > pFirst->m_dTop &&
text_line->m_dBot < pFirst->m_dBot &&
text_line->m_dLeft <= center &&
text_line->m_dRight >= center)
text_line->m_dBot < pFirst->m_dBot && !(
text_line->m_dRight < pFirst->m_dLeft || text_line->m_dLeft > pFirst->m_dRight))
return true;
return false;
@ -1666,7 +1661,11 @@ namespace NSDocxRenderer
paragraph->m_dRightBorder = m_dWidth - paragraph->m_dRight;
paragraph->m_dLeftBorder = min_left;
paragraph->m_dLineHeight = paragraph->m_dHeight / paragraph->m_arTextLines.size();
if (paragraph->m_arTextLines.size() == 1)
paragraph->m_dLineHeight = paragraph->m_dHeight;
else
paragraph->m_dLineHeight = (paragraph->m_dBot - firstLine->m_dBotWithMaxDescent) / (paragraph->m_arTextLines.size() - 1);
paragraph->m_bIsNeedFirstLineIndent = false;
paragraph->m_dFirstLine = 0;
paragraph->m_wsStyleId = m_oManagers.pParagraphStyleManager->GetDefaultParagraphStyleId(*paragraph);
@ -1674,20 +1673,22 @@ namespace NSDocxRenderer
paragraph->MergeLines();
// Correct first line position
double firstLine_height = firstLine->m_dBotWithMaxDescent - firstLine->m_dTopWithMaxAscent;
if (paragraph->m_dLineHeight > firstLine_height)
if (m_bFirstParagraphLineCorrection)
{
double offset = paragraph->m_dLineHeight - firstLine_height;
paragraph->m_dTop -= offset;
paragraph->m_dBot -= offset;
}
else
{
double ascent = firstLine->m_dBot - firstLine->m_dTopWithMaxAscent;
double newAscent = ascent * paragraph->m_dLineHeight / firstLine_height;
double offset = ascent - newAscent;
paragraph->m_dTop += offset;
paragraph->m_dBot += offset;
double firstLine_height = firstLine->m_dBotWithMaxDescent - firstLine->m_dTopWithMaxAscent;
if (paragraph->m_dLineHeight > firstLine_height)
{
double offset = paragraph->m_dLineHeight - firstLine_height;
paragraph->m_dTop -= offset;
}
else
{
double ascent = firstLine->m_dBot - firstLine->m_dTopWithMaxAscent;
double newAscent = ascent * paragraph->m_dLineHeight / firstLine_height;
double offset = ascent - newAscent;
paragraph->m_dTop += offset;
}
paragraph->m_dHeight = paragraph->m_dBot - paragraph->m_dTop;
}
// setting TextAlignmentType
@ -1935,6 +1936,9 @@ namespace NSDocxRenderer
double curr_max_right = text_lines[0]->m_dRight;
double curr_min_left = text_lines[0]->m_dLeft;
double line_with_first_right_min = std::numeric_limits<double>::max();
double line_with_first_left_max = std::numeric_limits<double>::lowest();
for (size_t index = 0; index < ar_positions.size() - 1; ++index)
{
Position position = ar_positions[index];
@ -1945,6 +1949,10 @@ namespace NSDocxRenderer
{
curr_max_right = line_bot->m_dRight;
curr_min_left = line_bot->m_dLeft;
line_with_first_right_min = std::numeric_limits<double>::max();
line_with_first_left_max = std::numeric_limits<double>::lowest();
continue;
}
@ -1952,15 +1960,18 @@ namespace NSDocxRenderer
double line_with_first_right = line_top->m_dRight + line_bot->m_dFirstWordWidth;
double line_with_first_left = line_top->m_dLeft - line_bot->m_dFirstWordWidth;
line_with_first_right_min = std::min(line_with_first_right_min, line_with_first_right);
line_with_first_left_max = std::max(line_with_first_left_max, line_with_first_left);
curr_max_right = std::max(curr_max_right, line_bot->m_dRight);
curr_min_left = std::min(curr_min_left, line_bot->m_dLeft);
double diff = 0;
if (position.right && !position.left)
diff = line_with_first_left - curr_min_left;
diff = line_with_first_left_max - curr_min_left;
else if (position.left || ar_indents[index] || position.center)
diff = curr_max_right - line_with_first_right;
diff = curr_max_right - line_with_first_right_min;
if (diff <= 0)
continue;
@ -1969,6 +1980,8 @@ namespace NSDocxRenderer
ar_delims[index] = true;
curr_max_right = line_bot->m_dRight;
curr_min_left = line_bot->m_dLeft;
line_with_first_right_min = std::numeric_limits<double>::max();
line_with_first_left_max = std::numeric_limits<double>::lowest();
}
}
@ -2717,6 +2730,20 @@ namespace NSDocxRenderer
pShape->m_dImageTop = imageVector.GetTop();
pShape->m_dImageLeft = imageVector.GetLeft();
pShape->m_dImageRight = imageVector.GetRight();
// for reflection along the x-axis
if (fabs(fabs(pShape->m_dRotation) - 180.0) < 0.01 && m_oTransform.sx() > 0.0)
{
std::swap(pShape->m_dImageBot, pShape->m_dImageTop);
pShape->m_dRotation = 0.0;
}
// for reflection along the y-axis
if (fabs(fabs(pShape->m_dRotation) - 180.0) < 0.01 && m_oTransform.sy() > 0.0)
{
std::swap(pShape->m_dImageLeft, pShape->m_dImageRight);
pShape->m_dRotation = 0.0;
}
}
void CPage::DrawGradient(shape_ptr_t pShape)

View File

@ -50,6 +50,7 @@ namespace NSDocxRenderer
bool m_bIsBuildTables {false};
bool m_bIsLuminosityShapesFiled{false};
bool m_bFontSubstitution {false};
bool m_bFirstParagraphLineCorrection{false};
CPage(NSFonts::IApplicationFonts* pAppFonts, const CManagers& oManagers);
~CPage();

View File

@ -142,7 +142,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
*/
CHtmlFile2 oFile;
CHtmlParams oFileParams;
HTML::THTMLParameters oFileParams;
oFileParams.SetAuthors (m_oBookInfo.GetCreators());
oFileParams.SetGenres (m_oBookInfo.GetSubjects());
@ -155,7 +155,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
std::wstring sDocxFileTempDir = m_sTempDir + L"/tmp";
NSDirectory::CreateDirectory(sDocxFileTempDir);
oFile.SetTmpDirectory(sDocxFileTempDir);
oFile.SetTempDirectory(sDocxFileTempDir);
oFile.SetCoreDirectory(NSFile::GetDirectoryName(sContent));
std::vector<std::wstring> arFiles;
@ -182,7 +182,7 @@ HRESULT CEpubFile::Convert(const std::wstring& sInputFile, const std::wstring& s
sOutputDir = sOutputFile;
NSDirectory::CreateDirectory(sOutputDir);
HRESULT hRes = oFile.OpenBatchHtml(arFiles, sOutputDir, &oFileParams);
HRESULT hRes = oFile.ConvertHTML2OOXML(arFiles, sOutputDir, &oFileParams);
if (bIsOutCompress && S_OK == hRes)
hRes = oOfficeUtils.CompressFileOrDirectory(sOutputDir, sOutputFile);

View File

@ -2170,7 +2170,7 @@ HRESULT CFb2File::FromHtml(const std::wstring& sHtmlFile, const std::wstring& sD
RELEASEARRAYOBJECTS(pData);
//XmlUtils::CXmlLiteReader oIndexHtml;
std::wstring xhtml = htmlToXhtml(sContent, bNeedConvert);
std::wstring xhtml = HTML::htmlToXhtml(sContent, bNeedConvert);
if (!m_internal->m_oLightReader.FromString(xhtml))
return S_FALSE;

64
HtmlFile2/Common.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef COMMON_H
#define COMMON_H
#include <string>
#include "../DesktopEditor/common/StringBuilder.h"
namespace HTML
{
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
using XmlString = NSStringUtils::CStringBuilder;
inline void replace_all(std::wstring& s, const std::wstring& s1, const std::wstring& s2)
{
size_t pos = s.find(s1);
size_t l = s2.length();
while (pos != std::string::npos)
{
if (!(s1 == L"&" && s2 == L"&amp;" && s.length() > pos + 4 && s[pos] == L'&' && s[pos + 1] == L'a' && s[pos + 2] == L'm' && s[pos + 3] == L'p' && s[pos + 4] == L';'))
s.replace(pos, s1.length(), s2);
pos = s.find(s1, pos + l);
}
}
inline std::wstring EncodeXmlString(const std::wstring& s)
{
std::wstring sRes = s;
replace_all(sRes, L"&", L"&amp;");
replace_all(sRes, L"<", L"&lt;");
replace_all(sRes, L">", L"&gt;");
replace_all(sRes, L"\"", L"&quot;");
replace_all(sRes, L"\'", L"&#39;");
replace_all(sRes, L"\n", L"&#xA;");
replace_all(sRes, L"\r", L"&#xD;");
replace_all(sRes, L"\t", L"&#x9;");
return sRes;
}
inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilder, NSStringUtils::CStringBuilder& oDstStringBuilder)
{
if (oSrcStringBuilder.GetCurSize() < MAX_STRING_BLOCK_SIZE)
{
oDstStringBuilder.Write(oSrcStringBuilder);
return;
}
size_t ulSize = oSrcStringBuilder.GetCurSize();
size_t ulCurrentBlockSize = 0, ulPosition = 0;
while (ulSize > 0)
{
ulCurrentBlockSize = std::min(ulSize, MAX_STRING_BLOCK_SIZE);
oDstStringBuilder.WriteString(oSrcStringBuilder.GetSubData(ulPosition, ulCurrentBlockSize));
ulSize -= ulCurrentBlockSize;
ulPosition += ulCurrentBlockSize;
}
}
}
#endif // COMMON_H

View File

@ -0,0 +1,69 @@
#ifndef HTMLPARAMETERS_H
#define HTMLPARAMETERS_H
#include <string>
namespace HTML
{
struct THTMLParameters
{
std::wstring m_sGenres; // Жанры
std::wstring m_sAuthors; // Авторы
std::wstring m_sBookTitle; // Название
std::wstring m_sDate; // Дата
std::wstring m_sDescription; // описание
std::wstring m_sLanguage; // Язык
bool m_bNeedPageBreakBefore; // Новый html с новой страницы
std::wstring m_sdocDefaults; // Стиль docDefaults
std::wstring m_sNormal; // Стиль normal
THTMLParameters() : m_bNeedPageBreakBefore(false) {}
void SetNormal(const std::wstring& sStyle)
{
m_sNormal = sStyle;
}
void SetDocDefaults(const std::wstring& sStyle)
{
m_sdocDefaults = sStyle;
}
void SetPageBreakBefore(bool bNeed)
{
m_bNeedPageBreakBefore = bNeed;
}
void SetDate(const std::wstring& sDate)
{
m_sDate = sDate;
}
void SetDescription(const std::wstring& sDescription)
{
m_sDescription = sDescription;
}
void SetGenres(const std::wstring& sGenres)
{
m_sGenres = sGenres;
}
void SetAuthors(const std::wstring& sAuthors)
{
m_sAuthors = sAuthors;
}
void SetTitle(const std::wstring& sTitle)
{
m_sBookTitle = sTitle;
}
void SetLanguage(const std::wstring& sLanguage)
{
m_sLanguage = sLanguage;
}
};
}
#endif // HTMLPARAMETERS_H

1533
HtmlFile2/HTMLReader.cpp Normal file

File diff suppressed because it is too large Load Diff

93
HtmlFile2/HTMLReader.h Normal file
View File

@ -0,0 +1,93 @@
#ifndef HTMLREADER_H
#define HTMLREADER_H
#include <unordered_map>
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
#include "../DesktopEditor/xml/include/xmlutils.h"
#include "HTMLParameters.h"
#include "MarkdownParameters.h"
#include "Writers/IWriter.h"
#include "Tags/HTMLTags.h"
#include "Table.h"
namespace HTML
{
class CHTMLReader
{
XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
NSCSS::CCssCalculator m_oCSSCalculator; // Css калькулятор
bool m_bIsTempDirOwner;
std::wstring m_wsTempDirectory; // Temp папка
std::wstring m_wsSrcDirectory; // Директория источника
std::wstring m_wsDstDirectory; // Директория назначения
std::wstring m_wsBaseDirectory; // Полный базовый адрес
std::wstring m_wsCoreDirectory; // Путь до корневого файла (используется для работы с Epub)
IWriter *m_pWriter;
std::unordered_map<UINT, std::shared_ptr<ITag>> m_mTags;
public:
CHTMLReader();
~CHTMLReader();
void SetTempDirectory(const std::wstring& wsPath);
void SetCoreDirectory(const std::wstring& wsPath);
HRESULT ConvertHTML2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
HRESULT ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
HRESULT ConvertHTML2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
HRESULT ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
HRESULT ConvertMHT2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
HRESULT ConvertMHT2Markdown (const std::wstring& wsPath, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
HRESULT ConvertMHT2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, THTMLParameters* pParameters = nullptr);
HRESULT ConvertMHT2Markdown (const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, TMarkdownParameters* pParameters = nullptr);
NSCSS::CCssCalculator* GetCSSCalculator();
private:
void Clear();
void InitOOXMLTags(THTMLParameters* pParametrs = nullptr);
void InitMDTags(TMarkdownParameters* pParametrs = nullptr);
bool IsHTML();
typedef std::function<bool(const std::wstring&, XmlUtils::CXmlLiteReader&)> Convert_Func;
HRESULT InitAndConvert2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, Convert_Func Convertation, THTMLParameters* pParameters = nullptr);
HRESULT InitAndConvert2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, Convert_Func Convertation, TMarkdownParameters* pParameters = nullptr);
bool Convert(const std::wstring& wsPath, Convert_Func Convertation);
void ReadStyle();
void ReadStyle2();
void ReadStyleFromNetwork();
void ReadDocument();
void ReadHead();
void ReadBody();
bool ReadStream(std::vector<NSCSS::CNode>& arSelectors, bool bInsertEmptyP = false);
bool ReadInside(std::vector<NSCSS::CNode>& arSelectors);
bool ReadText(std::vector<NSCSS::CNode>& arSelectors);
bool ReadSVG(const std::vector<NSCSS::CNode>& arSelectors);
bool ReadEmptyTag(UINT unTag, const std::vector<NSCSS::CNode>& arSelectors);
bool ReadDefaultTag(UINT unTag, std::vector<NSCSS::CNode>& arSelectors);
bool ReadTable(std::vector<NSCSS::CNode>& arSelectors);
void ReadTableCaption(CStorageTable& oTable, std::vector<NSCSS::CNode>& arSelectors);
void ReadTableRows(CStorageTable& oTable, std::vector<NSCSS::CNode>& arSelectors, ERowParseMode eMode);
void ReadTableColspan(CStorageTable& oTable);
void GetSubClass(std::vector<NSCSS::CNode>& arSelectors);
};
}
#endif // HTMLREADER_H

View File

@ -13,6 +13,7 @@ DEFINES += CSSCALCULATOR_LIBRARY_STATIC
DEFINES += CSS_CALCULATOR_WITH_XHTML
DEFINES += DISABLE_RUBY_SUPPORT
DEFINES += MDCONVERTER_DECL_EXPORT
DEFINES += HTML_NORMALIZER_DECL_EXPORT
CORE_ROOT_DIR = $$PWD/..
PWD_ROOT_DIR = $$PWD
@ -31,8 +32,25 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri)
ADD_DEPENDENCY(kernel, UnicodeConverter, graphics, kernel_network)
SOURCES += htmlfile2.cpp
SOURCES += htmlfile2.cpp \
./Writers/OOXMLWriter.cpp \
HTMLReader.cpp \
Tags/MDTags.cpp \
Writers/MDWriter.cpp \
Table.cpp \
Tags/OOXMLTags.cpp
HEADERS += htmlfile2.h \
./src/StringFinder.h \
./src/Languages.h
./src/Languages.h \
Common.h \
./Writers/OOXMLWriter.h \
./Writers/IWriter.h \
HTMLParameters.h \
HTMLReader.h \
./Tags/HTMLTags.h \
MarkdownParameters.h \
Tags/MDTags.h \
Writers/MDWriter.h \
Table.h \
Tags/OOXMLTags.h

View File

@ -0,0 +1,14 @@
#ifndef MARKDOWNPARAMETERS_H
#define MARKDOWNPARAMETERS_H
namespace HTML
{
struct TMarkdownParameters
{
bool m_bUseAlternativeHTMLTags = false; //Использовать html теги там, где нет стандартной реализации в md(например для подчеркиваний)
wchar_t m_wchUnorderedList = L'-'; // Возможные варианты в md: -, +, *
wchar_t m_wchOrderedList = L'.'; // Возможные варианты в md: ., )
};
}
#endif // MARKDOWNPARAMETERS_H

715
HtmlFile2/Table.cpp Normal file
View File

@ -0,0 +1,715 @@
#include "Table.h"
#include "Common.h"
#include "src/StringFinder.h"
namespace HTML
{
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
#define RELEASE_VECTOR_PTR(vector_object, object_type) \
for (object_type* pElement : vector_object) \
RELEASEOBJECT(pElement)
#define FIRST_ELEMENT 0x00000001
#define LAST_ELEMENT 0x00000002
#define MID_ELEMENT 0x00000004
#define PARSE_MODE_HEADER 0x00000100
#define PARSE_MODE_BODY 0x00000200
#define PARSE_MODE_FOOTHER 0x00000400
#define COL_POSITION_MASK 0x0000000F
#define ROW_POSITION_MASK 0x000000F0
#define PARSE_MODE_MASK 0x00000F00
#define DEFAULT_PAGE_WIDTH 12240 // Значение в Twips
#define DEFAULT_PAGE_HEIGHT 15840 // Значение в Twips
TTableRowStyle::TTableRowStyle()
: m_unMaxIndex(0), m_unMaxHeight(0), m_bIsHeader(false)
{}
bool TTableRowStyle::Empty() const
{
return 0 == m_unMaxHeight && false == m_bIsHeader;
}
TTableCellStyle::TTableCellStyle()
{}
bool TTableCellStyle::Empty()
{
return m_oWidth.Empty() && m_oHeight.Empty() && m_oBorder.Empty() && m_oPadding.Empty() && m_wsVAlign.empty() && m_wsVAlign.empty();
}
void TTableCellStyle::Copy(const TTableCellStyle* pTableCellStyle)
{
if (NULL == pTableCellStyle)
return;
m_oWidth = pTableCellStyle->m_oWidth;
m_oHeight = pTableCellStyle->m_oHeight;
m_oBorder = pTableCellStyle->m_oBorder;
m_oPadding = pTableCellStyle->m_oPadding;
m_oBackground = pTableCellStyle->m_oBackground;
m_wsHAlign = pTableCellStyle->m_wsHAlign;
m_wsVAlign = pTableCellStyle->m_wsVAlign;
}
TTableCellStyle& TTableCellStyle::operator+=(const TTableCellStyle* pCellStyle)
{
if (NULL == pCellStyle)
return *this;
m_oWidth += pCellStyle->m_oWidth;
m_oHeight += pCellStyle->m_oHeight;
m_oBorder += pCellStyle->m_oBorder;
m_oPadding += pCellStyle->m_oPadding;
m_oBackground += pCellStyle->m_oBackground;
if (m_wsHAlign.empty())
m_wsHAlign = pCellStyle->m_wsHAlign;
if (m_wsVAlign.empty())
m_wsVAlign = pCellStyle->m_wsVAlign;
return *this;
}
CStorageTableCell::CStorageTableCell()
: m_unColspan(1), m_unRowSpan(1), m_bIsMerged(false), m_bIsEmpty(false), m_oData(30)
{}
CStorageTableCell::CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty)
: m_unColspan(unColspan), m_unRowSpan(unRowspan), m_bIsMerged(bIsMerged),
m_bIsEmpty(bIsEmpty)
{}
CStorageTableCell::CStorageTableCell(CStorageTableCell& oCell)
: m_unColspan(oCell.m_unColspan), m_unRowSpan(oCell.m_unRowSpan), m_bIsMerged(oCell.m_bIsMerged),
m_bIsEmpty(oCell.m_bIsEmpty), m_oStyles(oCell.m_oStyles)
{
WriteToStringBuilder(oCell.m_oData, m_oData);
}
bool CStorageTableCell::Empty() const
{
return m_bIsEmpty;
}
bool CStorageTableCell::Merged() const
{
return m_bIsMerged;
}
CStorageTableCell* CStorageTableCell::Copy()
{
return new CStorageTableCell(*this);
}
CStorageTableCell* CStorageTableCell::CreateEmpty(UINT unColspan, bool m_bIsMerged, const TTableCellStyle* pStyle)
{
CStorageTableCell *pCell = new CStorageTableCell(unColspan, 1, m_bIsMerged, true);
pCell->m_oStyles.Copy(pStyle);
return pCell;
}
CStorageTableCell* CStorageTableCell::CreateEmpty(const TTableCellStyle* pStyle)
{
CStorageTableCell *pCell = new CStorageTableCell(1, 1, false, true);
pCell->m_oStyles.Copy(pStyle);
return pCell;
}
void CStorageTableCell::SetColspan(UINT unColspan, UINT unCurrentIndex)
{
if (MAXCOLUMNSINTABLE - 1 != unCurrentIndex)
m_unColspan = std::min(MAXCOLUMNSINTABLE - 1 - unCurrentIndex, unColspan);
else
m_unColspan = 1;
}
UINT CStorageTableCell::GetColspan() const
{
return m_unColspan;
}
void CStorageTableCell::SetRowspan(UINT unRowspan)
{
m_unRowSpan = unRowspan;
}
UINT CStorageTableCell::GetRowspan() const
{
return m_unRowSpan;
}
NSStringUtils::CStringBuilder* CStorageTableCell::GetData()
{
return &m_oData;
}
const TTableCellStyle* CStorageTableCell::GetStyles() const
{
return &m_oStyles;
}
TTableCellStyle* CStorageTableCell::GetStyles()
{
return &m_oStyles;
}
void CStorageTableCell::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
{
m_oStyles.m_oWidth = oWidth;
}
void CStorageTableCell::SetHeight(const NSCSS::NSProperties::CDigit& oHeight)
{
m_oStyles.m_oHeight = oHeight;
}
UINT CStorageTableCell::GetWidth() const
{
return m_oStyles.m_oWidth.ToInt(NSCSS::Twips, DEFAULT_PAGE_WIDTH);
}
UINT CStorageTableCell::GetHeight() const
{
return m_oStyles.m_oHeight.ToInt(NSCSS::Twips, DEFAULT_PAGE_HEIGHT);
}
void CStorageTableCell::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
{
m_oStyles.m_oBorder = oBorder;
}
void CStorageTableCell::ClearTopBorder()
{
m_oStyles.m_oBorder.SetTopSide(L"none", 0, true);
}
void CStorageTableCell::ClearLeftBorder()
{
m_oStyles.m_oBorder.SetLeftSide(L"none", 0, true);
}
void CStorageTableCell::ClearBottomBorder()
{
m_oStyles.m_oBorder.SetBottomSide(L"none", 0, true);
}
void CStorageTableCell::ClearRightBorder()
{
m_oStyles.m_oBorder.SetRightSide(L"none", 0, true);
}
void CStorageTableCell::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
{
m_oStyles.m_oPadding = oPadding;
}
void CStorageTableCell::SetHAlign(const std::wstring& wsAlign)
{
m_oStyles.m_wsHAlign = wsAlign;
}
void CStorageTableCell::SetVAlign(const std::wstring& wsAlign)
{
m_oStyles.m_wsVAlign = wsAlign;
}
void CStorageTableCell::SetBackground(const NSCSS::NSProperties::CColor& oColor)
{
m_oStyles.m_oBackground = oColor;
}
CStorageTableRow::CStorageTableRow()
{}
CStorageTableRow::~CStorageTableRow()
{
for (CStorageTableCell* pCell : m_arCells)
RELEASEOBJECT(pCell);
}
void CStorageTableRow::AddCell(CStorageTableCell* pCell)
{
InsertCell(pCell, -1);
}
void CStorageTableRow::InsertCell(CStorageTableCell* pCell, int nPosition)
{
if (NULL == pCell)
return;
if (nPosition < 0)
{
std::vector<CStorageTableCell*>::iterator itFoundEmpty = std::find_if(m_arCells.begin(), m_arCells.end(), [](CStorageTableCell* pCell) { return pCell->Empty() && !pCell->Merged(); });
if (m_arCells.end() != itFoundEmpty)
{
--m_oStyles.m_unMaxIndex;
delete *itFoundEmpty;
*itFoundEmpty = pCell;
if (1 != pCell->GetColspan())
{
++itFoundEmpty;
UINT unColspan = pCell->GetColspan() - 1;
while (m_arCells.end() != itFoundEmpty && (*itFoundEmpty)->Empty() && unColspan > 0)
{
--m_oStyles.m_unMaxIndex;
--unColspan;
delete (*itFoundEmpty);
itFoundEmpty = m_arCells.erase(itFoundEmpty);
}
if (unColspan != 0)
pCell->SetColspan(pCell->GetColspan() - unColspan, MAXCOLUMNSINTABLE);
}
}
else
m_arCells.push_back(pCell);
}
else if (nPosition >= m_arCells.size())
{
const UINT unMissingCount = nPosition - m_arCells.size();
for (UINT unIndex = 0; unIndex < unMissingCount; ++unIndex)
m_arCells.push_back(CStorageTableCell::CreateEmpty());
m_oStyles.m_unMaxIndex += unMissingCount;
m_arCells.push_back(pCell);
}
else if (m_arCells[nPosition]->Empty())
{
delete m_arCells[nPosition];
--m_oStyles.m_unMaxIndex;
m_arCells[nPosition] = pCell;
if (1 != pCell->GetColspan())
{
++nPosition;
UINT unDeleteCount = pCell->GetColspan() - 1;
while (nPosition < m_arCells.size() && m_arCells[nPosition]->Empty() && !m_arCells[nPosition]->Merged() && unDeleteCount > 0)
{
delete m_arCells[nPosition];
--m_oStyles.m_unMaxIndex;
m_arCells.erase(m_arCells.begin() + nPosition);
--unDeleteCount;
}
if (0 != unDeleteCount)
pCell->SetColspan(pCell->GetColspan() - unDeleteCount, MAXCOLUMNSINTABLE);
}
}
else
m_arCells.insert(m_arCells.begin() + nPosition, pCell);
m_oStyles.m_unMaxIndex += pCell->GetColspan();
if (1 == pCell->GetColspan() && 1 == pCell->GetRowspan())
m_oStyles.m_unMaxHeight = std::max(m_oStyles.m_unMaxHeight, pCell->GetHeight());
}
UINT CStorageTableRow::GetIndex() const
{
return m_oStyles.m_unMaxIndex;
}
UINT CStorageTableRow::GetCount() const
{
return m_arCells.size();
}
CStorageTableCell* CStorageTableRow::operator[](UINT unIndex)
{
if (unIndex >= m_arCells.size())
return NULL;
return m_arCells[unIndex];
}
bool CStorageTableRow::Empty() const
{
return m_arCells.empty();
}
const TTableRowStyle& CStorageTableRow::GetStyles() const
{
return m_oStyles;
}
const std::vector<CStorageTableCell*>& CStorageTableRow::GetCells() const
{
return m_arCells;
}
CTableCol::CTableCol(UINT unSpan)
: m_unSpan(unSpan)
{}
CTableCol::CTableCol(const NSCSS::CNode& oTableColNode)
: m_unSpan(1)
{
m_unSpan = NSStringFinder::ToInt(oTableColNode.GetAttributeValue(L"span"));
}
UINT CTableCol::GetSpan() const
{
return m_unSpan;
}
TTableCellStyle* CTableCol::GetStyle()
{
return &m_oStyle;
}
const TTableCellStyle* CTableCol::GetStyle() const
{
return &m_oStyle;
}
CTableColgroup::CTableColgroup(NSCSS::CNode& oTableColgroupNode)
: m_unWidth(0)
{
m_unWidth = NSStringFinder::ToInt(oTableColgroupNode.GetAttributeValue(L"width"), 0);
}
CTableColgroup::~CTableColgroup()
{
RELEASE_VECTOR_PTR(m_arCols, CTableCol)
}
bool CTableColgroup::Empty() const
{
return m_arCols.empty();
}
void CTableColgroup::AddCol(CTableCol* pCol)
{
if (NULL != pCol)
m_arCols.push_back(pCol);
}
const std::vector<CTableCol*>& CTableColgroup::GetCols() const
{
return m_arCols;
}
TTableStyles::TTableStyles()
: m_nCellSpacing(-1), m_enRules(None)
{}
bool TTableStyles::Empty() const
{
return m_oPadding.Empty() && m_oMargin.Empty() && m_oBorder.Empty() && m_oWidth.Empty() && -1 == m_nCellSpacing && m_wsAlign.empty();
}
CStorageTable::CStorageTable()
: m_unMaxColumns(0)
{}
CStorageTable::~CStorageTable()
{
for (std::vector<CStorageTableRow*>& arHeaders : m_arHeaders)
RELEASE_VECTOR_PTR(arHeaders, CStorageTableRow)
RELEASE_VECTOR_PTR(m_arFoother, CStorageTableRow)
RELEASE_VECTOR_PTR(m_arRows, CStorageTableRow)
RELEASE_VECTOR_PTR(m_arColgroups, CTableColgroup)
}
CStorageTableRow* CStorageTable::operator[](UINT unIndex)
{
if (unIndex < m_arRows.size())
return m_arRows[unIndex];
return NULL;
}
bool CStorageTable::Empty() const
{
return m_arHeaders.empty() && m_arRows.empty() && m_arFoother.empty();
}
bool CStorageTable::HaveCaption()
{
return 0 != m_oCaption.GetCurSize();
}
bool CStorageTable::HaveColgroups() const
{
return !m_arColgroups.empty();
}
bool CStorageTable::HaveHeader() const
{
return !m_arHeaders.empty();
}
UINT CStorageTable::GetRowCount() const
{
return m_arRows.size();
}
const TTableStyles& CStorageTable::GetTableStyles() const
{
return m_oStyles;
}
const TTableCellStyle* CStorageTable::GetColStyle(UINT unColumnNumber) const
{
if (m_arColgroups.empty())
return NULL;
UINT unCurrentNumber = 0;
for (const CTableColgroup* pColgroup : m_arColgroups)
{
for (const CTableCol* pCol : pColgroup->GetCols())
{
unCurrentNumber += pCol->GetSpan();
if (unCurrentNumber >= unColumnNumber)
return pCol->GetStyle();
}
}
return NULL;
}
void CStorageTable::AddRows(std::vector<CStorageTableRow*>& arRows, ERowParseMode eParseMode)
{
if (arRows.empty())
return;
if (ERowParseMode::Foother == eParseMode && !m_arFoother.empty())
eParseMode = ERowParseMode::Header;
if (ERowParseMode::Header == eParseMode)
m_arHeaders.push_back({});
for (CStorageTableRow* pRow : arRows)
AddRow(pRow, eParseMode);
}
void CStorageTable::AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode)
{
if (NULL == pRow)
return;
for (UINT unIndex = 0; unIndex < pRow->GetCount(); ++unIndex)
{
if (unIndex >= m_arMinColspan.size())
m_arMinColspan.push_back((*pRow)[unIndex]->GetColspan());
else if ((*pRow)[unIndex]->GetColspan() < m_arMinColspan[unIndex])
m_arMinColspan[unIndex] = (*pRow)[unIndex]->GetColspan();
}
switch (eParseMode)
{
default:
case ERowParseMode::Body:
{
m_arRows.push_back(pRow);
break;
}
case ERowParseMode::Header:
{
if (m_arHeaders.empty())
m_arHeaders.push_back({});
m_arHeaders.back().push_back(pRow);
break;
}
case ERowParseMode::Foother:
{
m_arFoother.push_back(pRow);
break;
}
}
}
NSStringUtils::CStringBuilder* CStorageTable::GetCaptionData()
{
return &m_oCaption;
}
void CStorageTable::SetPadding(const NSCSS::NSProperties::CIndent& oPadding)
{
m_oStyles.m_oPadding = oPadding;
}
const NSCSS::NSProperties::CIndent& CStorageTable::GetPadding() const
{
return m_oStyles.m_oPadding;
}
void CStorageTable::SetMargin(const NSCSS::NSProperties::CIndent& oMargin)
{
m_oStyles.m_oMargin = oMargin;
}
void CStorageTable::SetBorder(const NSCSS::NSProperties::CBorder& oBorder)
{
m_oStyles.m_oBorder = oBorder;
}
void CStorageTable::SetWidth(const NSCSS::NSProperties::CDigit& oWidth)
{
m_oStyles.m_oWidth = oWidth;
}
void CStorageTable::SetCellSpacing(int nCellSpacing)
{
m_oStyles.m_nCellSpacing = nCellSpacing;
}
void CStorageTable::SetAlign(const std::wstring& wsValue)
{
m_oStyles.m_wsAlign = wsValue;
}
void CStorageTable::SetRules(const std::wstring& wsValue)
{
if (wsValue.empty())
return;
if (NSStringFinder::Equals(wsValue, L"all"))
m_oStyles.m_enRules = TTableStyles::ETableRules::All;
else if (NSStringFinder::Equals(wsValue, L"groups"))
m_oStyles.m_enRules = TTableStyles::ETableRules::Groups;
else if (NSStringFinder::Equals(wsValue, L"cols"))
m_oStyles.m_enRules = TTableStyles::ETableRules::Cols;
else if (NSStringFinder::Equals(wsValue, L"none"))
m_oStyles.m_enRules = TTableStyles::ETableRules::None;
else if (NSStringFinder::Equals(wsValue, L"rows"))
m_oStyles.m_enRules = TTableStyles::ETableRules::Rows;
}
void CStorageTable::AddColgroup(CTableColgroup* pElement)
{
if (NULL != pElement)
m_arColgroups.push_back(pElement);
}
void CStorageTable::RecalculateMaxColumns()
{
for (const std::vector<CStorageTableRow*>& arHeaders : m_arHeaders)
for (const CStorageTableRow* pHeader : arHeaders)
m_unMaxColumns = std::max(m_unMaxColumns, pHeader->GetIndex());
for (const CStorageTableRow* pRow : m_arRows)
m_unMaxColumns = std::max(m_unMaxColumns, pRow->GetIndex());
for (const CStorageTableRow* pFoother : m_arFoother)
m_unMaxColumns = std::max(m_unMaxColumns, pFoother->GetIndex());
}
void CStorageTable::Shorten()
{
UINT unIndex = 0;
CStorageTableCell* pCell = NULL;
UINT unMaxIndex = 0; //Максимальный индекс без учета строк, где имеется только 1 ячейка
for (const CStorageTableRow* pRow : m_arRows)
{
if (1 < pRow->GetCount())
unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
}
while (unIndex < m_arMinColspan.size())
{
for (CStorageTableRow* pRow : m_arRows)
{
if (0 != unMaxIndex && 1 == pRow->GetCount() && pRow->GetIndex() > unMaxIndex)
{
pCell = (*pRow)[unIndex];
if (NULL == pCell)
continue;
pCell->SetColspan(unMaxIndex, MAXCOLUMNSINTABLE);
continue;
}
if (1 == m_arMinColspan[unIndex])
break;
pCell = (*pRow)[unIndex];
if (NULL == pCell)
continue;
if (1 < pCell->GetColspan() && pCell->GetColspan() > m_arMinColspan[unIndex])
{
pCell->SetColspan(m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
continue;
}
if ((*pRow)[unIndex]->GetColspan() == m_arMinColspan[unIndex] + 1)
(*pRow)[unIndex]->SetColspan(2, MAXCOLUMNSINTABLE);
else if ((*pRow)[unIndex]->GetColspan() > m_arMinColspan[unIndex])
(*pRow)[unIndex]->SetColspan((*pRow)[unIndex]->GetColspan() - m_arMinColspan[unIndex], MAXCOLUMNSINTABLE);
}
++unIndex;
}
}
void CStorageTable::CompleteTable()
{
UINT unMaxIndex = 0;
for (CStorageTableRow* pRow : m_arRows)
unMaxIndex = std::max(unMaxIndex, pRow->GetIndex());
for (CStorageTableRow* pRow : m_arRows)
{
if (NULL == pRow || 0 == pRow->GetCount())
continue;
for (UINT unIndex = pRow->GetIndex(); unIndex < unMaxIndex; ++unIndex)
pRow->InsertCell(CStorageTableCell::CreateEmpty(), unIndex);
}
RecalculateMaxColumns();
}
const std::vector<std::vector<CStorageTableRow*>>& CStorageTable::GetHeaders() const
{
return m_arHeaders;
}
const std::vector<CStorageTableRow*>& CStorageTable::GetFoothers() const
{
return m_arFoother;
}
const std::vector<CStorageTableRow*>& CStorageTable::GetRows() const
{
return m_arRows;
}
const std::vector<CTableColgroup*> CStorageTable::GetColgroups() const
{
return m_arColgroups;
}
UINT CStorageTable::GetMaxColumns() const
{
return m_unMaxColumns;
}
}

255
HtmlFile2/Table.h Normal file
View File

@ -0,0 +1,255 @@
#ifndef TABLE_H
#define TABLE_H
#include "../DesktopEditor/common/StringBuilder.h"
#include "../Common/3dParty/html/css/src/StyleProperties.h"
#include "../Common/3dParty/html/css/src/CNode.h"
#include <vector>
namespace HTML
{
#define MAXCOLUMNSINTABLE 63
#define MAXROWSINTABLE 32767
enum class ERowParseMode
{
Header,
Body,
Foother
};
enum class ERowPosition
{
First,
Middle,
Last
};
struct TTableRowStyle
{
UINT m_unMaxIndex;
UINT m_unMaxHeight;
bool m_bIsHeader;
TTableRowStyle();
bool Empty() const;
};
struct TTableCellStyle
{
NSCSS::NSProperties::CDigit m_oWidth;
NSCSS::NSProperties::CDigit m_oHeight;
NSCSS::NSProperties::CBorder m_oBorder;
NSCSS::NSProperties::CIndent m_oPadding;
NSCSS::NSProperties::CColor m_oBackground;
std::wstring m_wsHAlign;
std::wstring m_wsVAlign;
TTableCellStyle();
bool Empty();
void Copy(const TTableCellStyle* pTableCellStyle);
TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle);
};
class CStorageTable;
class CStorageTableCell
{
public:
CStorageTableCell();
CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty);
CStorageTableCell(CStorageTableCell& oCell);
bool Empty() const;
bool Merged() const;
CStorageTableCell* Copy();
static CStorageTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL);
static CStorageTableCell* CreateEmpty(const TTableCellStyle* pStyle);
void SetColspan(UINT unColspan, UINT unCurrentIndex);
UINT GetColspan() const;
void SetRowspan(UINT unRowspan);
UINT GetRowspan() const;
NSStringUtils::CStringBuilder* GetData();
const TTableCellStyle* GetStyles() const;
TTableCellStyle* GetStyles();
void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
void SetHeight(const NSCSS::NSProperties::CDigit& oHeight);
UINT GetWidth() const;
UINT GetHeight() const;
void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
void ClearTopBorder();
void ClearLeftBorder();
void ClearBottomBorder();
void ClearRightBorder();
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
void SetHAlign(const std::wstring& wsAlign);
void SetVAlign(const std::wstring& wsAlign);
void SetBackground(const NSCSS::NSProperties::CColor& oColor);
private:
UINT m_unColspan;
UINT m_unRowSpan;
bool m_bIsMerged;
bool m_bIsEmpty;
TTableCellStyle m_oStyles;
NSStringUtils::CStringBuilder m_oData;
};
class CStorageTableRow
{
public:
CStorageTableRow();
~CStorageTableRow();
void AddCell(CStorageTableCell* pCell);
void InsertCell(CStorageTableCell *pCell, int nPosition);
UINT GetIndex() const;
UINT GetCount() const;
CStorageTableCell* operator[](UINT unIndex);
bool Empty() const;
const TTableRowStyle& GetStyles() const;
const std::vector<CStorageTableCell*>& GetCells() const;
private:
TTableRowStyle m_oStyles;
std::vector<CStorageTableCell*> m_arCells;
};
class CTableCol
{
public:
CTableCol(UINT unSpan);
CTableCol(const NSCSS::CNode& oTableColNode);
UINT GetSpan() const;
TTableCellStyle* GetStyle();
const TTableCellStyle* GetStyle() const;
private:
UINT m_unSpan;
TTableCellStyle m_oStyle;
};
class CTableColgroup
{
public:
CTableColgroup(NSCSS::CNode& oTableColgroupNode);
~CTableColgroup();
bool Empty() const;
void AddCol(CTableCol* pCol);
const std::vector<CTableCol*>& GetCols() const;
private:
std::vector<CTableCol*> m_arCols;
UINT m_unWidth;
};
//Необходимые стили таблицы
struct TTableStyles
{
NSCSS::NSProperties::CIndent m_oPadding;
NSCSS::NSProperties::CIndent m_oMargin;
NSCSS::NSProperties::CBorder m_oBorder;
NSCSS::NSProperties::CDigit m_oWidth;
int m_nCellSpacing;
std::wstring m_wsAlign;
enum ETableRules
{
All,
Groups,
Cols,
None,
Rows
} m_enRules;
TTableStyles();
bool Empty() const;
};
class CStorageTable
{
public:
CStorageTable();
~CStorageTable();
CStorageTableRow* operator[](UINT unIndex);
bool Empty() const;
bool HaveCaption();
bool HaveColgroups() const;
bool HaveHeader() const;
UINT GetRowCount() const;
const TTableStyles& GetTableStyles() const;
const TTableCellStyle* GetColStyle(UINT unColumnNumber) const;
void AddRows(std::vector<CStorageTableRow*>& m_arRows, ERowParseMode eParseMode = ERowParseMode::Body);
void AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::Body);
NSStringUtils::CStringBuilder* GetCaptionData();
void SetPadding(const NSCSS::NSProperties::CIndent& oPadding);
const NSCSS::NSProperties::CIndent& GetPadding() const;
void SetMargin(const NSCSS::NSProperties::CIndent& oMargin);
void SetBorder(const NSCSS::NSProperties::CBorder& oBorder);
void SetWidth(const NSCSS::NSProperties::CDigit& oWidth);
void SetCellSpacing(int nCellSpacing);
void SetAlign(const std::wstring& wsValue);
void SetRules(const std::wstring& wsValue);
void AddColgroup(CTableColgroup* pElement);
void RecalculateMaxColumns();
void Shorten();
void CompleteTable();
//TODO:: переделать на const std::vector<const T*> Get...() const;
const std::vector<std::vector<CStorageTableRow*>>& GetHeaders() const;
const std::vector<CStorageTableRow*>& GetFoothers() const;
const std::vector<CStorageTableRow*>& GetRows() const;
const std::vector<CTableColgroup*> GetColgroups() const;
UINT GetMaxColumns() const;
private:
std::vector<std::vector<CStorageTableRow*>> m_arHeaders;
std::vector<CStorageTableRow*> m_arFoother;
std::vector<CStorageTableRow*> m_arRows;
std::vector<UINT> m_arMinColspan;
NSStringUtils::CStringBuilder m_oCaption;
std::vector<CTableColgroup*> m_arColgroups;
TTableStyles m_oStyles;
UINT m_unMaxColumns;
};
}
#endif // TABLE_H

90
HtmlFile2/Tags/HTMLTags.h Normal file
View File

@ -0,0 +1,90 @@
#ifndef HTMLTAGS_H
#define HTMLTAGS_H
#include "../Common/3dParty/html/css/src/CNode.h"
#include <boost/any.hpp>
namespace HTML
{
class ITag
{
public:
virtual ~ITag() = default;
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) = 0;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
};
class CEmptyTag : public ITag
{
public:
virtual ~CEmptyTag() = default;
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any())
{
return true;
};
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) {};
};
template<class T>
class CTag : public ITag
{
protected:
T* m_pWriter;
public:
CTag(T* pWriter)
: m_pWriter(pWriter)
{}
virtual ~CTag() = default;
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) = 0;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
bool ValidWriter() const
{
return nullptr != m_pWriter;
}
};
#define CREATE_TAG(tag_name)\
template<class T>\
class tag_name : public CTag<T>\
{\
public:\
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors) = 0;\
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;\
}
CREATE_TAG(CAnchor);
CREATE_TAG(CAbbr);
CREATE_TAG(CBold);
CREATE_TAG(CBidirectional);
CREATE_TAG(CBreak);
CREATE_TAG(CCenter);
CREATE_TAG(CItalic);
CREATE_TAG(CKbd);
CREATE_TAG(CStrike);
CREATE_TAG(CUnderline);
CREATE_TAG(CMark);
CREATE_TAG(CQuotation);
CREATE_TAG(CSup);
CREATE_TAG(CSpan);
CREATE_TAG(CDD);
CREATE_TAG(CPreformatted);
CREATE_TAG(CHeader);
CREATE_TAG(CDivision);
CREATE_TAG(CImage);
CREATE_TAG(CFont);
CREATE_TAG(CInput);
CREATE_TAG(CBaseFont);
CREATE_TAG(CBlockquote);
CREATE_TAG(CHorizontalRule);
CREATE_TAG(CList);
CREATE_TAG(CListElement);
CREATE_TAG(CCaption);
CREATE_TAG(CTable);
CREATE_TAG(CTableRow);
CREATE_TAG(CTableCell);
CREATE_TAG(CCode);
CREATE_TAG(CHTML);
}
#endif // HTMLTAGS_H

520
HtmlFile2/Tags/MDTags.cpp Normal file
View File

@ -0,0 +1,520 @@
#include "MDTags.h"
#include "../src/StringFinder.h"
#include "../Table.h"
#include <boost/tuple/tuple.hpp>
namespace HTML
{
CAnchor<CMDWriter>::CAnchor(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CAnchor<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteString(L"[");
return true;
}
void CAnchor<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->WriteString(L"]");
std::wstring wsHref, wsTitle;
arSelectors.back().GetAttributeValue(L"href", wsHref);
arSelectors.back().GetAttributeValue(L"title", wsTitle);
m_pWriter->WriteString(L'(' + wsHref);
if (!wsTitle.empty())
m_pWriter->WriteString(L" \"" + wsTitle + L'"');
m_pWriter->WriteString(L")");
}
CBold<CMDWriter>::CBold(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CBold<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
if (m_pWriter->IsBold())
return true;
m_pWriter->WriteOpenSpecialString(L"**");
m_pWriter->EnteredBold();
return true;
}
void CBold<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter() || !m_pWriter->IsBold())
return;
m_pWriter->WriteCloseSpecialString(L"**");
m_pWriter->OutBold();
}
CBreak<CMDWriter>::CBreak(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CBreak<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteBreakLine();
return true;
}
void CBreak<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{}
CItalic<CMDWriter>::CItalic(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CItalic<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
if (m_pWriter->IsItalic())
return true;
m_pWriter->WriteOpenSpecialString(L"*");
m_pWriter->EnteredItalic();
return true;
}
void CItalic<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter() || !m_pWriter->IsItalic())
return;
m_pWriter->WriteCloseSpecialString(L"*");
m_pWriter->OutItalic();
}
CStrike<CMDWriter>::CStrike(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CStrike<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
if (m_pWriter->IsStrike())
return true;
m_pWriter->WriteOpenSpecialString(L"~~");
m_pWriter->EnteredStrike();
return true;
}
void CStrike<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter() || !m_pWriter->IsStrike())
return;
m_pWriter->WriteCloseSpecialString(L"~~");
m_pWriter->OutStrike();
}
CQuotation<CMDWriter>::CQuotation(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CQuotation<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
return true;
}
void CQuotation<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{}
CPreformatted<CMDWriter>::CPreformatted(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CPreformatted<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteOpenSpecialString(L"```");
m_pWriter->EnteredPreformatted();
return true;
}
void CPreformatted<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
bool bNeedBreakLine{false};
for (std::vector<NSCSS::CNode>::const_reverse_iterator itElement{arSelectors.crbegin()}; itElement < arSelectors.crend(); ++itElement)
{
if (L"pre" == itElement->m_wsName)
{
bNeedBreakLine = true;
break;
}
}
if (bNeedBreakLine && !m_pWriter->InTable())
m_pWriter->WriteBreakLine();
m_pWriter->WriteCloseSpecialString(L"```");
m_pWriter->OutPreformatted();
if (bNeedBreakLine && !m_pWriter->InTable())
m_pWriter->WriteBreakLine(false);
}
CHeader<CMDWriter>::CHeader(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CHeader<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
switch(arSelectors.back().m_wsName[1])
{
case L'1' : m_pWriter->WriteString(L"# ", true); break;
case L'2' : m_pWriter->WriteString(L"## ", true); break;
case L'3' : m_pWriter->WriteString(L"### ", true); break;
case L'4' : m_pWriter->WriteString(L"#### ", true); break;
case L'5' : m_pWriter->WriteString(L"##### ", true); break;
case L'6' : m_pWriter->WriteString(L"###### ", true); break;
default:
return false;
}
return true;
}
void CHeader<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
}
CImage<CMDWriter>::CImage(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CImage<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
std::wstring wsAlt, wsSrc, wsTitle;
if (!arSelectors.back().GetAttributeValue(L"src", wsSrc) &&
!arSelectors.back().GetAttributeValue(L"alt", wsAlt))
return false;
arSelectors.back().GetAttributeValue(L"title", wsTitle);
m_pWriter->WriteString(L"![" + wsAlt + L"](" + wsSrc);
if (!wsTitle.empty())
m_pWriter->WriteString(L" \"" + wsTitle + L'"');
m_pWriter->WriteString(L")");
return true;
}
void CImage<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->WriteBreakLine();
}
CHorizontalRule<CMDWriter>::CHorizontalRule(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CHorizontalRule<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteBreakLine(false);
m_pWriter->WriteString(L"---");
m_pWriter->WriteBreakLine(false);
return true;
}
void CHorizontalRule<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{}
CBlockquote<CMDWriter>::CBlockquote(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CBlockquote<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteBreakLine();
m_pWriter->EnteredBlockquote();
return true;
}
void CBlockquote<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->OutBlockquote();
m_pWriter->WriteBreakLine();
m_pWriter->WriteBreakLine(false);
}
CTable<CMDWriter>::CTable(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CTable<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter() /*|| m_pWriter->InTable()*/) //В MD не поддерживаются вложенные таблицы (пока разруливаем в парсере)
return false;
m_pWriter->WriteBreakLine();
m_pWriter->EnteredTable();
if (m_pWriter->InCode())
{
if (!m_pWriter->InPreformatted())
m_pWriter->WriteCloseSpecialString(L"`");
m_pWriter->OutCode();
}
if (m_pWriter->InPreformatted())
{
m_pWriter->WriteBreakLine();
m_pWriter->WriteCloseSpecialString(L"```");
m_pWriter->WriteBreakLine(false);
m_pWriter->OutPreformatted();
}
return true;
}
void CTable<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->OutTable();
m_pWriter->WriteBreakLine();
}
CTableRow<CMDWriter>::CTableRow(CMDWriter* pWriter)
: CTag(pWriter), m_unLastRowType(static_cast<UINT>(ERowParseMode::Foother))
{}
bool CTableRow<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
using DataForRow = boost::tuple<const TTableRowStyle*, const CStorageTable&, ERowParseMode, ERowPosition>;
if (!ValidWriter() || oExtraData.empty() || typeid(DataForRow) != oExtraData.type())
return false;
m_pWriter->EnteredTable();
const DataForRow& oDataForRow(boost::any_cast<DataForRow>(oExtraData));
const CStorageTable& oStorageTable{boost::get<1>(oDataForRow)};
if (nullptr == boost::get<0>(oDataForRow) && ERowParseMode::Header == boost::get<2>(oDataForRow))
{
for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
m_pWriter->WriteOpenSpecialString(L"| ");
m_pWriter->WriteOpenSpecialString(L"|");
m_pWriter->WriteBreakLine();
m_unLastRowType = static_cast<UINT>(ERowParseMode::Header);
return true;
}
if (m_unLastRowType == static_cast<UINT>(ERowParseMode::Header))
{
for (UINT unIndex = 0; unIndex < oStorageTable.GetMaxColumns(); ++unIndex)
m_pWriter->WriteString(L"|-");
m_pWriter->WriteOpenSpecialString(L"|");
m_pWriter->WriteBreakLine(false);
}
m_pWriter->WriteOpenSpecialString(L"| ");
m_unLastRowType = static_cast<UINT>(boost::get<2>(oDataForRow));
return true;
}
void CTableRow<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->WriteBreakLine(false);
}
CTableCell<CMDWriter>::CTableCell(CMDWriter* pWriter)
: CTag(pWriter), m_unNeedEmptyCells(0)
{}
bool CTableCell<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
using DataForCell = boost::tuple<const CStorageTableCell&, const CStorageTable&, UINT, ERowParseMode, ERowPosition>;
if (!ValidWriter() || oExtraData.empty() || typeid(DataForCell) != oExtraData.type())
return false;
const DataForCell& oDataForCell{boost::any_cast<const DataForCell>(oExtraData)};
m_unNeedEmptyCells = boost::get<0>(oDataForCell).GetColspan() - 1;
return true;
}
void CTableCell<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
for (UINT unIndex = 0; unIndex < m_unNeedEmptyCells; ++unIndex)
m_pWriter->WriteOpenSpecialString(L" |");
m_unNeedEmptyCells = 0;
m_pWriter->WriteOpenSpecialString(L" | ");
}
CList<CMDWriter>::CList(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CList<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->WriteBreakLine();
m_pWriter->EnteredList(L"ol" == arSelectors.back().m_wsName);
if (!m_pWriter->InOrederedList())
return true;
std::wstring wsIndex;
if (arSelectors.back().GetAttributeValue(L"start", wsIndex))
m_pWriter->SetIndexOrderedList(NSStringFinder::ToInt(wsIndex, 1));
return true;
}
void CList<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
m_pWriter->OutList();
}
CListElement<CMDWriter>::CListElement(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CListElement<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
if (0 != m_pWriter->GetLevelList())
{
for (UINT unLevelList = 0; unLevelList < m_pWriter->GetLevelList() - 1; ++unLevelList)
m_pWriter->WriteString(L" ");
}
if (m_pWriter->InOrederedList())
{
m_pWriter->WriteString(std::to_wstring(m_pWriter->GetIndexOrderedList()) + m_pWriter->GetParametrs().m_wchOrderedList + L' ');
m_pWriter->IncreaseIndexOrderedList();
}
else
m_pWriter->WriteString({m_pWriter->GetParametrs().m_wchUnorderedList, L' '});
return true;
}
void CListElement<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{}
CCode<CMDWriter>::CCode(CMDWriter* pWriter)
: CTag(pWriter)
{}
bool CCode<CMDWriter>::Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData)
{
if (!ValidWriter())
return false;
m_pWriter->EnteredCode();
if (m_pWriter->InPreformatted())
{
if (!arSelectors.back().m_wsClass.empty() && arSelectors.back().m_wsClass.size() >= 9 &&
0 == arSelectors.back().m_wsClass.compare(0, 9, L"language-"))
m_pWriter->WriteString(arSelectors.back().m_wsClass.substr(9, arSelectors.back().m_wsClass.size() - 9));
m_pWriter->WriteBreakLine(false);
}
else
m_pWriter->WriteOpenSpecialString(L"`");
return true;
}
void CCode<CMDWriter>::Close(const std::vector<NSCSS::CNode>& arSelectors)
{
if (!ValidWriter())
return;
if (!m_pWriter->InPreformatted())
m_pWriter->WriteCloseSpecialString(L"`");
m_pWriter->OutCode();
}
}

165
HtmlFile2/Tags/MDTags.h Normal file
View File

@ -0,0 +1,165 @@
#ifndef MDTAGS_H
#define MDTAGS_H
#include "HTMLTags.h"
#include "../Writers/MDWriter.h"
namespace HTML
{
template<>
class CAnchor<CMDWriter> : public CTag<CMDWriter>
{
public:
CAnchor(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBold<CMDWriter> : public CTag<CMDWriter>
{
public:
CBold(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBreak<CMDWriter> : public CTag<CMDWriter>
{
public:
CBreak(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CItalic<CMDWriter> : public CTag<CMDWriter>
{
public:
CItalic(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CStrike<CMDWriter> : public CTag<CMDWriter>
{
public:
CStrike(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CQuotation<CMDWriter> : public CTag<CMDWriter>
{
public:
CQuotation(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CPreformatted<CMDWriter> : public CTag<CMDWriter>
{
public:
CPreformatted(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CHeader<CMDWriter> : public CTag<CMDWriter>
{
public:
CHeader(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CImage<CMDWriter> : public CTag<CMDWriter>
{
public:
CImage(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CHorizontalRule<CMDWriter> : public CTag<CMDWriter>
{
public:
CHorizontalRule(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBlockquote<CMDWriter> : public CTag<CMDWriter>
{
public:
CBlockquote(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTable<CMDWriter> : public CTag<CMDWriter>
{
public:
CTable(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTableRow<CMDWriter> : public CTag<CMDWriter>
{
UINT m_unLastRowType;
public:
CTableRow(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTableCell<CMDWriter> : public CTag<CMDWriter>
{
UINT m_unNeedEmptyCells;
public:
CTableCell(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CList<CMDWriter> : public CTag<CMDWriter>
{
public:
CList(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CListElement<CMDWriter> : public CTag<CMDWriter>
{
public:
CListElement(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CCode<CMDWriter> : public CTag<CMDWriter>
{
public:
CCode(CMDWriter* pWriter);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
}
#endif // MDTAGS_H

1492
HtmlFile2/Tags/OOXMLTags.cpp Normal file

File diff suppressed because it is too large Load Diff

167
HtmlFile2/Tags/OOXMLTags.h Normal file
View File

@ -0,0 +1,167 @@
#ifndef OOXMLTAGS_H
#define OOXMLTAGS_H
#include "HTMLTags.h"
#include "../Writers/OOXMLWriter.h"
namespace HTML
{
template<>
class CAnchor<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CAnchor(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CAbbr<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CAbbr(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBreak<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CBreak(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CDivision<COOXMLWriter> : public CTag<COOXMLWriter>
{
std::stack<UINT> m_arFootnoteIDs;
public:
CDivision(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CImage<COOXMLWriter> : public CTag<COOXMLWriter>
{
std::vector<std::wstring> m_arrImages;
public:
CImage(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CFont<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CFont(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CInput<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CInput(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBaseFont<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CBaseFont(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CBlockquote<COOXMLWriter> : public CTag<COOXMLWriter>
{
std::map<std::wstring, UINT> m_mDivs;
public:
CBlockquote(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CHorizontalRule<COOXMLWriter> : public CTag<COOXMLWriter>
{
UINT m_unShapeId;
public:
CHorizontalRule(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CList<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CList(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CListElement<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CListElement(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CCaption<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CCaption(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTable<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CTable(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTableRow<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CTableRow(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CTableCell<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CTableCell(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CHTML<COOXMLWriter> : public CTag<COOXMLWriter>
{
public:
CHTML(COOXMLWriter* pInterpretator);
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) override;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
}
#endif // OOXMLTAGS_H

View File

@ -0,0 +1,37 @@
#ifndef IWRITER_H
#define IWRITER_H
#include "../../Common/3dParty/html/css/src/CNode.h"
#include "../Common.h"
namespace HTML
{
class IWriter
{
public:
IWriter() = default;
virtual ~IWriter() = default;
virtual void Begin(const std::wstring& wsDst) = 0;
virtual void End(const std::wstring& wsDst) = 0;
virtual bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) = 0;
virtual void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) = 0;
virtual void PageBreak() = 0;
virtual void BeginBlock() = 0;
virtual void EndBlock(bool bAddBlock) = 0;
virtual void SetDataOutput(XmlString* pOutputData) = 0; // Задаем место вывода для интерпретатора
virtual void RevertDataOutput() = 0; // Возвращаем место вывода к исходному
virtual XmlString* GetCurrentDocument() const = 0;
//TODO:: перенести разруливание вложенных таблиц в конвертацию после изменения принципа работы с таблицами
virtual bool SupportNestedTables() const = 0;
};
}
#endif // IWRITER_H

View File

@ -0,0 +1,408 @@
#include "MDWriter.h"
#include <cwctype>
#include "../../DesktopEditor/common/File.h"
#include "../../Common/3dParty/html/css/src/CCompiledStyle.h"
namespace HTML
{
CMDWriter::CMDWriter(const TMarkdownParameters& oMDParametrs)
: m_oMDParametrs(oMDParametrs)
{
m_arStates.push(TState{});
m_arStates.top().m_pCurrentDocument = &m_oDocument;
}
void CMDWriter::Begin(const std::wstring& wsDst)
{
}
void CMDWriter::End(const std::wstring& wsDst)
{
NSFile::CFileBinary oDocument;
if (!oDocument.CreateFileW(wsDst))
return;
oDocument.WriteStringUTF8(m_oDocument.GetData());
oDocument.CloseFile();
}
inline void ReplaceSpaces(std::wstring& wsValue)
{
// boost::wregex oRegex(L"\\s+");
// wsValue = boost::regex_replace(wsValue, oRegex, L" ");
std::wstring::const_iterator itBegin = std::find_if(wsValue.cbegin(), wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
std::wstring::const_iterator itEnd;
while (wsValue.cend() != itBegin)
{
itEnd = std::find_if(itBegin, wsValue.cend(), [](wchar_t wchValue){ return !std::iswspace(wchValue) || 0xa0 == wchValue; });
wsValue.replace(itBegin, itEnd, L" ");
itBegin = std::find_if(itBegin + 1, wsValue.cend(), [](wchar_t wchValue){ return std::iswspace(wchValue) && 0xa0 != wchValue; });
}
}
bool CMDWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors)
{
bool bPreformatted{InPreformatted()};
const NSCSS::CCompiledStyle* pCompiledStyle{arSelectors.back().m_pCompiledStyle};
if (!bPreformatted && nullptr != pCompiledStyle)
{
// TODO::поведение должно быть немного разное (реализовать)
switch(pCompiledStyle->m_oDisplay.GetWhiteSpace().ToInt())
{
case NSCSS::NSProperties::EWhiteSpace::Pre:
case NSCSS::NSProperties::EWhiteSpace::Pre_Wrap:
case NSCSS::NSProperties::EWhiteSpace::Pre_Line:
bPreformatted = true;
default:
break;
}
}
if (!bPreformatted && wsText.end() == std::find_if_not(wsText.begin(), wsText.end(), [](wchar_t wchChar){ return iswspace(wchChar) && 0xa0 != wchChar;}))
return false;
if (bPreformatted && !m_arStates.top().m_bEmptyLine && !m_arStates.top().m_bInTable)
{
for (std::vector<NSCSS::CNode>::const_reverse_iterator itElement{arSelectors.crbegin()}; itElement < arSelectors.crend(); ++itElement)
{
if (L"pre" == itElement->m_wsName)
{
GetCurrentDocument()->AddCharSafe(L'\n');
break;
}
}
}
//Пока корректно работает только для текста (необходимо проверить и с другими нодами)
if (m_arStates.top().m_bEmptyLine)
{
for (UINT unIndex = 0; unIndex < GetLevelBlockquote(); ++unIndex)
WriteString(L"> ", true);
}
if (!bPreformatted && !InCode())
ReplaceSpaces(wsText);
bool bNeedBold{false}, bNeedItalic{false}, bNeedStrike{false};
if (nullptr != pCompiledStyle)
{
if (!IsBold() && pCompiledStyle->m_oFont.Bold())
bNeedBold = true;
if (!IsItalic() && pCompiledStyle->m_oFont.Italic())
bNeedItalic = true;
if (!IsStrike() && pCompiledStyle->m_oText.LineThrough())
bNeedStrike = true;
}
if (bNeedBold)
WriteString(L"**");
if (bNeedItalic)
WriteString(L"*");
if (bNeedStrike)
WriteString(L"~~");
ApplyAlternativeTags(pCompiledStyle);
WriteString(wsText);
ApplyAlternativeTags(pCompiledStyle, true);
if (bNeedBold)
WriteString(L"**");
if (bNeedItalic)
WriteString(L"*");
if (bNeedStrike)
WriteString(L"~~");
if (L'\n' == wsText.back())
m_arStates.top().m_bNeedBreakLine = false;
return true;
}
void CMDWriter::WriteEmptyParagraph(bool bVahish, bool bInP)
{}
void CMDWriter::PageBreak()
{}
void CMDWriter::BeginBlock()
{
if (!m_arStates.top().m_bInList)
WriteBreakLine();
}
void CMDWriter::EndBlock(bool bAddBlock)
{
if (!m_arStates.top().m_bInTable)
WriteBreakLine();
}
void CMDWriter::SetDataOutput(XmlString* pOutputData)
{
SaveState();
m_arStates.top().m_pCurrentDocument = pOutputData;
}
void CMDWriter::RevertDataOutput()
{
RollBackState();
}
TMarkdownParameters CMDWriter::GetParametrs() const
{
return m_oMDParametrs;
}
void CMDWriter::WriteString(const std::wstring& wsString, bool bSpecialString)
{
GetCurrentDocument()->WriteString(wsString);
if (m_arStates.top().m_bEmptyLine)
m_arStates.top().m_bEmptyLine = wsString.empty();
if (!bSpecialString)
m_arStates.top().m_bNeedBreakLine = true;
}
void CMDWriter::WriteOpenSpecialString(const std::wstring& wsString)
{
if (m_arStates.top().m_wsLastSpecialString == wsString)
GetCurrentDocument()->WriteString(L" ");
m_arStates.top().m_wsLastSpecialString.clear();
WriteString(wsString, true);
}
void CMDWriter::WriteCloseSpecialString(const std::wstring& wsString)
{
m_arStates.top().m_wsLastSpecialString = wsString;
WriteString(wsString, true);
}
XmlString* CMDWriter::GetCurrentDocument() const
{
return m_arStates.top().m_pCurrentDocument;
}
bool CMDWriter::SupportNestedTables() const
{
return false;
}
void CMDWriter::WriteBreakLine(bool bNeedChecked)
{
if (bNeedChecked && !m_arStates.top().m_bNeedBreakLine)
return;
if (m_arStates.top().m_bInTable && bNeedChecked)
{
if (m_oMDParametrs.m_bUseAlternativeHTMLTags)
WriteString(L"</br>");
m_arStates.top().m_bNeedBreakLine = false;
return;
}
if (m_arStates.top().m_bEmptyLine)
{
for (UINT unIndex = 0; unIndex < GetLevelBlockquote(); ++unIndex)
WriteString(L"> ", true);
}
GetCurrentDocument()->WriteString(L" \n");
m_arStates.top().m_bEmptyLine = true;
m_arStates.top().m_bNeedBreakLine = false;
m_arStates.top().m_wsLastSpecialString.clear();
}
void CMDWriter::EnteredBold()
{
m_arStates.top().m_bBold = true;
}
void CMDWriter::OutBold()
{
m_arStates.top().m_bBold = false;
}
bool CMDWriter::IsBold()
{
return m_arStates.top().m_bBold;
}
void CMDWriter::EnteredItalic()
{
m_arStates.top().m_bItalic = true;
}
void CMDWriter::OutItalic()
{
m_arStates.top().m_bItalic = false;
}
bool CMDWriter::IsItalic()
{
return m_arStates.top().m_bItalic;
}
void CMDWriter::EnteredStrike()
{
m_arStates.top().m_bStrike = true;
}
void CMDWriter::OutStrike()
{
m_arStates.top().m_bStrike = false;
}
bool CMDWriter::IsStrike()
{
return m_arStates.top().m_bStrike;
}
void CMDWriter::EnteredBlockquote()
{
m_arStates.top().m_unLevelBlockquote++;
}
void CMDWriter::OutBlockquote()
{
if (m_arStates.top().m_unLevelBlockquote > 0)
m_arStates.top().m_unLevelBlockquote--;
}
UINT CMDWriter::GetLevelBlockquote()
{
return m_arStates.top().m_unLevelBlockquote;
}
void CMDWriter::EnteredTable()
{
m_arStates.top().m_bInTable = true;
}
void CMDWriter::OutTable()
{
m_arStates.top().m_bInTable = false;
}
bool CMDWriter::InTable() const
{
return m_arStates.top().m_bInTable;
}
void CMDWriter::EnteredPreformatted()
{
m_arStates.top().m_bInPreformatted = true;
}
void CMDWriter::OutPreformatted()
{
m_arStates.top().m_bInPreformatted = false;
}
bool CMDWriter::InPreformatted() const
{
return m_arStates.top().m_bInPreformatted;
}
void CMDWriter::EnteredCode()
{
m_arStates.top().m_bInCode = true;
}
void CMDWriter::OutCode()
{
m_arStates.top().m_bInCode = false;
}
bool CMDWriter::InCode() const
{
return m_arStates.top().m_bInCode;
}
void CMDWriter::EnteredList(bool bOrderedList)
{
SaveState();
m_arStates.top().m_bInList = true;
m_arStates.top().m_bIsOrederedList = bOrderedList;
m_arStates.top().m_unLevelList++;
}
void CMDWriter::OutList()
{
RollBackState();
}
void CMDWriter::SetIndexOrderedList(UINT unIndex)
{
m_arStates.top().m_unIndexListElement = unIndex;
}
void CMDWriter::IncreaseIndexOrderedList()
{
m_arStates.top().m_unIndexListElement++;
}
bool CMDWriter::InOrederedList() const
{
return m_arStates.top().m_bIsOrederedList;
}
UINT CMDWriter::GetIndexOrderedList() const
{
return m_arStates.top().m_unIndexListElement;
}
UINT CMDWriter::GetLevelList() const
{
return m_arStates.top().m_unLevelList;
}
void CMDWriter::SaveState()
{
m_arStates.push(m_arStates.top());
}
void CMDWriter::RollBackState()
{
if (m_arStates.size() > 1)
m_arStates.pop();
}
void CMDWriter::ApplyAlternativeTags(const NSCSS::CCompiledStyle* pCompiledStyle, bool bIsCloseTag)
{
if (nullptr == pCompiledStyle || !m_oMDParametrs.m_bUseAlternativeHTMLTags)
return;
if (pCompiledStyle->m_oText.Underline())
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</u>" : L"<u>");
if (L"top" == pCompiledStyle->m_oDisplay.GetVAlign().ToWString())
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</sup>" : L"<sup>");
else if (L"bottom" == pCompiledStyle->m_oDisplay.GetVAlign().ToWString())
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</sub>" : L"<sub>");
if (L"FFFF00" == pCompiledStyle->m_oBackground.GetColor().ToHEX())
GetCurrentDocument()->WriteString(bIsCloseTag ? L"</mark>" : L"<mark>");
}
}

View File

@ -0,0 +1,119 @@
#ifndef MDWRITER_H
#define MDWRITER_H
#include "IWriter.h"
#include "../MarkdownParameters.h"
#include <stack>
namespace HTML
{
class CMDWriter : public IWriter
{
XmlString m_oDocument;
struct TState
{
XmlString *m_pCurrentDocument{nullptr};
bool m_bNeedBreakLine{false};
bool m_bEmptyLine{true};
UINT m_unLevelBlockquote{0};
bool m_bBold{false};
bool m_bItalic{false};
bool m_bStrike{false};
bool m_bInTable{false};
bool m_bInPreformatted{false};
bool m_bInCode{false};
bool m_bInList{false};
bool m_bIsOrederedList{false};
UINT m_unLevelList{0};
UINT m_unIndexListElement{1};
std::wstring m_wsLastSpecialString;
};
std::stack<TState> m_arStates;
TMarkdownParameters m_oMDParametrs;
public:
CMDWriter(const TMarkdownParameters& oMDParametrs);
void Begin(const std::wstring& wsDst) override;
void End(const std::wstring& wsDst) override;
bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) override;
void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) override;
void PageBreak() override;
void BeginBlock() override;
void EndBlock(bool bAddBlock) override;
void SetDataOutput(XmlString* pOutputData) override;
void RevertDataOutput() override;
TMarkdownParameters GetParametrs() const;
void WriteString(const std::wstring& wsString, bool bSpecialString = false);
void WriteOpenSpecialString(const std::wstring& wsString);
void WriteCloseSpecialString(const std::wstring& wsString);
XmlString* GetCurrentDocument() const override;
bool SupportNestedTables() const override;
void WriteBreakLine(bool bNeedChecked = true);
void EnteredBold();
void OutBold();
bool IsBold();
void EnteredItalic();
void OutItalic();
bool IsItalic();
void EnteredStrike();
void OutStrike();
bool IsStrike();
void EnteredBlockquote();
void OutBlockquote();
UINT GetLevelBlockquote();
void EnteredTable();
void OutTable();
bool InTable() const;
void EnteredPreformatted();
void OutPreformatted();
bool InPreformatted() const;
void EnteredCode();
void OutCode();
bool InCode() const;
void EnteredList(bool bOrderedList);
void OutList();
void SetIndexOrderedList(UINT unIndex);
void IncreaseIndexOrderedList();
bool InOrederedList() const;
UINT GetIndexOrderedList() const;
UINT GetLevelList() const;
void SetLinePrefix(const std::wstring& wsPrefix);
void ClearLinePrefix();
private:
void SaveState();
void RollBackState();
void ApplyAlternativeTags(const NSCSS::CCompiledStyle* pCompiledStyle, bool bIsCloseTag = false);
};
}
#endif // MDWRITER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,216 @@
#ifndef OOXMLWRITER_H
#define OOXMLWRITER_H
#include "../../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h"
#include "../../Common/3dParty/html/css/src/CCssCalculator.h"
#include "../HTMLParameters.h"
#include "IWriter.h"
#include <stack>
namespace NSFonts { class IApplicationFonts; }
namespace HTML
{
struct TImageData
{
UINT m_unWidth;
UINT m_unHeight;
int m_nHSpace;
int m_nVSpace;
std::wstring m_wsAlign;
TImageData()
: m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left")
{}
bool ZeroSize() const
{
return 0 == m_unWidth || 0 == m_unHeight;
}
bool ZeroSpaces() const
{
return 0 == m_nHSpace && 0 == m_nVSpace;
}
};
class COOXMLWriter : public IWriter
{
const std::wstring *m_pDstPath; // Директория назначения
const std::wstring *m_pTempDir; // Temp папка
const std::wstring *m_pSrcPath; // Директория источника
const std::wstring *m_pBasePath; // Полный базовый адрес
const std::wstring *m_pCorePath; // Путь до корневого файла (используется для работы с Epub)
XmlString m_oStylesXml; // styles.xml
XmlString m_oDocXmlRels; // document.xml.rels
XmlString m_oNoteXmlRels; // footnotes.xml.rels
XmlString m_oDocXml; // document.xml
XmlString m_oNoteXml; // footnotes.xml
XmlString m_oNumberXml; // numbering.xml
XmlString m_oWebSettings; // webSettings.xml
NSCSS::CDocumentStyle m_oXmlStyle; // Ooxml стиль
NSCSS::NSProperties::CPage m_oPageData; // Стили страницы
NSCSS::CCssCalculator *m_pStylesCalculator;
THTMLParameters *m_pHTMLParameters;
struct TState
{
bool m_bInP; // <w:p> открыт?
bool m_bInR; // <w:r> открыт?
bool m_bInT; // <w:t> открыт?
bool m_bWasPStyle; // <w:pStyle> записан?
bool m_bWasSpace; // Был пробел?
bool m_bInHyperlink; // <w:hyperlink> открыт?
std::wstring m_wsTooltip;
std::wstring m_wsHref;
std::wstring m_wsFootnote;
bool m_bIsFootnote;
bool m_bISCrossHyperlink;
XmlString *m_pCurrentDocument; //Текущее место записи
bool m_bRemoveCurrentDocument;
TState(XmlString *pCurrentDocument)
: m_bInP(false), m_bInR(false), m_bInT(false),
m_bWasPStyle(false), m_bWasSpace(true), m_bInHyperlink(false),
m_bIsFootnote(false), m_bISCrossHyperlink(false),
m_pCurrentDocument(pCurrentDocument), m_bRemoveCurrentDocument(false)
{}
~TState()
{
if (m_bRemoveCurrentDocument && nullptr != m_pCurrentDocument)
delete m_pCurrentDocument;
}
void CreateNewCurrentDocument()
{
m_pCurrentDocument = new XmlString();
m_bRemoveCurrentDocument = true;
}
};
std::stack<TState> m_arStates;
int m_nFootnoteId; // ID сноски
int m_nHyperlinkId; // ID ссылки
int m_nListId; // ID списка
int m_nElementId; // ID остальные элементы
bool m_bBanUpdatePageData; // Запретить обновление данных о странице?
std::stack<std::wstring> m_arDivId;
bool m_bWasDivs;
std::map<std::wstring, std::wstring> m_mFootnotes; // Сноски
std::map<std::wstring, UINT> m_mBookmarks; // Закладки
using anchors_map = std::map<std::wstring, std::wstring>;
anchors_map m_mAnchors; // Map якорей с индивидуальными id
NSFonts::IApplicationFonts* m_pFonts; // Необходимо для оптимизации работы со шрифтами
public:
COOXMLWriter(THTMLParameters* pHTMLParameters = nullptr, NSCSS::CCssCalculator* pCSSCalculator = nullptr);
void SetSrcDirectory (const std::wstring& wsPath);
void SetDstDirectory (const std::wstring& wsPath);
void SetTempDirectory(const std::wstring& wsPath);
void SetBaseDirectory(const std::wstring& wsPath);
void SetCoreDirectory(const std::wstring& wsPath);
void Begin(const std::wstring& wsDst) override;
void End(const std::wstring& wsDst) override;
bool OpenP();
bool OpenR();
bool OpenT();
void OpenHyperlink();
void CloseP();
void CloseR();
void CloseT();
void CloseHyperlink();
void PageBreak() override;
void BeginBlock() override;
void EndBlock(bool bAddBlock) override;
void SetDataOutput(XmlString* pOutputData) override;
void RevertDataOutput() override;
void SaveState();
void RollBackState();
void SetCurrentDocument(XmlString* pNewDocument);
void Break(const std::vector<NSCSS::CNode>& arSelectors);
void SetHyperlinkData(const std::wstring& wsRef, const std::wstring& wsTooltip, bool bIsCross, const std::wstring& wsFootnote, bool bIsFootnote);
void ClearHyperlinkData();
void OpenCrossHyperlink(const std::wstring& wsRef);
void OpenExternalHyperlink(const std::wstring& wsRef, const std::wstring& wsTooltip);
void CloseCrossHyperlink(const std::vector<NSCSS::CNode>& arSelectors, std::wstring wsFootnote, const std::wstring& wsRef);
void CloseExternalHyperlink();
std::wstring WritePPr(const std::vector<NSCSS::CNode>& arSelectors);
std::wstring WriteRPr(XmlString& oXml, const std::vector<NSCSS::CNode>& arSelectors);
bool WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors) override;
void WriteEmptyParagraph(bool bVahish = false, bool bInP = false) override;
void WriteSpace();
void WriteEmptyBookmark(const std::wstring& wsId);
std::wstring AddLiteBookmark();
std::wstring WriteBookmark(const std::wstring& wsId);
std::wstring AddAnchor(const std::wstring& wsAnchorValue);
void WriteImage(const TImageData& oImageData, const std::wstring& wsId);
void WriteAlternativeImage(const std::wstring& wsAlt, const std::wstring& wsSrc, const TImageData& oImageData);
void WriteEmptyImage(int nWidth, int nHeight, const std::wstring& wsName = L"", const std::wstring& wsDescr = L"");
void WriteImageRels(const std::wstring& wsImageId, const std::wstring& wsImageName);
std::wstring GetStyle(const NSCSS::CCompiledStyle& oStyle, bool bParagraphStyle);
void UpdatePageStyle(const std::vector<NSCSS::CNode>& arSelectors);
void SetBaseFont(const std::wstring& wsFontStyles);
void SetDivId(const std::wstring& wsDivId);
void RollBackDivId();
void IncreaseListId();
int GetListId() const;
std::wstring FindFootnote(const std::wstring& wsId);
void OpenFootnote(const std::wstring& wsFootnoteID);
void CloseFootnote();
XmlString& GetStylesXml();
XmlString& GetDocRelsXml();
XmlString& GetNotesRelsXml();
XmlString& GetDocumentXml();
XmlString& GetNotesXml();
XmlString& GetNumberingXml();
XmlString& GetWebSettingsXml();
XmlString* GetCurrentDocument() const override;
bool SupportNestedTables() const override;
const NSCSS::NSProperties::CPage* GetPageData() const;
NSFonts::IApplicationFonts* GetFonts();
std::wstring GetMediaDir() const;
std::wstring GetTempDir() const;
std::wstring GetSrcPath() const;
std::wstring GetBasePath() const;
std::wstring GetCorePath() const;
};
}
#endif // OOXMLWRITER_H

View File

@ -5,9 +5,11 @@
#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include "../Common/3dParty/html/htmltoxhtml.h"
#include "htmlfile2.h"
#ifdef USE_OLD_HTML_CONVERTER
#include "../Common/3dParty/html/htmltoxhtml.h".
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
#include "../Common/3dParty/html/css/src/xhtml/CDocumentStyle.h"
#include "../Common/Network/FileTransporter/include/FileTransporter.h"
@ -23,7 +25,6 @@
#include "../DesktopEditor/raster/BgraFrame.h"
#include "../DesktopEditor/graphics/pro/Graphics.h"
#include "htmlfile2.h"
#include "src/Languages.h"
#include <boost/regex.hpp>
@ -267,7 +268,7 @@ struct CTextSettings
bool bPre; // Сохранение форматирования (Сохранение пробелов, табуляций, переносов строк)
bool bQ; // Цитата
bool bAddSpaces; // Добавлять пробелы перед текстом?
bool bMergeText; // Объединять подяр идущий текст в 1?
bool bMergeText; // Объединять подряд идущий текст в 1?
int nLi; // Уровень списка
bool bNumberingLi; // Является ли список нумерованным
@ -2488,16 +2489,6 @@ private:
sSelectors.push_back(NSCSS::CNode(L"html", L"", L""));
GetSubClass(&m_oDocXml, sSelectors);
/*
std::wstring sCrossId = std::to_wstring(m_nCrossId++);
m_oDocXml.WriteString(L"<w:bookmarkStart w:id=\"");
m_oDocXml.WriteString(sCrossId);
m_oDocXml.WriteString(L"\" w:name=\"");
m_oDocXml.WriteString(sFileName);
m_oDocXml.WriteString(L"\"/><w:bookmarkEnd w:id=\"");
m_oDocXml.WriteString(sCrossId);
m_oDocXml.WriteString(L"\"/>");
*/
if (!sSelectors.back().m_mAttributes.empty())
{
@ -2573,7 +2564,7 @@ private:
NSStringUtils::CStringBuilder oPPr;
const std::wstring sPStyle = wrP(&oPPr, arSelectors, oTS);
wrP(&oPPr, arSelectors, oTS);
WriteToStringBuilder(oPPr, *pXml);
@ -2590,9 +2581,6 @@ private:
sRStyle = wrRPr(&oRPr, arSelectors, oTS);
WriteToStringBuilder(oRPr, *pXml);
if (oTS.bQ)
pXml->WriteString(L"<w:t xml:space=\"preserve\">&quot;</w:t>");
}
if (oTS.bQ)
@ -2608,10 +2596,7 @@ private:
while (std::wstring::npos != unBegin)
{
if (OpenR(pXml))
{
pXml->WriteString(L"<w:test/>");
WriteToStringBuilder(oRPr, *pXml);
}
OpenT(pXml);
if (unEnd == std::wstring::npos)
@ -2684,11 +2669,13 @@ private:
wrP(pXml, arSelectors, oTS);
const std::wstring wsName{L"Bookmark" + std::to_wstring(m_mBookmarks.size() + 1)};
m_mBookmarks.insert(std::make_pair(wsName, m_mBookmarks.size() + 1));
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + wsName + L"\" \\o \"");
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"begin\"/></w:r><w:r><w:instrText>HYPERLINK \\l \"" + wsName + L"\" \\o \"");
pXml->WriteEncodeXmlString(wsNote);
pXml->WriteString(L"\"</w:instrText></w:r>");
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"separate\"/></w:r>");
const bool bResult = readStream(pXml, arSelectors, oTS);
pXml->WriteString(L"<w:r><w:fldChar w:fldCharType=\"end\"/></w:r>");
wsNote.clear();
@ -2701,7 +2688,7 @@ private:
return false;
CTextSettings oTSR(oTS);
oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
// oTSR.oAdditionalStyle.m_oFont.SetWeight(L"bold", UINT_MAX, true);
return readStream(pXml, arSelectors, oTSR);
}
@ -3843,7 +3830,7 @@ private:
CTextSettings oNewSettings{oTS};
const std::wstring wsHighlight{sSelectors.back().m_pCompiledStyle->m_oBackground.GetColor()
.EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
.EquateToColor({{{0, 0, 0}, L"black"}, {{0, 0, 255}, L"blue"}, {{0, 255, 255}, L"cyan"},
{{0, 255, 0}, L"green"}, {{255, 0, 255}, L"magenta"}, {{255, 0, 0}, L"red"},
{{255, 255, 0}, L"yellow"}, {{255, 255, 255}, L"white"}, {{0, 0, 139}, L"darkBlue"},
{{0, 139, 139}, L"darkCyan"}, {{0, 100, 0}, L"darkGreen"}, {{139, 0, 139}, L"darkMagenta"},
@ -4094,71 +4081,7 @@ private:
if(m_oLightReader.IsEmptyNode())
return false;
CloseP(oXml, arSelectors);
CTextSettings oTSLi(oTS);
++oTSLi.nLi;
//Нумерованный список
if (L"ol" == arSelectors.back().m_wsName)
{
int nStart = 1;
while(m_oLightReader.MoveToNextAttribute())
if(m_oLightReader.GetName() == L"start")
nStart = NSStringFinder::ToInt(m_oLightReader.GetText(), 1);
m_oLightReader.MoveToElement();
oTSLi.bNumberingLi = true;
const std::wstring wsStart(std::to_wstring(nStart));
m_oNumberXml.WriteString(L"<w:abstractNum w:abstractNumId=\"");
m_oNumberXml.WriteString(std::to_wstring(m_nNumberingId++));
m_oNumberXml.WriteString(L"\"><w:multiLevelType w:val=\"hybridMultilevel\"/><w:lvl w:ilvl=\"0\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%1.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"709\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"1\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%2.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"1429\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"2\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%3.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"2149\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"3\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%4.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2869\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"4\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%5.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"3589\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"5\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%6.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"4309\" w:hanging=\"180\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"6\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%7.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5029\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"7\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%8.\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"5749\" w:hanging=\"360\"/></w:pPr></w:lvl><w:lvl w:ilvl=\"8\"><w:start w:val=\"");
m_oNumberXml.WriteString(wsStart);
m_oNumberXml.WriteString(L"\"/><w:numFmt w:val=\"decimal\"/><w:isLgl w:val=\"false\"/><w:suff w:val=\"tab\"/><w:lvlText w:val=\"%9.\"/><w:lvlJc w:val=\"right\"/><w:pPr><w:ind w:left=\"6469\" w:hanging=\"180\"/></w:pPr></w:lvl></w:abstractNum>");
}
else
oTSLi.bNumberingLi = false;
CTextSettings oTSList{oTSLi};
oTSList.oAdditionalStyle.m_oMargin.SetTop (100, NSCSS::UnitMeasure::Twips, 0, true);
oTSList.oAdditionalStyle.m_oMargin.SetBottom(100, NSCSS::UnitMeasure::Twips, 0, true);
int nDeath = m_oLightReader.GetDepth();
while(m_oLightReader.ReadNextSiblingNode2(nDeath))
{
const std::wstring wsName = m_oLightReader.GetName();
if (L"li" == wsName)
ReadListElement(oXml, arSelectors, oTSList);
else
{
CloseP(oXml, arSelectors);
readInside(oXml, arSelectors, oTSLi, wsName);
}
}
CloseP(oXml, arSelectors);
return true;
}
bool readLi (NSStringUtils::CStringBuilder* oXml, std::vector<NSCSS::CNode>& sSelectors, CTextSettings& oTS, bool bType)
@ -5081,17 +5004,29 @@ private:
return true;
}
};
#else
#include "HTMLReader.h"
#endif
CHtmlFile2::CHtmlFile2()
{
#ifdef USE_OLD_HTML_CONVERTER
m_internal = new CHtmlFile2_Private();
#else
m_pReader = new HTML::CHTMLReader();
#endif
}
CHtmlFile2::~CHtmlFile2()
{
#ifdef USE_OLD_HTML_CONVERTER
RELEASEOBJECT(m_internal);
#else
RELEASEOBJECT(m_pReader);
#endif
}
#ifdef USE_OLD_HTML_CONVERTER
bool CHtmlFile2::IsHtmlFile(const std::wstring& sFile)
{
// Конвертируем в xhtml
@ -5109,47 +5044,77 @@ bool CHtmlFile2::IsMhtFile(const std::wstring& sFile)
// Читаем html
return m_internal->isHtml();
}
#endif
void CHtmlFile2::SetTmpDirectory(const std::wstring& sFolder)
void CHtmlFile2::SetTempDirectory(const std::wstring& wsFolder)
{
m_internal->m_sTmp = NSSystemPath::NormalizePath(sFolder);
#ifdef USE_OLD_HTML_CONVERTER
m_internal->m_sTmp = NSSystemPath::NormalizePath(wsFolder);
#else
m_pReader->SetTempDirectory(wsFolder);
#endif
}
void CHtmlFile2::SetCoreDirectory(const std::wstring& wsFolder)
{
#ifdef USE_OLD_HTML_CONVERTER
m_internal->m_sCore = NSSystemPath::NormalizePath(wsFolder);
#else
m_pReader->SetCoreDirectory(wsFolder);
#endif
}
HRESULT CHtmlFile2::OpenHtml(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
HRESULT CHtmlFile2::ConvertHTML2OOXML(const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
{
#ifndef USE_OLD_HTML_CONVERTER
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertHTML2OOXML(wsPath, wsDirectory, pParametrs);
#else
if(!m_internal->m_oLightReader.IsValid())
if(!IsHtmlFile(sSrc))
return S_FALSE;
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sSrc);
m_internal->m_sDst = sDst;
m_internal->CreateDocxEmpty(oParams);
m_internal->CreateDocxEmpty(pParametrs);
m_internal->readStyle();
// Переходим в начало
if(!m_internal->m_oLightReader.MoveToStart())
return S_FALSE;
if(oParams && oParams->m_bNeedPageBreakBefore)
if(pParametrs && pParametrs->m_bNeedPageBreakBefore)
m_internal->PageBreakBefore();
m_internal->readSrc();
m_internal->write();
return S_OK;
#endif
}
HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
HRESULT CHtmlFile2::ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
return S_FALSE;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertHTML2Markdown(wsPath, wsFinalFile, pParametrs);
#endif
}
HRESULT CHtmlFile2::ConvertMHT2OOXML(const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
if(!m_internal->m_oLightReader.IsValid())
if(!IsMhtFile(sSrc))
if(!IsMhtFile(wsPath))
return S_FALSE;
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sSrc);
m_internal->m_sDst = sDst;
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(wsPath);
m_internal->m_sDst = sDirectory;
m_internal->CreateDocxEmpty(oParams);
m_internal->readStyle();
@ -5162,19 +5127,38 @@ HRESULT CHtmlFile2::OpenMht(const std::wstring& sSrc, const std::wstring& sDst,
m_internal->readSrc();
m_internal->write();
return S_OK;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertMHT2OOXML(wsPath, wsDirectory, pParametrs);
#endif
}
HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const std::wstring& sDst, CHtmlParams* oParams)
HRESULT CHtmlFile2::ConvertMHT2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
{
m_internal->m_sDst = sDst;
#ifdef USE_OLD_HTML_CONVERTER
return S_FALSE;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertMHT2Markdown(wsPath, wsFinalFile, pParametrs);
#endif
}
HRESULT CHtmlFile2::ConvertHTML2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
m_internal->m_sDst = wsDirectory;
m_internal->CreateDocxEmpty(oParams);
bool bFirst = true;
for(const std::wstring& sS : sSrc)
for(const std::wstring& sS : arPaths)
{
#ifdef _DEBUG
#ifdef _DEBUG
std::wcout << NSFile::GetFileName(sS) << std::endl;
#endif
#endif
m_internal->m_sSrc = NSSystemPath::GetDirectoryName(sS);
if(!IsHtmlFile(sS))
@ -5202,8 +5186,51 @@ HRESULT CHtmlFile2::OpenBatchHtml(const std::vector<std::wstring>& sSrc, const s
m_internal->write();
return S_OK;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertHTML2OOXML(arPaths, wsDirectory, pParametrs);
#endif
}
HRESULT CHtmlFile2::ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
return S_FALSE;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertHTML2Markdown(arPaths, wsFinalFile, pParametrs);
#endif
}
HRESULT CHtmlFile2::ConvertMHT2OOXML(const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
return S_FALSE;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertMHT2OOXML(arPaths, wsDirectory, pParametrs);
#endif
}
HRESULT CHtmlFile2::ConvertMHT2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs)
{
#ifdef USE_OLD_HTML_CONVERTER
return S_FALSE;
#else
if (nullptr == m_pReader)
return S_FALSE;
return m_pReader->ConvertMHT2Markdown(arPaths, wsFinalFile, pParametrs);
#endif
}
#ifdef USE_OLD_HTML_CONVERTER
std::wstring CTableRow::ConvertToOOXML(const CTable& oTable, int nInstruction)
{
if (m_arCells.empty())
@ -5359,3 +5386,4 @@ std::wstring CTableCell::ConvertToOOXML(const CTable& oTable, UINT unColumnNumbe
return oCell.GetData();
}
#endif

View File

@ -5,6 +5,9 @@
#include <vector>
#include "../DesktopEditor/common/Types.h"
#include "HTMLParameters.h"
#include "MarkdownParameters.h"
#ifndef HTMLFILE2_USE_DYNAMIC_LIBRARY
#define HTMLFILE2_DECL_EXPORT
#else
@ -12,82 +15,43 @@
#define HTMLFILE2_DECL_EXPORT Q_DECL_EXPORT
#endif
struct CHtmlParams
{
std::wstring m_sGenres; // Жанры
std::wstring m_sAuthors; // Авторы
std::wstring m_sBookTitle; // Название
std::wstring m_sDate; // Дата
std::wstring m_sDescription; // описание
std::wstring m_sLanguage; // Язык
bool m_bNeedPageBreakBefore; // Новый html с новой страницы
std::wstring m_sdocDefaults; // Стиль docDefaults
std::wstring m_sNormal; // Стиль normal
CHtmlParams() : m_bNeedPageBreakBefore(false) {}
void SetNormal(const std::wstring& sStyle)
{
m_sNormal = sStyle;
}
void SetDocDefaults(const std::wstring& sStyle)
{
m_sdocDefaults = sStyle;
}
void SetPageBreakBefore(bool bNeed)
{
m_bNeedPageBreakBefore = bNeed;
}
void SetDate(const std::wstring& sDate)
{
m_sDate = sDate;
}
void SetDescription(const std::wstring& sDescription)
{
m_sDescription = sDescription;
}
void SetGenres(const std::wstring& sGenres)
{
m_sGenres = sGenres;
}
void SetAuthors(const std::wstring& sAuthors)
{
m_sAuthors = sAuthors;
}
void SetTitle(const std::wstring& sTitle)
{
m_sBookTitle = sTitle;
}
void SetLanguage(const std::wstring& sLanguage)
{
m_sLanguage = sLanguage;
}
};
#ifdef USE_OLD_HTML_CONVERTER
class CHtmlFile2_Private;
#else
namespace HTML { class CHTMLReader; }
#endif
class HTMLFILE2_DECL_EXPORT CHtmlFile2
{
private:
#ifdef USE_OLD_HTML_CONVERTER
CHtmlFile2_Private* m_internal;
#else
HTML::CHTMLReader* m_pReader;
#endif
public:
CHtmlFile2();
~CHtmlFile2();
bool IsHtmlFile(const std::wstring& sFile);
bool IsMhtFile (const std::wstring& sFile);
void SetTmpDirectory(const std::wstring& sFolder);
#ifdef USE_OLD_HTML_CONVERTER
bool IsHtmlFile(const std::wstring& wsFile);
bool IsMhtFile (const std::wstring& wsFile);
#endif
void SetTempDirectory(const std::wstring& wsFolder);
void SetCoreDirectory(const std::wstring& wsFolder);
HRESULT OpenHtml(const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
HRESULT OpenMht (const std::wstring& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
HRESULT OpenBatchHtml(const std::vector<std::wstring>& sPath, const std::wstring& sDirectory, CHtmlParams* oParams = NULL);
HRESULT ConvertHTML2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
HRESULT ConvertHTML2Markdown(const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
HRESULT ConvertMHT2OOXML (const std::wstring& wsPath, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
HRESULT ConvertMHT2Markdown (const std::wstring& wsPath, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
HRESULT ConvertHTML2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
HRESULT ConvertHTML2Markdown(const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
HRESULT ConvertMHT2OOXML (const std::vector<std::wstring>& arPaths, const std::wstring& wsDirectory, HTML::THTMLParameters* pParametrs = nullptr);
HRESULT ConvertMHT2Markdown (const std::vector<std::wstring>& arPaths, const std::wstring& wsFinalFile, HTML::TMarkdownParameters* pParametrs = nullptr);
};
#endif // _HTMLFILE2_HTMLFILE2_H

View File

@ -60,23 +60,23 @@ namespace NSStringFinder
return sValue;
}
std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition)
inline std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition)
{
return FindPropertyTemplate<char>(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition);
}
std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition)
inline std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition)
{
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition);
}
std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0)
inline std::string FindProperty(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0)
{
size_t unEndPosition = 0;
return FindPropertyTemplate<char>(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition);
}
std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0)
inline std::wstring FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0)
{
size_t unEndPosition = 0;
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition);
@ -130,12 +130,12 @@ namespace NSStringFinder
return oData;
}
TFoundedData<char> FindProperty(const std::string& sString, const std::string& sProperty, const std::vector<std::string>& arDelimiters, const std::vector<std::string>& arEndings, const size_t& unStarting = 0)
inline TFoundedData<char> FindProperty(const std::string& sString, const std::string& sProperty, const std::vector<std::string>& arDelimiters, const std::vector<std::string>& arEndings, const size_t& unStarting = 0)
{
return FindPropertyTemplate<char>(sString, sProperty, arDelimiters, arEndings, unStarting);
}
TFoundedData<wchar_t> FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector<std::wstring>& arDelimiters, const std::vector<std::wstring>& arEndings, const size_t& unStarting = 0)
inline TFoundedData<wchar_t> FindProperty(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector<std::wstring>& arDelimiters, const std::vector<std::wstring>& arEndings, const size_t& unStarting = 0)
{
return FindPropertyTemplate<wchar_t>(wsString, wsProperty, arDelimiters, arEndings, unStarting);
}
@ -154,12 +154,12 @@ namespace NSStringFinder
return true;
}
bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0)
inline bool RemoveEmptyTag(std::string& sValue, const std::string& sTagName, size_t unStart = 0)
{
return RemoveEmptyTagTemplate<char>(sValue, sTagName, unStart);
}
bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0)
inline bool RemoveEmptyTag(std::wstring& sValue, const std::wstring& sTagName, size_t unStart = 0)
{
return RemoveEmptyTagTemplate<wchar_t>(sValue, sTagName, unStart);
}
@ -223,7 +223,7 @@ namespace NSStringFinder
return !boost::algorithm::ifind_first(sString, sValue).empty();
}
int ToInt(const std::wstring& oValue, int nMinValue = 0)
inline int ToInt(const std::wstring& oValue, int nMinValue = 0)
{
boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))");
@ -237,7 +237,7 @@ namespace NSStringFinder
return std::max(nMinValue, nValue);
}
int ToDouble(const std::wstring& oValue, double dMinValue = 0.)
inline int ToDouble(const std::wstring& oValue, double dMinValue = 0.)
{
boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))");

View File

@ -6,6 +6,13 @@
#include "../../DesktopEditor/common/Directory.h"
#include "../../OfficeUtils/src/OfficeUtils.h"
#include "../../Common/3dParty/md/md2html.h"
#include <iostream>
#include <map>
#include <memory>
#include <string>
void getDirectories(const std::wstring& sDirectory, std::vector<std::wstring>& arrDirectory)
{
arrDirectory.push_back(sDirectory);
@ -15,6 +22,15 @@ void getDirectories(const std::wstring& sDirectory, std::vector<std::wstring>& a
int main()
{
// if (Md::ConvertMdFileToHtml(L"C:\\ONLYOFFICE\\Files\\md\\Bugs\\74626\\file-1.md",
// L"C:\\ONLYOFFICE\\Files\\md\\Bugs\\74626\\file-1.html"))
// std::wcout << L"Good" << std::endl;
// else
// std::wcout << L"Bad" << std::endl;
// return 0;
bool bBatchMode = false;
bool bMhtMode = false;
if(bBatchMode)
@ -97,7 +113,7 @@ int main()
oParams.SetDescription(L"Description");
// Файл, который открываем
std::wstring sFile = NSFile::GetProcessDirectory() + L"/test.html";
std::wstring sFile = L"C:\\ONLYOFFICE\\Files\\html\\test_tag_a_1.html";
CHtmlFile2 oFile;
oFile.SetTmpDirectory(sOutputDirectory);
nResConvert = (bMhtMode ? oFile.OpenMht(sFile, sOutputDirectory, &oParams) : oFile.OpenHtml(sFile, sOutputDirectory, &oParams));

View File

@ -339,7 +339,6 @@ namespace DocFileFormat
if ((chpxs != NULL) && (chpxFcs != NULL) && !chpxFcs->empty())//? второе
{
size_t i = 0;
bool changechpx = false;
// write a runs for each CHPX
for (size_t it = 0; it < chpxs->size(); ++it)
@ -348,15 +347,6 @@ namespace DocFileFormat
int fcChpxStart = ((chpxFcs) && (i < chpxFcs->size())) ? chpxFcs->at(i) : fc;
int fcChpxEnd = fcEnd;
if (i > 0)
{
int previous = chpxFcs->at(i-1);
if ((fcChpxStart != fc) && (previous > fcChpxStart))
{
fcChpxStart = previous;
changechpx = true;
}
}
if ((chpxFcs) && ( i < chpxFcs->size() - 1))
fcChpxEnd = chpxFcs->at(i + 1);
@ -442,13 +432,7 @@ namespace DocFileFormat
}
else
{
if (changechpx == true)
{
size_t a = it - 1;
cp = writeRun(chpxChars, chpxs->at(a), cp);
}
else
cp = writeRun(chpxChars, chpxs->at(it), cp);
cp = writeRun(chpxChars, chpxs->at(it), cp);
}
}
}

View File

@ -42,7 +42,7 @@ namespace DocFileFormat
{
ShapeConcentricFill = true;
Joins = round;
Path = L"wr-21600,,21600,43200,,,21600,21600nfewr-21600,,21600,43200,,,21600,21600l,21600nsxe";
Path = L"wr-21600,,21600,43200,,,21600,21600nfe";
Formulas.push_back( L"val #2");
Formulas.push_back( L"val #3");

View File

@ -312,7 +312,7 @@ void CFRecord::appendRawData(const char* raw_data, const size_t size)
void CFRecord::appendRawDataToStatic(const unsigned char *raw_data, const size_t size)
{
if(MAX_RECORD_SIZE - rdPtr > size)
if(MAX_RECORD_SIZE - rdPtr >= size)
{
memcpy(&intData[rdPtr], raw_data, size);
rdPtr += size;
@ -483,7 +483,7 @@ void CFRecord::resetPointerToBegin()
rdPtr = 0;
}
void CFRecord::save(NSBinPptxRW::CXlsbBinaryWriter& writer)
void CFRecord::save(NSBinPptxRW::CXlsyBinaryWriter& writer)
{
writer.XlsbStartRecord(type_id_, rdPtr);
writer.WriteBYTEArray((BYTE*)&intData[0], rdPtr);

View File

@ -90,7 +90,7 @@ public:
void resetPointerToBegin();
//save record to stream
void save(NSBinPptxRW::CXlsbBinaryWriter& writer);
void save(NSBinPptxRW::CXlsyBinaryWriter& writer);
void save(CFStreamPtr& writer);
template<class T>

View File

@ -93,7 +93,7 @@ const size_t CFStreamCacheWriter::writeToStream(const size_t num_of_records_min_
}
//---------------------------------------------------------------------------------------------------------
BinaryStreamCacheWriter::BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream, GlobalWorkbookInfoPtr global_info)
BinaryStreamCacheWriter::BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream, GlobalWorkbookInfoPtr global_info)
: StreamCacheWriter(global_info), binaryStream_(binaryStream)
{

View File

@ -71,7 +71,7 @@ protected:
class CFStreamCacheWriter : public StreamCacheWriter
{
public:
CFStreamCacheWriter(CFStreamPtr stream, const GlobalWorkbookInfoPtr global_info);
CFStreamCacheWriter(CFStreamPtr stream, const GlobalWorkbookInfoPtr global_info);
~CFStreamCacheWriter();
// Return the next new CFRecord
@ -92,13 +92,13 @@ private:
class BinaryStreamCacheWriter : public StreamCacheWriter
{
public:
BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream, const GlobalWorkbookInfoPtr global_info);
BinaryStreamCacheWriter(boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream, const GlobalWorkbookInfoPtr global_info);
~BinaryStreamCacheWriter();
const size_t GetRecordPosition()override{return 0;}
private:
const size_t writeToStream(const size_t num_of_records_min_necessary) override;
boost::shared_ptr<NSBinPptxRW::CXlsbBinaryWriter> binaryStream_;
boost::shared_ptr<NSBinPptxRW::CXlsyBinaryWriter> binaryStream_;
};
} // namespace XLS

View File

@ -66,7 +66,7 @@ public:
bool fInvertNeg = false;
IcvChart icvFore = 0x004D;
IcvChart icvBack = 0x0009;
IcvChart icvBack = 0x004D;
};
} // namespace XLS

View File

@ -372,6 +372,7 @@ void CF12::writeFields(CFRecord& record)
else if (dxfObj.m_oNumFmt->m_oFormatCode.IsInit())
{
dxf.dxfn->fIfmtUser = true;
dxf.dxfn->ifmtNinch = false;
dxf.dxfn->dxfnum.user_defined.fmt = dxfObj.m_oNumFmt->m_oFormatCode.get();
}
}

View File

@ -56,7 +56,7 @@ public:
//-----------------------------
_INT16 catCross = 0;
_INT16 catLabel = 0;
_INT16 catLabel = 1;
_INT16 catMark = 0;
bool fBetween = false;

View File

@ -174,9 +174,17 @@ void Dv::writeFields(CFRecord& record)
if (record.getGlobalWorkbookInfo()->Version < 0x0800)
{
XLUnicodeString PromptTitle_(PromptTitle);
if(PromptTitle.empty())
PromptTitle_ = std::wstring (1, L'\0');
XLUnicodeString ErrorTitle_(ErrorTitle);
if(ErrorTitle.empty())
ErrorTitle_ = std::wstring (1, L'\0');
XLUnicodeString Prompt_(Prompt);
if(Prompt.empty())
Prompt_ = std::wstring (1, L'\0');
XLUnicodeString Error_(Error);
if(Error.empty())
Error_ = std::wstring (1, L'\0');
record << PromptTitle_ << ErrorTitle_ << Prompt_ << Error_;
}

View File

@ -37,6 +37,9 @@
#include "../Biff_structures/ODRAW/OfficeArtFSPGR.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../Biff_structures/ODRAW/OfficeArtFOPT.h"
#include "../Biff_structures/ODRAW/OfficeArtClientAnchorChart.h"
#include "../Biff_structures/ODRAW/OfficeArtClientAnchorSheet.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
namespace XLS
{
@ -134,81 +137,124 @@ const bool MsoDrawing::isEndingRecord(CFRecord& record)
return ODRAW::OfficeArtDgContainer::CheckIfContainerSizeOK(record);
}
void MsoDrawing::prepareComment(const unsigned int CommentId)
void MsoDrawing::prepareDrawing(const DrawingType Type, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
const unsigned int row2, const unsigned int col2, const unsigned int param)
{
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Sheet);
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
if(rgChildRec.first)
{
auto ShapeGroup = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
auto groupFsp = new ODRAW::OfficeArtFSP;
ShapeGroup->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(groupFsp);
groupFsp->shape_id = 0;
groupFsp->fGroup = true;
groupFsp->fPatriarch = true;
groupFsp->spid = CommentId;
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = DrawingtId;
fdgPtr->spidCur = DrawingtId;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
ShapeGroup->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Sheet);
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(ShapeGroup));
{
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
groupFSPGR->xLeft = col1;
groupFSPGR->xRight = col2;
groupFSPGR->yTop = row1;
groupFSPGR->yBottom = row2;
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 0;
fsprPtr->spid = DrawingtId;
fsprPtr->fGroup = true;
fsprPtr->fPatriarch = true;
}
}
auto TextboxContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = CommentId;
fdgPtr->csp = 2;
fdgPtr->spidCur = CommentId+1;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(TextboxContainer));
auto fsprPtr = new ODRAW::OfficeArtFSP;
TextboxContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 0xCA;
fsprPtr->spid = CommentId+1;
fsprPtr->fHaveAnchor = true;
fsprPtr->fHaveSpt = true;
{
//todo add mandatory optrions writing
//auto textboxOpt = new ODRAW::OfficeArtFOPT;
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Sheet);
if(rgChildRec.first && rgChildRec.m_OfficeArtSpgrContainer != nullptr)
{
auto spgrContainer = static_cast<ODRAW::OfficeArtSpgrContainer*>(rgChildRec.m_OfficeArtSpgrContainer.get());
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
}
else
rgChildRec.m_OfficeArtSpContainer.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
if(Type == DrawingType::comment)
fsprPtr->shape_id = 0xCA;
else
fsprPtr->shape_id = 1;
fsprPtr->spid = DrawingtId+1;
fsprPtr->fHaveMaster = true;
auto clientAnchor = new ODRAW::OfficeArtClientAnchorSheet;
clientAnchor->colL = col1;
clientAnchor->colR = col2;
clientAnchor->rwT = row1;
clientAnchor->rwB = row2;
SpContainer->m_OfficeArtAnchor = ODRAW::OfficeArtRecordPtr(clientAnchor);
auto clientData = new ODRAW::OfficeArtClientData;
SpContainer->m_oOfficeArtClientData = ODRAW::OfficeArtRecordPtr(clientData);
if(Type == DrawingType::comment)
{
auto commentOptions = new ODRAW::OfficeArtFOPT;
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0080;
txId->op = DrawingtId;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x008B;
txId->op = 2;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x00BF;
txId->op = 0x00080008;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0158;
txId->op = 0x0000;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x0181;
txId->op = 0x08000050;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
{
auto txId = new ODRAW::OfficeArtFOPTE;
txId->opid = 0x03BF;
txId->op = 0x00020002;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(txId));
}
commentOptions->fopt.options_count += 6;
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
SpContainer->extraSize += 8;
}
else if(Type == DrawingType::pic)
{
auto commentOptions = new ODRAW::OfficeArtFOPT;
{
auto PicOp = new ODRAW::OfficeArtFOPTE;//pib
PicOp->opid = 0x0104;
PicOp->fComplex = false;
PicOp->fBid = true;
PicOp->op = param;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(PicOp));
}
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
commentOptions->fopt.options_count += 1;
}
}
}
void MsoDrawing::prepareChart(const unsigned int chartId, const unsigned int xPos, const unsigned int xOffset,
const unsigned int yPos, const unsigned int yOffset)
{
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = chartId;
fdgPtr->csp = 1;
fdgPtr->spidCur = chartId;
rgChildRec.m_OfficeArtFDG = ODRAW::OfficeArtRecordPtr(fdgPtr);
auto spgrContainer = new ODRAW::OfficeArtSpgrContainer(ODRAW::OfficeArtRecord::CA_Chart);
rgChildRec.m_OfficeArtSpgrContainer = ODRAW::OfficeArtRecordPtr(spgrContainer);
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Chart);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
auto groupFSPGR = new ODRAW::OfficeArtFSPGR;
groupFSPGR->xLeft = xPos;
groupFSPGR->xRight = xOffset;
groupFSPGR->yTop = yPos;
groupFSPGR->yBottom = yOffset;
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 0;
fsprPtr->spid = chartId;
fsprPtr->fGroup = true;
fsprPtr->fPatriarch = true;
}
} // namespace XLS

View File

@ -60,18 +60,22 @@ public:
virtual const bool isStartingRecord (CFRecord& record);
virtual const bool isEndingRecord (CFRecord& record);
virtual void useContinueRecords (CFRecord& record);
void prepareComment (const unsigned int CommentId);
void prepareChart (const unsigned int chartId, const unsigned int xPos, const unsigned int xOffset,
const unsigned int yPos, const unsigned int yOffset );
//-----------------------------
ODRAW::OfficeArtDgContainer rgChildRec;
bool isReading;
enum DrawingType
{
chart,
comment,
pic
};
DrawingType xlsDrawingType;
void prepareDrawing(const DrawingType DrawingType, const unsigned int DrawingtId, const unsigned int row1, const unsigned int col1,
const unsigned int row2, const unsigned int col2, const unsigned int param = 1);
};
typedef boost::shared_ptr<MsoDrawing> MsoDrawingPtr;
} // namespace XLS

View File

@ -31,6 +31,9 @@
*/
#include "MsoDrawingGroup.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../Biff_structures/ODRAW/OfficeArtFDGGBlock.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
namespace XLS
{
@ -64,5 +67,57 @@ void MsoDrawingGroup::readFields(CFRecord& record)
record >> rgChildRec;
}
void MsoDrawingGroup::writeFields(CFRecord& record)
{
rgChildRec.save(record);
}
void MsoDrawingGroup::prepareChart(unsigned int count)
{
if(!drawingCount)
return;
auto fdggblock = new ODRAW::OfficeArtFDGGBlock;
rgChildRec.m_OfficeArtFDGGBlock = ODRAW::OfficeArtRecordPtr(fdggblock);
fdggblock->cdgSaved = count;
fdggblock->cspSaved = count;
for(auto i = 0; i < count; i++)
{
ODRAW::OfficeArtIDCL idcl;
idcl.cspidCur = i;
idcl.dgid = i;
fdggblock->Rgidcl.push_back(idcl);
}
}
int MsoDrawingGroup::AddPict(const std::wstring& picPath)
{
int pictNum = -1;
ODRAW::OfficeArtBStoreContainer *bstore;
if(rgChildRec.m_OfficeArtBStoreContainer == nullptr)
{
bstore = new ODRAW::OfficeArtBStoreContainer;
rgChildRec.m_OfficeArtBStoreContainer = ODRAW::OfficeArtRecordPtr(bstore);
}
else
bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(rgChildRec.m_OfficeArtBStoreContainer.get());
if(!drawingNames.IsInit())
drawingNames.Init();
if(drawingNames->find(picPath) == drawingNames->end())
{
auto fileBlock = new ODRAW::OfficeArtBStoreContainerFileBlock;
bstore->rgfb.push_back(fileBlock);
pictNum = bstore->rgfb.size();
drawingNames->emplace(picPath, pictNum);
DWORD fileSize = 0;
auto result = NSFile::CFileBinary::ReadAllBytes(picPath, (BYTE**)&fileBlock->pict_data, fileSize);
fileBlock->pict_size = fileSize;
}
else
pictNum = drawingNames->find(picPath)->second;
return pictNum;
}
} // namespace XLS

View File

@ -33,6 +33,7 @@
#include "BiffRecordContinued.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../../../../../OOXML/Base/Nullable.h"
namespace XLS
{
@ -44,15 +45,21 @@ class MsoDrawingGroup: public BiffRecordContinued
BIFF_RECORD_DEFINE_TYPE_INFO(MsoDrawingGroup)
BASE_OBJECT_DEFINE_CLASS_NAME(MsoDrawingGroup)
public:
MsoDrawingGroup(const bool is_inside_chart_sheet);
MsoDrawingGroup(const bool is_inside_chart_sheet = false);
~MsoDrawingGroup();
BaseObjectPtr clone();
void readFields(CFRecord& record);
void writeFields(CFRecord& record);
void prepareChart(unsigned int count);
int AddPict(const std::wstring& pictPath);
ODRAW::OfficeArtDggContainer rgChildRec;
unsigned int drawingCount = 0;
nullable<std::map<std::wstring, unsigned int>> drawingNames;
};

View File

@ -56,10 +56,10 @@ public:
//-----------------------------
bool fManSerAlloc = false;
bool fManPlotArea = false;
bool fManPlotArea = true;
bool fPlotVisOnly = true;
bool fNotSizeWith = false;
bool fAlwaysAutoPlotArea = false;
bool fAlwaysAutoPlotArea = true;
unsigned char mdBlank = 0;
};

View File

@ -60,10 +60,10 @@ public:
unsigned char tktMajor = 0;
unsigned char tktMinor = 0;
unsigned char tlt = 0;
unsigned char wBkgMode = 0;
unsigned char wBkgMode = 1;
LongRGB rgb;
bool fAutoCo = false;
bool fAutoCo = true;
bool fAutoMode = false;
unsigned char rot = 0;
bool fAutoRot = false;

View File

@ -52,7 +52,7 @@ public:
virtual void load(CFRecord& record);
virtual void save(CFRecord& record);
bool fAutoPict = false;
bool fAutoPict = true;
bool fDde = false;
bool fPrintCalc = false;
bool fIcon = false;

View File

@ -80,6 +80,23 @@ void OfficeArtBStoreContainer::loadFields(XLS::CFRecord& record)
}
}
void OfficeArtBStoreContainer::save(XLS::CFRecord& record)
{
rh_own.recVer = 0xF;
rh_own.recInstance = rgfb.size();
rh_own.recType = 0xF001;
for(auto i : rgfb)
{
rh_own.recLen += 44; //OfficeArtFBSE
if(!i->nameData.empty())
rh_own.recLen += i->nameData.size()+1;
rh_own.recLen += 25; //blipHeader
rh_own.recLen += i->pict_size;
}
record << rh_own;
}
const unsigned short OfficeArtBStoreContainer::GetInstanceToStore()
{
return rgfb.size();

View File

@ -61,6 +61,7 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainer;
virtual void loadFields(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
// overriden
const unsigned short GetInstanceToStore();

View File

@ -269,4 +269,71 @@ void OfficeArtBStoreContainerFileBlock::load(XLS::CFRecord& record)
}
const void WriteMD4Digest(std::wstring UidStr, XLS::CFRecord& record)
{
if(UidStr.size() < 16 )
UidStr = L"0000000000000000";
for(int i = 0; i < 16; i++)
{
unsigned char hex_data = UidStr.at(i);
record << hex_data;
}
}
void OfficeArtBStoreContainerFileBlock::save(XLS::CFRecord& record)
{
//fbse
{
OfficeArtRecordHeader FbseHeader;
FbseHeader.recVer = 2;
FbseHeader.recInstance = 5;
FbseHeader.recType = 0xF007;
FbseHeader.recLen = pict_size + 36 + 25;
if(!nameData.empty())
FbseHeader.recLen += nameData.size()+1;
record << FbseHeader;
BYTE btOs = FbseHeader.recInstance;
record << btOs << btOs;
WriteMD4Digest(rgbUid1, record);
unsigned short tag = 0xFF;
record << tag;
unsigned int Size = pict_size + 17 + 8;
record << Size;
unsigned int Cref = 1;
record << Cref;
unsigned int foDelay = 0;
record << foDelay;
record.reserveNunBytes(1);
BYTE cbName = 0;
if(!nameData.empty())
cbName = nameData.size()+1;
record << cbName;
record.reserveNunBytes(2);
if(cbName)
{
for(auto i : nameData)
{
record << i;
}
BYTE terminal = L'\0';
record << terminal;
}
}
OfficeArtRecordHeader rc_header;
rc_header.recVer = 0;
rc_header.recInstance = 0x46A;
rc_header.recType = 0xF01D;
rc_header.recLen = pict_size + 17;
record << rc_header;
record.reserveNunBytes(16);
BYTE tag = 0xFF;
record << tag;
//record.appendRawDataToStatic((BYTE*)pict_data, pict_size);
}
} // namespace XLS

View File

@ -71,6 +71,7 @@ public:
}
virtual void load(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainerFileBlock;
@ -86,6 +87,7 @@ public:
size_t recType;
std::wstring rgbUid1;
std::wstring rgbUid2;
std::wstring nameData;
bool result;
const std::wstring ReadMD4Digest(XLS::CFRecord& record)

View File

@ -56,5 +56,17 @@ void OfficeArtClientAnchorChart::loadFields(XLS::CFRecord& record)
}
void OfficeArtClientAnchorChart::save(XLS::CFRecord& record)
{
rh_own.recVer = 0;
rh_own.recType = 0xF010;
rh_own.recLen = 0x00000012;
record << rh_own;
unsigned short flags = 3;
record << flags << lx1 << ly1 << lx2 << ly2;
}
} // namespace XLS

View File

@ -52,14 +52,15 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtClientAnchorChart;
virtual void loadFields(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
// bool fMove; // This attribute is ignored for chart sheets
bool fSize;
int lx1;
int ly1;
int lx2;
int ly2;
int lx1 = 0;
int ly1 = 0;
int lx2 = 0;
int ly2 = 0;
};
typedef boost::shared_ptr<OfficeArtClientAnchorChart> OfficeArtClientAnchorChartPtr;

View File

@ -70,6 +70,18 @@ void OfficeArtClientAnchorSheet::loadFields(XLS::CFRecord& record)
record >> colL >> dxL >> rwT >> dyT >> colR >> dxR >> rwB >> dyB;
}
void OfficeArtClientAnchorSheet::save(XLS::CFRecord& record)
{
rh_own.recVer = 0;
rh_own.recType = 0xF010;
rh_own.recLen = 0x00000012;
record << rh_own;
unsigned short flags = 0;
SETBIT(flags, 0, fMove)
SETBIT(flags, 1, fSize)
record << flags << colL << dxL << rwT << dyT << colR << dxR << rwB << dyB;
}
void OfficeArtClientAnchorSheet::calculate()
{
global_info->GetDigitFontSizePixels();

View File

@ -53,18 +53,19 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtClientAnchorSheet;
virtual void loadFields(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
bool fMove;
bool fSize;
bool fMove = true;
bool fSize = true;
XLS::Col256U colL;
short dxL;
XLS::RwU rwT;
short dyT;
XLS::Col256U colR;
short dxR;
XLS::RwU rwB;
short dyB;
XLS::Col256U colL = 0;
short dxL = 0;
XLS::RwU rwT = 0;
short dyT = 0;
XLS::Col256U colR = 0;
short dxR = 0;
XLS::RwU rwB = 0;
short dyB = 0;
//-----------------------------------------------------------------------------
XLS::GlobalWorkbookInfoPtr global_info;

View File

@ -31,6 +31,7 @@
*/
#include "OfficeArtDgContainer.h"
#include "SimpleOfficeArtContainers.h"
namespace ODRAW
{
@ -147,29 +148,39 @@ void OfficeArtDgContainer::loadFields(XLS::CFRecord& record)
void OfficeArtDgContainer::save(XLS::CFRecord& record)
{
rh_own.recVer = 0xF;
rh_own.recInstance = 0;
rh_own.recType = 0xF002;
record << rh_own;
auto sizePos = record.getRdPtr();
if(m_OfficeArtFDG != nullptr)
m_OfficeArtFDG->save(record);
if(m_OfficeArtFRITContainer != nullptr)
m_OfficeArtFRITContainer->save(record);
if(m_OfficeArtSpgrContainer != nullptr)
m_OfficeArtSpgrContainer->save(record);
auto sizePos = 0;
if(first)
{
rh_own.recVer = 0xF;
rh_own.recInstance = 0;
rh_own.recType = 0xF002;
record << rh_own;
sizePos = record.getRdPtr();
if(m_OfficeArtFDG != nullptr)
m_OfficeArtFDG->save(record);
if(m_OfficeArtFRITContainer != nullptr)
m_OfficeArtFRITContainer->save(record);
if(m_OfficeArtSpgrContainer != nullptr)
{
auto castedContainer = static_cast<OfficeArtSpgrContainer*>(m_OfficeArtSpgrContainer.get());
castedContainer->rh_own.recLen += totalSize;
m_OfficeArtSpgrContainer->save(record);
}
}
for(auto i : m_OfficeArtSpContainer)
if(i != nullptr)
i->save(record);
if(m_OfficeArtSpgrContainerFileBlock != nullptr)
m_OfficeArtSpgrContainerFileBlock->save(record);
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
auto recLen = rh_own.recLen;
record << recLen;
record.skipNunBytes(rh_own.recLen);
if(first)
{
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
auto recLen = rh_own.recLen + totalSize;
record << recLen;
record.skipNunBytes(rh_own.recLen);
}
}
} // namespace ODRAW

View File

@ -62,6 +62,8 @@ public:
OfficeArtRecordPtr m_OfficeArtSpgrContainer;
std::vector<OfficeArtRecordPtr> m_OfficeArtSpContainer;
OfficeArtRecordPtr m_OfficeArtSpgrContainerFileBlock;
bool first = true;
unsigned int totalSize = 0;
};
typedef boost::shared_ptr<OfficeArtDgContainer> OfficeArtDgContainerPtr;

View File

@ -61,4 +61,17 @@ void OfficeArtFDGGBlock::loadFields(XLS::CFRecord& record)
}
}
void OfficeArtFDGGBlock::save(XLS::CFRecord& record)
{
rh_own.recVer = 0;
rh_own.recInstance = 0;
rh_own.recType = 0xF006;
rh_own.recLen = 0x10 + Rgidcl.size()*8;
record << rh_own;
_UINT32 cidcl = Rgidcl.size()+1;
record << spidMax << cidcl << cspSaved << cdgSaved;
for(auto i : Rgidcl)
i.save(record);
}
} // namespace XLS

View File

@ -53,10 +53,11 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtFDGGBlock;
virtual void loadFields(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
_UINT32 spidMax;
_UINT32 cspSaved;
_UINT32 cdgSaved;
_UINT32 spidMax = 0x02FFD7FF;
_UINT32 cspSaved = 1;
_UINT32 cdgSaved = 0;
std::vector<OfficeArtIDCL> Rgidcl;
};

View File

@ -76,10 +76,10 @@ public:
virtual void ReadComplexData(XLS::CFRecord& record);
virtual void ReadComplexData(IBinaryReader* reader);
unsigned short opid;
bool fBid;
bool fComplex;
_INT32 op;
unsigned short opid = 0;
bool fBid = false;
bool fComplex = false;
_INT32 op = 0;
};
class FillColor : public OfficeArtFOPTE
@ -1068,50 +1068,47 @@ public:
{
case ODRAW::rtLineTo:
{
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; ++j)
{
if (valuePointer + 1 > m_arPoints.size())
{
break;
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; j++)
{
if (valuePointer + 1 > m_arPoints.size())
{
break;
strVmlPath += L"l";
strVmlPath += std::to_wstring(m_arPoints[0].x);
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[0].y);
strVmlPath += L"l";
strVmlPath += std::to_wstring(m_arPoints[0].x);
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[0].y);
++valuePointer;
}
else
{
strVmlPath += L"l";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
++valuePointer;
}
else
{
strVmlPath += L"l";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
++valuePointer;
}
}
++valuePointer;
}
}
}break;
case ODRAW::rtCurveTo:
{
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; ++j)
{
if (valuePointer + 3 > m_arPoints.size())
break;
strVmlPath += L"c";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].y );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].y );
valuePointer += 3;
}
if (valuePointer + 3 > m_arPoints.size())
break;
strVmlPath += L"c";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer].y );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 1].y );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].x );
strVmlPath += L",";
strVmlPath += std::to_wstring(m_arPoints[valuePointer + 2].y );
valuePointer += 3;
}break;
case ODRAW::rtMoveTo:
{
@ -1126,6 +1123,16 @@ public:
}
}
break;
case ODRAW::rtNoFill:
{
strVmlPath += L"nf";
}
break;
case ODRAW::rtNoStroke:
{
strVmlPath += L"ns";
}
break;
case ODRAW::rtClose:
{
strVmlPath += L"x";

View File

@ -46,5 +46,10 @@ void OfficeArtIDCL::load(XLS::CFRecord& record)
record >> dgid >> cspidCur;
}
void OfficeArtIDCL::save(XLS::CFRecord& record)
{
record << dgid << cspidCur;
}
} // namespace XLS

View File

@ -50,10 +50,11 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtIDCL;
virtual void load(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
_UINT32 dgid;
_UINT32 cspidCur;
_UINT32 dgid = 0;
_UINT32 cspidCur = 0;
};
typedef boost::shared_ptr<OfficeArtIDCL> OfficeArtIDCLPtr;

View File

@ -69,7 +69,7 @@ public:
std::vector<OfficeArtFOPTEPtr> Transform_props;
std::vector<OfficeArtFOPTEPtr> Other_props;
unsigned short options_count;
unsigned short options_count = 0;
};
typedef boost::shared_ptr<OfficeArtRGFOPTE> OfficeArtRGFOPTEPtr;

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