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().WriteOString(m_aSectionBreaks.makeStringAndClear());
329  m_bBufferSectionBreaks = true;
330 
331  // output section headers / footers
332  if (!m_bBufferSectionHeaders)
333  m_rExport.Strm().WriteOString(m_aSectionHeaders.makeStringAndClear());
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().WriteOString(aPar.makeStringAndClear());
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().WriteOString(aProperties);
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) + "\\* jc");
510  aStr += OUString::number(aWW8Ruby.GetJC()) + " \\* \"Font:";
511  aStr += aWW8Ruby.GetFontFamily() + "\" \\* hps";
512  aStr += OUString::number((aWW8Ruby.GetRubyHeight() + 5) / 10) + " \\o";
513  if (aWW8Ruby.GetDirective())
514  {
515  aStr += "\\a" + OUStringChar(aWW8Ruby.GetDirective());
516  }
517  aStr += "(\\s\\up " + OUString::number((aWW8Ruby.GetBaseHeight() + 10) / 20 - 1) + "(";
518  EndRun(&rNode, nPos);
519  m_rExport.OutputField(nullptr, ww::eEQ, aStr, FieldFlags::Start | FieldFlags::CmdStart);
520  aStr = rRuby.GetText() + "),";
521  m_rExport.OutputField(nullptr, ww::eEQ, aStr, FieldFlags::NONE);
522 }
523 
524 void RtfAttributeOutput::EndRuby(const SwTextNode& rNode, sal_Int32 nPos)
525 {
526  m_rExport.OutputField(nullptr, ww::eEQ, ")",
528  EndRun(&rNode, nPos);
529 }
530 
531 bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& rTarget)
532 {
533  m_sURL = rUrl;
534  // Ignore hyperlink without a URL.
535  if (!rUrl.isEmpty())
536  {
537  m_aRun->append('{');
538  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FIELD);
539  m_aRun->append('{');
540  m_aRun->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
541  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
542  m_aRun->append(" HYPERLINK ");
543 
544  m_aRun->append("\"");
545  m_aRun->append(msfilter::rtfutil::OutString(rUrl, m_rExport.GetCurrentEncoding()));
546  m_aRun->append("\" ");
547 
548  if (!rTarget.isEmpty())
549  {
550  m_aRun->append("\\\\t \"");
551  m_aRun->append(msfilter::rtfutil::OutString(rTarget, m_rExport.GetCurrentEncoding()));
552  m_aRun->append("\" ");
553  }
554 
555  m_aRun->append("}");
556  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
557  }
558  return true;
559 }
560 
561 bool RtfAttributeOutput::EndURL(bool const isAtEndOfParagraph)
562 {
563  if (!m_sURL.isEmpty())
564  {
565  // UGLY: usually EndRun is called earlier, but there is an extra
566  // call to OutAttrWithRange() when at the end of the paragraph,
567  // so in that special case the output needs to be appended to the
568  // new run's text instead of the previous run
569  if (isAtEndOfParagraph)
570  {
571  // close the fldrslt group
572  m_aRunText->append("}}");
573  // close the field group
574  m_aRunText->append('}');
575  }
576  else
577  {
578  // close the fldrslt group
579  m_aRun->append("}}");
580  // close the field group
581  m_aRun->append('}');
582  }
583  m_sURL.clear();
584  }
585  return true;
586 }
587 
588 void RtfAttributeOutput::FieldVanish(const OUString& /*rText*/, ww::eField /*eType*/)
589 {
590  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
591 }
592 
594 {
595  if (!pRedline)
596  return;
597 
598  if (pRedline->GetType() == RedlineType::Insert)
599  {
600  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED);
601  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
602  m_aRun->append(static_cast<sal_Int32>(
603  m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor()))));
604  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
605  }
606  else if (pRedline->GetType() == RedlineType::Delete)
607  {
608  m_aRun->append(OOO_STRING_SVTOOLS_RTF_DELETED);
609  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
610  m_aRun->append(static_cast<sal_Int32>(
611  m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor()))));
612  m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
613  }
614  m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp())));
615  m_aRun->append(' ');
616 }
617 
619  const SwFormatDrop& /*rSwFormatDrop*/, sal_uInt16 /*nStyle*/,
620  ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/,
621  ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/)
622 {
623  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
624 }
625 
626 void RtfAttributeOutput::ParagraphStyle(sal_uInt16 nStyle)
627 {
628  OString* pStyle = m_rExport.GetStyle(nStyle);
629  OStringBuffer aStyle;
630  aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
631  aStyle.append(static_cast<sal_Int32>(nStyle));
632  if (pStyle)
633  aStyle.append(pStyle->getStr());
634  if (!m_bBufferSectionHeaders)
635  m_rExport.Strm().WriteOString(aStyle.makeStringAndClear());
636  else
637  m_aSectionHeaders.append(aStyle.makeStringAndClear());
638 }
639 
641  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
642 {
643  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
644  if (m_nTableDepth > 1)
645  {
646  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
647  m_aStyles.append(static_cast<sal_Int32>(m_nTableDepth));
648  }
649  m_bWroteCellInfo = true;
650 }
651 
653 {
654  /* noop */
655 }
656 
658  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
659 {
660  InitTableHelper(pTableTextNodeInfoInner);
661 
662  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
663  SwFrameFormat* pFormat = pTable->GetFrameFormat();
664 
665  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
666  TableOrientation(pTableTextNodeInfoInner);
667  TableBidi(pTableTextNodeInfoInner);
668  TableHeight(pTableTextNodeInfoInner);
669  TableCanSplit(pTableTextNodeInfoInner);
670 
671  // Cell margins
672  const SvxBoxItem& rBox = pFormat->GetBox();
673  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
674  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
675 
676  static const char* aRowPadNames[]
679 
680  static const char* aRowPadUnits[]
683 
684  for (int i = 0; i < 4; ++i)
685  {
686  m_aRowDefs.append(aRowPadUnits[i]);
687  m_aRowDefs.append(sal_Int32(3));
688  m_aRowDefs.append(aRowPadNames[i]);
689  m_aRowDefs.append(static_cast<sal_Int32>(rBox.GetDistance(aBorders[i])));
690  }
691 
692  // The cell-dependent properties
693  const double fWidthRatio = m_pTableWrt->GetAbsWidthRatio();
694  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
695  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
696  SwTwips nSz = 0;
697 
698  // Not using m_nTableDepth, which is not yet incremented here.
699  sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
700  m_aCells[nCurrentDepth] = pRow->GetCells().size();
701  for (sal_uInt32 i = 0; i < m_aCells[nCurrentDepth]; i++)
702  {
703  const SwWriteTableCell* const pCell = pRow->GetCells()[i].get();
704  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
705 
706  pTableTextNodeInfoInner->setCell(i);
707  TableCellProperties(pTableTextNodeInfoInner);
708 
709  // Right boundary: this can't be in TableCellProperties as the old
710  // value of nSz is needed.
711  nSz += pCellFormat->GetFrameSize().GetWidth();
712  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
713  m_aRowDefs.append(static_cast<sal_Int32>(pFormat->GetLRSpace().GetLeft()
714  + rtl::math::round(nSz * fWidthRatio)));
715  }
716 }
717 
719  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
720 {
721  /*
722  * The function name is a bit misleading: given that we write borders
723  * before each row, we just have borders, not default ones. Additionally,
724  * this function actually writes borders for a specific cell only and is
725  * called for each cell.
726  */
727 
728  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
729  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
730  const SwWriteTableCell* const pCell
731  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
732  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
733  const SfxPoolItem* pItem;
734  if (pCellFormat->GetAttrSet().HasItem(RES_BOX, &pItem))
735  {
736  auto& rBox = static_cast<const SvxBoxItem&>(*pItem);
737  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
738  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
739  static const char* aBorderNames[]
742  //Yes left and top are swapped with each other for cell padding! Because
743  //that's what the thundering annoying rtf export/import word xp does.
744  static const char* aCellPadNames[]
747  static const char* aCellPadUnits[]
750  for (int i = 0; i < 4; ++i)
751  {
752  if (const editeng::SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
753  m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
754  if (rBox.GetDistance(aBorders[i]))
755  {
756  m_aRowDefs.append(aCellPadUnits[i]);
757  m_aRowDefs.append(sal_Int32(3));
758  m_aRowDefs.append(aCellPadNames[i]);
759  m_aRowDefs.append(static_cast<sal_Int32>(rBox.GetDistance(aBorders[i])));
760  }
761  }
762  }
763 }
764 
766  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
767 {
768  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
769  const SwTableBox* pTableBox = pTableTextNodeInfoInner->getTableBox();
770  const SwTableLine* pTableLine = pTableBox->GetUpper();
771 
772  Color aColor = COL_AUTO;
773  auto pTableColorProp
775  if (pTableColorProp)
776  aColor = pTableColorProp->GetColor();
777 
778  auto pRowColorProp
780  if (pRowColorProp && pRowColorProp->GetColor() != COL_AUTO)
781  aColor = pRowColorProp->GetColor();
782 
783  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
784  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
785  const SwWriteTableCell* const pCell
786  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
787  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
788  const SfxPoolItem* pItem;
789  if (pCellFormat->GetAttrSet().HasItem(RES_BACKGROUND, &pItem))
790  {
791  auto& rBack = static_cast<const SvxBrushItem&>(*pItem);
792  if (rBack.GetColor() != COL_AUTO)
793  aColor = rBack.GetColor();
794  }
795 
796  if (!aColor.GetTransparency())
797  {
798  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
799  m_aRowDefs.append(static_cast<sal_Int32>(m_rExport.GetColor(aColor)));
800  }
801 }
802 
804  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
805 {
806 }
807 
809  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
810 {
811 }
812 
814 {
815  const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
816  const SwTableLine* pTabLine = pTabBox->GetUpper();
817  const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
818  const SwFormatFrameSize& rLSz = pLineFormat->GetFrameSize();
819 
820  if (ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight())
821  {
822  sal_Int32 nHeight = 0;
823 
824  switch (rLSz.GetHeightSizeType())
825  {
826  case ATT_FIX_SIZE:
827  nHeight = -rLSz.GetHeight();
828  break;
829  case ATT_MIN_SIZE:
830  nHeight = rLSz.GetHeight();
831  break;
832  default:
833  break;
834  }
835 
836  if (nHeight)
837  {
838  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
839  m_aRowDefs.append(nHeight);
840  }
841  }
842 }
843 
845  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
846 {
847  const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
848  const SwTableLine* pTabLine = pTabBox->GetUpper();
849  const SwFrameFormat* pLineFormat = pTabLine->GetFrameFormat();
850  const SwFormatRowSplit& rSplittable = pLineFormat->GetRowSplit();
851 
852  // The rtf default is to allow a row to break
853  if (!rSplittable.GetValue())
854  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
855 }
856 
858 {
859  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
860  const SwFrameFormat* pFrameFormat = pTable->GetFrameFormat();
861 
862  if (m_rExport.TrueFrameDirection(*pFrameFormat) != SvxFrameDirection::Horizontal_RL_TB)
863  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
864  else
865  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
866 }
867 
869  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
870 {
871  const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
872  SwWriteTableRow* pRow = aRows[pTableTextNodeInfoInner->getRow()].get();
873  const SwWriteTableCell* const pCell
874  = pRow->GetCells()[pTableTextNodeInfoInner->getCell()].get();
875  const SwFrameFormat* pCellFormat = pCell->GetBox()->GetFrameFormat();
876 
877  // Text direction.
878  if (SvxFrameDirection::Vertical_RL_TB == m_rExport.TrueFrameDirection(*pCellFormat))
879  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLTXTBRL);
880  else if (SvxFrameDirection::Vertical_LR_BT == m_rExport.TrueFrameDirection(*pCellFormat))
881  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLTXBTLR);
882 
883  const SfxPoolItem* pItem;
884 
885  // vertical merges
886  if (pCell->GetRowSpan() > 1)
887  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
888  else if (pCell->GetRowSpan() == 0)
889  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
890 
891  // vertical alignment
892  if (pCellFormat->GetAttrSet().HasItem(RES_VERT_ORIENT, &pItem))
893  switch (static_cast<const SwFormatVertOrient*>(pItem)->GetVertOrient())
894  {
895  case text::VertOrientation::CENTER:
896  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC);
897  break;
898  case text::VertOrientation::BOTTOM:
899  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB);
900  break;
901  default:
902  m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT);
903  break;
904  }
905 }
906 
908 {
909  // This is called when the nested table ends in a cell, and there's no
910  // paragraph behind that; so we must check for the ends of cell, rows,
911  // and tables
912  FinishTableRowCell(pNodeInfoInner);
913 }
914 
916  ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
917 {
918  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
919  SwFrameFormat* pFormat = pTable->GetFrameFormat();
920 
921  OStringBuffer aTableAdjust(OOO_STRING_SVTOOLS_RTF_TRQL);
922  switch (pFormat->GetHoriOrient().GetHoriOrient())
923  {
924  case text::HoriOrientation::CENTER:
925  aTableAdjust.setLength(0);
926  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
927  break;
928  case text::HoriOrientation::RIGHT:
929  aTableAdjust.setLength(0);
930  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
931  break;
933  case text::HoriOrientation::LEFT_AND_WIDTH:
934  aTableAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
935  aTableAdjust.append(static_cast<sal_Int32>(pFormat->GetLRSpace().GetLeft()));
936  break;
937  default:
938  break;
939  }
940 
941  m_aRowDefs.append(aTableAdjust.makeStringAndClear());
942 }
943 
945  ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
946 {
947  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
948 }
949 
950 void RtfAttributeOutput::TableRowEnd(sal_uInt32 /*nDepth*/) { /* noop, see EndTableRow() */}
951 
952 /*
953  * Our private table methods.
954  */
955 
957  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
958 {
959  const SwTable* pTable = pTableTextNodeInfoInner->getTable();
960  if (m_pTableWrt && pTable == m_pTableWrt->GetTable())
961  return;
962 
963  long nPageSize = 0;
964  bool bRelBoxSize = false;
965 
966  // Create the SwWriteTable instance to use col spans
967  GetTablePageSize(pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize);
968 
969  const SwFrameFormat* pFormat = pTable->GetFrameFormat();
970  const sal_uInt32 nTableSz = pFormat->GetFrameSize().GetWidth();
971 
972  const SwHTMLTableLayout* pLayout = pTable->GetHTMLTableLayout();
973  if (pLayout && pLayout->IsExportable())
974  m_pTableWrt = std::make_unique<SwWriteTable>(pTable, pLayout);
975  else
976  m_pTableWrt = std::make_unique<SwWriteTable>(pTable, pTable->GetTabLines(), nPageSize,
977  nTableSz, false);
978 }
979 
981 {
982  // To trigger calling InitTableHelper()
983  m_pTableWrt.reset();
984 }
985 
987  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
988 {
989  sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
990  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << nCurrentDepth << ")");
991  m_bTableRowEnded = false;
992 
993  TableDefinition(pTableTextNodeInfoInner);
994 
995  if (!m_bLastTable)
996  m_aTables.push_back(m_aRowDefs.makeStringAndClear());
997 
998  // We'll write the table definition for nested tables later
999  if (nCurrentDepth > 1)
1000  return;
1001  // Empty the previous row closing buffer before starting the new one,
1002  // necessary for subtables.
1003  m_rExport.Strm().WriteOString(m_aAfterRuns.makeStringAndClear());
1004  m_rExport.Strm().WriteOString(m_aRowDefs.makeStringAndClear());
1005 }
1006 
1007 void RtfAttributeOutput::StartTableCell() { m_bTableCellOpen = true; }
1008 
1010  const ww8::WW8TableNodeInfoInner::Pointer_t& pTableTextNodeInfoInner)
1011 {
1012  TableDefaultBorders(pTableTextNodeInfoInner);
1013  TableBackgrounds(pTableTextNodeInfoInner);
1014  TableVerticalCell(pTableTextNodeInfoInner);
1015 }
1016 
1018 {
1019  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
1020 
1021  if (!m_bWroteCellInfo)
1022  {
1023  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_INTBL);
1024  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ITAP);
1025  m_aAfterRuns.append(static_cast<sal_Int32>(m_nTableDepth));
1026  }
1027  if (m_nTableDepth > 1)
1028  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
1029  else
1030  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
1031 
1032  m_bTableCellOpen = false;
1033  m_bTableAfterCell = true;
1034  m_bWroteCellInfo = false;
1035  if (m_aCells[m_nTableDepth] > 0)
1036  m_aCells[m_nTableDepth]--;
1037 }
1038 
1040 {
1041  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
1042 
1043  // Trying to end the row without writing the required number of cells? Fill with empty ones.
1044  for (sal_uInt32 i = 0; i < m_aCells[m_nTableDepth]; i++)
1045  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
1046 
1047  if (m_nTableDepth > 1)
1048  {
1049  m_aAfterRuns.append(
1051  if (!m_aRowDefs.isEmpty())
1052  m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
1053  else if (!m_aTables.empty())
1054  {
1055  m_aAfterRuns.append(m_aTables.back());
1056  m_aTables.pop_back();
1057  }
1058  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW
1059  "}"
1061  }
1062  else
1063  {
1064  if (!m_aTables.empty())
1065  {
1066  m_aAfterRuns.append(m_aTables.back());
1067  m_aTables.pop_back();
1068  }
1069  m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
1070  }
1071  m_bTableRowEnded = true;
1072 }
1073 
1075 {
1076  if (m_nTableDepth > 0)
1077  {
1078  m_nTableDepth--;
1079  m_pTableWrt.reset();
1080  }
1081 
1082  // We closed the table; if it is a nested table, the cell that contains it
1083  // still continues
1084  m_bTableCellOpen = true;
1085 
1086  // Cleans the table helper
1087  m_pTableWrt.reset();
1088 }
1089 
1091 {
1092  if (pInner)
1093  {
1094  // Where are we in the table
1095  sal_uInt32 nRow = pInner->getRow();
1096 
1097  const SwTable* pTable = pInner->getTable();
1098  const SwTableLines& rLines = pTable->GetTabLines();
1099  sal_uInt16 nLinesCount = rLines.size();
1100 
1101  if (pInner->isEndOfCell())
1102  EndTableCell();
1103 
1104  // This is a line end
1105  if (pInner->isEndOfLine())
1106  EndTableRow();
1107 
1108  // This is the end of the table
1109  if (pInner->isEndOfLine() && (nRow + 1) == nLinesCount)
1110  EndTable();
1111  }
1112 }
1113 
1115 {
1116  m_rExport.Strm()
1117  .WriteCharPtr(SAL_NEWLINE_STRING)
1118  .WriteChar('{')
1119  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLORTBL);
1120  m_rExport.OutColorTable();
1121  OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
1122  m_aStylesheet.append(SAL_NEWLINE_STRING);
1123  m_aStylesheet.append('{');
1124  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
1125 }
1126 
1127 void RtfAttributeOutput::EndStyles(sal_uInt16 /*nNumberOfStyles*/)
1128 {
1129  m_rExport.Strm().WriteChar('}');
1130  m_rExport.Strm().WriteOString(m_aStylesheet.makeStringAndClear());
1131  m_rExport.Strm().WriteChar('}');
1132 }
1133 
1134 void RtfAttributeOutput::DefaultStyle() { /* noop, the default style is always 0 in RTF */}
1135 
1136 void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType, sal_uInt16 nBase,
1137  sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
1138  bool bAutoUpdate)
1139 {
1140  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rName = '" << rName << "'");
1141 
1142  m_aStylesheet.append('{');
1143  if (eType == STYLE_TYPE_PARA)
1144  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
1145  else
1147  m_aStylesheet.append(static_cast<sal_Int32>(nId));
1148 
1149  if (nBase != 0x0FFF)
1150  {
1151  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
1152  m_aStylesheet.append(static_cast<sal_Int32>(nBase));
1153  }
1154 
1155  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
1156  m_aStylesheet.append(static_cast<sal_Int32>(nNext));
1157 
1158  if (bAutoUpdate)
1159  m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SAUTOUPD);
1160 
1161  m_rStyleName = rName;
1162  m_nStyleId = nId;
1163 }
1164 
1166 {
1167  OString aStyles = MoveCharacterProperties();
1168  m_rExport.InsStyle(m_nStyleId, aStyles);
1169  m_aStylesheet.append(aStyles);
1170  m_aStylesheet.append(' ');
1171  m_aStylesheet.append(
1172  msfilter::rtfutil::OutString(m_rStyleName, m_rExport.GetCurrentEncoding()));
1173  m_aStylesheet.append(";}");
1174  m_aStylesheet.append(SAL_NEWLINE_STRING);
1175 }
1176 
1177 void RtfAttributeOutput::StartStyleProperties(bool /*bParProp*/, sal_uInt16 /*nStyle*/)
1178 {
1179  /* noop */
1180 }
1181 
1182 void RtfAttributeOutput::EndStyleProperties(bool /*bParProp*/) { /* noop */}
1183 
1185 {
1186  if (nLvl >= WW8ListManager::nMaxLevel)
1187  nLvl = WW8ListManager::nMaxLevel - 1;
1188 
1189  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
1190  m_aStyles.append(static_cast<sal_Int32>(nLvl));
1191  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
1192  m_aStyles.append(static_cast<sal_Int32>(nLvl));
1193 }
1194 
1196 {
1197  if (bBreak)
1198  {
1199  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAGEBB);
1200  }
1201 }
1202 
1204 {
1205  switch (nC)
1206  {
1207  case msword::ColumnBreak:
1208  m_nColBreakNeeded = true;
1209  break;
1210  case msword::PageBreak:
1211  if (pSectionInfo)
1212  m_rExport.SectionProperties(*pSectionInfo);
1213  break;
1214  }
1215 }
1216 
1218 {
1219  if (m_bIsBeforeFirstParagraph)
1220  return;
1221 
1223  if (!m_bBufferSectionBreaks)
1224  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
1225 }
1226 
1228 {
1229  /*
1230  * noop, \sect must go to StartSection or Word won't notice multiple
1231  * columns...
1232  */
1233 }
1234 
1236 {
1237  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
1238  m_aSectionBreaks.append(static_cast<sal_Int32>(!bProtected));
1239 }
1240 
1242  const SwLineNumberInfo& rLnNumInfo)
1243 {
1244  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEMOD);
1245  m_rExport.OutLong(rLnNumInfo.GetCountBy());
1246  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEX);
1247  m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
1248  if (!rLnNumInfo.IsRestartEachPage())
1249  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINECONT);
1250 
1251  if (nRestartNo > 0)
1252  {
1253  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINESTARTS);
1254  m_rExport.OutLong(nRestartNo);
1255  }
1256 }
1257 
1259 {
1260  /*
1261  * noop, handled in RtfExport::WriteHeaderFooter()
1262  */
1263 }
1264 
1266  const SwFrameFormat* /*pFirstPageFormat*/)
1267 {
1268  const SvxBoxItem& rBox = pFormat->GetBox();
1269  const editeng::SvxBorderLine* pLine = rBox.GetTop();
1270  if (pLine)
1271  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRT,
1272  rBox.GetDistance(SvxBoxItemLine::TOP)));
1273  pLine = rBox.GetBottom();
1274  if (pLine)
1275  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRB,
1276  rBox.GetDistance(SvxBoxItemLine::BOTTOM)));
1277  pLine = rBox.GetLeft();
1278  if (pLine)
1279  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRL,
1280  rBox.GetDistance(SvxBoxItemLine::LEFT)));
1281  pLine = rBox.GetRight();
1282  if (pLine)
1283  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine, OOO_STRING_SVTOOLS_RTF_PGBRDRR,
1284  rBox.GetDistance(SvxBoxItemLine::RIGHT)));
1285 }
1286 
1288 {
1289  m_rExport.Strm().WriteCharPtr(bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT
1291 }
1292 
1294  sal_uInt16 nNumType, const ::boost::optional<sal_uInt16>& oPageRestartNumber)
1295 {
1296  if (oPageRestartNumber)
1297  {
1298  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
1299  m_aSectionBreaks.append(static_cast<sal_Int32>(oPageRestartNumber.get()));
1300  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
1301  }
1302 
1303  const char* pStr = nullptr;
1304  switch (nNumType)
1305  {
1309  break;
1313  break;
1314  case SVX_NUM_ROMAN_UPPER:
1316  break;
1317  case SVX_NUM_ROMAN_LOWER:
1319  break;
1320 
1321  case SVX_NUM_ARABIC:
1323  break;
1324  }
1325  if (pStr)
1326  m_aSectionBreaks.append(pStr);
1327 }
1328 
1330 {
1331  SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", nBreakCode = " << int(nBreakCode));
1332 
1333  /*
1334  * break code: 0 No break, 1 New column
1335  * 2 New page, 3 Even page, 4 Odd page
1336  */
1337  const char* sType = nullptr;
1338  switch (nBreakCode)
1339  {
1340  case 1:
1342  break;
1343  case 2:
1345  break;
1346  case 3:
1348  break;
1349  case 4:
1351  break;
1352  default:
1354  break;
1355  }
1356  m_aSectionBreaks.append(sType);
1357  if (!m_bBufferSectionBreaks)
1358  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
1359 }
1360 
1361 void RtfAttributeOutput::NumberingDefinition(sal_uInt16 nId, const SwNumRule& /*rRule*/)
1362 {
1363  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE);
1364  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1365  m_rExport.OutULong(nId);
1366  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT).WriteChar('0');
1367  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LS);
1368  m_rExport.OutULong(nId).WriteChar('}');
1369 }
1370 
1372 {
1373  m_rExport.Strm()
1374  .WriteChar('{')
1375  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LIST)
1377  m_rExport.OutULong(nId);
1378  m_nListId = nId;
1379 }
1380 
1382 {
1383  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
1384  m_rExport.OutULong(m_nListId).WriteChar('}').WriteCharPtr(SAL_NEWLINE_STRING);
1385 }
1386 
1387 void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel, sal_uInt16 nStart,
1388  sal_uInt16 nNumberingType, SvxAdjust eAdjust,
1389  const sal_uInt8* pNumLvlPos, sal_uInt8 nFollow,
1390  const wwFont* pFont, const SfxItemSet* pOutSet,
1391  sal_Int16 nIndentAt, sal_Int16 nFirstLineIndex,
1392  sal_Int16 /*nListTabPos*/, const OUString& rNumberingString,
1393  const SvxBrushItem* pBrush)
1394 {
1395  m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1396  if (nLevel > 8) // RTF knows only 9 levels
1397  m_rExport.Strm()
1398  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE)
1399  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SOUTLVL);
1400 
1401  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTLEVEL);
1402 
1403  sal_uInt16 nVal = 0;
1404  switch (nNumberingType)
1405  {
1406  case SVX_NUM_ROMAN_UPPER:
1407  nVal = 1;
1408  break;
1409  case SVX_NUM_ROMAN_LOWER:
1410  nVal = 2;
1411  break;
1414  nVal = 3;
1415  break;
1418  nVal = 4;
1419  break;
1421  nVal = 14;
1422  break;
1423  case SVX_NUM_CIRCLE_NUMBER:
1424  nVal = 18;
1425  break;
1427  nVal = 35;
1428  if (pOutSet)
1429  {
1430  const SvxLanguageItem& rLang = pOutSet->Get(RES_CHRATR_CJK_LANGUAGE);
1432  {
1433  nVal = 39;
1434  }
1435  }
1436  break;
1438  nVal = 38;
1439  break;
1441  nVal = 34;
1442  break;
1443  case SVX_NUM_TIAN_GAN_ZH:
1444  nVal = 30;
1445  break;
1446  case SVX_NUM_DI_ZI_ZH:
1447  nVal = 31;
1448  break;
1450  nVal = 16;
1451  break;
1453  nVal = 20;
1454  break;
1456  nVal = 12;
1457  break;
1459  nVal = 21;
1460  break;
1462  nVal = 13;
1463  break;
1464  case style::NumberingType::HANGUL_SYLLABLE_KO:
1465  nVal = 24;
1466  break; // ganada
1467  case style::NumberingType::HANGUL_JAMO_KO:
1468  nVal = 25;
1469  break; // chosung
1470  case style::NumberingType::HANGUL_CIRCLED_SYLLABLE_KO:
1471  nVal = 24;
1472  break;
1473  case style::NumberingType::HANGUL_CIRCLED_JAMO_KO:
1474  nVal = 25;
1475  break;
1476  case style::NumberingType::NUMBER_HANGUL_KO:
1477  nVal = 41;
1478  break;
1479  case style::NumberingType::NUMBER_UPPER_KO:
1480  nVal = 44;
1481  break;
1482 
1483  case SVX_NUM_BITMAP:
1484  case SVX_NUM_CHAR_SPECIAL:
1485  nVal = 23;
1486  break;
1487  case SVX_NUM_NUMBER_NONE:
1488  nVal = 255;
1489  break;
1490  }
1491  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNFC);
1492  m_rExport.OutULong(nVal);
1493 
1494  switch (eAdjust)
1495  {
1496  case SvxAdjust::Center:
1497  nVal = 1;
1498  break;
1499  case SvxAdjust::Right:
1500  nVal = 2;
1501  break;
1502  default:
1503  nVal = 0;
1504  break;
1505  }
1506  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELJC);
1507  m_rExport.OutULong(nVal);
1508 
1509  // bullet
1510  if (nNumberingType == SVX_NUM_BITMAP && pBrush)
1511  {
1512  int nIndex = m_rExport.GetGrfIndex(*pBrush);
1513  if (nIndex != -1)
1514  {
1515  m_rExport.Strm().WriteCharPtr(LO_STRING_SVTOOLS_RTF_LEVELPICTURE);
1516  m_rExport.OutULong(nIndex);
1517  }
1518  }
1519 
1520  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT);
1521  m_rExport.OutULong(nStart);
1522 
1523  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW);
1524  m_rExport.OutULong(nFollow);
1525 
1526  // leveltext group
1527  m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELTEXT).WriteChar(' ');
1528 
1529  if (SVX_NUM_CHAR_SPECIAL == nNumberingType || SVX_NUM_BITMAP == nNumberingType)
1530  {
1531  m_rExport.Strm().WriteCharPtr("\\'01");
1532  sal_Unicode cChar = rNumberingString[0];
1533  m_rExport.Strm().WriteCharPtr("\\u");
1534  m_rExport.OutULong(cChar);
1535  m_rExport.Strm().WriteCharPtr(" ?");
1536  }
1537  else
1538  {
1539  m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(
1540  msfilter::rtfutil::OutHex(rNumberingString.getLength(), 2).getStr());
1541  m_rExport.Strm().WriteCharPtr(msfilter::rtfutil::OutString(rNumberingString,
1542  m_rExport.GetDefaultEncoding(),
1543  /*bUnicode =*/false)
1544  .getStr());
1545  }
1546 
1547  m_rExport.Strm().WriteCharPtr(";}");
1548 
1549  // write the levelnumbers
1550  m_rExport.Strm().WriteCharPtr("{").WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS);
1551  for (sal_uInt8 i = 0; i <= nLevel && pNumLvlPos[i]; ++i)
1552  {
1553  m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(
1554  msfilter::rtfutil::OutHex(pNumLvlPos[i], 2).getStr());
1555  }
1556  m_rExport.Strm().WriteCharPtr(";}");
1557 
1558  if (pOutSet)
1559  {
1560  if (pFont)
1561  {
1562  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
1563  m_rExport.OutULong(m_rExport.m_aFontHelper.GetId(*pFont));
1564  }
1565  m_rExport.OutputItemSet(*pOutSet, false, true, i18n::ScriptType::LATIN,
1566  m_rExport.m_bExportModeRTF);
1567  const OString aProperties = MoveCharacterProperties(true);
1568  m_rExport.Strm().WriteOString(aProperties);
1569  }
1570 
1571  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FI);
1572  m_rExport.OutLong(nFirstLineIndex).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LI);
1573  m_rExport.OutLong(nIndentAt);
1574 
1575  m_rExport.Strm().WriteChar('}');
1576  if (nLevel > 8)
1577  m_rExport.Strm().WriteChar('}');
1578 }
1579 
1581  const OUString& rFieldCmd, FieldFlags nMode)
1582 {
1583  // If there are no field instructions, don't export it as a field.
1584  bool bHasInstructions = !rFieldCmd.isEmpty();
1585  if (FieldFlags::All == nMode)
1586  {
1587  if (bHasInstructions)
1588  {
1589  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1591  " ");
1592  m_aRunText->append(
1593  msfilter::rtfutil::OutString(rFieldCmd, m_rExport.GetCurrentEncoding()));
1594  m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
1595  }
1596  if (pField)
1597  m_aRunText->append(msfilter::rtfutil::OutString(pField->ExpandField(true, nullptr),
1598  m_rExport.GetDefaultEncoding()));
1599  if (bHasInstructions)
1600  m_aRunText->append("}}");
1601  }
1602  else
1603  {
1604  if (nMode & FieldFlags::CmdStart)
1605  {
1606  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
1608  // paragraph break closes group so open another one "inside" to
1609  " {"); // prevent leaving the field instruction
1610  }
1611  if (bHasInstructions)
1612  m_aRunText->append(
1613  msfilter::rtfutil::OutString(rFieldCmd, m_rExport.GetCurrentEncoding()));
1614  if (nMode & FieldFlags::CmdEnd)
1615  {
1616  m_aRunText->append("}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
1617  }
1618  if (nMode & FieldFlags::Close)
1619  {
1620  m_aRunText->append("}}}");
1621  }
1622  }
1623 }
1624 
1625 void RtfAttributeOutput::WriteBookmarks_Impl(std::vector<OUString>& rStarts,
1626  std::vector<OUString>& rEnds)
1627 {
1628  for (const auto& rStart : rStarts)
1629  {
1631  m_aRun->append(msfilter::rtfutil::OutString(rStart, m_rExport.GetCurrentEncoding()));
1632  m_aRun->append('}');
1633  }
1634  rStarts.clear();
1635 
1636  for (const auto& rEnd : rEnds)
1637  {
1639  m_aRun->append(msfilter::rtfutil::OutString(rEnd, m_rExport.GetCurrentEncoding()));
1640  m_aRun->append('}');
1641  }
1642  rEnds.clear();
1643 }
1644 
1645 void RtfAttributeOutput::WriteAnnotationMarks_Impl(std::vector<OUString>& rStarts,
1646  std::vector<OUString>& rEnds)
1647 {
1648  for (const auto& rStart : rStarts)
1649  {
1650  OString rName = OUStringToOString(rStart, RTL_TEXTENCODING_UTF8);
1651 
1652  // Output the annotation mark
1653  const sal_Int32 nId = m_nNextAnnotationMarkId++;
1654  m_rOpenedAnnotationMarksIds[rName] = nId;
1656  m_aRun->append(OString::number(nId).getStr());
1657  m_aRun->append('}');
1658  }
1659  rStarts.clear();
1660 
1661  for (const auto& rEnd : rEnds)
1662  {
1663  OString rName = OUStringToOString(rEnd, RTL_TEXTENCODING_UTF8);
1664 
1665  // Get the id of the annotation mark
1666  auto it = m_rOpenedAnnotationMarksIds.find(rName);
1667  if (it != m_rOpenedAnnotationMarksIds.end())
1668  {
1669  const sal_Int32 nId = it->second;
1671  m_aRun->append(OString::number(nId).getStr());
1672  m_aRun->append('}');
1673  m_rOpenedAnnotationMarksIds.erase(rName);
1674 
1675  if (m_aPostitFields.find(nId) != m_aPostitFields.end())
1676  {
1677  m_aRunText->append("{");
1678  m_nCurrentAnnotationMarkId = nId;
1679  PostitField(m_aPostitFields[nId]);
1680  m_nCurrentAnnotationMarkId = -1;
1681  m_aRunText->append("}");
1682  }
1683  }
1684  }
1685  rEnds.clear();
1686 }
1687 
1689  const sal_Char* pStr, bool bTitlepg)
1690 {
1691  OStringBuffer aSectionBreaks = m_aSectionBreaks;
1692  m_aSectionBreaks.setLength(0);
1693  RtfStringBuffer aRun = m_aRun;
1694  m_aRun.clear();
1695 
1696  m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY
1698  m_aSectionHeaders.append(
1699  static_cast<sal_Int32>(m_rExport.m_pCurrentPageDesc->GetMaster().GetULSpace().GetUpper()));
1700  if (bTitlepg)
1701  m_aSectionHeaders.append(OOO_STRING_SVTOOLS_RTF_TITLEPG);
1702  m_aSectionHeaders.append('{');
1703  m_aSectionHeaders.append(pStr);
1704  m_bBufferSectionHeaders = true;
1705  m_rExport.WriteHeaderFooterText(rFormat, bHeader);
1706  m_bBufferSectionHeaders = false;
1707  m_aSectionHeaders.append('}');
1708 
1709  m_aSectionBreaks = aSectionBreaks;
1710  m_aRun = aRun;
1711 }
1712 
1713 namespace
1714 {
1715 void lcl_TextFrameShadow(std::vector<std::pair<OString, OString>>& rFlyProperties,
1716  const SwFrameFormat& rFrameFormat)
1717 {
1718  const SvxShadowItem& aShadowItem = rFrameFormat.GetShadow();
1719  if (aShadowItem.GetLocation() == SvxShadowLocation::NONE)
1720  return;
1721 
1722  rFlyProperties.push_back(std::make_pair<OString, OString>("fShadow", OString::number(1)));
1723 
1724  const Color& rColor = aShadowItem.GetColor();
1725  // We in fact need RGB to BGR, but the transformation is symmetric.
1726  rFlyProperties.push_back(std::make_pair<OString, OString>(
1727  "shadowColor", OString::number(wwUtility::RGBToBGR(rColor))));
1728 
1729  // Twips -> points -> EMUs -- hacky, the intermediate step hides rounding errors on roundtrip.
1730  OString aShadowWidth = OString::number(sal_Int32(aShadowItem.GetWidth() / 20) * 12700);
1731  OString aOffsetX;
1732  OString aOffsetY;
1733  switch (aShadowItem.GetLocation())
1734  {
1735  case SvxShadowLocation::TopLeft:
1736  aOffsetX = "-" + aShadowWidth;
1737  aOffsetY = "-" + aShadowWidth;
1738  break;
1739  case SvxShadowLocation::TopRight:
1740  aOffsetX = aShadowWidth;
1741  aOffsetY = "-" + aShadowWidth;
1742  break;
1743  case SvxShadowLocation::BottomLeft:
1744  aOffsetX = "-" + aShadowWidth;
1745  aOffsetY = aShadowWidth;
1746  break;
1747  case SvxShadowLocation::BottomRight:
1748  aOffsetX = aShadowWidth;
1749  aOffsetY = aShadowWidth;
1750  break;
1751  case SvxShadowLocation::NONE:
1752  case SvxShadowLocation::End:
1753  break;
1754  }
1755  if (!aOffsetX.isEmpty())
1756  rFlyProperties.emplace_back("shadowOffsetX", aOffsetX);
1757  if (!aOffsetY.isEmpty())
1758  rFlyProperties.emplace_back("shadowOffsetY", aOffsetY);
1759 }
1760 
1761 void lcl_TextFrameRelativeSize(std::vector<std::pair<OString, OString>>& rFlyProperties,
1762  const SwFrameFormat& rFrameFormat)
1763 {
1764  const SwFormatFrameSize& rSize = rFrameFormat.GetFrameSize();
1765 
1766  // Relative size of the Text Frame.
1767  const sal_uInt8 nWidthPercent = rSize.GetWidthPercent();
1768  if (nWidthPercent && nWidthPercent != SwFormatFrameSize::SYNCED)
1769  {
1770  rFlyProperties.push_back(
1771  std::make_pair<OString, OString>("pctHoriz", OString::number(nWidthPercent * 10)));
1772 
1773  OString aRelation;
1774  switch (rSize.GetWidthPercentRelation())
1775  {
1776  case text::RelOrientation::PAGE_FRAME:
1777  aRelation = "1"; // page
1778  break;
1779  default:
1780  aRelation = "0"; // margin
1781  break;
1782  }
1783  rFlyProperties.emplace_back(std::make_pair("sizerelh", aRelation));
1784  }
1785  const sal_uInt8 nHeightPercent = rSize.GetHeightPercent();
1786  if (nHeightPercent && nHeightPercent != SwFormatFrameSize::SYNCED)
1787  {
1788  rFlyProperties.push_back(
1789  std::make_pair<OString, OString>("pctVert", OString::number(nHeightPercent * 10)));
1790 
1791  OString aRelation;
1792  switch (rSize.GetHeightPercentRelation())
1793  {
1794  case text::RelOrientation::PAGE_FRAME:
1795  aRelation = "1"; // page
1796  break;
1797  default:
1798  aRelation = "0"; // margin
1799  break;
1800  }
1801  rFlyProperties.emplace_back(std::make_pair("sizerelv", aRelation));
1802  }
1803 }
1804 }
1805 
1806 void RtfAttributeOutput::writeTextFrame(const ww8::Frame& rFrame, bool bTextBox)
1807 {
1808  RtfStringBuffer aRunText;
1809  if (bTextBox)
1810  {
1811  m_rExport.setStream();
1812  aRunText = m_aRunText;
1813  m_aRunText.clear();
1814  }
1815 
1816  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
1817 
1818  {
1819  // Save table state, in case the inner text also contains a table.
1820  ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.m_pTableInfo;
1821  m_rExport.m_pTableInfo = std::make_shared<ww8::WW8TableInfo>();
1822  std::unique_ptr<SwWriteTable> pTableWrt(std::move(m_pTableWrt));
1823  sal_uInt32 nTableDepth = m_nTableDepth;
1824 
1825  m_nTableDepth = 0;
1826  /*
1827  * Save m_aRun as we should not lose the opening brace.
1828  * OTOH, just drop the contents of m_aRunText in case something
1829  * would be there, causing a problem later.
1830  */
1831  OString aSave = m_aRun.makeStringAndClear();
1832  // Also back m_bInRun and m_bSingleEmptyRun up.
1833  bool bInRunOrig = m_bInRun;
1834  m_bInRun = false;
1835  bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
1836  m_bSingleEmptyRun = false;
1837  m_rExport.SetRTFFlySyntax(true);
1838 
1839  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
1840  const SwNodeIndex* pNodeIndex = rFrameFormat.GetContent().GetContentIdx();
1841  sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex() + 1 : 0;
1842  sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
1843  m_rExport.SaveData(nStt, nEnd);
1844  m_rExport.m_pParentFrame = &rFrame;
1845  m_rExport.WriteText();
1846  m_rExport.RestoreData();
1847 
1848  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
1849  m_rExport.SetRTFFlySyntax(false);
1850  m_aRun->append(aSave);
1851  m_aRunText.clear();
1852  m_bInRun = bInRunOrig;
1853  m_bSingleEmptyRun = bSingleEmptyRunOrig;
1854 
1855  // Restore table state.
1856  m_rExport.m_pTableInfo = pTableInfoOrig;
1857  m_pTableWrt = std::move(pTableWrt);
1858  m_nTableDepth = nTableDepth;
1859  }
1860 
1861  m_rExport.m_pParentFrame = nullptr;
1862 
1863  m_rExport.Strm().WriteChar('}'); // shptxt
1864 
1865  if (bTextBox)
1866  {
1867  m_aRunText = aRunText;
1868  m_aRunText->append(m_rExport.getStream());
1869  m_rExport.resetStream();
1870  }
1871 }
1872 
1873 void RtfAttributeOutput::OutputFlyFrame_Impl(const ww8::Frame& rFrame, const Point& /*rNdTopLeft*/)
1874 {
1875  const SwNode* pNode = rFrame.GetContent();
1876  const SwGrfNode* pGrfNode = pNode ? pNode->GetGrfNode() : nullptr;
1877 
1878  switch (rFrame.GetWriterType())
1879  {
1880  case ww8::Frame::eTextBox:
1881  {
1882  // If this is a TextBox of a shape, then ignore: it's handled in RtfSdrExport::StartShape().
1884  break;
1885 
1886  assert(m_aRunText.getLength() == 0 && "this will corrupt the document");
1887  m_rExport.m_pParentFrame = &rFrame;
1888 
1889  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP);
1890  m_rExport.Strm().WriteCharPtr(
1892 
1893  // Shape properties.
1894  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
1895  "shapeType", OString::number(ESCHER_ShpInst_TextBox)));
1896 
1897  // When a frame has some low height, but automatically expanded due
1898  // to lots of contents, this size contains the real size.
1899  const Size aSize = rFrame.GetSize();
1900  m_pFlyFrameSize = &aSize;
1901 
1902  m_rExport.m_bOutFlyFrameAttrs = true;
1903  m_rExport.SetRTFFlySyntax(true);
1904  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1905 
1906  // Write ZOrder.
1907  if (const SdrObject* pObject = rFrame.GetFrameFormat().FindRealSdrObject())
1908  {
1909  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPZ);
1910  m_rExport.OutULong(pObject->GetOrdNum());
1911  }
1912 
1913  m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
1914  m_rExport.Strm().WriteOString(m_aStyles.makeStringAndClear());
1915  m_rExport.m_bOutFlyFrameAttrs = false;
1916  m_rExport.SetRTFFlySyntax(false);
1917  m_pFlyFrameSize = nullptr;
1918 
1919  const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
1920  lcl_TextFrameShadow(m_aFlyProperties, rFrameFormat);
1921  lcl_TextFrameRelativeSize(m_aFlyProperties, rFrameFormat);
1922 
1923  for (const std::pair<OString, OString>& rPair : m_aFlyProperties)
1924  {
1925  m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
1926  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
1927  m_rExport.Strm().WriteOString(rPair.first);
1928  m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
1929  m_rExport.Strm().WriteOString(rPair.second);
1930  m_rExport.Strm().WriteCharPtr("}}");
1931  }
1932  m_aFlyProperties.clear();
1933 
1934  writeTextFrame(rFrame);
1935 
1936  m_rExport.Strm().WriteChar('}'); // shpinst
1937  m_rExport.Strm().WriteChar('}'); // shp
1938 
1939  m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
1940  }
1941  break;
1942  case ww8::Frame::eGraphic:
1943  if (!rFrame.IsInline())
1944  {
1945  m_rExport.m_pParentFrame = &rFrame;
1946  m_rExport.SetRTFFlySyntax(true);
1947  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1948  m_rExport.SetRTFFlySyntax(false);
1949  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
1950  m_rExport.OutputFormat(rFrame.GetFrameFormat(), false, false, true);
1951  m_aRunText->append('}');
1952  m_rExport.m_pParentFrame = nullptr;
1953  m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
1954  }
1955 
1956  if (pGrfNode)
1957  {
1958  m_aRunText.append(dynamic_cast<const SwFlyFrameFormat*>(&rFrame.GetFrameFormat()),
1959  pGrfNode);
1960  m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
1961  }
1962  break;
1963  case ww8::Frame::eDrawing:
1964  {
1965  const SdrObject* pSdrObj = rFrame.GetFrameFormat().FindRealSdrObject();
1966  if (pSdrObj)
1967  {
1968  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
1969  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
1970  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
1971  m_aRunText->append(" SHAPE ");
1972  m_aRunText->append("}"
1974 
1975  m_rExport.SdrExporter().AddSdrObject(*pSdrObj);
1976 
1977  m_aRunText->append('}');
1978  m_aRunText->append('}');
1979  m_rExport.Strm().WriteOString(m_aRunText.makeStringAndClear());
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 : std::as_const(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  double fHeight = 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  fHeight = -fHeight;
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  m_aStyles.append(static_cast<sal_Int32>(round(fHeight * nEsc / 1000)));
2344 }
2345 
2347 {
2348  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LOCH);
2349  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_F);
2350  m_aStyles.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2351 
2352  if (!m_rExport.HasItem(RES_CHRATR_CJK_FONT) && !m_rExport.HasItem(RES_CHRATR_CTL_FONT))
2353  {
2354  // Be explicit about that the given font should be used everywhere, not
2355  // just for the loch range.
2356  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_HICH);
2357  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2358  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2359  }
2360 
2361  // FIXME: this may be a tad expensive... but the charset needs to be
2362  // consistent with what wwFont::WriteRtf() does
2363  sw::util::FontMapExport aTmp(rFont.GetFamilyName());
2365  aTmp.msPrimary, aTmp.msSecondary, rFont.GetCharSet());
2366  m_rExport.SetCurrentEncoding(rtl_getTextEncodingFromWindowsCharset(nWindowsCharset));
2367  if (m_rExport.GetCurrentEncoding() == RTL_TEXTENCODING_DONTKNOW)
2368  m_rExport.SetCurrentEncoding(m_rExport.GetDefaultEncoding());
2369 }
2370 
2372 {
2373  switch (rFontSize.Which())
2374  {
2375  case RES_CHRATR_FONTSIZE:
2376  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
2377  m_aStyles.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2378  break;
2380  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_FS);
2381  m_aStylesAssoc.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2382  break;
2384  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AFS);
2385  m_aStylesAssoc.append(static_cast<sal_Int32>(rFontSize.GetHeight() / 10));
2386  break;
2387  }
2388 }
2389 
2391 {
2392  // in quarter points then in twips
2393  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
2394  m_aStyles.append(static_cast<sal_Int32>(rKerning.GetValue() / 5));
2395  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
2396  m_aStyles.append(static_cast<sal_Int32>(rKerning.GetValue()));
2397 }
2398 
2400 {
2401  switch (rLanguage.Which())
2402  {
2403  case RES_CHRATR_LANGUAGE:
2404  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANG);
2405  m_aStyles.append(
2406  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2407  break;
2409  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
2410  m_aStylesAssoc.append(
2411  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2412  break;
2414  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_ALANG);
2415  m_aStylesAssoc.append(
2416  static_cast<sal_Int32>(static_cast<sal_uInt16>(rLanguage.GetLanguage())));
2417  break;
2418  }
2419 }
2420 
2422 {
2423  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
2424  if (rPosture.GetPosture() == ITALIC_NONE)
2425  m_aStyles.append(sal_Int32(0));
2426 }
2427 
2429 {
2430  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
2431  if (!rShadow.GetValue())
2432  m_aStyles.append(sal_Int32(0));
2433 }
2434 
2436 {
2437  const char* pStr = nullptr;
2438  const SfxPoolItem* pItem = m_rExport.HasItem(RES_CHRATR_WORDLINEMODE);
2439  bool bWord = false;
2440  if (pItem)
2441  bWord = static_cast<const SvxWordLineModeItem*>(pItem)->GetValue();
2442  switch (rUnderline.GetLineStyle())
2443  {
2444  case LINESTYLE_SINGLE:
2446  break;
2447  case LINESTYLE_DOUBLE:
2449  break;
2450  case LINESTYLE_NONE:
2452  break;
2453  case LINESTYLE_DOTTED:
2455  break;
2456  case LINESTYLE_DASH:
2458  break;
2459  case LINESTYLE_DASHDOT:
2461  break;
2462  case LINESTYLE_DASHDOTDOT:
2464  break;
2465  case LINESTYLE_BOLD:
2467  break;
2468  case LINESTYLE_WAVE:
2470  break;
2471  case LINESTYLE_BOLDDOTTED:
2473  break;
2474  case LINESTYLE_BOLDDASH:
2476  break;
2477  case LINESTYLE_LONGDASH:
2479  break;
2482  break;
2483  case LINESTYLE_BOLDDASHDOT:
2485  break;
2488  break;
2489  case LINESTYLE_BOLDWAVE:
2491  break;
2492  case LINESTYLE_DOUBLEWAVE:
2494  break;
2495  default:
2496  break;
2497  }
2498 
2499  if (pStr)
2500  {
2501  m_aStyles.append(pStr);
2502  // NEEDSWORK looks like here rUnderline.GetColor() is always black,
2503  // even if the color in the odt is for example green...
2504  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
2505  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rUnderline.GetColor())));
2506  }
2507 }
2508 
2510 {
2511  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
2512  if (rWeight.GetWeight() != WEIGHT_BOLD)
2513  m_aStyles.append(sal_Int32(0));
2514 }
2515 
2517 {
2518  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
2519  m_aStyles.append(static_cast<sal_Int32>(rAutoKern.GetValue() ? 1 : 0));
2520 }
2521 
2523 {
2524  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
2525  m_aStyles.append(static_cast<sal_Int32>(rBlink.GetValue() ? 2 : 0));
2526 }
2527 
2529 {
2530  if (!rBrush.GetColor().GetTransparency())
2531  {
2532  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
2533  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rBrush.GetColor())));
2534  }
2535 }
2536 
2538 {
2539  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2540  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2541  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2542 }
2543 
2545 {
2546  CharFontSize(rFontSize);
2547 }
2548 
2550 {
2551  CharLanguage(rLanguageItem);
2552 }
2553 
2555 {
2556  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_I);
2557  if (rPosture.GetPosture() == ITALIC_NONE)
2558  m_aStylesAssoc.append(sal_Int32(0));
2559 }
2560 
2562 {
2563  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_B);
2564  if (rWeight.GetWeight() != WEIGHT_BOLD)
2565  m_aStylesAssoc.append(sal_Int32(0));
2566 }
2567 
2569 {
2570  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_DBCH);
2571  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AF);
2572  m_aStylesAssoc.append(static_cast<sal_Int32>(m_rExport.m_aFontHelper.GetId(rFont)));
2573 }
2574 
2576 {
2577  CharFontSize(rFontSize);
2578 }
2579 
2581 {
2582  CharLanguage(rLanguageItem);
2583 }
2584 
2586 {
2587  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AI);
2588  if (rPosture.GetPosture() == ITALIC_NONE)
2589  m_aStylesAssoc.append(sal_Int32(0));
2590 }
2591 
2593 {
2594  m_aStylesAssoc.append(OOO_STRING_SVTOOLS_RTF_AB);
2595  if (rWeight.GetWeight() != WEIGHT_BOLD)
2596  m_aStylesAssoc.append(sal_Int32(0));
2597 }
2598 
2600 
2602 
2604 {
2605  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
2606  m_aStyles.append(static_cast<sal_Int32>(rRotate.IsFitToLine() ? 1 : 0));
2607 }
2608 
2610 {
2611  FontEmphasisMark v = rEmphasisMark.GetEmphasisMark();
2612  if (v == FontEmphasisMark::NONE)
2613  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCNONE);
2614  else if (v == (FontEmphasisMark::Dot | FontEmphasisMark::PosAbove))
2615  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCDOT);
2616  else if (v == (FontEmphasisMark::Accent | FontEmphasisMark::PosAbove))
2617  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCOMMA);
2618  else if (v == (FontEmphasisMark::Circle | FontEmphasisMark::PosAbove))
2619  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCIRCLE);
2620  else if (v == (FontEmphasisMark::Dot | FontEmphasisMark::PosBelow))
2621  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCUNDERDOT);
2622 }
2623 
2625 {
2626  if (rTwoLines.GetValue())
2627  {
2628  sal_Unicode cStart = rTwoLines.GetStartBracket();
2629  sal_Unicode cEnd = rTwoLines.GetEndBracket();
2630 
2631  sal_uInt16 nType;
2632  if (!cStart && !cEnd)
2633  nType = 0;
2634  else if ('{' == cStart || '}' == cEnd)
2635  nType = 4;
2636  else if ('<' == cStart || '>' == cEnd)
2637  nType = 3;
2638  else if ('[' == cStart || ']' == cEnd)
2639  nType = 2;
2640  else // all other kind of brackets
2641  nType = 1;
2642 
2643  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
2644  m_aStyles.append(static_cast<sal_Int32>(nType));
2645  }
2646 }
2647 
2649 {
2650  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
2651  m_aStyles.append(static_cast<sal_Int32>(rScaleWidth.GetValue()));
2652 }
2653 
2655 {
2656  const sal_Char* pStr;
2657  switch (rRelief.GetValue())
2658  {
2659  case FontRelief::Embossed:
2661  break;
2662  case FontRelief::Engraved:
2664  break;
2665  default:
2666  pStr = nullptr;
2667  break;
2668  }
2669 
2670  if (pStr)
2671  m_aStyles.append(pStr);
2672 }
2673 
2675 {
2676  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
2677  if (!rHidden.GetValue())
2678  m_aStyles.append(sal_Int32(0));
2679 }
2680 
2682  const sal_uInt16 nDist, const bool bShadow)
2683 {
2684  m_aStyles.append(
2685  OutBorderLine(m_rExport, pAllBorder, OOO_STRING_SVTOOLS_RTF_CHBRDR, nDist,
2686  bShadow ? SvxShadowLocation::BottomRight : SvxShadowLocation::NONE));
2687 }
2688 
2690 {
2691  if (!rBrush.GetColor().GetTransparency())
2692  {
2693  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
2694  m_aStyles.append(static_cast<sal_Int32>(msfilter::util::TransColToIco(rBrush.GetColor())));
2695  }
2696 }
2697 
2699 {
2700  if (!rURL.GetValue().isEmpty())
2701  {
2702  const SwCharFormat* pFormat;
2703  const SwTextINetFormat* pTextAtr = rURL.GetTextINetFormat();
2704 
2705  if (pTextAtr && nullptr != (pFormat = pTextAtr->GetCharFormat()))
2706  {
2707  sal_uInt16 nStyle = m_rExport.GetId(pFormat);
2708  OString* pString = m_rExport.GetStyle(nStyle);
2709  if (pString)
2710  m_aStyles.append(*pString);
2711  }
2712  }
2713 }
2714 
2716 {
2717  sal_uInt16 nStyle = m_rExport.GetId(rCharFormat.GetCharFormat());
2718  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CS);
2719  m_aStyles.append(static_cast<sal_Int32>(nStyle));
2720  OString* pString = m_rExport.GetStyle(nStyle);
2721  if (pString)
2722  m_aStyles.append(*pString);
2723 }
2724 
2726 {
2727  if (rFootnote.GetNumStr().isEmpty())
2728  m_aRun->append(OOO_STRING_SVTOOLS_RTF_CHFTN);
2729  else
2730  m_aRun->append(
2731  msfilter::rtfutil::OutString(rFootnote.GetNumStr(), m_rExport.GetCurrentEncoding()));
2732 }
2733 
2735 {
2736  SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
2737 
2738  m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
2739  EndRunProperties(nullptr);
2740  m_aRun->append(' ');
2741  WriteTextFootnoteNumStr(rFootnote);
2743  if (rFootnote.IsEndNote() || m_rExport.m_pDoc->GetFootnoteInfo().ePos == FTNPOS_CHAPTER)
2744  m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
2745  m_aRun->append(' ');
2746  WriteTextFootnoteNumStr(rFootnote);
2747 
2748  /*
2749  * The footnote contains a whole paragraph, so we have to:
2750  * 1) Reset, then later restore the contents of our run buffer and run state.
2751  * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
2752  */
2753  const SwNodeIndex* pIndex = rFootnote.GetTextFootnote()->GetStartNode();
2754  RtfStringBuffer aRun = m_aRun;
2755  m_aRun.clear();
2756  bool bInRunOrig = m_bInRun;
2757  m_bInRun = false;
2758  bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
2759  m_bSingleEmptyRun = false;
2760  m_bBufferSectionHeaders = true;
2761  m_rExport.WriteSpecialText(pIndex->GetIndex() + 1, pIndex->GetNode().EndOfSectionIndex(),
2762  !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
2763  m_bBufferSectionHeaders = false;
2764  m_bInRun = bInRunOrig;
2765  m_bSingleEmptyRun = bSingleEmptyRunOrig;
2766  m_aRun = aRun;
2767  m_aRun->append(m_aSectionHeaders.makeStringAndClear());
2768 
2769  m_aRun->append("}");
2770  m_aRun->append("}");
2771 
2772  SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
2773 }
2774 
2775 void RtfAttributeOutput::ParaLineSpacing_Impl(short nSpace, short nMulti)
2776 {
2777  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
2778  m_aStyles.append(static_cast<sal_Int32>(nSpace));
2779  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
2780  m_aStyles.append(static_cast<sal_Int32>(nMulti));
2781 }
2782 
2784 {
2785  switch (rAdjust.GetAdjust())
2786  {
2787  case SvxAdjust::Left:
2788  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
2789  break;
2790  case SvxAdjust::Right:
2791  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
2792  break;
2793  case SvxAdjust::BlockLine:
2794  case SvxAdjust::Block:
2795  if (rAdjust.GetLastBlock() == SvxAdjust::Block)
2796  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QD);
2797  else
2798  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
2799  break;
2800  case SvxAdjust::Center:
2801  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
2802  break;
2803  default:
2804  break;
2805  }
2806 }
2807 
2809 {
2810  if (!rSplit.GetValue())
2811  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
2812 }
2813 
2815 {
2816  if (rWidows.GetValue())
2817  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
2818  else
2819  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
2820 }
2821 
2823 {
2824  long nOffset = 0;
2825  // Tabs are absolute by default.
2826  if (m_rExport.m_pDoc->getIDocumentSettingAccess().get(
2828  nOffset = m_rExport.GetItem(RES_LR_SPACE).GetTextLeft();
2829 
2830  for (sal_uInt16 n = 0; n < rTabStop.Count(); n++)
2831  {
2832  const SvxTabStop& rTS = rTabStop[n];
2833  if (SvxTabAdjust::Default != rTS.GetAdjustment())
2834  {
2835  const char* pFill = nullptr;
2836  switch (rTS.GetFill())
2837  {
2838  case cDfltFillChar:
2839  break;
2840 
2841  case '.':
2843  break;
2844  case '_':
2846  break;
2847  case '-':
2849  break;
2850  case '=':
2852  break;
2853  default:
2854  break;
2855  }
2856  if (pFill)
2857  m_aStyles.append(pFill);
2858 
2859  const sal_Char* pAdjStr = nullptr;
2860  switch (rTS.GetAdjustment())
2861  {
2862  case SvxTabAdjust::Right:
2863  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
2864  break;
2865  case SvxTabAdjust::Decimal:
2866  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
2867  break;
2868  case SvxTabAdjust::Center:
2869  pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
2870  break;
2871  default:
2872  break;
2873  }
2874  if (pAdjStr)
2875  m_aStyles.append(pAdjStr);
2876  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
2877  m_aStyles.append(static_cast<sal_Int32>(rTS.GetTabPos() + nOffset));
2878  }
2879  else
2880  {
2881  m_aTabStop.append(OOO_STRING_SVTOOLS_RTF_DEFTAB);
2882  m_aTabStop.append(rTabStop[0].GetTabPos());
2883  }
2884  }
2885 }
2886 
2888 {
2889  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHPAR);
2890  m_aStyles.append(sal_Int32(rHyphenZone.IsHyphen()));
2891 }
2892 
2893 void RtfAttributeOutput::ParaNumRule_Impl(const SwTextNode* pTextNd, sal_Int32 nLvl,
2894  sal_Int32 nNumId)
2895 {
2896  if (USHRT_MAX == nNumId || 0 == nNumId || nullptr == pTextNd)
2897  return;
2898 
2899  const SwNumRule* pRule = pTextNd->GetNumRule();
2900 
2901  if (!pRule || !pTextNd->IsInList())
2902  return;
2903 
2904  SAL_WARN_IF(pTextNd->GetActualListLevel() < 0 || pTextNd->GetActualListLevel() >= MAXLEVEL,
2905  "sw.rtf", "text node does not have valid list level");
2906 
2907  const SwNumFormat* pFormat = pRule->GetNumFormat(nLvl);
2908  if (!pFormat)
2909  pFormat = &pRule->Get(nLvl);
2910 
2911  const SfxItemSet& rNdSet = pTextNd->GetSwAttrSet();
2912 
2913  m_aStyles.append('{');
2914  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
2915  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
2916  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
2917  m_aStyles.append(' ');
2918 
2919  SvxLRSpaceItem aLR(rNdSet.Get(RES_LR_SPACE));
2920  aLR.SetTextLeft(aLR.GetTextLeft() + pFormat->GetIndentAt());
2921  aLR.SetTextFirstLineOfst(pFormat->GetFirstLineOffset()); //TODO: overflow
2922 
2923  sal_uInt16 nStyle = m_rExport.GetId(pFormat->GetCharFormat());
2924  OString* pString = m_rExport.GetStyle(nStyle);
2925  if (pString)
2926  m_aStyles.append(*pString);
2927 
2928  {
2929  OUString sText;
2930  if (SVX_NUM_CHAR_SPECIAL == pFormat->GetNumberingType()
2931  || SVX_NUM_BITMAP == pFormat->GetNumberingType())
2932  sText = OUString(pFormat->GetBulletChar());
2933  else
2934  sText = pTextNd->GetNumString();
2935 
2936  if (!sText.isEmpty())
2937  {
2938  m_aStyles.append(' ');
2939  m_aStyles.append(msfilter::rtfutil::OutString(sText, m_rExport.GetDefaultEncoding()));
2940  }
2941 
2942  if (OUTLINE_RULE != pRule->GetRuleType())
2943  {
2944  if (!sText.isEmpty())
2945  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
2946  m_aStyles.append('}');
2947  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
2948  if (nLvl > 8) // RTF knows only 9 levels
2949  {
2950  m_aStyles.append(sal_Int32(8));
2952  m_aStyles.append(nLvl);
2953  m_aStyles.append('}');
2954  }
2955  else
2956  m_aStyles.append(nLvl);
2957  }
2958  else
2959  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
2960  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
2961  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetNumberingId(*pRule)) + 1);
2962  m_aStyles.append(' ');
2963  }
2964  FormatLRSpace(aLR);
2965 }
2966 
2968 {
2969  if (!rScriptSpace.GetValue())
2970  return;
2971 
2972  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
2973 }
2974 
2976 {
2977  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2978 }
2979 
2981 {
2982  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
2983 }
2984 
2986 {
2987  const char* pStr;
2988  switch (rAlign.GetValue())
2989  {
2992  break;
2995  break;
2998  break;
3001  break;
3002 
3003  default:
3005  break;
3006  }
3007  m_aStyles.append(pStr);
3008 }
3009 
3011 {
3012  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3013 }
3014 
3016 {
3017  if (m_rExport.m_bOutPageDescs)
3018  {
3019  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
3020  m_aSectionBreaks.append(static_cast<sal_Int32>(rSize.GetWidth()));
3021  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
3022  m_aSectionBreaks.append(static_cast<sal_Int32>(rSize.GetHeight()));
3023  if (!m_bBufferSectionBreaks)
3024  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
3025  }
3026 }
3027 
3029 {
3030  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3031 }
3032 
3034 {
3035  if (!m_rExport.m_bOutFlyFrameAttrs)
3036  {
3037  if (m_rExport.m_bOutPageDescs)
3038  {
3039  if (rLRSpace.GetLeft())
3040  {
3041  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
3042  m_aSectionBreaks.append(static_cast<sal_Int32>(rLRSpace.GetLeft()));
3043  }
3044  if (rLRSpace.GetRight())
3045  {
3046  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
3047  m_aSectionBreaks.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3048  }
3049  if (!m_bBufferSectionBreaks)
3050  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
3051  }
3052  else
3053  {
3054  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
3055  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextLeft()));
3056  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
3057  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3058  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
3059  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextLeft()));
3060  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
3061  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetRight()));
3062  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
3063  m_aStyles.append(static_cast<sal_Int32>(rLRSpace.GetTextFirstLineOfst()));
3064  }
3065  }
3066  else if (m_rExport.GetRTFFlySyntax())
3067  {
3068  // Wrap: top and bottom spacing, convert from twips to EMUs.
3069  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3070  "dxWrapDistLeft", OString::number(rLRSpace.GetLeft() * 635)));
3071  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3072  "dxWrapDistRight", OString::number(rLRSpace.GetRight() * 635)));
3073  }
3074 }
3075 
3077 {
3078  if (!m_rExport.m_bOutFlyFrameAttrs)
3079  {
3080  if (m_rExport.m_bOutPageDescs)
3081  {
3082  OSL_ENSURE(m_rExport.GetCurItemSet(), "Impossible");
3083  if (!m_rExport.GetCurItemSet())
3084  return;
3085 
3086  // If we export a follow page format, then our doc model has
3087  // separate header/footer distances for the first page and the
3088  // follow pages, but Word can have only a single distance. In case
3089  // the two values differ, work with the value from the first page
3090  // format to be in sync with the import.
3091  sw::util::HdFtDistanceGlue aDistances(m_rExport.GetFirstPageItemSet()
3092  ? *m_rExport.GetFirstPageItemSet()
3093  : *m_rExport.GetCurItemSet());
3094 
3095  if (aDistances.dyaTop)
3096  {
3097  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
3098  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaTop));
3099  }
3100  if (aDistances.HasHeader())
3101  {
3102  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_HEADERY);
3103  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaHdrTop));
3104  }
3105 
3106  if (aDistances.dyaBottom)
3107  {
3108  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
3109  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaBottom));
3110  }
3111  if (aDistances.HasFooter())
3112  {
3113  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_FOOTERY);
3114  m_aSectionBreaks.append(static_cast<sal_Int32>(aDistances.dyaHdrBottom));
3115  }
3116  if (!m_bBufferSectionBreaks)
3117  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
3118  }
3119  else
3120  {
3121  // Spacing before.
3122  if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == rULSpace.GetUpper())
3123  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SBAUTO "1");
3124  else if (m_bParaBeforeAutoSpacing && m_nParaBeforeSpacing == -1)
3125  {
3126  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SBAUTO "0");
3127  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
3128  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetUpper()));
3129  }
3130  else
3131  {
3132  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
3133  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetUpper()));
3134  }
3135  m_bParaBeforeAutoSpacing = false;
3136 
3137  // Spacing after.
3138  if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == rULSpace.GetLower())
3139  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SAAUTO "1");
3140  else if (m_bParaAfterAutoSpacing && m_nParaAfterSpacing == -1)
3141  {
3142  m_aStyles.append(LO_STRING_SVTOOLS_RTF_SAAUTO "0");
3143  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
3144  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetLower()));
3145  }
3146  else
3147  {
3148  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
3149  m_aStyles.append(static_cast<sal_Int32>(rULSpace.GetLower()));
3150  }
3151  m_bParaAfterAutoSpacing = false;
3152 
3153  // Contextual spacing.
3154  if (rULSpace.GetContext())
3155  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE);
3156  }
3157  }
3158  else if (m_rExport.GetRTFFlySyntax())
3159  {
3160  // Wrap: top and bottom spacing, convert from twips to EMUs.
3161  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3162  "dyWrapDistTop", OString::number(rULSpace.GetUpper() * 635)));
3163  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3164  "dyWrapDistBottom", OString::number(rULSpace.GetLower() * 635)));
3165  }
3166 }
3167 
3169 {
3170  if (m_rExport.m_bOutFlyFrameAttrs && !m_rExport.GetRTFFlySyntax())
3171  {
3172  css::text::WrapTextMode eSurround = rSurround.GetSurround();
3173  bool bGold = css::text::WrapTextMode_DYNAMIC == eSurround;
3174  if (bGold)
3175  eSurround = css::text::WrapTextMode_PARALLEL;
3176  RTFSurround aMC(bGold, static_cast<sal_uInt8>(eSurround));
3177  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
3178  m_aRunText->append(static_cast<sal_Int32>(aMC.GetValue()));
3179  }
3180  else if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3181  {
3182  // See DocxSdrExport::startDMLAnchorInline() for SwFormatSurround -> WR / WRK mappings.
3183  sal_Int32 nWr = -1;
3185  switch (rSurround.GetValue())
3186  {
3187  case css::text::WrapTextMode_NONE:
3188  nWr = 1; // top and bottom
3189  break;
3190  case css::text::WrapTextMode_THROUGH:
3191  nWr = 3; // none
3192  break;
3193  case css::text::WrapTextMode_PARALLEL:
3194  nWr = 2; // around
3195  oWrk = 0; // both sides
3196  break;
3197  case css::text::WrapTextMode_DYNAMIC:
3198  default:
3199  nWr = 2; // around
3200  oWrk = 3; // largest
3201  break;
3202  }
3203 
3204  if (rSurround.IsContour())
3205  nWr = 4; // tight
3206 
3207  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWR);
3208  m_rExport.OutLong(nWr);
3209  if (oWrk)
3210  {
3211  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWRK);
3212  m_rExport.OutLong(*oWrk);
3213  }
3214  }
3215 }
3216 
3218 {
3219  if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3220  {
3221  switch (rFlyVert.GetRelationOrient())
3222  {
3223  case text::RelOrientation::PAGE_FRAME:
3224  m_aFlyProperties.push_back(
3225  std::make_pair<OString, OString>("posrelv", OString::number(1)));
3226  break;
3227  default:
3228  m_aFlyProperties.push_back(
3229  std::make_pair<OString, OString>("posrelv", OString::number(2)));
3230  m_rExport.Strm()
3231  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYPARA)
3232  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
3233  break;
3234  }
3235 
3236  switch (rFlyVert.GetVertOrient())
3237  {
3238  case text::VertOrientation::TOP:
3239  case text::VertOrientation::LINE_TOP:
3240  m_aFlyProperties.push_back(
3241  std::make_pair<OString, OString>("posv", OString::number(1)));
3242  break;
3243  case text::VertOrientation::BOTTOM:
3244  case text::VertOrientation::LINE_BOTTOM:
3245  m_aFlyProperties.push_back(
3246  std::make_pair<OString, OString>("posv", OString::number(3)));
3247  break;
3248  case text::VertOrientation::CENTER:
3249  case text::VertOrientation::LINE_CENTER:
3250  m_aFlyProperties.push_back(
3251  std::make_pair<OString, OString>("posv", OString::number(2)));
3252  break;
3253  default:
3254  break;
3255  }
3256 
3257  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPTOP);
3258  m_rExport.OutLong(rFlyVert.GetPos());
3259  if (m_pFlyFrameSize)
3260  {
3261  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM);
3262  m_rExport.OutLong(rFlyVert.GetPos() + m_pFlyFrameSize->Height());
3263  }
3264  }
3265 }
3266 
3268 {
3269  if (m_rExport.m_bOutFlyFrameAttrs && m_rExport.GetRTFFlySyntax())
3270  {
3271  switch (rFlyHori.GetRelationOrient())
3272  {
3273  case text::RelOrientation::PAGE_FRAME:
3274  m_aFlyProperties.push_back(
3275  std::make_pair<OString, OString>("posrelh", OString::number(1)));
3276  break;
3277  default:
3278  m_aFlyProperties.push_back(
3279  std::make_pair<OString, OString>("posrelh", OString::number(2)));
3280  m_rExport.Strm()
3281  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN)
3282  .WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
3283  break;
3284  }
3285 
3286  switch (rFlyHori.GetHoriOrient())
3287  {
3288  case text::HoriOrientation::LEFT:
3289  m_aFlyProperties.push_back(
3290  std::make_pair<OString, OString>("posh", OString::number(1)));
3291  break;
3292  case text::HoriOrientation::CENTER:
3293  m_aFlyProperties.push_back(
3294  std::make_pair<OString, OString>("posh", OString::number(2)));
3295  break;
3296  case text::HoriOrientation::RIGHT:
3297  m_aFlyProperties.push_back(
3298  std::make_pair<OString, OString>("posh", OString::number(3)));
3299  break;
3300  default:
3301  break;
3302  }
3303 
3304  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPLEFT);
3305  m_rExport.OutLong(rFlyHori.GetPos());
3306  if (m_pFlyFrameSize)
3307  {
3308  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPRIGHT);
3309  m_rExport.OutLong(rFlyHori.GetPos() + m_pFlyFrameSize->Width());
3310  }
3311  }
3312 }
3313 
3315 {
3316  if (!m_rExport.GetRTFFlySyntax())
3317  {
3318  RndStdIds eId = rAnchor.GetAnchorId();
3319  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
3320  m_aRunText->append(static_cast<sal_Int32>(eId));
3321  switch (eId)
3322  {
3323  case RndStdIds::FLY_AT_PAGE:
3324  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
3325  m_aRunText->append(static_cast<sal_Int32>(rAnchor.GetPageNum()));
3326  break;
3327  case RndStdIds::FLY_AT_PARA:
3328  case RndStdIds::FLY_AS_CHAR:
3329  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
3330  break;
3331  default:
3332  break;
3333  }
3334  }
3335 }
3336 
3338 {
3339  if (m_rExport.GetRTFFlySyntax())
3340  {
3341  const Color& rColor = rBrush.GetColor();
3342  // We in fact need RGB to BGR, but the transformation is symmetric.
3343  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3344  "fillColor", OString::number(wwUtility::RGBToBGR(rColor))));
3345  }
3346  else if (!rBrush.GetColor().GetTransparency())
3347  {
3348  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CBPAT);
3349  m_aStyles.append(static_cast<sal_Int32>(m_rExport.GetColor(rBrush.GetColor())));
3350  }
3351 }
3352 
3354 {
3355  m_oFillStyle.reset(rFillStyle.GetValue());
3356 }
3357 
3359 {
3360  if (*m_oFillStyle == drawing::FillStyle_GRADIENT)
3361  {
3362  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3363  "fillType", OString::number(7))); // Shade using the fillAngle
3364 
3365  const XGradient& rGradient = rFillGradient.GetGradientValue();
3366  const Color& rStartColor = rGradient.GetStartColor();
3367  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3368  "fillBackColor", OString::number(wwUtility::RGBToBGR(rStartColor))));
3369 
3370  const Color& rEndColor = rGradient.GetEndColor();
3371  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3372  "fillColor", OString::number(wwUtility::RGBToBGR(rEndColor))));
3373 
3374  switch (rGradient.GetGradientStyle())
3375  {
3376  case css::awt::GradientStyle_LINEAR:
3377  break;
3378  case css::awt::GradientStyle_AXIAL:
3379  m_aFlyProperties.push_back(
3380  std::make_pair<OString, OString>("fillFocus", OString::number(50)));
3381  break;
3382  case css::awt::GradientStyle_RADIAL:
3383  case css::awt::GradientStyle_ELLIPTICAL:
3384  case css::awt::GradientStyle_SQUARE:
3385  case css::awt::GradientStyle_RECT:
3386  default:
3387  break;
3388  }
3389  }
3390 }
3391 
3393 {
3394  static const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
3395  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
3396  static const sal_Char* aBorderNames[]
3399 
3400  sal_uInt16 const nDist = rBox.GetSmallestDistance();
3401 
3402  if (m_rExport.GetRTFFlySyntax())
3403  {
3404  // Borders: spacing to contents, convert from twips to EMUs.
3405  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3406  "dxTextLeft", OString::number(rBox.GetDistance(SvxBoxItemLine::LEFT) * 635)));
3407  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3408  "dyTextTop", OString::number(rBox.GetDistance(SvxBoxItemLine::TOP) * 635)));
3409  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3410  "dxTextRight", OString::number(rBox.GetDistance(SvxBoxItemLine::RIGHT) * 635)));
3411  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3412  "dyTextBottom", OString::number(rBox.GetDistance(SvxBoxItemLine::BOTTOM) * 635)));
3413 
3414  const editeng::SvxBorderLine* pLeft = rBox.GetLine(SvxBoxItemLine::LEFT);
3415  const editeng::SvxBorderLine* pRight = rBox.GetLine(SvxBoxItemLine::RIGHT);
3416  const editeng::SvxBorderLine* pTop = rBox.GetLine(SvxBoxItemLine::TOP);
3417  const editeng::SvxBorderLine* pBottom = rBox.GetLine(SvxBoxItemLine::BOTTOM);
3418  if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop
3419  && *pLeft == *pBottom)
3420  {
3421  const Color& rColor = pTop->GetColor();
3422  // We in fact need RGB to BGR, but the transformation is symmetric.
3423  m_aFlyProperties.push_back(std::make_pair<OString, OString>(
3424  "lineColor", OString::number(wwUtility::RGBToBGR(rColor))));
3425 
3426  if (pTop->GetBorderLineStyle() != SvxBorderLineStyle::NONE)
3427  {
3428  double const fConverted(editeng::ConvertBorderWidthToWord(
3429  pTop->GetBorderLineStyle(), pTop->GetWidth()));
3430  sal_Int32 nWidth = fConverted * 635; // Twips -> EMUs
3431  m_aFlyProperties.push_back(
3432  std::make_pair<OString, OString>("lineWidth", OString::number(nWidth)));
3433  }
3434  else
3435  // No border: no line.
3436  m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0"));
3437  }
3438 
3439  return;
3440  }
3441 
3442  if (rBox.GetTop() && rBox.GetBottom() && rBox.GetLeft() && rBox.GetRight()
3443  && *rBox.GetTop() == *rBox.GetBottom() && *rBox.GetTop() == *rBox.GetLeft()
3444  && *rBox.GetTop() == *rBox.GetRight() && nDist == rBox.GetDistance(SvxBoxItemLine::TOP)
3445  && nDist == rBox.GetDistance(SvxBoxItemLine::LEFT)
3446  && nDist == rBox.GetDistance(SvxBoxItemLine::BOTTOM)
3447  && nDist == rBox.GetDistance(SvxBoxItemLine::RIGHT))
3448  m_aSectionBreaks.append(
3449  OutBorderLine(m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist));
3450  else
3451  {
3452  SvxShadowLocation eShadowLocation = SvxShadowLocation::NONE;
3453  if (const SfxPoolItem* pItem = GetExport().HasItem(RES_SHADOW))
3454  eShadowLocation = static_cast<const SvxShadowItem*>(pItem)->GetLocation();
3455 
3456  const SvxBoxItemLine* pBrd = aBorders;
3457  const sal_Char** pBrdNms = aBorderNames;
3458  for (int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
3459  {
3460  if (const editeng::SvxBorderLine* pLn = rBox.GetLine(*pBrd))
3461  {
3462  m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
3463  rBox.GetDistance(*pBrd), eShadowLocation));
3464  }
3465  }
3466  }
3467 
3468  if (!m_bBufferSectionBreaks)
3469  m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
3470 }
3471 
3472 void RtfAttributeOutput::FormatColumns_Impl(sal_uInt16 nCols, const SwFormatCol& rCol, bool bEven,
3473  SwTwips nPageSize)
3474 {
3475  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLS);
3476  m_rExport.OutLong(nCols);
3477 
3478  if (rCol.GetLineAdj() != COLADJ_NONE)
3479  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEBETCOL);
3480 
3481  if (bEven)
3482  {
3483  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSX);
3484  m_rExport.OutLong(rCol.GetGutterWidth(true));
3485  }
3486  else
3487  {
3488  const SwColumns& rColumns = rCol.GetColumns();
3489  for (sal_uInt16 n = 0; n < nCols;)
3490  {
3491  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLNO);
3492  m_rExport.OutLong(n + 1);
3493 
3494  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLW);
3495  m_rExport.OutLong(rCol.CalcPrtColWidth(n, nPageSize));
3496 
3497  if (++n != nCols)
3498  {
3499  m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSR);
3500  m_rExport.OutLong(rColumns[n - 1].GetRight() + rColumns[n].GetLeft());
3501  }
3502  }
3503  }
3504 }
3505 
3507 {
3508  if (rItem.GetValue())
3509  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
3510 }
3511 
3513 {
3514  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3515 }
3516 
3518 {
3519  if (!rNumbering.IsCount())
3520  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
3521 }
3522 
3524 {
3525  SvxFrameDirection nDir = rDirection.GetValue();
3526  if (nDir == SvxFrameDirection::Environment)
3527  nDir = GetExport().GetDefaultFrameDirection();
3528 
3529  if (m_rExport.m_bOutPageDescs)
3530  {
3531  if (nDir == SvxFrameDirection::Vertical_RL_TB)
3532  {
3533  m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_STEXTFLOW);
3534  m_aSectionBreaks.append(static_cast<sal_Int32>(1));
3535  if (!m_bBufferSectionBreaks)
3536  m_rExport.Strm().WriteOString(m_aSectionBreaks.makeStringAndClear());
3537  }
3538  return;
3539  }
3540 
3541  if (m_rExport.GetRTFFlySyntax())
3542  {
3543  if (nDir == SvxFrameDirection::Vertical_RL_TB)
3544  {
3545  // Top to bottom non-ASCII font
3546  m_aFlyProperties.push_back(std::make_pair<OString, OString>("txflTextFlow", "3"));
3547  }
3548  else if (rDirection.GetValue() == SvxFrameDirection::Vertical_LR_BT)
3549  {
3550  // Bottom to top non-ASCII font
3551  m_aFlyProperties.push_back(std::make_pair<OString, OString>("txflTextFlow", "2"));
3552  }
3553  return;
3554  }
3555 
3556  if (nDir == SvxFrameDirection::Horizontal_RL_TB)
3557  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
3558  else
3559  m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
3560 }
3561 
3563 {
3564  const std::map<OUString, css::uno::Any>& rMap = rItem.GetGrabBag();
3565  for (const auto& rValue : rMap)
3566  {
3567  if (rValue.first == "ParaTopMarginBeforeAutoSpacing")
3568  {
3569  m_bParaBeforeAutoSpacing = true;
3570  rValue.second >>= m_nParaBeforeSpacing;
3571  m_nParaBeforeSpacing = convertMm100ToTwip(m_nParaBeforeSpacing);
3572  }
3573  else if (rValue.first == "ParaBottomMarginAfterAutoSpacing")
3574  {
3575  m_bParaAfterAutoSpacing = true;
3576  rValue.second >>= m_nParaAfterSpacing;
3577  m_nParaAfterSpacing = convertMm100ToTwip(m_nParaAfterSpacing);
3578  }
3579  }
3580 }
3581 
3583 
3585 
3587 {
3588  OUString sCmd; // for optional Parameters
3589  switch (pField->GetTyp()->Which())
3590  {
3591  //#i119803# Export user field for RTF filter
3592  case SwFieldIds::User:
3593  sCmd = pField->GetTyp()->GetName();
3594  m_rExport.OutputField(pField, ww::eNONE, sCmd);
3595  break;
3596  default:
3597  m_rExport.OutputField(pField, ww::eUNKNOWN, sCmd);
3598  break;
3599  }
3600 }
3601 
3602 void RtfAttributeOutput::RefField(const SwField& /*rField*/, const OUString& /*rRef*/)
3603 {
3604  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3605 }
3606 
3608 {
3609  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3610 }
3611 
3612 void RtfAttributeOutput::SetField(const SwField& /*rField*/, ww::eField /*eType*/,
3613  const OUString& /*rCmd*/)
3614 {
3615  SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
3616 }
3617 
3619 {
3620  const SwPostItField& rPField = *static_cast<const SwPostItField*>(pField);
3621 
3622  OString aName = OUStringToOString(rPField.GetName(), RTL_TEXTENCODING_UTF8);
3623  auto it = m_rOpenedAnnotationMarksIds.find(aName);
3624  if (it != m_rOpenedAnnotationMarksIds.end())
3625  {
3626  // In case this field is inside annotation marks, we want to write the
3627  // annotation itself after the annotation mark is closed, not here.
3628  m_aPostitFields[it->second] = &rPField;
3629  return;
3630  }
3631 
3632  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
3633  m_aRunText->append(OUStringToOString(rPField.GetInitials(), m_rExport.GetCurrentEncoding()));
3634  m_aRunText->append("}");
3636  m_aRunText->append(OUStringToOString(rPField.GetPar1(), m_rExport.GetCurrentEncoding()));
3637  m_aRunText->append("}");
3638  m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN);
3639 
3641 
3642  if (m_nCurrentAnnotationMarkId != -1)
3643  {
3645  m_aRunText->append(m_nCurrentAnnotationMarkId);
3646  m_aRunText->append('}');
3647  }
3649  m_aRunText->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(rPField.GetDateTime())));
3650  m_aRunText->append('}');
3651  if (const OutlinerParaObject* pObject = rPField.GetTextObject())
3652  m_rExport.SdrExporter().WriteOutliner(*pObject, TXT_ATN);
3653  m_aRunText->append('}');
3654 }
3655 
3657 {
3658  // this is handled in OutputFlyFrame_Impl()
3659  return true;
3660 }
3661 
3663 {
3664  m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD
3666  " MACROBUTTON None ");
3667  RunText(pField->GetPar1());
3668  m_aRunText->append("}}");
3669  return false; // do not expand
3670 }
3671 
3673  : AttributeOutputBase("") // ConvertURL isn't used now in RTF output
3674  , m_rExport(rExport)
3675  , m_pPrevPageDesc(nullptr)
3676  , m_nStyleId(0)
3677  , m_nListId(0)
3678  , m_bIsRTL(false)
3679  , m_nScript(i18n::ScriptType::LATIN)
3680  , m_bControlLtrRtl(false)
3681  , m_nNextAnnotationMarkId(0)
3682  , m_nCurrentAnnotationMarkId(-1)
3683  , m_bTableCellOpen(false)
3684  , m_nTableDepth(0)
3685  , m_bTableAfterCell(false)
3686  , m_nColBreakNeeded(false)
3687  , m_bBufferSectionBreaks(false)
3688  , m_bBufferSectionHeaders(false)
3689  , m_bLastTable(true)
3690  , m_bWroteCellInfo(false)
3691  , m_bTableRowEnded(false)
3692  , m_bIsBeforeFirstParagraph(true)
3693  , m_bSingleEmptyRun(false)
3694  , m_bInRun(false)
3695  , m_pFlyFrameSize(nullptr)
3696  , m_bParaBeforeAutoSpacing(false)
3697  , m_nParaBeforeSpacing(0)
3698  , m_bParaAfterAutoSpacing(false)
3699  , m_nParaAfterSpacing(0)
3700 {
3701 }
3702 
3704 
3706 
3707 // These are used by wwFont::WriteRtf()
3708 
3710 void RtfAttributeOutput::StartFont(const OUString& rFamilyName) const
3711 {
3712  // write the font name hex-encoded, but without Unicode - Word at least
3713  // cannot read *both* Unicode and fallback as written by OutString
3715  msfilter::rtfutil::OutString(rFamilyName, m_rExport.GetCurrentEncoding(), false).getStr());
3716 }
3717 
3720 {
3721  m_rExport.Strm().WriteCharPtr(";}");
3723 }
3724 
3726 void RtfAttributeOutput::FontAlternateName(const OUString& rName) const
3727 {
3728  m_rExport.Strm()
3729  .WriteChar('{')
3732  .WriteChar(' ');
3733  // write the font name hex-encoded, but without Unicode - Word at least
3734  // cannot read *both* Unicode and fallback as written by OutString
3735  m_rExport.Strm()
3736  .WriteCharPtr(
3737  msfilter::rtfutil::OutString(rName, m_rExport.GetCurrentEncoding(), false).getStr())
3738  .WriteChar('}');
3739 }
3740 
3743 {
3745  m_rExport.OutULong(nCharSet);
3746  m_rExport.Strm().WriteChar(' ');
3747  m_rExport.SetCurrentEncoding(rtl_getTextEncodingFromWindowsCharset(nCharSet));
3748 }
3749 
3751 void RtfAttributeOutput::FontFamilyType(FontFamily eFamily, const wwFont& rFont) const
3752 {
3754 
3755  const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
3756  switch (eFamily)
3757  {
3758  case FAMILY_ROMAN:
3760  break;
3761  case FAMILY_SWISS:
3763  break;
3764  case FAMILY_MODERN:
3766  break;
3767  case FAMILY_SCRIPT:
3769  break;
3770  case FAMILY_DECORATIVE:
3772  break;
3773  default:
3774  break;
3775  }
3776  m_rExport.OutULong(m_rExport.m_aFontHelper.GetId(rFont)).WriteCharPtr(pStr);
3777 }
3778 
3781 {
3783 
3784  sal_uInt16 nVal = 0;
3785  switch (ePitch)
3786  {
3787  case PITCH_FIXED:
3788  nVal = 1;
3789  break;
3790  case PITCH_VARIABLE:
3791  nVal = 2;
3792  break;
3793  default:
3794  break;
3795  }
3796  m_rExport.OutULong(nVal);
3797 }
3798 
3799 static void lcl_AppendSP(OStringBuffer& rBuffer, const char cName[], const OUString& rValue,
3800  const RtfExport& rExport)
3801 {
3802  rBuffer.append("{" OOO_STRING_SVTOOLS_RTF_SP "{"); // "{\sp{"
3803  rBuffer.append(OOO_STRING_SVTOOLS_RTF_SN " "); //" \sn "
3804  rBuffer.append(cName); //"PropName"
3805  rBuffer.append("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
3806  // "}{ \sv "
3807  rBuffer.append(msfilter::rtfutil::OutString(rValue, rExport.GetCurrentEncoding()));
3808  rBuffer.append("}}");
3809 }
3810 
3811 static OString ExportPICT(const SwFlyFrameFormat* pFlyFrameFormat, const Size& rOrig,
3812  const Size& rRendered, const Size& rMapped, const SwCropGrf& rCr,
3813  const char* pBLIPType, const sal_uInt8* pGraphicAry, sal_uInt64 nSize,
3814  const RtfExport& rExport, SvStream* pStream = nullptr,
3815  bool bWritePicProp = true, const SwAttrSet* pAttrSet = nullptr)
3816 {
3817  OStringBuffer aRet;
3818  if (pBLIPType && nSize && pGraphicAry)
3819  {
3820  bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
3821 
3822  aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
3823 
3824  if (pFlyFrameFormat && bWritePicProp)
3825  {
3826  OUString sDescription = pFlyFrameFormat->GetObjDescription();
3827  //write picture properties - wzDescription at first
3828  //looks like: "{\*\picprop{\sp{\sn PropertyName}{\sv PropertyValue}}}"
3829  aRet.append(
3831  lcl_AppendSP(aRet, "wzDescription", sDescription, rExport);
3832  OUString sName = pFlyFrameFormat->GetObjTitle();
3833  lcl_AppendSP(aRet, "wzName", sName, rExport);
3834 
3835  if (pAttrSet)
3836  {
3837  MirrorGraph eMirror = pAttrSet->Get(RES_GRFATR_MIRRORGRF).GetValue();
3838  if (eMirror == MirrorGraph::Vertical || eMirror == MirrorGraph::Both)
3839  // Mirror on the vertical axis is a horizontal flip.
3840  lcl_AppendSP(aRet, "fFlipH", "1", rExport);
3841  }
3842 
3843  aRet.append("}"); //"}"
3844  }
3845 
3846  long nXCroppedSize = rOrig.Width() - (rCr.GetLeft() + rCr.GetRight());
3847  long nYCroppedSize = rOrig.Height() - (rCr.GetTop() + rCr.GetBottom());
3848  /* Graphic with a zero height or width, typically copied from webpages, caused crashes. */
3849  if (!nXCroppedSize)
3850  nXCroppedSize = 100;
3851  if (!nYCroppedSize)
3852  nYCroppedSize = 100;
3853 
3854  //Given the original size and taking cropping into account
3855  //first, how much has the original been scaled to get the
3856  //final rendered size
3857  aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
3858  aRet.append(static_cast<sal_Int32>((100 * rRendered.Width()) / nXCroppedSize));
3859  aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
3860  aRet.append(static_cast<sal_Int32>((100 * rRendered.Height()) / nYCroppedSize));
3861 
3862  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
3863  aRet.append(rCr.GetLeft());
3864  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
3865  aRet.append(rCr.GetRight());
3866  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
3867  aRet.append(rCr.GetTop());
3868  aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
3869  aRet.append(rCr.GetBottom());
3870 
3871  aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
3872  aRet.append(static_cast<sal_Int32>(rMapped.Width()));
3873  aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
3874  aRet.append(static_cast<sal_Int32>(rMapped.Height()));
3875 
3876  aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
3877  aRet.append(static_cast<sal_Int32>(rOrig.Width()));
3878  aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
3879  aRet.append(static_cast<sal_Int32>(rOrig.Height()));
3880 
3881  aRet.append(pBLIPType);
3882  if (bIsWMF)
3883  {
3884  aRet.append(sal_Int32(8));
3885  msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
3886  }
3887  aRet.append(SAL_NEWLINE_STRING);
3888  if (pStream)
3889  pStream->WriteOString(aRet.makeStringAndClear());
3890  if (pStream)
3891  msfilter::rtfutil::WriteHex(pGraphicAry, nSize, pStream);
3892  else
3893  aRet.append(msfilter::rtfutil::WriteHex(pGraphicAry, nSize));
3894  aRet.append('}');
3895  if (pStream)
3896  pStream->WriteOString(aRet.makeStringAndClear());
3897  }
3898  return aRet.makeStringAndClear();
3899 }
3900 
3902  SwOLENode& rOLENode, const Size& rSize)
3903 {
3905  Size aSize(rOLENode.GetTwipSize());
3906  Size aRendered(aSize);
3907  aRendered.setWidth(rSize.Width());
3908  aRendered.setHeight(rSize.Height());
3909  const Graphic* pGraphic = rOLENode.GetGraphic();
3910  Size aMapped(pGraphic->GetPrefSize());
3911  auto& rCr = static_cast<const SwCropGrf&>(rOLENode.GetAttr(RES_GRFATR_CROPGRF));
3912  const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
3913  const sal_uInt8* pGraphicAry = nullptr;
3914  SvMemoryStream aStream;
3915  if (GraphicConverter::Export(aStream, *pGraphic, ConvertDataFormat::PNG) != ERRCODE_NONE)
3916  SAL_WARN("sw.rtf", "failed to export the graphic");
3917  sal_uInt32 nSize = aStream.TellEnd();
3918  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
3919  m_aRunText->append(ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType,
3920  pGraphicAry, nSize, m_rExport));
3921  m_aRunText->append("}"); // shppict
3924  SvMemoryStream aWmfStream;
3925  if (GraphicConverter::Export(aWmfStream, *pGraphic, ConvertDataFormat::WMF) != ERRCODE_NONE)
3926  SAL_WARN("sw.rtf", "failed to export the graphic");
3927  nSize = aWmfStream.TellEnd();
3928  pGraphicAry = static_cast<sal_uInt8 const*>(aWmfStream.GetData());
3929  m_aRunText->append(ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType,
3930  pGraphicAry, nSize, m_rExport));
3931  m_aRunText->append("}"); // nonshppict
3932 }
3933 
3935  SwOLENode& rOLENode, const Size& rSize)
3936 {
3937  uno::Reference<embed::XEmbeddedObject> xObj(rOLENode.GetOLEObj().GetOleRef());
3938  sal_Int64 nAspect = rOLENode.GetAspect();
3939  svt::EmbeddedObjectRef aObjRef(xObj, nAspect);
3940  SvGlobalName aObjName(aObjRef->getClassID());
3941 
3942  if (!SotExchange::IsMath(aObjName))
3943  return false;
3944 
3946  uno::Reference<util::XCloseable> xClosable = xObj->getComponent();
3947  if (!xClosable.is())
3948  return false;
3949  // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
3950  // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
3951  // to RTLD_GLOBAL, so most probably a gcc bug.
3952  auto pBase
3953  = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xClosable.get()));
3954  assert(pBase != nullptr);
3955  OStringBuffer aBuf;
3956  if (pBase)
3957  pBase->writeFormulaRtf(aBuf, m_rExport.GetCurrentEncoding());
3958  m_aRunText->append(aBuf.makeStringAndClear());
3959  // Replacement graphic.
3961  FlyFrameOLEReplacement(pFlyFrameFormat, rOLENode, rSize);
3962  m_aRunText->append("}"); // mmathPict
3963  m_aRunText->append("}"); // mmath
3964 
3965  return true;
3966 }
3967 
3968 void RtfAttributeOutput::FlyFrameOLE(const SwFlyFrameFormat* pFlyFrameFormat, SwOLENode& rOLENode,
3969  const Size& rSize)
3970 {
3971  if (FlyFrameOLEMath(pFlyFrameFormat, rOLENode, rSize))
3972  return;
3973 
3974  FlyFrameOLEReplacement(pFlyFrameFormat, rOLENode, rSize);
3975 }
3976 
3978  const SwGrfNode* pGrfNode)
3979 {
3980  SvMemoryStream aStream;
3981  const sal_uInt8* pGraphicAry = nullptr;
3982  sal_uInt32 nSize = 0;
3983 
3984  const Graphic& rGraphic(pGrfNode->GetGrf());
3985 
3986  // If there is no graphic there is not much point in parsing it
3987  if (rGraphic.GetType() == GraphicType::NONE)
3988  return;
3989 
3990  ConvertDataFormat aConvertDestinationFormat = ConvertDataFormat::WMF;
3991  const sal_Char* pConvertDestinationBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
3992 
3993  GfxLink aGraphicLink;
3994  const sal_Char* pBLIPType = nullptr;
3995  if (rGraphic.IsGfxLink())
3996  {
3997  aGraphicLink = rGraphic.GetGfxLink();
3998  nSize = aGraphicLink.GetDataSize();
3999  pGraphicAry = aGraphicLink.GetData();
4000  switch (aGraphicLink.GetType())
4001  {
4002  // #i15508# trying to add BMP type for better exports, need to check if this works
4003  // checked, does not work. Also need to reset pGraphicAry to NULL to force conversion
4004  // to PNG, else the BMP array will be used.
4005  // It may work using direct DIB data, but that needs to be checked eventually
4006  //
4007  // #i15508# before GfxLinkType::NativeBmp was added the graphic data
4008  // (to be hold in pGraphicAry) was not available; thus for now to stay
4009  // compatible, keep it that way by assigning NULL value to pGraphicAry
4010  case GfxLinkType::NativeBmp:
4011  // pBLIPType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
4012  pGraphicAry = nullptr;
4013  break;
4014 
4015  case GfxLinkType::NativeJpg:
4016  pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
4017  break;
4018  case GfxLinkType::NativePng:
4019  pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
4020  break;
4021  case GfxLinkType::NativeWmf:
4022  pBLIPType = aGraphicLink.IsEMF() ? OOO_STRING_SVTOOLS_RTF_EMFBLIP
4024  break;
4025  case GfxLinkType::NativeGif:
4026  // GIF is not supported by RTF, but we override default conversion to WMF, PNG seems fits better here.
4027  aConvertDestinationFormat = ConvertDataFormat::PNG;
4028  pConvertDestinationBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
4029  break;
4030  default:
4031  break;
4032  }
4033  }
4034 
4035  GraphicType eGraphicType = rGraphic.GetType();
4036  if (!pGraphicAry)
4037  {
4038  if (ERRCODE_NONE
4039  == GraphicConverter::Export(aStream, rGraphic,
4040  (eGraphicType == GraphicType::Bitmap)
4041  ? ConvertDataFormat::PNG
4042  : ConvertDataFormat::WMF))
4043  {
4044  pBLIPType = (eGraphicType == GraphicType::Bitmap) ? OOO_STRING_SVTOOLS_RTF_PNGBLIP
4046  nSize = aStream.TellEnd();
4047  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4048  }
4049  }
4050 
4051  Size aMapped(eGraphicType == GraphicType::Bitmap ? rGraphic.GetSizePixel()
4052  : rGraphic.GetPrefSize());
4053 
4054  auto& rCr = static_cast<const SwCropGrf&>(pGrfNode->GetAttr(RES_GRFATR_CROPGRF));
4055 
4056  //Get original size in twips
4057  Size aSize(pGrfNode->GetTwipSize());
4058  Size aRendered(aSize);
4059 
4060  const SwFormatFrameSize& rS = pFlyFrameFormat->GetFrameSize();
4061  aRendered.setWidth(rS.GetWidth());
4062  aRendered.setHeight(rS.GetHeight());
4063 
4064  ww8::Frame* pFrame = nullptr;
4065  for (auto& rFrame : m_rExport.m_aFrames)
4066  {
4067  if (pFlyFrameFormat == &rFrame.GetFrameFormat())
4068  {
4069  pFrame = &rFrame;
4070  break;
4071  }
4072  }
4073 
4074  /*
4075  If the graphic is not of type WMF then we will have to store two
4076  graphics, one in the native format wrapped in shppict, and the other in
4077  the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
4078  a wmf already then we don't need any such wrapping
4079  */
4080  bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
4081  const SwAttrSet* pAttrSet = pGrfNode->GetpSwAttrSet();
4082  if (!pFrame || pFrame->IsInline())
4083  {
4084  if (!bIsWMF)
4087  }
4088  else
4089  {
4093  m_pFlyFrameSize = &aRendered;
4094  m_rExport.m_pParentFrame = pFrame;
4096  m_rExport.SetRTFFlySyntax(true);
4097  m_rExport.OutputFormat(pFrame->GetFrameFormat(), false, false, true);
4099  m_rExport.SetRTFFlySyntax(false);
4100  m_rExport.m_pParentFrame = nullptr;
4101  m_pFlyFrameSize = nullptr;
4102 
4103  std::vector<std::pair<OString, OString>> aFlyProperties;
4104  aFlyProperties.push_back(std::make_pair<OString, OString>(
4105  "shapeType", OString::number(ESCHER_ShpInst_PictureFrame)));
4106  aFlyProperties.push_back(std::make_pair<OString, OString>(
4107  "wzDescription", msfilter::rtfutil::OutString(pFlyFrameFormat->GetObjDescription(),
4109  aFlyProperties.push_back(std::make_pair<OString, OString>(
4110  "wzName", msfilter::rtfutil::OutString(pFlyFrameFormat->GetObjTitle(),
4112 
4113  // If we have a wrap polygon, then handle that here.
4114  if (pFlyFrameFormat->GetSurround().IsContour())
4115  {
4116  if (const SwNoTextNode* pNd
4117  = sw::util::GetNoTextNodeFromSwFrameFormat(*pFlyFrameFormat))
4118  {
4119  const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
4120  if (pPolyPoly && pPolyPoly->Count())
4121  {
4122  tools::Polygon aPoly
4123  = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd);
4124  OStringBuffer aVerticies;
4125  for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
4126  aVerticies.append(";(")
4127  .append(aPoly[i].X())
4128  .append(",")
4129  .append(aPoly[i].Y())
4130  .append(")");
4131  aFlyProperties.push_back(std::make_pair<OString, OString>(
4132  "pWrapPolygonVertices",
4133  "8;" + OString::number(aPoly.GetSize()) + aVerticies.makeStringAndClear()));
4134  }
4135  }
4136  }
4137 
4138  // Below text, behind document, opaque: they all refer to the same thing.
4139  if (!pFlyFrameFormat->GetOpaque().GetValue())
4140  aFlyProperties.push_back(std::make_pair<OString, OString>("fBehindDocument", "1"));
4141 
4142  if (pAttrSet)
4143  {
4144  if (sal_Int32 nRot = pAttrSet->Get(RES_GRFATR_ROTATION).GetValue())
4145  {
4146  // See writerfilter::rtftok::RTFSdrImport::applyProperty(),
4147  // positive rotation angles are clockwise in RTF, we have them
4148  // as counter-clockwise.
4149  // Additionally, RTF type is 0..360*2^16, our is 0..360*10.
4150  nRot = nRot * -1 * RTF_MULTIPLIER / 10;
4151  aFlyProperties.emplace_back("rotation", OString::number(nRot));
4152  }
4153  }
4154 
4155  for (const std::pair<OString, OString>& rPair : aFlyProperties)
4156  {
4159  m_rExport.Strm().WriteOString(rPair.first);
4161  m_rExport.Strm().WriteOString(rPair.second);
4162  m_rExport.Strm().WriteCharPtr("}}");
4163  }
4165  " pib"
4166  "}{" OOO_STRING_SVTOOLS_RTF_SV " ");
4167  }
4168 
4169  bool bWritePicProp = !pFrame || pFrame->IsInline();
4170  if (pBLIPType)
4171  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
4172  m_rExport, &m_rExport.Strm(), bWritePicProp, pAttrSet);
4173  else
4174  {
4175  aStream.Seek(0);
4176  if (GraphicConverter::Export(aStream, rGraphic, aConvertDestinationFormat) != ERRCODE_NONE)
4177  SAL_WARN("sw.rtf", "failed to export the graphic");
4178  pBLIPType = pConvertDestinationBLIPType;
4179  nSize = aStream.TellEnd();
4180  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4181 
4182  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize,
4183  m_rExport, &m_rExport.Strm(), bWritePicProp, pAttrSet);
4184  }
4185 
4186  if (!pFrame || pFrame->IsInline())
4187  {
4188  if (!bIsWMF)
4189  {
4192 
4193  aStream.Seek(0);
4194  if (GraphicConverter::Export(aStream, rGraphic, ConvertDataFormat::WMF) != ERRCODE_NONE)
4195  SAL_WARN("sw.rtf", "failed to export the graphic");
4197  nSize = aStream.TellEnd();
4198  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4199 
4200  ExportPICT(pFlyFrameFormat, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry,
4201  nSize, m_rExport, &m_rExport.Strm());
4202 
4203  m_rExport.Strm().WriteChar('}');
4204  }
4205  }
4206  else
4207  m_rExport.Strm().WriteCharPtr("}}}}"); // Close SV, SP, SHPINST and SHP.
4208 
4210 }
4211 
4212 void RtfAttributeOutput::BulletDefinition(int /*nId*/, const Graphic& rGraphic, Size aSize)
4213 {
4216 
4218  m_rExport.OutULong(aSize.Width());
4220  m_rExport.OutULong(aSize.Height());
4221 
4223  const sal_uInt8* pGraphicAry = nullptr;
4224  SvMemoryStream aStream;
4225  if (GraphicConverter::Export(aStream, rGraphic, ConvertDataFormat::PNG) != ERRCODE_NONE)
4226  SAL_WARN("sw.rtf", "failed to export the numbering picture bullet");
4227  sal_uInt32 nSize = aStream.TellEnd();
4228  pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
4229  msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &m_rExport.Strm());
4230  m_rExport.Strm().WriteCharPtr("}}"); // pict, shppict
4231 }
4232 
4233 /* 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:1084
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:136
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:93
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:3157
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
#define RES_CHRATR_FONTSIZE
Definition: hintids.hxx:77
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:161
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:79
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:112
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:177
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:74
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:87
#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:127
#define OOO_STRING_SVTOOLS_RTF_FOOTNOTE
#define OOO_STRING_SVTOOLS_RTF_FROMAN
#define RES_SHADOW
Definition: hintids.hxx:214
#define RES_CHRATR_WORDLINEMODE
Definition: hintids.hxx:85
#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:280
const SwPageDesc * FindPageDesc(size_t *pPgDescNdIdx=nullptr) const
Search PageDesc with which this node is formatted.
Definition: node.cxx:464
#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:913
#define OOO_STRING_SVTOOLS_RTF_FORMFIELD
SvStream & Strm()
Definition: rtfexport.cxx:1062
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:1798
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:119
#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
SvStream & WriteOString(const OString &rStr)
#define OOO_STRING_SVTOOLS_RTF_RTLPAR
bool IsEndNote() const
Definition: fmtftn.hxx:74
#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:91
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:92
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:172
#define OOO_STRING_SVTOOLS_RTF_MARGRSXN
#define OOO_STRING_SVTOOLS_RTF_RTLROW
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2588
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:4097
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:241
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:263
#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:86
sal_uInt16 sal_Unicode
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
bool IsRestartEachPage() const
Definition: lineinfo.hxx:89
const Color & GetColor() const
RedlineType GetType() const
Definition: redline.hxx:125
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.
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:97
#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:759
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:152
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.