LibreOffice Module sw (master)  1
writerwordglue.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 <msfilter.hxx>
21 #include "writerwordglue.hxx"
22 #include <doc.hxx>
23 #include "writerhelper.hxx"
25 
26 #include <algorithm>
27 
28 #include <rtl/tencinfo.h>
29 #include <sal/log.hxx>
30 
31 #include <unicode/ubidi.h>
32 #include <tools/tenccvt.hxx>
33 #include <com/sun/star/i18n/ScriptType.hpp>
34 #include <com/sun/star/i18n/XBreakIterator.hpp>
35 
36 #include <unotools/fontcvt.hxx>
37 #include <editeng/paperinf.hxx>
38 #include <editeng/lrspitem.hxx>
39 #include <editeng/ulspitem.hxx>
40 #include <editeng/boxitem.hxx>
41 #include <editeng/fontitem.hxx>
42 #include <frmfmt.hxx>
43 #include <fmtclds.hxx>
44 #include <hfspacingitem.hxx>
45 #include <fmtfsize.hxx>
46 #include <poolfmt.hxx>
47 #include <swrect.hxx>
48 #include <fmthdft.hxx>
49 #include <frmatr.hxx>
50 #include <ndtxt.hxx>
51 #include <breakit.hxx>
52 #include <i18nlangtag/mslangid.hxx>
53 
54 using namespace css;
55 
56 namespace myImplHelpers
57 {
58  static SwTwips CalcHdFtDist(const SwFrameFormat& rFormat, sal_uInt16 nSpacing)
59  {
60  /*
61  The normal case for reexporting word docs is to have dynamic spacing,
62  as this is word's only setting, and the reason for the existence of the
63  dynamic spacing features. If we have dynamic spacing active then we can
64  add its spacing to the value height of the h/f and get the wanted total
65  size for word.
66 
67  Otherwise we have to get the real layout rendered
68  height, which is totally nonoptimum, but the best we can do.
69  */
70  long nDist=0;
71  const SwFormatFrameSize& rSz = rFormat.GetFrameSize();
72 
73  const SwHeaderAndFooterEatSpacingItem &rSpacingCtrl =
74  sw::util::ItemGet<SwHeaderAndFooterEatSpacingItem>
76  if (rSpacingCtrl.GetValue())
77  nDist += rSz.GetHeight();
78  else
79  {
80  SwRect aRect(rFormat.FindLayoutRect());
81  if (aRect.Height())
82  nDist += aRect.Height();
83  else
84  {
85  const SwFormatFrameSize& rSize = rFormat.GetFrameSize();
86  if (ATT_VAR_SIZE != rSize.GetHeightSizeType())
87  nDist += rSize.GetHeight();
88  else
89  {
90  nDist += 274; // default for 12pt text
91  nDist += nSpacing;
92  }
93  }
94  }
95  return nDist;
96  }
97 
98  static SwTwips CalcHdDist(const SwFrameFormat& rFormat)
99  {
100  return CalcHdFtDist(rFormat, rFormat.GetULSpace().GetUpper());
101  }
102 
103  static SwTwips CalcFtDist(const SwFrameFormat& rFormat)
104  {
105  return CalcHdFtDist(rFormat, rFormat.GetULSpace().GetLower());
106  }
107 
108  /*
109  SwTextFormatColl and SwCharFormat are quite distinct types and how they are
110  gotten is also distinct, but the algorithm to match word's equivalents into
111  them is the same, so we put the different stuff into two separate helper
112  implementations and a core template that uses the helpers that uses the
113  same algorithm to do the work. We'll make the helpers specializations of a
114  non existing template so I can let the compiler figure out the right one
115  to use from a simple argument to the algorithm class
116  */
117  template <class C> class MapperImpl;
118  template<> class MapperImpl<SwTextFormatColl>
119  {
120  private:
122  public:
123  MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
124  SwTextFormatColl* GetBuiltInStyle(ww::sti eSti);
125  SwTextFormatColl* GetStyle(const OUString &rName);
126  SwTextFormatColl* MakeStyle(const OUString &rName);
127  };
128 
130  {
132  static const RES_POOL_COLLFMT_TYPE aArr[]=
133  {
140  RES_POOLCOLL_TOX_IDX3, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
141  RES_NONE, RES_NONE, RES_POOLCOLL_TOX_CNTNT1,
147  RES_POOLCOLL_FOOTER, RES_POOLCOLL_TOX_IDXH, RES_NONE, RES_NONE,
149  RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_ENDNOTE,
150  RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_LISTS_BEGIN,
151  RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
152  RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
153  RES_NONE, RES_NONE, RES_POOLCOLL_HEADLINE_BASE, RES_NONE,
155  RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
156  RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL
157  };
158 
159  OSL_ENSURE(SAL_N_ELEMENTS(aArr) == 75, "Style Array has false size");
160 
161  SwTextFormatColl* pRet = nullptr;
162  //If this is a built-in word style that has a built-in writer
163  //equivalent, then map it to one of our built in styles regardless
164  //of its name
165  if (sal::static_int_cast< size_t >(eSti) < SAL_N_ELEMENTS(aArr) && aArr[eSti] != RES_NONE)
166  pRet = mrDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( static_cast< sal_uInt16 >(aArr[eSti]), false);
167  return pRet;
168  }
169 
171  {
172  return sw::util::GetParaStyle(mrDoc, rName);
173  }
174 
176  {
177  return mrDoc.MakeTextFormatColl(rName,
178  mrDoc.GetDfltTextFormatColl());
179  }
180 
181  template<> class MapperImpl<SwCharFormat>
182  {
183  private:
185  public:
186  MapperImpl(SwDoc &rDoc) : mrDoc(rDoc) {}
187  SwCharFormat* GetBuiltInStyle(ww::sti eSti);
188  SwCharFormat* GetStyle(const OUString &rName);
189  SwCharFormat* MakeStyle(const OUString &rName);
190  };
191 
193  {
195  switch (eSti)
196  {
197  case ww::stiFootnoteRef:
198  eLookup = RES_POOLCHR_FOOTNOTE;
199  break;
200  case ww::stiLnn:
201  eLookup = RES_POOLCHR_LINENUM;
202  break;
203  case ww::stiPgn:
204  eLookup = RES_POOLCHR_PAGENO;
205  break;
206  case ww::stiEdnRef:
207  eLookup = RES_POOLCHR_ENDNOTE;
208  break;
209  case ww::stiHyperlink:
210  eLookup = RES_POOLCHR_INET_NORMAL;
211  break;
213  eLookup = RES_POOLCHR_INET_VISIT;
214  break;
215  case ww::stiStrong:
216  eLookup = RES_POOLCHR_HTML_STRONG;
217  break;
218  case ww::stiEmphasis:
219  eLookup = RES_POOLCHR_HTML_EMPHASIS;
220  break;
221  default:
222  eLookup = RES_POOLCHR_NORMAL_END;
223  break;
224  }
225  SwCharFormat *pRet = nullptr;
226  if (eLookup != RES_POOLCHR_NORMAL_END)
227  pRet = mrDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool( static_cast< sal_uInt16 >(eLookup) );
228  return pRet;
229  }
230 
232  {
233  return sw::util::GetCharStyle(mrDoc, rName);
234  }
235 
237  {
238  return mrDoc.MakeCharFormat(rName, mrDoc.GetDfltCharFormat());
239  }
240 
241  template<class C> class StyleMapperImpl
242  {
243  private:
245  std::set<const C*> maUsedStyles;
246  C* MakeNonCollidingStyle(const OUString& rName);
247  public:
248  typedef std::pair<C*, bool> StyleResult;
249  explicit StyleMapperImpl(SwDoc &rDoc) : maHelper(rDoc) {}
250  StyleResult GetStyle(const OUString& rName, ww::sti eSti);
251  };
252 
253  template<class C>
254  typename StyleMapperImpl<C>::StyleResult
255  StyleMapperImpl<C>::GetStyle(const OUString& rName, ww::sti eSti)
256  {
257  C *pRet = maHelper.GetBuiltInStyle(eSti);
258 
259  //If we've used it once, don't reuse it
260  if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
261  pRet = nullptr;
262 
263  if (!pRet)
264  {
265  pRet = maHelper.GetStyle(rName);
266  //If we've used it once, don't reuse it
267  if (pRet && (maUsedStyles.end() != maUsedStyles.find(pRet)))
268  pRet = nullptr;
269  }
270 
271  bool bStyExist = pRet != nullptr;
272 
273  if (!pRet)
274  {
275  OUString aName(rName);
276  sal_Int32 nIdx = rName.indexOf(',');
277  // No commas allow in SW style names
278  if (-1 != nIdx)
279  aName = rName.copy( 0, nIdx );
280  pRet = MakeNonCollidingStyle( aName );
281  }
282 
283  if (pRet)
284  maUsedStyles.insert(pRet);
285 
286  return StyleResult(pRet, bStyExist);
287  }
288 
289  template<class C>
291  {
292  OUString aName(rName);
293  C* pColl = 0;
294 
295  if (0 != (pColl = maHelper.GetStyle(aName)))
296  {
297  //If the style collides first stick WW- in front of it, unless
298  //it already has it and then successively add a larger and
299  //larger number after it, its got to work at some stage!
300  if (!aName.startsWith("WW-"))
301  aName = "WW-" + aName;
302 
303  sal_Int32 nI = 1;
304  OUString aBaseName = aName;
305  while (
306  0 != (pColl = maHelper.GetStyle(aName)) &&
307  (nI < SAL_MAX_INT32)
308  )
309  {
310  aName = aBaseName + OUString::number(nI++);
311  }
312  }
313 
314  return pColl ? 0 : maHelper.MakeStyle(aName);
315  }
316 
317  static OUString FindBestMSSubstituteFont(const OUString &rFont)
318  {
319  if (IsStarSymbol(rFont))
320  return OUString("Arial Unicode MS");
321  return GetSubsFontName(rFont, SubsFontFlags::ONLYONE | SubsFontFlags::MS);
322  }
323 
324  //Utility to remove entries before a given starting position
326  {
327  private:
328  sal_Int32 const mnStart;
329  public:
330  explicit IfBeforeStart(sal_Int32 nStart) : mnStart(nStart) {}
331  bool operator()(const sw::util::CharRunEntry &rEntry) const
332  {
333  return rEntry.mnEndPos < mnStart;
334  }
335  };
336 }
337 
340 {
341  SvxLRSpaceItem aLR(rFormat.GetLRSpace());
342  const SvxBoxItem& rBox = rFormat.GetBox();
343 
344  aLR.SetLeft(aLR.GetLeft() + rBox.GetDistance(SvxBoxItemLine::LEFT));
345  if (const editeng::SvxBorderLine* pLeft = rBox.GetLeft())
346  aLR.SetLeft(aLR.GetLeft() + pLeft->GetWidth());
347 
348  aLR.SetRight(aLR.GetRight() + rBox.GetDistance(SvxBoxItemLine::RIGHT));
349  if (const editeng::SvxBorderLine* pRight = rBox.GetRight())
350  aLR.SetRight(aLR.GetRight() + pRight->GetWidth());
351 
352  return aLR;
353 }
354 
355 namespace sw
356 {
357  namespace util
358  {
359 
360  bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
361  {
362  bool bPlausableSingleWordSection = true;
363 
364  const SwFormatCol& rFirstCols = rTitleFormat.GetCol();
365  const SwFormatCol& rFollowCols = rFollowFormat.GetCol();
366  const SwColumns& rFirstColumns = rFirstCols.GetColumns();
367  const SwColumns& rFollowColumns = rFollowCols.GetColumns();
368  SvxLRSpaceItem aOneLR = lcl_getWordLRSpace(rTitleFormat);
369  SvxLRSpaceItem aTwoLR = lcl_getWordLRSpace(rFollowFormat);
370  const SwFormatFrameSize& rFirstFrameSize = rTitleFormat.GetFrameSize();
371  const SwFormatFrameSize& rFollowFrameSize = rFollowFormat.GetFrameSize();
372 
373  if (rFirstColumns.size() != rFollowColumns.size())
374  {
375  //e.g. #i4320#
376  bPlausableSingleWordSection = false;
377  }
378  else if (aOneLR != aTwoLR)
379  bPlausableSingleWordSection = false;
380  else if (rFirstFrameSize != rFollowFrameSize)
381  bPlausableSingleWordSection = false;
382  else
383  {
384  HdFtDistanceGlue aOne(rTitleFormat.GetAttrSet());
385  HdFtDistanceGlue aTwo(rFollowFormat.GetAttrSet());
386  //e.g. #i14509#
387  if (!aOne.StrictEqualTopBottom(aTwo))
388  bPlausableSingleWordSection = false;
389  }
390  return bPlausableSingleWordSection;
391  }
392 
393  HdFtDistanceGlue::HdFtDistanceGlue(const SfxItemSet &rPage)
394  {
395  if (const SvxBoxItem *pBox = rPage.GetItem<SvxBoxItem>(RES_BOX))
396  {
397  dyaHdrTop = pBox->CalcLineSpace( SvxBoxItemLine::TOP, /*bEvenIfNoLine*/true );
398  dyaHdrBottom = pBox->CalcLineSpace( SvxBoxItemLine::BOTTOM, /*bEvenIfNoLine*/true );
399  }
400  else
401  {
402  dyaHdrTop = dyaHdrBottom = 0;
403  }
404  const SvxULSpaceItem &rUL =
405  ItemGet<SvxULSpaceItem>(rPage, RES_UL_SPACE);
406  dyaHdrTop += rUL.GetUpper();
407  dyaHdrBottom += rUL.GetLower();
408 
409  dyaTop = dyaHdrTop;
410  dyaBottom = dyaHdrBottom;
411 
412  const SwFormatHeader *pHd = rPage.GetItem<SwFormatHeader>(RES_HEADER);
413  if (pHd && pHd->IsActive() && pHd->GetHeaderFormat())
414  {
415  mbHasHeader = true;
416  dyaTop = dyaTop + static_cast< sal_uInt16 >( (myImplHelpers::CalcHdDist(*(pHd->GetHeaderFormat()))) );
417  }
418  else
419  mbHasHeader = false;
420 
421  const SwFormatFooter *pFt = rPage.GetItem<SwFormatFooter>(RES_FOOTER);
422  if (pFt && pFt->IsActive() && pFt->GetFooterFormat())
423  {
424  mbHasFooter = true;
425  dyaBottom = dyaBottom + static_cast< sal_uInt16 >( (myImplHelpers::CalcFtDist(*(pFt->GetFooterFormat()))) );
426  }
427  else
428  mbHasFooter = false;
429  }
430 
431  bool HdFtDistanceGlue::StrictEqualTopBottom(const HdFtDistanceGlue &rOther)
432  const
433  {
434  // Check top only if both object have a header or if
435  // both object don't have a header
436  if (HasHeader() == rOther.HasHeader())
437  {
438  if (dyaTop != rOther.dyaTop)
439  return false;
440  }
441 
442  // Check bottom only if both object have a footer or if
443  // both object don't have a footer
444  if (HasFooter() == rOther.HasFooter())
445  {
446  if (dyaBottom != rOther.dyaBottom)
447  return false;
448  }
449 
450  return true;
451  }
452 
453  ParaStyleMapper::ParaStyleMapper(SwDoc &rDoc)
454  : mpImpl(new myImplHelpers::StyleMapperImpl<SwTextFormatColl>(rDoc))
455  {
456  }
457 
459  {
460  }
461 
463  const OUString& rName, ww::sti eSti)
464  {
465  return mpImpl->GetStyle(rName, eSti);
466  }
467 
469  : mpImpl(new myImplHelpers::StyleMapperImpl<SwCharFormat>(rDoc))
470  {
471  }
472 
474  {
475  }
476 
478  const OUString& rName, ww::sti eSti)
479  {
480  return mpImpl->GetStyle(rName, eSti);
481  }
482 
483  FontMapExport::FontMapExport(const OUString &rFamilyName)
484  {
485  sal_Int32 nIndex = 0;
486  msPrimary = GetNextFontToken(rFamilyName, nIndex);
488  if (msSecondary.isEmpty() && nIndex != -1)
489  msSecondary = GetNextFontToken(rFamilyName, nIndex);
490  }
491 
492  bool ItemSort::operator()(sal_uInt16 nA, sal_uInt16 nB) const
493  {
494  /*
495  #i24291#
496  All we want to do is ensure for now is that if a charfmt exist
497  in the character properties that it rises to the top and is
498  exported first. In the future we might find more ordering
499  dependencies for export, in which case this is the place to do
500  it
501  */
502  if (nA == nB)
503  return false;
504  if (nA == RES_TXTATR_CHARFMT)
505  return true;
506  if (nB == RES_TXTATR_CHARFMT)
507  return false;
508  if (nA == RES_TXTATR_INETFMT)
509  return true;
510  if (nB == RES_TXTATR_INETFMT)
511  return false;
512  return nA < nB;
513  }
514 
516  {
517  const OUString &rText = rTextNd.GetText();
518 
519  bool bParaIsRTL = false;
520  OSL_ENSURE(rTextNd.GetDoc(), "No document for node?, suspicious");
521  if (rTextNd.GetDoc())
522  {
523  if (SvxFrameDirection::Horizontal_RL_TB ==
524  rTextNd.GetDoc()->GetTextDirection(SwPosition(rTextNd)))
525  {
526  bParaIsRTL = true;
527  }
528  }
529 
530  using namespace ::com::sun::star::i18n;
531 
532  sal_uInt16 nScript = i18n::ScriptType::LATIN;
533  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
534  if (!rText.isEmpty())
535  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, 0);
536 
537  rtl_TextEncoding eChrSet = ItemGet<SvxFontItem>(rTextNd,
538  GetWhichOfScript(RES_CHRATR_FONT, nScript)).GetCharSet();
539  eChrSet = GetExtendedTextEncoding(eChrSet);
540 
541  CharRuns aRunChanges;
542 
543  if (rText.isEmpty())
544  {
545  aRunChanges.emplace_back(0, nScript, eChrSet,
546  bParaIsRTL);
547  return aRunChanges;
548  }
549 
550  typedef std::pair<int32_t, bool> DirEntry;
551  typedef std::vector<DirEntry> DirChanges;
552 
553  typedef std::pair<sal_Int32, sal_uInt16> ScriptEntry;
554  typedef std::vector<ScriptEntry> ScriptChanges;
555 
556  DirChanges aDirChanges;
557  ScriptChanges aScripts;
558 
559  UBiDiDirection eDefaultDir = bParaIsRTL ? UBIDI_RTL : UBIDI_LTR;
560  UErrorCode nError = U_ZERO_ERROR;
561  UBiDi* pBidi = ubidi_openSized(rText.getLength(), 0, &nError);
562  ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(rText.getStr()), rText.getLength(),
563  static_cast< UBiDiLevel >(eDefaultDir), nullptr, &nError);
564 
565  sal_Int32 nCount = ubidi_countRuns(pBidi, &nError);
566  aDirChanges.reserve(nCount);
567 
568  int32_t nStart = 0;
569  int32_t nEnd;
570  UBiDiLevel nCurrDir;
571 
572  for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
573  {
574  ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
575  /*
576  UBiDiLevel is the type of the level values in this BiDi
577  implementation.
578 
579  It holds an embedding level and indicates the visual direction
580  by its bit 0 (even/odd value).
581 
582  The value for UBIDI_DEFAULT_LTR is even and the one for
583  UBIDI_DEFAULT_RTL is odd
584  */
585  aDirChanges.emplace_back(nEnd, nCurrDir & 0x1);
586  nStart = nEnd;
587  }
588  ubidi_close(pBidi);
589 
590  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
591 
592  sal_Int32 nLen = rText.getLength();
593  sal_Int32 nPos = 0;
594  while (nPos < nLen)
595  {
596  sal_Int32 nEnd2 = g_pBreakIt->GetBreakIter()->endOfScript(rText, nPos,
597  nScript);
598  if (nEnd2 < 0)
599  break;
600  nPos = nEnd2;
601  aScripts.emplace_back(nPos, nScript);
602  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, nPos);
603  }
604 
605  auto aBiDiEnd = aDirChanges.cend();
606  auto aScriptEnd = aScripts.cend();
607 
608  auto aBiDiIter = aDirChanges.cbegin();
609  auto aScriptIter = aScripts.cbegin();
610 
611  bool bCharIsRTL = bParaIsRTL;
612 
613  while (
614  aBiDiIter != aBiDiEnd ||
615  aScriptIter != aScriptEnd
616  )
617  {
618  sal_Int32 nMinPos = rText.getLength();
619 
620  if (aBiDiIter != aBiDiEnd)
621  {
622  if (aBiDiIter->first < nMinPos)
623  nMinPos = aBiDiIter->first;
624  bCharIsRTL = aBiDiIter->second;
625  }
626 
627  if (aScriptIter != aScriptEnd)
628  {
629  if (aScriptIter->first < nMinPos)
630  nMinPos = aScriptIter->first;
631  nScript = aScriptIter->second;
632  }
633 
634  aRunChanges.emplace_back(nMinPos, nScript, eChrSet, bCharIsRTL);
635 
636  if (aBiDiIter != aBiDiEnd)
637  {
638  if (aBiDiIter->first == nMinPos)
639  ++aBiDiIter;
640  }
641 
642  if (aScriptIter != aScriptEnd)
643  {
644  if (aScriptIter->first == nMinPos)
645  ++aScriptIter;
646  }
647  }
648 
649  aRunChanges.erase(std::remove_if(aRunChanges.begin(),
650  aRunChanges.end(), myImplHelpers::IfBeforeStart(0/*nTextStart*/)), aRunChanges.end());
651 
652  return aRunChanges;
653  }
654  }
655 
656  namespace ms
657  {
658  sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
659  {
660  sal_uInt8 nRet =
661  rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
662  switch (eTextEncoding)
663  {
664  case RTL_TEXTENCODING_DONTKNOW:
665  case RTL_TEXTENCODING_UCS2:
666  case RTL_TEXTENCODING_UTF7:
667  case RTL_TEXTENCODING_UTF8:
668  case RTL_TEXTENCODING_JAVA_UTF8:
669  nRet = 0x01;
670  break;
671  default:
672  break;
673  }
674  return nRet;
675  }
676 
677  static bool
678  CanEncode(OUString const& rString, rtl_TextEncoding const eEncoding)
679  {
680  OString tmp;
681  return rString.convertToString(&tmp, eEncoding,
682  RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
683  RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
684  }
685 
687  OUString const& rFontName, OUString const& rAltName,
688  rtl_TextEncoding eTextEncoding)
689  {
690  sal_uInt8 nRet =
691  rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
692  rtl_TextEncoding enc2 = rtl_getTextEncodingFromWindowsCharset(nRet);
693  if (!rtl_isOctetTextEncoding(enc2) /* check to avoid asserts */ ||
694  !(CanEncode(rFontName, enc2) && CanEncode(rAltName, enc2)))
695  {
696  static struct { rtl_TextEncoding enc; sal_uInt8 charset; }
697  const s_fallbacks [] = {
698  { RTL_TEXTENCODING_MS_932, 0x80 }, // Shift-JIS
699  { RTL_TEXTENCODING_MS_936, 0x86 }, // GB-2312
700  { RTL_TEXTENCODING_MS_950, 0x88 }, // Big5
701  { RTL_TEXTENCODING_MS_949, 0x81 }, // EUC-KR
702  };
703  for (const auto & i : s_fallbacks)
704  {
705  // fall back to a charset that can at least encode the
706  // font's name
707  if (CanEncode(rFontName, i.enc)
708  && CanEncode(rAltName, i.enc))
709  {
710  return i.charset;
711  }
712  }
713  SAL_INFO("sw.rtf", "no fallback charset found for font: "
714  << rFontName << " " << rAltName);
715  nRet = 0x01; // all hope lost: "default", whatever that is
716  }
717  return nRet;
718  }
719 
720  sal_uInt32 DateTime2DTTM( const DateTime& rDT )
721  {
722  /*
723  mint short :6 0000003F minutes (0-59)
724  hr short :5 000007C0 hours (0-23)
725  dom short :5 0000F800 days of month (1-31)
726  mon short :4 000F0000 months (1-12)
727  yr short :9 1FF00000 years (1900-2411)-1900
728  wdy short :3 E0000000 weekday(Sunday=0
729  Monday=1
730  ( wdy can be ignored ) Tuesday=2
731  Wednesday=3
732  Thursday=4
733  Friday=5
734  Saturday=6)
735  */
736 
737  if ( rDT.GetDate() == 0 )
738  return 0;
739  sal_uInt32 nDT = ( rDT.GetDayOfWeek() + 1 ) % 7;
740  nDT <<= 9;
741  nDT += ( rDT.GetYear() - 1900 ) & 0x1ff;
742  nDT <<= 4;
743  nDT += rDT.GetMonth() & 0xf;
744  nDT <<= 5;
745  nDT += rDT.GetDay() & 0x1f;
746  nDT <<= 5;
747  nDT += rDT.GetHour() & 0x1f;
748  nDT <<= 6;
749  nDT += rDT.GetMin() & 0x3f;
750  return nDT;
751  }
752 
753 
757  static sal_Int32 findUnquoted( const OUString& rParams, sal_Unicode cFind, sal_Int32 nFromPos )
758  {
759  const sal_Int32 nLen = rParams.getLength();
760  if (nFromPos < 0 || nLen <= nFromPos)
761  return -1;
762  for (sal_Int32 nI = nFromPos; nI < nLen; ++nI)
763  {
764  const sal_Unicode c = rParams[nI];
765  if (c == '\\')
766  ++nI;
767  else if (c == '\"')
768  {
769  ++nI;
770  // While not at the end and not at an unescaped end quote
771  while (nI < nLen)
772  {
773  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
774  break;
775  ++nI;
776  }
777  }
778  else //normal unquoted section
779  {
780  if (c == cFind)
781  return nI;
782  }
783  }
784  return -1;
785  }
786 
790  static bool replaceUnquoted( OUString& rParams, const OUString& rFind, const OUString& rReplace )
791  {
792  bool bReplaced = false;
793  if (rFind.isEmpty())
794  return bReplaced;
795  const sal_Unicode cFirst = rFind[0];
796 
797  sal_Int32 nLen = rParams.getLength();
798  for (sal_Int32 nI = 0; nI < nLen; ++nI)
799  {
800  const sal_Unicode c = rParams[nI];
801  if (rParams[nI] == '\\')
802  ++nI;
803  else if (rParams[nI] == '\"')
804  {
805  ++nI;
806  // While not at the end and not at an unescaped end quote
807  while (nI < nLen)
808  {
809  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
810  break;
811  ++nI;
812  }
813  }
814  else //normal unquoted section
815  {
816  if (c == cFirst && rParams.match( rFind, nI))
817  {
818  const sal_Int32 nFindLen = rFind.getLength();
819  const sal_Int32 nDiff = rReplace.getLength() - nFindLen;
820  rParams = rParams.replaceAt( nI, nFindLen, rReplace);
821  nI += nFindLen + nDiff - 1;
822  nLen += nDiff;
823  bReplaced = true;
824  }
825  }
826  }
827  return bReplaced;
828  }
829 
831  SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri,
832  LanguageType nDocLang)
833  {
834  // tell the Formatter about the new entry
835  sal_Int32 nCheckPos = 0;
836  SvNumFormatType nType = SvNumFormatType::DEFINED;
837  sal_uInt32 nKey = 0;
838 
839  SwapQuotesInField(rParams);
840 
841  // Force to Japanese when finding one of 'geE'.
842  // XXX This actually may not be correct, all era keywords could be
843  // used in other locales as well. I just don't know about Word. But
844  // this is how it was for 10 years..
845  bool bForceJapanese = (-1 != findUnquoted( rParams, 'g', 0));
846  // XXX Why replace? The number formatter does handle them and this
847  // effectively changes from Gengou to Gregorian calendar. Legacy
848  // because it wasn't supported a decade ago and now moot? Or is
849  // that a Word specialty?
850  bForceJapanese |= replaceUnquoted( rParams, "ee", "yyyy");
851  bForceJapanese |= replaceUnquoted( rParams, "EE", "YYYY");
852  if (LANGUAGE_FRENCH != nDocLang)
853  {
854  // Handle the 'a' case here
855  sal_Int32 nLastPos = 0;
856  do
857  {
858  sal_Int32 nPos = findUnquoted( rParams, 'a', nLastPos + 1 );
859  bForceJapanese |= ( nPos != -1 && IsNotAM( rParams, nPos ) );
860  nLastPos = nPos;
861  } while ( -1 != nLastPos );
862  }
863 
864  // Force to NatNum when finding one of 'oOA'
865  bool bForceNatNum = replaceUnquoted( rParams, "o", "m")
866  || replaceUnquoted( rParams, "O", "M");
867  if (LANGUAGE_FRENCH != nDocLang)
868  {
869  // Handle the 'A' case here
870  sal_Int32 nLastPos = 0;
871  do
872  {
873  sal_Int32 nPos = findUnquoted( rParams, 'A', nLastPos + 1 );
874  bool bIsCharA = ( nPos != -1 && IsNotAM( rParams, nPos ) );
875  bForceNatNum |= bIsCharA;
876  if ( bIsCharA )
877  rParams = rParams.replaceAt( nPos, 1, "D" );
878  nLastPos = nPos;
879  } while ( -1 != nLastPos );
880  }
881 
882  sal_Int32 nLen = rParams.getLength();
883  for (sal_Int32 nI = 0; nI < nLen; ++nI)
884  {
885  if (rParams[nI] == '\\')
886  ++nI;
887  else if (rParams[nI] == '\"')
888  {
889  ++nI;
890  // While not at the end and not at an unescaped end quote
891  while (nI < nLen)
892  {
893  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
894  break;
895  ++nI;
896  }
897  }
898  else //normal unquoted section
899  {
900  sal_Unicode nChar = rParams[nI];
901 
902  // Change the localized word string to english
903  if ( nDocLang == LANGUAGE_FRENCH )
904  {
905  if ( ( nChar == 'a' || nChar == 'A' ) && IsNotAM(rParams, nI) )
906  rParams = rParams.replaceAt(nI, 1, "Y");
907  }
908  if (nChar == '/')
909  {
910  // MM: We have to escape '/' in case it's used as a char.
911  // But not if it's a '/' inside AM/PM
912  if (!(IsPreviousAM(rParams, nI) && IsNextPM(rParams, nI)))
913  {
914  rParams = rParams.replaceAt(nI, 1, "\\/");
915  nLen++;
916  }
917  nI++;
918  }
919 
920  // Deal with language differences in date format expression.
921  // Should be made with i18n framework.
922  // The list of the mappings and of those "special" locales is to be found at:
923  // http://l10n.openoffice.org/i18n_framework/LocaleData.html
924  if ( !bForceJapanese && !bForceNatNum )
925  {
926  // Convert to the localized equivalent for OOo
927  if ( rLang == LANGUAGE_FINNISH )
928  {
929  if (nChar == 'y' || nChar == 'Y')
930  rParams = rParams.replaceAt(nI, 1, "V");
931  else if (nChar == 'm' || nChar == 'M')
932  rParams = rParams.replaceAt(nI, 1, "K");
933  else if (nChar == 'd' || nChar == 'D')
934  rParams = rParams.replaceAt(nI, 1, "P");
935  else if (nChar == 'h' || nChar == 'H')
936  rParams = rParams.replaceAt(nI, 1, "T");
937  }
938  else if ( rLang.anyOf(
945  {
946  if (nChar == 'h' || nChar == 'H')
947  rParams = rParams.replaceAt(nI, 1, "T");
948  }
949  else if ( rLang.anyOf(
972  {
973  if (nChar == 'a' || nChar == 'A')
974  rParams = rParams.replaceAt(nI, 1, "O");
975  else if (nChar == 'y' || nChar == 'Y')
976  rParams = rParams.replaceAt(nI, 1, "A");
977  }
978  else if ( rLang.anyOf(
981  {
982  if (nChar == 'y' || nChar == 'Y')
983  rParams = rParams.replaceAt(nI, 1, "J");
984  else if (nChar == 'u' || nChar == 'U')
985  rParams = rParams.replaceAt(nI, 1, "H");
986  }
987  else if ( rLang.anyOf(
990  {
991  if (nChar == 'a' || nChar == 'A')
992  rParams = rParams.replaceAt(nI, 1, "O");
993  else if (nChar == 'g' || nChar == 'G')
994  rParams = rParams.replaceAt(nI, 1, "X");
995  else if (nChar == 'y' || nChar == 'Y')
996  rParams = rParams.replaceAt(nI, 1, "A");
997  else if (nChar == 'd' || nChar == 'D')
998  rParams = rParams.replaceAt(nI, 1, "G");
999  }
1000  else if ( rLang.anyOf(
1006  {
1007  if (nChar == 'y' || nChar == 'Y')
1008  rParams = rParams.replaceAt(nI, 1, "J");
1009  else if (nChar == 'd' || nChar == 'D')
1010  rParams = rParams.replaceAt(nI, 1, "T");
1011  }
1012  else if ( rLang.anyOf(
1019  {
1020  if (nChar == 'y' || nChar == 'Y' || nChar == 'a')
1021  rParams = rParams.replaceAt(nI, 1, "A");
1022  else if (nChar == 'd' || nChar == 'D' || nChar == 'j')
1023  rParams = rParams.replaceAt(nI, 1, "J");
1024  }
1025  }
1026  }
1027  }
1028 
1029  if (bForceNatNum)
1030  bForceJapanese = true;
1031 
1032  if (bForceJapanese)
1033  rLang = LANGUAGE_JAPANESE;
1034 
1035  if (bForceNatNum)
1036  rParams = "[NatNum1][$-411]" + rParams;
1037 
1038  if (bHijri)
1039  rParams = "[~hijri]" + rParams;
1040 
1041  pFormatter->PutEntry(rParams, nCheckPos, nType, nKey, rLang);
1042 
1043  return nKey;
1044  }
1045 
1046  bool IsPreviousAM(OUString const & rParams, sal_Int32 nPos)
1047  {
1048  return nPos>=2 && rParams.matchIgnoreAsciiCase("am", nPos-2);
1049  }
1050  bool IsNextPM(OUString const & rParams, sal_Int32 nPos)
1051  {
1052  return nPos+2<rParams.getLength() && rParams.matchIgnoreAsciiCase("pm", nPos+1);
1053  }
1054  bool IsNotAM(OUString const & rParams, sal_Int32 nPos)
1055  {
1056  ++nPos;
1057  return nPos>=rParams.getLength() || (rParams[nPos]!='M' && rParams[nPos]!='m');
1058  }
1059 
1060  void SwapQuotesInField(OUString &rFormat)
1061  {
1062  //Swap unescaped " and ' with ' and "
1063  const sal_Int32 nLen = rFormat.getLength();
1064  for (sal_Int32 nI = 0; nI < nLen; ++nI)
1065  {
1066  if (!nI || rFormat[nI-1]!='\\')
1067  {
1068  if (rFormat[nI]=='\"')
1069  rFormat = rFormat.replaceAt(nI, 1, "\'");
1070  else if (rFormat[nI]=='\'')
1071  rFormat = rFormat.replaceAt(nI, 1, "\"");
1072  }
1073  }
1074  }
1075 
1076  }
1077 }
1078 
1079 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool GetValue() const
#define LANGUAGE_SPANISH_PANAMA
#define LANGUAGE_GERMAN
#define LANGUAGE_SPANISH_EL_SALVADOR
#define LANGUAGE_SPANISH_VENEZUELA
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
Represents the style of a paragraph.
Definition: fmtcol.hxx:55
Marks a position in the document model.
Definition: pam.hxx:35
std::vector< SwColumn > SwColumns
Definition: fmtclds.hxx:57
DayOfWeek GetDayOfWeek() const
#define RES_HEADER
Definition: hintids.hxx:201
#define LANGUAGE_DANISH
#define LANGUAGE_DUTCH_BELGIAN
sal_uInt16 GetLower() const
const OUString & GetText() const
Definition: ndtxt.hxx:211
sal_uLong MSDateTimeFormatToSwFormat(OUString &rParams, SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri, LanguageType nDocLang)
Convert from Word Date/Time field str to Writer's Date Time str.
Pages/field.
Definition: poolfmt.hxx:115
#define LANGUAGE_SPANISH_GUATEMALA
sal_uIntPtr sal_uLong
#define LANGUAGE_SPANISH_ECUADOR
Definition: doc.hxx:185
bool IsNotAM(OUString const &rParams, sal_Int32 nPos)
Used by MSDateTimeFormatToSwFormat to identify AM time fields.
void Height(long nNew)
Definition: swrect.hxx:189
Content 1st level.
Definition: poolfmt.hxx:375
#define RES_CHRATR_FONT
Definition: hintids.hxx:75
OUString GetSubsFontName(const OUString &rName, SubsFontFlags nFlags)
#define LANGUAGE_FRENCH_MONACO
long SwTwips
Definition: swtypes.hxx:49
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt=nullptr) const
Definition: doclay.cxx:1614
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:40
#define LANGUAGE_FRENCH_SWISS
#define LANGUAGE_GERMAN_AUSTRIAN
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
#define RES_TXTATR_CHARFMT
Definition: hintids.hxx:142
static SwTwips CalcHdDist(const SwFrameFormat &rFormat)
static SvxLRSpaceItem lcl_getWordLRSpace(const SwFrameFormat &rFormat)
Count what Word calls left/right margin from a format's LRSpace + Box.
#define LANGUAGE_FRENCH_CANADIAN
#define C
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwTextFormatColl > > mpImpl
Definition: msfilter.hxx:148
#define LANGUAGE_SPANISH_NICARAGUA
Content 5th level.
Definition: poolfmt.hxx:379
const SvxBoxItem & GetBox(bool=true) const
Definition: frmatr.hxx:84
bool IsActive() const
Definition: fmthdft.hxx:89
#define LANGUAGE_NORWEGIAN_NYNORSK
sal_uInt16 GetHour() const
#define LANGUAGE_SPANISH_HONDURAS
#define LANGUAGE_PORTUGUESE
sal_uInt16 sal_Unicode
FUNC_TYPE const nType
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
#define LANGUAGE_SWEDISH
sal_uInt16 GetMonth() const
#define LANGUAGE_ITALIAN
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:34
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
sal_uInt16 GetMin() const
Content 6th level.
Definition: poolfmt.hxx:389
#define RES_UL_SPACE
Definition: hintids.hxx:197
std::pair< SwTextFormatColl *, bool > StyleResult
StyleResult StyleResult is a std::pair of a pointer to a style and a flag which is true if the style ...
Definition: msfilter.hxx:157
bool operator()(sal_uInt16 nA, sal_uInt16 nB) const
sal_Int32 GetDate() const
Content 2nd level.
Definition: poolfmt.hxx:376
Text body indent.
Definition: poolfmt.hxx:254
#define LANGUAGE_SWEDISH_FINLAND
#define LANGUAGE_NORWEGIAN_BOKMAL
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW)
#define LANGUAGE_NORWEGIAN
#define SAL_N_ELEMENTS(arr)
Content 3rd level.
Definition: poolfmt.hxx:377
rtl_TextEncoding GetExtendedTextEncoding(rtl_TextEncoding eEncoding)
sal_Int16 GetYear() const
#define LANGUAGE_SPANISH_COLOMBIA
#define LANGUAGE_ITALIAN_SWISS
Style of a layout element.
Definition: frmfmt.hxx:57
#define LANGUAGE_SPANISH_DOMINICAN_REPUBLIC
#define SAL_MAX_INT32
bool IsPreviousAM(OUString const &rParams, sal_Int32 nPos)
Internet visited.
Definition: poolfmt.hxx:122
const SwColumns & GetColumns() const
Definition: fmtclds.hxx:112
const SwFrameFormat * GetFooterFormat() const
Definition: fmthdft.hxx:85
Subgroup headings.
Definition: poolfmt.hxx:261
Subgroup footer.
Definition: poolfmt.hxx:336
static bool CanEncode(OUString const &rString, rtl_TextEncoding const eEncoding)
sal_uInt8 rtl_TextEncodingToWinCharsetRTF(OUString const &rFontName, OUString const &rAltName, rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
Text body.
Definition: poolfmt.hxx:251
#define LANGUAGE_GERMAN_LIECHTENSTEIN
#define LANGUAGE_SPANISH_MEXICAN
int i
bool IsNextPM(OUString const &rParams, sal_Int32 nPos)
std::pair< C *, bool > StyleResult
static SwTwips CalcFtDist(const SwFrameFormat &rFormat)
SwDoc * GetDoc()
Definition: node.hxx:702
Internet normal.
Definition: poolfmt.hxx:121
Header Left&Right.
Definition: poolfmt.hxx:331
static SwTwips CalcHdFtDist(const SwFrameFormat &rFormat, sal_uInt16 nSpacing)
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:195
sal_uInt16 GetDay() const
static OUString FindBestMSSubstituteFont(const OUString &rFont)
SvNumFormatType
sti
Definition: wwstyles.hxx:27
#define LANGUAGE_GERMAN_LUXEMBOURG
#define LANGUAGE_SPANISH_BOLIVIA
#define RES_TXTATR_INETFMT
Definition: hintids.hxx:141
RES_POOL_CHRFMT_TYPE
Ranges for the IDs of the formats.
Definition: poolfmt.hxx:109
#define LANGUAGE_SPANISH_PUERTO_RICO
#define LANGUAGE_SPANISH_MODERN
#define RES_FOOTER
Definition: hintids.hxx:202
CharRuns GetPseudoCharRuns(const SwTextNode &rTextNd)
Collect the ranges of Text which share.
SwTextFormatColl * GetParaStyle(SwDoc &rDoc, const OUString &rName)
Get a Paragraph Style which fits a given name.
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
#define LANGUAGE_PORTUGUESE_BRAZILIAN
Content 9th level.
Definition: poolfmt.hxx:392
const SvxULSpaceItem & GetULSpace(bool=true) const
Definition: frmatr.hxx:76
#define LANGUAGE_SPANISH_URUGUAY
#define LANGUAGE_FRENCH
#define LANGUAGE_SPANISH_COSTARICA
#define LANGUAGE_SPANISH_PERU
bool operator()(const sw::util::CharRunEntry &rEntry) const
Make export a word section top/bottom values easy.
unsigned char sal_uInt8
sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
MSOffice appears to set the charset of unicode fonts to MS 932.
sal_uInt32 DateTime2DTTM(const DateTime &rDT)
Convert from DTTM to Writer's DateTime.
#define SAL_INFO(area, stream)
Content 4th level.
Definition: poolfmt.hxx:378
#define LANGUAGE_DUTCH
#define RES_HEADER_FOOTER_EAT_SPACING
Definition: hintids.hxx:226
std::pair< SwCharFormat *, bool > StyleResult
StyleResult StyleResult is a std::pair of a pointer to a style and a flag which is true if the style ...
Definition: msfilter.hxx:214
RES_POOL_COLLFMT_TYPE
Definition: poolfmt.hxx:245
Content 8th level.
Definition: poolfmt.hxx:391
FontMapExport(const OUString &rFontDescription)
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
std::set< const C * > maUsedStyles
bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
See if two page formats can be expressed as a single word section.
Header, for PageFormats Client of FrameFormat describing the header.
Definition: fmthdft.hxx:33
const SvxPageUsage aArr[]
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
static sal_Int32 findUnquoted(const OUString &rParams, sal_Unicode cFind, sal_Int32 nFromPos)
Find cFind in rParams if not embedded in " double quotes.
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter()
Definition: breakit.hxx:62
OString const aName
#define LANGUAGE_FRENCH_LUXEMBOURG
#define RES_BOX
Definition: hintids.hxx:211
OUString GetNextFontToken(const OUString &rTokenStr, sal_Int32 &rIndex)
Line numbering.
Definition: poolfmt.hxx:126
#define LANGUAGE_FINNISH
Content 7th level.
Definition: poolfmt.hxx:390
#define LANGUAGE_SPANISH_PARAGUAY
Subgroup index tables.
Definition: poolfmt.hxx:367
#define LANGUAGE_FRENCH_BELGIAN
std::vector< CharRunEntry > CharRuns
Definition: msfilter.hxx:372
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:116
bool IsStarSymbol(const OUString &rFontName)
bool IsActive() const
Definition: fmthdft.hxx:58
void SwapQuotesInField(OUString &rFormat)
Another function used by MSDateTimeFormatToSwFormat.
long GetHeight() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
sal_Int32 nPos
SwCharFormat * GetCharStyle(SwDoc &rDoc, const OUString &rName)
Get a Character Style which fits a given name.
#define LANGUAGE_JAPANESE
Frame is variable in Var-direction.
Definition: fmtfsize.hxx:37
#define LANGUAGE_SPANISH_DATED
#define LANGUAGE_GERMAN_SWISS
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwCharFormat > > mpImpl
Definition: msfilter.hxx:205
#define LANGUAGE_SPANISH_ARGENTINA
const SwFrameFormat * GetHeaderFormat() const
Definition: fmthdft.hxx:54
Doc. subtitle.
Definition: poolfmt.hxx:424
#define LANGUAGE_SPANISH_CHILE
bool anyOf(strong_int v) const
sal_uInt16 GetUpper() const
SwFrameSize GetHeightSizeType() const
Definition: fmtfsize.hxx:80
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
static bool replaceUnquoted(OUString &rParams, const OUString &rFind, const OUString &rReplace)
Find all rFind in rParams if not embedded in " double quotes and replace with rReplace.