LibreOffice Module writerfilter (master) 1
rtfdispatchflag.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <sal/config.h>
11
12#include <string_view>
13
14#include "rtfdocumentimpl.hxx"
15
16#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
17#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
18#include <com/sun/star/text/RelOrientation.hpp>
19#include <com/sun/star/text/VertOrientation.hpp>
20#include <com/sun/star/lang/XMultiServiceFactory.hpp>
21
23
24#include <ooxml/resourceids.hxx>
25
26#include <sal/log.hxx>
27
28#include "rtfsdrimport.hxx"
30
31using namespace com::sun::star;
32
34{
36{
37 // Positioned Wrapped Tables
38 OUString aParam;
39 switch (nKeyword)
40 {
42 aParam = "text";
43 break;
45 aParam = "margin";
46 break;
48 aParam = "page";
49 break;
50 default:
51 break;
52 }
53 if (!aParam.isEmpty())
54 {
55 putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblpPr,
56 NS_ooxml::LN_CT_TblPPr_vertAnchor, new RTFValue(aParam));
57 return true;
58 }
59 switch (nKeyword)
60 {
62 aParam = "text";
63 break;
65 aParam = "margin";
66 break;
68 aParam = "page";
69 break;
70 default:
71 break;
72 }
73 if (!aParam.isEmpty())
74 {
75 putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblpPr,
76 NS_ooxml::LN_CT_TblPPr_horzAnchor, new RTFValue(aParam));
77 return true;
78 }
79 switch (nKeyword)
80 {
82 aParam = "center";
83 break;
85 aParam = "bottom";
86 break;
87 default:
88 break;
89 }
90 if (!aParam.isEmpty())
91 {
92 putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblpPr,
93 NS_ooxml::LN_CT_TblPPr_tblpYSpec, new RTFValue(aParam));
94 return true;
95 }
96 switch (nKeyword)
97 {
99 aParam = "center";
100 break;
102 aParam = "right";
103 break;
104 default:
105 break;
106 }
107 if (!aParam.isEmpty())
108 {
109 putNestedAttribute(m_aStates.top().getTableRowSprms(), NS_ooxml::LN_CT_TblPrBase_tblpPr,
110 NS_ooxml::LN_CT_TblPPr_tblpXSpec, new RTFValue(aParam));
111 return true;
112 }
113
114 return false;
115}
116
118{
119 setNeedSect(true);
120 checkUnicode(/*bUnicode =*/true, /*bHex =*/true);
121 RTFSkipDestination aSkip(*this);
122 int nParam = -1;
123 int nSprm = -1;
124
125 // Underline flags.
126 switch (nKeyword)
127 {
128 case RTFKeyword::ULD:
129 nSprm = NS_ooxml::LN_Value_ST_Underline_dotted;
130 break;
131 case RTFKeyword::ULW:
132 nSprm = NS_ooxml::LN_Value_ST_Underline_words;
133 break;
134 default:
135 break;
136 }
137 if (nSprm >= 0)
138 {
139 auto pValue = new RTFValue(nSprm);
140 m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_Underline_val, pValue);
141 return RTFError::OK;
142 }
143
144 // Indentation
145 switch (nKeyword)
146 {
147 case RTFKeyword::QC:
148 nParam = NS_ooxml::LN_Value_ST_Jc_center;
149 break;
150 case RTFKeyword::QJ:
151 nParam = NS_ooxml::LN_Value_ST_Jc_both;
152 break;
153 case RTFKeyword::QL:
154 nParam = NS_ooxml::LN_Value_ST_Jc_left;
155 break;
156 case RTFKeyword::QR:
157 nParam = NS_ooxml::LN_Value_ST_Jc_right;
158 break;
159 case RTFKeyword::QD:
160 nParam = NS_ooxml::LN_Value_ST_Jc_distribute;
161 break;
162 default:
163 break;
164 }
165 if (nParam >= 0)
166 {
167 auto pValue = new RTFValue(nParam);
168 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_jc, pValue);
169 m_bNeedPap = true;
170 return RTFError::OK;
171 }
172
173 // Font Alignment
174 switch (nKeyword)
175 {
178 nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_auto;
179 break;
181 nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_top;
182 break;
184 nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_center;
185 break;
187 nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline;
188 break;
190 nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom;
191 break;
192 default:
193 break;
194 }
195 if (nParam >= 0)
196 {
197 auto pValue = new RTFValue(nParam);
198 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_textAlignment, pValue);
199 return RTFError::OK;
200 }
201
202 // Tab kind.
203 switch (nKeyword)
204 {
205 case RTFKeyword::TQR:
206 nParam = NS_ooxml::LN_Value_ST_TabJc_right;
207 break;
208 case RTFKeyword::TQC:
209 nParam = NS_ooxml::LN_Value_ST_TabJc_center;
210 break;
212 nParam = NS_ooxml::LN_Value_ST_TabJc_decimal;
213 break;
214 default:
215 break;
216 }
217 if (nParam >= 0)
218 {
219 auto pValue = new RTFValue(nParam);
220 m_aStates.top().getTabAttributes().set(NS_ooxml::LN_CT_TabStop_val, pValue);
221 return RTFError::OK;
222 }
223
224 // Tab lead.
225 switch (nKeyword)
226 {
228 nParam = NS_ooxml::LN_Value_ST_TabTlc_dot;
229 break;
231 nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot;
232 break;
234 nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen;
235 break;
236 case RTFKeyword::TLUL:
237 case RTFKeyword::TLTH:
238 nParam = NS_ooxml::LN_Value_ST_TabTlc_underscore;
239 break;
240 case RTFKeyword::TLEQ:
241 default:
242 break;
243 }
244 if (nParam >= 0)
245 {
246 auto pValue = new RTFValue(nParam);
247 m_aStates.top().getTabAttributes().set(NS_ooxml::LN_CT_TabStop_leader, pValue);
248 return RTFError::OK;
249 }
250
251 // Border types
252 {
253 switch (nKeyword)
254 {
255 // brdrhair and brdrs are the same, brdrw will make a difference
256 // map to values in ooxml/model.xml resource ST_Border
259 nParam = NS_ooxml::LN_Value_ST_Border_single;
260 break;
262 nParam = NS_ooxml::LN_Value_ST_Border_dotted;
263 break;
265 nParam = NS_ooxml::LN_Value_ST_Border_dashed;
266 break;
268 nParam = NS_ooxml::LN_Value_ST_Border_double;
269 break;
271 nParam = NS_ooxml::LN_Value_ST_Border_thinThickSmallGap;
272 break;
274 nParam = NS_ooxml::LN_Value_ST_Border_thinThickMediumGap;
275 break;
277 nParam = NS_ooxml::LN_Value_ST_Border_thinThickLargeGap;
278 break;
280 nParam = NS_ooxml::LN_Value_ST_Border_thickThinSmallGap;
281 break;
283 nParam = NS_ooxml::LN_Value_ST_Border_thickThinMediumGap;
284 break;
286 nParam = NS_ooxml::LN_Value_ST_Border_thickThinLargeGap;
287 break;
289 nParam = NS_ooxml::LN_Value_ST_Border_threeDEmboss;
290 break;
292 nParam = NS_ooxml::LN_Value_ST_Border_threeDEngrave;
293 break;
295 nParam = NS_ooxml::LN_Value_ST_Border_outset;
296 break;
298 nParam = NS_ooxml::LN_Value_ST_Border_inset;
299 break;
301 nParam = NS_ooxml::LN_Value_ST_Border_dashSmallGap;
302 break;
304 nParam = NS_ooxml::LN_Value_ST_Border_dotDash;
305 break;
307 nParam = NS_ooxml::LN_Value_ST_Border_dotDotDash;
308 break;
310 nParam = NS_ooxml::LN_Value_ST_Border_none;
311 break;
312 default:
313 break;
314 }
315 if (nParam >= 0)
316 {
317 auto pValue = new RTFValue(nParam);
318 putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_val, pValue);
319 return RTFError::OK;
320 }
321 }
322
323 // Section breaks
324 switch (nKeyword)
325 {
327 nParam = NS_ooxml::LN_Value_ST_SectionMark_continuous;
328 break;
330 nParam = NS_ooxml::LN_Value_ST_SectionMark_nextColumn;
331 break;
333 nParam = NS_ooxml::LN_Value_ST_SectionMark_nextPage;
334 break;
336 nParam = NS_ooxml::LN_Value_ST_SectionMark_evenPage;
337 break;
339 nParam = NS_ooxml::LN_Value_ST_SectionMark_oddPage;
340 break;
341 default:
342 break;
343 }
344 if (nParam >= 0)
345 {
347 {
348 m_nResetBreakOnSectBreak = nKeyword;
349 }
350 auto pValue = new RTFValue(nParam);
351 m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_type, pValue);
352 return RTFError::OK;
353 }
354
355 // Footnote numbering
356 switch (nKeyword)
357 {
359 nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
360 break;
362 nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
363 break;
365 nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
366 break;
368 nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
369 break;
371 nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
372 break;
374 nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
375 break;
376 default:
377 break;
378 }
379 if (nParam >= 0)
380 {
381 auto pInner = new RTFValue(nParam);
382 RTFSprms aAttributes;
383 aAttributes.set(NS_ooxml::LN_CT_NumFmt_val, pInner);
384 auto pOuter = new RTFValue(aAttributes);
386 NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt,
387 pOuter);
388 return RTFError::OK;
389 }
390
391 // Footnote restart type
392 switch (nKeyword)
393 {
395 nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage;
396 break;
398 nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect;
399 break;
401 nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous;
402 break;
403 default:
404 break;
405 }
406 if (nParam >= 0)
407 {
408 auto pValue = new RTFValue(nParam);
410 NS_ooxml::LN_EG_SectPrContents_footnotePr,
411 NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
412 return RTFError::OK;
413 }
414
415 // Endnote numbering
416 switch (nKeyword)
417 {
419 nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal;
420 break;
422 nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter;
423 break;
425 nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter;
426 break;
428 nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman;
429 break;
431 nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman;
432 break;
434 nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago;
435 break;
436 default:
437 break;
438 }
439 if (nParam >= 0)
440 {
441 auto pInner = new RTFValue(nParam);
442 RTFSprms aAttributes;
443 aAttributes.set(NS_ooxml::LN_CT_NumFmt_val, pInner);
444 auto pOuter = new RTFValue(aAttributes);
445 putNestedSprm(m_aDefaultState.getParagraphSprms(), NS_ooxml::LN_EG_SectPrContents_endnotePr,
446 NS_ooxml::LN_CT_EdnProps_numFmt, pOuter);
447 return RTFError::OK;
448 }
449
450 switch (nKeyword)
451 {
452 case RTFKeyword::TRQL:
453 nParam = NS_ooxml::LN_Value_ST_Jc_left;
454 break;
455 case RTFKeyword::TRQC:
456 nParam = NS_ooxml::LN_Value_ST_Jc_center;
457 break;
458 case RTFKeyword::TRQR:
459 nParam = NS_ooxml::LN_Value_ST_Jc_right;
460 break;
461 default:
462 break;
463 }
464 if (nParam >= 0)
465 {
466 auto pValue = new RTFValue(nParam);
467 m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TrPrBase_jc, pValue);
468 return RTFError::OK;
469 }
470
471 // Cell Text Flow
472 switch (nKeyword)
473 {
475 nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTb;
476 break;
478 nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRl;
479 break;
481 nParam = NS_ooxml::LN_Value_ST_TextDirection_btLr;
482 break;
484 nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTbV;
485 break;
487 nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRlV;
488 break;
489 default:
490 break;
491 }
492 if (nParam >= 0)
493 {
494 auto pValue = new RTFValue(nParam);
495 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
496 }
497
498 // Trivial paragraph flags
499 switch (nKeyword)
500 {
501 case RTFKeyword::KEEP:
503 nParam = NS_ooxml::LN_CT_PPrBase_keepLines;
504 break;
506 nParam = NS_ooxml::LN_CT_PPrBase_keepNext;
507 break;
509 {
511 nParam = NS_ooxml::LN_inTbl;
512 }
513 break;
515 nParam = NS_ooxml::LN_CT_PPrBase_pageBreakBefore;
516 break;
517 default:
518 break;
519 }
520 if (nParam >= 0)
521 {
522 auto pValue = new RTFValue(1);
523 m_aStates.top().getParagraphSprms().set(nParam, pValue);
524 return RTFError::OK;
525 }
526
527 if (dispatchFloatingTableFlag(nKeyword))
528 {
529 return RTFError::OK;
530 }
531
532 switch (nKeyword)
533 {
534 case RTFKeyword::FNIL:
542 // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
543 break;
544 case RTFKeyword::ANSI:
545 m_aStates.top().setCurrentEncoding(RTL_TEXTENCODING_MS_1252);
546 break;
547 case RTFKeyword::MAC:
548 m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_APPLE_ROMAN);
550 break;
551 case RTFKeyword::PC:
552 m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_IBM_437);
554 break;
555 case RTFKeyword::PCA:
556 m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_IBM_850);
558 break;
560 {
566 }
567 break;
568 case RTFKeyword::PARD:
569 {
570 if (m_bHadPicture)
572 // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table.
573 // It should not reset the paragraph style, either, so remember the old paragraph style.
574 RTFValue::Pointer_t pOldStyle
575 = m_aStates.top().getParagraphSprms().find(NS_ooxml::LN_CT_PPrBase_pStyle);
578
579 if (m_nTopLevelCells == 0 && m_nNestedCells == 0)
580 {
581 // Reset that we're in a table.
582 m_aStates.top().setCurrentBuffer(nullptr);
583 }
584 else
585 {
586 // We are still in a table.
587 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_inTbl, new RTFValue(1));
588 if (m_bAfterCellBeforeRow && pOldStyle)
589 // And we still have the same paragraph style.
590 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle,
591 pOldStyle);
592 // Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering.
593 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_tabs,
594 new RTFValue());
595 }
596 resetFrame();
597
598 // Reset currently selected paragraph style as well, unless we are in the special "after \cell, before \row" state.
599 // By default the style with index 0 is applied.
601 {
602 OUString const aName = getStyleName(0);
603 // But only in case it's not a character style.
604 if (!aName.isEmpty()
605 && getStyleType(0) != NS_ooxml::LN_Value_ST_StyleType_character)
606 {
607 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle,
608 new RTFValue(aName));
609 }
611 }
612 // Need to send paragraph properties again, if there will be any.
613 m_bNeedPap = true;
614 break;
615 }
617 {
620 }
621 break;
623 {
624 // Back these up, in case later we still need this info.
627 // In case the table definition is in the middle of the row
628 // (invalid), make sure table definition is emitted.
629 m_bNeedPap = true;
630 }
631 break;
634 {
635 auto pValue = new RTFValue(int(nKeyword == RTFKeyword::WIDCTLPAR));
636 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_widowControl, pValue);
637 }
638 break;
639 case RTFKeyword::BOX:
640 {
641 RTFSprms aAttributes;
642 auto pValue = new RTFValue(aAttributes);
643 for (int i = 0; i < 4; i++)
646 }
647 break;
650 {
651 auto pValue = new RTFValue(nKeyword == RTFKeyword::LTRSECT ? 0 : 1);
653 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_EG_SectPrContents_textDirection,
654 pValue);
655 }
656 break;
659 {
660 auto pValue = new RTFValue(nKeyword == RTFKeyword::LTRPAR ? 0 : 1);
662 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_bidi, pValue);
663 }
664 break;
669 NS_ooxml::LN_CT_TblPrBase_bidiVisual,
670 new RTFValue(int(nKeyword == RTFKeyword::RTLROW)));
671 break;
673 // dmapper does not support this.
676 else
678 break;
682 else
684
685 if (m_aDefaultState.getCurrentEncoding() == RTL_TEXTENCODING_MS_1255)
687 break;
689 {
690 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Underline_none);
691 m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_Underline_val, pValue);
692 }
693 break;
695 case RTFKeyword::MMATHPICT: // Picture group used by readers not understanding \moMath group
697 break;
702 {
703 RTFSprms aAttributes;
704 RTFSprms aSprms;
705 auto pValue = new RTFValue(aAttributes, aSprms);
706 switch (nKeyword)
707 {
709 nSprm = NS_ooxml::LN_CT_TcBorders_top;
710 break;
712 nSprm = NS_ooxml::LN_CT_TcBorders_left;
713 break;
715 nSprm = NS_ooxml::LN_CT_TcBorders_bottom;
716 break;
718 nSprm = NS_ooxml::LN_CT_TcBorders_right;
719 break;
720 default:
721 break;
722 }
723 putNestedSprm(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcBorders,
724 nSprm, pValue);
726 }
727 break;
732 {
733 RTFSprms aAttributes;
734 RTFSprms aSprms;
735 auto pValue = new RTFValue(aAttributes, aSprms);
736 switch (nKeyword)
737 {
739 nSprm = NS_ooxml::LN_CT_PageBorders_top;
740 break;
742 nSprm = NS_ooxml::LN_CT_PageBorders_left;
743 break;
745 nSprm = NS_ooxml::LN_CT_PageBorders_bottom;
746 break;
748 nSprm = NS_ooxml::LN_CT_PageBorders_right;
749 break;
750 default:
751 break;
752 }
754 NS_ooxml::LN_EG_SectPrContents_pgBorders, nSprm, pValue);
756 }
757 break;
763 {
764 RTFSprms aAttributes;
765 RTFSprms aSprms;
766 auto pValue = new RTFValue(aAttributes, aSprms);
767 switch (nKeyword)
768 {
770 nSprm = getParagraphBorder(0);
771 break;
773 nSprm = getParagraphBorder(1);
774 break;
776 nSprm = getParagraphBorder(2);
777 break;
779 nSprm = getParagraphBorder(3);
780 break;
782 nSprm = getParagraphBorder(4);
783 break;
784 default:
785 break;
786 }
787 putNestedSprm(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PrBase_pBdr, nSprm,
788 pValue);
790 }
791 break;
793 {
794 RTFSprms aAttributes;
795 auto pValue = new RTFValue(aAttributes);
796 m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_bdr, pValue);
798 }
799 break;
801 {
802 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart);
803 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
804 }
805 break;
807 {
808 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue);
809 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
810 }
811 break;
813 {
814 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart);
815 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
816 }
817 break;
819 {
820 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue);
821 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
822 }
823 break;
827 {
828 switch (nKeyword)
829 {
831 nParam = NS_ooxml::LN_Value_ST_VerticalJc_top;
832 break;
834 nParam = NS_ooxml::LN_Value_ST_VerticalJc_center;
835 break;
837 nParam = NS_ooxml::LN_Value_ST_VerticalJc_bottom;
838 break;
839 default:
840 break;
841 }
842 auto pValue = new RTFValue(nParam);
843 m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
844 }
845 break;
847 {
848 auto pValue = new RTFValue(1);
849 m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TrPrBase_cantSplit, pValue);
850 }
851 break;
853 {
854 auto pValue = new RTFValue(0);
855 m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
856 }
857 break;
860 // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
861 break;
862 case RTFKeyword::LOCH:
864 break;
865 case RTFKeyword::HICH:
867 break;
868 case RTFKeyword::DBCH:
870 break;
872 {
873 auto pValue = new RTFValue(1);
874 m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
875 }
876 break;
878 {
879 // Make sure character properties are not lost if the document
880 // starts with a footnote.
881 if (!isStyleSheetImport())
882 {
884 checkNeedPap();
885 }
886
889
890 auto pValue = new RTFValue("superscript");
891 m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
892 }
893 break;
894 case RTFKeyword::SUB:
895 {
896 auto pValue = new RTFValue("subscript");
897 m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
898 }
899 break;
901 {
903 {
904 replayBuffer(m_aSuperBuffer, nullptr, nullptr);
905 m_aStates.top().setCurrentBuffer(nullptr);
906 }
907 m_aStates.top().getCharacterSprms().erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
908 }
909 break;
912 {
913 auto pValue = new RTFValue(nKeyword == RTFKeyword::LINEPPAGE
914 ? NS_ooxml::LN_Value_ST_LineNumberRestart_newPage
915 : NS_ooxml::LN_Value_ST_LineNumberRestart_continuous);
917 NS_ooxml::LN_EG_SectPrContents_lnNumType,
918 NS_ooxml::LN_CT_LineNumber_restart, pValue);
919 }
920 break;
922 // Noop, this is the default in Writer.
924 // Noop
926 // Noop, this is the default in Writer.
928 // Noop
930 // Noop, this is the default in Writer.
931 break;
933 {
934 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect);
936 NS_ooxml::LN_EG_SectPrContents_footnotePr,
937 NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
938 }
939 break;
942 NS_ooxml::LN_EG_SectPrContents_lnNumType,
943 NS_ooxml::LN_CT_LineNumber_distance);
944 break;
946 // Noop, this is the default in Writer.
947 break;
950 break;
953 break;
955 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
956 NS_ooxml::LN_Value_doc_ST_YAlign_top);
957 break;
959 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
960 NS_ooxml::LN_Value_doc_ST_YAlign_bottom);
961 break;
963 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
964 NS_ooxml::LN_Value_doc_ST_YAlign_center);
965 break;
967 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
968 NS_ooxml::LN_Value_doc_ST_YAlign_inside);
969 break;
971 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
972 NS_ooxml::LN_Value_doc_ST_YAlign_outside);
973 break;
975 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign,
976 NS_ooxml::LN_Value_doc_ST_YAlign_inline);
977 break;
978
980 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor,
981 NS_ooxml::LN_Value_doc_ST_HAnchor_margin);
982 break;
984 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor,
985 NS_ooxml::LN_Value_doc_ST_VAnchor_margin);
986 break;
987 case RTFKeyword::PHPG:
988 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor,
989 NS_ooxml::LN_Value_doc_ST_HAnchor_page);
990 break;
991 case RTFKeyword::PVPG:
992 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor,
993 NS_ooxml::LN_Value_doc_ST_VAnchor_page);
994 break;
996 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor,
997 NS_ooxml::LN_Value_doc_ST_HAnchor_text);
998 break;
1000 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor,
1001 NS_ooxml::LN_Value_doc_ST_VAnchor_text);
1002 break;
1003
1004 case RTFKeyword::POSXC:
1005 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign,
1006 NS_ooxml::LN_Value_doc_ST_XAlign_center);
1007 break;
1008 case RTFKeyword::POSXI:
1009 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign,
1010 NS_ooxml::LN_Value_doc_ST_XAlign_inside);
1011 break;
1012 case RTFKeyword::POSXO:
1013 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign,
1014 NS_ooxml::LN_Value_doc_ST_XAlign_outside);
1015 break;
1016 case RTFKeyword::POSXL:
1017 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign,
1018 NS_ooxml::LN_Value_doc_ST_XAlign_left);
1019 break;
1020 case RTFKeyword::POSXR:
1021 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign,
1022 NS_ooxml::LN_Value_doc_ST_XAlign_right);
1023 break;
1024
1025 case RTFKeyword::DPLINE:
1026 case RTFKeyword::DPRECT:
1028 case RTFKeyword::DPTXBX:
1031 {
1032 sal_Int32 nType = 0;
1033 switch (nKeyword)
1034 {
1035 case RTFKeyword::DPLINE:
1036 {
1038 getModelFactory()->createInstance("com.sun.star.drawing.LineShape"),
1039 uno::UNO_QUERY);
1041 break;
1042 }
1044 {
1045 // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
1047 getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"),
1048 uno::UNO_QUERY);
1050 break;
1051 }
1053 {
1055 getModelFactory()->createInstance("com.sun.star.drawing.PolyPolygonShape"),
1056 uno::UNO_QUERY);
1058 break;
1059 }
1060 case RTFKeyword::DPRECT:
1061 {
1063 getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"),
1064 uno::UNO_QUERY);
1066 break;
1067 }
1070 break;
1071 case RTFKeyword::DPTXBX:
1072 {
1074 getModelFactory()->createInstance("com.sun.star.text.TextFrame"),
1075 uno::UNO_QUERY);
1077 std::vector<beans::PropertyValue> aDefaults
1079 for (const auto& rDefault : aDefaults)
1080 {
1081 if (!findPropertyName(
1083 rDefault.Name))
1085 rDefault);
1086 }
1087 checkFirstRun();
1090 }
1091 break;
1092 default:
1093 break;
1094 }
1095 if (nType)
1096 {
1098 getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"),
1099 uno::UNO_QUERY);
1101 }
1102 uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY);
1104 m_aStates.top().getDrawingObject().getShape(), uno::UNO_QUERY);
1105 m_aStates.top().getDrawingObject().setPropertySet(xPropertySet);
1106 if (xDrawSupplier.is())
1107 {
1108 uno::Reference<drawing::XShapes> xShapes = xDrawSupplier->getDrawPage();
1109 if (xShapes.is() && nKeyword != RTFKeyword::DPTXBX)
1110 {
1111 // set default VertOrient before inserting
1112 m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue(
1113 "VertOrient", uno::Any(text::VertOrientation::NONE));
1114 xShapes->add(m_aStates.top().getDrawingObject().getShape());
1115 }
1116 }
1117 if (nType)
1118 {
1120 m_aStates.top().getDrawingObject().getShape(), uno::UNO_QUERY);
1121 xDefaulter->createCustomShapeDefaults(OUString::number(nType));
1122 }
1123 std::vector<beans::PropertyValue>& rPendingProperties
1125 for (const auto& rPendingProperty : rPendingProperties)
1126 m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue(
1127 rPendingProperty.Name, rPendingProperty.Value);
1130 /*bOldStyle=*/true);
1131 }
1132 break;
1135 {
1136 beans::PropertyValue aPropertyValue;
1137 aPropertyValue.Name
1138 = (nKeyword == RTFKeyword::DOBXMARGIN ? std::u16string_view(u"HoriOrientRelation")
1139 : std::u16string_view(u"VertOrientRelation"));
1140 aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
1141 m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue);
1142 }
1143 break;
1146 {
1147 beans::PropertyValue aPropertyValue;
1148 aPropertyValue.Name
1149 = (nKeyword == RTFKeyword::DOBXPAGE ? std::u16string_view(u"HoriOrientRelation")
1150 : std::u16string_view(u"VertOrientRelation"));
1151 aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
1152 m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue);
1153 }
1154 break;
1156 {
1157 beans::PropertyValue aPropertyValue;
1158 aPropertyValue.Name = "VertOrientRelation";
1159 aPropertyValue.Value <<= text::RelOrientation::FRAME;
1160 m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue);
1161 }
1162 break;
1164 {
1165 auto pValue = new RTFValue(1);
1166 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_contextualSpacing,
1167 pValue);
1168 }
1169 break;
1171 {
1172 auto pValue = new RTFValue(1);
1173 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
1174 }
1175 break;
1177 {
1178 auto pValue = new RTFValue(2);
1179 m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_nsid, pValue);
1180 }
1181 break;
1182 case RTFKeyword::PNDEC:
1183 {
1184 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_decimal);
1185 putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_numFmt,
1186 NS_ooxml::LN_CT_NumFmt_val, pValue);
1187 }
1188 break;
1190 {
1191 m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_nsid,
1192 new RTFValue(1));
1193 putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_numFmt,
1194 NS_ooxml::LN_CT_NumFmt_val,
1195 new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_bullet));
1196 }
1197 break;
1199 {
1200 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
1202 NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient,
1203 pValue);
1204 [[fallthrough]]; // set the default + current value
1205 }
1207 {
1208 auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_PageOrientation_landscape);
1210 NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient,
1211 pValue);
1212 }
1213 break;
1215 m_aStates.top().getShape().setHoriOrientRelation(text::RelOrientation::PAGE_FRAME);
1217 NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page);
1218 break;
1220 m_aStates.top().getShape().setVertOrientRelation(text::RelOrientation::PAGE_FRAME);
1222 NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page);
1223 break;
1226 break;
1229 // Seems this old syntax has no way to specify a custom radius, and this is the default
1230 m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue(
1231 "CornerRadius", uno::Any(sal_Int32(83)));
1232 break;
1233 case RTFKeyword::NOWRAP:
1234 m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_wrap,
1235 NS_ooxml::LN_Value_doc_ST_Wrap_notBeside);
1236 break;
1237 case RTFKeyword::MNOR:
1238 m_bMathNor = true;
1239 break;
1241 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_trackRevisions, new RTFValue(1));
1242 break;
1243 case RTFKeyword::BRDRSH:
1244 putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_shadow, new RTFValue(1));
1245 break;
1247 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_noColumnBalance, new RTFValue(1));
1248 break;
1250 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_mirrorMargins, new RTFValue(1));
1251 break;
1253 m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Style_autoRedefine,
1254 new RTFValue(1));
1255 break;
1257 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_widowControl, new RTFValue(1));
1258 break;
1261 NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_sep,
1262 new RTFValue(1));
1263 break;
1266 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1267 NS_ooxml::LN_CT_PageNumber_start, new RTFValue(1));
1268 break;
1270 {
1271 auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_upperLetter);
1273 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1274 NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
1275 }
1276 break;
1278 {
1279 auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter);
1281 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1282 NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
1283 }
1284 break;
1286 {
1287 auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_upperRoman);
1289 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1290 NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
1291 }
1292 break;
1294 {
1295 auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman);
1297 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1298 NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
1299 }
1300 break;
1301 case RTFKeyword::PGNDEC:
1302 {
1303 auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_decimal);
1305 NS_ooxml::LN_EG_SectPrContents_pgNumType,
1306 NS_ooxml::LN_CT_PageNumber_fmt, pIntValue);
1307 }
1308 break;
1310 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing,
1311 new RTFValue(0));
1312 break;
1314 // tdf#128428 switch off longer space sequence
1315 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_longerSpaceSequence,
1316 new RTFValue(0));
1317 break;
1319 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_gutterAtTop, new RTFValue(1));
1320 break;
1322 {
1323 m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_rtlGutter,
1324 new RTFValue(1));
1325 }
1326 break;
1328 {
1331 }
1332 break;
1334 {
1335 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_doNotBreakWrappedTables,
1336 new RTFValue(0));
1337 }
1338 break;
1339 default:
1340 {
1341 SAL_INFO("writerfilter", "TODO handle flag '" << keywordToString(nKeyword) << "'");
1342 aSkip.setParsed(false);
1343 }
1344 break;
1345 }
1346 return RTFError::OK;
1347}
1348
1349} // namespace writerfilter
1350
1351/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
virtual void startShape(css::uno::Reference< css::drawing::XShape > const &xShape)=0
Receives a shape.
void setNeedSect(bool bNeedSect)
If we need a final section break at the end of the document.
bool m_bHadPicture
A picture was seen in the current paragraph.
std::deque< RTFBuffer_t > m_aTableBufferStack
Buffered table cells, till cell definitions are not reached.
int m_nDefaultFontIndex
Raw default font index, use getFont() on it to get a real one.
bool isStyleSheetImport()
Are we inside the stylesheet table?
RTFKeyword m_nResetBreakOnSectBreak
clean up a synthetic page break, see RTF_PAGE if inactive value is -1, otherwise the RTF_SKB* to rest...
void resetFrame()
Resets m_aStates.top().aFrame.
RTFError dispatchSymbol(RTFKeyword nKeyword) override
RTFSprms m_aSettingsTableSprms
The settings table sprms.
void checkUnicode(bool bUnicode, bool bHex)
If we have some unicode or hex characters to send.
RTFBuffer_t m_aSuperBuffer
Buffered superscript, till footnote is reached (or not).
Id getStyleType(int nIndex)
Return the style type of an RTF style index.
bool dispatchFloatingTableFlag(RTFKeyword nKeyword)
Dispatches flags related to Positioned Wrapped Tables.
RTFParserState & getDefaultState()
Get the default parser state.
int m_nNestedCells
cell props buffer for nested tables, reset by \nestrow the \nesttableprops is a destination and must ...
const css::uno::Reference< css::lang::XMultiServiceFactory > & getModelFactory() const
OUString getStyleName(int nIndex)
Return the style name of an RTF style index.
int getFontIndex(int nIndex)
Return the dmapper index of an RTF index for fonts.
bool m_bMathNor
Normal text property, that is math italic and math spacing are not applied to the current run.
css::uno::Reference< css::lang::XComponent > const & m_xDstDoc
int m_nTopLevelCells
cell props buffer for top-level table, reset by \row
RTFParserState m_aDefaultState
Read by RTF_PARD.
void checkFirstRun()
If this is the first run of the document, starts the initial paragraph.
void replayBuffer(RTFBuffer_t &rBuffer, RTFSprms *pSprms, RTFSprms const *pAttributes)
tools::SvRef< RTFSdrImport > m_pSdrImport
RTFError dispatchFlag(RTFKeyword nKeyword) override
bool m_bAfterCellBeforeRow
Are we after a \cell, but before a \row?
rtl_TextEncoding getEncoding(int nFontIndex)
Return the encoding associated with a font index.
bool m_bNeedPap
If paragraph properties should be emitted on next run.
void setPropertySet(const css::uno::Reference< css::beans::XPropertySet > &xPropertySet)
const css::uno::Reference< css::beans::XPropertySet > & getPropertySet() const
std::vector< css::beans::PropertyValue > & getPendingProperties()
void setHadShapeText(bool bHadShapeText)
const css::uno::Reference< css::drawing::XShape > & getShape() const
void setShape(const css::uno::Reference< css::drawing::XShape > &xShape)
void setSprm(Id nId, Id nValue)
Store a property.
void setCurrentCharacterStyleIndex(int nCurrentCharacterStyleIndex)
void setCurrentEncoding(rtl_TextEncoding nCurrentEncoding)
void setCurrentStyleIndex(int nCurrentStyleIndex)
void setBorderState(RTFBorderState nBorderState)
void setCurrentBuffer(RTFBuffer_t *pCurrentBuffer)
rtl_TextEncoding getCurrentEncoding() const
void setDestination(Destination eDestination)
static std::vector< css::beans::PropertyValue > getTextFrameDefaults(bool bNew)
These are the default in Word, but not in Writer.
void setHoriOrientRelation(sal_Int16 nHoriOrientRelation)
void setVertOrientRelationToken(sal_uInt32 nVertOrientRelationToken)
void setVertOrientRelation(sal_Int16 nVertOrientRelation)
void setHoriOrientRelationToken(sal_uInt32 nHoriOrientRelationToken)
Skips a destination after a not parsed control word if it was prefixed with *.
A list of RTFSprm with a copy constructor that performs a deep copy.
Definition: rtfsprm.hxx:39
RTFValue::Pointer_t find(Id nKeyword, bool bFirst=true, bool bForWrite=false)
Definition: rtfsprm.cxx:74
void set(Id nKeyword, const RTFValue::Pointer_t &pValue, RTFOverwrite eOverwrite=RTFOverwrite::YES)
Does the same as ->push_back(), except that it can overwrite or ignore existing entries.
Definition: rtfsprm.cxx:98
bool erase(Id nKeyword)
Definition: rtfsprm.cxx:136
Value of an RTF keyword.
Definition: rtfvalue.hxx:33
float u
#define ESCHER_ShpInst_Ellipse
OUString aName
#define SAL_INFO(area, stream)
int i
bool findPropertyName(const std::vector< beans::PropertyValue > &rProperties, const OUString &rName)
void putNestedAttribute(RTFSprms &rSprms, Id nParent, Id nId, const RTFValue::Pointer_t &pValue, RTFOverwrite eOverwrite, bool bAttribute)
bool eraseNestedAttribute(RTFSprms &rSprms, Id nParent, Id nId)
void putNestedSprm(RTFSprms &rSprms, Id nParent, Id nId, const RTFValue::Pointer_t &pValue, RTFOverwrite eOverwrite)
Id getParagraphBorder(sal_uInt32 nIndex)
const char * keywordToString(RTFKeyword nKeyword)
void putBorderProperty(RTFStack &aStates, Id nId, const RTFValue::Pointer_t &pValue)
QPRO_FUNC_TYPE nType