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