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