Compare commits

...

272 Commits

Author SHA1 Message Date
acdc1e3962 fix bug #67861 2026-05-26 21:52:09 +03:00
156b912945 Fix build 2026-05-26 20:48:21 +03:00
38d3a703a2 Merge pull request 'Add interface for tables' (#768) from feature/docxrenderer-tables-connect into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/768
2026-05-26 16:04:46 +00:00
24bc36e66d fix bug #49658 2026-05-26 18:54:04 +03:00
049af6d91b Add license 2026-05-26 18:33:13 +03:00
47ccef0855 Fix typo 2026-05-26 18:30:42 +03:00
c45aa7a68d Add utils for tables 2026-05-26 16:56:36 +03:00
6b04a4ebd1 Fix pwd root 2026-05-26 16:55:57 +03:00
721431c676 Replace pro to pri file 2026-05-26 15:33:15 +03:00
83088fcef2 Add Table.cpp file 2026-05-26 14:26:17 +03:00
2de90e32c3 Add interface for tables 2026-05-26 13:59:35 +03:00
cb3daf1b6a for bug #38234 2026-05-26 12:46:12 +03:00
29bb590151 Merge remote-tracking branch 'origin/feature/pdf-redact' into develop 2026-05-25 17:45:08 +03:00
7fe4efbb54 Fix build x2t example for mac 2026-05-25 13:29:12 +03:00
f7e17d0080 Fix previous commit 2026-05-25 10:16:28 +03:00
ea7f362d99 Update header.license for wasm 2026-05-21 16:21:05 +03:00
de49ae5f32 Fix gid=code when font substitution 2026-05-21 14:09:32 +03:00
b607249544 fix bug #77975 2026-05-20 19:05:31 +03:00
bd62388d81 Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-05-19 19:00:06 +03:00
c0cad5429e Addons for previous commit 2026-05-19 17:54:52 +03:00
e353ff1b96 Fix EncodeXmlString method 2026-05-19 17:48:55 +03:00
5f6075ca33 Merge branch 'release/v9.4.0' into develop 2026-05-19 16:46:09 +03:00
40bd21caac fix table fmla conversion 2026-05-19 17:51:09 +06:00
f1ab3e4bf7 fix complex shared strings conversion to xls 2026-05-19 16:18:03 +06:00
55e5f973b0 Fix UTF-8 BOM position 2026-05-19 09:37:04 +03:00
78ed5b3d74 . 2026-05-18 17:59:14 +03:00
ba0e0f7449 Merge branch 'develop' of https://git.onlyoffice.com/ONLYOFFICE/core into develop 2026-05-18 16:31:05 +03:00
ba992cc401 . 2026-05-18 16:30:25 +03:00
fba14fcf7b Merge pull request 'fix bug #74293' (#763) from fix/bug74293 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/763
2026-05-18 12:25:26 +00:00
aa43506bf9 fix inline value cells compression 2026-05-18 18:04:58 +06:00
544b0c54bc Merge branch 'develop' into feature/add-xls-writing 2026-05-18 13:17:25 +06:00
a2c24b8dc0 Merge pull request 'Fix bug 77975' (#764) from fix/forbug77975 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/764
2026-05-18 07:13:43 +00:00
073f100fe0 Fix prev 2026-05-18 10:11:07 +03:00
e30a6acc87 Fix bug 77975 2026-05-17 23:00:22 +03:00
4a15aaab0d add table id check 2026-05-15 21:04:56 +06:00
30f21fc3c7 Fix prev commit 2026-05-15 17:11:44 +03:00
b2c2a0ec6c Fix build wasm 2026-05-15 14:50:00 +03:00
77ef943473 Refactoring PdfFile 2026-05-15 13:53:02 +03:00
5d862891ca fix styles conversion 2026-05-14 18:11:51 +06:00
be921d6be7 fix bug #81371 2026-05-14 12:28:56 +03:00
6a7aedaeb2 fix xls fmla refs 2026-05-14 15:24:47 +06:00
67733c1733 fix bug #74293 2026-05-14 11:30:40 +03:00
812c59beaa Fix bug 81426 2026-05-13 14:31:41 +03:00
97900e0c6e Merge branch 'develop' into feature/add-xls-writing 2026-05-13 13:23:16 +06:00
ac06652662 add attached llbls conversion for chart series 2026-05-12 19:46:42 +06:00
c5b798b8a9 Merge pull request 'Update OFD file interface' (#759) from fix/OFD into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/759
2026-05-08 13:01:58 +00:00
175028396e add dataPoint conversion 2026-05-08 16:31:46 +06:00
35ba9d7445 add numdataVal to baseSer 2026-05-08 15:53:49 +06:00
67d31207e5 add baseSer conversion 2026-05-08 15:15:02 +06:00
75e095abb9 add ext spPr conversion 2026-05-07 21:06:39 +06:00
6a6c85b6bd Added getting the links in OFD file 2026-05-07 16:59:38 +03:00
d8133b7cb2 add image offset conversion 2026-05-07 17:57:03 +06:00
0e40482b9f . 2026-05-07 11:06:24 +03:00
742dfb54b8 fix bug #66296 2026-05-07 10:51:27 +03:00
52b21fbaed Added getting the structure in OFD file 2026-05-07 01:56:10 +03:00
aef42511ad . 2026-05-06 16:47:43 +03:00
692eb8c878 . 2026-05-06 16:39:19 +03:00
11c9900a5e add one cell anchor image conversion 2026-05-06 18:26:06 +06:00
7f16ac66f0 Merge remote-tracking branch 'origin/fix/bug81411' into develop 2026-05-06 13:12:56 +03:00
a94d46ee06 fix bug #81411 2026-05-06 13:12:17 +03:00
2dd929dc95 Merge pull request 'fix/FillingSM' (#673) from fix/FillingSM into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/673
2026-05-05 15:30:46 +00:00
1cfce0fe84 Merge pull request 'fix bug #81408' (#757) from fix/bug81408 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/757
2026-05-05 15:26:55 +00:00
1fc363c189 fix bug #81408 2026-05-05 21:16:16 +06:00
3a0c438b9c Merge branch 'fix/fix-build-html2' into develop 2026-05-04 19:25:39 +03:00
a5f4e04550 add bdr colors to condFmt 2026-05-04 17:29:44 +06:00
e0141264a7 Merge branch 'develop' into feature/add-xls-writing 2026-05-04 13:21:12 +06:00
f2bf914e72 Fix build 2026-05-03 16:55:48 +03:00
62a25fa847 Refactoring HTML tags 2026-05-03 04:18:39 +03:00
bc9e8637ef add theme conversion 2026-04-30 19:09:08 +06:00
7ac9645010 Merge remote-tracking branch 'origin/fix/fix-bugs' into develop 2026-04-30 15:08:09 +03:00
4250382f87 fix bug #81350 2026-04-30 15:04:12 +03:00
4eca22efde . 2026-04-30 14:45:11 +03:00
f531e480ff fix tint colors conversion 2026-04-30 16:48:00 +06:00
9db2d2f328 for bug #53378 2026-04-30 13:01:23 +03:00
a868451b5d . 2026-04-30 10:48:14 +03:00
cb217be2a2 . 2026-04-30 10:38:36 +03:00
6ccf19e036 Merge remote-tracking branch 'origin/release/v9.4.0' into develop 2026-04-30 10:07:24 +03:00
2582927c72 Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-04-30 10:04:54 +03:00
3fe3382c1e Merge remote-tracking branch 'origin/feature/odf-drawingfile' into develop 2026-04-29 17:10:04 +03:00
b139dec538 Fix bug 2026-04-29 16:22:47 +03:00
0b12c5b521 Added some fields to GetInfo in OFD 2026-04-29 14:40:37 +03:00
4c0c47a3cf Added font selection by glyph in ofd in the WASM module 2026-04-29 14:39:58 +03:00
234f867837 Fix LoadFont 2026-04-29 11:57:06 +03:00
6366306f9c Add gradient fill conversion 2026-04-29 13:26:46 +06:00
75f97349ca Fix build 2026-04-28 23:46:45 +03:00
9ef4de7010 Fix build 2026-04-28 22:54:51 +03:00
5bf72dcfb6 Added retrieval of information about the OFD file 2026-04-28 17:29:59 +03:00
f6decd4754 add border clr ext conversion 2026-04-28 17:23:21 +06:00
f4a0f3f01a add font clr ext conversion 2026-04-28 15:28:17 +06:00
50816132e9 Fix rgb ext color conversion 2026-04-28 14:38:28 +06:00
8e596451a9 Work with fonts in OFD for the WASM module has been updated 2026-04-27 19:38:31 +03:00
8364bc02a6 Fix xlx version in bof 2026-04-27 22:11:24 +06:00
815b6623a3 Merge pull request 'fix bug #81244' (#753) from fix/bug81244 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/753
2026-04-27 08:58:08 +00:00
051f1d2c94 Merge pull request 'fix bug #80899' (#737) from fix/bug80899 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/737
2026-04-27 08:57:59 +00:00
c2000257aa fix bug #81244 2026-04-27 14:50:04 +06:00
c5b2f3d1f2 fix flipH 2026-04-27 07:01:09 +03:00
72f7aaa6c2 Improved font handling in OFD in the WASM module 2026-04-24 19:22:00 +03:00
13b19cc13f Fix build 2026-04-24 15:56:49 +03:00
9720bd18a4 TODO 2026-04-24 13:37:50 +03:00
a46e0d0a67 Test ofd 2026-04-24 13:31:35 +03:00
9ddd969b01 fix size shape 2026-04-22 22:32:36 +03:00
828eee5ed5 Added memory reading for ofd 2026-04-22 20:44:45 +03:00
a95d8712d3 Create IOfficeDrawingFilePainter 2026-04-22 13:51:34 +03:00
3f76fca0f7 Merge pull request 'Fix html conversion' (#746) from fix/markdown into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/746
2026-04-22 07:07:01 +00:00
1c9ce65ba9 fix bug #75103 2026-04-22 09:12:47 +03:00
09b1d56a9a Merge remote-tracking branch 'origin/release/v9.4.0' into develop 2026-04-22 08:50:01 +03:00
bc59e34153 Fix OFD detected 2026-04-21 14:28:07 +03:00
9679c6e7f8 OFD detected 2026-04-21 14:18:32 +03:00
2ffc0a7844 drawingfile build OFDFile 2026-04-21 13:29:18 +03:00
c7e7fd4aa1 Dependency on boost has been removed 2026-04-21 11:29:45 +03:00
1846056b74 Fix bug 81029 2026-04-20 14:38:20 +03:00
378841d655 Fix bug 80025 2026-04-20 11:47:09 +03:00
facd131d7b fix rotate 2026-04-17 13:43:56 +03:00
f39716a5da fix bug #80887 2026-04-17 13:39:12 +03:00
d1fada2542 Refactoring 2026-04-16 17:21:11 +03:00
16929b3a54 Merge branch 'develop' into fix/markdown 2026-04-16 17:15:01 +03:00
a2f52951b2 Fix build 2026-04-16 16:29:06 +03:00
f3d34b1363 . 2026-04-15 22:27:35 +03:00
07e563afe8 fix bug #81054 2026-04-15 22:12:12 +03:00
75b3665ad5 Fix bugs in html to OOXML/Markdown conversion 2026-04-15 21:14:30 +03:00
bdbad87830 Merge remote-tracking branch 'origin/feature/add-xls-writing' into develop 2026-04-15 18:07:31 +03:00
290e4a0884 Fix AP removal for modified annotations on split-merge 2026-04-15 10:50:34 +03:00
0242c5885b Merge pull request 'add horizontal rule' (#736) from fix/doc into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/736
2026-04-14 19:25:15 +00:00
1c13c80197 Fix AP removal for modified annotations on split-merge 2026-04-14 11:25:41 +03:00
ddd991601c Fix bug 57854 2026-04-13 12:23:34 +03:00
8d2331b097 Write RedactAnnot with changes 2026-04-10 16:39:47 +03:00
57c26eb998 Add default theme writing 2026-04-10 19:37:16 +06:00
2c35b5f422 Fix bugs in html conversion 2026-04-09 16:46:37 +03:00
61fca43920 Merge remote-tracking branch 'origin/develop' into feature/pdf-redact
# Conflicts:
#	DesktopEditor/graphics/IRenderer.h
#	PdfFile/PdfEditor.cpp
#	PdfFile/PdfFile.h
#	PdfFile/SrcWriter/Pages.cpp
2026-04-09 15:45:59 +03:00
2cceef7386 Write RedactAnnot without changes 2026-04-09 15:37:47 +03:00
ab76f46fd4 add extProps conversion 2026-04-09 16:41:28 +06:00
2dd2f3bcc6 fix xfext frt 2026-04-09 16:19:29 +06:00
5f005b4501 for bug #53378 2026-04-08 13:29:34 +03:00
0830ed031e Merge branch 'develop' into feature/add-xls-writing 2026-04-08 13:16:56 +06:00
e63d62bb04 Merge pull request 'fix conversion to xls' (#739) from fix/xls-conversion into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/739
2026-04-08 07:13:31 +00:00
90029fb2f3 fix conversion to xls 2026-04-08 13:04:57 +06:00
37f8c52e43 Create ctRedactAnnot 2026-04-07 16:42:14 +03:00
d4e1b31e10 Merge branch 'release/v9.4.0' into develop 2026-04-07 15:11:10 +03:00
1580494bdb fix bug #80899 2026-04-07 16:30:32 +06:00
f4fc487ce3 Fix bugs and refactoring in html cenversion 2026-04-06 21:47:03 +03:00
a5bfa94770 Fix bugs in HTML to OOXML conversion 2026-04-06 19:41:29 +03:00
85a615cc9a add xfs Crc writing 2026-04-06 21:33:04 +06:00
91701ed58d add horizontal rule 2026-04-06 13:49:45 +03:00
279349323f Merge remote-tracking branch 'origin/fix/bug-65751' into develop 2026-04-06 10:52:40 +03:00
1dae175272 Fix bug 65751 2026-04-06 10:51:27 +03:00
7c6f9f2ad6 edit the flipV 2026-04-04 09:29:15 +03:00
efc9bab6ed for bug #53378 2026-04-04 09:26:06 +03:00
73b32984e2 fix ptgList toArea conversion 2026-04-03 21:47:41 +06:00
f269db67bb Read Type3 font 2026-04-03 16:54:05 +03:00
685b2bb9e0 Merge pull request 'Fix bug 77975' (#735) from fix/bug77975 into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/735
2026-04-03 12:18:02 +00:00
55fe2e968f Fix bug 77975 2026-04-03 14:56:34 +03:00
d90c3aa3ac Add row fields check 2026-04-03 15:44:01 +06:00
e3e247e835 fix date fields in pivot cache 2026-04-02 21:50:37 +06:00
87c3f9beff fix pivot row items conversion 2026-04-02 16:34:07 +06:00
9b196ada1f Fix bug 68657 2026-04-02 10:04:28 +03:00
cd58508d0f Fix pivot cache conversion 2026-04-01 21:00:31 +06:00
d41aef7ec6 Fix bug 68459 2026-04-01 11:20:35 +03:00
bdc22190bd fix pivot cache ref conversion 2026-03-31 18:14:27 +06:00
9989510d60 add shared item index conversion 2026-03-31 16:59:21 +06:00
2f1a76fba6 Improved work with images in the html converter 2026-03-30 20:41:14 +03:00
0693bdc115 add pivot items conversion 2026-03-30 18:38:20 +06:00
ffb528636f Fix bug 80784 2026-03-30 14:52:50 +03:00
abc4619924 add pivot cache file check 2026-03-30 15:48:05 +06:00
fe36b3e1e6 add inlineStr cell value conversion 2026-03-27 20:47:01 +06:00
e72a4f8e8c add picture file check 2026-03-27 19:50:06 +06:00
0b2babbefc for bug #53378 2026-03-27 12:28:44 +03:00
32da1a4901 Refactoring 2026-03-27 01:53:35 +03:00
15f423dbb9 Merge pull request 'add horizontal rule' (#732) from fix/bugrtf into develop
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/732
2026-03-26 14:19:15 +00:00
b5c29e49e2 Add emf image conversion 2026-03-26 17:14:09 +06: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
261cf72685 fix surface chart conversion 2026-03-24 21:23:12 +06:00
219bf06855 add seriesAxis conversion 2026-03-24 18:29:29 +06: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
1f9ee8628e Merge branch 'develop' into fix/FillingSM 2026-03-23 11:47:07 +03:00
84aa409b1e Merge branch 'develop' into feature/add-xls-writing 2026-03-23 13:06:49 +06:00
6df60b9b4e Redesigned the principle of working with tables in html 2026-03-23 03:14:08 +03:00
52096d1b0b add horizontal rule 2026-03-20 21:10:37 +03: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
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
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
4cdc416e0b fix bug #79301 2026-03-12 12:34:51 +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
278dffc7c7 fix bug #80491 2026-03-11 18:11:16 +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
e83dbf57af Fixed a bug with unnecessary transfer of images to markdown 2026-03-10 18:52:19 +03:00
3aa729d65b Fixed a bug with formatted spaces in markdown 2026-03-10 18:51:44 +03:00
3bb03cb735 Fix Metadata RedactInfo 2026-03-10 18:02:05 +03:00
cb0176ecca add comment writing 2026-03-10 21:00:46 +06: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
c2dd7b5108 fix bug #68331 2026-03-09 19:06:21 +03:00
c057c8eb24 Create RedacctInfo 2026-03-06 14:08:36 +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
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
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
eca98f612c Merge branch release/v9.3.0 into develop 2026-03-04 09:17:01 +00: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
8a8e17562b fix defined names conversion 2026-03-02 19:17:40 +06:00
9f36c04d33 fix title pos 2026-03-02 15:56:10 +06: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
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
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
3b2721e2da fix/bug79307
fix bug #79307
2026-02-26 15:15:23 +03:00
19c66750a8 fix/bug79307
fix bug #79307
2026-02-25 23:09:05 +03:00
4b61f6e62a Merge branch 'release/v9.4.0' into feature/add-xls-writing 2026-02-25 22:36:59 +06: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
644ec4e651 fix separate chart conversion 2026-02-24 14:05:03 +06:00
6ca34d9c69 fix several charts conversion 2026-02-20 19:20:59 +06:00
473f6aef1e add several chart conversion 2026-02-19 16:58:22 +06:00
85027065e6 Add drawing group conversion 2026-02-17 15:01:53 +06:00
f66c646c2c add drawingGroup writing 2026-02-16 19:00:09 +06:00
a40e246d7d fix bug 2025-10-10 13:52:46 +03:00
66d36b64b0 for bug #68408 2025-10-04 19:52:32 +03:00
954f3c91bb Merge pull request 'release/v9.1.0' (#468) from release/v9.1.0 into fix/FillingSM
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/468
2025-10-02 12:39:53 +00:00
18d36179bd add hash annotation 2025-08-12 10:27:21 +03:00
442 changed files with 12748 additions and 6918 deletions

View File

@ -525,6 +525,7 @@ namespace NSCSS
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"}});
m_mDefaultStyleData[L"th"] = new CElement(L"b", {{L"font-weight", L"bold"}});
}
CCssCalculator_Private::CCssCalculator_Private()

View File

@ -118,6 +118,11 @@ namespace NSCSS
return *this;
}
bool LessSignificantThen(const CValueBase& oValue) const
{
return oValue.m_unLevel >= m_unLevel && (!m_bImportant || oValue.m_bImportant) && !oValue.Empty();
}
};
template<typename T>

View File

@ -1,6 +1,5 @@
#include "CDocumentStyle.h"
#include <iostream>
#include <unordered_set>
#include <wchar.h>
#include <math.h>

View File

@ -1,32 +1,35 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
* Copyright (C) Ascensio System SIA, 2009-2026
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
* version 3 as published by the Free Software Foundation, together with the
* additional terms provided in the LICENSE file.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
* You can contact Ascensio System SIA by email at info@onlyoffice.com
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
* LV-1050, Latvia, European Union.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* The interactive user interfaces in modified versions of the Program
* are required to display Appropriate Legal Notices in accordance with
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
* No trademark rights are granted under this License.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
* All non-code elements of the Product, including illustrations,
* icon sets, and technical writing content, are licensed under the
* Creative Commons Attribution-ShareAlike 4.0 International License:
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
*
* This license applies only to such non-code elements and does not
* modify or replace the licensing terms applicable to the Program's
* source code, which remains licensed under the GNU Affero General
* Public License v3.
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

View File

@ -48,7 +48,7 @@ TARGET = allthemesgen
DEFINES += KERNEL_USE_DYNAMIC_LIBRARY
DEFINES += GRAPHICS_USE_DYNAMIC_LIBRARY
ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, DocxRenderer)
ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, OFDFile, DocxRenderer)
core_windows {
DEFINES -= UNICODE

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

@ -58,7 +58,7 @@ core_windows {
DESTDIR = $$CORE_BUILDS_BINARY_PATH
################################################
ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, DocxRenderer)
ADD_DEPENDENCY(graphics, kernel, kernel_network, UnicodeConverter, doctrenderer, PdfFile, XpsFile, DjVuFile, OFDFile, DocxRenderer)
core_linux {
LIBS += -ldl

View File

@ -149,7 +149,7 @@ DEFINES += BUIDLER_OPEN_BASE64_ENABLED
CONFIG += drawingfile_support
drawingfile_support {
DEFINES += WASM_SERIALIZER_USE_ALLOCATOR
ADD_DEPENDENCY(PdfFile, XpsFile, DjVuFile, DocxRenderer)
ADD_DEPENDENCY(PdfFile, XpsFile, DjVuFile, OFDFile, DocxRenderer)
HEADERS += \
$$PWD_CUR/drawingfile.h \

View File

@ -44,6 +44,8 @@
#include "../graphics/pro/js/wasm/src/serialize.h"
#include "../graphics/pro/js/wasm/src/HTMLRendererText.h"
#include "../../DocxRenderer/DocxRenderer.h"
#include "../../OFDFile/OFDFile.h"
#include "../../OfficeUtils/src/OfficeUtils.h"
#define CHECKER_FILE_BUFFER_LEN 4096
@ -106,6 +108,9 @@ public:
case odftXPS:
m_nType = 2;
break;
case odftOFD:
m_nType = 3;
break;
default:
break;
}
@ -168,6 +173,16 @@ public:
else
m_nType = 2;
}
case 3:
{
m_pFile = new COFDFile(m_pApplicationFonts);
if (!m_pFile->LoadFromFile(sFile, L"", sPassword, sPassword))
{
RELEASEOBJECT(m_pFile);
}
else
m_nType = 3;
}
default:
break;
}
@ -218,6 +233,16 @@ public:
else
m_nType = 2;
}
case 3:
{
m_pFile = new COFDFile(m_pApplicationFonts);
if (!m_pFile->LoadFromMemory(data, size, L"", sPassword, sPassword))
{
RELEASEOBJECT(m_pFile);
}
else
m_nType = 3;
}
default:
break;
}
@ -291,6 +316,11 @@ public:
return bRes;
}
void SetPainter(IOfficeDrawingFilePainter* pPainter)
{
if (m_pFile)
m_pFile->SetPainter(pPainter);
}
BYTE* GetPixmap(int nPageIndex, int nRasterW, int nRasterH, int nBackgroundColor)
{
if (!m_pFile)
@ -637,7 +667,7 @@ private:
double dPageDpiX, dPageDpiY;
double dWidth, dHeight;
m_pFile->GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);
if (m_nType == 2)
if (m_nType == 2 || m_nType == 3)
{
dWidth = dWidth / 25.4 * 96.0;
dHeight = dHeight / 25.4 * 96.0;
@ -675,6 +705,7 @@ private:
// 0 - PDF
// 1 - DJVU
// 2 - XPS
// 3 - OFD
LONG nSize = size < CHECKER_FILE_BUFFER_LEN ? size : CHECKER_FILE_BUFFER_LEN;
char* pData = (char*)data;
for (int i = 0; i < nSize - 5; ++i)
@ -686,6 +717,25 @@ private:
if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] &&
0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7]))
return 1;
COfficeUtils OfficeUtils(NULL);
if (OfficeUtils.IsArchive(data, size) == S_FALSE)
return -1;
ULONG nBufferSize = 0;
BYTE *pBuffer = NULL;
int nFileType = -1;
HRESULT hresult = OfficeUtils.LoadFileFromArchive(data, size, L"OFD.xml", &pBuffer, nBufferSize);
if (hresult == S_OK && pBuffer != NULL)
{
if (19 <= nBufferSize && NULL != strstr((char *)pBuffer, "ofd:OFD"))
nFileType = 3;
delete[] pBuffer;
pBuffer = NULL;
return nFileType;
}
return 2;
}
};

View File

@ -189,6 +189,7 @@ namespace Aggplus
{
m_bIsClip = false;
m_bIsClip2 = false;
m_bIsEmpty = false;
}
CClipMulti::~CClipMulti()
{
@ -211,6 +212,7 @@ namespace Aggplus
m_rasterizer.clip_box(0, 0, width, height);
m_bIsClip = false;
m_bIsClip2 = false;
m_bIsEmpty = false;
}
void CClipMulti::GenerateClip(CGraphicsPath* pPath, CMatrix* pMatrix)
@ -247,15 +249,21 @@ namespace Aggplus
if (!m_bIsClip)
return GenerateClip2(bEvenOdd);
pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
if (!pRasterizer->rewind_scanlines())
{
if (op == agg::sbool_and)
SetEmpty();
return;
}
if (!m_bIsClip2)
{
// need to blend with rasterizer
pRasterizer->filling_rule(bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, m_rasterizer, *pRasterizer, sl1, sl2, sl, m_storage1);
m_lCurStorage = 1;
@ -263,15 +271,8 @@ namespace Aggplus
else
{
// need to blend with storage
pRasterizer->filling_rule(op ? agg::fill_even_odd : agg::fill_non_zero);
scanline_type sl1;
scanline_type sl2;
scanline_type sl;
agg::sbool_combine_shapes_aa(op, *pRasterizer, (m_lCurStorage == 1) ? m_storage1 : m_storage2, sl1, sl2, sl,
(m_lCurStorage == 1) ? m_storage2 : m_storage1);
agg::sbool_combine_shapes_aa(op, (m_lCurStorage == 1) ? m_storage1 : m_storage2, *pRasterizer, sl1, sl2, sl,
(m_lCurStorage == 1) ? m_storage2 : m_storage1);
if (1 == m_lCurStorage)
{
@ -295,6 +296,10 @@ namespace Aggplus
{
return m_bIsClip2;
}
bool CClipMulti::IsEmpty()
{
return m_bIsEmpty;
}
void CClipMulti::Reset()
{
@ -305,5 +310,13 @@ namespace Aggplus
m_bIsClip = false;
m_bIsClip2 = false;
m_bIsEmpty = false;
}
void CClipMulti::SetEmpty()
{
m_bIsEmpty = true;
m_bIsClip2 = true;
m_lCurStorage = 1;
//m_storage1.prepare();
}
}

View File

@ -154,6 +154,7 @@ public:
bool m_bIsClip;
bool m_bIsClip2;
bool m_bIsEmpty;
LONG m_lWidth;
LONG m_lHeight;
@ -172,8 +173,10 @@ public:
bool IsClip();
bool IsClip2();
bool IsEmpty();
void Reset();
void SetEmpty();
};
}

View File

@ -1353,7 +1353,7 @@ namespace Aggplus
{
agg::render_scanlines(ras, sl, ren);
}
else
else if (!m_oClip.IsEmpty())
{
if (!m_oClip.IsClip2())
{
@ -2191,14 +2191,11 @@ namespace Aggplus
for (LONG i = 0; i < lCount2; ++i)
{
if (0 == i)
{
poly2_dash.add_dash((params[i * 2]) * dKoef, params[i * 2 + 1] * dKoef);
}
else
{
poly2_dash.add_dash(params[i * 2] * dKoef, params[i * 2 + 1] * dKoef);
}
double dashLen = params[i * 2] * dKoef;
double gapLen = params[i * 2 + 1] * dKoef;
if (m_bIs0PenWidthAs1px && fabs(dashLen) < 0.0001 && LineCap == agg::round_cap)
dashLen = 0.0001;
poly2_dash.add_dash(dashLen, gapLen);
}
if (1 == (lCount % 2))
{

View File

@ -152,7 +152,7 @@ public:
Link = 1,
DocInfo = 2,
FormField = 3, // Backward compatibility for docxf
Annotaion = 4,
Annotation = 4,
DeleteAnnot = 5,
WidgetsInfo = 6,
ShapeStart = 7,
@ -161,6 +161,7 @@ public:
PageRotate = 10,
Headings = 11,
Redact = 12,
RedactAnnot = 13,
Undefined = 255
};
@ -308,6 +309,10 @@ public:
LONG c = (NULL == codepoints) ? 32 : codepoints[0];
return CommandDrawTextExCHAR(c, (LONG)gid, x, y, w, h);
}
virtual HRESULT CommandDrawType3CHAR(const std::wstring& wsUnicodeText, const double& x, const double& y, const double& w, const double& h, const double& ascent, const double& descent, const double& unitsPerEm)
{
return S_OK;
}
//-------- Command markers ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType) = 0;

View File

@ -1067,7 +1067,7 @@ namespace NSOnlineOfficeBinToPdf
switch (eCommand)
{
case ctFormField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::FormField; break;
case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotaion; break;
case ctAnnotField: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::Annotation; break;
case ctAnnotFieldDelete: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::DeleteAnnot; break;
case ctWidgetsInfo: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::WidgetsInfo; break;
case ctShapeStart: eAdvancedCommandType = IAdvancedCommand::AdvancedCommandType::ShapeStart; break;

View File

@ -135,7 +135,7 @@ CAnnotFieldInfo::CActionFieldPr* ReadAction(NSOnlineOfficeBinToPdf::CBufferReade
return pRes;
}
CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotaion)
CAnnotFieldInfo::CAnnotFieldInfo() : IAdvancedCommand(AdvancedCommandType::Annotation)
{
m_nType = EAnnotType::Unknown;
@ -154,20 +154,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()
{
@ -184,6 +186,8 @@ CAnnotFieldInfo::~CAnnotFieldInfo()
RELEASEOBJECT(m_pStampPr);
RELEASEOBJECT(m_pRedactPr);
RELEASEOBJECT(m_pLinkPr);
RELEASEOBJECT(m_pFileAttachmentPr);
RELEASEOBJECT(m_pScreenPr);
RELEASEOBJECT(m_pWidgetPr);
}
@ -277,6 +281,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();
@ -406,21 +422,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)
{
@ -509,6 +535,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);
@ -516,6 +544,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;
}
@ -837,6 +867,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; }
@ -862,6 +893,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; }
@ -1336,3 +1487,11 @@ bool CRedact::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRe
return true;
}
CRedactAnnot::CRedactAnnot() : IAdvancedCommand(AdvancedCommandType::RedactAnnot) {}
int CRedactAnnot::GetID() { return m_nID; }
bool CRedactAnnot::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector)
{
m_nID = pReader->ReadInt();
return true;
}

