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