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 <o3tl/string_view.hxx>
29 #include <rtl/tencinfo.h>
30 #include <sal/log.hxx>
31 #include <svl/numformat.hxx>
32 
33 #include <unicode/ubidi.h>
34 #include <tools/tenccvt.hxx>
35 #include <com/sun/star/i18n/ScriptType.hpp>
36 #include <com/sun/star/i18n/XBreakIterator.hpp>
37 
38 #include <editeng/lrspitem.hxx>
39 #include <editeng/ulspitem.hxx>
40 #include <editeng/boxitem.hxx>
41 #include <editeng/fontitem.hxx>
42 #include <o3tl/sorted_vector.hxx>
43 #include <frmfmt.hxx>
44 #include <fmtclds.hxx>
45 #include <hfspacingitem.hxx>
46 #include <fmtfsize.hxx>
47 #include <poolfmt.hxx>
48 #include <swrect.hxx>
49 #include <fmthdft.hxx>
50 #include <frmatr.hxx>
51 #include <ndtxt.hxx>
52 #include <breakit.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  tools::Long nDist=0;
71  const SwFormatFrameSize& rSz = rFormat.GetFrameSize();
72 
73  const SwHeaderAndFooterEatSpacingItem &rSpacingCtrl =
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();
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_SUBTITLE
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:
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 = nullptr;
293 
294  if (nullptr != (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, it's 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  nullptr != (pColl = maHelper.GetStyle(aName)) &&
306  (nI < SAL_MAX_INT32)
307  )
308  {
309  aName = aBaseName + OUString::number(nI++);
310  }
311  }
312 
313  return pColl ? nullptr : maHelper.MakeStyle(aName);
314  }
315 
316  static OUString FindBestMSSubstituteFont(std::u16string_view rFont)
317  {
318  if (IsStarSymbol(rFont))
319  return "Arial Unicode MS";
320  return GetSubsFontName(rFont, SubsFontFlags::ONLYONE | SubsFontFlags::MS);
321  }
322 
323  namespace {
324 
325  //Utility to remove entries before a given starting position
326  class IfBeforeStart
327  {
328  private:
329  sal_Int32 mnStart;
330  public:
331  explicit IfBeforeStart(sal_Int32 nStart) : mnStart(nStart) {}
332  bool operator()(const sw::util::CharRunEntry &rEntry) const
333  {
334  return rEntry.mnEndPos < mnStart;
335  }
336  };
337 
338  }
339 }
340 
343 {
344  SvxLRSpaceItem aLR(rFormat.GetLRSpace());
345  const SvxBoxItem& rBox = rFormat.GetBox();
346 
347  aLR.SetLeft(aLR.GetLeft() + rBox.GetDistance(SvxBoxItemLine::LEFT));
348  if (const editeng::SvxBorderLine* pLeft = rBox.GetLeft())
349  aLR.SetLeft(aLR.GetLeft() + pLeft->GetWidth());
350 
351  aLR.SetRight(aLR.GetRight() + rBox.GetDistance(SvxBoxItemLine::RIGHT));
352  if (const editeng::SvxBorderLine* pRight = rBox.GetRight())
353  aLR.SetRight(aLR.GetRight() + pRight->GetWidth());
354 
355  return aLR;
356 }
357 
358 namespace sw
359 {
360  namespace util
361  {
362 
363  bool IsPlausableSingleWordSection(const SwFrameFormat &rTitleFormat, const SwFrameFormat &rFollowFormat)
364  {
365  bool bPlausableSingleWordSection = true;
366 
367  const SwFormatCol& rFirstCols = rTitleFormat.GetCol();
368  const SwFormatCol& rFollowCols = rFollowFormat.GetCol();
369  const SwColumns& rFirstColumns = rFirstCols.GetColumns();
370  const SwColumns& rFollowColumns = rFollowCols.GetColumns();
371  SvxLRSpaceItem aOneLR = lcl_getWordLRSpace(rTitleFormat);
372  SvxLRSpaceItem aTwoLR = lcl_getWordLRSpace(rFollowFormat);
373  const SwFormatFrameSize& rFirstFrameSize = rTitleFormat.GetFrameSize();
374  const SwFormatFrameSize& rFollowFrameSize = rFollowFormat.GetFrameSize();
375 
376  if (rFirstColumns.size() != rFollowColumns.size())
377  {
378  //e.g. #i4320#
379  bPlausableSingleWordSection = false;
380  }
381  else if (aOneLR != aTwoLR)
382  bPlausableSingleWordSection = false;
383  else if (rFirstFrameSize != rFollowFrameSize)
384  bPlausableSingleWordSection = false;
385  else
386  {
387  HdFtDistanceGlue aOne(rTitleFormat.GetAttrSet());
388  HdFtDistanceGlue aTwo(rFollowFormat.GetAttrSet());
389  //e.g. #i14509#
390  if (!aOne.StrictEqualTopBottom(aTwo))
391  bPlausableSingleWordSection = false;
392  }
393  return bPlausableSingleWordSection;
394  }
395 
396  HdFtDistanceGlue::HdFtDistanceGlue(const SfxItemSet &rPage)
397  {
398  if (const SvxBoxItem *pBox = rPage.GetItem<SvxBoxItem>(RES_BOX))
399  {
400  dyaHdrTop = pBox->CalcLineSpace( SvxBoxItemLine::TOP, /*bEvenIfNoLine*/true );
401  dyaHdrBottom = pBox->CalcLineSpace( SvxBoxItemLine::BOTTOM, /*bEvenIfNoLine*/true );
402  }
403  else
404  {
405  dyaHdrTop = dyaHdrBottom = 0;
406  }
407  const SvxULSpaceItem &rUL = rPage.Get(RES_UL_SPACE);
408  dyaHdrTop += rUL.GetUpper();
409  dyaHdrBottom += rUL.GetLower();
410 
411  dyaTop = dyaHdrTop;
412  dyaBottom = dyaHdrBottom;
413 
414  const SwFormatHeader *pHd = rPage.GetItem<SwFormatHeader>(RES_HEADER);
415  if (pHd && pHd->IsActive() && pHd->GetHeaderFormat())
416  {
417  mbHasHeader = true;
418  dyaTop = dyaTop + static_cast< sal_uInt16 >( (myImplHelpers::CalcHdDist(*(pHd->GetHeaderFormat()))) );
419  }
420  else
421  mbHasHeader = false;
422 
423  const SwFormatFooter *pFt = rPage.GetItem<SwFormatFooter>(RES_FOOTER);
424  if (pFt && pFt->IsActive() && pFt->GetFooterFormat())
425  {
426  mbHasFooter = true;
427  dyaBottom = dyaBottom + static_cast< sal_uInt16 >( (myImplHelpers::CalcFtDist(*(pFt->GetFooterFormat()))) );
428  }
429  else
430  mbHasFooter = false;
431  }
432 
433  bool HdFtDistanceGlue::StrictEqualTopBottom(const HdFtDistanceGlue &rOther)
434  const
435  {
436  // Check top only if both object have a header or if
437  // both object don't have a header
438  if (HasHeader() == rOther.HasHeader())
439  {
440  if (dyaTop != rOther.dyaTop)
441  return false;
442  }
443 
444  // Check bottom only if both object have a footer or if
445  // both object don't have a footer
446  if (HasFooter() == rOther.HasFooter())
447  {
448  if (dyaBottom != rOther.dyaBottom)
449  return false;
450  }
451 
452  return true;
453  }
454 
455  ParaStyleMapper::ParaStyleMapper(SwDoc &rDoc)
456  : mpImpl(new myImplHelpers::StyleMapperImpl<SwTextFormatColl>(rDoc))
457  {
458  }
459 
461  {
462  }
463 
465  const OUString& rName, ww::sti eSti)
466  {
467  return mpImpl->GetStyle(rName, eSti);
468  }
469 
471  : mpImpl(new myImplHelpers::StyleMapperImpl<SwCharFormat>(rDoc))
472  {
473  }
474 
476  {
477  }
478 
480  const OUString& rName, ww::sti eSti)
481  {
482  return mpImpl->GetStyle(rName, eSti);
483  }
484 
485  FontMapExport::FontMapExport(std::u16string_view rFamilyName)
486  {
487  sal_Int32 nIndex = 0;
488  msPrimary = GetNextFontToken(rFamilyName, nIndex);
490  if (msSecondary.isEmpty() && nIndex != -1)
491  msSecondary = GetNextFontToken(rFamilyName, nIndex);
492  }
493 
494  bool ItemSort::operator()(sal_uInt16 nA, sal_uInt16 nB) const
495  {
496  /*
497  #i24291#
498  All we want to do is ensure for now is that if a charfmt exist
499  in the character properties that it rises to the top and is
500  exported first. In the future we might find more ordering
501  dependencies for export, in which case this is the place to do
502  it
503  */
504  if (nA == nB)
505  return false;
506  if (nA == RES_TXTATR_CHARFMT)
507  return true;
508  if (nB == RES_TXTATR_CHARFMT)
509  return false;
510  if (nA == RES_TXTATR_INETFMT)
511  return true;
512  if (nB == RES_TXTATR_INETFMT)
513  return false;
514  return nA < nB;
515  }
516 
518  {
519  const OUString &rText = rTextNd.GetText();
520 
521  bool bParaIsRTL = false;
522  if (SvxFrameDirection::Horizontal_RL_TB ==
523  rTextNd.GetDoc().GetTextDirection(SwPosition(rTextNd)))
524  {
525  bParaIsRTL = true;
526  }
527 
528  using namespace ::com::sun::star::i18n;
529 
530  sal_uInt16 nScript = i18n::ScriptType::LATIN;
531  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
532  if (!rText.isEmpty())
533  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, 0);
534 
536  rtl_TextEncoding eChrSet = rTextNd.GetAttr(nFontWhichId).GetCharSet();
537  eChrSet = GetExtendedTextEncoding(eChrSet);
538 
539  CharRuns aRunChanges;
540 
541  if (rText.isEmpty())
542  {
543  aRunChanges.emplace_back(0, nScript, eChrSet,
544  bParaIsRTL);
545  return aRunChanges;
546  }
547 
548  typedef std::pair<int32_t, bool> DirEntry;
549  typedef std::pair<sal_Int32, sal_uInt16> ScriptEntry;
550  std::vector<DirEntry> aDirChanges;
551  std::vector<ScriptEntry> aScripts;
552 
553  UBiDiDirection eDefaultDir = bParaIsRTL ? UBIDI_RTL : UBIDI_LTR;
554  UErrorCode nError = U_ZERO_ERROR;
555  UBiDi* pBidi = ubidi_openSized(rText.getLength(), 0, &nError);
556  ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(rText.getStr()), rText.getLength(),
557  static_cast< UBiDiLevel >(eDefaultDir), nullptr, &nError);
558 
559  sal_Int32 nCount = ubidi_countRuns(pBidi, &nError);
560  aDirChanges.reserve(nCount);
561 
562  int32_t nStart = 0;
563  int32_t nEnd;
564  UBiDiLevel nCurrDir;
565 
566  for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
567  {
568  ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
569  /*
570  UBiDiLevel is the type of the level values in this BiDi
571  implementation.
572 
573  It holds an embedding level and indicates the visual direction
574  by its bit 0 (even/odd value).
575 
576  The value for UBIDI_DEFAULT_LTR is even and the one for
577  UBIDI_DEFAULT_RTL is odd
578  */
579  aDirChanges.emplace_back(nEnd, nCurrDir & 0x1);
580  nStart = nEnd;
581  }
582  ubidi_close(pBidi);
583 
584  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
585 
586  sal_Int32 nLen = rText.getLength();
587  sal_Int32 nPos = 0;
588  while (nPos < nLen)
589  {
590  sal_Int32 nEnd2 = g_pBreakIt->GetBreakIter()->endOfScript(rText, nPos,
591  nScript);
592  if (nEnd2 < 0)
593  break;
594  nPos = nEnd2;
595  aScripts.emplace_back(nPos, nScript);
596  nScript = g_pBreakIt->GetBreakIter()->getScriptType(rText, nPos);
597  }
598 
599  auto aBiDiEnd = aDirChanges.cend();
600  auto aScriptEnd = aScripts.cend();
601 
602  auto aBiDiIter = aDirChanges.cbegin();
603  auto aScriptIter = aScripts.cbegin();
604 
605  bool bCharIsRTL = bParaIsRTL;
606 
607  while (
608  aBiDiIter != aBiDiEnd ||
609  aScriptIter != aScriptEnd
610  )
611  {
612  sal_Int32 nMinPos = rText.getLength();
613 
614  if (aBiDiIter != aBiDiEnd)
615  {
616  if (aBiDiIter->first < nMinPos)
617  nMinPos = aBiDiIter->first;
618  bCharIsRTL = aBiDiIter->second;
619  }
620 
621  if (aScriptIter != aScriptEnd)
622  {
623  if (aScriptIter->first < nMinPos)
624  nMinPos = aScriptIter->first;
625  nScript = aScriptIter->second;
626  }
627 
628  aRunChanges.emplace_back(nMinPos, nScript, eChrSet, bCharIsRTL);
629 
630  if (aBiDiIter != aBiDiEnd)
631  {
632  if (aBiDiIter->first == nMinPos)
633  ++aBiDiIter;
634  }
635 
636  if (aScriptIter != aScriptEnd)
637  {
638  if (aScriptIter->first == nMinPos)
639  ++aScriptIter;
640  }
641  }
642 
643  aRunChanges.erase(std::remove_if(aRunChanges.begin(),
644  aRunChanges.end(), myImplHelpers::IfBeforeStart(0/*nTextStart*/)), aRunChanges.end());
645 
646  return aRunChanges;
647  }
648  }
649 
650  namespace ms
651  {
652  sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding)
653  {
654  sal_uInt8 nRet =
655  rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
656  switch (eTextEncoding)
657  {
658  case RTL_TEXTENCODING_DONTKNOW:
659  case RTL_TEXTENCODING_UCS2:
660  case RTL_TEXTENCODING_UTF7:
661  case RTL_TEXTENCODING_UTF8:
662  case RTL_TEXTENCODING_JAVA_UTF8:
663  nRet = 0x01;
664  break;
665  default:
666  break;
667  }
668  return nRet;
669  }
670 
671  static bool
672  CanEncode(OUString const& rString, rtl_TextEncoding const eEncoding)
673  {
674  OString tmp;
675  return rString.convertToString(&tmp, eEncoding,
676  RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
677  RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
678  }
679 
681  OUString const& rFontName, OUString const& rAltName,
682  rtl_TextEncoding eTextEncoding)
683  {
684  sal_uInt8 nRet =
685  rtl_getBestWindowsCharsetFromTextEncoding(eTextEncoding);
686  rtl_TextEncoding enc2 = rtl_getTextEncodingFromWindowsCharset(nRet);
687  if (!rtl_isOctetTextEncoding(enc2) /* check to avoid asserts */ ||
688  !(CanEncode(rFontName, enc2) && CanEncode(rAltName, enc2)))
689  {
690  static struct { rtl_TextEncoding enc; sal_uInt8 charset; }
691  const s_fallbacks [] = {
692  { RTL_TEXTENCODING_MS_932, 0x80 }, // Shift-JIS
693  { RTL_TEXTENCODING_MS_936, 0x86 }, // GB-2312
694  { RTL_TEXTENCODING_MS_950, 0x88 }, // Big5
695  { RTL_TEXTENCODING_MS_949, 0x81 }, // EUC-KR
696  };
697  for (const auto & i : s_fallbacks)
698  {
699  // fall back to a charset that can at least encode the
700  // font's name
701  if (CanEncode(rFontName, i.enc)
702  && CanEncode(rAltName, i.enc))
703  {
704  return i.charset;
705  }
706  }
707  SAL_INFO("sw.rtf", "no fallback charset found for font: "
708  << rFontName << " " << rAltName);
709  nRet = 0x01; // all hope lost: "default", whatever that is
710  }
711  return nRet;
712  }
713 
714  sal_uInt32 DateTime2DTTM( const DateTime& rDT )
715  {
716  /*
717  mint short :6 0000003F minutes (0-59)
718  hr short :5 000007C0 hours (0-23)
719  dom short :5 0000F800 days of month (1-31)
720  mon short :4 000F0000 months (1-12)
721  yr short :9 1FF00000 years (1900-2411)-1900
722  wdy short :3 E0000000 weekday(Sunday=0
723  Monday=1
724  ( wdy can be ignored ) Tuesday=2
725  Wednesday=3
726  Thursday=4
727  Friday=5
728  Saturday=6)
729  */
730 
731  if ( rDT.GetDate() == 0 )
732  return 0;
733  sal_uInt32 nDT = ( rDT.GetDayOfWeek() + 1 ) % 7;
734  nDT <<= 9;
735  nDT += ( rDT.GetYear() - 1900 ) & 0x1ff;
736  nDT <<= 4;
737  nDT += rDT.GetMonth() & 0xf;
738  nDT <<= 5;
739  nDT += rDT.GetDay() & 0x1f;
740  nDT <<= 5;
741  nDT += rDT.GetHour() & 0x1f;
742  nDT <<= 6;
743  nDT += rDT.GetMin() & 0x3f;
744  return nDT;
745  }
746 
747 
751  static sal_Int32 findUnquoted( const OUString& rParams, sal_Unicode cFind, sal_Int32 nFromPos )
752  {
753  const sal_Int32 nLen = rParams.getLength();
754  if (nFromPos < 0 || nLen <= nFromPos)
755  return -1;
756  for (sal_Int32 nI = nFromPos; nI < nLen; ++nI)
757  {
758  const sal_Unicode c = rParams[nI];
759  if (c == '\\')
760  ++nI;
761  else if (c == '\"')
762  {
763  ++nI;
764  // While not at the end and not at an unescaped end quote
765  while (nI < nLen)
766  {
767  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
768  break;
769  ++nI;
770  }
771  }
772  else //normal unquoted section
773  {
774  if (c == cFind)
775  return nI;
776  }
777  }
778  return -1;
779  }
780 
784  static bool replaceUnquoted( OUString& rParams, const OUString& rFind, const OUString& rReplace )
785  {
786  bool bReplaced = false;
787  if (rFind.isEmpty())
788  return bReplaced;
789  const sal_Unicode cFirst = rFind[0];
790 
791  sal_Int32 nLen = rParams.getLength();
792  for (sal_Int32 nI = 0; nI < nLen; ++nI)
793  {
794  const sal_Unicode c = rParams[nI];
795  if (rParams[nI] == '\\')
796  ++nI;
797  else if (rParams[nI] == '\"')
798  {
799  ++nI;
800  // While not at the end and not at an unescaped end quote
801  while (nI < nLen)
802  {
803  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
804  break;
805  ++nI;
806  }
807  }
808  else //normal unquoted section
809  {
810  if (c == cFirst && rParams.match( rFind, nI))
811  {
812  const sal_Int32 nFindLen = rFind.getLength();
813  const sal_Int32 nDiff = rReplace.getLength() - nFindLen;
814  rParams = rParams.replaceAt( nI, nFindLen, rReplace);
815  nI += nFindLen + nDiff - 1;
816  nLen += nDiff;
817  bReplaced = true;
818  }
819  }
820  }
821  return bReplaced;
822  }
823 
825  SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri,
826  LanguageType nDocLang)
827  {
828  // tell the Formatter about the new entry
829  sal_Int32 nCheckPos = 0;
830  SvNumFormatType nType = SvNumFormatType::DEFINED;
831  sal_uInt32 nKey = 0;
832 
833  SwapQuotesInField(rParams);
834 
835  // Force to Japanese when finding one of 'geE'.
836  // XXX This actually may not be correct, all era keywords could be
837  // used in other locales as well. I just don't know about Word. But
838  // this is how it was for 10 years...
839  bool bForceJapanese = (-1 != findUnquoted( rParams, 'g', 0));
840  // XXX Why replace? The number formatter does handle them and this
841  // effectively changes from Gengou to Gregorian calendar. Legacy
842  // because it wasn't supported a decade ago and now moot? Or is
843  // that a Word specialty?
844  bForceJapanese |= replaceUnquoted( rParams, "ee", "yyyy");
845  bForceJapanese |= replaceUnquoted( rParams, "EE", "YYYY");
846  if (LANGUAGE_FRENCH != nDocLang)
847  {
848  // Handle the 'a' case here
849  sal_Int32 nLastPos = 0;
850  do
851  {
852  sal_Int32 nPos = findUnquoted( rParams, 'a', nLastPos + 1 );
853  bForceJapanese |= ( nPos != -1 && IsNotAM( rParams, nPos ) );
854  nLastPos = nPos;
855  } while ( -1 != nLastPos );
856  }
857 
858  // Force to NatNum when finding one of 'oOA'
859  bool bForceNatNum = replaceUnquoted( rParams, "o", "m")
860  || replaceUnquoted( rParams, "O", "M");
861  if (LANGUAGE_FRENCH != nDocLang)
862  {
863  // Handle the 'A' case here
864  sal_Int32 nLastPos = 0;
865  do
866  {
867  sal_Int32 nPos = findUnquoted( rParams, 'A', nLastPos + 1 );
868  bool bIsCharA = ( nPos != -1 && IsNotAM( rParams, nPos ) );
869  bForceNatNum |= bIsCharA;
870  if ( bIsCharA )
871  rParams = rParams.replaceAt( nPos, 1, u"D" );
872  nLastPos = nPos;
873  } while ( -1 != nLastPos );
874  }
875 
876  sal_Int32 nLen = rParams.getLength();
877  for (sal_Int32 nI = 0; nI < nLen; ++nI)
878  {
879  if (rParams[nI] == '\\')
880  ++nI;
881  else if (rParams[nI] == '\"')
882  {
883  ++nI;
884  // While not at the end and not at an unescaped end quote
885  while (nI < nLen)
886  {
887  if (rParams[nI] == '\"' && rParams[nI-1] != '\\')
888  break;
889  ++nI;
890  }
891  }
892  else //normal unquoted section
893  {
894  sal_Unicode nChar = rParams[nI];
895 
896  // Change the localized word string to english
897  if ( nDocLang == LANGUAGE_FRENCH )
898  {
899  if ( ( nChar == 'a' || nChar == 'A' ) && IsNotAM(rParams, nI) )
900  rParams = rParams.replaceAt(nI, 1, u"Y");
901  }
902  if (nChar == '/')
903  {
904  // MM: We have to escape '/' in case it's used as a char.
905  // But not if it's a '/' inside AM/PM
906  if (!(IsPreviousAM(rParams, nI) && IsNextPM(rParams, nI)))
907  {
908  rParams = rParams.replaceAt(nI, 1, u"\\/");
909  nLen++;
910  }
911  nI++;
912  }
913 
914  // Deal with language differences in date format expression.
915  // Should be made with i18n framework.
916  // The list of the mappings and of those "special" locales is to be found at:
917  // http://l10n.openoffice.org/i18n_framework/LocaleData.html
918  if ( !bForceJapanese && !bForceNatNum )
919  {
920  // Convert to the localized equivalent for OOo
921  if ( rLang == LANGUAGE_FINNISH )
922  {
923  if (nChar == 'y' || nChar == 'Y')
924  rParams = rParams.replaceAt(nI, 1, u"V");
925  else if (nChar == 'm' || nChar == 'M')
926  rParams = rParams.replaceAt(nI, 1, u"K");
927  else if (nChar == 'd' || nChar == 'D')
928  rParams = rParams.replaceAt(nI, 1, u"P");
929  else if (nChar == 'h' || nChar == 'H')
930  rParams = rParams.replaceAt(nI, 1, u"T");
931  }
932  else if ( rLang.anyOf(
939  {
940  if (nChar == 'h' || nChar == 'H')
941  rParams = rParams.replaceAt(nI, 1, u"T");
942  }
943  else if ( rLang.anyOf(
966  {
967  if (nChar == 'a' || nChar == 'A')
968  rParams = rParams.replaceAt(nI, 1, u"O");
969  else if (nChar == 'y' || nChar == 'Y')
970  rParams = rParams.replaceAt(nI, 1, u"A");
971  }
972  else if ( rLang.anyOf(
975  {
976  if (nChar == 'y' || nChar == 'Y')
977  rParams = rParams.replaceAt(nI, 1, u"J");
978  else if (nChar == 'u' || nChar == 'U')
979  rParams = rParams.replaceAt(nI, 1, u"H");
980  }
981  else if ( rLang.anyOf(
984  {
985  if (nChar == 'a' || nChar == 'A')
986  rParams = rParams.replaceAt(nI, 1, u"O");
987  else if (nChar == 'g' || nChar == 'G')
988  rParams = rParams.replaceAt(nI, 1, u"X");
989  else if (nChar == 'y' || nChar == 'Y')
990  rParams = rParams.replaceAt(nI, 1, u"A");
991  else if (nChar == 'd' || nChar == 'D')
992  rParams = rParams.replaceAt(nI, 1, u"G");
993  }
994  else if ( rLang.anyOf(
1000  {
1001  if (nChar == 'y' || nChar == 'Y')
1002  rParams = rParams.replaceAt(nI, 1, u"J");
1003  else if (nChar == 'd' || nChar == 'D')
1004  rParams = rParams.replaceAt(nI, 1, u"T");
1005  }
1006  else if ( rLang.anyOf(
1013  {
1014  if (nChar == 'y' || nChar == 'Y' || nChar == 'a')
1015  rParams = rParams.replaceAt(nI, 1, u"A");
1016  else if (nChar == 'd' || nChar == 'D' || nChar == 'j')
1017  rParams = rParams.replaceAt(nI, 1, u"J");
1018  }
1019  }
1020  }
1021  }
1022 
1023  if (bForceNatNum)
1024  bForceJapanese = true;
1025 
1026  if (bForceJapanese)
1027  rLang = LANGUAGE_JAPANESE;
1028 
1029  if (bForceNatNum)
1030  rParams = "[NatNum1][$-411]" + rParams;
1031 
1032  if (bHijri)
1033  rParams = "[~hijri]" + rParams;
1034 
1035  pFormatter->PutEntry(rParams, nCheckPos, nType, nKey, rLang);
1036 
1037  return nKey;
1038  }
1039 
1040  bool IsPreviousAM(std::u16string_view rParams, sal_Int32 nPos)
1041  {
1042  return nPos>=2 && o3tl::matchIgnoreAsciiCase(rParams, u"am", nPos-2);
1043  }
1044  bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
1045  {
1046  return o3tl::make_unsigned(nPos+2)<rParams.size() && o3tl::matchIgnoreAsciiCase(rParams, u"pm", nPos+1);
1047  }
1048  bool IsNotAM(std::u16string_view rParams, sal_Int32 nPos)
1049  {
1050  ++nPos;
1051  return o3tl::make_unsigned(nPos)>=rParams.size() || (rParams[nPos]!='M' && rParams[nPos]!='m');
1052  }
1053 
1054  void SwapQuotesInField(OUString &rFormat)
1055  {
1056  //Swap unescaped " and ' with ' and "
1057  const sal_Int32 nLen = rFormat.getLength();
1058  for (sal_Int32 nI = 0; nI < nLen; ++nI)
1059  {
1060  if (!nI || rFormat[nI-1]!='\\')
1061  {
1062  if (rFormat[nI]=='\"')
1063  rFormat = rFormat.replaceAt(nI, 1, u"\'");
1064  else if (rFormat[nI]=='\'')
1065  rFormat = rFormat.replaceAt(nI, 1, u"\"");
1066  }
1067  }
1068  }
1069 
1070  }
1071 }
1072 
1073 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool GetValue() const
#define LANGUAGE_SPANISH_PANAMA
#define LANGUAGE_GERMAN
#define LANGUAGE_SPANISH_EL_SALVADOR
constexpr TypedWhichId< SwHeaderAndFooterEatSpacingItem > RES_HEADER_FOOTER_EAT_SPACING(121)
sal_Int32 nIndex
#define LANGUAGE_SPANISH_VENEZUELA
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
Marks a position in the document model.
Definition: pam.hxx:36
std::vector< SwColumn > SwColumns
Definition: fmtclds.hxx:57
DayOfWeek GetDayOfWeek() const
#define LANGUAGE_DANISH
#define LANGUAGE_DUTCH_BELGIAN
sal_uInt16 GetLower() const
sal_Int32 mnStart
const OUString & GetText() const
Definition: ndtxt.hxx:218
constexpr TypedWhichId< SwFormatHeader > RES_HEADER(96)
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.
bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
Pages/field.
Definition: poolfmt.hxx:114
#define LANGUAGE_SPANISH_GUATEMALA
sal_uIntPtr sal_uLong
long Long
SwRect FindLayoutRect(const bool bPrtArea=false, const Point *pPoint=nullptr) const
Definition: atrfrm.cxx:2710
std::u16string_view GetNextFontToken(std::u16string_view rTokenStr, sal_Int32 &rIndex)
Doc. subtitle.
Definition: poolfmt.hxx:424
#define LANGUAGE_SPANISH_ECUADOR
Definition: doc.hxx:187
Content 1st level.
Definition: poolfmt.hxx:375
#define LANGUAGE_FRENCH_MONACO
SvxFrameDirection GetTextDirection(const SwPosition &rPos, const Point *pPt=nullptr) const
Definition: doclay.cxx:1609
Dialog to specify the properties of date form field.
#define LANGUAGE_FRENCH_SWISS
#define LANGUAGE_GERMAN_AUSTRIAN
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
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
constexpr TypedWhichId< SvxFontItem > RES_CHRATR_FONT(7)
bool IsStarSymbol(std::u16string_view rFontName)
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwTextFormatColl > > mpImpl
Definition: msfilter.hxx:144
#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
bool matchIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2, sal_Int32 fromIndex=0)
#define LANGUAGE_NORWEGIAN_NYNORSK
sal_uInt16 GetHour() const
#define LANGUAGE_SPANISH_HONDURAS
#define LANGUAGE_PORTUGUESE
sal_uInt16 sal_Unicode
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
static OUString FindBestMSSubstituteFont(std::u16string_view rFont)
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bReplaceBooleanEquivalent=true)
#define LANGUAGE_SWEDISH
sal_uInt16 GetMonth() const
#define LANGUAGE_ITALIAN
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
int nCount
sal_uInt16 GetMin() const
Content 6th level.
Definition: poolfmt.hxx:389
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:153
bool operator()(sal_uInt16 nA, sal_uInt16 nB) const
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
sal_Int32 GetDate() const
Content 2nd level.
Definition: poolfmt.hxx:376
Text body indent.
Definition: poolfmt.hxx:254
OUString GetSubsFontName(std::u16string_view rName, SubsFontFlags nFlags)
#define LANGUAGE_SWEDISH_FINLAND
#define LANGUAGE_NORWEGIAN_BOKMAL
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
#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
bool IsPreviousAM(std::u16string_view rParams, sal_Int32 nPos)
#define LANGUAGE_ITALIAN_SWISS
Style of a layout element.
Definition: frmfmt.hxx:59
#define LANGUAGE_SPANISH_DOMINICAN_REPUBLIC
#define SAL_MAX_INT32
Internet visited.
Definition: poolfmt.hxx:121
int i
const SwColumns & GetColumns() const
Definition: fmtclds.hxx:112
SwDoc & GetDoc()
Definition: node.hxx:213
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
const SvxPageUsage aArr[]
std::pair< C *, bool > StyleResult
static SwTwips CalcFtDist(const SwFrameFormat &rFormat)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Internet normal.
Definition: poolfmt.hxx:120
float u
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:190
sal_uInt16 GetDay() const
FontMapExport(std::u16string_view rFontDescription)
SvNumFormatType
o3tl::sorted_vector< const C * > maUsedStyles
#define LANGUAGE_GERMAN_LUXEMBOURG
tools::Long GetHeight() const
#define LANGUAGE_SPANISH_BOLIVIA
Represents the style of a text portion.
Definition: charfmt.hxx:26
RES_POOL_CHRFMT_TYPE
Ranges for the IDs of the formats.
Definition: poolfmt.hxx:108
tools::Long SwTwips
Definition: swtypes.hxx:51
#define LANGUAGE_SPANISH_PUERTO_RICO
#define LANGUAGE_SPANISH_MODERN
CharRuns GetPseudoCharRuns(const SwTextNode &rTextNd)
Collect the ranges of Text which share.
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
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
Make export a word section top/bottom values easy.
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
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)
OUString aName
Content 4th level.
Definition: poolfmt.hxx:378
#define LANGUAGE_DUTCH
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:210
RES_POOL_COLLFMT_TYPE
Definition: poolfmt.hxx:245
Content 8th level.
Definition: poolfmt.hxx:391
StyleResult GetStyle(const OUString &rName, ww::sti eSti)
Get the writer style which the word style should map to.
QPRO_FUNC_TYPE nType
const SfxPoolItem & GetFormatAttr(sal_uInt16 nWhich, bool bInParents=true) const
If bInParents is FALSE, search only in this format for attribute.
Definition: format.cxx:367
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
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
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.
#define LANGUAGE_FRENCH_LUXEMBOURG
constexpr TypedWhichId< SwFormatFooter > RES_FOOTER(97)
Line numbering.
Definition: poolfmt.hxx:125
#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:373
bool IsNotAM(std::u16string_view rParams, sal_Int32 nPos)
Used by MSDateTimeFormatToSwFormat to identify AM time fields.
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
Frame is variable in Var-direction.
bool IsActive() const
Definition: fmthdft.hxx:58
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:731
void SwapQuotesInField(OUString &rFormat)
Another function used by MSDateTimeFormatToSwFormat.
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SwCharFormat * GetCharStyle(SwDoc &rDoc, const OUString &rName)
Get a Character Style which fits a given name.
void Height(tools::Long nNew)
Definition: swrect.hxx:193
#define LANGUAGE_JAPANESE
#define LANGUAGE_SPANISH_DATED
#define LANGUAGE_GERMAN_SWISS
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
std::unique_ptr<::myImplHelpers::StyleMapperImpl< SwCharFormat > > mpImpl
Definition: msfilter.hxx:201
#define LANGUAGE_SPANISH_ARGENTINA
const SwFrameFormat * GetHeaderFormat() const
Definition: fmthdft.hxx:54
sal_uInt16 nPos
#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
sti
Definition: wwstyles.hxx:27
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.