View File

@ -62,6 +62,7 @@ public:
Ink = 14,
Popup = 15,
FileAttachment = 16,
Screen = 20,
Redact = 25,
Widget = 26,
WidgetPushButton = 27,
@ -493,6 +494,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();
@ -502,11 +504,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();
@ -548,21 +617,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);
@ -595,20 +668,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
@ -686,4 +761,17 @@ private:
std::vector<SRedact*> m_arrRedact;
};
class GRAPHICS_DECL CRedactAnnot : public IAdvancedCommand
{
public:
CRedactAnnot();
int GetID();
bool Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafileToRenderter* pCorrector);
private:
int m_nID;
};
#endif // _BUILD_ANNOTFIELD_H_

View File

@ -201,5 +201,4 @@ private:
std::vector<CHeading*> m_arrHeading;
};
#endif // _BUILD_DOCINFO_H_

View File

@ -49,10 +49,10 @@
struct TBBox
{
float fMinX;
float fMaxX;
float fMinY;
float fMaxY;
float fMinX = 0;
float fMaxX = 0;
float fMinY = 0;
float fMaxY = 0;
};
struct TBBoxAdvance

View File

@ -32,6 +32,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#include "HTMLRendererText.h"
#include "Text.h"
@ -357,6 +358,17 @@ namespace NSHtmlRenderer
return S_OK;
}
HRESULT CHTMLRendererText::CommandDrawType3CHAR(const std::wstring& wsUnicodeText, const double& x, const double& y, const double& w, const double& h, const double& ascent, const double& descent, const double& unitsPerEm)
{
m_pInternal->m_oSmartText.m_oFontManager.SetType3Metrics(ascent, descent, unitsPerEm, w);
m_pInternal->GetUnicodes(wsUnicodeText);
m_pInternal->WriteText(m_pInternal->m_pTempUnicodes, NULL, m_pInternal->m_nTempUnicodesLen, x, y);
m_pInternal->m_oSmartText.m_oFontManager.ClearType3();
return S_OK;
}
//-------- Command markers ---------------------------------------------------------------
HRESULT CHTMLRendererText::BeginCommand(const DWORD& lType) { return S_OK; }
HRESULT CHTMLRendererText::EndCommand(const DWORD& lType) { return S_OK; }

View File

