LibreOffice Module sw (master)  1
itratr.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 <sal/config.h>
21 
22 #include <algorithm>
23 
24 #include <hintids.hxx>
26 #include <svl/itemiter.hxx>
27 #include <svx/svdobj.hxx>
28 #include <vcl/svapp.hxx>
29 #include <fmtanchr.hxx>
30 #include <fmtfsize.hxx>
31 #include <fmtornt.hxx>
32 #include <fmtflcnt.hxx>
33 #include <fmtcntnt.hxx>
34 #include <fmtftn.hxx>
35 #include <frmatr.hxx>
36 #include <frmfmt.hxx>
37 #include <fmtfld.hxx>
38 #include <doc.hxx>
40 #include <txatbase.hxx>
41 #include <viewsh.hxx>
42 #include <rootfrm.hxx>
43 #include <docary.hxx>
44 #include <ndtxt.hxx>
45 #include <fldbas.hxx>
46 #include <pam.hxx>
47 #include "itratr.hxx"
48 #include <htmltbl.hxx>
49 #include <swtable.hxx>
50 #include "redlnitr.hxx"
51 #include <redline.hxx>
52 #include <fmtsrnd.hxx>
53 #include "itrtxt.hxx"
54 #include <breakit.hxx>
55 #include <com/sun/star/i18n/WordType.hpp>
56 #include <com/sun/star/i18n/XBreakIterator.hpp>
57 #include <editeng/lrspitem.hxx>
58 #include <calbck.hxx>
59 #include <frameformats.hxx>
60 
61 using namespace ::com::sun::star::i18n;
62 using namespace ::com::sun::star;
63 
64 static sal_Int32 GetNextAttrImpl(SwTextNode const* pTextNode,
65  size_t nStartIndex, size_t nEndIndex, sal_Int32 nPosition);
66 
68  : m_pViewShell(nullptr)
69  , m_pFont(nullptr)
70  , m_pScriptInfo(nullptr)
71  , m_pLastOut(nullptr)
72  , m_nChgCnt(0)
73  , m_nStartIndex(0)
74  , m_nEndIndex(0)
75  , m_nPosition(0)
76  , m_nPropFont(0)
77  , m_pTextNode(pTextNode)
78  , m_pMergedPara(nullptr)
79 {
81 }
82 
83 SwAttrIter::SwAttrIter(SwTextNode& rTextNode, SwScriptInfo& rScrInf, SwTextFrame const*const pFrame)
84  : m_pViewShell(nullptr)
85  , m_pFont(nullptr)
86  , m_pScriptInfo(nullptr)
87  , m_pLastOut(nullptr)
88  , m_nChgCnt(0)
89  , m_nPropFont(0)
90  , m_pTextNode(&rTextNode)
91  , m_pMergedPara(nullptr)
92 {
93  CtorInitAttrIter(rTextNode, rScrInf, pFrame);
94 }
95 
96 void SwAttrIter::Chg( SwTextAttr const *pHt )
97 {
98  assert(pHt && m_pFont && "No attribute of font available for change");
99  if( m_pRedline && m_pRedline->IsOn() )
100  m_pRedline->ChangeTextAttr( m_pFont, *pHt, true );
101  else
103  m_nChgCnt++;
104 }
105 
106 void SwAttrIter::Rst( SwTextAttr const *pHt )
107 {
108  assert(pHt && m_pFont && "No attribute of font available for reset");
109  // get top from stack after removing pHt
110  if( m_pRedline && m_pRedline->IsOn() )
111  m_pRedline->ChangeTextAttr( m_pFont, *pHt, false );
112  else
113  m_aAttrHandler.PopAndChg( *pHt, *m_pFont );
114  m_nChgCnt--;
115 }
116 
118 {
119  m_pRedline.reset();
120  delete m_pFont;
121 }
122 
124 {
125  return nullptr != m_pTextNode->GetpSwpHints() || nullptr != m_pMergedPara;
126 }
127 
144 {
145  std::pair<SwTextNode const*, sal_Int32> const pos( m_pMergedPara
146  ? sw::MapViewToModel(*m_pMergedPara, nPosition)
147  : std::make_pair(m_pTextNode, sal_Int32(nPosition)));
148  return pos.first->GetTextAttrForCharAt(pos.second);
149 }
150 
152 {
153  std::pair<SwTextNode const*, sal_Int32> const pos( m_pMergedPara
154  ? sw::MapViewToModel(*m_pMergedPara, nNewPos)
155  : std::make_pair(m_pTextNode, sal_Int32(nNewPos)));
156  bool bChg = m_nStartIndex && pos.first == m_pTextNode && pos.second == m_nPosition
157  ? m_pFont->IsFntChg()
158  : Seek( nNewPos );
159  if ( m_pLastOut.get() != pOut )
160  {
161  m_pLastOut = pOut;
162  m_pFont->SetFntChg( true );
163  bChg = true;
164  }
165  if( bChg )
166  {
167  // if the change counter is zero, we know the cache id of the wanted font
168  if ( !m_nChgCnt && !m_nPropFont )
171  m_pFont->ChgPhysFnt( m_pViewShell, *pOut );
172  }
173 
174  return bChg;
175 }
176 
178 {
179  Seek( nNewPos );
180  if ( !m_nChgCnt && !m_nPropFont )
183  return m_pFont->IsSymbol( m_pViewShell );
184 }
185 
187 {
188  SwTextInfo info(const_cast<SwTextFrame*>(this));
189  SwTextIter iter(const_cast<SwTextFrame*>(this), &info);
190  return iter.IsSymbol(nPos);
191 }
192 
193 bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const bool bParaFont )
194 {
195  SwTextNode const*const pFirstTextNode(m_pMergedPara ? m_pMergedPara->pFirstNode : m_pTextNode);
196  if ( m_pRedline && m_pRedline->ExtOn() )
197  m_pRedline->LeaveExtend(*m_pFont, pFirstTextNode->GetIndex(), 0);
198 
199  if (m_pTextNode != pFirstTextNode)
200  {
201  assert(m_pMergedPara);
202  m_pTextNode = m_pMergedPara->pFirstNode;
204  m_pMergedPara->mergedText, nullptr, nullptr);
205  }
206 
207  // reset font to its original state
210 
211  m_nStartIndex = 0;
212  m_nEndIndex = 0;
213  m_nPosition = 0;
214  m_nChgCnt = 0;
215  if( m_nPropFont )
217  if( m_pRedline )
218  {
219  m_pRedline->Clear( m_pFont );
220  if( !bParaFont )
221  m_nChgCnt = m_nChgCnt + m_pRedline->Seek(*m_pFont, pFirstTextNode->GetIndex(), 0, COMPLETE_STRING);
222  else
223  m_pRedline->Reset();
224  }
225 
226  SwpHints const*const pHints(m_pTextNode->GetpSwpHints());
227  if (pHints && !bParaFont)
228  {
229  SwTextAttr *pTextAttr;
230  // While we've not reached the end of the StartArray && the TextAttribute starts at position 0...
231  while ((m_nStartIndex < pHints->Count()) &&
232  !((pTextAttr = pHints->Get(m_nStartIndex))->GetStart()))
233  {
234  // open the TextAttributes
235  Chg( pTextAttr );
236  m_nStartIndex++;
237  }
238  }
239 
240  bool bChg = m_pFont->IsFntChg();
241  if ( m_pLastOut.get() != pOut )
242  {
243  m_pLastOut = pOut;
244  m_pFont->SetFntChg( true );
245  bChg = true;
246  }
247  if( bChg )
248  {
249  // if the application counter is zero, we know the cache id of the wanted font
250  if ( !m_nChgCnt && !m_nPropFont )
253  m_pFont->ChgPhysFnt( m_pViewShell, *pOut );
254  }
255  return bChg;
256 }
257 
258 // AMA: New AttrIter Nov 94
259 void SwAttrIter::SeekFwd(const sal_Int32 nOldPos, const sal_Int32 nNewPos)
260 {
261  SwpHints const*const pHints(m_pTextNode->GetpSwpHints());
262  SwTextAttr *pTextAttr;
263  const auto nHintsCount = pHints->Count();
264 
265  if ( m_nStartIndex ) // If attributes have been opened at all ...
266  {
267  // Close attributes that are currently open, but stop at nNewPos+1
268 
269  // As long as we've not yet reached the end of EndArray and the
270  // TextAttribute ends before or at the new position ...
271  while ((m_nEndIndex < nHintsCount) &&
272  ((pTextAttr = pHints->GetSortedByEnd(m_nEndIndex))->GetAnyEnd() <= nNewPos))
273  {
274  // Close the TextAttributes, whose StartPos were before or at
275  // the old nPos and are currently open
276  if (pTextAttr->GetStart() <= nOldPos) Rst( pTextAttr );
277  m_nEndIndex++;
278  }
279  }
280  else // skip the not opened ends
281  {
282  while ((m_nEndIndex < nHintsCount) &&
283  (pHints->GetSortedByEnd(m_nEndIndex)->GetAnyEnd() <= nNewPos))
284  {
285  m_nEndIndex++;
286  }
287  }
288 
289  // As long as we've not yet reached the end of EndArray and the
290  // TextAttribute ends before or at the new position...
291  while ((m_nStartIndex < nHintsCount) &&
292  ((pTextAttr = pHints->Get(m_nStartIndex))->GetStart() <= nNewPos))
293  {
294 
295  // open the TextAttributes, whose ends lie behind the new position
296  if ( pTextAttr->GetAnyEnd() > nNewPos ) Chg( pTextAttr );
297  m_nStartIndex++;
298  }
299 
300 }
301 
302 bool SwAttrIter::Seek(TextFrameIndex const nNewPos)
303 {
304  // note: nNewPos isn't necessarily an index returned from GetNextAttr
305  std::pair<SwTextNode const*, sal_Int32> const newPos( m_pMergedPara
306  ? sw::MapViewToModel(*m_pMergedPara, nNewPos)
307  : std::make_pair(m_pTextNode, sal_Int32(nNewPos)));
308 
309  if ( m_pRedline && m_pRedline->ExtOn() )
310  m_pRedline->LeaveExtend(*m_pFont, newPos.first->GetIndex(), newPos.second);
311  if (m_pTextNode->GetIndex() < newPos.first->GetIndex())
312  {
313  // Skipping to a different node - first seek until the end of this node
314  // to get rid of all hint items
315  if (m_pTextNode->GetpSwpHints())
316  {
317  sal_Int32 nPos(m_nPosition);
318  do
319  {
320  sal_Int32 const nOldPos(nPos);
322  if (nPos <= m_pTextNode->Len())
323  {
324  SeekFwd(nOldPos, nPos);
325  }
326  else
327  {
328  SeekFwd(nOldPos, m_pTextNode->Len());
329  }
330  }
331  while (nPos < m_pTextNode->Len());
332  }
333  assert(m_nChgCnt == 0); // should have reset it all? there cannot be ExtOn() inside of a Delete redline, surely?
334  // Unapply current para items:
335  // the SwAttrHandler doesn't appear to be capable of *unapplying*
336  // items at all; it can only apply a previously effective item.
337  // So do this by recreating the font from scratch.
338  // Apply new para items:
339  assert(m_pMergedPara);
341  m_pMergedPara->mergedText, nullptr, nullptr);
342  // reset to next
343  m_pTextNode = newPos.first;
344  m_nStartIndex = 0;
345  m_nEndIndex = 0;
346  m_nPosition = 0;
347  assert(m_pRedline);
348  }
349 
350  // sw_redlinehide: Seek(0) must move before the first character, which
351  // has a special case where the first node starts with delete redline.
352  if ((!nNewPos && !m_pMergedPara)
353  || newPos.first != m_pTextNode
354  || newPos.second < m_nPosition)
355  {
356  if (m_pMergedPara)
357  {
358  if (m_pTextNode != newPos.first)
359  {
360  m_pTextNode = newPos.first;
361  // sw_redlinehide: hope it's okay to use the current text node
362  // here; the AttrHandler shouldn't care about non-char items
364  m_pMergedPara->mergedText, nullptr, nullptr);
365  }
366  }
368  {
369  if( m_pRedline )
370  m_pRedline->Clear( nullptr );
371 
372  // reset font to its original state
375 
376  if( m_nPropFont )
378  m_nStartIndex = 0;
379  m_nEndIndex = 0;
380  m_nPosition = 0;
381  m_nChgCnt = 0;
382 
383  // Attention!
384  // resetting the font here makes it necessary to apply any
385  // changes for extended input directly to the font
386  if ( m_pRedline && m_pRedline->ExtOn() )
387  {
388  m_pRedline->UpdateExtFont( *m_pFont );
389  ++m_nChgCnt;
390  }
391  }
392  }
393 
394  if (m_pTextNode->GetpSwpHints())
395  {
396  if (m_pMergedPara)
397  {
398  // iterate hint by hint: SeekFwd does not mix ends and starts,
399  // it always applies all the starts last, so it must be called once
400  // per position where hints start/end!
401  sal_Int32 nPos(m_nPosition);
402  do
403  {
404  sal_Int32 const nOldPos(nPos);
406  if (nPos <= newPos.second)
407  {
408  SeekFwd(nOldPos, nPos);
409  }
410  else
411  {
412  SeekFwd(nOldPos, newPos.second);
413  }
414  }
415  while (nPos < newPos.second);
416  }
417  else
418  {
419  SeekFwd(m_nPosition, newPos.second);
420  }
421  }
422 
424 
425  if( m_pRedline )
426  m_nChgCnt = m_nChgCnt + m_pRedline->Seek(*m_pFont, m_pTextNode->GetIndex(), newPos.second, m_nPosition);
427  m_nPosition = newPos.second;
428 
429  if( m_nPropFont )
431 
432  return m_pFont->IsFntChg();
433 }
434 
435 static void InsertCharAttrs(SfxPoolItem const** pAttrs, SfxItemSet const& rItems)
436 {
437  SfxItemIter iter(rItems);
438  for (SfxPoolItem const* pItem = iter.GetCurItem(); pItem; pItem = iter.NextItem())
439  {
440  auto const nWhich(pItem->Which());
441  if (isCHRATR(nWhich) && RES_CHRATR_RSID != nWhich)
442  {
443  pAttrs[nWhich - RES_CHRATR_BEGIN] = pItem;
444  }
445  else if (nWhich == RES_TXTATR_UNKNOWN_CONTAINER)
446  {
447  pAttrs[RES_CHRATR_END - RES_CHRATR_BEGIN] = pItem;
448  }
449  }
450 }
451 
452 // if return false: portion ends at start of redline, indexes unchanged
453 // if return true: portion end not known (past end of redline), indexes point to first hint past end of redline
454 static bool CanSkipOverRedline(
455  SwTextNode const& rStartNode, sal_Int32 const nStartRedline,
456  SwRangeRedline const& rRedline,
457  size_t & rStartIndex, size_t & rEndIndex,
458  bool const isTheAnswerYes)
459 {
460  size_t nStartIndex(rStartIndex);
461  size_t nEndIndex(rEndIndex);
462  SwPosition const*const pRLEnd(rRedline.End());
463  if (!pRLEnd->nNode.GetNode().IsTextNode() // if fully deleted...
464  || pRLEnd->nContent == pRLEnd->nNode.GetNode().GetTextNode()->Len())
465  {
466  // shortcut: nothing follows redline
467  // current state is end state
468  return false;
469  }
470  std::vector<SwTextAttr*> activeCharFmts;
471  // can't compare the SwFont that's stored somewhere, it doesn't have compare
472  // operator, so try to recreate the situation with some temp arrays here
473  SfxPoolItem const* activeCharAttrsStart[RES_CHRATR_END - RES_CHRATR_BEGIN + 1] = { nullptr, };
474  if (&rStartNode != &pRLEnd->nNode.GetNode())
475  { // nodes' attributes are only needed if there are different nodes
476  InsertCharAttrs(activeCharAttrsStart, rStartNode.GetSwAttrSet());
477  }
478  if (SwpHints const*const pStartHints = rStartNode.GetpSwpHints())
479  {
480  // check hint ends of hints that start before and end within
481  sal_Int32 const nRedlineEnd(&rStartNode == &pRLEnd->nNode.GetNode()
482  ? pRLEnd->nContent.GetIndex()
483  : rStartNode.Len());
484  for ( ; nEndIndex < pStartHints->Count(); ++nEndIndex)
485  {
486  SwTextAttr *const pAttr(pStartHints->GetSortedByEnd(nEndIndex));
487  if (!pAttr->End())
488  {
489  continue;
490  }
491  if (nRedlineEnd < *pAttr->End())
492  {
493  break;
494  }
495  if (nStartRedline <= pAttr->GetStart())
496  {
497  continue;
498  }
499  if (pAttr->IsFormatIgnoreEnd())
500  {
501  continue;
502  }
503  switch (pAttr->Which())
504  {
505  // if any of these ends inside RL then we need a new portion
506  case RES_TXTATR_REFMARK:
507  case RES_TXTATR_TOXMARK:
508  case RES_TXTATR_META: // actually these 2 aren't allowed to overlap ???
510  case RES_TXTATR_INETFMT:
511  case RES_TXTATR_CJK_RUBY:
514  {
515  if (!isTheAnswerYes) return false; // always break
516  }
517  break;
518  // these are guaranteed not to overlap
519  // and come in order of application
520  case RES_TXTATR_AUTOFMT:
521  case RES_TXTATR_CHARFMT:
522  {
523  if (pAttr->Which() == RES_TXTATR_CHARFMT)
524  {
525  activeCharFmts.push_back(pAttr);
526  }
527  // pure formatting hints may end inside the redline &
528  // start again inside the redline, which must not cause
529  // a new text portion if they have the same items - so
530  // store the effective items & compare all at the end
531  SfxItemSet const& rSet((pAttr->Which() == RES_TXTATR_CHARFMT)
532  ? static_cast<SfxItemSet const&>(pAttr->GetCharFormat().GetCharFormat()->GetAttrSet())
533  : *pAttr->GetAutoFormat().GetStyleHandle());
534  InsertCharAttrs(activeCharAttrsStart, rSet);
535  }
536  break;
537  // SwTextNode::SetAttr puts it into AUTOFMT which is quite
538  // sensible so it doesn't actually exist as a hint
540  default: assert(false);
541  }
542  }
543  assert(nEndIndex == pStartHints->Count() ||
544  pRLEnd->nContent.GetIndex() < pStartHints->GetSortedByEnd(nEndIndex)->GetAnyEnd());
545  }
546 
547  if (&rStartNode != &pRLEnd->nNode.GetNode())
548  {
549  nStartIndex = 0;
550  nEndIndex = 0;
551  }
552 
553  // treat para properties as text properties
554  // ... with the FormatToTextAttr we get autofmts that correspond to the *effective* attr set difference
555  // effective attr set: para props + charfmts + autofmt *in that order*
556  // ... and the charfmt must be *nominally* the same
557 
558  SfxPoolItem const* activeCharAttrsEnd[RES_CHRATR_END - RES_CHRATR_BEGIN + 1] = { nullptr, };
559  if (&rStartNode != &pRLEnd->nNode.GetNode())
560  { // nodes' attributes are only needed if there are different nodes
561  InsertCharAttrs(activeCharAttrsEnd,
562  pRLEnd->nNode.GetNode().GetTextNode()->GetSwAttrSet());
563  }
564 
565  if (SwpHints *const pEndHints = pRLEnd->nNode.GetNode().GetTextNode()->GetpSwpHints())
566  {
567  // check hint starts of hints that start within and end after
568 #ifndef NDEBUG
569  sal_Int32 const nRedlineStart(&rStartNode == &pRLEnd->nNode.GetNode()
570  ? nStartRedline
571  : 0);
572 #endif
573  for ( ; nStartIndex < pEndHints->Count(); ++nStartIndex)
574  {
575  SwTextAttr *const pAttr(pEndHints->Get(nStartIndex));
576  // compare with < here, not <=, to get the effective formatting
577  // of the 1st char after the redline; should not cause problems
578  // with consecutive delete redlines because those are handed by
579  // GetNextRedln() and here we have the last end pos.
580  if (pRLEnd->nContent.GetIndex() < pAttr->GetStart())
581  {
582  break;
583  }
584  if (!pAttr->End())
585  continue;
586  if (pAttr->IsFormatIgnoreStart())
587  {
588  continue;
589  }
590  assert(nRedlineStart <= pAttr->GetStart()); // we wouldn't be here otherwise?
591  if (*pAttr->End() <= pRLEnd->nContent.GetIndex())
592  {
593  continue;
594  }
595  switch (pAttr->Which())
596  {
597  case RES_TXTATR_REFMARK:
598  case RES_TXTATR_TOXMARK:
599  case RES_TXTATR_META: // actually these 2 aren't allowed to overlap ???
601  case RES_TXTATR_INETFMT:
602  case RES_TXTATR_CJK_RUBY:
605  {
606  if (!isTheAnswerYes) return false;
607  }
608  break;
609  case RES_TXTATR_AUTOFMT:
610  case RES_TXTATR_CHARFMT:
611  {
612  // char formats must be *nominally* the same
613  if (pAttr->Which() == RES_TXTATR_CHARFMT)
614  {
615  auto iter = std::find_if(activeCharFmts.begin(), activeCharFmts.end(),
616  [&pAttr](const SwTextAttr* pCharFmt) { return *pCharFmt == *pAttr; });
617  if (iter != activeCharFmts.end())
618  activeCharFmts.erase(iter);
619  else if (!isTheAnswerYes)
620  return false;
621  }
622  SfxItemSet const& rSet((pAttr->Which() == RES_TXTATR_CHARFMT)
623  ? static_cast<SfxItemSet const&>(pAttr->GetCharFormat().GetCharFormat()->GetAttrSet())
624  : *pAttr->GetAutoFormat().GetStyleHandle());
625  InsertCharAttrs(activeCharAttrsEnd, rSet);
626 
627  }
628  break;
629  // SwTextNode::SetAttr puts it into AUTOFMT which is quite
630  // sensible so it doesn't actually exist as a hint
632  default: assert(false);
633  }
634  }
635  if (&rStartNode != &pRLEnd->nNode.GetNode())
636  {
637  // need to iterate the nEndIndex forward too so the loop in the
638  // caller can look for the right ends in the next iteration
639  for (nEndIndex = 0; nEndIndex < pEndHints->Count(); ++nEndIndex)
640  {
641  SwTextAttr *const pAttr(pEndHints->GetSortedByEnd(nEndIndex));
642  if (!pAttr->End())
643  continue;
644  if (pRLEnd->nContent.GetIndex() < *pAttr->End())
645  {
646  break;
647  }
648  }
649  }
650  }
651 
652  // if we didn't find a matching start for any end, then it really ends inside
653  if (!activeCharFmts.empty())
654  {
655  if (!isTheAnswerYes) return false;
656  }
657  for (size_t i = 0; i < SAL_N_ELEMENTS(activeCharAttrsStart); ++i)
658  {
659  // all of these are poolable
660 // assert(!activeCharAttrsStart[i] || activeCharAttrsStart[i]->GetItemPool()->IsItemPoolable(*activeCharAttrsStart[i]));
661  if (activeCharAttrsStart[i] != activeCharAttrsEnd[i])
662  {
663  if (!isTheAnswerYes) return false;
664  }
665  }
666  rStartIndex = nStartIndex;
667  rEndIndex = nEndIndex;
668  return true;
669 }
670 
671 static sal_Int32 GetNextAttrImpl(SwTextNode const*const pTextNode,
672  size_t const nStartIndex, size_t const nEndIndex,
673  sal_Int32 const nPosition)
674 {
675  // note: this used to be COMPLETE_STRING, but was set to Len() + 1 below,
676  // which is rather silly, so set it to Len() instead
677  sal_Int32 nNext = pTextNode->Len();
678  if (SwpHints const*const pHints = pTextNode->GetpSwpHints())
679  {
680  // are there attribute starts left?
681  for (size_t i = nStartIndex; i < pHints->Count(); ++i)
682  {
683  SwTextAttr *const pAttr(pHints->Get(i));
684  if (!pAttr->IsFormatIgnoreStart())
685  {
686  nNext = pAttr->GetStart();
687  break;
688  }
689  }
690  // are there attribute ends left?
691  for (size_t i = nEndIndex; i < pHints->Count(); ++i)
692  {
693  SwTextAttr *const pAttr(pHints->GetSortedByEnd(i));
694  if (!pAttr->IsFormatIgnoreEnd())
695  {
696  sal_Int32 const nNextEnd = pAttr->GetAnyEnd();
697  nNext = std::min(nNext, nNextEnd); // pick nearest one
698  break;
699  }
700  }
701  }
702  // TODO: maybe use hints like FieldHints for this instead of looking at the text...
703  const sal_Int32 l = std::min(nNext, pTextNode->Len());
704  sal_Int32 p = nPosition;
705  const sal_Unicode* pStr = pTextNode->GetText().getStr();
706  while (p < l)
707  {
708  sal_Unicode aChar = pStr[p];
709  switch (aChar)
710  {
713  case CH_TXT_ATR_FIELDSEP:
714  case CH_TXT_ATR_FIELDEND:
715  goto break_; // sigh...
716  default:
717  ++p;
718  }
719  }
720 break_:
721  assert(p <= nNext);
722  if (p < l)
723  {
724  // found a CH_TXT_ATR_FIELD*: if it's same as current position,
725  // skip behind it so that both before- and after-positions are returned
726  nNext = (nPosition < p) ? p : p + 1;
727  }
728  return nNext;
729 }
730 
732 {
733  size_t nStartIndex(m_nStartIndex);
734  size_t nEndIndex(m_nEndIndex);
735  size_t nPosition(m_nPosition);
736  SwTextNode const* pTextNode(m_pTextNode);
738 
739  while (true)
740  {
741  sal_Int32 nNext = GetNextAttrImpl(pTextNode, nStartIndex, nEndIndex, nPosition);
742  if( m_pRedline )
743  {
744  std::pair<sal_Int32, std::pair<SwRangeRedline const*, size_t>> const redline(
745  m_pRedline->GetNextRedln(nNext, pTextNode, nActRedline));
746  if (redline.second.first)
747  {
748  assert(m_pMergedPara);
749  assert(redline.second.first->End()->nNode.GetIndex() <= m_pMergedPara->pLastNode->GetIndex()
750  || !redline.second.first->End()->nNode.GetNode().IsTextNode());
751  if (CanSkipOverRedline(*pTextNode, redline.first, *redline.second.first,
752  nStartIndex, nEndIndex, m_nPosition == redline.first))
753  { // if current position is start of the redline, must skip!
754  nActRedline += redline.second.second;
755  if (&redline.second.first->End()->nNode.GetNode() != pTextNode)
756  {
757  pTextNode = redline.second.first->End()->nNode.GetNode().GetTextNode();
758  nPosition = redline.second.first->End()->nContent.GetIndex();
759  }
760  else
761  {
762  nPosition = redline.second.first->End()->nContent.GetIndex();
763  }
764  }
765  else
766  {
767  return sw::MapModelToView(*m_pMergedPara, pTextNode, redline.first);
768  }
769  }
770  else
771  {
772  return m_pMergedPara
773  ? sw::MapModelToView(*m_pMergedPara, pTextNode, redline.first)
774  : TextFrameIndex(redline.first);
775  }
776  }
777  else
778  {
779  return TextFrameIndex(nNext);
780  }
781  }
782 }
783 
784 namespace {
785 
786 class SwMinMaxArgs
787 {
788 public:
789  VclPtr<OutputDevice> m_pOut;
790  SwViewShell const* m_pSh;
791  sal_uLong& m_rMin;
792  sal_uLong& m_rAbsMin;
793  tools::Long m_nRowWidth;
794  tools::Long m_nWordWidth;
795  tools::Long m_nWordAdd;
796  sal_Int32 m_nNoLineBreak;
797  SwMinMaxArgs(OutputDevice* pOutI, SwViewShell const* pShI, sal_uLong& rMinI, sal_uLong& rAbsI)
798  : m_pOut(pOutI)
799  , m_pSh(pShI)
800  , m_rMin(rMinI)
801  , m_rAbsMin(rAbsI)
802  , m_nRowWidth(0)
803  , m_nWordWidth(0)
804  , m_nWordAdd(0)
805  , m_nNoLineBreak(COMPLETE_STRING)
806  { }
807  void Minimum( tools::Long nNew ) const {
808  if (static_cast<tools::Long>(m_rMin) < nNew)
809  m_rMin = nNew;
810  }
811  void NewWord() { m_nWordAdd = m_nWordWidth = 0; }
812 };
813 
814 }
815 
816 static bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const OUString &rText,
817  sal_Int32 nIdx, sal_Int32 nEnd )
818 {
819  bool bRet = false;
820  while( nIdx < nEnd )
821  {
822  sal_Int32 nStop = nIdx;
823  LanguageType eLang = pFnt->GetLanguage();
824  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
825 
826  bool bClear = CH_BLANK == rText[ nStop ];
827  Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary( rText, nIdx,
828  g_pBreakIt->GetLocale( eLang ),
829  WordType::DICTIONARY_WORD, true ) );
830  nStop = aBndry.endPos;
831  if (nIdx <= aBndry.startPos && nIdx && nIdx - 1 != rArg.m_nNoLineBreak)
832  rArg.NewWord();
833  if( nStop == nIdx )
834  ++nStop;
835  if( nStop > nEnd )
836  nStop = nEnd;
837 
838  SwDrawTextInfo aDrawInf(rArg.m_pSh, *rArg.m_pOut, rText, nIdx, nStop - nIdx);
839  tools::Long nCurrentWidth = pFnt->GetTextSize_( aDrawInf ).Width();
840  rArg.m_nRowWidth += nCurrentWidth;
841  if( bClear )
842  rArg.NewWord();
843  else
844  {
845  rArg.m_nWordWidth += nCurrentWidth;
846  if (static_cast<tools::Long>(rArg.m_rAbsMin) < rArg.m_nWordWidth)
847  rArg.m_rAbsMin = rArg.m_nWordWidth;
848  rArg.Minimum(rArg.m_nWordWidth + rArg.m_nWordAdd);
849  bRet = true;
850  }
851  nIdx = nStop;
852  }
853  return bRet;
854 }
855 
856 bool SwTextNode::IsSymbolAt(const sal_Int32 nBegin) const
857 {
858  SwScriptInfo aScriptInfo;
859  SwAttrIter aIter( *const_cast<SwTextNode*>(this), aScriptInfo );
860  aIter.Seek( TextFrameIndex(nBegin) );
861  return aIter.GetFnt()->IsSymbol( getIDocumentLayoutAccess().GetCurrentViewShell() );
862 }
863 
864 namespace {
865 
866 class SwMinMaxNodeArgs
867 {
868 public:
869  sal_uLong m_nMaxWidth; // sum of all frame widths
870  tools::Long m_nMinWidth; // biggest frame
871  tools::Long m_nLeftRest; // space not already covered by frames in the left margin
872  tools::Long m_nRightRest; // space not already covered by frames in the right margin
873  tools::Long m_nLeftDiff; // Min/Max-difference of the frame in the left margin
874  tools::Long m_nRightDiff; // Min/Max-difference of the frame in the right margin
875  SwNodeOffset m_nIndex; // index of the node
876  void Minimum( tools::Long nNew ) {
877  if (nNew > m_nMinWidth)
878  m_nMinWidth = nNew;
879  }
880 };
881 
882 }
883 
884 static void lcl_MinMaxNode(SwFrameFormat* pNd, SwMinMaxNodeArgs& rIn)
885 {
886  const SwFormatAnchor& rFormatA = pNd->GetAnchor();
887 
888  if ((RndStdIds::FLY_AT_PARA != rFormatA.GetAnchorId()) &&
889  (RndStdIds::FLY_AT_CHAR != rFormatA.GetAnchorId()))
890  {
891  return;
892  }
893 
894  const SwPosition *pPos = rFormatA.GetContentAnchor();
895  OSL_ENSURE(pPos, "Unexpected NULL arguments");
896  if (!pPos || rIn.m_nIndex != pPos->nNode.GetIndex())
897  return;
898 
899  tools::Long nMin, nMax;
900  SwHTMLTableLayout *pLayout = nullptr;
901  const bool bIsDrawFrameFormat = pNd->Which()==RES_DRAWFRMFMT;
902  if( !bIsDrawFrameFormat )
903  {
904  // Does the frame contain a table at the start or the end?
905  const SwNodes& rNodes = pNd->GetDoc()->GetNodes();
906  const SwFormatContent& rFlyContent = pNd->GetContent();
907  SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex();
908  SwTableNode* pTableNd = rNodes[nStt+1]->GetTableNode();
909  if( !pTableNd )
910  {
911  SwNode *pNd2 = rNodes[nStt];
912  pNd2 = rNodes[pNd2->EndOfSectionIndex()-1];
913  if( pNd2->IsEndNode() )
914  pTableNd = pNd2->StartOfSectionNode()->GetTableNode();
915  }
916 
917  if( pTableNd )
918  pLayout = pTableNd->GetTable().GetHTMLTableLayout();
919  }
920 
921  const SwFormatHoriOrient& rOrient = pNd->GetHoriOrient();
922  sal_Int16 eHoriOri = rOrient.GetHoriOrient();
923 
924  tools::Long nDiff;
925  if( pLayout )
926  {
927  nMin = pLayout->GetMin();
928  nMax = pLayout->GetMax();
929  nDiff = nMax - nMin;
930  }
931  else
932  {
933  if( bIsDrawFrameFormat )
934  {
935  const SdrObject* pSObj = pNd->FindSdrObject();
936  if( pSObj )
937  nMin = pSObj->GetCurrentBoundRect().GetWidth();
938  else
939  nMin = 0;
940 
941  }
942  else
943  {
944  const SwFormatFrameSize &rSz = pNd->GetFrameSize();
945  nMin = rSz.GetWidth();
946  }
947  nMax = nMin;
948  nDiff = 0;
949  }
950 
951  const SvxLRSpaceItem &rLR = pNd->GetLRSpace();
952  nMin += rLR.GetLeft();
953  nMin += rLR.GetRight();
954  nMax += rLR.GetLeft();
955  nMax += rLR.GetRight();
956 
957  if( css::text::WrapTextMode_THROUGH == pNd->GetSurround().GetSurround() )
958  {
959  rIn.Minimum( nMin );
960  return;
961  }
962 
963  // Frames, which are left- or right-aligned are only party considered
964  // when calculating the maximum, since the border is already being considered.
965  // Only if the frame extends into the text body, this part is being added
966  switch( eHoriOri )
967  {
968  case text::HoriOrientation::RIGHT:
969  {
970  if( nDiff )
971  {
972  rIn.m_nRightRest -= rIn.m_nRightDiff;
973  rIn.m_nRightDiff = nDiff;
974  }
975  if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
976  {
977  if (rIn.m_nRightRest > 0)
978  rIn.m_nRightRest = 0;
979  }
980  rIn.m_nRightRest -= nMin;
981  break;
982  }
983  case text::HoriOrientation::LEFT:
984  {
985  if( nDiff )
986  {
987  rIn.m_nLeftRest -= rIn.m_nLeftDiff;
988  rIn.m_nLeftDiff = nDiff;
989  }
990  if (text::RelOrientation::FRAME != rOrient.GetRelationOrient() && rIn.m_nLeftRest < 0)
991  rIn.m_nLeftRest = 0;
992  rIn.m_nLeftRest -= nMin;
993  break;
994  }
995  default:
996  {
997  rIn.m_nMaxWidth += nMax;
998  rIn.Minimum(nMin);
999  }
1000  }
1001 }
1002 
1003 #define FLYINCNT_MIN_WIDTH 284
1004 
1010  sal_uLong& rAbsMin ) const
1011 {
1013  OutputDevice* pOut = nullptr;
1014  if( pSh )
1015  pOut = pSh->GetWin()->GetOutDev();
1016  if( !pOut )
1018 
1019  MapMode aOldMap( pOut->GetMapMode() );
1020  pOut->SetMapMode( MapMode( MapUnit::MapTwip ) );
1021 
1022  rMin = 0;
1023  rMax = 0;
1024  rAbsMin = 0;
1025 
1026  const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
1027  tools::Long nLROffset = rSpace.GetTextLeft() + GetLeftMarginWithNum( true );
1028  short nFLOffs;
1029  // For enumerations a negative first line indentation is probably filled already
1030  if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
1031  nLROffset = nFLOffs;
1032 
1033  SwMinMaxNodeArgs aNodeArgs;
1034  aNodeArgs.m_nMinWidth = 0;
1035  aNodeArgs.m_nMaxWidth = 0;
1036  aNodeArgs.m_nLeftRest = nLROffset;
1037  aNodeArgs.m_nRightRest = rSpace.GetRight();
1038  aNodeArgs.m_nLeftDiff = 0;
1039  aNodeArgs.m_nRightDiff = 0;
1040  if( nIndex )
1041  {
1042  SwFrameFormats* pTmp = const_cast<SwFrameFormats*>(GetDoc().GetSpzFrameFormats());
1043  if( pTmp )
1044  {
1045  aNodeArgs.m_nIndex = nIndex;
1046  for( SwFrameFormat *pFormat : *pTmp )
1047  lcl_MinMaxNode(pFormat, aNodeArgs);
1048  }
1049  }
1050  if (aNodeArgs.m_nLeftRest < 0)
1051  aNodeArgs.Minimum(nLROffset - aNodeArgs.m_nLeftRest);
1052  aNodeArgs.m_nLeftRest -= aNodeArgs.m_nLeftDiff;
1053  if (aNodeArgs.m_nLeftRest < 0)
1054  aNodeArgs.m_nMaxWidth -= aNodeArgs.m_nLeftRest;
1055 
1056  if (aNodeArgs.m_nRightRest < 0)
1057  aNodeArgs.Minimum(rSpace.GetRight() - aNodeArgs.m_nRightRest);
1058  aNodeArgs.m_nRightRest -= aNodeArgs.m_nRightDiff;
1059  if (aNodeArgs.m_nRightRest < 0)
1060  aNodeArgs.m_nMaxWidth -= aNodeArgs.m_nRightRest;
1061 
1062  SwScriptInfo aScriptInfo;
1063  SwAttrIter aIter( *const_cast<SwTextNode*>(this), aScriptInfo );
1064  TextFrameIndex nIdx(0);
1065  aIter.SeekAndChgAttrIter( nIdx, pOut );
1066  TextFrameIndex nLen(m_Text.getLength());
1067  tools::Long nCurrentWidth = 0;
1068  tools::Long nAdd = 0;
1069  SwMinMaxArgs aArg( pOut, pSh, rMin, rAbsMin );
1070  while( nIdx < nLen )
1071  {
1072  TextFrameIndex nNextChg = aIter.GetNextAttr();
1073  TextFrameIndex nStop = aScriptInfo.NextScriptChg( nIdx );
1074  if( nNextChg > nStop )
1075  nNextChg = nStop;
1076  SwTextAttr *pHint = nullptr;
1077  sal_Unicode cChar = CH_BLANK;
1078  nStop = nIdx;
1079  while( nStop < nLen && nStop < nNextChg &&
1080  CH_TAB != (cChar = m_Text[sal_Int32(nStop)]) &&
1081  CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
1082  CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
1083  CH_TXT_ATR_INPUTFIELDSTART != cChar &&
1084  CH_TXT_ATR_INPUTFIELDEND != cChar &&
1085  CH_TXT_ATR_FORMELEMENT != cChar &&
1086  CH_TXT_ATR_FIELDSTART != cChar &&
1087  CH_TXT_ATR_FIELDSEP != cChar &&
1088  CH_TXT_ATR_FIELDEND != cChar &&
1089  !pHint )
1090  {
1091  // this looks like some defensive programming to handle dummy char
1092  // with missing hint? but it's rather silly because it may pass the
1093  // dummy char to lcl_MinMaxString in that case...
1094  if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
1095  || ( nullptr == ( pHint = aIter.GetAttr( nStop ) ) ) )
1096  ++nStop;
1097  }
1098  if (lcl_MinMaxString(aArg, aIter.GetFnt(), m_Text, sal_Int32(nIdx), sal_Int32(nStop)))
1099  {
1100  nAdd = 20;
1101  }
1102  nIdx = nStop;
1103  aIter.SeekAndChgAttrIter( nIdx, pOut );
1104  switch( cChar )
1105  {
1106  case CH_BREAK :
1107  {
1108  if (static_cast<tools::Long>(rMax) < aArg.m_nRowWidth)
1109  rMax = aArg.m_nRowWidth;
1110  aArg.m_nRowWidth = 0;
1111  aArg.NewWord();
1112  aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1113  }
1114  break;
1115  case CH_TAB :
1116  {
1117  aArg.NewWord();
1118  aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1119  }
1120  break;
1121  case CHAR_SOFTHYPHEN:
1122  ++nIdx;
1123  break;
1124  case CHAR_HARDBLANK:
1125  case CHAR_HARDHYPHEN:
1126  {
1127  OUString sTmp( cChar );
1128  SwDrawTextInfo aDrawInf( pSh,
1129  *pOut, sTmp, 0, 1, 0, false );
1130  nCurrentWidth = aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1131  aArg.m_nWordWidth += nCurrentWidth;
1132  aArg.m_nRowWidth += nCurrentWidth;
1133  if (static_cast<tools::Long>(rAbsMin) < aArg.m_nWordWidth)
1134  rAbsMin = aArg.m_nWordWidth;
1135  aArg.Minimum(aArg.m_nWordWidth + aArg.m_nWordAdd);
1136  aArg.m_nNoLineBreak = sal_Int32(nIdx++);
1137  }
1138  break;
1139  case CH_TXTATR_BREAKWORD:
1140  case CH_TXTATR_INWORD:
1141  {
1142  if( !pHint )
1143  break;
1144  tools::Long nOldWidth = aArg.m_nWordWidth;
1145  tools::Long nOldAdd = aArg.m_nWordAdd;
1146  aArg.NewWord();
1147 
1148  switch( pHint->Which() )
1149  {
1150  case RES_TXTATR_FLYCNT :
1151  {
1152  SwFrameFormat *pFrameFormat = pHint->GetFlyCnt().GetFrameFormat();
1153  const SvxLRSpaceItem &rLR = pFrameFormat->GetLRSpace();
1154  if( RES_DRAWFRMFMT == pFrameFormat->Which() )
1155  {
1156  const SdrObject* pSObj = pFrameFormat->FindSdrObject();
1157  if( pSObj )
1158  nCurrentWidth = pSObj->GetCurrentBoundRect().GetWidth();
1159  else
1160  nCurrentWidth = 0;
1161  }
1162  else
1163  {
1164  const SwFormatFrameSize& rTmpSize = pFrameFormat->GetFrameSize();
1165  if( RES_FLYFRMFMT == pFrameFormat->Which()
1166  && rTmpSize.GetWidthPercent() )
1167  {
1168  // This is a hack for the following situation: In the paragraph there's a
1169  // text frame with relative size. Then let's take 0.5 cm as minimum width
1170  // and USHRT_MAX as maximum width
1171  // It were cleaner and maybe necessary later on to iterate over the content
1172  // of the text frame and call GetMinMaxSize recursively
1173  nCurrentWidth = FLYINCNT_MIN_WIDTH; // 0.5 cm
1174  rMax = std::max(rMax, sal_uLong(USHRT_MAX));
1175  }
1176  else
1177  nCurrentWidth = pFrameFormat->GetFrameSize().GetWidth();
1178  }
1179  nCurrentWidth += rLR.GetLeft();
1180  nCurrentWidth += rLR.GetRight();
1181  aArg.m_nWordAdd = nOldWidth + nOldAdd;
1182  aArg.m_nWordWidth = nCurrentWidth;
1183  aArg.m_nRowWidth += nCurrentWidth;
1184  if (static_cast<tools::Long>(rAbsMin) < aArg.m_nWordWidth)
1185  rAbsMin = aArg.m_nWordWidth;
1186  aArg.Minimum(aArg.m_nWordWidth + aArg.m_nWordAdd);
1187  break;
1188  }
1189  case RES_TXTATR_FTN :
1190  {
1191  const OUString aText = pHint->GetFootnote().GetNumStr();
1192  if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, 0,
1193  aText.getLength() ) )
1194  nAdd = 20;
1195  break;
1196  }
1197 
1198  case RES_TXTATR_FIELD :
1199  case RES_TXTATR_ANNOTATION :
1200  {
1201  SwField *pField = const_cast<SwField*>(pHint->GetFormatField().GetField());
1202  const OUString aText = pField->ExpandField(true, nullptr);
1203  if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, 0,
1204  aText.getLength() ) )
1205  nAdd = 20;
1206  break;
1207  }
1208  default:
1209  aArg.m_nWordWidth = nOldWidth;
1210  aArg.m_nWordAdd = nOldAdd;
1211  }
1212  aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1213  }
1214  break;
1218  case CH_TXT_ATR_FIELDSTART:
1219  case CH_TXT_ATR_FIELDSEP:
1220  case CH_TXT_ATR_FIELDEND:
1221  { // just skip it and continue with the content...
1222  aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1223  }
1224  break;
1225  }
1226  }
1227  if (static_cast<tools::Long>(rMax) < aArg.m_nRowWidth)
1228  rMax = aArg.m_nRowWidth;
1229 
1230  nLROffset += rSpace.GetRight();
1231 
1232  rAbsMin += nLROffset;
1233  rAbsMin += nAdd;
1234  rMin += nLROffset;
1235  rMin += nAdd;
1236  if (static_cast<tools::Long>(rMin) < aNodeArgs.m_nMinWidth)
1237  rMin = aNodeArgs.m_nMinWidth;
1238  if (static_cast<tools::Long>(rAbsMin) < aNodeArgs.m_nMinWidth)
1239  rAbsMin = aNodeArgs.m_nMinWidth;
1240  rMax += aNodeArgs.m_nMaxWidth;
1241  rMax += nLROffset;
1242  rMax += nAdd;
1243  if( rMax < rMin ) // e.g. Frames with flow through only contribute to the minimum
1244  rMax = rMin;
1245  pOut->SetMapMode( aOldMap );
1246 }
1247 
1258  TextFrameIndex nStart, TextFrameIndex nEnd)
1259 {
1260  assert(GetOffset() <= nStart && (!GetFollow() || nStart < GetFollow()->GetOffset()));
1261  SwViewShell const*const pSh = getRootFrame()->GetCurrShell();
1262  assert(pSh);
1263  OutputDevice *const pOut = &pSh->GetRefDev();
1264  assert(pOut);
1265 
1266  MapMode aOldMap( pOut->GetMapMode() );
1267  pOut->SetMapMode( MapMode( MapUnit::MapTwip ) );
1268 
1269  if (nStart == nEnd)
1270  {
1271  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
1272 
1273  SwScriptInfo aScriptInfo;
1274  SwAttrIter aIter(*GetTextNodeFirst(), aScriptInfo, this);
1275  aIter.SeekAndChgAttrIter( nStart, pOut );
1276 
1277  Boundary aBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
1278  GetText(), sal_Int32(nStart),
1279  g_pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
1280  WordType::DICTIONARY_WORD, true );
1281 
1282  if (sal_Int32(nStart) == aBound.startPos)
1283  {
1284  // cursor is at left or right border of word
1285  pOut->SetMapMode( aOldMap );
1286  return 100;
1287  }
1288 
1289  nStart = TextFrameIndex(aBound.startPos);
1290  nEnd = TextFrameIndex(aBound.endPos);
1291 
1292  if (nStart == nEnd)
1293  {
1294  pOut->SetMapMode( aOldMap );
1295  return 100;
1296  }
1297  }
1298 
1299  SwScriptInfo aScriptInfo;
1300  SwAttrIter aIter(*GetTextNodeFirst(), aScriptInfo, this);
1301 
1302  // We do not want scaling attributes to be considered during this
1303  // calculation. For this, we push a temporary scaling attribute with
1304  // scaling value 100 and priority flag on top of the scaling stack
1305  SwAttrHandler& rAH = aIter.GetAttrHandler();
1307  SwTextAttrEnd aAttr( aItem, 0, COMPLETE_STRING );
1308  aAttr.SetPriorityAttr( true );
1309  rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
1310 
1311  TextFrameIndex nIdx = nStart;
1312 
1313  sal_uLong nWidth = 0;
1314  sal_uLong nProWidth = 0;
1315 
1316  while( nIdx < nEnd )
1317  {
1318  aIter.SeekAndChgAttrIter( nIdx, pOut );
1319 
1320  // scan for end of portion
1321  TextFrameIndex const nNextChg = std::min(aIter.GetNextAttr(), aScriptInfo.NextScriptChg(nIdx));
1322 
1323  TextFrameIndex nStop = nIdx;
1324  sal_Unicode cChar = CH_BLANK;
1325  SwTextAttr* pHint = nullptr;
1326 
1327  // stop at special characters in [ nIdx, nNextChg ]
1328  while( nStop < nEnd && nStop < nNextChg )
1329  {
1330  cChar = GetText()[sal_Int32(nStop)];
1331  if (
1332  CH_TAB == cChar ||
1333  CH_BREAK == cChar ||
1334  CHAR_HARDBLANK == cChar ||
1335  CHAR_HARDHYPHEN == cChar ||
1336  CHAR_SOFTHYPHEN == cChar ||
1337  CH_TXT_ATR_INPUTFIELDSTART == cChar ||
1338  CH_TXT_ATR_INPUTFIELDEND == cChar ||
1339  CH_TXT_ATR_FORMELEMENT == cChar ||
1340  CH_TXT_ATR_FIELDSTART == cChar ||
1341  CH_TXT_ATR_FIELDSEP == cChar ||
1342  CH_TXT_ATR_FIELDEND == cChar ||
1343  (
1344  (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
1345  (nullptr == (pHint = aIter.GetAttr(nStop)))
1346  )
1347  )
1348  {
1349  break;
1350  }
1351  else
1352  ++nStop;
1353  }
1354 
1355  // calculate text widths up to cChar
1356  if ( nStop > nIdx )
1357  {
1358  SwDrawTextInfo aDrawInf(pSh, *pOut, GetText(), sal_Int32(nIdx), sal_Int32(nStop - nIdx));
1359  nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1360  }
1361 
1362  nIdx = nStop;
1363  aIter.SeekAndChgAttrIter( nIdx, pOut );
1364 
1365  if ( cChar == CH_BREAK )
1366  {
1367  nWidth = std::max( nWidth, nProWidth );
1368  nProWidth = 0;
1369  nIdx++;
1370  }
1371  else if ( cChar == CH_TAB )
1372  {
1373  // tab receives width of one space
1374  SwDrawTextInfo aDrawInf(pSh, *pOut, OUStringChar(CH_BLANK), 0, 1);
1375  nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1376  nIdx++;
1377  }
1378  else if ( cChar == CHAR_SOFTHYPHEN )
1379  ++nIdx;
1380  else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
1381  {
1382  OUString sTmp( cChar );
1383  SwDrawTextInfo aDrawInf(pSh, *pOut, sTmp, 0, 1);
1384  nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1385  nIdx++;
1386  }
1387  else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || cChar == CH_TXTATR_INWORD ) )
1388  {
1389  switch( pHint->Which() )
1390  {
1391  case RES_TXTATR_FTN :
1392  {
1393  const OUString aText = pHint->GetFootnote().GetNumStr();
1394  SwDrawTextInfo aDrawInf(pSh, *pOut, aText, 0, aText.getLength());
1395 
1396  nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1397  break;
1398  }
1399 
1400  case RES_TXTATR_FIELD :
1401  case RES_TXTATR_ANNOTATION :
1402  {
1403  SwField *pField = const_cast<SwField*>(pHint->GetFormatField().GetField());
1404  OUString const aText = pField->ExpandField(true, getRootFrame());
1405  SwDrawTextInfo aDrawInf(pSh, *pOut, aText, 0, aText.getLength());
1406 
1407  nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1408  break;
1409  }
1410 
1411  default:
1412  {
1413  // any suggestions for a default action?
1414  }
1415  } // end of switch
1416  nIdx++;
1417  }
1418  else if (CH_TXT_ATR_INPUTFIELDSTART == cChar ||
1419  CH_TXT_ATR_INPUTFIELDEND == cChar ||
1420  CH_TXT_ATR_FORMELEMENT == cChar ||
1421  CH_TXT_ATR_FIELDSTART == cChar ||
1422  CH_TXT_ATR_FIELDSEP == cChar ||
1423  CH_TXT_ATR_FIELDEND == cChar)
1424  { // just skip it and continue with the content...
1425  ++nIdx;
1426  }
1427  } // end of while
1428 
1429  nWidth = std::max( nWidth, nProWidth );
1430 
1431  // search for the line containing nStart
1432  if (HasPara())
1433  {
1434  SwTextInfo aInf(this);
1435  SwTextIter aLine(this, &aInf);
1436  aLine.CharToLine( nStart );
1437  pOut->SetMapMode( aOldMap );
1438  return o3tl::narrowing<sal_uInt16>( nWidth ?
1439  ( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
1440  }
1441  // no frame or no paragraph, we take the height of the character
1442  // at nStart as line height
1443 
1444  aIter.SeekAndChgAttrIter( nStart, pOut );
1445  pOut->SetMapMode( aOldMap );
1446 
1447  SwDrawTextInfo aDrawInf(pSh, *pOut, GetText(), sal_Int32(nStart), 1);
1448  return o3tl::narrowing<sal_uInt16>( nWidth ? ((100 * aIter.GetFnt()->GetTextSize_( aDrawInf ).Height()) / nWidth ) : 0 );
1449 }
1450 
1452 {
1453  SwTwips nRet = 0;
1454 
1455  sal_Int32 nIdx = 0;
1456 
1457  while ( nIdx < GetText().getLength() )
1458  {
1459  const sal_Unicode cCh = GetText()[nIdx];
1460  if ( cCh!='\t' && cCh!=' ' )
1461  {
1462  break;
1463  }
1464  ++nIdx;
1465  }
1466 
1467  if ( nIdx > 0 )
1468  {
1469  SwPosition aPos( *this );
1470  aPos.nContent += nIdx;
1471 
1472  // Find the non-follow text frame:
1474  for( SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
1475  {
1476  // Only consider master frames:
1477  if (!pFrame->IsFollow() &&
1478  pFrame->GetTextNodeForFirstText() == this)
1479  {
1480  SwRectFnSet aRectFnSet(pFrame);
1481  SwRect aRect;
1482  pFrame->GetCharRect( aRect, aPos );
1483  nRet = pFrame->IsRightToLeft() ?
1484  aRectFnSet.GetPrtRight(*pFrame) - aRectFnSet.GetRight(aRect) :
1485  aRectFnSet.GetLeft(aRect) - aRectFnSet.GetPrtLeft(*pFrame);
1486  break;
1487  }
1488  }
1489  }
1490 
1491  return nRet;
1492 }
1493 
1494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwAttrHandler & GetAttrHandler()
Definition: itratr.hxx:109
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:225
SwScriptInfo * m_pScriptInfo
Definition: itratr.hxx:40
sal_uLong GetMin() const
Definition: htmltbl.hxx:280
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
bool SeekAndChgAttrIter(TextFrameIndex nPos, OutputDevice *pOut)
Executes ChgPhysFnt if Seek() returns true and change font to merge character border with neighbours...
Definition: itratr.cxx:151
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:162
tools::Long GetWidth() const
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:44
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1379
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:878
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:687
Marks a position in the document model.
Definition: pam.hxx:36
virtual const tools::Rectangle & GetCurrentBoundRect() const
bool MaybeHasHints() const
Definition: itratr.cxx:123
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1800
const SwField * GetField() const
Definition: fmtfld.hxx:116
tools::Long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1411
bool isCHRATR(const sal_uInt16 nWhich)
Definition: hintids.hxx:479
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
const OUString & GetText() const
Definition: ndtxt.hxx:218
void PopAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
Definition: atrstck.cxx:422
SwTextAttr * GetAttr(TextFrameIndex nPos) const
Returns the attribute for a position.
Definition: itratr.cxx:143
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:226
#define FLYINCNT_MIN_WIDTH
Definition: itratr.cxx:1003
bool HasPara() const
Definition: txtfrm.hxx:823
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_META(48)
static bool lcl_MinMaxString(SwMinMaxArgs &rArg, SwFont *pFnt, const OUString &rText, sal_Int32 nIdx, sal_Int32 nEnd)
Definition: itratr.cxx:816
SwNodeIndex nNode
Definition: pam.hxx:38
void SetPriorityAttr(bool bFlag)
Definition: txatbase.hxx:104
const SwTextNode * m_pTextNode
input: the current text node
Definition: itratr.hxx:57
bool GetFirstLineOfsWithNum(short &rFirstOffset) const
Returns the combined first line indent of this text node and its numbering.
Definition: ndtxt.cxx:3234
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:277
sal_uIntPtr sal_uLong
long Long
tools::Long GetRight() const
size_t m_nEndIndex
current iteration index in HintEnds
Definition: itratr.hxx:50
Base class of all fields.
Definition: fldbas.hxx:291
Size GetTextSize_(SwDrawTextInfo &rInf)
Definition: swfont.hxx:310
void SeekFwd(sal_Int32 nOldPos, sal_Int32 nNewPos)
Definition: itratr.cxx:259
TElementType * Next()
Definition: calbck.hxx:364
#define CHAR_HARDBLANK
Definition: swtypes.hxx:161
const MapMode & GetMapMode() const
TextFrameIndex GetNextAttr() const
Definition: itratr.cxx:731
SwFont * m_pFont
Definition: itratr.hxx:39
SwTwips GetWidthOfLeadingTabs() const
Returns the width of leading tabs/blanks in this paragraph.
Definition: itratr.cxx:1451
void CharToLine(TextFrameIndex)
Definition: itrtxt.cxx:193
Content, content of frame (header, footer, fly).
Definition: fmtcntnt.hxx:31
bool IsSymbol(SwViewShell const *pSh)
Definition: swfont.hxx:270
void ResetFont(SwFont &rFnt) const
Definition: atrhndl.hxx:104
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
static void lcl_MinMaxNode(SwFrameFormat *pNd, SwMinMaxNodeArgs &rIn)
Definition: itratr.cxx:884
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:161
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:180
void SetMapMode()
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:743
Value in Var-direction gives minimum (can be exceeded but not be less).
bool Seek(TextFrameIndex nPos)
Enables the attributes used at char pos nPos in the logical font.
Definition: itratr.cxx:302
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(156)
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:856
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:163
static OutputDevice * GetDefaultDevice()
constexpr tools::Long Width() const
sal_Int32 m_nPosition
current iteration index in text node
Definition: itratr.hxx:52
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:173
sal_uInt16 sal_Unicode
const SfxPoolItem * NextItem()
#define CH_TXTATR_INWORD
Definition: hintids.hxx:174
SwTableNode * GetTableNode()
Definition: node.hxx:609
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
SwAttrIter(SwTextNode const *pTextNode)
Definition: itratr.cxx:67
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
void CtorInitAttrIter(SwTextNode &rTextNode, SwScriptInfo &rScrInf, SwTextFrame const *pFrame=nullptr)
Definition: redlnitr.cxx:520
SwIndex nContent
Definition: pam.hxx:39
o3tl::enumarray< SwFontScript, sal_uInt16 > m_aFontIdx
Definition: itratr.hxx:55
size_t pos
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
#define CH_TXT_ATR_INPUTFIELDSTART
Definition: hintids.hxx:177
Used by Attribute Iterators to organize attributes on stacks to find the valid attribute in each cate...
Definition: atrhndl.hxx:37
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
void SetFntChg(const bool bNew)
Definition: swfont.hxx:209
oslFileHandle & pOut
constexpr tools::Long GetWidth() const
tools::Long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1410
constexpr TypedWhichId< SwFormatRuby > RES_TXTATR_CJK_RUBY(53)
const SwTable & GetTable() const
Definition: node.hxx:506
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
const OUString & GetNumStr() const
Definition: fmtftn.hxx:68
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:161
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
sal_uLong GetMax() const
Definition: htmltbl.hxx:281
bool SeekStartAndChgAttrIter(OutputDevice *pOut, const bool bParaFont)
Definition: itratr.cxx:193
void ChgPhysFnt(SwViewShell const *pSh, OutputDevice &rOut)
Definition: swfont.cxx:893
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
std::unique_ptr< SwRedlineItr, o3tl::default_delete< SwRedlineItr > > m_pRedline
Definition: itratr.hxx:46
SwFontScript GetActual() const
Definition: swfont.hxx:184
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:859
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:442
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
Specific frame formats (frames, DrawObjects).
vcl::RenderContext & GetRefDev() const
Definition: viewsh.cxx:2177
bool IsFntChg() const
Definition: swfont.hxx:208
#define SAL_N_ELEMENTS(arr)
void InitFontAndAttrHandler(SwTextNode const &rPropsNode, SwTextNode const &rTextNode, OUString const &rText, bool const *pbVertLayout, bool const *pbVertLayoutLRBT)
Definition: redlnitr.cxx:444
sw::MergedPara const * m_pMergedPara
Definition: itratr.hxx:58
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:461
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
tools::Long GetTextLeft() const
Style of a layout element.
Definition: frmfmt.hxx:59
void Reset()
Definition: atrstck.cxx:331
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
SwDoc & GetDoc()
Definition: node.hxx:213
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
const sal_Unicode CH_TAB
Definition: swfont.hxx:44
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(58)
void GetMinMaxSize(SwNodeOffset nIndex, sal_uLong &rMin, sal_uLong &rMax, sal_uLong &rAbs) const
Is in itratr.
Definition: itratr.cxx:1009
Count
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1186
TElementType * First()
Definition: calbck.hxx:356
SwNodeOffset GetIndex() const
Definition: node.hxx:292
vector_type::size_type size_type
Definition: docary.hxx:222
const sal_Unicode CH_BLANK
Definition: swfont.hxx:42
FlyAnchors.
Definition: fmtanchr.hxx:34
tools::Long GetLeft() const
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(MergedPara const &, TextFrameIndex nIndex)
Definition: txtfrm.cxx:1167
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:182
SwTextNode * pParaPropsNode
most paragraph properties are taken from the first non-empty node
Definition: txtfrm.hxx:968
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
css::text::WrapTextMode GetSurround() const
Definition: fmtsrnd.hxx:51
SwFont * GetFnt()
Definition: itratr.hxx:103
bool IsEndNode() const
Definition: node.hxx:642
tools::Long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3191
OUString mergedText
note: cannot be const currently to avoid UB because SwTextGuess::Guess const_casts it and modifies it...
Definition: txtfrm.hxx:966
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
static bool CanSkipOverRedline(SwTextNode const &rStartNode, sal_Int32 const nStartRedline, SwRangeRedline const &rRedline, size_t &rStartIndex, size_t &rEndIndex, bool const isTheAnswerYes)
Definition: itratr.cxx:454
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
tools::Long SwTwips
Definition: swtypes.hxx:51
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
constexpr TypedWhichId< SvxCharScaleWidthItem > RES_CHRATR_SCALEW(35)
sal_uInt16 GetScalingOfSelectedText(TextFrameIndex nStt, TextFrameIndex nEnd)
Calculates the width of the text part specified by nStart and nEnd, the height of the line containing...
Definition: itratr.cxx:1257
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
size_t m_nStartIndex
current iteration index in HintStarts
Definition: itratr.hxx:48
constexpr TypedWhichId< SvxRsidItem > RES_CHRATR_RSID(39)
sal_uInt8 m_nPropFont
Definition: itratr.hxx:53
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: node.cxx:2105
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(60)
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Rst(SwTextAttr const *pHt)
Definition: itratr.cxx:106
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:484
LanguageType GetLanguage() const
Definition: swfont.hxx:283
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:162
#define CH_TXT_ATR_INPUTFIELDEND
Definition: hintids.hxx:178
constexpr TypedWhichId< SwFormatContentControl > RES_TXTATR_CONTENTCONTROL(56)
An SwTextAttr container, stores all directly formatted text portions for a text node.
Definition: ndhints.hxx:67
o3tl::enumarray< SwFontScript, const void * > m_aFontCacheIds
Definition: itratr.hxx:54
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
sal_Int32 m_nPosition
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
constexpr tools::Long Height() const
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
void SetFontCacheId(const void *nNewFontCacheId, const sal_uInt16 nIdx, SwFontScript nWhich)
Definition: swfont.hxx:200
vcl::Window * GetWin() const
Definition: viewsh.hxx:338
SwHTMLTableLayout * GetHTMLTableLayout()
Definition: swtable.hxx:177
SwAttrHandler m_aAttrHandler
Definition: itratr.hxx:37
::OutputDevice const * GetOutDev() const
void SetActual(SwFontScript nNew)
Definition: swfont.hxx:751
SwNodes & GetNodes()
Definition: doc.hxx:408
const SwPosition * End() const
Definition: pam.hxx:218
void Chg(SwTextAttr const *pHt)
Definition: itratr.cxx:96
VclPtr< OutputDevice > m_pLastOut
Definition: itratr.hxx:43
void * p
constexpr TypedWhichId< SwTOXMark > RES_TXTATR_TOXMARK(47)
double getLength(const B2DPolygon &rCandidate)
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
constexpr sal_uInt16 RES_CHRATR_END(46)
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:184
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:724
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
void PushAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
Definition: atrstck.cxx:337
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
SwTextNode const * pLastNode
mainly for sanity checks
Definition: txtfrm.hxx:972
OutputDevice * get() const
SwFrameFormat * GetFrameFormat() const
Definition: fmtflcnt.hxx:45
static sal_Int32 GetNextAttrImpl(SwTextNode const *pTextNode, size_t nStartIndex, size_t nEndIndex, sal_Int32 nPosition)
Definition: itratr.cxx:671
bool IsSymbol(TextFrameIndex nPos)
Definition: itratr.cxx:177
SwTextNode *const pFirstNode
except break attributes, those are taken from the first node
Definition: txtfrm.hxx:970
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
SwViewShell * m_pViewShell
Definition: itratr.hxx:38
void SetProportion(const sal_uInt8 nNewPropr)
Definition: swfont.hxx:769
short m_nChgCnt
count currently open hints, redlines, ext-input
Definition: itratr.hxx:45
#define CH_TXT_ATR_FIELDSEP
Definition: hintids.hxx:183
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
virtual ~SwAttrIter()
Definition: itratr.cxx:117
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
static constexpr size_type npos
Definition: docary.hxx:223
OUString m_Text
Definition: ndtxt.hxx:98
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:140
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
static void InsertCharAttrs(SfxPoolItem const **pAttrs, SfxItemSet const &rItems)
Definition: itratr.cxx:435
constexpr TypedWhichId< SvXMLAttrContainerItem > RES_TXTATR_UNKNOWN_CONTAINER(54)
sal_uInt16 nPos
const SfxPoolItem * GetCurItem() const
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
bool IsSymbolAt(TextFrameIndex) const
Definition: itratr.cxx:186
const SwFormatFlyCnt & GetFlyCnt() const
Definition: txatbase.hxx:226
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
Base class of the Writer document model elements.
Definition: node.hxx:81