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