@ -32,6 +32,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#ifndef _ASC_HTMLRENDERER3_TEXT_H_
#define _ASC_HTMLRENDERER3_TEXT_H_
@ -144,6 +145,8 @@ namespace NSHtmlRenderer
virtual HRESULT CommandDrawTextExCHAR(const LONG& c, const LONG& gid, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT CommandDrawTextEx(const std::wstring& bsUnicodeText, const unsigned int* pGids, const unsigned int nGidsCount, const double& x, const double& y, const double& w, const double& h);
virtual HRESULT CommandDrawType3CHAR(const std::wstring& wsUnicodeText, const double& x, const double& y, const double& w, const double& h, const double& ascent, const double& descent, const double& unitsPerEm);
//-------- Command markers ---------------------------------------------------------------
virtual HRESULT BeginCommand(const DWORD& lType);
virtual HRESULT EndCommand(const DWORD& lType);

View File

@ -32,6 +32,7 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#ifndef _ASC_HTMLRENDERER_TEXT_H_
#define _ASC_HTMLRENDERER_TEXT_H_
@ -45,9 +46,9 @@ namespace NSHtmlRenderer
{
struct CHFontInfo
{
int m_lAscent;
int m_lDescent;
int m_lUnitsPerEm;
double m_lAscent;
double m_lDescent;
double m_lUnitsPerEm;
CHFontInfo() : m_lAscent(0), m_lDescent(0), m_lUnitsPerEm(0) {}
CHFontInfo(const CHFontInfo& oSrc) : m_lAscent(oSrc.m_lAscent), m_lDescent(oSrc.m_lDescent), m_lUnitsPerEm(oSrc.m_lUnitsPerEm) {}
@ -68,13 +69,29 @@ namespace NSHtmlRenderer
NSStructures::CFont* m_pFont;
CHFontInfo m_oCurrentInfo;
bool m_bIsType3;
double m_dType3GlyphWidth;
public:
CFontManagerWrapper() : m_pManager(NULL) {}
CFontManagerWrapper() : m_pManager(NULL), m_bIsType3(false), m_dType3GlyphWidth(0) {}
virtual ~CFontManagerWrapper()
{
RELEASEOBJECT(m_pManager);
}
void SetType3Metrics(double dAscent, double dDescent, double dUnitsPerEm, double dGlyphWidth)
{
m_bIsType3 = true;
m_dType3GlyphWidth = dGlyphWidth;
m_oCurrentInfo.m_lAscent = dAscent;
m_oCurrentInfo.m_lDescent = dDescent;
m_oCurrentInfo.m_lUnitsPerEm = dUnitsPerEm > 0 ? dUnitsPerEm : 1000;
}
void ClearType3()
{
m_bIsType3 = false;
}
void Init(NSFonts::IApplicationFonts* pApplicationFonts, int nCacheSize = 0)
{
RELEASEOBJECT(m_pManager);
@ -98,15 +115,25 @@ namespace NSHtmlRenderer
else
LoadFontByFile(m_pFont->Path, m_pFont->Size);
}
double MeasureString(const unsigned int* symbols, const int& count, double x, double y)
TBBox MeasureString(const unsigned int* symbols, const int& count, double x, double y)
{
if (m_bIsType3)
{
TBBox oBox;
double dUnitsPerEm = m_oCurrentInfo.m_lUnitsPerEm > 0 ? m_oCurrentInfo.m_lUnitsPerEm : 1000;
double dFontSizePt = m_pFont ? m_pFont->Size : 10.0;
oBox.fMinX = (float)x;
oBox.fMinY = (float)(-(m_oCurrentInfo.m_lAscent / dUnitsPerEm) * dFontSizePt);
oBox.fMaxX = (float)(x + m_dType3GlyphWidth);
oBox.fMaxY = (float)( (m_oCurrentInfo.m_lDescent / dUnitsPerEm) * dFontSizePt);
return oBox;
}
if (!m_pManager)
return 0;
return TBBox();
m_pManager->LoadString1(symbols, count, (float)x, (float)y);
TBBox _box = m_pManager->MeasureString2();
return abs((_box.fMaxX - _box.fMinX) * 25.4 / 72.0);
return m_pManager->MeasureString2();
}
private:
@ -358,7 +385,7 @@ namespace NSHtmlRenderer
}
// done, baseline is set. now just continue the line
if (bIsDumpFont)
if (bIsDumpFont && !m_oFontManager.m_bIsType3)
m_oFontManager.LoadCurrentFont();
double dKoef = m_oFontManager.m_pFont->Size * 25.4 / (72 * m_oFontManager.m_oCurrentInfo.m_lUnitsPerEm);
@ -386,7 +413,14 @@ namespace NSHtmlRenderer
double dPrevW = dOffsetX;
for (int i = 0; i < nCount; ++i)
{
double dW = m_oFontManager.MeasureString((const unsigned int*)(input + i), 1, 0, 0);
TBBox bBox = m_oFontManager.MeasureString((const unsigned int*)(input + i), 1, 0, 0);
double dW = std::abs((bBox.fMaxX - bBox.fMinX) * 25.4 / 72.0);
double dMeasureAscent = std::abs(bBox.fMinY * 25.4 / 72.0);
double dMeasureDescent = std::abs(bBox.fMaxY * 25.4 / 72.0);
if (m_oLine.m_dAscent < dMeasureAscent)
m_oLine.m_dAscent = dMeasureAscent;
if (m_oLine.m_dDescent < dMeasureDescent)
m_oLine.m_dDescent = dMeasureDescent;
NSWasm::CHChar* pChar = m_oLine.AddTail();
pChar->unicode = pUnicodes[i];

View File

@ -1,3 +1,38 @@
/*
* Copyright (C) Ascensio System SIA, 2009-2026
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation, together with the
* additional terms provided in the LICENSE file.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA by email at info@onlyoffice.com
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
* LV-1050, Latvia, European Union.
*
* The interactive user interfaces in modified versions of the Program
* are required to display Appropriate Legal Notices in accordance with
* Section 5 of the GNU AGPL version 3.
*
* No trademark rights are granted under this License.
*
* All non-code elements of the Product, including illustrations,
* icon sets, and technical writing content, are licensed under the
* Creative Commons Attribution-ShareAlike 4.0 International License:
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
*
* This license applies only to such non-code elements and does not
* modify or replace the licensing terms applicable to the Program's
* source code, which remains licensed under the GNU Affero General
* Public License v3.
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#ifndef _WASM_SERIALIZE_H
#define _WASM_SERIALIZE_H

View File

@ -144,3 +144,5 @@ void IOfficeDrawingFile::ConvertToRaster(int nPageIndex, const std::wstring& pat
pFrame->SaveFile(path, nImageType);
RELEASEOBJECT(pFrame);
}
void IOfficeDrawingFile::SetPainter(IOfficeDrawingFilePainter* pPainter) {}

View File

@ -59,6 +59,26 @@ struct COfficeDrawingPageParams
}
};
class IOfficeDrawingFilePainter
{
public:
enum class State
{
Paused,
Stopped,
Runned
};
enum class Status
{
Ok,
Cancel
};
virtual State GetState() = 0;
virtual void OnPaint(const Status&) = 0;
};
class GRAPHICS_DECL IOfficeDrawingFile
{
public:
@ -106,6 +126,9 @@ public:
virtual std::wstring GetInfo() = 0;
virtual unsigned char* GetStructure() = 0;
virtual unsigned char* GetLinks(int nPageIndex) = 0;
// DrawingFile control
virtual void SetPainter(IOfficeDrawingFilePainter* pPainter);
};
#endif // _OFFICE_DRAWING_FILE_H

View File

@ -119,8 +119,8 @@ namespace XmlUtils
void GetTextWithHHHH(bool bPreserve, wchar_t*& sBuffer, long& nSize, long& nLen);
std::wstring GetTextWithHHHH(bool bPreserve);
std::wstring GetOuterXml();
std::wstring GetInnerXml();
std::wstring GetOuterXml(bool bEncodingXml = true);
std::wstring GetInnerXml(bool bEncodingXml = true);
int GetAttributesCount();
bool MoveToFirstAttribute();

View File

@ -211,13 +211,13 @@ namespace XmlUtils
return m_pInternal->GetTextWithHHHH(bPreserve);
}
std::wstring CXmlLiteReader::GetOuterXml()
std::wstring CXmlLiteReader::GetOuterXml(bool bEncodingXml)
{
return m_pInternal->GetOuterXml();
return m_pInternal->GetOuterXml(bEncodingXml);
}
std::wstring CXmlLiteReader::GetInnerXml()
std::wstring CXmlLiteReader::GetInnerXml(bool bEncodingXml)
{
return m_pInternal->GetInnerXml();
return m_pInternal->GetInnerXml(bEncodingXml);
}
int CXmlLiteReader::GetAttributesCount()

View File

@ -638,13 +638,13 @@ namespace XmlUtils
GetTextWithHHHH(bPreserve, pUnicodes, nSize, nLen);
return std::wstring(pUnicodes, nLen);
}
inline std::wstring GetOuterXml()
inline std::wstring GetOuterXml(bool bEncodingXml = true)
{
return GetXml(false);
return GetXml(false, bEncodingXml);
}
inline std::wstring GetInnerXml()
inline std::wstring GetInnerXml(bool bEncodingXml = true)
{
return GetXml(true);
return GetXml(true, bEncodingXml);
}
inline int GetAttributesCount()
@ -703,7 +703,7 @@ namespace XmlUtils
}
private:
inline std::wstring GetXml(bool bInner)
inline std::wstring GetXml(bool bInner, bool bEncodingXml = true)
{
if (!IsValid())
return L"";
@ -733,7 +733,7 @@ namespace XmlUtils
eNodeType == XmlNodeType_Whitespace ||
eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE ||
eNodeType == XmlNodeType_CDATA)
oResult.WriteEncodeXmlString(GetText().c_str());
(bEncodingXml)? oResult.WriteEncodeXmlString(GetText().c_str()): oResult.WriteString(GetText().c_str());
else if (eNodeType == XmlNodeType_Element)
WriteElement(oResult);
else if (eNodeType == XmlNodeType_EndElement)

View File

@ -0,0 +1,113 @@
# Copyright (C) Ascensio System SIA, 2009-2026
#
# This program is a free software product. You can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License (AGPL)
# version 3 as published by the Free Software Foundation, together with the
# additional terms provided in the LICENSE file.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
# details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
#
# You can contact Ascensio System SIA by email at info@onlyoffice.com
# or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
# LV-1050, Latvia, European Union.
#
# The interactive user interfaces in modified versions of the Program
# are required to display Appropriate Legal Notices in accordance with
# Section 5 of the GNU AGPL version 3.
#
# No trademark rights are granted under this License.
#
# All non-code elements of the Product, including illustrations,
# icon sets, and technical writing content, are licensed under the
# Creative Commons Attribution-ShareAlike 4.0 International License:
# https://creativecommons.org/licenses/by-sa/4.0/legalcode
#
# This license applies only to such non-code elements and does not
# modify or replace the licensing terms applicable to the Program's
# source code, which remains licensed under the GNU Affero General
# Public License v3.
#
# SPDX-License-Identifier: AGPL-3.0-only
QT -= core gui
VERSION = 1.0.0.4
TARGET = DocxRenderer
TEMPLATE = lib
CONFIG += c++11
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/..
PWD_ROOT_DIR = $$PWD
include(../Common/base.pri)
DEFINES += DOCXRENDERER_USE_DYNAMIC_LIBRARY
ADD_DEPENDENCY(UnicodeConverter, kernel, graphics)
# Flag for disable full document creation. Enabled in pdf editor
#CONFIG += disable_full_document_creation
core_windows {
LIBS += \
-lgdi32 \
-ladvapi32 \
-luser32 \
-lshell32
}
HEADERS += \
$$PWD_ROOT_DIR/src/logic/elements/BaseItem.h \
$$PWD_ROOT_DIR/src/logic/elements/ContText.h \
$$PWD_ROOT_DIR/src/logic/elements/Paragraph.h \
$$PWD_ROOT_DIR/src/logic/elements/Shape.h \
$$PWD_ROOT_DIR/src/logic/elements/Table.h \
$$PWD_ROOT_DIR/src/logic/elements/TextLine.h \
$$PWD_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \
$$PWD_ROOT_DIR/src/logic/managers/FontStyleManager.h \
$$PWD_ROOT_DIR/src/logic/managers/ImageManager.h \
$$PWD_ROOT_DIR/src/logic/managers/FontManager.h \
$$PWD_ROOT_DIR/src/logic/managers/ParagraphStyleManager.h \
$$PWD_ROOT_DIR/src/logic/styles/FontStyle.h \
$$PWD_ROOT_DIR/src/logic/styles/ParagraphStyle.h \
$$PWD_ROOT_DIR/src/resources/ColorTable.h \
$$PWD_ROOT_DIR/src/resources/Constants.h \
$$PWD_ROOT_DIR/src/resources/ImageInfo.h \
$$PWD_ROOT_DIR/src/resources/LinesTable.h \
$$PWD_ROOT_DIR/src/resources/VectorGraphics.h \
$$PWD_ROOT_DIR/src/resources/resources.h \
$$PWD_ROOT_DIR/src/resources/utils.h \
$$PWD_ROOT_DIR/src/logic/Page.h \
$$PWD_ROOT_DIR/src/logic/Document.h \
$$PWD_ROOT_DIR/DocxRenderer.h
SOURCES += \
$$PWD_ROOT_DIR/src/logic/elements/BaseItem.cpp \
$$PWD_ROOT_DIR/src/logic/elements/ContText.cpp \
$$PWD_ROOT_DIR/src/logic/elements/Paragraph.cpp \
$$PWD_ROOT_DIR/src/logic/elements/Shape.cpp \
$$PWD_ROOT_DIR/src/logic/elements/TextLine.cpp \
$$PWD_ROOT_DIR/src/logic/managers/FontManager.cpp \
$$PWD_ROOT_DIR/src/logic/managers/FontStyleManager.cpp \
$$PWD_ROOT_DIR/src/logic/managers/ImageManager.cpp \
$$PWD_ROOT_DIR/src/logic/managers/ParagraphStyleManager.cpp \
$$PWD_ROOT_DIR/src/logic/styles/FontStyle.cpp \
$$PWD_ROOT_DIR/src/logic/Page.cpp \
$$PWD_ROOT_DIR/src/logic/Document.cpp \
$$PWD_ROOT_DIR/src/logic/styles/ParagraphStyle.cpp \
$$PWD_ROOT_DIR/src/resources/VectorGraphics.cpp \
$$PWD_ROOT_DIR/DocxRenderer.cpp
disable_full_document_creation {
DEFINES += DISABLE_FULL_DOCUMENT_CREATION
} else {
SOURCES += \
$$PWD_ROOT_DIR/src/resources/resources.cpp
}
DISTFILES += \
$$PWD_ROOT_DIR/readme.md

View File

@ -31,84 +31,8 @@
#
# SPDX-License-Identifier: AGPL-3.0-only
QT -= core gui
INCLUDEPATH += $$PWD
VERSION = 1.0.0.4
TARGET = DocxRenderer
TEMPLATE = lib
include(DocxRenderer.pri)
CONFIG += c++11
CONFIG += shared
CONFIG += plugin
CORE_ROOT_DIR = $$PWD/..
PWD_ROOT_DIR = $$PWD
include(../Common/base.pri)
DEFINES += DOCXRENDERER_USE_DYNAMIC_LIBRARY
ADD_DEPENDENCY(UnicodeConverter, kernel, graphics)
# Flag for disable full document creation. Enabled in pdf editor
#CONFIG += disable_full_document_creation
core_windows {
LIBS += \
-lgdi32 \
-ladvapi32 \
-luser32 \
-lshell32
}
HEADERS += \
src/logic/elements/BaseItem.h \
src/logic/elements/ContText.h \
src/logic/elements/Paragraph.h \
src/logic/elements/Shape.h \
src/logic/elements/Table.h \
src/logic/elements/TextLine.h \
src/logic/managers/ExternalImageStorage.h \
src/logic/managers/FontStyleManager.h \
src/logic/managers/ImageManager.h \
src/logic/managers/FontManager.h \
src/logic/managers/ParagraphStyleManager.h \
src/logic/styles/FontStyle.h \
src/logic/styles/ParagraphStyle.h \
src/resources/ColorTable.h \
src/resources/Constants.h \
src/resources/ImageInfo.h \
src/resources/LinesTable.h \
src/resources/VectorGraphics.h \
src/resources/resources.h \
src/resources/utils.h \
src/logic/Page.h \
src/logic/Document.h \
DocxRenderer.h
SOURCES += \
src/logic/elements/BaseItem.cpp \
src/logic/elements/ContText.cpp \
src/logic/elements/Paragraph.cpp \
src/logic/elements/Shape.cpp \
src/logic/elements/Table.cpp \
src/logic/elements/TextLine.cpp \
src/logic/managers/FontManager.cpp \
src/logic/managers/FontStyleManager.cpp \
src/logic/managers/ImageManager.cpp \
src/logic/managers/ParagraphStyleManager.cpp \
src/logic/styles/FontStyle.cpp \
src/logic/Page.cpp \
src/logic/Document.cpp \
src/logic/styles/ParagraphStyle.cpp \
src/resources/VectorGraphics.cpp \
DocxRenderer.cpp
disable_full_document_creation {
DEFINES += DISABLE_FULL_DOCUMENT_CREATION
} else {
SOURCES += \
src/resources/resources.cpp
}
DISTFILES += \
readme.md
SOURCES += $$PWD/src/logic/elements/Table.cpp

View File

@ -36,8 +36,6 @@
#include "Page.h"
#include <memory>
#include <map>
#include <set>
// #include <assert.h>
#include "../../../DesktopEditor/graphics/pro/Graphics.h"
@ -51,6 +49,7 @@ namespace NSDocxRenderer
m_oManagers(oManagers), m_oContBuilder(oManagers.pFontStyleManager, oManagers.pFontSelector)
{
m_pAppFonts = pAppFonts;
m_pTableBuilder = NSTables::Create();
CShape::ResetRelativeHeight();
}
@ -112,6 +111,8 @@ namespace NSDocxRenderer
CPage::~CPage()
{
Clear();
if (m_pTableBuilder)
delete m_pTableBuilder;
}
void CPage::DeleteTextClipPage()
@ -422,11 +423,23 @@ namespace NSDocxRenderer
auto text_line_groups = BuildTextLineGroups();
if (m_bIsBuildTables)
{
m_pTableBuilder->SetShapes(std::move(m_arShapes));
m_pTableBuilder->BuildGraphicallCells();
m_arShapes = std::move(m_pTableBuilder->ReturnShapes());
}
// building final objects
m_arParagraphs = BuildParagraphs(text_line_groups);
// if (m_bIsBuildTables)
// m_arTables = BuildTables(text_line_groups);
if (m_bIsBuildTables)
{
m_pTableBuilder->SetParagraphs(std::move(m_arParagraphs));
m_pTableBuilder->BuildTables();
m_arParagraphs = std::move(m_pTableBuilder->ReturnParagraphs());
m_arTables = std::move(m_pTableBuilder->GetTables());
}
// post analyze
CalcSelected();
@ -434,8 +447,8 @@ namespace NSDocxRenderer
CalcShapesRotation();
m_arOutputObjects = BuildOutputObjects();
// for (auto& t : m_arTables)
// m_arOutputObjects.push_back(t);
for (auto& t : m_arTables)
m_arOutputObjects.push_back(t);
}
void CPage::Record(NSStringUtils::CStringBuilder& oWriter, bool bIsLastPage)
@ -2073,595 +2086,6 @@ namespace NSDocxRenderer
return ar_paragraphs;
}
std::vector<CPage::text_cell_group_ptr_t> CPage::BuildTextCellGroups(const std::vector<CPage::text_line_group_ptr_t>& arTextLineGroups)
{
std::vector<CPage::text_cell_ptr_t> text_cells;
for (const auto& text_line_group : arTextLineGroups)
{
auto text_cell_new = std::make_shared<CTextCell>();
text_cell_new->RecalcWithNewItem(text_line_group.get());
text_cells.push_back(std::move(text_cell_new));
}
std::sort(text_cells.begin(), text_cells.end(),
[] (const text_cell_ptr_t& cell1, const text_cell_ptr_t& cell2) {
if (fabs(cell1->m_dTop - cell2->m_dTop) < c_dMAX_TABLE_LINE_WIDTH_MM)
return cell1->m_dLeft < cell2->m_dLeft;
return cell1->m_dTop < cell2->m_dTop;
});
std::vector<text_cell_group_ptr_t> text_cell_groups;
text_cell_group_ptr_t curr_group = std::make_shared<CBaseItemGroup<CTextCell>>();
curr_group->AddItem(text_cells[0]);
double curr_bot = text_cells[0]->m_dBot;
for (size_t i = 1; i < text_cells.size(); ++i)
{
const auto& cell = text_cells[i];
if (cell->m_dTop - curr_bot < 10)
curr_group->AddItem(cell);
else
{
text_cell_groups.push_back(std::move(curr_group));
curr_group = std::make_shared<CBaseItemGroup<CTextCell>>();
curr_group->AddItem(cell);
}
curr_bot = cell->m_dBot;
}
text_cell_groups.push_back(curr_group);
auto vert_crossing = [] (const CBaseItem* item1, const CBaseItem* item2) {
bool left_inside = item1->m_dLeft < item2->m_dRight;
bool right_inside = item1->m_dRight > item2->m_dLeft;
return left_inside && right_inside;
};
auto hor_crossing = [] (const CBaseItem* item1, const CBaseItem* item2) {
bool left_inside = item1->m_dTop < item2->m_dBot;
bool right_inside = item1->m_dBot > item2->m_dTop;
return left_inside && right_inside;
};
for (const auto& text_cells : text_cell_groups)
{
// calc max gaps between groups bot / right
for (size_t i = 0; i < text_cells->m_arItems.size(); ++i)
{
// max bot calc
for (size_t j = 0; j < text_cells->m_arItems.size(); ++j)
if (text_cells->m_arItems[i]->m_dBot < text_cells->m_arItems[j]->m_dTop && vert_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()))
text_cells->m_arItems[i]->m_dMaxPossibleBot = std::min(text_cells->m_arItems[i]->m_dMaxPossibleBot, text_cells->m_arItems[j]->m_dTop);
// max right calc
for (size_t j = 0; j < text_cells->m_arItems.size(); ++j)
if (text_cells->m_arItems[i]->m_dRight < text_cells->m_arItems[j]->m_dLeft &&
hor_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()))
text_cells->m_arItems[i]->m_dMaxPossibleRight = std::min(text_cells->m_arItems[i]->m_dMaxPossibleRight, text_cells->m_arItems[j]->m_dLeft);
}
// setting aligned params bot / right
for (size_t i = 0; i < text_cells->m_arItems.size(); ++i)
{
// bot recalc
for (size_t j = 0; j < text_cells->m_arItems.size(); ++j)
{
if (hor_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()) && i != j)
{
if (text_cells->m_arItems[i]->m_dMaxPossibleBot > text_cells->m_arItems[j]->m_dBot)
{
text_cells->m_arItems[i]->m_dBot = std::max(text_cells->m_arItems[i]->m_dBot, text_cells->m_arItems[j]->m_dBot);
text_cells->m_arItems[i]->m_dHeight = text_cells->m_arItems[i]->m_dBot - text_cells->m_arItems[i]->m_dTop;
}
else
break;
}
}
// right recalc
for (size_t j = 0; j < text_cells->m_arItems.size(); ++j)
{
if (vert_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()) && i != j)
{
if (text_cells->m_arItems[i]->m_dMaxPossibleRight > text_cells->m_arItems[j]->m_dRight)
{
text_cells->m_arItems[i]->m_dRight = std::max(text_cells->m_arItems[i]->m_dRight, text_cells->m_arItems[j]->m_dRight);
text_cells->m_arItems[i]->m_dWidth = text_cells->m_arItems[i]->m_dRight - text_cells->m_arItems[i]->m_dLeft;
}
else
break;
}
}
}
// calc max gaps between groups top / left
for (int i = text_cells->m_arItems.size() - 1; i >= 0; --i)
{
// max top calc
for (int j = text_cells->m_arItems.size() - 1; j >= 0; --j)
if (text_cells->m_arItems[i]->m_dTop > text_cells->m_arItems[j]->m_dBot &&
vert_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()))
text_cells->m_arItems[i]->m_dMinPossibleTop = std::max(text_cells->m_arItems[i]->m_dMinPossibleTop, text_cells->m_arItems[j]->m_dBot);
// max left calc
for (int j = text_cells->m_arItems.size() - 1; j >= 0; --j)
if (text_cells->m_arItems[i]->m_dLeft > text_cells->m_arItems[j]->m_dRight &&
hor_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()))
text_cells->m_arItems[i]->m_dMinPossibleLeft = std::max(text_cells->m_arItems[i]->m_dMinPossibleLeft, text_cells->m_arItems[j]->m_dRight);
}
// setting aligned params top / left
for (int i = text_cells->m_arItems.size() - 1; i >= 0; --i)
{
// top recalc
for (int j = text_cells->m_arItems.size() - 1; j >= 0; --j)
{
if (hor_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()) && i != j)
{
if (text_cells->m_arItems[i]->m_dMinPossibleTop < text_cells->m_arItems[j]->m_dTop)
{
text_cells->m_arItems[i]->m_dTop = std::min(text_cells->m_arItems[i]->m_dTop, text_cells->m_arItems[j]->m_dTop);
text_cells->m_arItems[i]->m_dHeight = text_cells->m_arItems[i]->m_dBot - text_cells->m_arItems[i]->m_dTop;
}
else
break;
}
}
// left recalc
for (int j = text_cells->m_arItems.size() - 1; j >= 0; --j)
{
if (vert_crossing(text_cells->m_arItems[i].get(), text_cells->m_arItems[j].get()) && i != j)
{
if (text_cells->m_arItems[i]->m_dMinPossibleLeft > text_cells->m_arItems[j]->m_dLeft)
{
text_cells->m_arItems[i]->m_dRight = std::min(text_cells->m_arItems[i]->m_dLeft, text_cells->m_arItems[j]->m_dLeft);
text_cells->m_arItems[i]->m_dWidth = text_cells->m_arItems[i]->m_dRight - text_cells->m_arItems[i]->m_dLeft;
}
else
break;
}
}
}
}
return text_cell_groups;
}
std::vector<CPage::table_ptr_t> CPage::BuildTables(const std::vector<text_line_group_ptr_t>& arTextLineGroups)
{
auto graphical_cells = BuildGraphicalCells();
auto text_cell_groups = BuildTextCellGroups(arTextLineGroups);
std::vector<cell_group_ptr_t> cell_groups;
for (const auto& text_cell_group : text_cell_groups)
{
cell_group_ptr_t cell_group_new = std::make_shared<CBaseItemGroup<CTable::CCell>>();
for (auto& text_cell : text_cell_group->m_arItems)
{
auto cell_new = std::make_shared<CTable::CCell>();
cell_new->RecalcWithNewItem(text_cell.get());
cell_group_new->AddItem(std::move(cell_new));
}
cell_groups.push_back(std::move(cell_group_new));
cell_group_new = std::make_shared<CBaseItemGroup<CTable::CCell>>();
}
if (cell_groups.empty())
return {};
// sets paragraphs into cells
for (auto& cells : cell_groups)
for (auto& cell : cells->m_arItems)
for (auto& paragraph : m_arParagraphs)
{
if (!paragraph)
continue;
bool top = fabs(cell->m_dTop - paragraph->m_arTextLines.front()->m_dTopWithMaxAscent) < c_dGRAPHICS_ERROR_MM
|| paragraph->m_arTextLines.front()->m_dTopWithMaxAscent > cell->m_dTop;
bool bot = fabs(cell->m_dBot - paragraph->m_dBot) < c_dGRAPHICS_ERROR_MM
|| paragraph->m_dBot < cell->m_dBot;
bool left = fabs(cell->m_dLeft - paragraph->m_dLeft) < c_dGRAPHICS_ERROR_MM
|| paragraph->m_dLeft > cell->m_dLeft;
bool right = fabs(cell->m_dRight - paragraph->m_dRight) < c_dGRAPHICS_ERROR_MM
|| paragraph->m_dRight < cell->m_dRight;
if (top && bot && left && right)
{
paragraph->m_dLeftBorder = paragraph->m_dLeft - cell->m_dLeft;
paragraph->m_dRightBorder = 0;
if (!cell->m_arParagraphs.empty())
paragraph->m_dSpaceBefore = paragraph->m_dTop - cell->m_arParagraphs.back()->m_dBot;
else if (paragraph->m_dTop - cell->m_dTop > 0)
paragraph->m_dSpaceBefore = paragraph->m_dTop - cell->m_dTop;
else
paragraph->m_dSpaceBefore = 0;
paragraph->m_dSpaceAfter = 0;
cell->AddParagraph(paragraph);
paragraph = nullptr;
}
}
auto right = MoveNullptr(m_arParagraphs.begin(), m_arParagraphs.end());
m_arParagraphs.erase(right, m_arParagraphs.end());
std::sort(m_arParagraphs.begin(), m_arParagraphs.end(), [] (const paragraph_ptr_t& p1, const paragraph_ptr_t& p2) {
return p1->m_dBot < p2->m_dBot;
});
std::vector<CTable::row_ptr_t> rows;
CTable::row_ptr_t curr_row = nullptr;
for (auto& cells : cell_groups)
for (auto& cell : cells->m_arItems)
{
if (!curr_row)
{
curr_row = std::make_shared<CTable::CRow>();
}
else if (fabs(curr_row->m_dBot - cell->m_dBot) > c_dMAX_TABLE_LINE_WIDTH_MM)
{
rows.push_back(std::move(curr_row));
curr_row = std::make_shared<CTable::CRow>();
}
curr_row->AddCell(cell);
}
if (!curr_row->IsEmpty())
rows.push_back(std::move(curr_row));
std::vector<table_ptr_t> tables;
table_ptr_t curr_table = nullptr;
for (const auto& row : rows)
{
if (!curr_table)
{
curr_table = std::make_shared<CTable>();
}
else if (fabs(curr_table->m_dBot - row->m_dTop) > c_dMAX_TABLE_LINE_WIDTH_MM)
{
tables.push_back(std::move(curr_table));
curr_table = std::make_shared<CTable>();
}
curr_table->AddRow(row);
}
if (!curr_table->IsEmpty())
tables.push_back(std::move(curr_table));
for (auto& t : tables)
t->CalcGridCols();
return tables;
}
std::vector<CPage::graphical_cell_ptr_t> CPage::BuildGraphicalCells()
{
struct Crossing;
struct Line;
enum class eLineDirection
{
ldTop,
ldBot,
ldLeft,
ldRight
};
struct Line
{
Crossing* crossing;
size_t shape_index;
eLineDirection direction;
};
// crossing is a logical intersection between two lines
// contains the lines from this crossing
struct Crossing
{
Point p {};
std::vector<Line> lines {};
Crossing() = default;
Crossing(const Point& _p, const std::vector<Line> _lines)
{
p = _p;
lines = _lines;
}
};
// returns index of the line with a direction
auto get_line = [] (const eLineDirection& direction, const std::vector<Line>& lines) -> const Line* {
for (size_t i = 0; i < lines.size(); ++i)
if (lines[i].direction == direction)
return &lines[i];
return nullptr;
};
// goes into direction through crossings (like a graph).
// add used shapes into out_indexes to remove it later
auto go_direction_until = [&get_line] (Crossing* crossing,
const Point& p,
const eLineDirection& direction,
std::set<size_t>& out_indexes) -> bool {
// difference depends on direction
auto diff = [&crossing, &p, &direction] () -> double {
if (direction == eLineDirection::ldRight) return p.x - crossing->p.x;
if (direction == eLineDirection::ldLeft) return crossing->p.x - p.x;
if (direction == eLineDirection::ldBot) return p.y - crossing->p.y;
if (direction == eLineDirection::ldTop) return crossing->p.y - p.y;
return 0;
};
while (diff() > c_dMAX_TABLE_LINE_WIDTH_MM)
{
auto curr_line = get_line(direction, crossing->lines);
if (!curr_line)
return false;
out_indexes.insert(curr_line->shape_index);
crossing = curr_line->crossing;
if (fabs(diff()) < c_dMAX_TABLE_LINE_WIDTH_MM)
return true;
}
return false;
};
// vector contains ptrs for easy exist-check
std::vector<std::shared_ptr<Crossing>> crossings;
auto find_crossing = [&crossings] (const Point& p) -> Crossing* {
for (auto& crossing : crossings)
{
if (!crossing)
continue;
if (fabs(crossing->p.x - p.x) < c_dMAX_TABLE_LINE_WIDTH_MM &&
fabs(crossing->p.y - p.y) < c_dMAX_TABLE_LINE_WIDTH_MM)
return crossing.get();
}
return nullptr;
};
auto precise_crossing_p = [] (Crossing* cr, const Point& p, const eLineDirection& direction) {
if (cr->lines.size() == 1)
{
switch (cr->lines[0].direction)
{
case eLineDirection::ldLeft:
case eLineDirection::ldRight:
if (direction == eLineDirection::ldLeft || direction == eLineDirection::ldRight)
cr->p.x = (cr->p.x + p.x) / 2;
else
cr->p.x = p.x;
break;
case eLineDirection::ldBot:
case eLineDirection::ldTop:
if (direction == eLineDirection::ldBot || direction == eLineDirection::ldTop)
cr->p.y = (cr->p.y + p.y) / 2;
else
cr->p.y = p.y;
break;
default:
break;
}
}
};
// check and adds points
auto add_crossings = [&precise_crossing_p, &crossings, &find_crossing, this] (const Point& p1, const Point& p2, size_t index) {
Crossing* crossing1 = find_crossing(p1);
Crossing* crossing2 = find_crossing(p2);
eLineDirection direction12;
eLineDirection direction21;
if (fabs(p1.y - p2.y) < c_dMAX_TABLE_LINE_WIDTH_MM)
{
direction12 = p1.x > p2.x ? eLineDirection::ldLeft : eLineDirection::ldRight;
direction21 = p1.x < p2.x ? eLineDirection::ldLeft : eLineDirection::ldRight;
}
else if (fabs(p1.x - p2.x) < c_dMAX_TABLE_LINE_WIDTH_MM)
{
direction12 = p1.y > p2.y ? eLineDirection::ldTop : eLineDirection::ldBot;
direction21 = p1.y < p2.y ? eLineDirection::ldTop : eLineDirection::ldBot;
}
// add empty crossing if no exists
if (!crossing1)
{
Crossing cr;
cr.p = p1;
crossings.push_back(std::make_shared<Crossing>(cr));
crossing1 = crossings.back().get();
}
if (!crossing2)
{
Crossing cr;
cr.p = p2;
crossings.push_back(std::make_shared<Crossing>(cr));
crossing2 = crossings.back().get();
}
auto curr_crossing_eq = [&crossing1] (const Line& line) -> bool {
return line.crossing == crossing1;
};
if (std::find_if(crossing2->lines.begin(), crossing2->lines.end(), curr_crossing_eq) == crossing2->lines.end())
{
precise_crossing_p(crossing2, p2, direction21);
Line line {crossing1, index, direction21};
crossing2->lines.push_back(std::move(line));
}
auto prev_crossing_eq = [&crossing2] (const Line& line) -> bool {
return line.crossing == crossing2;
};
if (std::find_if(crossing1->lines.begin(), crossing1->lines.end(), prev_crossing_eq) == crossing1->lines.end())
{
precise_crossing_p(crossing1, p1, direction12);
Line line {crossing2, index, direction12};
crossing1->lines.push_back(std::move(line));
}
};
// 2 main cases
// 1. lines of tables as a big rectangles with lines (onlyoffice), work with path commands
// 2. lines of tables as a small rectangels for a single line (adobe), work with entire shape
// also word -> pdf adobe sets points as crossings of the table lines, so we can use it
// check for adobe points
std::vector<std::pair<const Crossing*, size_t>> points_delete_later;
for (size_t i = 0; i < m_arShapes.size(); ++i)
{
auto& shape = m_arShapes[i];
if (!shape || shape->m_eGraphicsType != eGraphicsType::gtRectangle || shape->m_pImageInfo != nullptr)
continue;
// possible point of crossing in a adobe table
if (shape->m_dWidth < c_dMAX_TABLE_LINE_WIDTH_MM && shape->m_dHeight < c_dMAX_TABLE_LINE_WIDTH_MM)
{
Crossing cr;
cr.p.x = shape->m_dLeft + shape->m_dWidth / 2;
cr.p.y = shape->m_dTop + shape->m_dHeight;
auto cr_ptr = std::make_shared<Crossing>(cr);
crossings.push_back(cr_ptr);
points_delete_later.push_back({cr_ptr.get(), i});
}
}
for (size_t i = 0; i < m_arShapes.size(); ++i)
{
auto& shape = m_arShapes[i];
if (!shape || shape->m_eGraphicsType != eGraphicsType::gtRectangle || shape->m_pImageInfo != nullptr)
continue;
bool is_done = false;
if (shape->m_eSimpleLineType == eSimpleLineType::sltUnknown)
{
// possible point of crossing in a adobe table
if (shape->m_dWidth < c_dMAX_TABLE_LINE_WIDTH_MM && shape->m_dHeight < c_dMAX_TABLE_LINE_WIDTH_MM)
{
is_done = true;
}
// vertical line
else if (shape->m_dWidth < c_dMAX_TABLE_LINE_WIDTH_MM && shape->m_dHeight > c_dMAX_TABLE_LINE_WIDTH_MM)
{
Point p1(shape->m_dLeft + shape->m_dWidth / 2, shape->m_dTop);
Point p2(shape->m_dLeft + shape->m_dWidth / 2, shape->m_dBot);
add_crossings(p1, p2, i);
is_done = true;
}
// horizontal line
else if (shape->m_dWidth > c_dMAX_TABLE_LINE_WIDTH_MM && shape->m_dHeight < c_dMAX_TABLE_LINE_WIDTH_MM)
{
Point p1(shape->m_dLeft, shape->m_dTop + shape->m_dHeight / 2);
Point p2(shape->m_dRight, shape->m_dTop + shape->m_dHeight / 2);
add_crossings(p1, p2, i);
is_done = true;
}
}
if (is_done)
continue;
Point prev {};
for (const auto& command : shape->m_oVector.GetData())
{
if (!command.points.empty())
{
if (command.type == CVectorGraphics::ePathCommandType::pctLine)
{
const auto& curr = command.points.back();
// pure vertical / horizontal lines only
// not small lines
if (fabs(prev.x - curr.x) > c_dMAX_TABLE_LINE_WIDTH_MM && fabs(prev.y - curr.y) > c_dMAX_TABLE_LINE_WIDTH_MM ||
(fabs(prev.x - curr.x) < c_dMAX_TABLE_LINE_WIDTH_MM && fabs(prev.y - curr.y) < c_dMAX_TABLE_LINE_WIDTH_MM))
{
prev = curr;
continue;
}
add_crossings(prev, curr, i);
}
prev = command.points.back();
}
}
}
// remove adobe points line crossing shapes if used
for (auto& cr : points_delete_later)
if (!cr.first->lines.empty())
m_arShapes[cr.second] = nullptr;
// remove empty crossings
for (auto& cr : crossings)
if (cr && cr->lines.empty())
cr = nullptr;
auto cr_right = MoveNullptr(crossings.begin(), crossings.end());
crossings.erase(cr_right, crossings.end());
// sorting guarantee creating cell once (by taking second cross j > i)
std::sort(crossings.begin(), crossings.end(), [] (const std::shared_ptr<Crossing>& c1, const std::shared_ptr<Crossing>& c2) {
if (fabs(c1->p.y - c2->p.y) < c_dMAX_TABLE_LINE_WIDTH_MM)
return c1->p.x < c2->p.x;
return c1->p.y < c2->p.y;
});
std::vector<graphical_cell_ptr_t> graphical_cells;
std::map<size_t, bool> remove_later;
for (size_t i = 0; i < crossings.size(); ++i)
{
for (size_t j = i + 1; j < crossings.size(); ++j)
{
const auto& cr_first = crossings.at(i);
const auto& cr_second = crossings.at(j);
// first should be top left corner
// and second right bot (not the same line ofc)
if (fabs(cr_first->p.x - cr_second->p.x) < c_dMAX_TABLE_LINE_WIDTH_MM ||
cr_first->p.x > cr_second->p.x ||
fabs(cr_first->p.y - cr_second->p.y) < c_dMAX_TABLE_LINE_WIDTH_MM ||
cr_first->p.y > cr_second->p.y)
continue;
const Line* cr_f_top = get_line(eLineDirection::ldRight, cr_first->lines);
const Line* cr_f_left = get_line(eLineDirection::ldBot, cr_first->lines);
const Line* cr_s_bot = get_line(eLineDirection::ldLeft, cr_second->lines);
const Line* cr_s_right = get_line(eLineDirection::ldTop, cr_second->lines);
if (!cr_f_top || !cr_f_left || !cr_s_bot || !cr_s_right)
continue;
std::set<size_t> shape_indexes;
bool is_connected = go_direction_until(cr_first.get(), cr_second->p, eLineDirection::ldRight, shape_indexes);
is_connected &= go_direction_until(cr_first.get(), cr_second->p, eLineDirection::ldBot, shape_indexes);
is_connected &= go_direction_until(cr_second.get(), cr_first->p, eLineDirection::ldLeft, shape_indexes);
is_connected &= go_direction_until(cr_second.get(), cr_first->p, eLineDirection::ldTop, shape_indexes);
if (!is_connected)
continue;
for (const auto& index : shape_indexes)
remove_later[index] = true;
auto graphical_cell = std::make_shared<CGraphicalCell>();
graphical_cell->m_dLeft = cr_first->p.x;
graphical_cell->m_dRight = cr_second->p.x;
graphical_cell->m_dTop = cr_first->p.y;
graphical_cell->m_dBot = cr_second->p.y;
graphical_cell->m_dWidth = graphical_cell->m_dRight - graphical_cell->m_dLeft;
graphical_cell->m_dHeight = graphical_cell->m_dBot - graphical_cell->m_dTop;
graphical_cells.push_back(std::move(graphical_cell));
break;
}
}
return graphical_cells;
}
CPage::shape_ptr_t CPage::CreateSingleLineShape(text_line_ptr_t& pLine)
{
auto pParagraph = std::make_shared<CParagraph>();
@ -2766,6 +2190,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

@ -82,7 +82,7 @@ namespace NSDocxRenderer
bool m_bUseDefaultFont {false};
bool m_bWriteStyleRaw {false};
bool m_bCollectMetaInfo {false};
bool m_bIsBuildTables {false};
bool m_bIsBuildTables {true};
bool m_bIsLuminosityShapesFiled{false};
bool m_bFontSubstitution {false};
bool m_bFirstParagraphLineCorrection{false};
@ -133,15 +133,8 @@ namespace NSDocxRenderer
using base_item_ptr_t = std::shared_ptr<CBaseItem>;
using ooxml_item_ptr_t = std::shared_ptr<IOoxmlItem>;
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
using table_ptr_t = std::shared_ptr<CTable>;
using graphical_cell_ptr_t = std::shared_ptr<CGraphicalCell>;
using text_cell_ptr_t = std::shared_ptr<CTextCell>;
using cell_ptr_t = std::shared_ptr<CTable::CCell>;
using text_line_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTextLine>>;
using text_cell_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTextCell>>;
using cell_group_ptr_t = std::shared_ptr<CBaseItemGroup<CTable::CCell>>;
// returns std::vector of conts with diac. symbols and remove it from m_arConts
std::vector<cont_ptr_t> MoveDiacriticalSymbols();
@ -155,15 +148,6 @@ namespace NSDocxRenderer
// returns std::vector of paragraphs builded from m_arTextLines
std::vector<paragraph_ptr_t> BuildParagraphs(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
// return groups of text cells
std::vector<text_cell_group_ptr_t> BuildTextCellGroups(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
// returns std::vector of tables builded from shapes and paragraphes
std::vector<table_ptr_t> BuildTables(const std::vector<text_line_group_ptr_t>& arTextLineGroups);
// return std::vector of graphical cells (from shapes)
std::vector<graphical_cell_ptr_t> BuildGraphicalCells();
// returns std::vector of base items builded from m_arParagraphs
std::vector<ooxml_item_ptr_t> BuildOutputObjects();
@ -257,10 +241,12 @@ namespace NSDocxRenderer
CContTextBuilder m_oContBuilder;
CHorVerLinesCollector m_oHorVerLinesCollector;
ITableBuilder* m_pTableBuilder{nullptr};
std::vector<shape_ptr_t> m_arShapes;
std::vector<text_line_ptr_t> m_arTextLines;
std::vector<paragraph_ptr_t> m_arParagraphs;
std::vector<table_ptr_t> m_arTables;
std::vector<ooxml_item_ptr_t> m_arTables;
std::vector<ooxml_item_ptr_t> m_arOutputObjects;
std::vector<std::wstring> m_arCompleteObjectsXml;

View File

@ -84,18 +84,18 @@ namespace NSDocxRenderer
oWriter.WriteString(L"/>"); // end of w:spacing
oWriter.WriteString(L"<w:ind");
if (m_dLeftBorder > 0)
{
//if (m_dLeftBorder > 0)
//{
oWriter.WriteString(L" w:left=\"");
oWriter.AddInt(static_cast<int>(m_dLeftBorder * c_dMMToDx));
oWriter.WriteString(L"\"");
}
if (m_dRightBorder > 0)
{
//}
//if (m_dRightBorder > 0)
//{
oWriter.WriteString(L" w:right=\"");
oWriter.AddInt(static_cast<int>(m_dRightBorder * c_dMMToDx)); // here m_dRight is the distance from the right edge
oWriter.WriteString(L"\"");
}
//}
if (m_bIsNeedFirstLineIndent)
{
if (m_dFirstLine > 0)

View File

@ -1,265 +1,44 @@
/*
* Copyright (C) Ascensio System SIA, 2009-2026
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation, together with the
* additional terms provided in the LICENSE file.
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA by email at info@onlyoffice.com
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
* LV-1050, Latvia, European Union.
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified versions of the Program
* are required to display Appropriate Legal Notices in accordance with
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* No trademark rights are granted under this License.
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All non-code elements of the Product, including illustrations,
* icon sets, and technical writing content, are licensed under the
* Creative Commons Attribution-ShareAlike 4.0 International License:
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
* This license applies only to such non-code elements and does not
* modify or replace the licensing terms applicable to the Program's
* source code, which remains licensed under the GNU Affero General
* Public License v3.
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#include "Table.h"
#include "../../resources/SingletonTemplate.h"
#include "../../resources/utils.h"
namespace NSDocxRenderer
{
CTable::CCell::CCell(const CCell& other)
namespace NSTables
{
*this = other;
}
void CTable::CCell::Clear()
{
m_arParagraphs.clear();
}
void CTable::CCell::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
oWriter.WriteString(L"<w:tc>");
oWriter.WriteString(L"<w:tcPr>");
oWriter.WriteString(L"<w:tcW w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
oWriter.WriteString(L"\" w:type=\"dxa\"/>");
oWriter.WriteString(L"<w:gridSpan w:val=\"");
oWriter.AddUInt(m_nGridSpan);
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"<w:vMerge w:val=\"");
switch (m_eVMerge) {
case eVMerge::vmContinue:
oWriter.WriteString(L"continue");
break;
case eVMerge::vmRestart:
oWriter.WriteString(L"restart");
break;
default:
break;
}
oWriter.WriteString(L"\"/>");
oWriter.WriteString(L"<w:tcBorders>");
auto write_border = [&oWriter] (const CBorder& border, const std::wstring& prefix) {
oWriter.WriteString(L"<w:");
oWriter.WriteString(prefix);
oWriter.WriteString(L" w:val=");
oWriter.WriteString(SingletonInstance<LinesTable>().ConvertLineToString(border.lineType));
oWriter.WriteString(L" w:sz=\"");
oWriter.AddUInt(static_cast<unsigned int>(border.dWidth * c_dMMToPt * 8));
oWriter.WriteString(L"\" w:space=\"");
oWriter.AddUInt(static_cast<unsigned int>(border.dSpacing * c_dMMToPt));
oWriter.WriteString(L"\" w:color=\"");
oWriter.WriteHexInt3(ConvertColorBGRToRGB(border.lColor));
oWriter.WriteString(L"\" />");
};
write_border(m_oBorderTop, L"top");
write_border(m_oBorderBot, L"bottom");
write_border(m_oBorderLeft, L"left");
write_border(m_oBorderRight, L"right");
oWriter.WriteString(L"</w:tcBorders>");
oWriter.WriteString(L"</w:tcPr>");
for (const auto& p : m_arParagraphs)
p->ToXml(oWriter);
oWriter.WriteString(L"</w:tc>");
}
void CTable::CCell::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::CCell::ToBin(NSWasm::CData& oWriter) const
{
}
CTable::CCell& CTable::CCell::operator=(const CCell& other)
{
CBaseItem::operator=(other);
m_oBorderBot = other.m_oBorderBot;
m_oBorderTop = other.m_oBorderTop;
m_oBorderLeft = other.m_oBorderLeft;
m_oBorderRight = other.m_oBorderRight;
m_nGridSpan = other.m_nGridSpan;
m_eVMerge = other.m_eVMerge;
m_arParagraphs.clear();
for (const auto& p : other.m_arParagraphs)
m_arParagraphs.push_back(p);
return *this;
}
void CTable::CCell::AddParagraph(const paragraph_ptr_t& pParagraph)
{
m_arParagraphs.push_back(pParagraph);
}
void CTable::CRow::Clear()
{
m_arCells.clear();
}
void CTable::CRow::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
oWriter.WriteString(L"<w:tr>");
oWriter.WriteString(L"<w:trPr>");
oWriter.WriteString(L"<w:trHeight w:val=\"");
oWriter.AddUInt(static_cast<unsigned int>(m_dHeight * c_dMMToDx));
oWriter.WriteString(L"\" w:hRule=\"exact\"/>");
oWriter.WriteString(L"</w:trPr>");
for (const auto& c : m_arCells)
c->ToXml(oWriter);
oWriter.WriteString(L"</w:tr>");
}
void CTable::CRow::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::CRow::ToBin(NSWasm::CData& oWriter) const
{
}
void CTable::CRow::AddCell(const cell_ptr_t& pCell)
{
CBaseItem::RecalcWithNewItem(pCell.get());
m_arCells.push_back(pCell);
}
bool CTable::CRow::IsEmpty() const
{
return m_arCells.empty();
}
void CTable::Clear()
{
m_arRows.clear();
}
void CTable::ToXml(NSStringUtils::CStringBuilder& oWriter) const
{
oWriter.WriteString(L"<w:tbl>");
oWriter.WriteString(L"<w:tblPr>");
oWriter.WriteString(L"<w:tblpPr ");
oWriter.WriteString(L"w:horzAnchor=\"page\" w:vertAnchor=\"page\" w:tblpX=\"");
oWriter.AddInt64(static_cast<long long>(m_dLeft * c_dMMToDx));
oWriter.WriteString(L"\" w:tblpY=\"");
oWriter.AddInt64(static_cast<long long>(m_dTop * c_dMMToDx));
oWriter.WriteString(L"\" />");
oWriter.WriteString(L"<w:tblW w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(m_dWidth * c_dMMToDx));
oWriter.WriteString(L"\" w:type=\"dxa\"/>");
oWriter.WriteString(L"</w:tblPr>");
oWriter.WriteString(L"<w:tblGrid>");
for (const auto& gc : m_arGridCols)
ITableBuilder* Create()
{
oWriter.WriteString(L"<w:gridCol w:w=\"");
oWriter.AddUInt(static_cast<unsigned int>(gc * c_dMMToDx));
oWriter.WriteString(L"\" />");
return new ITableBuilder();
}
oWriter.WriteString(L"</w:tblGrid>");
for (const auto& r : m_arRows)
r->ToXml(oWriter);
oWriter.WriteString(L"</w:tbl>");
}
void CTable::ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const
{
}
void CTable::ToBin(NSWasm::CData& oWriter) const
{
}
void CTable::AddRow(const row_ptr_t& pRow)
{
CBaseItem::RecalcWithNewItem(pRow.get());
m_arRows.push_back(pRow);
}
void CTable::CalcGridCols()
{
std::vector<double> cells_left;
auto add_if_no_exists = [&cells_left] (double val) {
bool exists = false;
for (const auto& curr : cells_left)
{
if (fabs(curr - val) < c_dMAX_TABLE_LINE_WIDTH_MM)
{
exists = true;
break;
}
}
if (!exists)
cells_left.push_back(val);
};
double right = 0;
for (const auto& row : m_arRows)
{
for (const auto& cell : row->m_arCells)
{
right = std::max(right, cell->m_dRight);
add_if_no_exists(cell->m_dLeft);
}
}
std::sort(cells_left.begin(), cells_left.end(), std::less<double>{});
for (size_t i = 0; i < cells_left.size() - 1; ++i)
m_arGridCols.push_back(cells_left[i + 1] - cells_left[i]);
m_arGridCols.push_back(right - cells_left.back());
}
bool CTable::IsEmpty() const
{
return m_arRows.empty();
}
void CTextCell::AddTextLine(const std::shared_ptr<CTextLine>& pTextLine)
{
CBaseItem::RecalcWithNewItem(pTextLine.get());
m_arTextLines.push_back(pTextLine);
}
} // namespace NSDocxRenderer
}

View File

@ -40,119 +40,52 @@
#include "BaseItem.h"
#include "Paragraph.h"
#include "Shape.h"
#include "../../resources/LinesTable.h"
namespace NSDocxRenderer
{
class CGraphicalCell;
class CTextCell;
class ITableBuilder
{
public:
using shape_ptr_t = std::shared_ptr<CShape>;
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
using ooxml_item_ptr_t = std::shared_ptr<IOoxmlItem>;
class CTable : public CBaseItem, public IOoxmlItem
ITableBuilder() = default;
~ITableBuilder() = default;
virtual void SetShapes(std::vector<shape_ptr_t>&& shapes)
{
public:
class CCell;
class CRow;
using cell_ptr_t = std::shared_ptr<CCell>;
using row_ptr_t = std::shared_ptr<CRow>;
using paragraph_ptr_t = std::shared_ptr<CParagraph>;
public:
class CCell : public CBaseItem, public IOoxmlItem
{
friend class CTable;
public:
struct CBorder
{
double dWidth{};
double dSpacing{};
long lColor{};
eLineType lineType{eLineType::ltNone};
};
enum class eVMerge
{
vmRestart,
vmContinue
};
CCell() = default;
CCell(const CCell& other);
virtual ~CCell() = default;
virtual void Clear();
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
CCell& operator=(const CCell& other);
void AddParagraph(const paragraph_ptr_t& pParagraph);
CBorder m_oBorderTop;
CBorder m_oBorderBot;
CBorder m_oBorderLeft;
CBorder m_oBorderRight;
unsigned int m_nGridSpan = 1;
eVMerge m_eVMerge = CTable::CCell::eVMerge::vmRestart;
std::vector<paragraph_ptr_t> m_arParagraphs;
};
class CRow : public CBaseItem, IOoxmlItem
{
friend class CTable;
public:
CRow() = default;
virtual ~CRow() = default;
virtual void Clear();
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void AddCell(const cell_ptr_t& pCell);
bool IsEmpty() const;
private:
std::vector<cell_ptr_t> m_arCells;
};
CTable() = default;
virtual ~CTable() = default;
virtual void Clear();
virtual void ToXml(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToXmlPptx(NSStringUtils::CStringBuilder& oWriter) const override final;
virtual void ToBin(NSWasm::CData& oWriter) const override final;
void AddRow(const row_ptr_t& pRow);
void CalcGridCols();
bool IsEmpty() const;
private:
std::vector<row_ptr_t> m_arRows;
std::vector<double> m_arGridCols;
};
class CGraphicalCell : public CBaseItem
m_arShapes = std::move(shapes);
}
virtual void SetParagraphs(std::vector<paragraph_ptr_t>&& paragraphs)
{
public:
// realization
};
m_arParagraphs = paragraphs;
}
class CTextCell : public CBaseItem
virtual std::vector<shape_ptr_t>&& ReturnShapes()
{
public:
void AddTextLine(const std::shared_ptr<CTextLine>& pTextLine);
std::vector<std::shared_ptr<CTextLine>> m_arTextLines;
return std::move(m_arShapes);
}
virtual std::vector<paragraph_ptr_t>&& ReturnParagraphs()
{
return std::move(m_arParagraphs);
}
virtual std::vector<ooxml_item_ptr_t>&& GetTables()
{
return std::move(m_arTables);
}
double m_dMinPossibleTop = std::numeric_limits<double>::lowest();
double m_dMinPossibleLeft = std::numeric_limits<double>::lowest();
public:
virtual void BuildGraphicallCells() noexcept {};
virtual void BuildTables() noexcept {};
double m_dMaxPossibleBot = std::numeric_limits<double>::max();
double m_dMaxPossibleRight = std::numeric_limits<double>::max();
};
private:
std::vector<ooxml_item_ptr_t> m_arTables;
std::vector<shape_ptr_t> m_arShapes;
std::vector<paragraph_ptr_t> m_arParagraphs;
};
namespace NSTables {
ITableBuilder* Create();
}
} // namespace NSDocxRenderer

View File

@ -44,6 +44,8 @@
#define USING_DELETE_DUPLICATING_CONTS 0 // 0 - all duplicate lines become shapes, 1 - duplicate lines are deleted
// #define USE_DEFAULT_FONT_TO_RECALC
const double c_dCOMPARE_EPSILON = 0.1;
const double c_dDpiX = 72.0;
const double c_dDpiY = 72.0;
@ -68,9 +70,10 @@ const double c_dERROR_OF_PARAGRAPH_BORDERS_MM = 1.0;
const double c_dCENTER_POSITION_ERROR_MM = 1.5;
const double c_dTHE_STRING_X_PRECISION_MM = 0.5;
const double c_dERROR_FOR_TEXT_WITH_GRAPHICS_MM = 0.1;
const double c_dGRAPHICS_ERROR_MM = 0.5;
const double c_dGRAPHICS_ERROR_MM = 1.0;
const double c_dMAX_TABLE_LINE_WIDTH_MM = 2.2;
const double c_dMAX_TABLE_CELL_DIFF_MM = 7.0;
const double c_dMIN_TABLE_DIFF_MM = 0.3;
const double c_dGRAPHICS_ERROR_IN_LINES_MM = 0.3;
const double c_dMAX_LINE_HEIGHT_MM = 2.5;
const double c_dMAX_LINE_WITH_TEXT_ERROR_MM = 2.5;
@ -85,6 +88,8 @@ const double c_dAVERAGE_SPACE_WIDTH_COEF = 0.9;
const double c_dSPACE_WIDTH_COEF = 0.39;
const double c_dMIN_ROTATION = 0.01;
const double c_dMAX_FIRST_LINE_INDENT = 20.0;
const double c_dMIN_RIGHT_MARGIN = 0.4;
constexpr double c_dSTANDART_TABLE_SPACING_MM = 108.0 / c_dMMToDx;
const UINT c_iWhiteColor = 0xFFFFFF;
const UINT c_iBlackColor = 0x000000;

View File

@ -37,6 +37,7 @@
#include <type_traits>
#include <limits>
#include <algorithm>
#include <functional>
#include "../../../DesktopEditor/common/Types.h"
@ -71,3 +72,11 @@ bool CmpOrEqual(const T& val1,
{
return std::abs(val1 - val2) < eps || cmp(val1, val2);
}
template <typename T>
std::function<bool(const T&, const T&)> makeEqualComp(T eps)
{
return [eps](const T& a, const T& b) -> bool {
return std::abs(a - b) < eps;
};
}

View File

@ -38,6 +38,10 @@
#include <string>
#include "../DesktopEditor/common/StringBuilder.h"
#include "../DesktopEditor/common/ProcessEnv.h"
#include "../DesktopEditor/common/Path.h"
#include <boost/algorithm/string/predicate.hpp>
namespace HTML
{
@ -94,6 +98,31 @@ inline void WriteToStringBuilder(NSStringUtils::CStringBuilder& oSrcStringBuilde
}
}
inline bool GetStatusUsingExternalLocalFiles()
{
if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP))
return NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP);
return true;
}
inline bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsSrcPath, const std::wstring& wsCorePath, bool bIsAllowExternalLocalFiles)
{
if (bIsAllowExternalLocalFiles)
return true;
if (!wsCorePath.empty())
{
const std::wstring wsFullPath = NSSystemPath::ShortenPath(NSSystemPath::Combine(wsSrcPath, wsPath));
return boost::starts_with(wsFullPath, wsCorePath);
}
if (wsPath.length() >= 3 && L"../" == wsPath.substr(0, 3))
return false;
return true;
}
}
#endif // COMMON_H

File diff suppressed because it is too large Load Diff

View File

@ -36,8 +36,6 @@
#ifndef HTMLREADER_H
#define HTMLREADER_H
#include <unordered_map>
#include "../Common/3dParty/html/css/src/CCssCalculator.h"
#include "../DesktopEditor/xml/include/xmlutils.h"
@ -48,11 +46,12 @@
#include "Tags/HTMLTags.h"
#include "Table.h"
#include <set>
namespace HTML
{
class CHTMLReader
{
XmlUtils::CXmlLiteReader m_oLightReader; // SAX Reader
NSCSS::CCssCalculator m_oCSSCalculator; // CSS calculator
bool m_bIsTempDirOwner;
@ -64,7 +63,11 @@ class CHTMLReader
IWriter *m_pWriter;
std::unordered_map<UINT, std::shared_ptr<ITag>> m_mTags;
CTableElement* m_pTableElement; // Table Converter
std::set<std::wstring> m_arStopTags;
std::map<int, std::shared_ptr<ITag>> m_mTags;
public:
CHTMLReader();
~CHTMLReader();
@ -87,10 +90,10 @@ public:
NSCSS::CCssCalculator* GetCSSCalculator();
private:
void Clear();
void InitOOXMLTags(THTMLParameters* pParametrs = nullptr);
void InitMDTags(TMarkdownParameters* pParametrs = nullptr);
bool InitOOXMLTags(THTMLParameters* pParametrs = nullptr);
bool InitMDTags(TMarkdownParameters* pParametrs = nullptr);
bool IsHTML();
bool IsHTML(XmlUtils::CXmlLiteReader& oReader);
typedef std::function<bool(const std::wstring&, XmlUtils::CXmlLiteReader&)> Convert_Func;
@ -99,29 +102,28 @@ private:
bool Convert(const std::wstring& wsPath, Convert_Func Convertation);
void ReadStyle();
void ReadStyle2();
void ReadStyleFromNetwork();
void ReadStyle(XmlUtils::CXmlLiteReader& oReader);
void ReadStyle2(XmlUtils::CXmlLiteReader& oReader);
void ReadStyleFromNetwork(XmlUtils::CXmlLiteReader& oReader);
void ReadDocument();
void ReadHead();
void ReadBody();
void ReadDocument(XmlUtils::CXmlLiteReader& oReader);
void ReadHead(XmlUtils::CXmlLiteReader& oReader);
void ReadBody(XmlUtils::CXmlLiteReader& oReader);
bool ReadStream(std::vector<NSCSS::CNode>& arSelectors, bool bInsertEmptyP = false);
bool ReadInside(std::vector<NSCSS::CNode>& arSelectors);
bool ReadStream(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors, bool bInsertEmptyP = false);
bool ReadInside(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors);
bool ReadText(std::vector<NSCSS::CNode>& arSelectors);
bool ReadText(XmlUtils::CXmlLiteReader& oReader, 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(XmlUtils::CXmlLiteReader& oReader, 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);
bool ReadEmptyTag(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors, std::shared_ptr<ITag> pTag);
bool ReadTag(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors, std::shared_ptr<ITag> pTag);
void GetSubClass(std::vector<NSCSS::CNode>& arSelectors);
std::shared_ptr<ITag> GetTag(int nTag);
void AddStopTag(const std::wstring& wsTag);
void ClearStopTags();
};
}

File diff suppressed because it is too large Load Diff

View File

@ -36,10 +36,12 @@
#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 "../DesktopEditor/xml/include/xmlutils.h"
#include "Writers/IWriter.h"
#include "src/StringFinder.h"
#include <stack>
#include <vector>
namespace HTML
@ -47,244 +49,330 @@ namespace HTML
#define MAXCOLUMNSINTABLE 63
#define MAXROWSINTABLE 32767
enum class ERowParseMode
struct TCurentTablePosition
{
Header,
Body,
Foother
size_t m_unRowIndex;
size_t m_unColumnIndex;
size_t m_unStartRowIndex;
size_t m_unStartColumnIndex;
TCurentTablePosition(size_t unRowIndex, size_t unColumnIndex, size_t unStartRowIndex, size_t unStartColumnIndex)
: m_unRowIndex{unRowIndex}, m_unColumnIndex{unColumnIndex},
m_unStartRowIndex{unStartRowIndex}, m_unStartColumnIndex{unStartColumnIndex}
{}
};
enum class ERowPosition
enum class ETableElement
{
First,
Middle,
Last
FillingCell,
Cell,
FlatTable,
TableContainer
};
struct TTableRowStyle
// !TODO!:: At the moment, I don't really like the implementation where there is a table inside a cell,
// or when there are multiple nested tables inside a cell
// Perhaps it's worth doing it as follows:
// ITableCell -> CTableCell (A regular cell that does not contain nested tables)
// -> CTableCellContainer (Stores anything (like default, but has a container for storing nested tables))
class ITableElementCell
{
UINT m_unMaxIndex;
UINT m_unMaxHeight;
bool m_bIsHeader;
size_t m_unColspan;
protected:
ITableElementCell(size_t unColspan);
public:
virtual ~ITableElementCell() = default;
TTableRowStyle();
virtual ETableElement GetType() const = 0;
bool Empty() const;
void SetColspan(size_t unColspan);
size_t GetColspan() const;
};
struct TTableCellStyle
class CTableElementCell : public ITableElementCell
{
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;
ETableElement m_eType;
std::wstring m_wsHAlign;
std::wstring m_wsVAlign;
protected:
CTableElementCell(bool bIsFilling, size_t unColspan);
public:
virtual ~CTableElementCell();
TTableCellStyle();
ETableElement GetType() const override;
bool Empty();
void Copy(const TTableCellStyle* pTableCellStyle);
void IsFlatTable();
TTableCellStyle& operator+=(const TTableCellStyle* pCellStyle);
static CTableElementCell* CreateCell(const size_t& unColspan = 1);
static CTableElementCell* CreateFillingCell(const size_t& unColspan = 1);
};
class CStorageTable;
class ITag;
class IWriter;
class CStorageTableCell
struct TExternalTableData
{
typedef std::function<bool(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors)> FuncReadStream;
typedef std::function<void(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors)> FuncGetSubClass;
typedef std::function<bool(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors)> FuncReadInside;
typedef std::function<void(const std::wstring& wsTag)> FuncAddStopTag;
typedef std::function<void()> FuncClearStopTags;
FuncReadStream ReadStream;
FuncGetSubClass GetSubClass;
FuncReadInside ReadInside;
FuncAddStopTag AddStopTag;
FuncClearStopTags ClearStopTags;
IWriter* m_pWriter{nullptr};
};
typedef std::vector<ITableElementCell*> Row;
typedef std::vector<Row> Table;
class IWriter;
class CTableMatrix
{
public:
CStorageTableCell();
CStorageTableCell(UINT unColspan, UINT unRowspan, bool bIsMerged, bool bIsEmpty);
CStorageTableCell(CStorageTableCell& oCell);
CTableMatrix();
virtual ~CTableMatrix();
bool Empty() const;
bool Merged() const;
CStorageTableCell* Copy();
void Clear();
static CStorageTableCell* CreateEmpty(UINT unColspan = 1, bool m_bIsMerged = false, const TTableCellStyle* pStyle = NULL);
static CStorageTableCell* CreateEmpty(const TTableCellStyle* pStyle);
bool SetCell(size_t unRowIndex, size_t unColumnIndex, ITableElementCell* pCell, bool bAutoClean = true);
void SetColspan(UINT unColspan, UINT unCurrentIndex);
UINT GetColspan() const;
void NormalizeNumberColumns(size_t unNumberColumns);
void SetRowspan(UINT unRowspan);
UINT GetRowspan() const;
bool IsFillingCell(size_t unRowIndex, size_t unColumnIndex) const;
bool IsNotNullCell(size_t unRowIndex, size_t unColumnIndex) const;
NSStringUtils::CStringBuilder* GetData();
size_t GetRowSize() const;
size_t GetColumnSize() const;
const TTableCellStyle* GetStyles() const;
TTableCellStyle* GetStyles();
const Table& GetMatrixCells() const;
Table& GetMatrixCells();
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;
const ITableElementCell* GetCell(size_t unRowIndex, size_t unColumnIndex) const;
ITableElementCell* GetCell(size_t unRowIndex, size_t unColumnIndex);
protected:
Table m_arCells;
};
class CTableCol
{
public:
CTableCol(UINT unSpan);
CTableCol(const NSCSS::CNode& oTableColNode);
CTableCol(NSCSS::CNode& oTableColNode);
~CTableCol();
UINT GetSpan() const;
TTableCellStyle* GetStyle();
const TTableCellStyle* GetStyle() const;
const NSCSS::CCompiledStyle* GetStyle() const;
private:
UINT m_unSpan;
TTableCellStyle m_oStyle;
NSCSS::CCompiledStyle* m_pStyle;
};
class CTableColgroup
{
public:
CTableColgroup(NSCSS::CNode& oTableColgroupNode);
CTableColgroup(const NSCSS::CNode& oTableColgroupNode);
~CTableColgroup();
bool Empty() const;
void AddCol(CTableCol* pCol);
UINT GetTotalSpans() const;
const std::vector<CTableCol*>& GetCols() const;
const NSCSS::CCompiledStyle* GetColStyle(size_t unIndex) const;
private:
std::vector<CTableCol*> m_arCols;
UINT m_unWidth;
UINT m_unTotalSpans;
};
//Required table styles
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
class CTableElement
{
protected:
CTableElement(TExternalTableData &oExternalData);
public:
CStorageTable();
~CStorageTable();
virtual ~CTableElement();
CStorageTableRow* operator[](UINT unIndex);
void Clear();
bool Empty() const;
bool HaveCaption();
bool HaveColgroups() const;
bool HaveHeader() const;
UINT GetRowCount() const;
const TTableStyles& GetTableStyles() const;
const TTableCellStyle* GetColStyle(UINT unColumnNumber) const;
bool HaveCaption() const;
void AddRows(std::vector<CStorageTableRow*>& m_arRows, ERowParseMode eParseMode = ERowParseMode::Body);
void AddRow(CStorageTableRow* pRow, ERowParseMode eParseMode = ERowParseMode::Body);
virtual bool PreParse(XmlUtils::CXmlLiteReader& oReader) = 0;
virtual void Normalize() = 0;
virtual bool Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) = 0;
protected:
CTableMatrix m_oHeader;
CTableMatrix m_oBody;
CTableMatrix m_oFoother;
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:: refactor to 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;
XmlString *m_pCaption;
std::vector<CTableColgroup*> m_arColgroups;
TTableStyles m_oStyles;
TExternalTableData m_oExternalData;
UINT m_unMaxColumns;
const NSCSS::CCompiledStyle* GetColStyle(size_t unColIndex) const;
virtual bool ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) = 0;
virtual bool ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector<CTableColgroup*>& arColgroups) = 0;
template<typename T>
inline bool ParseTable(XmlUtils::CXmlLiteReader& oReader, T* pTable);
template<typename T>
inline bool ParseMatrix(XmlUtils::CXmlLiteReader& oReader, CTableMatrix* pMatrix, size_t& unRowIndex, size_t& unColumnIndex);
};
class CTableContainer : public ITableElementCell
{
public:
CTableContainer();
virtual ~CTableContainer();
ETableElement GetType() const override;
void AddTable(CTableElement* pTable);
const std::vector<CTableElement*>& GetTables() const;
private:
std::vector<CTableElement*> m_arTables;
};
struct TTableData
{
CTableMatrix m_oHeader;
CTableMatrix m_oBody;
CTableMatrix m_oFoother;
XmlString *m_pCaption;
std::vector<CTableColgroup*> m_arColgroups;
};
template<typename T>
inline bool CTableElement::ParseTable(XmlUtils::CXmlLiteReader& oReader, T* pTable)
{
const int nDeath{oReader.GetDepth()};
std::wstring wsName;
while(oReader.ReadNextSiblingNode(nDeath))
{
wsName = oReader.GetName();
size_t unRowIndex{0}, unColumnIndex{0};
if(L"thead" == wsName)
ParseMatrix<T>(oReader, &pTable->m_oHeader, unRowIndex, unColumnIndex);
if(L"tbody" == wsName)
ParseMatrix<T>(oReader, &pTable->m_oBody, unRowIndex, unColumnIndex);
else if(L"tfoot" == wsName)
ParseMatrix<T>(oReader, &pTable->m_oFoother, unRowIndex, unColumnIndex);
else if (L"caption" == wsName)
ParseCaption(oReader, pTable->m_pCaption);
else if (L"colgroup" == wsName)
ParseColgroup(oReader, pTable->m_arColgroups);
}
return true;
}
template<typename T>
inline bool CTableElement::ParseMatrix(XmlUtils::CXmlLiteReader& oReader, CTableMatrix* pMatrix, size_t& unRowIndex, size_t& unColumnIndex)
{
const std::wstring wsElementName{oReader.GetName()};
if (L"table" == wsElementName)
{
T* pNewTable{new T(m_oExternalData)};
if (nullptr == pNewTable)
return false;
ITableElementCell* pTableElement{pMatrix->GetCell(unRowIndex - 1, unColumnIndex - 1)};
CTableContainer *pContainer{nullptr};
if (nullptr != pTableElement && ETableElement::TableContainer == pTableElement->GetType())
pContainer = dynamic_cast<CTableContainer*>(pTableElement);
else
{
pContainer = new CTableContainer();
pMatrix->SetCell(unRowIndex - 1, unColumnIndex - 1, pContainer);
}
if (nullptr == pContainer)
return false;
pContainer->AddTable(pNewTable);
ParseTable<T>(oReader, pNewTable);
}
else if (L"tr" == wsElementName)
{
const int nDepth{oReader.GetDepth()};
++unRowIndex;
unColumnIndex = 0;
while (oReader.ReadNextSiblingNode(nDepth))
{
if (L"td" != oReader.GetName() && L"th" != oReader.GetName())
continue;
ParseMatrix<T>(oReader, pMatrix, unRowIndex, unColumnIndex);
}
}
else if (L"td" == wsElementName || L"th" == wsElementName)
{
++unColumnIndex;
while (pMatrix->IsFillingCell(unRowIndex - 1, unColumnIndex - 1))
++unColumnIndex;
size_t unRowspan{1}, unColspan{1};
if (oReader.MoveToFirstAttribute())
{
do
{
if (L"rowspan" == oReader.GetName())
unRowspan = NSStringFinder::ToInt(oReader.GetText(), 1);
else if (L"colspan" == oReader.GetName())
unColspan = NSStringFinder::ToInt(oReader.GetText(), 1);
}while (oReader.MoveToNextAttribute());
oReader.MoveToElement();
}
if (!pMatrix->SetCell(unRowIndex - 1, unColumnIndex - 1, CTableElementCell::CreateCell(unColspan)))
return false;
for (size_t unRow = 1; unRow < unRowspan; ++unRow)
pMatrix->SetCell(unRowIndex + unRow - 1, unColumnIndex - 1, CTableElementCell::CreateFillingCell(unColspan));
const int nDepth{oReader.GetDepth()};
while (oReader.ReadNextSiblingNode(nDepth))
ParseMatrix<T>(oReader, pMatrix, unRowIndex, unColumnIndex);
}
else if (oReader.IsEmptyNode())
return false;
else
{
const int nDepth{oReader.GetDepth()};
while (oReader.ReadNextSiblingNode(nDepth))
ParseMatrix<T>(oReader, pMatrix, unRowIndex, unColumnIndex);
}
return true;
}
bool MoveToNextTableCell(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors, std::stack<int>& arDepths, TExternalTableData::FuncGetSubClass& GetSubClass);
}
#endif // TABLE_H

View File

@ -37,89 +37,56 @@
#define HTMLTAGS_H
#include "../Common/3dParty/html/css/src/CNode.h"
#include <boost/any.hpp>
namespace HTML
{
class ITag
{
public:
ITag() = default;
virtual ~ITag() = default;
virtual bool Open(const std::vector<NSCSS::CNode>& arSelectors, const boost::any& oExtraData = boost::any()) = 0;
virtual bool Open (const std::vector<NSCSS::CNode>& arSelectors) = 0;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
};
template<class Writer>
class IHTMLTag : public ITag
{
protected:
Writer* m_pWriter;
bool Valid() const
{
return nullptr != m_pWriter;
}
public:
IHTMLTag(Writer* pWriter)
: m_pWriter(pWriter) {};
virtual ~IHTMLTag() = default;
virtual bool Open (const std::vector<NSCSS::CNode>& arSelectors) = 0;
virtual void Close(const std::vector<NSCSS::CNode>& arSelectors) = 0;
};
#define CREATE_TAG(tag_name, writer)\
class C ## tag_name ## Tag : public IHTMLTag<writer>\
{\
public:\
C ## tag_name ## Tag(writer *pWriter)\
: IHTMLTag(pWriter) {}\
\
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override;\
void Close(const std::vector<NSCSS::CNode>& arSelectors) override;\
}
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) {};
CEmptyTag() = default;
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override { return true; }
void Close(const std::vector<NSCSS::CNode>& arSelectors) override {};
};
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

File diff suppressed because it is too large Load Diff

View File

@ -38,162 +38,59 @@
#include "HTMLTags.h"
#include "../Writers/MDWriter.h"
#include "../Table.h"
#include <map>
namespace HTML
{
template<>
class CAnchor<CMDWriter> : public CTag<CMDWriter>
#define CREATE_MD_TAG(class_name) CREATE_TAG(class_name##MD, CMDWriter)
CREATE_MD_TAG(Anchor);
CREATE_MD_TAG(Break);
CREATE_MD_TAG(Preformatted);
CREATE_MD_TAG(Header);
CREATE_MD_TAG(Image);
CREATE_MD_TAG(HorizontalRule);
CREATE_MD_TAG(Blockquote);
CREATE_MD_TAG(List);
CREATE_MD_TAG(ListElement);
CREATE_MD_TAG(Code);
void InitTagsForMD(std::map<int, std::shared_ptr<ITag>>& mTags, CMDWriter* pWriter);
struct TElementInfo
{
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;
size_t m_unRows;
size_t m_unColumns;
TElementInfo()
: m_unRows{0}, m_unColumns{0}
{}
TElementInfo(const size_t& unRows, const size_t& m_unColumns)
: m_unRows{unRows}, m_unColumns{m_unColumns}
{}
};
template<>
class CBold<CMDWriter> : public CTag<CMDWriter>
class CMarkdownTable : public CTableElement
{
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;
};
CMarkdownTable(TExternalTableData &oExternalData);
virtual ~CMarkdownTable();
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;
};
bool PreParse(XmlUtils::CXmlLiteReader& oReader) override;
void Normalize() override;
bool Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) override;
private:
bool ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) override;
bool ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector<CTableColgroup*>& arColgroups) 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;
};
bool ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, std::vector<NSCSS::CNode>& arSelectors, const Table& oMatrix, CMDWriter* pWriter, bool bIsHeader = false);
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;
static Table Flatten(Table&& srcTable);
static TElementInfo ComputeInfo(const ITableElementCell* pCell);
static TElementInfo ComputeInfo(const CTableElement* pTable);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -38,164 +38,132 @@
#include "HTMLTags.h"
#include "../Writers/OOXMLWriter.h"
#include "../Table.h"
#include <unordered_map>
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;
};
#define CREATE_OOXML_TAG(class_name) CREATE_TAG(class_name##OOXML, COOXMLWriter)
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;
};
CREATE_OOXML_TAG(Anchor);
CREATE_OOXML_TAG(Abbr);
CREATE_OOXML_TAG(Break);
CREATE_OOXML_TAG(Font);
CREATE_OOXML_TAG(Input);
CREATE_OOXML_TAG(BaseFont);
CREATE_OOXML_TAG(List);
CREATE_OOXML_TAG(ListElement);
CREATE_OOXML_TAG(HTML);
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>
class CDivisionOOXMLTag : public IHTMLTag<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;
CDivisionOOXMLTag(COOXMLWriter *pWriter);
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override;
void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CImage<COOXMLWriter> : public CTag<COOXMLWriter>
class CImageOOXMLTag : public IHTMLTag<COOXMLWriter>
{
std::vector<std::wstring> m_arrImages;
std::vector<std::wstring> m_arImages;
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;
CImageOOXMLTag(COOXMLWriter *pWriter);
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override;
void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CFont<COOXMLWriter> : public CTag<COOXMLWriter>
class CBlockquoteOOXMLTag : public IHTMLTag<COOXMLWriter>
{
std::map<std::wstring, UINT> m_mDivs;
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;
CBlockquoteOOXMLTag(COOXMLWriter *pWriter);
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override;
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>
class CHorizontalRuleOOXMLTag : public IHTMLTag<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;
CHorizontalRuleOOXMLTag(COOXMLWriter *pWriter);
bool Open (const std::vector<NSCSS::CNode>& arSelectors) override;
void Close(const std::vector<NSCSS::CNode>& arSelectors) override;
};
template<>
class CList<COOXMLWriter> : public CTag<COOXMLWriter>
void InitTagsForOOXML(std::map<int, std::shared_ptr<ITag>>& mTags, COOXMLWriter* pWriter);
enum class ETableRules
{
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;
All,
Groups,
Cols,
None,
Rows
};
template<>
class CListElement<COOXMLWriter> : public CTag<COOXMLWriter>
class COOXMLTable : public CTableElement
{
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;
};
COOXMLTable(TExternalTableData &oExternalData);
virtual ~COOXMLTable();
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;
};
bool PreParse(XmlUtils::CXmlLiteReader& oReader) override;
void Normalize() override;
bool Convert(XmlUtils::CXmlLiteReader& oReader, const NSCSS::CNode& oTableNode) override;
private:
bool ParseCaption(XmlUtils::CXmlLiteReader& oReader, XmlString*& pCaption) override;
bool ParseColgroup(XmlUtils::CXmlLiteReader& oReader, std::vector<CTableColgroup*>& arColgroups) 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;
};
bool HaveColgroups() const;
size_t GetColumnsCount() const;
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;
};
struct TTableStyles
{
size_t m_unCellSpacing;
ETableRules m_enRules;
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;
};
const COOXMLTable *m_pTable;
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;
NSCSS::NSProperties::CBorder m_oBorder;
NSCSS::NSProperties::CIndent m_oPadding;
TTableStyles()
: m_unCellSpacing{0}, m_enRules{ETableRules::All}, m_pTable{nullptr}
{}
};
enum class ERowParseMode
{
Header,
Body,
Foother
};
enum class ERowPosition
{
First,
Middle,
Last
};
void OpenTable(XmlString& oXmlString, const NSCSS::CNode& oTableNode, TTableStyles& oTableStyles, const COOXMLTable& oTable);
void CloseTable(XmlString& oXmlString);
void OpenRow(XmlString& oXmlString, bool bIsHeader, size_t unMaxHeight, size_t unCellSpacing);
void CloseRow(XmlString& oXmlString);
void OpenCell(XmlString& oXmlString);
void OpenCell(XmlString& oXmlString, const NSCSS::CNode& oCellNode, ITableElementCell* pCell, size_t unColumnIndex, ERowParseMode eRowParseMode, ERowPosition eRowPosition, size_t& unHeight, const TTableStyles& oTableStyles, std::unordered_map<size_t, NSCSS::CNode>& mFillingColumn);
void CloseCell(XmlString& oXmlString);
void ConvertTable(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& oWriter, const COOXMLTable& oTable, const NSCSS::CNode& oTableNode);
void ConvertMatrix(XmlUtils::CXmlLiteReader& oReader, COOXMLWriter& oWriter, std::vector<NSCSS::CNode>& arSelectors, std::stack<int>& arDepths, const Table& oMatrix, TTableStyles& oTableStyles, ERowParseMode eRowParseMode);
};
}

View File

@ -36,6 +36,8 @@
#ifndef IWRITER_H
#define IWRITER_H
#include "../../DesktopEditor/graphics/pro/Fonts.h"
#include "../../Common/3dParty/html/css/src/CNode.h"
#include "../Common.h"
@ -43,9 +45,25 @@ namespace HTML
{
class IWriter
{
protected:
const std::wstring *m_pTempDir; // Temp folder
const std::wstring *m_pSrcPath; // Source directory
const std::wstring *m_pBasePath; // Full base path
const std::wstring *m_pCorePath; // Path to the root file (used for working with Epub)
NSFonts::IApplicationFonts* m_pFonts; // Necessary for optimizing font handling
public:
IWriter() = default;
virtual ~IWriter() = default;
IWriter()
: m_pTempDir(nullptr), m_pSrcPath(nullptr),
m_pBasePath(nullptr), m_pCorePath(nullptr),
m_pFonts(nullptr)
{};
virtual ~IWriter()
{
if (nullptr != m_pFonts)
delete m_pFonts;
};
virtual void Begin(const std::wstring& wsDst) = 0;
virtual void End(const std::wstring& wsDst) = 0;
@ -64,8 +82,52 @@ public:
virtual XmlString* GetCurrentDocument() const = 0;
//TODO:: move nested tables handling to conversion after changing how tables work
virtual bool SupportNestedTables() const = 0;
void SetSrcDirectory (const std::wstring& wsPath)
{
m_pSrcPath = &wsPath;
}
void SetTempDirectory(const std::wstring& wsPath)
{
m_pTempDir = &wsPath;
}
void SetBaseDirectory(const std::wstring& wsPath)
{
m_pBasePath = &wsPath;
}
void SetCoreDirectory(const std::wstring& wsPath)
{
m_pCorePath = &wsPath;
}
std::wstring GetTempDir() const
{
return (nullptr != m_pTempDir) ? *m_pTempDir : std::wstring();
}
std::wstring GetSrcPath() const
{
return (nullptr != m_pSrcPath) ? *m_pSrcPath : std::wstring();
}
std::wstring GetBasePath() const
{
return (nullptr != m_pBasePath) ? *m_pBasePath : std::wstring();
}
std::wstring GetCorePath() const
{
return (nullptr != m_pCorePath) ? *m_pCorePath : std::wstring();
}
NSFonts::IApplicationFonts* GetFonts()
{
if (nullptr == m_pFonts)
{
m_pFonts = NSFonts::NSApplication::Create();
if (NULL != m_pFonts)
m_pFonts->Initialize();
}
return m_pFonts;
}
};
}

View File

@ -50,9 +50,7 @@ CMDWriter::CMDWriter(const TMarkdownParameters& oMDParametrs)
}
void CMDWriter::Begin(const std::wstring& wsDst)
{
}
{}
void CMDWriter::End(const std::wstring& wsDst)
{
@ -83,6 +81,77 @@ inline void ReplaceSpaces(std::wstring& wsValue)
}
}
void ReplaceSpecialCharsInEdges(std::wstring& wsText)
{
// Hexadecimal codes of the characters being replaced
const wchar_t SP {0x20}; // space
const wchar_t NBSP{0xA0}; // non-breaking space
const wchar_t ENSP{0x2002}; // en space
const wchar_t EMSP{0x2003}; // em space
// Corresponding HTML sequences
const std::wstring NBSP_REP{L"&nbsp;"};
const std::wstring ENSP_REP{L"&ensp;"};
const std::wstring EMSP_REP{L"&emsp;"};
auto is_special = [&](wchar_t c) -> bool {
return c == SP || c == NBSP || c == ENSP || c == EMSP;
};
size_t unFirstNormal{0};
while (unFirstNormal < wsText.size() && is_special(wsText[unFirstNormal]))
++unFirstNormal;
if (unFirstNormal == wsText.size())
{
std::wstring wsResult;
wsResult.reserve(wsText.size() * 6); // each character will be replaced by 6
for (wchar_t c : wsText)
{
if (c == SP || c == NBSP) wsResult.append(NBSP_REP);
else if (c == ENSP) wsResult.append(ENSP_REP);
else if (c == EMSP) wsResult.append(EMSP_REP);
else wsResult.push_back(c);
}
wsText = std::move(wsResult);
return;
}
size_t unLastNormal{wsText.size() - 1};
while (unLastNormal > unFirstNormal && is_special(wsText[unLastNormal]))
--unLastNormal;
const size_t unLeftCount {unFirstNormal};
const size_t unRightCount{wsText.size() - 1 - unLastNormal};
const size_t unNormalLen{unLastNormal - unFirstNormal + 1};
const size_t unNewLen {unNormalLen + unLeftCount * 6 + unRightCount * 6};
std::wstring wsResult;
wsResult.reserve(unNewLen);
for (size_t i = 0; i < unLeftCount; ++i)
{
wchar_t c = wsText[i];
if (c == SP || c == NBSP) wsResult.append(NBSP_REP);
else if (c == ENSP) wsResult.append(ENSP_REP);
else if (c == EMSP) wsResult.append(EMSP_REP);
}
for (size_t i = unFirstNormal; i <= unLastNormal; ++i)
wsResult.push_back(wsText[i]);
for (size_t i = unLastNormal + 1; i < wsText.size(); ++i)
{
wchar_t c = wsText[i];
if (c == SP || c == NBSP) wsResult.append(NBSP_REP);
else if (c == ENSP) wsResult.append(ENSP_REP);
else if (c == EMSP) wsResult.append(EMSP_REP);
}
wsText = std::move(wsResult);
}
bool CMDWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>& arSelectors)
{
bool bPreformatted{InPreformatted()};
@ -125,44 +194,51 @@ bool CMDWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode>&
WriteString(L"> ", true);
}
const bool bOnlySpaces{wsText.end() == std::find_if_not(wsText.begin(), wsText.end(), [](wchar_t wchChar){ return iswspace(wchChar);})};
if (!bPreformatted && !InCode())
ReplaceSpaces(wsText);
bool bNeedBold{false}, bNeedItalic{false}, bNeedStrike{false};
if (nullptr != pCompiledStyle)
{
if (!IsBold() && pCompiledStyle->m_oFont.Bold())
ReplaceSpaces(wsText);
ReplaceSpecialCharsInEdges(wsText);
}
bool bNeedBold {false},
bNeedItalic{false},
bNeedStrike{false};
if (nullptr != pCompiledStyle && !bOnlySpaces)
{
if (pCompiledStyle->m_oFont.Bold())
bNeedBold = true;
if (!IsItalic() && pCompiledStyle->m_oFont.Italic())
if (pCompiledStyle->m_oFont.Italic())
bNeedItalic = true;
if (!IsStrike() && pCompiledStyle->m_oText.LineThrough())
if (pCompiledStyle->m_oText.LineThrough())
bNeedStrike = true;
}
if (bNeedBold)
WriteString(L"**");
WriteOpenSpecialString(L"**");
if (bNeedItalic)
WriteString(L"*");
WriteOpenSpecialString(L"*");
if (bNeedStrike)
WriteString(L"~~");
WriteOpenSpecialString(L"~~");
ApplyAlternativeTags(pCompiledStyle);
WriteString(wsText);
ApplyAlternativeTags(pCompiledStyle, true);
if (bNeedBold)
WriteString(L"**");
WriteCloseSpecialString(L"**");
if (bNeedItalic)
WriteString(L"*");
WriteCloseSpecialString(L"*");
if (bNeedStrike)
WriteString(L"~~");
WriteCloseSpecialString(L"~~");
if (L'\n' == wsText.back())
m_arStates.top().m_bNeedBreakLine = false;
@ -212,22 +288,32 @@ void CMDWriter::WriteString(const std::wstring& wsString, bool bSpecialString)
m_arStates.top().m_bEmptyLine = wsString.empty();
if (!bSpecialString)
{
if (!m_arStates.top().m_oSpecialString.m_wsLastSpecialString.empty() &&
m_arStates.top().m_oSpecialString.m_bClosed)
m_arStates.top().m_oSpecialString.m_wsLastSpecialString.clear();
m_arStates.top().m_bNeedBreakLine = true;
}
}
void CMDWriter::WriteOpenSpecialString(const std::wstring& wsString)
{
if (m_arStates.top().m_wsLastSpecialString == wsString)
if (!m_arStates.top().m_oSpecialString.m_wsLastSpecialString.empty() &&
(m_arStates.top().m_oSpecialString.m_wsLastSpecialString == wsString ||
(L'*' == m_arStates.top().m_oSpecialString.m_wsLastSpecialString.front() && L'*' == wsString.front())))
GetCurrentDocument()->WriteString(L" ");
m_arStates.top().m_wsLastSpecialString.clear();
m_arStates.top().m_oSpecialString.m_wsLastSpecialString.clear();
m_arStates.top().m_oSpecialString.m_bClosed = false;
WriteString(wsString, true);
}
void CMDWriter::WriteCloseSpecialString(const std::wstring& wsString)
{
m_arStates.top().m_wsLastSpecialString = wsString;
m_arStates.top().m_oSpecialString.m_wsLastSpecialString = wsString;
m_arStates.top().m_oSpecialString.m_bClosed = true;
WriteString(wsString, true);
}
@ -237,11 +323,6 @@ 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)
@ -266,52 +347,6 @@ void CMDWriter::WriteBreakLine(bool bNeedChecked)
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()

View File

@ -56,10 +56,6 @@ class CMDWriter : public IWriter
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};
@ -69,7 +65,11 @@ class CMDWriter : public IWriter
UINT m_unLevelList{0};
UINT m_unIndexListElement{1};
std::wstring m_wsLastSpecialString;
struct TSpecialString
{
std::wstring m_wsLastSpecialString;
bool m_bClosed{false};
}m_oSpecialString;
};
std::stack<TState> m_arStates;
@ -100,22 +100,8 @@ public:
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();

View File

@ -41,8 +41,6 @@
#include "../../DesktopEditor/common/Directory.h"
#include "../../DesktopEditor/common/SystemUtils.h"
#include "../../DesktopEditor/graphics/pro/Fonts.h"
#include "../src/Languages.h"
namespace HTML
@ -54,11 +52,8 @@ namespace HTML
#define MAX_STRING_BLOCK_SIZE (size_t)10485760
#define MAXCOLUMNSINTABLE 63
#define MAXROWSINTABLE 32767
#define DEFAULT_PAGE_WIDTH 12240 // Value in Twips
#define DEFAULT_PAGE_HEIGHT 15840 // Value in Twips
#define DEFAULT_PAGE_WIDTH 12240 // Value in twips
#define DEFAULT_PAGE_HEIGHT 15840 // Value in twips
#define DEFAULT_LANGUAGE std::wstring(L"en-US")
#define DEFAULT_FONT_FAMILY std::wstring(L"Times New Roman")
@ -76,10 +71,9 @@ inline UINT GetFontSizeByLevel(UINT unLevel);
inline void ReplaceSpaces(std::wstring& wsValue);
COOXMLWriter::COOXMLWriter(THTMLParameters* pHTMLParameters, NSCSS::CCssCalculator* pCSSCalculator)
: m_pDstPath(nullptr), m_pTempDir(nullptr), m_pSrcPath(nullptr),
m_pBasePath(nullptr), m_pCorePath(nullptr), m_pStylesCalculator(pCSSCalculator),
: m_pDstPath(nullptr), m_pStylesCalculator(pCSSCalculator),
m_pHTMLParameters(pHTMLParameters), m_nFootnoteId(1), m_nHyperlinkId(1), m_nListId(1),
m_nElementId(1), m_bBanUpdatePageData(false), m_bWasDivs(false), m_pFonts(nullptr)
m_nElementId(1), m_bBanUpdatePageData(false), m_bWasDivs(false)
{
m_oPageData.SetWidth (DEFAULT_PAGE_WIDTH, NSCSS::UnitMeasure::Twips, 0, true);
m_oPageData.SetHeight(DEFAULT_PAGE_HEIGHT, NSCSS::UnitMeasure::Twips, 0, true);
@ -91,31 +85,11 @@ COOXMLWriter::COOXMLWriter(THTMLParameters* pHTMLParameters, NSCSS::CCssCalculat
m_arStates.top().m_pCurrentDocument = &m_oDocXml;
}
void COOXMLWriter::SetSrcDirectory(const std::wstring& wsPath)
{
m_pSrcPath = &wsPath;
}
void COOXMLWriter::SetDstDirectory(const std::wstring& wsPath)
{
m_pDstPath = &wsPath;
}
void COOXMLWriter::SetTempDirectory(const std::wstring& wsPath)
{
m_pTempDir = &wsPath;
}
void COOXMLWriter::SetBaseDirectory(const std::wstring& wsPath)
{
m_pBasePath = &wsPath;
}
void COOXMLWriter::SetCoreDirectory(const std::wstring& wsPath)
{
m_pCorePath = &wsPath;
}
void COOXMLWriter::Begin(const std::wstring& wsDst)
{
// Create empty folders
@ -592,12 +566,12 @@ void COOXMLWriter::SetCurrentDocument(XmlString* pNewDocument)
m_arStates.top().m_bRemoveCurrentDocument = false;
}
void COOXMLWriter::Break(const std::vector<NSCSS::CNode>& arSelectors)
void COOXMLWriter::Break(const NSCSS::CNode& oTagNode)
{
if (m_arStates.top().m_bInP)
{
OpenR();
if(arSelectors.back().m_pCompiledStyle->m_oText.GetAlign() == L"both")
if(oTagNode.m_pCompiledStyle->m_oText.GetAlign() == L"both")
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:tab/>");
m_arStates.top().m_pCurrentDocument->WriteString(L"<w:br/>");
CloseR();
@ -852,7 +826,7 @@ bool COOXMLWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode
return false;
bool bBidirectional{false}, bPreformatted{false}, bQuotation{false},
bAddSpaces{true}, bMergedText{false}, bDeleted{false};
bAddSpaces{true}, bDeleted{false};
for (const NSCSS::CNode& oNode : arSelectors)
{
@ -982,9 +956,6 @@ bool COOXMLWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode
else
GetCurrentDocument()->WriteString(L"<w:delText>");
if (bMergedText && !m_arStates.top().m_bWasSpace && bInT && !bPreformatted)
m_arStates.top().m_pCurrentDocument->WriteEncodeXmlString(L" ");
if (!wsText.empty())
{
m_arStates.top().m_bWasSpace = std::iswspace(wsText.back());
@ -1000,8 +971,7 @@ bool COOXMLWriter::WriteText(std::wstring wsText, const std::vector<NSCSS::CNode
else
GetCurrentDocument()->WriteString(L"</w:delText>");
if (!bMergedText)
CloseR();
CloseR();
if (bDeleted)
GetCurrentDocument()->WriteString(L"</w:del>");
@ -1296,54 +1266,16 @@ XmlString* COOXMLWriter::GetCurrentDocument() const
return m_arStates.top().m_pCurrentDocument;
}
bool COOXMLWriter::SupportNestedTables() const
{
return true;
}
const NSCSS::NSProperties::CPage* COOXMLWriter::GetPageData() const
{
return &m_oPageData;
}
NSFonts::IApplicationFonts* COOXMLWriter::GetFonts()
{
if (nullptr == m_pFonts)
{
m_pFonts = NSFonts::NSApplication::Create();
if (NULL != m_pFonts)
m_pFonts->Initialize();
}
return m_pFonts;
}
std::wstring COOXMLWriter::GetMediaDir() const
{
return ((nullptr != m_pDstPath) ? *m_pDstPath : std::wstring()) + L"/word/media/";
}
std::wstring COOXMLWriter::GetTempDir() const
{
return (nullptr != m_pTempDir) ? *m_pTempDir : std::wstring();
}
std::wstring COOXMLWriter::GetSrcPath() const
{
return (nullptr != m_pSrcPath) ? *m_pSrcPath : std::wstring();
}
std::wstring COOXMLWriter::GetBasePath() const
{
return (nullptr != m_pBasePath) ? *m_pBasePath : std::wstring();
}
std::wstring COOXMLWriter::GetCorePath() const
{
return (nullptr != m_pCorePath) ? *m_pCorePath : std::wstring();
}
inline bool ElementInTable(const std::vector<NSCSS::CNode>& arSelectors)
{
return arSelectors.crend() != std::find_if(arSelectors.crbegin(), arSelectors.crend(), [](const NSCSS::CNode& oNode) { return L"table" == oNode.m_wsName; });

View File

@ -43,8 +43,6 @@
#include <stack>
namespace NSFonts { class IApplicationFonts; }
namespace HTML
{
struct TImageData
@ -58,7 +56,7 @@ struct TImageData
std::wstring m_wsAlign;
TImageData()
: m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left")
: m_unWidth(0), m_unHeight(0), m_nHSpace(0), m_nVSpace(0), m_wsAlign(L"left")
{}
bool ZeroSize() const
@ -75,10 +73,6 @@ struct TImageData
class COOXMLWriter : public IWriter
{
const std::wstring *m_pDstPath; // Destination directory
const std::wstring *m_pTempDir; // Temp folder
const std::wstring *m_pSrcPath; // Source directory
const std::wstring *m_pBasePath; // Full base address
const std::wstring *m_pCorePath; // Path to root file (used for working with Epub)
XmlString m_oStylesXml; // styles.xml
XmlString m_oDocXmlRels; // document.xml.rels
@ -148,16 +142,10 @@ class COOXMLWriter : public IWriter
std::map<std::wstring, UINT> m_mBookmarks; // Bookmarks
using anchors_map = std::map<std::wstring, std::wstring>;
anchors_map m_mAnchors; // Map of anchors with individual ids
NSFonts::IApplicationFonts* m_pFonts; // Needed for font handling optimization
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;
@ -185,7 +173,7 @@ public:
void SetCurrentDocument(XmlString* pNewDocument);
void Break(const std::vector<NSCSS::CNode>& arSelectors);
void Break(const NSCSS::CNode& oTagNode);
void SetHyperlinkData(const std::wstring& wsRef, const std::wstring& wsTooltip, bool bIsCross, const std::wstring& wsFootnote, bool bIsFootnote);
void ClearHyperlinkData();
@ -235,16 +223,9 @@ public:
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;
};
}

View File

@ -106,7 +106,7 @@ const std::map<std::wstring, HtmlTag> m_HTML_TAGS
ADD_TAG(L"acronym", ACRONYM),
ADD_TAG(L"address", ADDRESS),
ADD_TAG(L"applet", APPLET),
ADD_TAG(L"area", AREA),
ADD_TAG(L"area", AREA),
ADD_TAG(L"article", ARTICLE),
ADD_TAG(L"aside", ASIDE),
ADD_TAG(L"audio", AUDIO),

View File

@ -305,6 +305,9 @@ namespace DocFileFormat
bool bFilled = true;
bool hasTextbox = false;
bool layoutInCell = true; //anmeldebogenfos.doc
bool HorizRule = false;
bool StandardHR = false;
bool NoshadeHR = false;
bool b3D = false;
bool bShadow = false;
bool bPicturePresent = false;
@ -403,6 +406,18 @@ namespace DocFileFormat
{
layoutInCell = booleans->fLayoutInCell;
}
if (booleans->fUsefHorizRule)
{
HorizRule = booleans->fHorizRule;
}
if (booleans->fUsefStandardHR)
{
StandardHR = booleans->fStandardHR;
}
if (booleans->fUsefNoshadeHR)
{
NoshadeHR = booleans->fNoshadeHR;
}
}
break;
// GEOMETRY
@ -750,6 +765,27 @@ namespace DocFileFormat
}
}
}break;
case ODRAW::pctHR:
{
int pctValue = (int)iter->op;
if (pctValue > 0)
{
std::wstring pctStr = std::to_wstring(pctValue);
m_pXmlWriter->WriteAttribute(L"o:hrpct", pctStr);
}
}break;
case ODRAW::alignHR:
{
switch (iter->op)
{
case 0: m_pXmlWriter->WriteAttribute(L"o:hralign", L"left"); break;
case 1: m_pXmlWriter->WriteAttribute(L"o:hralign", L"center"); break;
case 2: m_pXmlWriter->WriteAttribute(L"o:hralign", L"right"); break;
}
}break;
// OLE
case ODRAW::pictureId:
{
@ -1061,6 +1097,18 @@ namespace DocFileFormat
m_pXmlWriter->WriteAttribute(L"coordsize", (FormatUtils::SizeTToWideString(*xCoord) + L"," + FormatUtils::SizeTToWideString(*yCoord)));
}
}
if (HorizRule)
{
m_pXmlWriter->WriteAttribute(L"o:hr", L"t");
}
if (StandardHR)
{
m_pXmlWriter->WriteAttribute(L"o:hrstd", L"t");
}
if (NoshadeHR)
{
m_pXmlWriter->WriteAttribute(L"o:hrnoshade", L"t");
}
int nCode = 0;
if (pShape->GetShapeType())

View File

@ -42,6 +42,7 @@
//#include "../Records/SoundCollectionContainer.h"
//#include "../Records/SoundContainer.h"
#include "../Enums/_includer.h"
#include "../../../OfficeCryptReader/source/CryptTransform.h"
using namespace PPT;
using namespace ODRAW;
@ -177,17 +178,28 @@ bool CPPTUserInfo::ReadFromStream(CRecordUserEditAtom* pUser, POLE::Stream* pStr
m_bEncrypt = true;
m_oEncryptionHeader.ReadFromStream(oHeader, pStream);
m_pDecryptor = new CRYPT::ECMADecryptor();
m_pDecryptor->SetCryptData(m_oEncryptionHeader.crypt_data_aes);
if (m_strPassword.empty())
if (m_oEncryptionHeader.bStandard)
{
if (m_pDecryptor->SetPassword(L"VelvetSweatshop") == false)
m_pDecryptor = new CRYPT::RC4Decryptor(m_oEncryptionHeader.crypt_data_rc4,
m_strPassword.empty() ? L"VelvetSweatshop" : m_strPassword);
if (!m_pDecryptor->IsVerify())
return false;
}
else if (m_pDecryptor->SetPassword(m_strPassword) == false)
else
{
return false;
CRYPT::ECMADecryptor* ecmaDecryptor = new CRYPT::ECMADecryptor();
ecmaDecryptor->SetCryptData(m_oEncryptionHeader.crypt_data_aes);
m_pDecryptor = ecmaDecryptor;
if (m_strPassword.empty())
{
if (ecmaDecryptor->SetPassword(L"VelvetSweatshop") == false)
return false;
}
else if (ecmaDecryptor->SetPassword(m_strPassword) == false)
{
return false;
}
}
std::wstring sTemp = m_pDocumentInfo->m_pCommonInfo->tempPath + FILE_SEPARATOR_STR + L"~tempFile.ppt";

View File

@ -61,7 +61,7 @@ public:
CEncryptionHeader m_oEncryptionHeader;
bool m_bEncrypt;
std::wstring m_strPassword;
CRYPT::ECMADecryptor* m_pDecryptor;
CRYPT::Decryptor* m_pDecryptor;
POLE::Storage* m_pStorageDecrypt;
std::vector<XLS::CFStreamPtr> m_arStreamDecrypt; // each Persist has its own ... o_O

View File

@ -257,7 +257,7 @@ void CPPTFileReader::ReadPictures()
XLS::CFStreamPtr pStream = GetPictureStream();
if (!pStream) return;
CRYPT::ECMADecryptor *pDecryptor = m_oDocumentInfo.m_arUsers[0]->m_pDecryptor;
CRYPT::Decryptor *pDecryptor = m_oDocumentInfo.m_arUsers[0]->m_pDecryptor;
while (true)
{

View File

@ -677,7 +677,7 @@ CMetaHeader::CMetaHeader()
{
}
void CMetaHeader::FromStream(POLE::Stream* pStream, CRYPT::ECMADecryptor *pDecryptor)
void CMetaHeader::FromStream(POLE::Stream* pStream, CRYPT::Decryptor *pDecryptor)
{
BYTE pData[34];
pStream->read(pData, 34);

View File

@ -40,7 +40,7 @@
namespace CRYPT
{
class ECMADecryptor;
class Decryptor;
}
namespace PPT
{
@ -154,7 +154,7 @@ public:
public:
CMetaHeader();
void FromStream(POLE::Stream* pStream, CRYPT::ECMADecryptor *pDecryptor = NULL);
void FromStream(POLE::Stream* pStream, CRYPT::Decryptor *pDecryptor = NULL);
void ToEMFHeader(Gdiplus::ENHMETAHEADER3* pHeader);
void ToWMFHeader(Gdiplus::WmfPlaceableFileHeader* pHeader);

View File

@ -113,20 +113,9 @@ void CEncryptionHeader::ReadFromStream(SRecordHeader &oHeader, POLE::Stream *pSt
int Reserved1 = StreamUtils::ReadDWORD(pStream);
int Reserved2 = StreamUtils::ReadDWORD(pStream);
POLE::uint64 pos = pStream->tell();
POLE::uint64 size = pStream->size();
// skip csp name
pStream->seek(pos_start_record + 12 + HeaderSize);
std::vector<char> dataCSPName;
while(pos < size - 1)
{
dataCSPName.push_back(StreamUtils::ReadBYTE(pStream));
dataCSPName.push_back(StreamUtils::ReadBYTE(pStream));
if (dataCSPName[dataCSPName.size() - 1] == 0 && dataCSPName[dataCSPName.size() - 2] == 0)
{
break;
}
pos+=2;//unicode null-terminate string
}
//EncryptionVerifier
crypt_data_aes.saltSize = StreamUtils::ReadDWORD(pStream);
crypt_data_aes.saltValue = StreamUtils::ReadStringA(pStream, crypt_data_aes.saltSize);
@ -138,8 +127,6 @@ void CEncryptionHeader::ReadFromStream(SRecordHeader &oHeader, POLE::Stream *pSt
int szEncryptedVerifierHash = (ProviderType == 0x0001) ? 0x14 : 0x20;
crypt_data_aes.encryptedVerifierValue = StreamUtils::ReadStringA(pStream, szEncryptedVerifierHash);
pos = pStream->tell();
//------------------------------------------------------------------------------------------
switch(AlgIDHash)
{

View File

@ -52,7 +52,7 @@ void CRecordOfficeArtBlip::ReadFromStream(SRecordHeader & oHeader, POLE::Stream*
{
if ((oHeader.RecVersion == PSFLAG_CONTAINER) || ((oHeader.RecVersion & 0x0F) == 0x0F)) return;
CRYPT::ECMADecryptor *pDecryptor = m_pDocumentInfo ? m_pDocumentInfo->m_arUsers[0]->m_pDecryptor : NULL;
CRYPT::Decryptor *pDecryptor = m_pDocumentInfo ? m_pDocumentInfo->m_arUsers[0]->m_pDecryptor : NULL;
CMetaFileBuffer oMetaFile;
std::wstring sExt = L".jpg";

View File

@ -315,7 +315,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;

View File

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

View File

@ -50,11 +50,6 @@ BOF::BOF()
fOOM = false;
fGlJmp = false;
fFontLimit = false;
verXLHigh = 0;
verLowestBiff = 6;
verLastXLSaved = 0;
}

View File

@ -91,9 +91,9 @@ public:
bool fGlJmp = 0;
bool fFontLimit = 0;
_UINT16 verXLHigh = 0x7;
_UINT16 verXLHigh = 0x8;
unsigned char verLowestBiff = 0x6;
unsigned char verLastXLSaved = 0x7;
unsigned char verLastXLSaved = 0x8;
_CP_OPT(unsigned int) stream_ptr;

View File

@ -128,7 +128,7 @@ void CF12::readFields(CFRecord& record)
dxfId_ = global_info->RegistrDxfn(strm.str());
}
void ProcessBorderProp( OOX::Spreadsheet::CBorderProp* prop, unsigned char& DgPtr, unsigned char& icvPtr)
void ProcessBorderProp( OOX::Spreadsheet::CBorderProp* prop, unsigned char& DgPtr, ExtProp &BdrColor)
{
if(prop->m_oStyle.IsInit())
{
@ -204,8 +204,24 @@ void ProcessBorderProp( OOX::Spreadsheet::CBorderProp* prop, unsigned char& DgPt
break;
}
}
if(prop->m_oColor.IsInit() && prop->m_oColor->m_oIndexed.IsInit())
icvPtr = prop->m_oColor->m_oIndexed->GetValue();
if(prop->m_oColor.IsInit())
{
if(prop->m_oColor->m_oIndexed.IsInit())
{
BdrColor.extPropData.color.xclrType = 1;
BdrColor.extPropData.color.xclrValue = prop->m_oColor->m_oIndexed->GetValue();
}
else if(prop->m_oColor->m_oThemeColor.IsInit())
{
BdrColor.extPropData.color.xclrType = 3;
BdrColor.extPropData.color.xclrValue = prop->m_oColor->m_oThemeColor->GetValue();
}
else if(prop->m_oColor->m_oRgb.IsInit())
{
BdrColor.extPropData.color.xclrType = 2;
BdrColor.extPropData.color.xclrValue = prop->m_oColor->m_oRgb->ToInt();
}
}
}
void CF12::writeFields(CFRecord& record)
@ -224,6 +240,11 @@ void CF12::writeFields(CFRecord& record)
{
OOX::Spreadsheet::CDxf dxfObj;
XmlUtils::CXmlLiteReader oReader;
if(dxf.dxfn->xfext == nullptr)
{
auto Ext = new XFExtNoFRT;
dxf.dxfn->xfext = XFExtNoFRTPtr(Ext);
}
if(oReader.FromString(global_info->arrUserDxfs.at(dxfId_)))
{
if(oReader.ReadNextNode())
@ -243,11 +264,6 @@ void CF12::writeFields(CFRecord& record)
{
dxf.dxfn->icvFNinch= false;
ExtProp fgColor;
if(dxf.dxfn->xfext == nullptr)
{
auto Ext = new XFExtNoFRT;
dxf.dxfn->xfext = XFExtNoFRTPtr(Ext);
}
if(dxfObj.m_oFill->m_oPatternFill->m_oFgColor->m_oThemeColor.IsInit())
{
fgColor.extType = ExtProp::ForeColor;
@ -261,7 +277,8 @@ void CF12::writeFields(CFRecord& record)
fgColor.extPropData.color.xclrType = 2;
fgColor.extPropData.color.xclrValue = dxfObj.m_oFill->m_oPatternFill->m_oFgColor->m_oRgb->ToInt();
}
if(dxfObj.m_oFill->m_oPatternFill->m_oFgColor->m_oTint.IsInit())
fgColor.extPropData.color.nTintShade = dxfObj.m_oFill->m_oPatternFill->m_oFgColor->m_oTint->GetValue() * 32767;
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::ForeColor, fgColor);
}
if(dxfObj.m_oFill->m_oPatternFill->m_oBgColor.IsInit() && dxfObj.m_oFill->m_oPatternFill->m_oBgColor->m_oIndexed.IsInit())
@ -273,11 +290,6 @@ void CF12::writeFields(CFRecord& record)
{
ExtProp bgColor;
dxf.dxfn->icvBNinch = false;
if(dxf.dxfn->xfext == nullptr)
{
auto Ext = new XFExtNoFRT;
dxf.dxfn->xfext = XFExtNoFRTPtr(Ext);
}
if(dxfObj.m_oFill->m_oPatternFill->m_oBgColor->m_oThemeColor.IsInit())
{
bgColor.extType = ExtProp::BackColor;
@ -291,7 +303,8 @@ void CF12::writeFields(CFRecord& record)
bgColor.extPropData.color.xclrType = 2;
bgColor.extPropData.color.xclrValue = dxfObj.m_oFill->m_oPatternFill->m_oBgColor->m_oRgb->ToInt();
}
if(dxfObj.m_oFill->m_oPatternFill->m_oBgColor->m_oTint.IsInit())
bgColor.extPropData.color.nTintShade = dxfObj.m_oFill->m_oPatternFill->m_oBgColor->m_oTint->GetValue() * 32767;
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::BackColor, bgColor);
}
}
@ -326,8 +339,30 @@ void CF12::writeFields(CFRecord& record)
else if(dxfObj.m_oFont->m_oUnderline->m_oUnderline->GetValue() == SimpleTypes::Spreadsheet::EUnderline::underlineDoubleAccounting)
dxf.dxfn->dxffntd.stxp.uls = 0x22;
}
if(dxfObj.m_oFont->m_oColor.IsInit() && dxfObj.m_oFont->m_oColor->m_oIndexed.IsInit())
dxf.dxfn->dxffntd.icvFore = dxfObj.m_oFont->m_oColor->m_oIndexed->GetValue();
if(dxfObj.m_oFont->m_oColor.IsInit())
{
ExtProp fntColor;
fntColor.extType = ExtProp::TextColor;
if(dxfObj.m_oFont->m_oColor->m_oThemeColor.IsInit())
{
fntColor.extPropData.color.xclrType = 3;
fntColor.extPropData.color.xclrValue = dxfObj.m_oFont->m_oColor->m_oThemeColor->GetValue();
}
else if(dxfObj.m_oFont->m_oColor->m_oRgb.IsInit())
{
fntColor.extPropData.color.xclrType = 2;
fntColor.extPropData.color.xclrValue = dxfObj.m_oFont->m_oColor->m_oRgb->ToInt();
}
else if(dxfObj.m_oFont->m_oColor->m_oIndexed.IsInit())
{
fntColor.extPropData.color.xclrType = 1;
fntColor.extPropData.color.xclrValue = dxfObj.m_oFont->m_oColor->m_oIndexed->GetValue();
}
if(dxfObj.m_oFont->m_oColor->m_oTint.IsInit())
fntColor.extPropData.color.nTintShade = dxfObj.m_oFont->m_oColor->m_oTint->GetValue() * 32767;
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::TextColor, fntColor);
}
}
if(dxfObj.m_oBorder.IsInit())
{
@ -335,22 +370,34 @@ void CF12::writeFields(CFRecord& record)
if(dxfObj.m_oBorder->m_oBottom.IsInit())
{
dxf.dxfn->glBottomNinch = false;
ProcessBorderProp(dxfObj.m_oBorder->m_oBottom.GetPointer(), dxf.dxfn->dxfbdr.dgBottom, dxf.dxfn->dxfbdr.icvBottom);
ExtProp BdrColor;
BdrColor.extType = ExtProp::BottomBorderColor;
ProcessBorderProp(dxfObj.m_oBorder->m_oBottom.GetPointer(), dxf.dxfn->dxfbdr.dgBottom, BdrColor);
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::BottomBorderColor, BdrColor);
}
if(dxfObj.m_oBorder->m_oTop.IsInit())
{
dxf.dxfn->glTopNinch = false;
ProcessBorderProp(dxfObj.m_oBorder->m_oTop.GetPointer(), dxf.dxfn->dxfbdr.dgTop, dxf.dxfn->dxfbdr.icvTop);
ExtProp BdrColor;
BdrColor.extType = ExtProp::TopBorderColor;
ProcessBorderProp(dxfObj.m_oBorder->m_oTop.GetPointer(), dxf.dxfn->dxfbdr.dgTop, BdrColor);
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::TopBorderColor, BdrColor);
}
if(dxfObj.m_oBorder->m_oStart.IsInit())
{
dxf.dxfn->glLeftNinch = false;
ProcessBorderProp(dxfObj.m_oBorder->m_oStart.GetPointer(), dxf.dxfn->dxfbdr.dgLeft, dxf.dxfn->dxfbdr.icvLeft);
ExtProp BdrColor;
BdrColor.extType = ExtProp::LeftBorderColor;
ProcessBorderProp(dxfObj.m_oBorder->m_oStart.GetPointer(), dxf.dxfn->dxfbdr.dgLeft, BdrColor);
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::LeftBorderColor, BdrColor);
}
if(dxfObj.m_oBorder->m_oEnd.IsInit())
{
dxf.dxfn->glRightNinch = false;
ProcessBorderProp(dxfObj.m_oBorder->m_oEnd.GetPointer(), dxf.dxfn->dxfbdr.dgRight, dxf.dxfn->dxfbdr.icvRight);
ExtProp BdrColor;
BdrColor.extType = ExtProp::RightBorderColor;
ProcessBorderProp(dxfObj.m_oBorder->m_oEnd.GetPointer(), dxf.dxfn->dxfbdr.dgRight, BdrColor);
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::RightBorderColor, BdrColor);
}
if(dxfObj.m_oBorder->m_oDiagonal.IsInit())
{
@ -360,8 +407,12 @@ void CF12::writeFields(CFRecord& record)
dxf.dxfn->dxfbdr.bitDiagDown = true;
if(dxfObj.m_oBorder->m_oDiagonalUp.IsInit() && dxfObj.m_oBorder->m_oDiagonalUp->GetValue())
dxf.dxfn->dxfbdr.bitDiagUp = true;
ProcessBorderProp(dxfObj.m_oBorder->m_oDiagonal.GetPointer(), dxf.dxfn->dxfbdr.dgDiag, dxf.dxfn->dxfbdr.icvDiag);
ExtProp BdrColor;
BdrColor.extType = ExtProp::DiagonalBorderColor;
ProcessBorderProp(dxfObj.m_oBorder->m_oDiagonal.GetPointer(), dxf.dxfn->dxfbdr.dgDiag, BdrColor);
dxf.dxfn->xfext->mapRgExt.emplace(ExtProp::DiagonalBorderColor, BdrColor);
}
}
if(dxfObj.m_oNumFmt.IsInit())
{
@ -375,6 +426,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

@ -68,6 +68,11 @@ void CRN::readFields(CFRecord& record)
record >> rec_type;
SerArPtr ser(SerAr::createSerAr(rec_type));
if(ser == nullptr)
{
colLast = (i > 0) ? (colFirst + i - 1) : colFirst;
break;
}
record >> *ser;
crnOper.push_back(ser);
if(record.getRdPtr() >= record.getDataSize())

View File

@ -140,107 +140,142 @@ 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 rx1, const unsigned int rx2, const unsigned int ry1,
const unsigned int ry2, 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;
}
}
void MsoDrawing::prepareChart(const unsigned int chartId, const unsigned int x1, const unsigned int x2,
const unsigned int y1, const unsigned int y2, const unsigned int x1Offset, const unsigned int x2Offset,
const unsigned int y1Offset,const unsigned int y2Offset)
{
auto fdgPtr = new ODRAW::OfficeArtFDG;
fdgPtr->rh_own.recInstance = chartId;
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 = x1;
groupFSPGR->xRight = x2;
groupFSPGR->yTop = y1;
groupFSPGR->yBottom = y2;
SpContainer->m_OfficeArtFSPGR = ODRAW::OfficeArtRecordPtr(groupFSPGR);
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);
fsprPtr->shape_id = 0;
fsprPtr->spid = chartId;
fsprPtr->fGroup = true;
fsprPtr->fPatriarch = true;
}
{
auto SpContainer = new ODRAW::OfficeArtSpContainer(ODRAW::OfficeArtRecord::CA_Chart);
spgrContainer->m_OfficeArtSpgrContainerFileBlock.push_back(ODRAW::OfficeArtContainerPtr(SpContainer));
auto fsprPtr = new ODRAW::OfficeArtFSP;
SpContainer->m_OfficeArtFSP = ODRAW::OfficeArtRecordPtr(fsprPtr);
fsprPtr->shape_id = 1;
fsprPtr->spid = chartId;
if(Type == DrawingType::comment)
fsprPtr->shape_id = 0xCA;
else
fsprPtr->shape_id = 1;
fsprPtr->spid = DrawingtId+1;
fsprPtr->fHaveMaster = true;
fsprPtr->fFlipV = true;
auto clientAnchor = new ODRAW::OfficeArtClientAnchorSheet;
clientAnchor->colL = x1;
clientAnchor->dxL = x1Offset;
clientAnchor->colR = x2;
clientAnchor->dxR = x2Offset;
clientAnchor->rwT = y1;
clientAnchor->dyT = y1Offset;
clientAnchor->rwB = y2;
clientAnchor->dyB = y2Offset;
clientAnchor->colL = col1;
clientAnchor->colR = col2;
clientAnchor->rwT = row1;
clientAnchor->rwB = row2;
{
clientAnchor->dxL = rx1;
clientAnchor->dxR = rx2;
clientAnchor->dyT = ry1;
clientAnchor->dyB = ry2;
}
SpContainer->m_OfficeArtAnchor = ODRAW::OfficeArtRecordPtr(clientAnchor);
auto clientData = new ODRAW::OfficeArtClientData;
SpContainer->m_oOfficeArtClientData = ODRAW::OfficeArtRecordPtr(clientData);
}
fdgPtr->csp = spgrContainer->m_OfficeArtSpgrContainerFileBlock.size();
}
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));
}
{
auto PicOp = new ODRAW::OfficeArtFOPTE;
PicOp->opid = 0x01BF;
PicOp->fComplex = false;
PicOp->fBid = false;
PicOp->op = 0x100000;
commentOptions->fopt.Text_props.push_back(ODRAW::OfficeArtFOPTEPtr(PicOp));
}
commentOptions->fopt.options_count += 2;
SpContainer->m_oOfficeArtFOPT = ODRAW::OfficeArtRecordPtr(commentOptions);
}
}
}
} // namespace XLS

View File

@ -63,19 +63,23 @@ 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 x1, const unsigned int x2,
const unsigned int y1, const unsigned int y2, const unsigned int x1Offset = 0, const unsigned int x2Offset = 0,
const unsigned int y1Offset = 0,const unsigned int y2Offset = 0);
//-----------------------------
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 rx1 = 0, const unsigned int rx2 = 0,
const unsigned int ry1 = 0,const unsigned int ry2 = 0, const unsigned int param = 1);
};
typedef boost::shared_ptr<MsoDrawing> MsoDrawingPtr;
} // namespace XLS

View File

@ -34,6 +34,9 @@
*/
#include "MsoDrawingGroup.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../Biff_structures/ODRAW/OfficeArtFDGGBlock.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
namespace XLS
{
@ -67,5 +70,58 @@ 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(OOX::CPath& 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.GetPath()) == drawingNames->end())
{
auto fileBlock = new ODRAW::OfficeArtBStoreContainerFileBlock;
bstore->rgfb.push_back(fileBlock);
pictNum = bstore->rgfb.size();
drawingNames->emplace(picPath.GetPath(), pictNum);
DWORD fileSize = 0;
auto result = NSFile::CFileBinary::ReadAllBytes(picPath.GetPath(), (BYTE**)&fileBlock->pict_data, fileSize);
fileBlock->pict_size = fileSize;
fileBlock->pict_type = picPath.GetExtention();
}
else
pictNum = drawingNames->find(picPath.GetPath())->second;
return pictNum;
}
} // namespace XLS

View File

@ -36,6 +36,8 @@
#include "BiffRecordContinued.h"
#include "../Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../../../../../OOXML/Base/Nullable.h"
#include "../../../../../OOXML/SystemUtility/SystemUtility.h"
namespace XLS
{
@ -47,15 +49,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(OOX::CPath& pictPath);
ODRAW::OfficeArtDggContainer rgChildRec;
unsigned int drawingCount = 0;
nullable<std::map<std::wstring, unsigned int>> drawingNames;
};

View File

@ -57,7 +57,7 @@ public:
bool fAllAtoms = false;
bool fSomeUnhashed = false;
bool fUsed = false;
bool fUsed = true;
bool fHasParent = false;
bool fRangeGroup = false;
bool fNumField = false;

View File

@ -50,7 +50,7 @@ namespace XLS
bool fSbt = 0;
bool fBlock = 0;
bool fGrand = 0;
bool fMultiDataOnAxis = true;
bool fMultiDataOnAxis = false;
std::vector<short> rgisxvi;
};

