LibreOffice Module sw (master)  1
rtfattributeoutput.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  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "rtfattributeoutput.hxx"
21 #include <memory>
22 #include <cstring>
23 #include "rtfsdrexport.hxx"
24 #include "writerwordglue.hxx"
25 #include "ww8par.hxx"
26 #include <fmtcntnt.hxx>
27 #include <rtl/tencinfo.h>
28 #include <sal/log.hxx>
29 #include <sot/exchange.hxx>
30 #include <svtools/rtfkeywd.hxx>
31 #include <editeng/fontitem.hxx>
32 #include <editeng/tstpitem.hxx>
33 #include <editeng/adjustitem.hxx>
34 #include <editeng/spltitem.hxx>
35 #include <editeng/widwitem.hxx>
36 #include <editeng/postitem.hxx>
37 #include <editeng/wghtitem.hxx>
38 #include <editeng/kernitem.hxx>
40 #include <editeng/cmapitem.hxx>
41 #include <editeng/wrlmitem.hxx>
42 #include <editeng/udlnitem.hxx>
43 #include <editeng/langitem.hxx>
45 #include <editeng/fhgtitem.hxx>
46 #include <editeng/colritem.hxx>
48 #include <editeng/contouritem.hxx>
49 #include <editeng/shdditem.hxx>
50 #include <editeng/autokernitem.hxx>
52 #include <editeng/twolinesitem.hxx>
57 #include <editeng/blinkitem.hxx>
59 #include <editeng/boxitem.hxx>
60 #include <editeng/brushitem.hxx>
61 #include <editeng/ulspitem.hxx>
62 #include <editeng/shaditem.hxx>
63 #include <editeng/keepitem.hxx>
64 #include <editeng/frmdiritem.hxx>
65 #include <editeng/opaqitem.hxx>
66 #include <svx/svdouno.hxx>
68 #include <sfx2/sfxbasemodel.hxx>
69 #include <svx/xfillit0.hxx>
70 #include <svx/xflgrit.hxx>
71 #include <docufld.hxx>
72 #include <fmtclds.hxx>
73 #include <fmtrowsplt.hxx>
74 #include <fmtline.hxx>
75 #include <fmtanchr.hxx>
76 #include <ftninfo.hxx>
77 #include <htmltbl.hxx>
78 #include <ndgrf.hxx>
79 #include <pagedesc.hxx>
80 #include <swmodule.hxx>
81 #include <txtftn.hxx>
82 #include <txtinet.hxx>
83 #include <grfatr.hxx>
84 #include <ndole.hxx>
85 #include <lineinfo.hxx>
86 #include <redline.hxx>
87 #include <rtf.hxx>
89 #include <vcl/cvtgrf.hxx>
90 #include <oox/mathml/export.hxx>
91 #include <com/sun/star/i18n/ScriptType.hpp>
92 #include <svl/grabbagitem.hxx>
93 #include <frmatr.hxx>
94 #include <swtable.hxx>
95 #include "rtfexport.hxx"
96 
97 using namespace ::com::sun::star;
98 using namespace sw::util;
99 
100 static OString OutTBLBorderLine(RtfExport const& rExport, const editeng::SvxBorderLine* pLine,
101  const sal_Char* pStr)
102 {
103  OStringBuffer aRet;
104  if (!pLine->isEmpty())
105  {
106  aRet.append(pStr);
107  // single line
108  switch (pLine->GetBorderLineStyle())
109  {
110  case SvxBorderLineStyle::SOLID:
111  {
112  if (DEF_LINE_WIDTH_0 == pLine->GetWidth())
113  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRHAIR);
114  else
115  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS);
116  }
117  break;
118  case SvxBorderLineStyle::DOTTED:
119  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDOT);
120  break;
121  case SvxBorderLineStyle::DASHED:
122  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDASH);
123  break;
124  case SvxBorderLineStyle::DOUBLE:
125  case SvxBorderLineStyle::DOUBLE_THIN:
126  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
127  break;
128  case SvxBorderLineStyle::THINTHICK_SMALLGAP:
130  break;
131  case SvxBorderLineStyle::THINTHICK_MEDIUMGAP:
133  break;
134  case SvxBorderLineStyle::THINTHICK_LARGEGAP:
136  break;
137  case SvxBorderLineStyle::THICKTHIN_SMALLGAP:
139  break;
140  case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP:
142  break;
143  case SvxBorderLineStyle::THICKTHIN_LARGEGAP:
145  break;
146  case SvxBorderLineStyle::EMBOSSED:
148  break;
149  case SvxBorderLineStyle::ENGRAVED:
151  break;
152  case SvxBorderLineStyle::OUTSET:
154  break;
155  case SvxBorderLineStyle::INSET:
157  break;
158  case SvxBorderLineStyle::FINE_DASHED:
160  break;
161  case SvxBorderLineStyle::DASH_DOT:
163  break;
164  case SvxBorderLineStyle::DASH_DOT_DOT:
166  break;
167  case SvxBorderLineStyle::NONE:
168  default:
169  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRNONE);
170  break;
171  }
172 
173  double const fConverted(
175  if (255 >= pLine->GetWidth()) // That value comes from RTF specs
176  {
177  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW).append(static_cast<sal_Int32>(fConverted));
178  }
179  else
180  {
181  // use \brdrth to double the value range...
183  aRet.append(static_cast<sal_Int32>(fConverted) / 2);
184  }
185 
186  aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
187  aRet.append(static_cast<sal_Int32>(rExport.GetColor(pLine->GetColor())));
188  }
189  return aRet.makeStringAndClear();
190 }
191 
192 static OString OutBorderLine(RtfExport const& rExport, const editeng::SvxBorderLine* pLine,
193  const sal_Char* pStr, sal_uInt16 nDist,
194  SvxShadowLocation eShadowLocation = SvxShadowLocation::NONE)
195 {
196  OStringBuffer aRet;
197  aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
198  aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
199  aRet.append(static_cast<sal_Int32>(nDist));
200  if (eShadowLocation == SvxShadowLocation::BottomRight)
201  aRet.append(LO_STRING_SVTOOLS_RTF_BRDRSH);
202  return aRet.makeStringAndClear();
203 }
204 
205 void RtfAttributeOutput::RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)
206 {
207  m_bIsRTL = bIsRTL;
208  m_nScript = nScript;
209  m_bControlLtrRtl = true;
210 }
211 
213 {
214  if (m_bIsBeforeFirstParagraph && m_rExport.m_nTextTyp != TXT_HDFT)
215  m_bIsBeforeFirstParagraph = false;
216 
217  // Output table/table row/table cell starts if needed
218  if (pTextNodeInfo)
219  {
220  sal_uInt32 nRow = pTextNodeInfo->getRow();
221  sal_uInt32 nCell = pTextNodeInfo->getCell();
222 
223  // New cell/row?
224  if (m_nTableDepth > 0 && !m_bTableCellOpen)
225  {
227  pTextNodeInfo->getInnerForDepth(m_nTableDepth));
228  OSL_ENSURE(pDeepInner, "TableNodeInfoInner not found");
229  // Make sure we always start a row between ending one and starting a cell.
230  // In case of subtables, we may not get the first cell.
231  if (pDeepInner && (pDeepInner->getCell() == 0 || m_bTableRowEnded))
232  {
233  StartTableRow(pDeepInner);
234  }
235 
236  StartTableCell();
237  }
238 
239  // Again, if depth was incremented, start a new table even if we skipped the first cell.
240  if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth()))
241  {
242  // Do we have to start the table?
243  // [If we are at the right depth already, it means that we
244  // continue the table cell]
245  sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
246 
247  if (nCurrentDepth > m_nTableDepth)
248  {
249  // Start all the tables that begin here
250  for (sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth();
251  ++nDepth)
252  {
254  pTextNodeInfo->getInnerForDepth(nDepth));
255 
256  m_bLastTable = (nDepth == pTextNodeInfo->getDepth());
257  StartTable();
258  StartTableRow(pInner);
259  StartTableCell();
260  }
261 
262  m_nTableDepth = nCurrentDepth;
263  }
264  }
265  }
266 
267  OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
268 }
269 
271 {
272  bool bLastPara = false;
273  if (m_rExport.m_nTextTyp == TXT_FTN || m_rExport.m_nTextTyp == TXT_EDN
274  || m_rExport.m_pDoc->IsClipBoard())
275  {
276  // We're ending a paragraph that is the last paragraph of a footnote or endnote, or of clipboard.
277  bLastPara
278  = m_rExport.GetCurrentNodeIndex()
279  && m_rExport.GetCurrentNodeIndex() == m_rExport.m_pCurPam->End()->nNode.GetIndex();
280  }
281 
282  FinishTableRowCell(pTextNodeInfoInner);
283 
284  RtfStringBuffer aParagraph;
285 
286  aParagraph.appendAndClear(m_aRun);
287  aParagraph->append(m_aAfterRuns.makeStringAndClear());
288  if (m_bTableAfterCell)
289  m_bTableAfterCell = false;
290  else
291  {
292  aParagraph->append(SAL_NEWLINE_STRING);
293  // RTF_PAR at the end of the footnote or clipboard, would cause an additional empty paragraph.
294  if (!bLastPara)
295  {
296  aParagraph->append(OOO_STRING_SVTOOLS_RTF_PAR);
297  aParagraph->append(' ');
298  }
299  }
300  if (m_nColBreakNeeded)
301  {
303  m_nColBreakNeeded = false;
304  }
305 
306  if (!m_bBufferSectionHeaders)
307  aParagraph.makeStringAndClear(this);
308  else
309  m_aSectionHeaders.append(aParagraph.makeStringAndClear());
310 }
311 
313 {
314  m_rExport.Strm()
315  .WriteCharPtr(SAL_NEWLINE_STRING)
316  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAR)
317  .WriteChar(' ');
318 }
319 
321 {
322  SwNodeIndex aNextIndex(rNode, 1);
323  if (rNode.IsTextNode())
324  {
325  OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
326 
327  // output page/section breaks
328  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
329  m_bBufferSectionBreaks = true;
330 
331  // output section headers / footers
332  if (!m_bBufferSectionHeaders)
333  m_rExport.Strm().WriteCharPtr(m_aSectionHeaders.makeStringAndClear().getStr());
334 
335  if (aNextIndex.GetNode().IsTextNode())
336  {
337  const SwTextNode* pTextNode = static_cast<SwTextNode*>(&aNextIndex.GetNode());
338  m_rExport.OutputSectionBreaks(pTextNode->GetpSwAttrSet(), *pTextNode);
339  // Save the current page description for now, so later we will be able to access the previous one.
340  m_pPrevPageDesc = pTextNode->FindPageDesc();
341  }
342  else if (aNextIndex.GetNode().IsTableNode())
343  {
344  const SwTableNode* pTableNode = static_cast<SwTableNode*>(&aNextIndex.GetNode());
345  const SwFrameFormat* pFormat = pTableNode->GetTable().GetFrameFormat();
346  m_rExport.OutputSectionBreaks(&(pFormat->GetAttrSet()), *pTableNode);
347  }
348  m_bBufferSectionBreaks = false;
349  }
350  else if (rNode.IsEndNode())
351  {
352  // End of something: make sure that it's the end of a table.
353  assert(rNode.StartOfSectionNode()->IsTableNode());
354  if (aNextIndex.GetNode().IsTextNode())
355  {
356  // Handle section break between a table and a text node following it.
357  const SwTextNode* pTextNode = aNextIndex.GetNode().GetTextNode();
358  m_rExport.OutputSectionBreaks(pTextNode->GetpSwAttrSet(), *pTextNode);
359  }
360  }
361 }
362 
364 {
365  OStringBuffer aPar;
366  if (!m_rExport.GetRTFFlySyntax())
367  {
368  aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
369  aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
370  aPar.append(' ');
371  }
372  if (!m_bBufferSectionHeaders)
373  m_rExport.Strm().WriteCharPtr(aPar.makeStringAndClear().getStr());
374  else
375  m_aSectionHeaders.append(aPar.makeStringAndClear());
376 }
377 
379  const SfxItemSet& /*rParagraphMarkerProperties*/, const SwRedlineData* /*pRedlineData*/,
380  const SwRedlineData* /*pRedlineParagraphMarkerDeleted*/,
381  const SwRedlineData* /*pRedlineParagraphMarkerInserted*/)
382 {
383  const OString aProperties = MoveCharacterProperties(true);
384  m_rExport.Strm().WriteCharPtr(aProperties.getStr());
385 }
386 
387 void RtfAttributeOutput::StartRun(const SwRedlineData* pRedlineData, sal_Int32 /*nPos*/,
388  bool bSingleEmptyRun)
389 {
390  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", bSingleEmptyRun: " << bSingleEmptyRun);
391 
392  m_bInRun = true;
393  m_bSingleEmptyRun = bSingleEmptyRun;
394  if (!m_bSingleEmptyRun)
395  m_aRun->append('{');
396 
397  // if there is some redlining in the document, output it
398  Redline(pRedlineData);
399 
400  OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
401 }
402 
403 void RtfAttributeOutput::EndRun(const SwTextNode* /*pNode*/, sal_Int32 /*nPos*/, bool /*bLastRun*/)
404 {
405  m_aRun->append(SAL_NEWLINE_STRING);
406  m_aRun.appendAndClear(m_aRunText);
407  if (!m_bSingleEmptyRun && m_bInRun)
408  m_aRun->append('}');
409  m_bInRun = false;
410 }
411 
413 {
414  OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
415 }
416 
418 {
419  const OString aProperties = MoveCharacterProperties(true);
420  m_aRun->append(aProperties.getStr());
421 }
422 
423 OString RtfAttributeOutput::MoveCharacterProperties(bool aAutoWriteRtlLtr)
424 {
425  const OString aAssoc = m_aStylesAssoc.makeStringAndClear();
426  const OString aNormal = m_aStyles.makeStringAndClear();
427  OStringBuffer aBuf;
428 
429  if (aAutoWriteRtlLtr && !m_bControlLtrRtl)
430  {
431  m_bControlLtrRtl = !aAssoc.isEmpty();
432  m_bIsRTL = false;
433  m_nScript = i18n::ScriptType::LATIN;
434  }
435 
436  if (m_bControlLtrRtl)
437  {
438  m_bControlLtrRtl = false;
439 
440  /*
441  You would have thought that
442  m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficient here ,
443  but looks like word needs to see the other directional token to be
444  satisfied that all is kosher, otherwise it seems in ver 2003 to go and
445  semi-randomly stick strike through about the place. Perhaps
446  strikethrough is some ms developers "something is wrong signal" debugging
447  code that we're triggering ?
448  */
449  if (!aAssoc.isEmpty() || !aNormal.isEmpty())
450  {
451  if (m_bIsRTL)
452  {
453  aBuf.append(OOO_STRING_SVTOOLS_RTF_LTRCH)
454  .append(aAssoc)
455  .append(' ')
457  .append(aNormal);
458  }
459  else
460  {
461  aBuf.append(OOO_STRING_SVTOOLS_RTF_RTLCH)
462  .append(aAssoc)
463  .append(' ')
465  .append(aNormal);
466  }
467  }
468 
469  switch (m_nScript)
470  {
471  case i18n::ScriptType::LATIN:
472  aBuf.append(OOO_STRING_SVTOOLS_RTF_LOCH);
473  break;
474  case i18n::ScriptType::ASIAN:
475  aBuf.append(OOO_STRING_SVTOOLS_RTF_DBCH);
476  break;
477  case i18n::ScriptType::COMPLEX:
478  /* noop */
479  default:
480  /* should not happen? */
481  break;
482  }
483  }
484  else
485  {
486  aBuf.append(aAssoc).append(aNormal);
487  }
488 
489  return aBuf.makeStringAndClear();
490 }
491 
492 void RtfAttributeOutput::RunText(const OUString& rText, rtl_TextEncoding /*eCharSet*/)
493 {
494  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rText: " << rText);
495  RawText(rText, m_rExport.GetCurrentEncoding());
496 }
497 
498 OStringBuffer& RtfAttributeOutput::RunText() { return m_aRunText.getLastBuffer(); }
499 
500 void RtfAttributeOutput::RawText(const OUString& rText, rtl_TextEncoding eCharSet)
501 {
502  m_aRunText->append(msfilter::rtfutil::OutString(rText, eCharSet));
503 }
504 
505 void RtfAttributeOutput::StartRuby(const SwTextNode& rNode, sal_Int32 nPos,
506  const SwFormatRuby& rRuby)
507 {
508  WW8Ruby aWW8Ruby(rNode, rRuby, GetExport());
509  OUString aStr(FieldString(ww::eEQ));
510  aStr += "\\* jc";
511  aStr += OUString::number(aWW8Ruby.GetJC());
512 
513  aStr += " \\* \"Font:";
514  aStr += aWW8Ruby.GetFontFamily();
515  aStr += "\" \\* hps";
516  aStr += OUString::number((aWW8Ruby.GetRubyHeight() + 5) / 10);
517  aStr += " \\o";
518  if (aWW8Ruby.GetDirective())
519  {
520  aStr += "\\a" + OUString(aWW8Ruby.GetDirective());
521  }
522  aStr += "(\\s\\up ";
523 
524  aStr += OUString::number((aWW8Ruby.GetBaseHeight() + 10) / 20 - 1);
525  aStr += "(";
526  EndRun(&rNode, nPos);
527  m_rExport.OutputField(nullptr, ww::eEQ, aStr, FieldFlags::Start | FieldFlags::CmdStart);
528  aStr = rRuby.GetText();
529  aStr += ")";
530  aStr += ",";
531  m_rExport.OutputField(nullptr, ww::eEQ, aStr, FieldFlags::NONE);
532 }
533 
534 void RtfAttributeOutput::EndRuby(const SwTextNode& rNode, sal_Int32 nPos)
535 {
536  m_rExport.OutputField(nullptr, ww::eEQ, ")", FieldFlags::End | FieldFlags::Close);
537  EndRun(&rNode, nPos);
538 }
539 
540 bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& rTarget)
541 {
542  m_sURL = rUrl;
543  // Ignore hyperlink without a URL.
544  if (!rUrl.isEmpty())
545  {
546  m_aRun->append('{');
547  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FIELD);
548  m_aRun->append('{');
549  m_aRun->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
550  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
551  m_aRun->append(" HYPERLINK ");
552 
553  m_aRun->append("\"");
554  m_aRun->append(msfilter::rtfutil::OutString(rUrl, m_rExport.GetCurrentEncoding()));
555  m_aRun->append("\" ");
556 
557  if (!rTarget.isEmpty())
558  {
559  m_aRun->append("\\\\t \"");
560  m_aRun->append(msfilter::rtfutil::OutString(rTarget, m_rExport.GetCurrentEncoding()));
561  m_aRun->append("\" ");
562  }
563 
564  m_aRun->append("}");
565  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
566  }
567  return true;
568 }
569 
570 bool RtfAttributeOutput::EndURL(bool const isAtEndOfParagraph)
571 {
572  if (!m_sURL.isEmpty())
573  {
574  // UGLY: usually EndRun is called earlier, but there is an extra
575  // call to OutAttrWithRange() when at the end of the paragraph,
576  // so in that special case the output needs to be appended to the
577  // new run's text instead of the previous run
578  if (isAtEndOfParagraph)
579  {
580  // close the fldrslt group
581  m_aRunText->append("}}");
582  // close the field group
583  m_aRunText->append('}');
584  }
585  else
586  {
587  // close the fldrslt group
588  m_aRun->append("}}");
589  // close the field group
590  m_aRun->append('}');
591  }
592  m_sURL.clear();
593  }
594  return true;
595 }
596 
597 void RtfAttributeOutput::FieldVanish(const OUString& /*rText*/, ww::eField /*eType*/)
598 {
599  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
600 }
601 
603 {
604  if (!pRedline)
605  return;
606 
607  if (pRedline->GetType() == RedlineType::Insert)
608  {
609  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED);
610  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
611  m_aRun->append(static_cast<sal_Int32>(
612  m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor()))));
613  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
614  }
615  else if (pRedline->GetType() == RedlineType::Delete)
616  {
617  m_aRun->append(OOO_STRING_SVTOOLS_RTF_DELETED);
618  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
619  m_aRun->append(static_cast<sal_Int32>(
620  m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor()))));
621  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
622  }
623  m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp())));
624  m_aRun->append(' ');
625 }
626 
628  const SwFormatDrop& /*rSwFormatDrop*/, sal_uInt16 /*nStyle*/,
629  ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/,
630  ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/)
631 {
632  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
633 }
634 
635 void RtfAttributeOutput::ParagraphStyle(sal_uInt16 nStyle)
636 {
637  OString* pStyle = m_rExport.GetStyle(nStyle);
638  OStringBuffer aStyle;
639  aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
640  aStyle.append(static_cast<sal_Int32>(nStyle));
641  if (pStyle)
642  aStyle.append(pStyle->getStr());
643  if (!m_bBufferSectionHeaders)
644  m_rExport.Strm().WriteCharPtr(aStyle.makeStringAndClear().getStr());
645  else
646  m_aSectionHeaders.append(aStyle.makeStringAndClear());
647 }
648 
650  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
651 {
652  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
653  if (m_nTableDepth > 1)
654  {
655  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
656  m_aStyles.append(static_cast<sal_Int32>(m_nTableDepth));
657  }
658  m_bWroteCellInfo = true;
659 }
660 
662 {
663  /* noop */
664 }
665 
667  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
668 {
669  InitTableHelper(pTableTextNodeInfoInner);
670 
671  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
672  SwFrameFormat* pFormat = pTable->GetFrameFormat();
673 
674  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
675  TableOrientation(pTableTextNodeInfoInner);
676  TableBidi(pTableTextNodeInfoInner);
677  TableHeight(pTableTextNodeInfoInner);
678  TableCanSplit(pTableTextNodeInfoInner);
679 
680  // Cell margins
681  const SvxBoxItem& rBox = pFormat->GetBox();
682  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
683  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
684 
685  static const char* aRowPadNames[]
688 
689  static const char* aRowPadUnits[]
692 
693  for (int i = 0; i < 4; ++i)
694  {
695  m_aRowDefs.append(aRowPadUnits[i]);
696  m_aRowDefs.append(sal_Int32(3));
697  m_aRowDefs.append(aRowPadNames[i]);
698  m_aRowDefs.append(static_cast<sal_Int32>(rBox.GetDistance(aBorders[i])));
699  }
700 
701  // The cell-dependent properties
702  const double fWidthRatio = m_pTableWrt->GetAbsWidthRatio();
703  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
704  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
705  SwTwips nSz = 0;
706 
707  // Not using m_nTableDepth, which is not yet incremented here.
708  sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
709  m_aCells[nCurrentDepth] = pRow->GetCells().size();
710  for (sal_uInt32 i = 0; i < m_aCells[nCurrentDepth]; i++)
711  {
712  const SwWriteTableCell* const pCell = pRow->GetCells()[i].get();
713  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
714 
715  pTableTextNodeInfoInner->setCell(i);
716  TableCellProperties(pTableTextNodeInfoInner);
717 
718  // Right boundary: this can't be in TableCellProperties as the old
719  // value of nSz is needed.
720  nSz += pCellFormat->GetFrameSize().GetWidth();
721  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
722  m_aRowDefs.append(static_cast<sal_Int32>(pFormat->GetLRSpace().GetLeft()
723  + rtl::math::round(nSz * fWidthRatio)));
724  }
725 }
726 
728  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
729 {
730  /*
731  * The function name is a bit misleading: given that we write borders
732  * before each row, we just have borders, not default ones. Additionally,
733  * this function actually writes borders for a specific cell only and is
734  * called for each cell.
735  */
736 
737  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
738  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
739  const SwWriteTableCell* const pCell
740  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
741  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
742  const SfxPoolItem* pItem;
743  if (pCellFormat->GetAttrSet().HasItem(RES_BOX, &pItem))
744  {
745  auto& rBox = static_cast<const SvxBoxItem&>(*pItem);
746  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
747  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
748  static const char* aBorderNames[]
751  //Yes left and top are swapped with each other for cell padding! Because
752  //that's what the thundering annoying rtf export/import word xp does.
753  static const char* aCellPadNames[]
756  static const char* aCellPadUnits[]
759  for (int i = 0; i < 4; ++i)
760  {
761  if (const editeng::SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
762  m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
763  if (rBox.GetDistance(aBorders[i]))
764  {
765  m_aRowDefs.append(aCellPadUnits[i]);
766  m_aRowDefs.append(sal_Int32(3));
767  m_aRowDefs.append(aCellPadNames[i]);
768  m_aRowDefs.append(static_cast<sal_Int32>(rBox.GetDistance(aBorders[i])));
769  }
770  }
771  }
772 }
773 
775  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
776 {
777  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
778  const SwTableBox* pTableBox = pTableTextNodeInfoInner->getTableBox();
779  const SwTableLine* pTableLine = pTableBox->GetUpper();
780 
781  Color aColor = COL_AUTO;
782  auto pTableColorProp
784  if (pTableColorProp)
785  aColor = pTableColorProp->GetColor();
786 
787  auto pRowColorProp
789  if (pRowColorProp && pRowColorProp->GetColor() != COL_AUTO)
790  aColor = pRowColorProp->GetColor();
791 
792  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
793  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
794  const SwWriteTableCell* const pCell
795  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
796  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
797  const SfxPoolItem* pItem;
798  if (pCellFormat->GetAttrSet().HasItem(RES_BACKGROUND, &pItem))
799  {
800  auto& rBack = static_cast<const SvxBrushItem&>(*pItem);
801  if (rBack.GetColor() != COL_AUTO)
802  aColor = rBack.GetColor();
803  }
804 
805  if (!aColor.GetTransparency())
806  {
807  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
808  m_aRowDefs.append(static_cast<sal_Int32>(m_rExport.GetColor(aColor)));
809  }
810 }
811 
813  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
814 {
815 }
816 
818  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
819 {
820 }
821 
823 {
824  const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
825  const SwTableLine* pTabLine = pTabBox->GetUpper();
826  const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
827  const SwFormatFrameSize& rLSz = pLineFormat->GetFrameSize();
828 
829  if (ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight())
830  {
831  sal_Int32 nHeight = 0;
832 
833  switch (rLSz.GetHeightSizeType())
834  {
835  case ATT_FIX_SIZE:
836  nHeight = -rLSz.GetHeight();
837  break;
838  case ATT_MIN_SIZE:
839  nHeight = rLSz.GetHeight();
840  break;
841  default:
842  break;
843  }
844 
845  if (nHeight)
846  {
847  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
848  m_aRowDefs.append(nHeight);
849  }
850  }
851 }
852 
854  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
855 {
856  const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
857  const SwTableLine* pTabLine = pTabBox->GetUpper();
858  const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
859  const SwFormatRowSplit& rSplittable = pLineFormat->GetRowSplit();
860 
861  // The rtf default is to allow a row to break
862  if (!rSplittable.GetValue())
863  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
864 }
865 
867 {
868  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
869  const SwFrameFormat* pFrameFormat = pTable->GetFrameFormat();
870 
871  if (m_rExport.TrueFrameDirection(*pFrameFormat) != SvxFrameDirection::Horizontal_RL_TB)
872  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
873  else
874  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
875 }
876 
878  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
879 {
880  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
881  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
882  const SwWriteTableCell* const pCell
883  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
884  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
885 
886  // Text direction.
887  if (SvxFrameDirection::Vertical_RL_TB == m_rExport.TrueFrameDirection(*pCellFormat))
888  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLTXTBRL);
889  else if (SvxFrameDirection::Vertical_LR_BT == m_rExport.TrueFrameDirection(*pCellFormat))
890  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLTXBTLR);
891 
892  const SfxPoolItem* pItem;
893 
894  // vertical merges
895  if (pCell->GetRowSpan() > 1)
896  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
897  else if (pCell->GetRowSpan() == 0)
898  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
899 
900  // vertical alignment
901  if (pCellFormat->GetAttrSet().HasItem(RES_VERT_ORIENT, &pItem))
902  switch (static_cast<const SwFormatVertOrient*>(pItem)->GetVertOrient())
903  {
904  case text::VertOrientation::CENTER:
905  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC);
906  break;
908  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB);
909  break;
910  default:
911  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT);
912  break;
913  }
914 }
915 
917 {
918  // This is called when the nested table ends in a cell, and there's no
919  // paragraph behind that; so we must check for the ends of cell, rows,
920  // and tables
921  FinishTableRowCell(pNodeInfoInner);
922 }
923 
925  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
926 {
927  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
928  SwFrameFormat* pFormat = pTable->GetFrameFormat();
929 
930  OStringBuffer aTableAdjust(OOO_STRING_SVTOOLS_RTF_TRQL);
931  switch (pFormat->GetHoriOrient().GetHoriOrient())
932  {
933  case text::HoriOrientation::CENTER:
934  aTableAdjust.setLength(0);
935  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
936  break;
938  aTableAdjust.setLength(0);
939  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
940  break;
942  case text::HoriOrientation::LEFT_AND_WIDTH:
943  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
944  aTableAdjust.append(static_cast<sal_Int32>(pFormat->GetLRSpace().GetLeft()));
945  break;
946  default:
947  break;
948  }
949 
950  m_aRowDefs.append(aTableAdjust.makeStringAndClear());
951 }
952 
954  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
955 {
956  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
957 }
958 
959 void RtfAttributeOutput::TableRowEnd(sal_uInt32 /*nDepth*/) { /* noop, see EndTableRow() */}
960 
961 /*
962  * Our private table methods.
963  */
964 
966  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
967 {
968  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
969  if (m_pTableWrt && pTable == m_pTableWrt->GetTable())
970  return;
971 
972  long nPageSize = 0;
973  bool bRelBoxSize = false;
974 
975  // Create the SwWriteTable instance to use col spans
976  GetTablePageSize(pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize);
977 
978  const SwFrameFormat* pFormat = pTable->GetFrameFormat();
979  const sal_uInt32 nTableSz = pFormat->GetFrameSize().GetWidth();
980 
981  const SwHTMLTableLayout* pLayout = pTable->GetHTMLTableLayout();
982  if (pLayout && pLayout->IsExportable())
983  m_pTableWrt = std::make_unique<SwWriteTable>(pTable, pLayout);
984  else
985  m_pTableWrt = std::make_unique<SwWriteTable>(pTable, pTable->GetTabLines(), nPageSize,
986  nTableSz, false);
987 }
988 
990 {
991  // To trigger calling InitTableHelper()
992  m_pTableWrt.reset();
993 }
994 
996  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
997 {
998  sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
999  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << nCurrentDepth << ")");
1000  m_bTableRowEnded = false;
1001 
1002  TableDefinition(pTableTextNodeInfoInner);
1003 
1004  if (!m_bLastTable)
1005  m_aTables.push_back(m_aRowDefs.makeStringAndClear());
1006 
1007  // We'll write the table definition for nested tables later
1008  if (nCurrentDepth > 1)
1009  return;
1010  // Empty the previous row closing buffer before starting the new one,
1011  // necessary for subtables.
1012  m_rExport.Strm().WriteCharPtr(m_aAfterRuns.makeStringAndClear().getStr());
1013  m_rExport.Strm().WriteCharPtr(m_aRowDefs.makeStringAndClear().getStr());
1014 }
1015 
1016 void RtfAttributeOutput::StartTableCell() { m_bTableCellOpen = true; }
1017 
1019  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
1020 {
1021  TableDefaultBorders(pTableTextNodeInfoInner);
1022  TableBackgrounds(pTableTextNodeInfoInner);
1023  TableVerticalCell(pTableTextNodeInfoInner);
1024 }
1025 
1027 {
1028  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
1029 
1030  if (!m_bWroteCellInfo)
1031  {
1032  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_INTBL);
1033  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ITAP);
1034  m_aAfterRuns.append(static_cast<sal_Int32>(m_nTableDepth));
1035  }
1036  if (m_nTableDepth > 1)
1037  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
1038  else
1039  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
1040 
1041  m_bTableCellOpen = false;
1042  m_bTableAfterCell = true;
1043  m_bWroteCellInfo = false;
1044  if (m_aCells[m_nTableDepth] > 0)
1045  m_aCells[m_nTableDepth]--;
1046 }
1047 
1049 {
1050  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
1051 
1052  // Trying to end the row without writing the required number of cells? Fill with empty ones.
1053  for (sal_uInt32 i = 0; i < m_aCells[m_nTableDepth]; i++)
1054  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
1055 
1056  if (m_nTableDepth > 1)
1057  {
1058  m_aAfterRuns.append(
1060  if (!m_aRowDefs.isEmpty())
1061  m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
1062  else if (!m_aTables.empty())
1063  {
1064  m_aAfterRuns.append(m_aTables.back());
1065  m_aTables.pop_back();
1066  }
1067  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW
1068  "}"
1070  }
1071  else
1072  {
1073  if (!m_aTables.empty())
1074  {
1075  m_aAfterRuns.append(m_aTables.back());
1076  m_aTables.pop_back();
1077  }
1078  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
1079  }
1080  m_bTableRowEnded = true;
1081 }
1082 
1084 {
1085  if (m_nTableDepth > 0)
1086  {
1087  m_nTableDepth--;
1088  m_pTableWrt.reset();
1089  }
1090 
1091  // We closed the table; if it is a nested table, the cell that contains it
1092  // still continues
1093  m_bTableCellOpen = true;
1094 
1095  // Cleans the table helper
1096  m_pTableWrt.reset();
1097 }
1098 
1100 {
1101  if (pInner)
1102  {
1103  // Where are we in the table
1104  sal_uInt32 nRow = pInner->getRow();
1105 
1106  const SwTable* pTable = pInner->getTable();
1107  const SwTableLines& rLines = pTable->GetTabLines();
1108  sal_uInt16 nLinesCount = rLines.size();
1109 
1110  if (pInner->isEndOfCell())
1111  EndTableCell();
1112 
1113  // This is a line end
1114  if (pInner->isEndOfLine())
1115  EndTableRow();
1116 
1117  // This is the end of the table
1118  if (pInner->isEndOfLine() && (nRow + 1) == nLinesCount)
1119  EndTable();
1120  }
1121 }
1122 
1124 {
1125  m_rExport.Strm()
1126  .WriteCharPtr(SAL_NEWLINE_STRING)
1127  .WriteChar('{')
1128  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLORTBL);
1129  m_rExport.OutColorTable();
1130  OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
1131  m_aStylesheet.append(SAL_NEWLINE_STRING);
1132  m_aStylesheet.append('{');
1133  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
1134 }
1135 
1136 void RtfAttributeOutput::EndStyles(sal_uInt16 /*nNumberOfStyles*/)
1137 {
1138  m_rExport.Strm().WriteChar('}');
1139  m_rExport.Strm().WriteCharPtr(m_aStylesheet.makeStringAndClear().getStr());
1140  m_rExport.Strm().WriteChar('}');
1141 }
1142 
1143 void RtfAttributeOutput::DefaultStyle() { /* noop, the default style is always 0 in RTF */}
1144 
1145 void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType, sal_uInt16 nBase,
1146  sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
1147  bool bAutoUpdate)
1148 {
1149  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rName = '" << rName << "'");
1150 
1151  m_aStylesheet.append('{');
1152  if (eType == STYLE_TYPE_PARA)
1153  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
1154  else
1156  m_aStylesheet.append(static_cast<sal_Int32>(nId));
1157 
1158  if (nBase != 0x0FFF)
1159  {
1160  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
1161  m_aStylesheet.append(static_cast<sal_Int32>(nBase));
1162  }
1163 
1164  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
1165  m_aStylesheet.append(static_cast<sal_Int32>(nNext));
1166 
1167  if (bAutoUpdate)
1168  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SAUTOUPD);
1169 
1170  m_rStyleName = rName;
1171  m_nStyleId = nId;
1172 }
1173 
1175 {
1176  OString aStyles = MoveCharacterProperties();
1177  m_rExport.InsStyle(m_nStyleId, aStyles);
1178  m_aStylesheet.append(aStyles);
1179  m_aStylesheet.append(' ');
1180  m_aStylesheet.append(
1181  msfilter::rtfutil::OutString(m_rStyleName, m_rExport.GetCurrentEncoding()));
1182  m_aStylesheet.append(";}");
1183  m_aStylesheet.append(SAL_NEWLINE_STRING);
1184 }
1185 
1186 void RtfAttributeOutput::StartStyleProperties(bool /*bParProp*/, sal_uInt16 /*nStyle*/)
1187 {
1188  /* noop */
1189 }
1190 
1191 void RtfAttributeOutput::EndStyleProperties(bool /*bParProp*/) { /* noop */}
1192 
1194 {
1195  if (nLvl >= WW8ListManager::nMaxLevel)
1196  nLvl = WW8ListManager::nMaxLevel - 1;
1197 
1198  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
1199  m_aStyles.append(static_cast<sal_Int32>(nLvl));
1200  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
1201  m_aStyles.append(static_cast<sal_Int32>(nLvl));
1202 }
1203 
1205 {
1206  if (bBreak)
1207  {
1208  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAGEBB);
1209  }
1210 }
1211 
1213 {
1214  switch (nC)
1215  {
1216  case msword::ColumnBreak:
1217  m_nColBreakNeeded = true;
1218  break;
1219  case msword::PageBreak:
1220  if (pSectionInfo)
1221  m_rExport.SectionProperties(*pSectionInfo);
1222  break;
1223  }
1224 }
1225 
1227 {
1228  if (m_bIsBeforeFirstParagraph)
1229  return;
1230 
1232  if (!m_bBufferSectionBreaks)
1233  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
1234 }
1235 
1237 {
1238  /*
1239  * noop, \sect must go to StartSection or Word won't notice multiple
1240  * columns...
1241  */
1242 }
1243 
1245 {
1246  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
1247  m_aSectionBreaks.append(static_cast<sal_Int32>(!bProtected));
1248 }
1249 
1251  const SwLineNumberInfo& rLnNumInfo)
1252 {
1253  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEMOD);
1254  m_rExport.OutLong(rLnNumInfo.GetCountBy());
1255  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEX);
1256  m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
1257  if (!rLnNumInfo.IsRestartEachPage())
1258  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINECONT);
1259 
1260  if (nRestartNo > 0)
1261  {
1262  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINESTARTS);
1263  m_rExport.OutLong(nRestartNo);
1264  }
1265 }
1266 
1268 {
1269  /*
1270  * noop, handled in RtfExport::WriteHeaderFooter()
1271  */
1272 }
1273 
1275  const SwFrameFormat* /*pFirstPageFormat*/)
1276 {
1277  const SvxBoxItem& rBox = pFormat->GetBox();
1278  const editeng::SvxBorderLine* pLine = rBox.GetTop();
1279  if (pLine)
1280  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRT,
1281  rBox.GetDistance(SvxBoxItemLine::TOP)));
1282  pLine = rBox.GetBottom();
1283  if (pLine)
1284  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRB,
1285  rBox.GetDistance(SvxBoxItemLine::BOTTOM)));
1286  pLine = rBox.GetLeft();
1287  if (pLine)
1288  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRL,
1289  rBox.GetDistance(SvxBoxItemLine::LEFT)));
1290  pLine = rBox.GetRight();
1291  if (pLine)
1292  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRR,
1293  rBox.GetDistance(SvxBoxItemLine::RIGHT)));
1294 }
1295 
1297 {
1298  m_rExport.Strm().WriteCharPtr(bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT
1300 }
1301 
1303  sal_uInt16 nNumType, const ::boost::optional<sal_uInt16>& oPageRestartNumber)
1304 {
1305  if (oPageRestartNumber)
1306  {
1307  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
1308  m_aSectionBreaks.append(static_cast<sal_Int32>(oPageRestartNumber.get()));
1309  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
1310  }
1311 
1312  const char* pStr = nullptr;
1313  switch (nNumType)
1314  {
1318  break;
1322  break;
1323  case SVX_NUM_ROMAN_UPPER:
1325  break;
1326  case SVX_NUM_ROMAN_LOWER:
1328  break;
1329 
1330  case SVX_NUM_ARABIC:
1332  break;
1333  }
1334  if (pStr)
1335  m_aSectionBreaks.append(pStr);
1336 }
1337 
1339 {
1340  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", nBreakCode = " << int(nBreakCode));
1341 
1342  /*
1343  * break code: 0 No break, 1 New column
1344  * 2 New page, 3 Even page, 4 Odd page
1345  */
1346  const char* sType = nullptr;
1347  switch (nBreakCode)
1348  {
1349  case 1:
1351  break;
1352  case 2:
1354  break;
1355  case 3:
1357  break;
1358  case 4:
1360  break;
1361  default:
1363  break;
1364  }
1365  m_aSectionBreaks.append(sType);
1366  if (!m_bBufferSectionBreaks)
1367  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
1368 }
1369 
1370 void RtfAttributeOutput::NumberingDefinition(sal_uInt16 nId, const SwNumRule& /*rRule*/)
1371 {
1372  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE);
1373  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1374  m_rExport.OutULong(nId);
1375  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT).WriteChar('0');
1376  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LS);
1377  m_rExport.OutULong(nId).WriteChar('}');
1378 }
1379 
1381 {
1382  m_rExport.Strm()
1383  .WriteChar('{')
1384  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LIST)
1386  m_rExport.OutULong(nId);
1387  m_nListId = nId;
1388 }
1389 
1391 {
1392  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1393  m_rExport.OutULong(m_nListId).WriteChar('}').WriteCharPtr(SAL_NEWLINE_STRING);
1394 }
1395 
1396 void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel, sal_uInt16 nStart,
1397  sal_uInt16 nNumberingType, SvxAdjust eAdjust,
1398  const sal_uInt8* pNumLvlPos, sal_uInt8 nFollow,
1399  const wwFont* pFont, const SfxItemSet* pOutSet,
1400  sal_Int16 nIndentAt, sal_Int16 nFirstLineIndex,
1401  sal_Int16 /*nListTabPos*/, const OUString& rNumberingString,
1402  const SvxBrushItem* pBrush)
1403 {
1404  m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1405  if (nLevel > 8) // RTF knows only 9 levels
1406  m_rExport.Strm()
1407  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE)
1408  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SOUTLVL);
1409 
1410  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTLEVEL);
1411 
1412  sal_uInt16 nVal = 0;
1413  switch (nNumberingType)
1414  {
1415  case SVX_NUM_ROMAN_UPPER:
1416  nVal = 1;
1417  break;
1418  case SVX_NUM_ROMAN_LOWER:
1419  nVal = 2;
1420  break;
1423  nVal = 3;
1424  break;
1427  nVal = 4;
1428  break;
1430  nVal = 14;
1431  break;
1432  case SVX_NUM_CIRCLE_NUMBER:
1433  nVal = 18;
1434  break;
1436  nVal = 35;
1437  if (pOutSet)
1438  {
1439  const SvxLanguageItem& rLang = pOutSet->Get(RES_CHRATR_CJK_LANGUAGE);
1441  {
1442  nVal = 39;
1443  }
1444  }
1445  break;
1447  nVal = 38;
1448  break;
1450  nVal = 34;
1451  break;
1452  case SVX_NUM_TIAN_GAN_ZH:
1453  nVal = 30;
1454  break;
1455  case SVX_NUM_DI_ZI_ZH:
1456  nVal = 31;
1457  break;
1459  nVal = 16;
1460  break;
1462  nVal = 20;
1463  break;
1465  nVal = 12;
1466  break;
1468  nVal = 21;
1469  break;
1471  nVal = 13;
1472  break;
1473  case style::NumberingType::HANGUL_SYLLABLE_KO:
1474  nVal = 24;
1475  break; // ganada
1476  case style::NumberingType::HANGUL_JAMO_KO:
1477  nVal = 25;
1478  break; // chosung
1479  case style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO:
1480  nVal = 24;
1481  break;
1482  case style::NumberingType::HANGUL_CIRCLED_JAMO_KO:
1483  nVal = 25;
1484  break;
1485  case style::NumberingType::NUMBER_HANGUL_KO:
1486  nVal = 41;
1487  break;
1488  case style::NumberingType::NUMBER_UPPER_KO:
1489  nVal = 44;
1490  break;
1491 
1492  case SVX_NUM_BITMAP:
1493  case SVX_NUM_CHAR_SPECIAL:
1494  nVal = 23;
1495  break;
1496  case SVX_NUM_NUMBER_NONE:
1497  nVal = 255;
1498  break;
1499  }
1500  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNFC);
1501  m_rExport.OutULong(nVal);
1502 
1503  switch (eAdjust)
1504  {
1505  case SvxAdjust::Center:
1506  nVal = 1;
1507  break;
1508  case SvxAdjust::Right:
1509  nVal = 2;
1510  break;
1511  default:
1512  nVal = 0;
1513  break;
1514  }
1515  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELJC);
1516  m_rExport.OutULong(nVal);
1517 
1518  // bullet
1519  if (nNumberingType == SVX_NUM_BITMAP && pBrush)
1520  {
1521  int nIndex = m_rExport.GetGrfIndex(*pBrush);
1522  if (nIndex != -1)
1523  {
1524  m_rExport.Strm().WriteCharPtr(LO_STRING_SVTOOLS_RTF_LEVELPICTURE);
1525  m_rExport.OutULong(nIndex);
1526  }
1527  }
1528 
1529  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT);
1530  m_rExport.OutULong(nStart);
1531 
1532  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW);
1533  m_rExport.OutULong(nFollow);
1534 
1535  // leveltext group
1536  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELTEXT).WriteChar(' ');
1537 
1538  if (SVX_NUM_CHAR_SPECIAL == nNumberingType || SVX_NUM_BITMAP == nNumberingType)
1539  {
1540  m_rExport.Strm().WriteCharPtr("\\'01");
1541  sal_Unicode cChar = rNumberingString[0];
1542  m_rExport.Strm().WriteCharPtr("\\u");
1543  m_rExport.OutULong(cChar);
1544  m_rExport.Strm().WriteCharPtr(" ?");
1545  }
1546  else
1547  {
1548  m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(
1549  msfilter::rtfutil::OutHex(rNumberingString.getLength(), 2).getStr());
1550  m_rExport.Strm().WriteCharPtr(msfilter::rtfutil::OutString(rNumberingString,
1551  m_rExport.GetDefaultEncoding(),
1552  /*bUnicode =*/false)
1553  .getStr());
1554  }
1555 
1556  m_rExport.Strm().WriteCharPtr(";}");
1557 
1558  // write the levelnumbers
1559  m_rExport.Strm().WriteCharPtr("{").WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS);
1560  for (sal_uInt8 i = 0; i <= nLevel && pNumLvlPos[i]; ++i)
1561  {
1562  m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(
1563  msfilter::rtfutil::OutHex(pNumLvlPos[i], 2).getStr());
1564  }
1565  m_rExport.Strm().WriteCharPtr(";}");
1566 
1567  if (pOutSet)
1568  {
1569  if (pFont)
1570  {
1571  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
1572  m_rExport.OutULong(m_rExport.m_aFontHelper.GetId(*pFont));
1573  }
1574  m_rExport.OutputItemSet(*pOutSet, false, true, i18n::ScriptType::LATIN,
1575  m_rExport.m_bExportModeRTF);
1576  const OString aProperties = MoveCharacterProperties(true);
1577  m_rExport.Strm().WriteCharPtr(aProperties.getStr());
1578  }
1579 
1580  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FI);
1581  m_rExport.OutLong(nFirstLineIndex).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LI);
1582  m_rExport.OutLong(nIndentAt);
1583 
1584  m_rExport.Strm().WriteChar('}');
1585  if (nLevel > 8)
1586  m_rExport.Strm().WriteChar('}');
1587 }
1588 
1590  const OUString& rFieldCmd, FieldFlags nMode)
1591 {
1592  // If there are no field instructions, don't export it as a field.
1593  bool bHasInstructions = !rFieldCmd.isEmpty();
1594  if (FieldFlags::All == nMode)
1595  {
1596  if (bHasInstructions)
1597  {
1598  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1600  " ");
1601  m_aRunText->append(
1602  msfilter::rtfutil::OutString(rFieldCmd, m_rExport.GetCurrentEncoding()));
1603  m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1604  }
1605  if (pField)
1606  m_aRunText->append(msfilter::rtfutil::OutString(pField->ExpandField(true, nullptr),
1607  m_rExport.GetDefaultEncoding()));
1608  if (bHasInstructions)
1609  m_aRunText->append("}}");
1610  }
1611  else if (eType == ww::eEQ)
1612  {
1613  if (FieldFlags::Start & nMode)
1614  {
1615  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1617  " ");
1618  }
1619  if (bHasInstructions)
1620  m_aRunText->append(
1621  msfilter::rtfutil::OutString(rFieldCmd, m_rExport.GetCurrentEncoding()));
1622  if (FieldFlags::End & nMode)
1623  {
1624  m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1625  m_aRunText->append("}}");
1626  }
1627  }
1628 }
1629 
1630 void RtfAttributeOutput::WriteBookmarks_Impl(std::vector<OUString>& rStarts,
1631  std::vector<OUString>& rEnds)
1632 {
1633  for (const auto& rStart : rStarts)
1634  {
1636  m_aRun->append(msfilter::rtfutil::OutString(rStart, m_rExport.GetCurrentEncoding()));
1637  m_aRun->append('}');
1638  }
1639  rStarts.clear();
1640 
1641  for (const auto& rEnd : rEnds)
1642  {
1644  m_aRun->append(msfilter::rtfutil::OutString(rEnd, m_rExport.GetCurrentEncoding()));
1645  m_aRun->append('}');
1646  }
1647  rEnds.clear();
1648 }
1649 
1650 void RtfAttributeOutput::WriteAnnotationMarks_Impl(std::vector<OUString>& rStarts,
1651  std::vector<OUString>& rEnds)
1652 {
1653  for (const auto& rStart : rStarts)
1654  {
1655  OString rName = OUStringToOString(rStart, RTL_TEXTENCODING_UTF8);
1656 
1657  // Output the annotation mark
1658  const sal_Int32 nId = m_nNextAnnotationMarkId++;
1659  m_rOpenedAnnotationMarksIds[rName] = nId;
1661  m_aRun->append(OString::number(nId).getStr());
1662  m_aRun->append('}');
1663  }
1664  rStarts.clear();
1665 
1666  for (const auto& rEnd : rEnds)
1667  {
1668  OString rName = OUStringToOString(rEnd, RTL_TEXTENCODING_UTF8);
1669 
1670  // Get the id of the annotation mark
1671  auto it = m_rOpenedAnnotationMarksIds.find(rName);
1672  if (it != m_rOpenedAnnotationMarksIds.end())
1673  {
1674  const sal_Int32 nId = it->second;
1676  m_aRun->append(OString::number(nId).getStr());
1677  m_aRun->append('}');
1678  m_rOpenedAnnotationMarksIds.erase(rName);
1679 
1680  if (m_aPostitFields.find(nId) != m_aPostitFields.end())
1681  {
1682  m_aRunText->append("{");
1683  m_nCurrentAnnotationMarkId = nId;
1684  PostitField(m_aPostitFields[nId]);
1685  m_nCurrentAnnotationMarkId = -1;
1686  m_aRunText->append("}");
1687  }
1688  }
1689  }
1690  rEnds.clear();
1691 }
1692 
1694  const sal_Char* pStr, bool bTitlepg)
1695 {
1696  OStringBuffer aSectionBreaks = m_aSectionBreaks;
1697  m_aSectionBreaks.setLength(0);
1698  RtfStringBuffer aRun = m_aRun;
1699  m_aRun.clear();
1700 
1701  m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY
1703  m_aSectionHeaders.append(
1704  static_cast<sal_Int32>(m_rExport.m_pCurrentPageDesc->GetMaster().GetULSpace().GetUpper()));
1705  if (bTitlepg)
1706  m_aSectionHeaders.append(OOO_STRING_SVTOOLS_RTF_TITLEPG);
1707  m_aSectionHeaders.append('{');
1708  m_aSectionHeaders.append(pStr);
1709  m_bBufferSectionHeaders = true;
1710  m_rExport.WriteHeaderFooterText(rFormat, bHeader);
1711  m_bBufferSectionHeaders = false;
1712  m_aSectionHeaders.append('}');
1713 
1714  m_aSectionBreaks = aSectionBreaks;
1715  m_aRun = aRun;
1716 }
1717 
1718 namespace
1719 {
1720 void lcl_TextFrameShadow(std::vector<std::pair<OString, OString>>& rFlyProperties,
1721  const SwFrameFormat& rFrameFormat)
1722 {
1723  const SvxShadowItem& aShadowItem = rFrameFormat.GetShadow();
1724  if (aShadowItem.GetLocation() == SvxShadowLocation::NONE)
1725  return;
1726 
1727  rFlyProperties.push_back(std::make_pair<OString, OString>("fShadow", OString::number(1)));
1728 
1729  const Color& rColor = aShadowItem.GetColor();
1730  // We in fact need RGB to BGR, but the transformation is symmetric.
1731  rFlyProperties.push_back(std::make_pair<OString, OString>(
1732  "shadowColor", OString::number(wwUtility::RGBToBGR(rColor))));
1733 
1734  // Twips -> points -> EMUs -- hacky, the intermediate step hides rounding errors on roundtrip.
1735  OString aShadowWidth = OString::number(sal_Int32(aShadowItem.GetWidth() / 20) * 12700);
1736  OString aOffsetX;
1737  OString aOffsetY;
1738  switch (aShadowItem.GetLocation())
1739  {
1740  case SvxShadowLocation::TopLeft:
1741  aOffsetX = "-" + aShadowWidth;
1742  aOffsetY = "-" + aShadowWidth;
1743  break;
1744  case SvxShadowLocation::TopRight:
1745  aOffsetX = aShadowWidth;
1746  aOffsetY = "-" + aShadowWidth;
1747  break;
1748  case SvxShadowLocation::BottomLeft:
1749  aOffsetX = "-" + aShadowWidth;
1750  aOffsetY = aShadowWidth;
1751  break;
1752  case SvxShadowLocation::BottomRight:
1753  aOffsetX = aShadowWidth;
1754  aOffsetY = aShadowWidth;
1755  break;
1756  case SvxShadowLocation::NONE:
1757  case SvxShadowLocation::End:
1758  break;
1759  }
1760  if (!aOffsetX.isEmpty())
1761  rFlyProperties.emplace_back("shadowOffsetX", aOffsetX);
1762  if (!aOffsetY.isEmpty())
1763  rFlyProperties.emplace_back("shadowOffsetY", aOffsetY);
1764 }
1765 
1766 void lcl_TextFrameRelativeSize(std::vector<std::pair<OString, OString>>& rFlyProperties,
1767  const SwFrameFormat& rFrameFormat)
1768 {
1769  const SwFormatFrameSize& rSize = rFrameFormat.GetFrameSize();
1770 
1771  // Relative size of the Text Frame.
1772  const sal_uInt8 nWidthPercent = rSize.GetWidthPercent();
1773  if (nWidthPercent && nWidthPercent != SwFormatFrameSize::SYNCED)
1774  {
1775  rFlyProperties.push_back(
1776  std::make_pair<OString, OString>("pctHoriz", OString::number(nWidthPercent * 10)));
1777 
1778  OString aRelation;
1779  switch (rSize.GetWidthPercentRelation())
1780  {
1781  case text::RelOrientation::PAGE_FRAME:
1782  aRelation = "1"; // page
1783  break;
1784  default:
1785  aRelation = "0"; // margin
1786  break;
1787  }
1788  rFlyProperties.emplace_back(std::make_pair("sizerelh", aRelation));
1789  }
1790  const sal_uInt8 nHeightPercent = rSize.GetHeightPercent();
1791  if (nHeightPercent && nHeightPercent != SwFormatFrameSize::SYNCED)
1792  {
1793  rFlyProperties.push_back(
1794  std::make_pair<OString, OString>("pctVert", OString::number(nHeightPercent * 10)));
1795 
1796  OString aRelation;
1797  switch (rSize.GetHeightPercentRelation())
1798  {
1799  case text::RelOrientation::PAGE_FRAME:
1800  aRelation = "1"; // page
1801  break;
1802  default:
1803  aRelation = "0"; // margin
1804  break;
1805  }
1806  rFlyProperties.emplace_back(std::make_pair("sizerelv", aRelation));
1807  }
1808 }
1809 }
1810 
1811 void RtfAttributeOutput::writeTextFrame(const ww8::Frame& rFrame, bool bTextBox)
1812 {
1813  RtfStringBuffer aRunText;
1814  if (bTextBox)
1815  {
1816  m_rExport.setStream();
1817  aRunText = m_aRunText;
1818  m_aRunText.clear();
1819  }
1820 
1821  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
1822 
1823  {
1824  // Save table state, in case the inner text also contains a table.
1825  ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.m_pTableInfo;
1826  m_rExport.m_pTableInfo = std::make_shared<ww8::WW8TableInfo>();
1827  std::unique_ptr<SwWriteTable> pTableWrt(std::move(m_pTableWrt));
1828  sal_uInt32 nTableDepth = m_nTableDepth;
1829 
1830  m_nTableDepth = 0;
1831  /*
1832  * Save m_aRun as we should not lose the opening brace.
1833  * OTOH, just drop the contents of m_aRunText in case something
1834  * would be there, causing a problem later.
1835  */
1836  OString aSave = m_aRun.makeStringAndClear();
1837  // Also back m_bInRun and m_bSingleEmptyRun up.
1838  bool bInRunOrig = m_bInRun;
1839  m_bInRun = false;
1840  bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
1841  m_bSingleEmptyRun = false;
1842  m_rExport.SetRTFFlySyntax(true);
1843 
1844  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
1845  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
1846  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
1847  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1848  m_rExport.SaveData(nStt, nEnd);
1849  m_rExport.m_pParentFrame = &rFrame;
1850  m_rExport.WriteText();
1851  m_rExport.RestoreData();
1852 
1853  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
1854  m_rExport.SetRTFFlySyntax(false);
1855  m_aRun->append(aSave);
1856  m_aRunText.clear();
1857  m_bInRun = bInRunOrig;
1858  m_bSingleEmptyRun = bSingleEmptyRunOrig;
1859 
1860  // Restore table state.
1861  m_rExport.m_pTableInfo = pTableInfoOrig;
1862  m_pTableWrt = std::move(pTableWrt);
1863  m_nTableDepth = nTableDepth;
1864  }
1865 
1866  m_rExport.m_pParentFrame = nullptr;
1867 
1868  m_rExport.Strm().WriteChar('}'); // shptxt
1869 
1870  if (bTextBox)
1871  {
1872  m_aRunText = aRunText;
1873  m_aRunText->append(m_rExport.getStream());
1874  m_rExport.resetStream();
1875  }
1876 }
1877 
1878 void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Point& /*rNdTopLeft*/)
1879 {
1880  const SwNode* pNode = rFrame.GetContent();
1881  const SwGrfNode* pGrfNode = pNode ? pNode->GetGrfNode() : nullptr;
1882 
1883  switch (rFrame.GetWriterType())
1884  {
1885  case ww8::Frame::eTextBox:
1886  {
1887  // If this is a TextBox of a shape, then ignore: it's handled in RtfSdrExport::StartShape().
1889  break;
1890 
1891  OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
1892  m_rExport.m_pParentFrame = &rFrame;
1893 
1894  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP);
1895  m_rExport.Strm().WriteCharPtr(
1897 
1898  // Shape properties.
1899  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
1900  "shapeType", OString::number(ESCHER_ShpInst_TextBox)));
1901 
1902  // When a frame has some low height, but automatically expanded due
1903  // to lots of contents, this size contains the real size.
1904  const Size aSize = rFrame.GetSize();
1905  m_pFlyFrameSize = &aSize;
1906 
1907  m_rExport.m_bOutFlyFrameAttrs = true;
1908  m_rExport.SetRTFFlySyntax(true);
1909  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1910 
1911  // Write ZOrder.
1912  if (const SdrObject* pObject = rFrame.GetFrameFormat().FindRealSdrObject())
1913  {
1914  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPZ);
1915  m_rExport.OutULong(pObject->GetOrdNum());
1916  }
1917 
1918  m_rExport.Strm().WriteCharPtr(m_aRunText.makeStringAndClear().getStr());
1919  m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
1920  m_rExport.m_bOutFlyFrameAttrs = false;
1921  m_rExport.SetRTFFlySyntax(false);
1922  m_pFlyFrameSize = nullptr;
1923 
1924  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
1925  lcl_TextFrameShadow(m_aFlyProperties, rFrameFormat);
1926  lcl_TextFrameRelativeSize(m_aFlyProperties, rFrameFormat);
1927 
1928  for (std::pair<OString, OString>& rPair : m_aFlyProperties)
1929  {
1930  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
1931  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
1932  m_rExport.Strm().WriteCharPtr(rPair.first.getStr());
1933  m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
1934  m_rExport.Strm().WriteCharPtr(rPair.second.getStr());
1935  m_rExport.Strm().WriteCharPtr("}}");
1936  }
1937  m_aFlyProperties.clear();
1938 
1939  writeTextFrame(rFrame);
1940 
1941  m_rExport.Strm().WriteChar('}'); // shpinst
1942  m_rExport.Strm().WriteChar('}'); // shp
1943 
1944  m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1945  }
1946  break;
1947  case ww8::Frame::eGraphic:
1948  if (!rFrame.IsInline())
1949  {
1950  m_rExport.m_pParentFrame = &rFrame;
1951  m_rExport.SetRTFFlySyntax(true);
1952  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1953  m_rExport.SetRTFFlySyntax(false);
1954  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
1955  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1956  m_aRunText->append('}');
1957  m_rExport.m_pParentFrame = nullptr;
1958  }
1959 
1960  if (pGrfNode)
1961  m_aRunText.append(dynamic_cast<const SwFlyFrameFormat*>(&rFrame.GetFrameFormat()),
1962  pGrfNode);
1963  break;
1964  case ww8::Frame::eDrawing:
1965  {
1966  const SdrObject* pSdrObj = rFrame.GetFrameFormat().FindRealSdrObject();
1967  if (pSdrObj)
1968  {
1969  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
1970  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
1971  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
1972  m_aRunText->append(" SHAPE ");
1973  m_aRunText->append("}"
1975 
1976  m_rExport.SdrExporter().AddSdrObject(*pSdrObj);
1977 
1978  m_aRunText->append('}');
1979  m_aRunText->append('}');
1980  }
1981  }
1982  break;
1984  {
1985  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
1986  const SdrObject* pObject = rFrameFormat.FindRealSdrObject();
1987 
1988  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1990 
1991  if (pObject && pObject->GetObjInventor() == SdrInventor::FmForm)
1992  {
1993  if (auto pFormObj = dynamic_cast<const SdrUnoObj*>(pObject))
1994  {
1995  const uno::Reference<awt::XControlModel>& xControlModel
1996  = pFormObj->GetUnoControlModel();
1997  uno::Reference<lang::XServiceInfo> xInfo(xControlModel, uno::UNO_QUERY);
1998  if (xInfo.is())
1999  {
2000  uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
2001  uno::Reference<beans::XPropertySetInfo> xPropSetInfo
2002  = xPropSet->getPropertySetInfo();
2003  OUString sName;
2004  if (xInfo->supportsService("com.sun.star.form.component.CheckBox"))
2005  {
2007  m_rExport.GetCurrentEncoding()));
2008  m_aRun->append(
2010  "{");
2011  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
2012  // checkbox size in half points, this seems to be always 20
2013  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
2014 
2015  OUString aStr;
2016  sName = "Name";
2017  if (xPropSetInfo->hasPropertyByName(sName))
2018  {
2019  xPropSet->getPropertyValue(sName) >>= aStr;
2020  m_aRun->append(
2022  " ");
2023  m_aRun->append(
2024  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2025  m_aRun->append('}');
2026  }
2027 
2028  sName = "HelpText";
2029  if (xPropSetInfo->hasPropertyByName(sName))
2030  {
2031  xPropSet->getPropertyValue(sName) >>= aStr;
2032  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
2033  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2035  m_aRun->append(
2036  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2037  m_aRun->append('}');
2038  }
2039 
2040  sName = "HelpF1Text";
2041  if (xPropSetInfo->hasPropertyByName(sName))
2042  {
2043  xPropSet->getPropertyValue(sName) >>= aStr;
2044  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
2045  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2047  m_aRun->append(
2048  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2049  m_aRun->append('}');
2050  }
2051 
2052  sal_Int16 nTemp = 0;
2053  xPropSet->getPropertyValue("DefaultState") >>= nTemp;
2054  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
2055  m_aRun->append(static_cast<sal_Int32>(nTemp));
2056  xPropSet->getPropertyValue("State") >>= nTemp;
2057  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
2058  m_aRun->append(static_cast<sal_Int32>(nTemp));
2059 
2060  m_aRun->append("}}");
2061 
2062  // field result is empty, ffres already contains the form result
2063  m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
2064  }
2065  else if (xInfo->supportsService("com.sun.star.form.component.TextField"))
2066  {
2067  OStringBuffer aBuf;
2068  OString aStr;
2069  OUString aTmp;
2070  const sal_Char* pStr;
2071 
2073  m_rExport.GetCurrentEncoding()));
2074  m_aRun->append(
2076  " ");
2077  for (int i = 0; i < 8; i++)
2078  aBuf.append(sal_Char(0x00));
2079  xPropSet->getPropertyValue("Name") >>= aTmp;
2080  aStr = OUStringToOString(aTmp, m_rExport.GetCurrentEncoding());
2081  aBuf.append(static_cast<sal_Char>(aStr.getLength()));
2082  aBuf.append(aStr);
2083  aBuf.append(sal_Char(0x00));
2084  xPropSet->getPropertyValue("DefaultText") >>= aTmp;
2085  aStr = OUStringToOString(aTmp, m_rExport.GetCurrentEncoding());
2086  aBuf.append(static_cast<sal_Char>(aStr.getLength()));
2087  aBuf.append(aStr);
2088  for (int i = 0; i < 11; i++)
2089  aBuf.append(sal_Char(0x00));
2090  aStr = aBuf.makeStringAndClear();
2091  pStr = aStr.getStr();
2092  for (int i = 0; i < aStr.getLength(); i++, pStr++)
2093  m_aRun->append(msfilter::rtfutil::OutHex(*pStr, 2));
2094  m_aRun->append('}');
2095  m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
2096  xPropSet->getPropertyValue("Text") >>= aTmp;
2097  m_aRun->append(OUStringToOString(aTmp, m_rExport.GetCurrentEncoding()));
2098  m_aRun->append('}');
2099  m_aRun->append(
2101  "{");
2102  sName = "HelpText";
2103  if (xPropSetInfo->hasPropertyByName(sName))
2104  {
2105  xPropSet->getPropertyValue(sName) >>= aTmp;
2106  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
2107  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2109  m_aRun->append(
2110  OUStringToOString(aTmp, m_rExport.GetCurrentEncoding()));
2111  m_aRun->append('}');
2112  }
2113 
2114  sName = "HelpF1Text";
2115  if (xPropSetInfo->hasPropertyByName(sName))
2116  {
2117  xPropSet->getPropertyValue(sName) >>= aTmp;
2118  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
2119  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2121  m_aRun->append(
2122  OUStringToOString(aTmp, m_rExport.GetCurrentEncoding()));
2123  m_aRun->append('}');
2124  }
2125  m_aRun->append("}");
2126  }
2127  else if (xInfo->supportsService("com.sun.star.form.component.ListBox"))
2128  {
2129  OUString aStr;
2130  uno::Sequence<sal_Int16> aIntSeq;
2131  uno::Sequence<OUString> aStrSeq;
2132 
2134  m_rExport.GetCurrentEncoding()));
2135  m_aRun->append(
2137  "{");
2138  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
2139  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
2140 
2141  xPropSet->getPropertyValue("DefaultSelection") >>= aIntSeq;
2142  if (aIntSeq.hasElements())
2143  {
2144  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
2145  // a dropdown list can have only one 'selected item by default'
2146  m_aRun->append(static_cast<sal_Int32>(aIntSeq[0]));
2147  }
2148 
2149  xPropSet->getPropertyValue("SelectedItems") >>= aIntSeq;
2150  if (aIntSeq.hasElements())
2151  {
2152  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
2153  // a dropdown list can have only one 'currently selected item'
2154  m_aRun->append(static_cast<sal_Int32>(aIntSeq[0]));
2155  }
2156 
2157  sName = "Name";
2158  if (xPropSetInfo->hasPropertyByName(sName))
2159  {
2160  xPropSet->getPropertyValue(sName) >>= aStr;
2161  m_aRun->append(
2163  " ");
2164  m_aRun->append(
2165  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2166  m_aRun->append('}');
2167  }
2168 
2169  sName = "HelpText";
2170  if (xPropSetInfo->hasPropertyByName(sName))
2171  {
2172  xPropSet->getPropertyValue(sName) >>= aStr;
2173  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
2174  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2176  m_aRun->append(
2177  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2178  m_aRun->append('}');
2179  }
2180 
2181  sName = "HelpF1Text";
2182  if (xPropSetInfo->hasPropertyByName(sName))
2183  {
2184  xPropSet->getPropertyValue(sName) >>= aStr;
2185  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
2186  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE
2188  m_aRun->append(
2189  OUStringToOString(aStr, m_rExport.GetCurrentEncoding()));
2190  m_aRun->append('}');
2191  }
2192 
2193  xPropSet->getPropertyValue("StringItemList") >>= aStrSeq;
2194  for (const auto& rStr : aStrSeq)
2195  m_aRun
2196  ->append(
2198  " ")
2199  .append(OUStringToOString(rStr, m_rExport.GetCurrentEncoding()))
2200  .append('}');
2201 
2202  m_aRun->append("}}");
2203 
2204  // field result is empty, ffres already contains the form result
2205  m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
2206  }
2207  else
2208  SAL_INFO("sw.rtf", OSL_THIS_FUNC << " unhandled form control: '"
2209  << xInfo->getImplementationName()
2210  << "'");
2211  m_aRun->append('}');
2212  }
2213  }
2214  }
2215 
2216  m_aRun->append('}');
2217  }
2218  break;
2219  case ww8::Frame::eOle:
2220  {
2221  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
2222  const SdrObject* pSdrObj = rFrameFormat.FindRealSdrObject();
2223  if (pSdrObj)
2224  {
2225  SwNodeIndex aIdx(*rFrameFormat.GetContent().GetContentIdx(), 1);
2226  SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
2227  FlyFrameOLE(dynamic_cast<const SwFlyFrameFormat*>(&rFrameFormat), rOLENd,
2228  rFrame.GetLayoutSize());
2229  }
2230  }
2231  break;
2232  default:
2233  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unknown type ("
2234  << static_cast<int>(rFrame.GetWriterType()) << ")");
2235  break;
2236  }
2237 }
2238 
2240 {
2241  switch (rCaseMap.GetValue())
2242  {
2243  case SvxCaseMap::SmallCaps:
2244  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
2245  break;
2246  case SvxCaseMap::Uppercase:
2247  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
2248  break;
2249  default: // Something that rtf does not support
2250  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
2251  m_aStyles.append(sal_Int32(0));
2252  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
2253  m_aStyles.append(sal_Int32(0));
2254  break;
2255  }
2256 }
2257 
2259 {
2260  const Color aColor(rColor.GetValue());
2261 
2262  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
2263  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(aColor)));
2264 }
2265 
2267 {
2268  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
2269  if (!rContour.GetValue())
2270  m_aStyles.append(sal_Int32(0));
2271 }
2272 
2274 {
2275  switch (rCrossedOut.GetStrikeout())
2276  {
2277  case STRIKEOUT_NONE:
2278  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
2279  m_aStyles.append(sal_Int32(0));
2280  break;
2281  case STRIKEOUT_DOUBLE:
2282  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
2283  m_aStyles.append(sal_Int32(1));
2284  break;
2285  default:
2286  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
2287  break;
2288  }
2289 }
2290 
2292 {
2293  short nEsc = rEscapement.GetEsc();
2294  if (rEscapement.GetProportionalHeight() == DFLT_ESC_PROP)
2295  {
2296  if (DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc)
2297  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUB);
2298  else if (DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc)
2299  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUPER);
2300  return;
2301  }
2302 
2303  const char* pUpDn;
2304 
2305  SwTwips nH = m_rExport.GetItem(RES_CHRATR_FONTSIZE).GetHeight();
2306 
2307  if (0 < rEscapement.GetEsc())
2308  pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
2309  else if (0 > rEscapement.GetEsc())
2310  {
2311  pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
2312  nH = -nH;
2313  }
2314  else
2315  return;
2316 
2317  short nProp = rEscapement.GetProportionalHeight() * 100;
2318  if (DFLT_ESC_AUTO_SUPER == nEsc)
2319  {
2320  nEsc = 100 - rEscapement.GetProportionalHeight();
2321  ++nProp;
2322  }
2323  else if (DFLT_ESC_AUTO_SUB == nEsc)
2324  {
2325  nEsc = -100 + rEscapement.GetProportionalHeight();
2326  ++nProp;
2327  }
2328 
2329  m_aStyles.append('{');
2330  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
2331  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
2332  m_aStyles.append(static_cast<sal_Int32>(nProp));
2333  m_aStyles.append('}');
2334  m_aStyles.append(pUpDn);
2335 
2336  /*
2337  * Calculate the act. FontSize and the percentage of the displacement;
2338  * RTF file expects half points, while internally it's in twips.
2339  * Formally : (FontSize * 1/20 ) pts x * 2
2340  * ----------------------- = ------------
2341  * 100% Escapement
2342  */
2343 
2344  m_aStyles.append(static_cast<sal_Int32>((long(nEsc) * nH) + 500) / 1000);
2345  // 500 to round !!
2346 }
2347 
2349 {
2350  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LOCH);
2351  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_F);
2352  m_aStyles.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2353 
2354  if (!m_rExport.HasItem(RES_CHRATR_CJK_FONT) && !m_rExport.HasItem(RES_CHRATR_CTL_FONT))
2355  {
2356  // Be explicit about that the given font should be used everywhere, not
2357  // just for the loch range.
2358  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_HICH);
2359  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2360  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2361  }
2362 
2363  // FIXME: this may be a tad expensive... but the charset needs to be
2364  // consistent with what wwFont::WriteRtf() does
2365  sw::util::FontMapExport aTmp(rFont.GetFamilyName());
2367  aTmp.msPrimary, aTmp.msSecondary, rFont.GetCharSet());
2368  m_rExport.SetCurrentEncoding(rtl_getTextEncodingFromWindowsCharset(nWindowsCharset));
2369  if (m_rExport.GetCurrentEncoding() == RTL_TEXTENCODING_DONTKNOW)
2370  m_rExport.SetCurrentEncoding(m_rExport.GetDefaultEncoding());
2371 }
2372 
2374 {
2375  switch (rFontSize.Which())
2376  {
2377  case RES_CHRATR_FONTSIZE:
2378  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
2379  m_aStyles.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2380  break;
2382  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_FS);
2383  m_aStylesAssoc.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2384  break;
2386  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AFS);
2387  m_aStylesAssoc.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2388  break;
2389  }
2390 }
2391 
2393 {
2394  // in quarter points then in twips
2395  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
2396  m_aStyles.append(static_cast<sal_Int32>(rKerning.GetValue() / 5));
2397  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
2398  m_aStyles.append(static_cast<sal_Int32>(rKerning.GetValue()));
2399 }
2400 
2402 {
2403  switch (rLanguage.Which())
2404  {
2405  case RES_CHRATR_LANGUAGE:
2406  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANG);
2407  m_aStyles.append(
2408  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2409  break;
2411  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
2412  m_aStylesAssoc.append(
2413  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2414  break;
2416  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_ALANG);
2417  m_aStylesAssoc.append(
2418  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2419  break;
2420  }
2421 }
2422 
2424 {
2425  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2426  if (rPosture.GetPosture() == ITALIC_NONE)
2427  m_aStyles.append(sal_Int32(0));
2428 }
2429 
2431 {
2432  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
2433  if (!rShadow.GetValue())
2434  m_aStyles.append(sal_Int32(0));
2435 }
2436 
2438 {
2439  const char* pStr = nullptr;
2440  const SfxPoolItem* pItem = m_rExport.HasItem(RES_CHRATR_WORDLINEMODE);
2441  bool bWord = false;
2442  if (pItem)
2443  bWord = static_cast<const SvxWordLineModeItem*>(pItem)->GetValue();
2444  switch (rUnderline.GetLineStyle())
2445  {
2446  case LINESTYLE_SINGLE:
2448  break;
2449  case LINESTYLE_DOUBLE:
2451  break;
2452  case LINESTYLE_NONE:
2454  break;
2455  case LINESTYLE_DOTTED:
2457  break;
2458  case LINESTYLE_DASH:
2460  break;
2461  case LINESTYLE_DASHDOT:
2463  break;
2464  case LINESTYLE_DASHDOTDOT:
2466  break;
2467  case LINESTYLE_BOLD:
2469  break;
2470  case LINESTYLE_WAVE:
2472  break;
2473  case LINESTYLE_BOLDDOTTED:
2475  break;
2476  case LINESTYLE_BOLDDASH:
2478  break;
2479  case LINESTYLE_LONGDASH:
2481  break;
2484  break;
2485  case LINESTYLE_BOLDDASHDOT:
2487  break;
2490  break;
2491  case LINESTYLE_BOLDWAVE:
2493  break;
2494  case LINESTYLE_DOUBLEWAVE:
2496  break;
2497  default:
2498  break;
2499  }
2500 
2501  if (pStr)
2502  {
2503  m_aStyles.append(pStr);
2504  // NEEDSWORK looks like here rUnderline.GetColor() is always black,
2505  // even if the color in the odt is for example green...
2506  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
2507  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rUnderline.GetColor())));
2508  }
2509 }
2510 
2512 {
2513  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2514  if (rWeight.GetWeight() != WEIGHT_BOLD)
2515  m_aStyles.append(sal_Int32(0));
2516 }
2517 
2519 {
2520  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
2521  m_aStyles.append(static_cast<sal_Int32>(rAutoKern.GetValue() ? 1 : 0));
2522 }
2523 
2525 {
2526  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
2527  m_aStyles.append(static_cast<sal_Int32>(rBlink.GetValue() ? 2 : 0));
2528 }
2529 
2531 {
2532  if (!rBrush.GetColor().GetTransparency())
2533  {
2534  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
2535  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rBrush.GetColor())));
2536  }
2537 }
2538 
2540 {
2541  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2542  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2543  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2544 }
2545 
2547 {
2548  CharFontSize(rFontSize);
2549 }
2550 
2552 {
2553  CharLanguage(rLanguageItem);
2554 }
2555 
2557 {
2558  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_I);
2559  if (rPosture.GetPosture() == ITALIC_NONE)
2560  m_aStylesAssoc.append(sal_Int32(0));
2561 }
2562 
2564 {
2565  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_B);
2566  if (rWeight.GetWeight() != WEIGHT_BOLD)
2567  m_aStylesAssoc.append(sal_Int32(0));
2568 }
2569 
2571 {
2572  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2573  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2574  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2575 }
2576 
2578 {
2579  CharFontSize(rFontSize);
2580 }
2581 
2583 {
2584  CharLanguage(rLanguageItem);
2585 }
2586 
2588 {
2589  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AI);
2590  if (rPosture.GetPosture() == ITALIC_NONE)
2591  m_aStylesAssoc.append(sal_Int32(0));
2592 }
2593 
2595 {
2596  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AB);
2597  if (rWeight.GetWeight() != WEIGHT_BOLD)
2598  m_aStylesAssoc.append(sal_Int32(0));
2599 }
2600 
2602 
2604 
2606 {
2607  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
2608  m_aStyles.append(static_cast<sal_Int32>(rRotate.IsFitToLine() ? 1 : 0));
2609 }
2610 
2612 {
2613  FontEmphasisMark v = rEmphasisMark.GetEmphasisMark();
2614  if (v == FontEmphasisMark::NONE)
2615  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCNONE);
2616  else if (v == (FontEmphasisMark::Dot | FontEmphasisMark::PosAbove))
2617  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCDOT);
2618  else if (v == (FontEmphasisMark::Accent | FontEmphasisMark::PosAbove))
2619  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCOMMA);
2620  else if (v == (FontEmphasisMark::Circle | FontEmphasisMark::PosAbove))
2621  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCIRCLE);
2622  else if (v == (FontEmphasisMark::Dot | FontEmphasisMark::PosBelow))
2623  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCUNDERDOT);
2624 }
2625 
2627 {
2628  if (rTwoLines.GetValue())
2629  {
2630  sal_Unicode cStart = rTwoLines.GetStartBracket();
2631  sal_Unicode cEnd = rTwoLines.GetEndBracket();
2632 
2633  sal_uInt16 nType;
2634  if (!cStart && !cEnd)
2635  nType = 0;
2636  else if ('{' == cStart || '}' == cEnd)
2637  nType = 4;
2638  else if ('<' == cStart || '>' == cEnd)
2639  nType = 3;
2640  else if ('[' == cStart || ']' == cEnd)
2641  nType = 2;
2642  else // all other kind of brackets
2643  nType = 1;
2644 
2645  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
2646  m_aStyles.append(static_cast<sal_Int32>(nType));
2647  }
2648 }
2649 
2651 {
2652  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
2653  m_aStyles.append(static_cast<sal_Int32>(rScaleWidth.GetValue()));
2654 }
2655 
2657 {
2658  const sal_Char* pStr;
2659  switch (rRelief.GetValue())
2660  {
2661  case FontRelief::Embossed:
2663  break;
2664  case FontRelief::Engraved:
2666  break;
2667  default:
2668  pStr = nullptr;
2669  break;
2670  }
2671 
2672  if (pStr)
2673  m_aStyles.append(pStr);
2674 }
2675 
2677 {
2678  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
2679  if (!rHidden.GetValue())
2680  m_aStyles.append(sal_Int32(0));
2681 }
2682 
2684  const sal_uInt16 nDist, const bool bShadow)
2685 {
2686  m_aStyles.append(
2687  OutBorderLine(m_rExport, pAllBorder, OOO_STRING_SVTOOLS_RTF_CHBRDR, nDist,
2688  bShadow ? SvxShadowLocation::BottomRight : SvxShadowLocation::NONE));
2689 }
2690 
2692 {
2693  if (!rBrush.GetColor().GetTransparency())
2694  {
2695  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
2696  m_aStyles.append(static_cast<sal_Int32>(msfilter::util::TransColToIco(rBrush.GetColor())));
2697  }
2698 }
2699 
2701 {
2702  if (!rURL.GetValue().isEmpty())
2703  {
2704  const SwCharFormat* pFormat;
2705  const SwTextINetFormat* pTextAtr = rURL.GetTextINetFormat();
2706 
2707  if (pTextAtr && nullptr != (pFormat = pTextAtr->GetCharFormat()))
2708  {
2709  sal_uInt16 nStyle = m_rExport.GetId(pFormat);
2710  OString* pString = m_rExport.GetStyle(nStyle);
2711  if (pString)
2712  m_aStyles.append(*pString);
2713  }
2714  }
2715 }
2716 
2718 {
2719  sal_uInt16 nStyle = m_rExport.GetId(rCharFormat.GetCharFormat());
2720  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CS);
2721  m_aStyles.append(static_cast<sal_Int32>(nStyle));
2722  OString* pString = m_rExport.GetStyle(nStyle);
2723  if (pString)
2724  m_aStyles.append(*pString);
2725 }
2726 
2728 {
2729  if (rFootnote.GetNumStr().isEmpty())
2730  m_aRun->append(OOO_STRING_SVTOOLS_RTF_CHFTN);
2731  else
2732  m_aRun->append(
2733  msfilter::rtfutil::OutString(rFootnote.GetNumStr(), m_rExport.GetCurrentEncoding()));
2734 }
2735 
2737 {
2738  SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
2739 
2740  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
2741  EndRunProperties(nullptr);
2742  m_aRun->append(' ');
2743  WriteTextFootnoteNumStr(rFootnote);
2745  if (rFootnote.IsEndNote() || m_rExport.m_pDoc->GetFootnoteInfo().ePos == FTNPOS_CHAPTER)
2746  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
2747  m_aRun->append(' ');
2748  WriteTextFootnoteNumStr(rFootnote);
2749 
2750  /*
2751  * The footnote contains a whole paragraph, so we have to:
2752  * 1) Reset, then later restore the contents of our run buffer and run state.
2753  * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
2754  */
2755  const SwNodeIndex* pIndex = rFootnote.GetTextFootnote()->GetStartNode();
2756  RtfStringBuffer aRun = m_aRun;
2757  m_aRun.clear();
2758  bool bInRunOrig = m_bInRun;
2759  m_bInRun = false;
2760  bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
2761  m_bSingleEmptyRun = false;
2762  m_bBufferSectionHeaders = true;
2763  m_rExport.WriteSpecialText(pIndex->GetIndex() + 1, pIndex->GetNode().EndOfSectionIndex(),
2764  !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
2765  m_bBufferSectionHeaders = false;
2766  m_bInRun = bInRunOrig;
2767  m_bSingleEmptyRun = bSingleEmptyRunOrig;
2768  m_aRun = aRun;
2769  m_aRun->append(m_aSectionHeaders.makeStringAndClear());
2770 
2771  m_aRun->append("}");
2772  m_aRun->append("}");
2773 
2774  SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
2775 }
2776 
2777 void RtfAttributeOutput::ParaLineSpacing_Impl(short nSpace, short nMulti)
2778 {
2779  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
2780  m_aStyles.append(static_cast<sal_Int32>(nSpace));
2781  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
2782  m_aStyles.append(static_cast<sal_Int32>(nMulti));
2783 }
2784 
2786 {
2787  switch (rAdjust.GetAdjust())
2788  {
2789  case SvxAdjust::Left:
2790  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
2791  break;
2792  case SvxAdjust::Right:
2793  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
2794  break;
2795  case SvxAdjust::BlockLine:
2796  case SvxAdjust::Block:
2797  if (rAdjust.GetLastBlock() == SvxAdjust::Block)
2798  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QD);
2799  else
2800  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
2801  break;
2802  case SvxAdjust::Center:
2803  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
2804  break;
2805  default:
2806  break;
2807  }
2808 }
2809 
2811 {
2812  if (!rSplit.GetValue())
2813  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
2814 }
2815 
2817 {
2818  if (rWidows.GetValue())
2819  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
2820  else
2821  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
2822 }
2823 
2825 {
2826  long nOffset = 0;
2827  // Tabs are absolute by default.
2828  if (m_rExport.m_pDoc->getIDocumentSettingAccess().get(
2830  nOffset = m_rExport.GetItem(RES_LR_SPACE).GetTextLeft();
2831 
2832  for (sal_uInt16 n = 0; n < rTabStop.Count(); n++)
2833  {
2834  const SvxTabStop& rTS = rTabStop[n];
2835  if (SvxTabAdjust::Default != rTS.GetAdjustment())
2836  {
2837  const char* pFill = nullptr;
2838  switch (rTS.GetFill())
2839  {
2840  case cDfltFillChar:
2841  break;
2842 
2843  case '.':
2845  break;
2846  case '_':
2848  break;
2849  case '-':
2851  break;
2852  case '=':
2854  break;
2855  default:
2856  break;
2857  }
2858  if (pFill)
2859  m_aStyles.append(pFill);
2860 
2861  const sal_Char* pAdjStr = nullptr;
2862  switch (rTS.GetAdjustment())
2863  {
2864  case SvxTabAdjust::Right:
2865  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
2866  break;
2867  case SvxTabAdjust::Decimal:
2868  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
2869  break;
2870  case SvxTabAdjust::Center:
2871  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
2872  break;
2873  default:
2874  break;
2875  }
2876  if (pAdjStr)
2877  m_aStyles.append(pAdjStr);
2878  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
2879  m_aStyles.append(static_cast<sal_Int32>(rTS.GetTabPos() + nOffset));
2880  }
2881  else
2882  {
2883  m_aTabStop.append(OOO_STRING_SVTOOLS_RTF_DEFTAB);
2884  m_aTabStop.append(rTabStop[0].GetTabPos());
2885  }
2886  }
2887 }
2888 
2890 {
2891  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHPAR);
2892  m_aStyles.append(sal_Int32(rHyphenZone.IsHyphen()));
2893 }
2894 
2895 void RtfAttributeOutput::ParaNumRule_Impl(const SwTextNode* pTextNd, sal_Int32 nLvl,
2896  sal_Int32 nNumId)
2897 {
2898  if (USHRT_MAX == nNumId || 0 == nNumId || nullptr == pTextNd)
2899  return;
2900 
2901  const SwNumRule* pRule = pTextNd->GetNumRule();
2902 
2903  if (!pRule || !pTextNd->IsInList())
2904  return;
2905 
2906  SAL_WARN_IF(pTextNd->GetActualListLevel() < 0 || pTextNd->GetActualListLevel() >= MAXLEVEL,
2907  "sw.rtf", "text node does not have valid list level");
2908 
2909  const SwNumFormat* pFormat = pRule->GetNumFormat(nLvl);
2910  if (!pFormat)
2911  pFormat = &pRule->Get(nLvl);
2912 
2913  const SfxItemSet& rNdSet = pTextNd->GetSwAttrSet();
2914 
2915  m_aStyles.append('{');
2916  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
2917  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
2918  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
2919  m_aStyles.append(' ');
2920 
2921  SvxLRSpaceItem aLR(rNdSet.Get(RES_LR_SPACE));
2922  aLR.SetTextLeft(aLR.GetTextLeft() + pFormat->GetIndentAt());
2923  aLR.SetTextFirstLineOfst(pFormat->GetFirstLineOffset()); //TODO: overflow
2924 
2925  sal_uInt16 nStyle = m_rExport.GetId(pFormat->GetCharFormat());
2926  OString* pString = m_rExport.GetStyle(nStyle);
2927  if (pString)
2928  m_aStyles.append(*pString);
2929 
2930  {
2931  OUString sText;
2932  if (SVX_NUM_CHAR_SPECIAL == pFormat->GetNumberingType()
2933  || SVX_NUM_BITMAP == pFormat->GetNumberingType())
2934  sText = OUString(pFormat->GetBulletChar());
2935  else
2936  sText = pTextNd->GetNumString();
2937 
2938  if (!sText.isEmpty())
2939  {
2940  m_aStyles.append(' ');
2941  m_aStyles.append(msfilter::rtfutil::OutString(sText, m_rExport.GetDefaultEncoding()));
2942  }
2943 
2944  if (OUTLINE_RULE != pRule->GetRuleType())
2945  {
2946  if (!sText.isEmpty())
2947  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
2948  m_aStyles.append('}');
2949  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
2950  if (nLvl > 8) // RTF knows only 9 levels
2951  {
2952  m_aStyles.append(sal_Int32(8));
2954  m_aStyles.append(nLvl);
2955  m_aStyles.append('}');
2956  }
2957  else
2958  m_aStyles.append(nLvl);
2959  }
2960  else
2961  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
2962  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
2963  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetId(*pRule)) + 1);
2964  m_aStyles.append(' ');
2965  }
2966  FormatLRSpace(aLR);
2967 }
2968 
2970 {
2971  if (!rScriptSpace.GetValue())
2972  return;
2973 
2974  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
2975 }
2976 
2978 {
2979  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2980 }
2981 
2983 {
2984  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2985 }
2986 
2988 {
2989  const char* pStr;
2990  switch (rAlign.GetValue())
2991  {
2994  break;
2997  break;
3000  break;
3003  break;
3004 
3005  default:
3007  break;
3008  }
3009  m_aStyles.append(pStr);
3010 }
3011 
3013 {
3014  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3015 }
3016 
3018 {
3019  if (m_rExport.m_bOutPageDescs)
3020  {
3021  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
3022  m_aSectionBreaks.append(static_cast<sal_Int32>(rSize.GetWidth()));
3023  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
3024  m_aSectionBreaks.append(static_cast<sal_Int32>(rSize.GetHeight()));
3025  if (!m_bBufferSectionBreaks)
3026  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
3027  }
3028 }
3029 
3031 {
3032  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3033 }
3034 
3036 {
3037  if (!m_rExport.m_bOutFlyFrameAttrs)
3038  {
3039  if (m_rExport.m_bOutPageDescs)
3040  {
3041  if (rLRSpace.GetLeft())
3042  {
3043  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
3044  m_aSectionBreaks.append(static_cast<sal_Int32>(rLRSpace.GetLeft()));
3045  }
3046  if (rLRSpace.GetRight())
3047  {
3048  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
3049  m_aSectionBreaks.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3050  }
3051  if (!m_bBufferSectionBreaks)
3052  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
3053  }
3054  else
3055  {
3056  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
3057  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextLeft()));
3058  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
3059  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3060  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
3061  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextLeft()));
3062  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
3063  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3064  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
3065  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextFirstLineOfst()));
3066  }
3067  }
3068  else if (m_rExport.GetRTFFlySyntax())
3069  {
3070  // Wrap: top and bottom spacing, convert from twips to EMUs.
3071  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3072  "dxWrapDistLeft", OString::number(rLRSpace.GetLeft() * 635)));
3073  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3074  "dxWrapDistRight", OString::number(rLRSpace.GetRight() * 635)));
3075  }
3076 }
3077 
3079 {
3080  if (!m_rExport.m_bOutFlyFrameAttrs)
3081  {
3082  if (m_rExport.m_bOutPageDescs)
3083  {
3084  OSL_ENSURE(m_rExport.GetCurItemSet(), "Impossible");
3085  if (!m_rExport.GetCurItemSet())
3086  return;
3087 
3088  // If we export a follow page format, then our doc model has
3089  // separate header/footer distances for the first page and the
3090  // follow pages, but Word can have only a single distance. In case
3091  // the two values differ, work with the value from the first page
3092  // format to be in sync with the import.
3093  sw::util::HdFtDistanceGlue aDistances(m_rExport.GetFirstPageItemSet()
3094  ? *m_rExport.GetFirstPageItemSet()
3095  : *m_rExport.GetCurItemSet());
3096 
3097  if (aDistances.dyaTop)
3098  {
3099  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
3100  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaTop));
3101  }
3102  if (aDistances.HasHeader())
3103  {
3104  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_HEADERY);
3105  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaHdrTop));
3106  }
3107 
3108  if (aDistances.dyaBottom)
3109  {
3110  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
3111  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaBottom));
3112  }
3113  if (aDistances.HasFooter())
3114  {
3115  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_FOOTERY);
3116  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaHdrBottom));
3117  }
3118  if (!m_bBufferSectionBreaks)
3119  m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
3120  }
3121  else
3122  {
3123  // Spacing before.
3124  if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == rULSpace.GetUpper())
3125  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SBAUTO "1");
3126  else if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == -1)
3127  {
3128  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SBAUTO "0");
3129  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
3130  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetUpper()));
3131  }
3132  else
3133  {
3134  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
3135  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetUpper()));
3136  }
3137  m_bParaBeforeAutoSpacing = false;
3138 
3139  // Spacing after.
3140  if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == rULSpace.GetLower())
3141  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SAAUTO "1");
3142  else if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == -1)
3143  {
3144  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SAAUTO "0");
3145  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
3146  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetLower()));
3147  }
3148  else
3149  {
3150  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
3151  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetLower()));
3152  }
3153  m_bParaAfterAutoSpacing = false;
3154 
3155  // Contextual spacing.
3156  if (rULSpace.GetContext())
3157  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE);
3158  }
3159  }
3160  else if (m_rExport.GetRTFFlySyntax())
3161  {
3162  // Wrap: top and bottom spacing, convert from twips to EMUs.
3163  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3164  "dyWrapDistTop", OString::number(rULSpace.GetUpper() * 635)));
3165  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3166  "dyWrapDistBottom", OString::number(rULSpace.GetLower() * 635)));
3167  }
3168 }
3169 
3171 {
3172  if (m_rExport.m_bOutFlyFrameAttrs && !m_rExport.GetRTFFlySyntax())
3173  {
3174  css::text::WrapTextMode eSurround = rSurround.GetSurround();
3175  bool bGold = css::text::WrapTextMode_DYNAMIC == eSurround;
3176  if (bGold)
3177  eSurround = css::text::WrapTextMode_PARALLEL;
3178  RTFSurround aMC(bGold, static_cast<sal_uInt8>(eSurround));
3179  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
3180  m_aRunText->append(static_cast<sal_Int32>(aMC.GetValue()));
3181  }
3182  else if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3183  {
3184  // See DocxSdrExport::startDMLAnchorInline() for SwFormatSurround -> WR / WRK mappings.
3185  sal_Int32 nWr = -1;
3187  switch (rSurround.GetValue())
3188  {
3189  case css::text::WrapTextMode_NONE:
3190  nWr = 1; // top and bottom
3191  break;
3192  case css::text::WrapTextMode_THROUGH:
3193  nWr = 3; // none
3194  break;
3195  case css::text::WrapTextMode_PARALLEL:
3196  nWr = 2; // around
3197  oWrk = 0; // both sides
3198  break;
3199  case css::text::WrapTextMode_DYNAMIC:
3200  default:
3201  nWr = 2; // around
3202  oWrk = 3; // largest
3203  break;
3204  }
3205 
3206  if (rSurround.IsContour())
3207  nWr = 4; // tight
3208 
3209  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWR);
3210  m_rExport.OutLong(nWr);
3211  if (oWrk)
3212  {
3213  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWRK);
3214  m_rExport.OutLong(*oWrk);
3215  }
3216  }
3217 }
3218 
3220 {
3221  if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3222  {
3223  switch (rFlyVert.GetRelationOrient())
3224  {
3225  case text::RelOrientation::PAGE_FRAME:
3226  m_aFlyProperties.push_back(
3227  std::make_pair<OString, OString>("posrelv", OString::number(1)));
3228  break;
3229  default:
3230  m_aFlyProperties.push_back(
3231  std::make_pair<OString, OString>("posrelv", OString::number(2)));
3232  m_rExport.Strm()
3233  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYPARA)
3234  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
3235  break;
3236  }
3237 
3238  switch (rFlyVert.GetVertOrient())
3239  {
3241  case text::VertOrientation::LINE_TOP:
3242  m_aFlyProperties.push_back(
3243  std::make_pair<OString, OString>("posv", OString::number(1)));
3244  break;
3246  case text::VertOrientation::LINE_BOTTOM:
3247  m_aFlyProperties.push_back(
3248  std::make_pair<OString, OString>("posv", OString::number(3)));
3249  break;
3250  case text::VertOrientation::CENTER:
3251  case text::VertOrientation::LINE_CENTER:
3252  m_aFlyProperties.push_back(
3253  std::make_pair<OString, OString>("posv", OString::number(2)));
3254  break;
3255  default:
3256  break;
3257  }
3258 
3259  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPTOP);
3260  m_rExport.OutLong(rFlyVert.GetPos());
3261  if (m_pFlyFrameSize)
3262  {
3263  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM);
3264  m_rExport.OutLong(rFlyVert.GetPos() + m_pFlyFrameSize->Height());
3265  }
3266  }
3267 }
3268 
3270 {
3271  if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3272  {
3273  switch (rFlyHori.GetRelationOrient())
3274  {
3275  case text::RelOrientation::PAGE_FRAME:
3276  m_aFlyProperties.push_back(
3277  std::make_pair<OString, OString>("posrelh", OString::number(1)));
3278  break;
3279  default:
3280  m_aFlyProperties.push_back(
3281  std::make_pair<OString, OString>("posrelh", OString::number(2)));
3282  m_rExport.Strm()
3283  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN)
3284  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
3285  break;
3286  }
3287 
3288  switch (rFlyHori.GetHoriOrient())
3289  {
3291  m_aFlyProperties.push_back(
3292  std::make_pair<OString, OString>("posh", OString::number(1)));
3293  break;
3294  case text::HoriOrientation::CENTER:
3295  m_aFlyProperties.push_back(
3296  std::make_pair<OString, OString>("posh", OString::number(2)));
3297  break;
3299  m_aFlyProperties.push_back(
3300  std::make_pair<OString, OString>("posh", OString::number(3)));
3301  break;
3302  default:
3303  break;
3304  }
3305 
3306  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPLEFT);
3307  m_rExport.OutLong(rFlyHori.GetPos());
3308  if (m_pFlyFrameSize)
3309  {
3310  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPRIGHT);
3311  m_rExport.OutLong(rFlyHori.GetPos() + m_pFlyFrameSize->Width());
3312  }
3313  }
3314 }
3315 
3317 {
3318  if (!m_rExport.GetRTFFlySyntax())
3319  {
3320  RndStdIds eId = rAnchor.GetAnchorId();
3321  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
3322  m_aRunText->append(static_cast<sal_Int32>(eId));
3323  switch (eId)
3324  {
3325  case RndStdIds::FLY_AT_PAGE:
3326  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
3327  m_aRunText->append(static_cast<sal_Int32>(rAnchor.GetPageNum()));
3328  break;
3329  case RndStdIds::FLY_AT_PARA:
3330  case RndStdIds::FLY_AS_CHAR:
3331  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
3332  break;
3333  default:
3334  break;
3335  }
3336  }
3337 }
3338 
3340 {
3341  if (m_rExport.GetRTFFlySyntax())
3342  {
3343  const Color& rColor = rBrush.GetColor();
3344  // We in fact need RGB to BGR, but the transformation is symmetric.
3345  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3346  "fillColor", OString::number(wwUtility::RGBToBGR(rColor))));
3347  }
3348  else if (!rBrush.GetColor().GetTransparency())
3349  {
3350  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CBPAT);
3351  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rBrush.GetColor())));
3352  }
3353 }
3354 
3356 {
3357  m_oFillStyle.reset(rFillStyle.GetValue());
3358 }
3359 
3361 {
3362  if (*m_oFillStyle == drawing::FillStyle_GRADIENT)
3363  {
3364  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3365  "fillType", OString::number(7))); // Shade using the fillAngle
3366 
3367  const XGradient& rGradient = rFillGradient.GetGradientValue();
3368  const Color& rStartColor = rGradient.GetStartColor();
3369  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3370  "fillBackColor", OString::number(wwUtility::RGBToBGR(rStartColor))));
3371 
3372  const Color& rEndColor = rGradient.GetEndColor();
3373  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3374  "fillColor", OString::number(wwUtility::RGBToBGR(rEndColor))));
3375 
3376  switch (rGradient.GetGradientStyle())
3377  {
3378  case css::awt::GradientStyle_LINEAR:
3379  break;
3380  case css::awt::GradientStyle_AXIAL:
3381  m_aFlyProperties.push_back(
3382  std::make_pair<OString, OString>("fillFocus", OString::number(50)));
3383  break;
3384  case css::awt::GradientStyle_RADIAL:
3385  case css::awt::GradientStyle_ELLIPTICAL:
3386  case css::awt::GradientStyle_SQUARE:
3387  case css::awt::GradientStyle_RECT:
3388  default:
3389  break;
3390  }
3391  }
3392 }
3393 
3395 {
3396  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
3397  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
3398  static const sal_Char* aBorderNames[]
3401 
3402  sal_uInt16 const nDist = rBox.GetSmallestDistance();
3403 
3404  if (m_rExport.GetRTFFlySyntax())
3405  {
3406  // Borders: spacing to contents, convert from twips to EMUs.
3407  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3408  "dxTextLeft", OString::number(rBox.GetDistance(SvxBoxItemLine::LEFT) * 635)));
3409  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3410  "dyTextTop", OString::number(rBox.GetDistance(SvxBoxItemLine::TOP) * 635)));
3411  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3412  "dxTextRight", OString::number(rBox.GetDistance(SvxBoxItemLine::RIGHT) * 635)));
3413  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3414  "dyTextBottom", OString::number(rBox.GetDistance(SvxBoxItemLine::BOTTOM) * 635)));
3415 
3416  const editeng::SvxBorderLine* pLeft = rBox.GetLine(SvxBoxItemLine::LEFT);
3417  const editeng::SvxBorderLine* pRight = rBox.GetLine(SvxBoxItemLine::RIGHT);
3418  const editeng::SvxBorderLine* pTop = rBox.GetLine(SvxBoxItemLine::TOP);
3419  const editeng::SvxBorderLine* pBottom = rBox.GetLine(SvxBoxItemLine::BOTTOM);
3420  if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop
3421  && *pLeft == *pBottom)
3422  {
3423  const Color& rColor = pTop->GetColor();
3424  // We in fact need RGB to BGR, but the transformation is symmetric.
3425  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3426  "lineColor", OString::number(wwUtility::RGBToBGR(rColor))));
3427 
3428  if (pTop->GetBorderLineStyle() != SvxBorderLineStyle::NONE)
3429  {
3430  double const fConverted(editeng::ConvertBorderWidthToWord(
3431  pTop->GetBorderLineStyle(), pTop->GetWidth()));
3432  sal_Int32 nWidth = fConverted * 635; // Twips -> EMUs
3433  m_aFlyProperties.push_back(
3434  std::make_pair<OString, OString>("lineWidth", OString::number(nWidth)));
3435  }
3436  else
3437  // No border: no line.
3438  m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0"));
3439  }
3440 
3441  return;
3442  }
3443 
3444  if (rBox.GetTop() && rBox.GetBottom() && rBox.GetLeft() && rBox.GetRight()
3445  && *rBox.GetTop() == *rBox.GetBottom() && *rBox.GetTop() == *rBox.GetLeft()
3446  && *rBox.GetTop() == *rBox.GetRight() && nDist == rBox.GetDistance(SvxBoxItemLine::TOP)
3447  && nDist == rBox.GetDistance(SvxBoxItemLine::LEFT)
3448  && nDist == rBox.GetDistance(SvxBoxItemLine::BOTTOM)
3449  && nDist == rBox.GetDistance(SvxBoxItemLine::RIGHT))
3450  m_aSectionBreaks.append(
3451  OutBorderLine(m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist));
3452  else
3453  {
3454  SvxShadowLocation eShadowLocation = SvxShadowLocation::NONE;
3455  if (const SfxPoolItem* pItem = GetExport().HasItem(RES_SHADOW))
3456  eShadowLocation = static_cast<const SvxShadowItem*>(pItem)->GetLocation();
3457 
3458  const SvxBoxItemLine* pBrd = aBorders;
3459  const sal_Char** pBrdNms = aBorderNames;
3460  for (int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3461  {
3462  if (const editeng::SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3463  {
3464  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
3465  rBox.GetDistance(*pBrd), eShadowLocation));
3466  }
3467  }
3468  }
3469 
3470  if (!m_bBufferSectionBreaks)
3471  m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
3472 }
3473 
3474 void RtfAttributeOutput::FormatColumns_Impl(sal_uInt16 nCols, const SwFormatCol& rCol, bool bEven,
3475  SwTwips nPageSize)
3476 {
3477  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLS);
3478  m_rExport.OutLong(nCols);
3479 
3480  if (rCol.GetLineAdj() != COLADJ_NONE)
3481  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEBETCOL);
3482 
3483  if (bEven)
3484  {
3485  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSX);
3486  m_rExport.OutLong(rCol.GetGutterWidth(true));
3487  }
3488  else
3489  {
3490  const SwColumns& rColumns = rCol.GetColumns();
3491  for (sal_uInt16 n = 0; n < nCols;)
3492  {
3493  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLNO);
3494  m_rExport.OutLong(n + 1);
3495 
3496  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLW);
3497  m_rExport.OutLong(rCol.CalcPrtColWidth(n, nPageSize));
3498 
3499  if (++n != nCols)
3500  {
3501  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSR);
3502  m_rExport.OutLong(rColumns[n - 1].GetRight() + rColumns[n].GetLeft());
3503  }
3504  }
3505  }
3506 }
3507 
3509 {
3510  if (rItem.GetValue())
3511  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
3512 }
3513 
3515 {
3516  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3517 }
3518 
3520 {
3521  if (!rNumbering.IsCount())
3522  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
3523 }
3524 
3526 {
3527  if (!m_rExport.m_bOutPageDescs)
3528  {
3529  SvxFrameDirection nDir = rDirection.GetValue();
3530  if (nDir == SvxFrameDirection::Environment)
3531  nDir = GetExport().GetDefaultFrameDirection();
3532 
3533  if (nDir == SvxFrameDirection::Horizontal_RL_TB)
3534  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
3535  else
3536  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
3537  }
3538 }
3539 
3541 {
3542  const std::map<OUString, css::uno::Any>& rMap = rItem.GetGrabBag();
3543  for (const auto& rValue : rMap)
3544  {
3545  if (rValue.first == "ParaTopMarginBeforeAutoSpacing")
3546  {
3547  m_bParaBeforeAutoSpacing = true;
3548  rValue.second >>= m_nParaBeforeSpacing;
3549  m_nParaBeforeSpacing = convertMm100ToTwip(m_nParaBeforeSpacing);
3550  }
3551  else if (rValue.first == "ParaBottomMarginAfterAutoSpacing")
3552  {
3553  m_bParaAfterAutoSpacing = true;
3554  rValue.second >>= m_nParaAfterSpacing;
3555  m_nParaAfterSpacing = convertMm100ToTwip(m_nParaAfterSpacing);
3556  }
3557  }
3558 }
3559 
3561 
3563 
3565 {
3566  OUString sCmd; // for optional Parameters
3567  switch (pField->GetTyp()->Which())
3568  {
3569  //#i119803# Export user field for RTF filter
3570  case SwFieldIds::User:
3571  sCmd = pField->GetTyp()->GetName();
3572  m_rExport.OutputField(pField, ww::eNONE, sCmd);
3573  break;
3574  default:
3575  m_rExport.OutputField(pField, ww::eUNKNOWN, sCmd);
3576  break;
3577  }
3578 }
3579 
3580 void RtfAttributeOutput::RefField(const SwField& /*rField*/, const OUString& /*rRef*/)
3581 {
3582  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3583 }
3584 
3586 {
3587  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3588 }
3589 
3590 void RtfAttributeOutput::SetField(const SwField& /*rField*/, ww::eField /*eType*/,
3591  const OUString& /*rCmd*/)
3592 {
3593  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3594 }
3595 
3597 {
3598  const SwPostItField& rPField = *static_cast<const SwPostItField*>(pField);
3599 
3600  OString aName = OUStringToOString(rPField.GetName(), RTL_TEXTENCODING_UTF8);
3601  auto it = m_rOpenedAnnotationMarksIds.find(aName);
3602  if (it != m_rOpenedAnnotationMarksIds.end())
3603  {
3604  // In case this field is inside annotation marks, we want to write the
3605  // annotation itself after the annotation mark is closed, not here.
3606  m_aPostitFields[it->second] = &rPField;
3607  return;
3608  }
3609 
3610  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
3611  m_aRunText->append(OUStringToOString(rPField.GetInitials(), m_rExport.GetCurrentEncoding()));
3612  m_aRunText->append("}");
3614  m_aRunText->append(OUStringToOString(rPField.GetPar1(), m_rExport.GetCurrentEncoding()));
3615  m_aRunText->append("}");
3616  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN);
3617 
3619 
3620  if (m_nCurrentAnnotationMarkId != -1)
3621  {
3623  m_aRunText->append(m_nCurrentAnnotationMarkId);
3624  m_aRunText->append('}');
3625  }
3627  m_aRunText->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(rPField.GetDateTime())));
3628  m_aRunText->append('}');
3629  if (const OutlinerParaObject* pObject = rPField.GetTextObject())
3630  m_rExport.SdrExporter().WriteOutliner(*pObject, TXT_ATN);
3631  m_aRunText->append('}');
3632 }
3633 
3635 {
3636  // this is handled in OutputFlyFrame_Impl()
3637  return true;
3638 }
3639 
3641 {
3642  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD
3644  " MACROBUTTON None ");
3645  RunText(pField->GetPar1());
3646  m_aRunText->append("}}");
3647  return false; // do not expand
3648 }
3649 
3651  : m_rExport(rExport)
3652  , m_pPrevPageDesc(nullptr)
3653  , m_nStyleId(0)
3654  , m_nListId(0)
3655  , m_bIsRTL(false)
3656  , m_nScript(i18n::ScriptType::LATIN)
3657  , m_bControlLtrRtl(false)
3658  , m_nNextAnnotationMarkId(0)
3659  , m_nCurrentAnnotationMarkId(-1)
3660  , m_bTableCellOpen(false)
3661  , m_nTableDepth(0)
3662  , m_bTableAfterCell(false)
3663  , m_nColBreakNeeded(false)
3664  , m_bBufferSectionBreaks(false)
3665  , m_bBufferSectionHeaders(false)
3666  , m_bLastTable(true)
3667  , m_bWroteCellInfo(false)
3668  , m_bTableRowEnded(false)
3669  , m_bIsBeforeFirstParagraph(true)
3670  , m_bSingleEmptyRun(false)
3671  , m_bInRun(false)
3672  , m_pFlyFrameSize(nullptr)
3673  , m_bParaBeforeAutoSpacing(false)
3674  , m_nParaBeforeSpacing(0)
3675  , m_bParaAfterAutoSpacing(false)
3676  , m_nParaAfterSpacing(0)
3677 {
3678 }
3679 
3681 
3683 
3684 // These are used by wwFont::WriteRtf()
3685 
3687 void RtfAttributeOutput::StartFont(const OUString& rFamilyName) const
3688 {
3689  // write the font name hex-encoded, but without Unicode - Word at least
3690  // cannot read *both* Unicode and fallback as written by OutString
3692  msfilter::rtfutil::OutString(rFamilyName, m_rExport.GetCurrentEncoding(), false).getStr());
3693 }
3694 
3697 {
3698  m_rExport.Strm().WriteCharPtr(";}");
3700 }
3701 
3703 void RtfAttributeOutput::FontAlternateName(const OUString& rName) const
3704 {
3705  m_rExport.Strm()
3706  .WriteChar('{')
3709  .WriteChar(' ');
3710  // write the font name hex-encoded, but without Unicode - Word at least
3711  // cannot read *both* Unicode and fallback as written by OutString
3712  m_rExport.Strm()
3713  .WriteCharPtr(
3714  msfilter::rtfutil::OutString(rName, m_rExport.GetCurrentEncoding(), false).getStr())
3715  .WriteChar('}');
3716 }
3717 
3720 {
3722  m_rExport.OutULong(nCharSet);
3723  m_rExport.Strm().WriteChar(' ');
3724  m_rExport.SetCurrentEncoding(rtl_getTextEncodingFromWindowsCharset(nCharSet));
3725 }
3726 
3728 void RtfAttributeOutput::FontFamilyType(FontFamily eFamily, const wwFont& rFont) const
3729 {
3731 
3732  const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
3733  switch (eFamily)
3734  {
3735  case FAMILY_ROMAN:
3737  break;
3738  case FAMILY_SWISS:
3740  break;
3741  case FAMILY_MODERN:
3743  break;
3744  case FAMILY_SCRIPT:
3746  break;
3747  case FAMILY_DECORATIVE:
3749  break;
3750  default:
3751  break;
3752  }
3753  m_rExport.OutULong(m_rExport.m_aFontHelper.GetId(rFont)).WriteCharPtr(pStr);
3754 }
3755 
3758 {
3760 
3761  sal_uInt16 nVal = 0;
3762  switch (ePitch)
3763  {
3764  case PITCH_FIXED:
3765  nVal = 1;
3766  break;
3767  case PITCH_VARIABLE:
3768  nVal = 2;
3769  break;
3770  default:
3771  break;
3772  }
3773  m_rExport.OutULong(nVal);
3774 }
3775 
3776 static void lcl_AppendSP(OStringBuffer& rBuffer, const char cName[], const OUString& rValue,
3777  const RtfExport& rExport)
3778 {
3779  rBuffer.append("{" OOO_STRING_SVTOOLS_RTF_SP "{"); // "{\sp{"
3780  rBuffer.append(OOO_STRING_SVTOOLS_RTF_SN " "); //" \sn "
3781  rBuffer.append(cName); //"PropName"
3782  rBuffer.append("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
3783  // "}{ \sv "
3784  rBuffer.append(msfilter::rtfutil::OutString(rValue, rExport.GetCurrentEncoding()));
3785  rBuffer.append("}}");
3786 }
3787 
3788 static OString ExportPICT(const SwFlyFrameFormat* pFlyFrameFormat, const Size& rOrig,
3789  const Size& rRendered, const Size& rMapped, const SwCropGrf& rCr,
3790  const char* pBLIPType, const sal_uInt8* pGraphicAry, sal_uInt64 nSize,
3791  const RtfExport& rExport, SvStream* pStream = nullptr,
3792  bool bWritePicProp = true, const SwAttrSet* pAttrSet = nullptr)
3793 {
3794  OStringBuffer aRet;
3795  if (pBLIPType && nSize && pGraphicAry)
3796  {
3797  bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3798 
3799  aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
3800 
3801  if (pFlyFrameFormat && bWritePicProp)
3802  {
3803  OUString sDescription = pFlyFrameFormat->GetObjDescription();
3804  //write picture properties - wzDescription at first
3805  //looks like: "{\*\picprop{\sp{\sn PropertyName}{\sv PropertyValue}}}"
3806  aRet.append(
3808  lcl_AppendSP(aRet, "wzDescription", sDescription, rExport);
3809  OUString sName = pFlyFrameFormat->GetObjTitle();
3810  lcl_AppendSP(aRet, "wzName", sName, rExport);
3811 
3812  if (pAttrSet)
3813  {
3814  MirrorGraph eMirror = pAttrSet->Get(RES_GRFATR_MIRRORGRF).GetValue();
3815  if (eMirror == MirrorGraph::Vertical || eMirror == MirrorGraph::Both)
3816  // Mirror on the vertical axis is a horizontal flip.
3817  lcl_AppendSP(aRet, "fFlipH", "1", rExport);
3818  }
3819 
3820  aRet.append("}"); //"}"
3821  }
3822 
3823  long nXCroppedSize = rOrig.Width() - (rCr.GetLeft() + rCr.GetRight());
3824  long nYCroppedSize = rOrig.Height() - (rCr.GetTop() + rCr.GetBottom());
3825  /* Graphic with a zero height or width, typically copied from webpages, caused crashes. */
3826  if (!nXCroppedSize)
3827  nXCroppedSize = 100;
3828  if (!nYCroppedSize)
3829  nYCroppedSize = 100;
3830 
3831  //Given the original size and taking cropping into account
3832  //first, how much has the original been scaled to get the
3833  //final rendered size
3834  aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
3835  aRet.append(static_cast<sal_Int32>((100 * rRendered.Width()) / nXCroppedSize));
3836  aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
3837  aRet.append(static_cast<sal_Int32>((100 * rRendered.Height()) / nYCroppedSize));
3838 
3839  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
3840  aRet.append(rCr.GetLeft());
3841  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
3842  aRet.append(rCr.GetRight());
3843  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
3844  aRet.append(rCr.GetTop());
3845  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
3846  aRet.append(rCr.GetBottom());
3847 
3848  aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
3849  aRet.append(static_cast<sal_Int32>(rMapped.Width()));
3850  aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
3851  aRet.append(static_cast<sal_Int32>(rMapped.Height()));
3852 
3853  aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
3854  aRet.append(static_cast<sal_Int32>(rOrig.Width()));
3855  aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
3856  aRet.append(static_cast<sal_Int32>(rOrig.Height()));
3857 
3858  aRet.append(pBLIPType);
3859  if (bIsWMF)
3860  {
3861  aRet.append(sal_Int32(8));
3862  msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
3863  }
3864  aRet.append(SAL_NEWLINE_STRING);
3865  if (pStream)
3866  pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
3867  if (pStream)
3868  msfilter::rtfutil::WriteHex(pGraphicAry, nSize, pStream);
3869  else
3870  aRet.append(msfilter::rtfutil::WriteHex(pGraphicAry, nSize));
3871  aRet.append('}');
3872  if (pStream)
3873  pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
3874  }
3875  return aRet.makeStringAndClear();
3876 }
3877 
3879  SwOLENode& rOLENode, const Size& rSize)
3880 {
3882  Size aSize(rOLENode.GetTwipSize());
3883  Size aRendered(aSize);
3884  aRendered.setWidth(rSize.Width());
3885  aRendered.setHeight(rSize.Height());
3886  const Graphic* pGraphic = rOLENode.GetGraphic();
3887  Size aMapped(pGraphic->GetPrefSize());
3888  auto& rCr = static_cast<const SwCropGrf&>(rOLENode.GetAttr(RES_GRFATR_CROPGRF));
3889  const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3890  const sal_uInt8* pGraphicAry = nullptr;
3891  SvMemoryStream aStream;
3892  if (GraphicConverter::Export(aStream, *pGraphic, ConvertDataFormat::PNG) != ERRCODE_NONE)
3893  SAL_WARN("sw.rtf", "failed to export the graphic");
3894  sal_uInt32 nSize = aStream.TellEnd();
3895  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
3896  m_aRunText->append(ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType,
3897  pGraphicAry, nSize, m_rExport));
3898  m_aRunText->append("}"); // shppict
3901  SvMemoryStream aWmfStream;
3902  if (GraphicConverter::Export(aWmfStream, *pGraphic, ConvertDataFormat::WMF) != ERRCODE_NONE)
3903  SAL_WARN("sw.rtf", "failed to export the graphic");
3904  nSize = aWmfStream.TellEnd();
3905  pGraphicAry = static_cast<sal_uInt8 const*>(aWmfStream.GetData());
3906  m_aRunText->append(ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType,
3907  pGraphicAry, nSize, m_rExport));
3908  m_aRunText->append("}"); // nonshppict
3909 }
3910 
3912  SwOLENode& rOLENode, const Size& rSize)
3913 {
3914  uno::Reference<embed::XEmbeddedObject> xObj(rOLENode.GetOLEObj().GetOleRef());
3915  sal_Int64 nAspect = rOLENode.GetAspect();
3916  svt::EmbeddedObjectRef aObjRef(xObj, nAspect);
3917  SvGlobalName aObjName(aObjRef->getClassID());
3918 
3919  if (!SotExchange::IsMath(aObjName))
3920  return false;
3921 
3923  uno::Reference<util::XCloseable> xClosable = xObj->getComponent();
3924  if (!xClosable.is())
3925  return false;
3926  // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3927  // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3928  // to RTLD_GLOBAL, so most probably a gcc bug.
3929  auto pBase
3930  = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xClosable.get()));
3931  assert(pBase != nullptr);
3932  OStringBuffer aBuf;
3933  if (pBase)
3934  pBase->writeFormulaRtf(aBuf, m_rExport.GetCurrentEncoding());
3935  m_aRunText->append(aBuf.makeStringAndClear());
3936  // Replacement graphic.
3938  FlyFrameOLEReplacement(pFlyFrameFormat, rOLENode, rSize);
3939  m_aRunText->append("}"); // mmathPict
3940  m_aRunText->append("}"); // mmath
3941 
3942  return true;
3943 }
3944 
3945 void RtfAttributeOutput::FlyFrameOLE(const SwFlyFrameFormat* pFlyFrameFormat, SwOLENode& rOLENode,
3946  const Size& rSize)
3947 {
3948  if (FlyFrameOLEMath(pFlyFrameFormat, rOLENode, rSize))
3949  return;
3950 
3951  FlyFrameOLEReplacement(pFlyFrameFormat, rOLENode, rSize);
3952 }
3953 
3955  const SwGrfNode* pGrfNode)
3956 {
3957  SvMemoryStream aStream;
3958  const sal_uInt8* pGraphicAry = nullptr;
3959  sal_uInt32 nSize = 0;
3960 
3961  const Graphic& rGraphic(pGrfNode->GetGrf());
3962 
3963  // If there is no graphic there is not much point in parsing it
3964  if (rGraphic.GetType() == GraphicType::NONE)
3965  return;
3966 
3967  ConvertDataFormat aConvertDestinationFormat = ConvertDataFormat::WMF;
3968  const sal_Char* pConvertDestinationBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3969 
3970  GfxLink aGraphicLink;
3971  const sal_Char* pBLIPType = nullptr;
3972  if (rGraphic.IsGfxLink())
3973  {
3974  aGraphicLink = rGraphic.GetGfxLink();
3975  nSize = aGraphicLink.GetDataSize();
3976  pGraphicAry = aGraphicLink.GetData();
3977  switch (aGraphicLink.GetType())
3978  {
3979  // #i15508# trying to add BMP type for better exports, need to check if this works
3980  // checked, does not work. Also need to reset pGraphicAry to NULL to force conversion
3981  // to PNG, else the BMP array will be used.
3982  // It may work using direct DIB data, but that needs to be checked eventually
3983  //
3984  // #i15508# before GfxLinkType::NativeBmp was added the graphic data
3985  // (to be hold in pGraphicAry) was not available; thus for now to stay
3986  // compatible, keep it that way by assigning NULL value to pGraphicAry
3987  case GfxLinkType::NativeBmp:
3988  // pBLIPType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
3989  pGraphicAry = nullptr;
3990  break;
3991 
3992  case GfxLinkType::NativeJpg:
3993  pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
3994  break;
3995  case GfxLinkType::NativePng:
3996  pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3997  break;
3998  case GfxLinkType::NativeWmf:
3999  pBLIPType = aGraphicLink.IsEMF() ? OOO_STRING_SVTOOLS_RTF_EMFBLIP
4001  break;
4002  case GfxLinkType::NativeGif:
4003  // GIF is not supported by RTF, but we override default conversion to WMF, PNG seems fits better here.
4004  aConvertDestinationFormat = ConvertDataFormat::PNG;
4005  pConvertDestinationBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
4006  break;
4007  default:
4008  break;
4009  }
4010  }
4011 
4012  GraphicType eGraphicType = rGraphic.GetType();
4013  if (!pGraphicAry)
4014  {
4015  if (ERRCODE_NONE
4016  == GraphicConverter::Export(aStream, rGraphic,
4017  (eGraphicType == GraphicType::Bitmap)
4018  ? ConvertDataFormat::PNG
4019  : ConvertDataFormat::WMF))
4020  {
4021  pBLIPType = (eGraphicType == GraphicType::Bitmap) ? OOO_STRING_SVTOOLS_RTF_PNGBLIP
4023  nSize = aStream.TellEnd();
4024  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4025  }
4026  }
4027 
4028  Size aMapped(eGraphicType == GraphicType::Bitmap ? rGraphic.GetSizePixel()
4029  : rGraphic.GetPrefSize());
4030 
4031  auto& rCr = static_cast<const SwCropGrf&>(pGrfNode->GetAttr(RES_GRFATR_CROPGRF));
4032 
4033  //Get original size in twips
4034  Size aSize(pGrfNode->GetTwipSize());
4035  Size aRendered(aSize);
4036 
4037  const SwFormatFrameSize& rS = pFlyFrameFormat->GetFrameSize();
4038  aRendered.setWidth(rS.GetWidth());
4039  aRendered.setHeight(rS.GetHeight());
4040 
4041  ww8::Frame* pFrame = nullptr;
4042  for (auto& rFrame : m_rExport.m_aFrames)
4043  {
4044  if (pFlyFrameFormat == &rFrame.GetFrameFormat())
4045  {
4046  pFrame = &rFrame;
4047  break;
4048  }
4049  }
4050 
4051  /*
4052  If the graphic is not of type WMF then we will have to store two
4053  graphics, one in the native format wrapped in shppict, and the other in
4054  the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
4055  a wmf already then we don't need any such wrapping
4056  */
4057  bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
4058  const SwAttrSet* pAttrSet = pGrfNode->GetpSwAttrSet();
4059  if (!pFrame || pFrame->IsInline())
4060  {
4061  if (!bIsWMF)
4064  }
4065  else
4066  {
4070  m_pFlyFrameSize = &aRendered;
4071  m_rExport.m_pParentFrame = pFrame;
4073  m_rExport.SetRTFFlySyntax(true);
4074  m_rExport.OutputFormat(pFrame->GetFrameFormat(), false, false, true);
4076  m_rExport.SetRTFFlySyntax(false);
4077  m_rExport.m_pParentFrame = nullptr;
4078  m_pFlyFrameSize = nullptr;
4079 
4080  std::vector<std::pair<OString, OString>> aFlyProperties;
4081  aFlyProperties.push_back(std::make_pair<OString, OString>(
4082  "shapeType", OString::number(ESCHER_ShpInst_PictureFrame)));
4083  aFlyProperties.push_back(std::make_pair<OString, OString>(
4084  "wzDescription", msfilter::rtfutil::OutString(pFlyFrameFormat->GetObjDescription(),
4086  aFlyProperties.push_back(std::make_pair<OString, OString>(
4087  "wzName", msfilter::rtfutil::OutString(pFlyFrameFormat->GetObjTitle(),
4089 
4090  // If we have a wrap polygon, then handle that here.
4091  if (pFlyFrameFormat->GetSurround().IsContour())
4092  {
4093  if (const SwNoTextNode* pNd
4094  = sw::util::GetNoTextNodeFromSwFrameFormat(*pFlyFrameFormat))
4095  {
4096  const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
4097  if (pPolyPoly && pPolyPoly->Count())
4098  {
4099  tools::Polygon aPoly
4100  = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd);
4101  OStringBuffer aVerticies;
4102  for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
4103  aVerticies.append(";(")
4104  .append(aPoly[i].X())
4105  .append(",")
4106  .append(aPoly[i].Y())
4107  .append(")");
4108  aFlyProperties.push_back(std::make_pair<OString, OString>(
4109  "pWrapPolygonVertices",
4110  "8;" + OString::number(aPoly.GetSize()) + aVerticies.makeStringAndClear()));
4111  }
4112  }
4113  }
4114 
4115  // Below text, behind document, opaque: they all refer to the same thing.
4116  if (!pFlyFrameFormat->GetOpaque().GetValue())
4117  aFlyProperties.push_back(std::make_pair<OString, OString>("fBehindDocument", "1"));
4118 
4119  if (pAttrSet)
4120  {
4121  if (sal_Int32 nRot = pAttrSet->Get(RES_GRFATR_ROTATION).GetValue())
4122  {
4123  // See writerfilter::rtftok::RTFSdrImport::applyProperty(),
4124  // positive rotation angles are clockwise in RTF, we have them
4125  // as counter-clockwise.
4126  // Additionally, RTF type is 0..360*2^16, our is 0..360*10.
4127  nRot = nRot * -1 * RTF_MULTIPLIER / 10;
4128  aFlyProperties.emplace_back("rotation", OString::number(nRot));
4129  }
4130  }
4131 
4132  for (std::pair<OString, OString>& rPair : aFlyProperties)
4133  {
4136  m_rExport.Strm().WriteCharPtr(rPair.first.getStr());
4138  m_rExport.Strm().WriteCharPtr(rPair.second.getStr());
4139  m_rExport.Strm().WriteCharPtr("}}");
4140  }
4142  " pib"
4143  "}{" OOO_STRING_SVTOOLS_RTF_SV " ");
4144  }
4145 
4146  bool bWritePicProp = !pFrame || pFrame->IsInline();
4147  if (pBLIPType)
4148  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
4149  m_rExport, &m_rExport.Strm(), bWritePicProp, pAttrSet);
4150  else
4151  {
4152  aStream.Seek(0);
4153  if (GraphicConverter::Export(aStream, rGraphic, aConvertDestinationFormat) != ERRCODE_NONE)
4154  SAL_WARN("sw.rtf", "failed to export the graphic");
4155  pBLIPType = pConvertDestinationBLIPType;
4156  nSize = aStream.TellEnd();
4157  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4158 
4159  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
4160  m_rExport, &m_rExport.Strm(), bWritePicProp, pAttrSet);
4161  }
4162 
4163  if (!pFrame || pFrame->IsInline())
4164  {
4165  if (!bIsWMF)
4166  {
4169 
4170  aStream.Seek(0);
4171  if (GraphicConverter::Export(aStream, rGraphic, ConvertDataFormat::WMF) != ERRCODE_NONE)
4172  SAL_WARN("sw.rtf", "failed to export the graphic");
4174  nSize = aStream.TellEnd();
4175  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4176 
4177  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry,
4178  nSize, m_rExport, &m_rExport.Strm());
4179 
4180  m_rExport.Strm().WriteChar('}');
4181  }
4182  }
4183  else
4184  m_rExport.Strm().WriteCharPtr("}}}}"); // Close SV, SP, SHPINST and SHP.
4185 
4187 }
4188 
4189 void RtfAttributeOutput::BulletDefinition(int /*nId*/, const Graphic& rGraphic, Size aSize)
4190 {
4193 
4195  m_rExport.OutULong(aSize.Width());
4197  m_rExport.OutULong(aSize.Height());
4198 
4200  const sal_uInt8* pGraphicAry = nullptr;
4201  SvMemoryStream aStream;
4202  if (GraphicConverter::Export(aStream, rGraphic, ConvertDataFormat::PNG) != ERRCODE_NONE)
4203  SAL_WARN("sw.rtf", "failed to export the numbering picture bullet");
4204  sal_uInt32 nSize = aStream.TellEnd();
4205  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4206  msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &m_rExport.Strm());
4207  m_rExport.Strm().WriteCharPtr("}}"); // pict, shppict
4208 }
4209 
4210 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define OOO_STRING_SVTOOLS_RTF_SNEXT
#define OOO_STRING_SVTOOLS_RTF_ULW
sal_uInt16 Count() const
long GetLeft() const
void FormatBackground(const SvxBrushItem &rBrush) override
Sfx item RES_BACKGROUND.
void FormatTextGrid(const SwTextGridItem &rItem) override
Sfx item RES_TEXTGRID.
bool GetValue() const
long Width() const
bool IsContour() const
Definition: fmtsrnd.hxx:53
SvStream & OutULong(sal_uLong nVal)
Definition: rtfexport.cxx:1090
void CharFontCTL(const SvxFontItem &rFont) override
Sfx item RES_CHRATR_CTL_FONT.
#define OOO_STRING_SVTOOLS_RTF_QL
void StartRun(const SwRedlineData *pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun=false) override
Start of the text run.
Wrapper around OStringBuffers, so less hexdump of graphics have to be kept in memory during RTF expor...
bool EndURL(bool isAtEndOfParagraph) override
Output URL end.
void TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
#define OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE
#define OOO_STRING_SVTOOLS_RTF_LTRSECT
#define OOO_STRING_SVTOOLS_RTF_ACCCOMMA
SVX_NUM_CHARS_UPPER_LETTER_N
void CharGrabBag(const SfxGrabBagItem &rItem) override
Sfx item RES_CHRATR_GRABBAG.
void Redline(const SwRedlineData *pRedline) override
Output redlining.
SwNoTextNode * GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
Get the SwNoTextNode associated with a SwFrameFormat if here is one.
sal_Int64 GetAspect() const
Definition: ndole.hxx:132
void TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
#define OOO_STRING_SVTOOLS_RTF_WIDCTLPAR
#define OOO_STRING_SVTOOLS_RTF_SHPRIGHT
void TextINetFormat(const SwFormatINetFormat &rURL) override
Sfx item RES_TXTATR_INETFMT.
SwCharFormat * GetCharFormat()
Definition: txtatr2.cxx:113
void FormatULSpace(const SvxULSpaceItem &rULSpace) override
Sfx item RES_UL_SPACE.
void FormatColumns_Impl(sal_uInt16 nCols, const SwFormatCol &rCol, bool bEven, SwTwips nPageSize) override
Sfx item RES_COL.
#define OOO_STRING_SVTOOLS_RTF_QR
#define OOO_STRING_SVTOOLS_RTF_ANIMTEXT
#define OOO_STRING_SVTOOLS_RTF_ULTHDASHD
sal_uInt16 GetRowSpan() const
Definition: wrtswtbl.hxx:77
#define OOO_STRING_SVTOOLS_RTF_ALANG
#define OOO_STRING_SVTOOLS_RTF_BRDRINSET
#define OOO_STRING_SVTOOLS_RTF_COLNO
sal_uInt16 Count() const
sal_Int32 GetLeft() const
std::vector< SwColumn > SwColumns
Definition: fmtclds.hxx:57
void FormatKeep(const SvxFormatKeepItem &rItem) override
Sfx item RES_KEEP.
#define OOO_STRING_SVTOOLS_RTF_FSWISS
#define RES_CHRATR_CJK_LANGUAGE
Definition: hintids.hxx:92
FAMILY_SCRIPT
void EndRuby(const SwTextNode &rNode, sal_Int32 nPos) override
Output ruby end.
#define OOO_STRING_SVTOOLS_RTF_SN
void FieldVanish(const OUString &rText, ww::eField eType) override
OUString GetObjDescription() const
Definition: atrfrm.cxx:3138
void CharKerning(const SvxKerningItem &rKerning) override
Sfx item RES_CHRATR_KERNING.
#define OOO_STRING_SVTOOLS_RTF_ULHWAVE
sal_uInt16 GetLower() const
SvxAdjust GetAdjust() const
#define OOO_STRING_SVTOOLS_RTF_PNGBLIP
sal_Char GetDirective()
#define RES_CHRATR_FONTSIZE
Definition: hintids.hxx:76
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:157
void ParaSnapToGrid(const SvxParaGridItem &rItem) override
Sfx item RES_PARATR_SNAPTOGRID.
#define OOO_STRING_SVTOOLS_RTF_CLVMGF
void CharBidiRTL(const SfxPoolItem &rItem) override
Sfx item RES_CHRATR_BidiRTL.
void WriteBookmarks_Impl(std::vector< OUString > &rStarts, std::vector< OUString > &rEnds)
bool GetValue() const
#define RES_CHRATR_LANGUAGE
Definition: hintids.hxx:78
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:110
double ConvertBorderWidthToWord(SvxBorderLineStyle, double)
void EndRun(const SwTextNode *pNode, sal_Int32 nPos, bool bLastRun=false) override
End of the text run.
#define OOO_STRING_SVTOOLS_RTF_SUB
void StartTableRow(const ww8::WW8TableNodeInfoInner::Pointer_t &pTableTextNodeInfoInner)
FAMILY_MODERN
#define OOO_STRING_SVTOOLS_RTF_EXPNDTW
RtfAttributeOutput(RtfExport &rExport)
#define OOO_STRING_SVTOOLS_RTF_FTNALT
#define OOO_STRING_SVTOOLS_RTF_BRDRENGRAVE
SVX_NUM_FULL_WIDTH_ARABIC
sal_Unicode GetStartBracket() const
std::string GetValue
#define OOO_STRING_SVTOOLS_RTF_FMODERN
rtl_TextEncoding GetCurrentEncoding() const
Definition: rtfexport.hxx:176
void CharBackground(const SvxBrushItem &rBrush) override
Sfx item RES_CHRATR_BACKGROUND.
short GetTextFirstLineOfst() const
#define OOO_STRING_SVTOOLS_RTF_SBASEDON
void FormatVertOrientation(const SwFormatVertOrient &rFlyVert) override
Sfx item RES_VERT_ORIENT.
#define OOO_STRING_SVTOOLS_RTF_ULDASH
sal_uInt16 GetCountBy() const
Definition: lineinfo.hxx:75
long Height() const
#define OOO_STRING_SVTOOLS_RTF_S
void PostitField(const SwField *pField) override
#define OOO_STRING_SVTOOLS_RTF_CLBRDRR
const SwNumFormat * GetNumFormat(sal_uInt16 i) const
Definition: number.cxx:93
#define OOO_STRING_SVTOOLS_RTF_SLMULT
#define OOO_STRING_SVTOOLS_RTF_LI
#define OOO_STRING_SVTOOLS_RTF_PICCROPT
#define OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW
long GetWidth() const
std::size_t GetAuthor() const
Definition: redline.hxx:125
#define OOO_STRING_SVTOOLS_RTF_FOOTNOTE
#define OOO_STRING_SVTOOLS_RTF_FROMAN
#define RES_SHADOW
Definition: hintids.hxx:212
#define RES_CHRATR_WORDLINEMODE
Definition: hintids.hxx:84
#define OOO_STRING_SVTOOLS_RTF_FFTYPE
LINESTYLE_BOLD
#define OOO_STRING_SVTOOLS_RTF_TLUL
#define OOO_STRING_SVTOOLS_RTF_FOOTERY
SVX_NUM_NUMBER_NONE
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:66
#define OOO_STRING_SVTOOLS_RTF_FFOWNSTAT
#define OOO_STRING_SVTOOLS_RTF_TQDEC
sal_uInt8 GetTransparency() const
sal_uInt8 TransColToIco(const Color &rCol)
#define OOO_STRING_SVTOOLS_RTF_ULDASHD
static OString OutBorderLine(RtfExport const &rExport, const editeng::SvxBorderLine *pLine, const sal_Char *pStr, sal_uInt16 nDist, SvxShadowLocation eShadowLocation=SvxShadowLocation::NONE)
SwTwips GetPos() const
Definition: fmtornt.hxx:92
sal_uIntPtr sal_uLong
void CharHighlight(const SvxBrushItem &rBrush) override
Sfx item RES_CHRATR_HIGHLIGHT.
void FormatDrop(const SwTextNode &rNode, const SwFormatDrop &rSwFormatDrop, sal_uInt16 nStyle, ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner) override
#define OOO_STRING_SVTOOLS_RTF_CLPADFR
sal_uInt8 & GetProportionalHeight()
#define OOO_STRING_SVTOOLS_RTF_TRPADDB
#define OOO_STRING_SVTOOLS_RTF_ASPALPHA
#define OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS
bool FlyFrameOLEMath(const SwFlyFrameFormat *pFlyFrameFormat, SwOLENode &rOLENode, const Size &rSize)
Math export.
FontEmphasisMark
#define OOO_STRING_SVTOOLS_RTF_ULTHLDASH
#define OOO_STRING_SVTOOLS_RTF_UP
Base class of all fields.
Definition: fldbas.hxx:279
const SwPageDesc * FindPageDesc(size_t *pPgDescNdIdx=nullptr) const
Search PageDesc with which this node is formatted.
Definition: node.cxx:466
#define OOO_STRING_SVTOOLS_RTF_PICCROPL
#define OOO_STRING_SVTOOLS_RTF_RIN
void ParaHangingPunctuation(const SfxBoolItem &rItem) override
Sfx item RES_PARATR_HANGINGPUNCTUATION.
SVX_NUM_CHARS_UPPER_LETTER
#define LO_STRING_SVTOOLS_RTF_LEVELPICTURE
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:900
#define OOO_STRING_SVTOOLS_RTF_FORMFIELD
SvStream & Strm()
Definition: rtfexport.cxx:1068
static OString OutTBLBorderLine(RtfExport const &rExport, const editeng::SvxBorderLine *pLine, const sal_Char *pStr)
GraphicType
#define OOO_STRING_SVTOOLS_RTF_AF
#define OOO_STRING_SVTOOLS_RTF_FFNAME
#define OOO_STRING_SVTOOLS_RTF_LISTLEVEL
void ParaNumRule_Impl(const SwTextNode *pTextNd, sal_Int32 nLvl, sal_Int32 nNumId) override
Sfx item RES_PARATR_NUMRULE.
#define OOO_STRING_SVTOOLS_RTF_ATNREF
#define OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN
SVX_NUM_CIRCLE_NUMBER
#define OOO_STRING_SVTOOLS_RTF_SL
void ParaSplit(const SvxFormatSplitItem &rSplit) override
Sfx item RES_PARATR_SPLIT.
void StartFont(const OUString &rFamilyName) const
Start the font.
aBuf
void CharFontCJK(const SvxFontItem &rFont) override
Sfx item RES_CHRATR_CJK_FONT.
LINESTYLE_BOLDWAVE
sal_Int16 nId
sal_uInt16 GetDistance(SvxBoxItemLine nLine) const
void FlyFrameGraphic(const SwFlyFrameFormat *pFlyFrameFormat, const SwGrfNode *pGrfNode)
Output graphic fly frames.
#define OOO_STRING_SVTOOLS_RTF_PICT
void clear()
Similar to ->setLength(0), but for all buffers.
void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual OUString GetPar1() const override
Author.
Definition: docufld.cxx:1787
sal_uInt64 Seek(sal_uInt64 nPos)
void ParaWidows(const SvxWidowsItem &rWidows) override
Sfx item RES_PARATR_WIDOWS.
#define cDfltFillChar
#define OOO_STRING_SVTOOLS_RTF_FIELD
SwTableLine is one table row in the document model.
Definition: swtable.hxx:344
#define OOO_STRING_SVTOOLS_RTF_KEEPN
#define OOO_STRING_SVTOOLS_RTF_ULDB
#define OOO_STRING_SVTOOLS_RTF_SAUTOUPD
#define OOO_STRING_SVTOOLS_RTF_SHPWRK
void FormatSurround(const SwFormatSurround &rSurround) override
Sfx item RES_SURROUND.
void SetTextLeft(const long nL, const sal_uInt16 nProp=100)
SwNode & GetNode() const
Definition: ndindex.hxx:118
#define OOO_STRING_SVTOOLS_RTF_PICSCALEY
MirrorGraph
Definition: grfatr.hxx:31
long SwTwips
Definition: swtypes.hxx:49
void EndStyles(sal_uInt16 nNumberOfStyles) override
End of the styles table.
#define LO_STRING_SVTOOLS_RTF_MMATH
#define LO_STRING_SVTOOLS_RTF_MMATHPICT
void RefField(const SwField &rField, const OUString &rRef) override
#define OOO_STRING_SVTOOLS_RTF_INTBL
SvxFrameDirection
#define OOO_STRING_SVTOOLS_RTF_CLTXTBRL
#define OOO_STRING_SVTOOLS_RTF_SOUTLVL
#define OOO_STRING_SVTOOLS_RTF_BKMKEND
void CharLanguage(const SvxLanguageItem &rLanguage) override
Sfx item RES_CHRATR_LANGUAGE.
#define OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL
#define OOO_STRING_SVTOOLS_RTF_FLYANCHOR
#define OOO_STRING_SVTOOLS_RTF_FSCRIPT
void StartAbstractNumbering(sal_uInt16 nId) override
Start of the abstract numbering definition instance.
#define OOO_STRING_SVTOOLS_RTF_CLVMRG
#define OOO_STRING_SVTOOLS_RTF_RTLPAR
bool IsEndNote() const
Definition: fmtftn.hxx:73
#define DFLT_ESC_AUTO_SUB
#define OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT
#define OOO_STRING_SVTOOLS_RTF_FLDRSLT
void StartStyles() override
Start of the styles table.
void FormatFrameSize(const SwFormatFrameSize &rSize) override
Sfx item RES_FRM_SIZE.
#define RES_CHRATR_CJK_FONT
Definition: hintids.hxx:90
FAMILY_ROMAN
void SectionTitlePage() override
Has different headers/footers for the title page.
tools::Polygon CorrectWordWrapPolygonForExport(const tools::PolyPolygon &rPolyPoly, const SwNoTextNode *pNd)
Undo all scaling / move tricks of the wrap polygon done during import.
void CharPostureCTL(const SvxPostureItem &rPosture) override
Sfx item RES_CHRATR_CTL_POSTURE.
#define OOO_STRING_SVTOOLS_RTF_ACCUNDERDOT
#define RES_CHRATR_CJK_FONTSIZE
Definition: hintids.hxx:91
void FlyFrameOLE(const SwFlyFrameFormat *pFlyFrameFormat, SwOLENode &rOLENode, const Size &rSize)
#define OOO_STRING_SVTOOLS_RTF_LTRCH
const sal_uInt8 ColumnBreak
void SectionBiDi(bool bBiDi) override
Columns populated from right/numbers on the right side?
const editeng::SvxBorderLine * GetRight() const
#define OOO_STRING_SVTOOLS_RTF_SBKNONE
void CharCaseMap(const SvxCaseMapItem &rCaseMap) override
Sfx item Sfx item RES_CHRATR_CASEMAP.
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:55
#define OOO_STRING_SVTOOLS_RTF_CLVERTALB
#define OOO_STRING_SVTOOLS_RTF_PICH
Frame cannot be moved in Var-direction.
Definition: fmtfsize.hxx:38
rtl_TextEncoding GetDefaultEncoding() const
Definition: rtfexport.hxx:171
#define OOO_STRING_SVTOOLS_RTF_MARGRSXN
#define OOO_STRING_SVTOOLS_RTF_RTLROW
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2580
SvStream & WriteCharPtr(const char *pBuf)
#define OOO_STRING_SVTOOLS_RTF_HIGHLIGHT
#define OOO_STRING_SVTOOLS_RTF_SHPPICT
#define OOO_STRING_SVTOOLS_RTF_FAROMAN
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4095
SwTableFormat * GetFrameFormat()
Definition: swtable.hxx:201
void StartSection() override
Start of the section properties.
void TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
void CharWeight(const SvxWeightItem &rWeight) override
Sfx item RES_CHRATR_WEIGHT.
void TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
size_type size() const
Definition: swtable.hxx:74
FontItalic GetPosture() const
#define OOO_STRING_SVTOOLS_RTF_LINECONT
#define OOO_STRING_SVTOOLS_RTF_CLPADFB
#define OOO_STRING_SVTOOLS_RTF_CHBRDR
#define RES_GRFATR_MIRRORGRF
Definition: hintids.hxx:239
static bool isTextBox(const SwFrameFormat &rFrameFormat)
Is this a standalone TextFrame, or used as a TextBox of a shape?
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
virtual sal_uInt64 TellEnd() override
const SwTextINetFormat * GetTextINetFormat() const
Definition: fmtinfmt.hxx:70
#define OOO_STRING_SVTOOLS_RTF_FLYPAGE
LINESTYLE_DASH
void NumberingDefinition(sal_uInt16 nId, const SwNumRule &rRule) override
Definition of a numbering instance.
#define OOO_STRING_SVTOOLS_RTF_CLPADFL
WEIGHT_BOLD
#define OOO_STRING_SVTOOLS_RTF_FAHANG
const Color & GetStartColor() const
#define OOO_STRING_SVTOOLS_RTF_HICH
void TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
const SwTableBox * GetBox() const
Definition: wrtswtbl.hxx:72
void WriteExpand(const SwField *pField) override
Write the expanded field.
#define OOO_STRING_SVTOOLS_RTF_ACCDOT
virtual OUString GetPar1() const
Definition: fldbas.cxx:271
#define OOO_STRING_SVTOOLS_RTF_CLPADFT
#define OOO_STRING_SVTOOLS_RTF_DELETED
constexpr::Color COL_AUTO(0xFF, 0xFF, 0xFF, 0xFF)
void CharBorder(const ::editeng::SvxBorderLine *pAllBorder, sal_uInt16 nDist, bool bShadow) override
Sfx item RES_CHRATR_BOX.
#define OOO_STRING_SVTOOLS_RTF_SBKEVEN
bool StripMetafileHeader(const sal_uInt8 *&rpGraphicAry, sal_uInt64 &rSize)
LINESTYLE_DASHDOT
void ParaAdjust(const SvxAdjustItem &rAdjust) override
Sfx item RES_PARATR_ADJUST.
const SwTextFootnote * GetTextFootnote() const
Definition: fmtftn.hxx:85
sal_uInt16 sal_Unicode
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
bool IsRestartEachPage() const
Definition: lineinfo.hxx:90
const Color & GetColor() const
RedlineType GetType() const
Definition: redline.hxx:123
sal_Unicode GetEndBracket() const
#define OOO_STRING_SVTOOLS_RTF_PGNLCLTR
LINESTYLE_BOLDDASHDOTDOT
FieldFlags
Definition: wrtww8.hxx:146
#define OOO_STRING_SVTOOLS_RTF_BRDRTH
Value in Var-direction gives minimum (can be exceeded but not be less).
Definition: fmtfsize.hxx:39
#define OOO_STRING_SVTOOLS_RTF_BRDRCF
#define OOO_STRING_SVTOOLS_RTF_ACCCIRCLE
SvxShadowLocation GetLocation() const
#define OOO_STRING_SVTOOLS_RTF_ATNAUTHOR
#define OOO_STRING_SVTOOLS_RTF_BRDRDASHDD
void FontCharset(sal_uInt8 nCharSet) const
Font charset.
#define OOO_STRING_SVTOOLS_RTF_MARGBSXN
void FontPitchType(FontPitch ePitch) const
Font pitch.
FUNC_TYPE const nType
void CharScaleWidth(const SvxCharScaleWidthItem &rScaleWidth) override
Sfx item RES_CHRATR_SCALEW.
The class that does all the actual RTF export-related work.
Definition: rtfexport.hxx:36
#define OOO_STRING_SVTOOLS_RTF_ULTH
#define OOO_STRING_SVTOOLS_RTF_TRPADDFL
LINESTYLE_NONE
#define RES_CHRATR_CTL_FONTSIZE
Definition: hintids.hxx:96
#define OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID
void ParaForbiddenRules(const SfxBoolItem &rItem) override
Sfx item RES_PARATR_FORBIDDEN_RULES.
#define OOO_STRING_SVTOOLS_RTF_TITLEPG
void EndParagraphProperties(const SfxItemSet &rParagraphMarkerProperties, const SwRedlineData *pRedlineData, const SwRedlineData *pRedlineParagraphMarkerDeleted, const SwRedlineData *pRedlineParagraphMarkerInserted) override
Called after we end outputting the attributes.
#define OOO_STRING_SVTOOLS_RTF_I
#define OOO_STRING_SVTOOLS_RTF_SHPZ
#define OOO_STRING_SVTOOLS_RTF_NESTROW
void ParaScriptSpace(const SfxBoolItem &rScriptSpace) override
Sfx item RES_PARATR_SCRIPTSPACE.
#define X
void OutputFormat(const SwFormat &rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat=false)
Output attributes.
Definition: ww8atr.cxx:754
rtl_TextEncoding GetCharSet() const
#define OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG
void PageBreakBefore(bool bBreak) override
Page break As a paragraph property - the paragraph should be on the next page.
#define OOO_STRING_SVTOOLS_RTF_SBKODD
char sal_Char
StyleType
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
sal_Int32 & GetTabPos()
const Size & GetLayoutSize() const
The layout size of the contained element.
void TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
SVX_NUM_ARABIC
#define OOO_STRING_SVTOOLS_RTF_QJ
eField
Definition: fields.hxx:26
const sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:95
#define OOO_STRING_SVTOOLS_RTF_LANG
#define OOO_STRING_SVTOOLS_RTF_MARGLSXN
const SwWriteTableCells & GetCells() const
Definition: wrtswtbl.hxx:134
void FormatFillGradient(const XFillGradientItem &rFillGradient) override
Sfx item RES_FILL_GRADIENT.
SVX_NUM_ROMAN_UPPER
sal_uInt32 RGBToBGR(::Color nColour)
Definition: ww8struc.hxx:1084
#define DFLT_ESC_AUTO_SUPER
FontEmphasisMark GetEmphasisMark() const
#define OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT
const SwTable & GetTable() const
Definition: node.hxx:497
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66