View File

@ -56,7 +56,7 @@ public:
static const ElementType type = typeTheme;
//-----------------------------
_UINT32 dwThemeVersion = 0;
_UINT32 dwThemeVersion = 124226;
FrtHeader frtHeader;
_UINT32 nThemeDataSize = 0;

View File

@ -421,10 +421,13 @@ void XF::writeFields(CFRecord& record)
if(font_index == 0xffff)
font_index = 0;
if(ifmt == 0xffff)
ifmt = 164;
ifmt = 0;
FontIndex ifnt;
ifnt.setValue(font_index + 5);
if(font_index)
ifnt.setValue(font_index + 5);
else
ifnt.setValue(0);
record <<ifnt << ifmt;
_UINT16 flags = 0, flags5 = 0;
_UINT32 flags2 = 0, flags3 = 0, flags4 = 0;

View File

@ -66,7 +66,7 @@ namespace XLS
_UINT16 font_index = 0;
_UINT16 ifmt = 164; //used
_UINT16 ifmt = 0; //used
std::wstring format_code = L"";
_UINT16 ixfParent = 0xFFF;

View File

@ -71,7 +71,7 @@ void XFExt::readFields(CFRecord& record)
void XFExt::writeFields(CFRecord& record)
{
frtHeader.rt = 0x0892;
frtHeader.rt = 0x087D;
record << frtHeader;
record.reserveNunBytes(2); // reserved
record << ixfe;

View File

@ -192,19 +192,10 @@ public:
RwType rw;
ColType col = 0;
rw = row;
auto version = record.getGlobalWorkbookInfo()->Version;
if (version < 0x0800)
{
col = column;
}
else
{
SETBITS(col, 0, 13, column);
SETBIT(col, 14, colRelative);
SETBIT(col, 15, rowRelative);
}
SETBITS(col, 0, 13, column);
SETBIT(col, 14, colRelative);
SETBIT(col, 15, rowRelative);
record << rw << col;
}

View File

@ -67,9 +67,9 @@ public:
LeftBorderColor = 9,
RightBorderColor = 10,
DiagonalBorderColor = 11,
TextColor = 12,
FontScheme = 13,
Indent = 14
TextColor = 13,
FontScheme = 14,
Indent = 15
}extType = None;
struct extPropData_Tag

View File

@ -62,11 +62,11 @@ public:
virtual void save(CFRecord& record);
_UINT32 idField = 1;
_UINT32 lfdt = 1;
_UINT32 lfdt = 0;
_UINT32 lfxidt = 0;
_UINT32 ilta = 0;
_UINT32 cbFmtAgg = 0;
_UINT32 istnAgg = 0;
_UINT32 istnAgg = 0xFFFFFFFF;
bool fAutoFilter = false;
bool fAutoFilterHidden = false;

View File

@ -55,7 +55,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

@ -83,6 +83,25 @@ 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
if(i->pict_type == L".emf" || i->pict_type == L".wmf")
rh_own.recLen += 33;
rh_own.recLen += i->pict_size;
}
record << rh_own;
}
const unsigned short OfficeArtBStoreContainer::GetInstanceToStore()
{
return rgfb.size();

View File

@ -64,6 +64,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

@ -272,4 +272,125 @@ 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;
if(pict_type == L".emf")
FbseHeader.recInstance = 0x2;
else if(pict_type == L".wmf")
FbseHeader.recInstance = 0x3;
else if(pict_type == L".png")
FbseHeader.recInstance = 0x6;
else
FbseHeader.recInstance = 0x5;
FbseHeader.recType = 0xF007;
FbseHeader.recLen = pict_size + 36;
if(pict_type == L".emf" || pict_type == L".wmf")
FbseHeader.recLen += 58;
else
FbseHeader.recLen += 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;
if(pict_type == L".emf" || pict_type == L".wmf")
Size += 33; //metadata block
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;
}
}
if(pict_type == L".emf" || pict_type == L".wmf")
{
OfficeArtRecordHeader rc_header;
rc_header.recVer = 0;
if(pict_type == L".emf")
{
rc_header.recInstance = 0x3D4;
rc_header.recType = 0xF01A;
}
else if(pict_type == L".wmf")
{
rc_header.recInstance = 0x216;
rc_header.recType = 0xF01B;
}
rc_header.recLen = pict_size + 50;
record << rc_header;
record.reserveNunBytes(16);
_UINT32 cbSize = pict_size;
record << cbSize;
record.reserveNunBytes(16);
_UINT64 PtSize = 0;
record << PtSize;
_UINT32 cbSave = pict_size;
record << cbSave;
BYTE compression = 0xFE;
record << compression;
BYTE filter = 0xFE;
record << filter;
}
else
{
OfficeArtRecordHeader rc_header;
rc_header.recVer = 0;
if(pict_type == L".png")
{
rc_header.recInstance = 0x6E0;
rc_header.recType = 0xF01E;
}
else
{
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

@ -74,6 +74,7 @@ public:
}
virtual void load(XLS::CFRecord& record);
virtual void save(XLS::CFRecord& record);
static const XLS::ElementType type = XLS::typeOfficeArtBStoreContainerFileBlock;
@ -89,6 +90,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

@ -34,6 +34,7 @@
*/
#include "OfficeArtDgContainer.h"
#include "SimpleOfficeArtContainers.h"
namespace ODRAW
{
@ -150,29 +151,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

@ -65,6 +65,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

@ -64,4 +64,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

@ -56,10 +56,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

@ -79,10 +79,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
@ -1071,25 +1071,28 @@ public:
{
case ODRAW::rtLineTo:
{
if (valuePointer + 1 > m_arPoints.size())
for (_UINT16 j = 0; j < m_arSegments[i].m_nCount; j++)
{
break;
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:

View File

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

View File

@ -53,10 +53,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

@ -34,6 +34,7 @@
*/
#include "SimpleOfficeArtContainers.h"
#include "OfficeArtBStoreContainer.h"
namespace ODRAW
{
@ -60,6 +61,15 @@ void OfficeArtClientTextbox::loadFields(XLS::CFRecord& record)
}
}
void OfficeArtClientTextbox::save(XLS::CFRecord& record)
{
rh_own.recVer = 0x00;
rh_own.recInstance = 0;
rh_own.recType = 0xF00D;
rh_own.recLen = 0;
record << rh_own;
}
void OfficeArtClientData::loadFields(XLS::CFRecord& record)
{
if (rh_own.recLen > 0)
@ -128,6 +138,32 @@ void OfficeArtDggContainer::loadFields(XLS::CFRecord& record)
}
}
void OfficeArtDggContainer::save(XLS::CFRecord& record)
{
rh_own.recVer = 0xF;
rh_own.recInstance = 0;
rh_own.recType = 0xF000;
record << rh_own;
auto sizePos = record.getRdPtr();
if(m_OfficeArtFDGGBlock != nullptr)
m_OfficeArtFDGGBlock->save(record);
if(m_OfficeArtBStoreContainer != nullptr)
m_OfficeArtBStoreContainer->save(record);
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
auto recLen = rh_own.recLen;
if(m_OfficeArtBStoreContainer != nullptr)
{
//recLen+=8;//container Header
auto bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(m_OfficeArtBStoreContainer.get());
recLen+= bstore->rh_own.recLen;
}
record << recLen;
record.skipNunBytes(rh_own.recLen);
}
void OfficeArtSpgrContainer::loadFields(XLS::CFRecord& record)
{
OfficeArtContainer::loadFields(record);
@ -156,10 +192,11 @@ void OfficeArtSpgrContainer::save(XLS::CFRecord& record)
i->save(record);
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
auto recSize = record.getRdPtr() - sizePos;
rh_own.recLen += recSize;
record.RollRdPtrBack(recSize + 4);
record << rh_own.recLen;
record.skipNunBytes(rh_own.recLen);
record.skipNunBytes(recSize);
}
void OfficeArtSpContainer::loadFields(XLS::CFRecord& record)
@ -210,7 +247,8 @@ void OfficeArtSpContainer::save(XLS::CFRecord& record)
//calculating size
rh_own.recLen = record.getRdPtr() - sizePos;
record.RollRdPtrBack(rh_own.recLen + 4);
record << rh_own.recLen;
_UINT32 fullSize = rh_own.recLen + extraSize;
record << fullSize;
record.skipNunBytes(rh_own.recLen);
}

View File

@ -49,6 +49,7 @@ public:
static const XLS::ElementType type = XLS::typeOfficeArtDggContainer;
void loadFields(XLS::CFRecord& record);
void save(XLS::CFRecord& record);
OfficeArtRecordPtr m_OfficeArtBStoreContainer;
OfficeArtRecordPtr m_OfficeArtColorMRUContainer;
@ -101,6 +102,7 @@ public:
OfficeArtRecordPtr m_OfficeArtAnchor;
OfficeArtRecordPtr m_oOfficeArtFOPT;
OfficeArtRecordPtr m_oOfficeArtClientData;
unsigned int extraSize = 0;
};
class OfficeArtClientData : public OfficeArtRecord
@ -174,6 +176,7 @@ public:
XLS::BiffStructurePtr clone() { return XLS::BiffStructurePtr(new OfficeArtClientTextbox(*this)); }
void loadFields(XLS::CFRecord& record);
void save(XLS::CFRecord& record);
static const XLS::ElementType type = XLS::typeOfficeArtClientTextbox;
};

View File

@ -169,19 +169,28 @@ Ptg* PtgList::toArea()
{
tableRef.fromString(tableRefIndex->second);
tableRef.columnFirst += colFirst;
tableRef.columnLast = tableRef.columnFirst + (colLast - colFirst);
tableRef.columnLast = tableRef.columnFirst;
if(colLast > colFirst)
tableRef.columnLast += (colLast - colFirst);
if(rowType == 0x2) //headers
tableRef.rowLast = tableRef.rowFirst;
else if(rowType == 0x0) //data
{
tableRef.rowFirst++;
tableRef.rowLast--;
}
else if(rowType == 0x6) //dataheaders
tableRef.rowLast--;
else if(rowType == 0x0C) // datatotals
tableRef.rowFirst--;
tableRef.rowFirst++;
else if(rowType == 0x8) //totals
tableRef.rowFirst = tableRef.rowLast;
}
PtgArea3d* listArea = new PtgArea3d(0x3B, CellRef());
unsigned char ptgType = type_+1;
unsigned char areaType = 0x3B;
SETBITS(areaType,5,6, ptgType);
PtgArea3d* listArea = new PtgArea3d(areaType, CellRef());
listArea->ixti = ixti;
listArea->area = tableRef;
listArea->area.rowFirstRelative = false;

View File

@ -62,17 +62,17 @@ public:
//const std::wstring toString() const;
_UINT16 ixti;
BYTE columns;
BYTE rowType;
bool squareBracketSpace;
bool commaSpace;
_UINT16 ixti = 0;
BYTE columns = 0;
BYTE rowType = 0;
bool squareBracketSpace = false;
bool commaSpace = false;
BYTE type_;
bool invalid;
bool nonresident;
bool invalid = false;
bool nonresident = false;
_UINT32 listIndex;
_UINT16 colFirst;
_UINT16 colLast;
_UINT16 colFirst = 0;
_UINT16 colLast = 0;
private:
GlobalWorkbookInfoPtr global_info;

View File

@ -458,7 +458,7 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std::
if (boost::regex_search(first, last, results, reg_table_name))
{
std::wstring tableName;
_UINT32 indexTable;
_UINT32 indexTable = 0;
tableName = results.str(1);
if (XMLSTUFF::isTableFmla(tableName, indexTable))
@ -622,10 +622,12 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std::
}
else if (boost::regex_search(first, last, results_1, reg_inside_table6))
{
_UINT16 indexColumn = 0;
XMLSTUFF::isColumn(L"", indexTable, indexColumn);
ptgList.columns = 0;
ptgList.colFirst = 0;
ptgList.colLast = 0;
ptgList.rowType = 0x00;
ptgList.colLast = indexColumn;
ptgList.rowType = 0x0C;
first = results_1[0].second;
return true;
}

View File

@ -293,9 +293,10 @@ const bool CHARTFORMATS::loadContent(BinProcessor& proc)
const bool CHARTFORMATS::saveContent(BinProcessor& proc)
{
if(m_ChartRect == nullptr)
return false;
proc.mandatory(*m_ChartRect);
if(m_ChartRect != nullptr)
proc.mandatory(*m_ChartRect);
else
proc.mandatory<Chart>();
proc.mandatory<Begin>();
for(auto i : m_arFONTLIST)
{

View File

@ -51,6 +51,7 @@ public:
BaseObjectPtr clone();
virtual const bool loadContent(BinProcessor& proc);
virtual const bool saveContent(BinProcessor& proc);
static const ElementType type = typeMSODRAWINGGROUP;

View File

@ -36,6 +36,8 @@
#include "MSODRAWINGGROUP.h"
#include "../Biff_records/MsoDrawingGroup.h"
#include "../Biff_records/Continue.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
#include "../Biff_structures/ODRAW/OfficeArtBStoreContainerFileBlock.h"
namespace XLS
{
@ -74,5 +76,79 @@ const bool MSODRAWINGGROUP::loadContent(BinProcessor& proc)
return true;
}
const bool MSODRAWINGGROUP::saveContent(BinProcessor& proc)
{
auto MaxRecSize = 8224;
proc.mandatory(*m_MsoDrawingGroup);
auto castedGroup = static_cast<MsoDrawingGroup*>(m_MsoDrawingGroup.get());
if(castedGroup->rgChildRec.m_OfficeArtBStoreContainer)
{
auto bstore = static_cast<ODRAW::OfficeArtBStoreContainer*>(castedGroup->rgChildRec.m_OfficeArtBStoreContainer.get());
for (auto* block : bstore->rgfb)
{
CFRecord continueRecord(60, proc.getGlobalWorkbookInfo());
block->save(continueRecord);
size_t headerSize = continueRecord.getRdPtr();
size_t filePtr = 0;
const BYTE* data = (BYTE*)block->pict_data;
size_t dataSize = block->pict_size;
while (filePtr < dataSize)
{
size_t freeSpace;
if (filePtr == 0)
freeSpace = MaxRecSize - headerSize;
else
freeSpace = MaxRecSize;
size_t chunkSize = (std::min)(freeSpace, dataSize - filePtr);
XLS::Continue continueRec;
size_t recSize = (filePtr == 0)
? headerSize + chunkSize
: chunkSize;
continueRec.m_iDataSize = recSize;
continueRec.m_pData = new char[recSize];
if (filePtr == 0)
{
memcpy(
continueRec.m_pData,
continueRecord.getCurStaticData<BYTE>() - headerSize,
headerSize
);
memcpy(
continueRec.m_pData + headerSize,
data + filePtr,
chunkSize
);
}
else
{
auto datPtr = data + filePtr;
memcpy(
continueRec.m_pData,
datPtr,
chunkSize
);
auto testPt = datPtr;
auto test2 = testPt;
}
proc.mandatory(continueRec);
filePtr += chunkSize;
}
}
}
return true;
}
} // namespace XLS

View File

@ -57,6 +57,7 @@ public:
virtual const bool saveContent(BinProcessor& proc);
BaseObjectPtr m_Obj;
std::vector<BaseObjectPtr> m_arrChart;
static const ElementType type = typeOBJ;

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