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 assert(m_nChgCnt == 0); // should have reset it all? there cannot be ExtOn() inside of a Delete redline, surely?
334 // Unapply current para items:
335 // the SwAttrHandler doesn't appear to be capable of *unapplying*
336 // items at all; it can only apply a previously effective item.
337 // So do this by recreating the font from scratch.
338 // Apply new para items:
339 assert(m_pMergedPara);
341 m_pMergedPara->mergedText, nullptr, nullptr);
342 // reset to next
343 m_pTextNode = newPos.first;
344 m_nStartIndex = 0;
345 m_nEndIndex = 0;
346 m_nPosition = 0;
347 assert(m_pRedline);
348 }
349
350 // sw_redlinehide: Seek(0) must move before the first character, which
351 // has a special case where the first node starts with delete redline.
352 if ((!nNewPos && !m_pMergedPara)
353 || newPos.first != m_pTextNode
354 || newPos.second < m_nPosition)
355 {
356 if (m_pMergedPara)
357 {
358 if (m_pTextNode != newPos.first)
359 {
360 m_pTextNode = newPos.first;
361 // sw_redlinehide: hope it's okay to use the current text node
362 // here; the AttrHandler shouldn't care about non-char items
364 m_pMergedPara->mergedText, nullptr, nullptr);
365 }
366 }
368 {
369 if( m_pRedline )
370 m_pRedline->Clear( nullptr );
371
372 // reset font to its original state
375
376 if( m_nPropFont )
378 m_nStartIndex = 0;
379 m_nEndIndex = 0;
380 m_nPosition = 0;
381 m_nChgCnt = 0;
382
383 // Attention!
384 // resetting the font here makes it necessary to apply any
385 // changes for extended input directly to the font
386 if ( m_pRedline && m_pRedline->ExtOn() )
387 {
388 m_pRedline->UpdateExtFont( *m_pFont );
389 ++m_nChgCnt;
390 }
391 }
392 }
393
395 {
396 if (m_pMergedPara)
397 {
398 // iterate hint by hint: SeekFwd does not mix ends and starts,
399 // it always applies all the starts last, so it must be called once
400 // per position where hints start/end!
401 sal_Int32 nPos(m_nPosition);
402 do
403 {
404 sal_Int32 const nOldPos(nPos);
406 if (nPos <= newPos.second)
407 {
408 SeekFwd(nOldPos, nPos);
409 }
410 else
411 {
412 SeekFwd(nOldPos, newPos.second);
413 }
414 }
415 while (nPos < newPos.second);
416 }
417 else
418 {
419 SeekFwd(m_nPosition, newPos.second);
420 }
421 }
422
424
425 if( m_pRedline )
426 m_nChgCnt = m_nChgCnt + m_pRedline->Seek(*m_pFont, m_pTextNode->GetIndex(), newPos.second, m_nPosition);
427 m_nPosition = newPos.second;
428
429 if( m_nPropFont )
431
432 return m_pFont->IsFntChg();
433}
434
435static void InsertCharAttrs(SfxPoolItem const** pAttrs, SfxItemSet const& rItems)
436{
437 SfxItemIter iter(rItems);
438 for (SfxPoolItem const* pItem = iter.GetCurItem(); pItem; pItem = iter.NextItem())
439 {
440 auto const nWhich(pItem->Which());
441 if (isCHRATR(nWhich) && RES_CHRATR_RSID != nWhich)
442 {
443 pAttrs[nWhich - RES_CHRATR_BEGIN] = pItem;
444 }
445 else if (nWhich == RES_TXTATR_UNKNOWN_CONTAINER)
446 {
447 pAttrs[RES_CHRATR_END - RES_CHRATR_BEGIN] = pItem;
448 }
449 }
450}
451
452// if return false: portion ends at start of redline, indexes unchanged
453// if return true: portion end not known (past end of redline), indexes point to first hint past end of redline
455 SwTextNode const& rStartNode, sal_Int32 const nStartRedline,
456 SwRangeRedline const& rRedline,
457 size_t & rStartIndex, size_t & rEndIndex,
458 bool const isTheAnswerYes)
459{
460 size_t nStartIndex(rStartIndex);
461 size_t nEndIndex(rEndIndex);
462 SwPosition const*const pRLEnd(rRedline.End());
463 if (!pRLEnd->GetNode().IsTextNode() // if fully deleted...
464 || pRLEnd->GetContentIndex() == pRLEnd->GetNode().GetTextNode()->Len())
465 {
466 // shortcut: nothing follows redline
467 // current state is end state
468 return false;
469 }
470 std::vector<SwTextAttr*> activeCharFmts;
471 // can't compare the SwFont that's stored somewhere, it doesn't have compare
472 // operator, so try to recreate the situation with some temp arrays here
473 SfxPoolItem const* activeCharAttrsStart[RES_CHRATR_END - RES_CHRATR_BEGIN + 1] = { nullptr, };
474 if (rStartNode != pRLEnd->GetNode())
475 { // nodes' attributes are only needed if there are different nodes
476 InsertCharAttrs(activeCharAttrsStart, rStartNode.GetSwAttrSet());
477 }
478 if (SwpHints const*const pStartHints = rStartNode.GetpSwpHints())
479 {
480 // check hint ends of hints that start before and end within
481 sal_Int32 const nRedlineEnd(rStartNode == pRLEnd->GetNode()
482 ? pRLEnd->GetContentIndex()
483 : rStartNode.Len());
484 for ( ; nEndIndex < pStartHints->Count(); ++nEndIndex)
485 {
486 SwTextAttr *const pAttr(pStartHints->GetSortedByEnd(nEndIndex));
487 if (!pAttr->End())
488 {
489 continue;
490 }
491 if (nRedlineEnd < *pAttr->End())
492 {
493 break;
494 }
495 if (nStartRedline <= pAttr->GetStart())
496 {
497 continue;
498 }
499 if (pAttr->IsFormatIgnoreEnd())
500 {
501 continue;
502 }
503 switch (pAttr->Which())
504 {
505 // if any of these ends inside RL then we need a new portion
508 case RES_TXTATR_META: // actually these 2 aren't allowed to overlap ???
514 {
515 if (!isTheAnswerYes) return false; // always break
516 }
517 break;
518 // these are guaranteed not to overlap
519 // and come in order of application
522 {
523 if (pAttr->Which() == RES_TXTATR_CHARFMT)
524 {
525 activeCharFmts.push_back(pAttr);
526 }
527 // pure formatting hints may end inside the redline &
528 // start again inside the redline, which must not cause
529 // a new text portion if they have the same items - so
530 // store the effective items & compare all at the end
531 SfxItemSet const& rSet((pAttr->Which() == RES_TXTATR_CHARFMT)
532 ? static_cast<SfxItemSet const&>(pAttr->GetCharFormat().GetCharFormat()->GetAttrSet())
533 : *pAttr->GetAutoFormat().GetStyleHandle());
534 InsertCharAttrs(activeCharAttrsStart, rSet);
535 }
536 break;
537 // SwTextNode::SetAttr puts it into AUTOFMT which is quite
538 // sensible so it doesn't actually exist as a hint
540 default: assert(false);
541 }
542 }
543 assert(nEndIndex == pStartHints->Count() ||
544 pRLEnd->GetContentIndex() < pStartHints->GetSortedByEnd(nEndIndex)->GetAnyEnd());
545 }
546
547 if (rStartNode != pRLEnd->GetNode())
548 {
549 nStartIndex = 0;
550 nEndIndex = 0;
551 }
552
553 // treat para properties as text properties
554 // ... with the FormatToTextAttr we get autofmts that correspond to the *effective* attr set difference
555 // effective attr set: para props + charfmts + autofmt *in that order*
556 // ... and the charfmt must be *nominally* the same
557
558 SfxPoolItem const* activeCharAttrsEnd[RES_CHRATR_END - RES_CHRATR_BEGIN + 1] = { nullptr, };
559 if (rStartNode != pRLEnd->GetNode())
560 { // nodes' attributes are only needed if there are different nodes
561 InsertCharAttrs(activeCharAttrsEnd,
562 pRLEnd->GetNode().GetTextNode()->GetSwAttrSet());
563 }
564
565 if (SwpHints *const pEndHints = pRLEnd->GetNode().GetTextNode()->GetpSwpHints())
566 {
567 // check hint starts of hints that start within and end after
568#ifndef NDEBUG
569 sal_Int32 const nRedlineStart(rStartNode == pRLEnd->GetNode()
570 ? nStartRedline
571 : 0);
572#endif
573 for ( ; nStartIndex < pEndHints->Count(); ++nStartIndex)
574 {
575 SwTextAttr *const pAttr(pEndHints->Get(nStartIndex));
576 // compare with < here, not <=, to get the effective formatting
577 // of the 1st char after the redline; should not cause problems
578 // with consecutive delete redlines because those are handed by
579 // GetNextRedln() and here we have the last end pos.
580 if (pRLEnd->GetContentIndex() < pAttr->GetStart())
581 {
582 break;
583 }
584 if (!pAttr->End())
585 continue;
586 if (pAttr->IsFormatIgnoreStart())
587 {
588 continue;
589 }
590 assert(nRedlineStart <= pAttr->GetStart()); // we wouldn't be here otherwise?
591 if (*pAttr->End() <= pRLEnd->GetContentIndex())
592 {
593 continue;
594 }
595 switch (pAttr->Which())
596 {
599 case RES_TXTATR_META: // actually these 2 aren't allowed to overlap ???
605 {
606 if (!isTheAnswerYes) return false;
607 }
608 break;
611 {
612 // char formats must be *nominally* the same
613 if (pAttr->Which() == RES_TXTATR_CHARFMT)
614 {
615 auto iter = std::find_if(activeCharFmts.begin(), activeCharFmts.end(),
616 [&pAttr](const SwTextAttr* pCharFmt) { return *pCharFmt == *pAttr; });
617 if (iter != activeCharFmts.end())
618 activeCharFmts.erase(iter);
619 else if (!isTheAnswerYes)
620 return false;
621 }
622 SfxItemSet const& rSet((pAttr->Which() == RES_TXTATR_CHARFMT)
623 ? static_cast<SfxItemSet const&>(pAttr->GetCharFormat().GetCharFormat()->GetAttrSet())
624 : *pAttr->GetAutoFormat().GetStyleHandle());
625 InsertCharAttrs(activeCharAttrsEnd, rSet);
626
627 }
628 break;
629 // SwTextNode::SetAttr puts it into AUTOFMT which is quite
630 // sensible so it doesn't actually exist as a hint
632 default: assert(false);
633 }
634 }
635 if (rStartNode != pRLEnd->GetNode())
636 {
637 // need to iterate the nEndIndex forward too so the loop in the
638 // caller can look for the right ends in the next iteration
639 for (nEndIndex = 0; nEndIndex < pEndHints->Count(); ++nEndIndex)
640 {
641 SwTextAttr *const pAttr(pEndHints->GetSortedByEnd(nEndIndex));
642 if (!pAttr->End())
643 continue;
644 if (pRLEnd->GetContentIndex() < *pAttr->End())
645 {
646 break;
647 }
648 }
649 }
650 }
651
652 // if we didn't find a matching start for any end, then it really ends inside
653 if (!activeCharFmts.empty())
654 {
655 if (!isTheAnswerYes) return false;
656 }
657 for (size_t i = 0; i < SAL_N_ELEMENTS(activeCharAttrsStart); ++i)
658 {
659 // all of these are poolable
660// assert(!activeCharAttrsStart[i] || activeCharAttrsStart[i]->GetItemPool()->IsItemPoolable(*activeCharAttrsStart[i]));
661 if (activeCharAttrsStart[i] != activeCharAttrsEnd[i])
662 {
663 if (!isTheAnswerYes) return false;
664 }
665 }
666 rStartIndex = nStartIndex;
667 rEndIndex = nEndIndex;
668 return true;
669}
670
671static sal_Int32 GetNextAttrImpl(SwTextNode const*const pTextNode,
672 size_t const nStartIndex, size_t const nEndIndex,
673 sal_Int32 const nPosition)
674{
675 // note: this used to be COMPLETE_STRING, but was set to Len() + 1 below,
676 // which is rather silly, so set it to Len() instead
677 sal_Int32 nNext = pTextNode->Len();
678 if (SwpHints const*const pHints = pTextNode->GetpSwpHints())
679 {
680 // are there attribute starts left?
681 for (size_t i = nStartIndex; i < pHints->Count(); ++i)
682 {
683 SwTextAttr *const pAttr(pHints->Get(i));
684 if (!pAttr->IsFormatIgnoreStart())
685 {
686 nNext = pAttr->GetStart();
687 break;
688 }
689 }
690 // are there attribute ends left?
691 for (size_t i = nEndIndex; i < pHints->Count(); ++i)
692 {
693 SwTextAttr *const pAttr(pHints->GetSortedByEnd(i));
694 if (!pAttr->IsFormatIgnoreEnd())
695 {
696 sal_Int32 const nNextEnd = pAttr->GetAnyEnd();
697 nNext = std::min(nNext, nNextEnd); // pick nearest one
698 break;
699 }
700 }
701 }
702 // TODO: maybe use hints like FieldHints for this instead of looking at the text...
703 const sal_Int32 l = std::min(nNext, pTextNode->Len());
704 sal_Int32 p = nPosition;
705 const sal_Unicode* pStr = pTextNode->GetText().getStr();
706 while (p < l)
707 {
708 sal_Unicode aChar = pStr[p];
709 switch (aChar)
710 {
715 goto break_; // sigh...
716 default:
717 ++p;
718 }
719 }
720break_:
721 assert(p <= nNext);
722 if (p < l)
723 {
724 // found a CH_TXT_ATR_FIELD*: if it's same as current position,
725 // skip behind it so that both before- and after-positions are returned
726 nNext = (nPosition < p) ? p : p + 1;
727 }
728 return nNext;
729}
730
732{
733 size_t nStartIndex(m_nStartIndex);
734 size_t nEndIndex(m_nEndIndex);
735 size_t nPosition(m_nPosition);
736 SwTextNode const* pTextNode(m_pTextNode);
738
739 while (true)
740 {
741 sal_Int32 nNext = GetNextAttrImpl(pTextNode, nStartIndex, nEndIndex, nPosition);
742 if( m_pRedline )
743 {
744 std::pair<sal_Int32, std::pair<SwRangeRedline const*, size_t>> const redline(
745 m_pRedline->GetNextRedln(nNext, pTextNode, nActRedline));
746 if (redline.second.first)
747 {
748 assert(m_pMergedPara);
749 assert(redline.second.first->End()->GetNodeIndex() <= m_pMergedPara->pLastNode->GetIndex()
750 || !redline.second.first->End()->GetNode().IsTextNode());
751 if (CanSkipOverRedline(*pTextNode, redline.first, *redline.second.first,
752 nStartIndex, nEndIndex, m_nPosition == redline.first))
753 { // if current position is start of the redline, must skip!
754 nActRedline += redline.second.second;
755 if (&redline.second.first->End()->GetNode() != pTextNode)
756 {
757 pTextNode = redline.second.first->End()->GetNode().GetTextNode();
758 nPosition = redline.second.first->End()->GetContentIndex();
759 }
760 else
761 {
762 nPosition = redline.second.first->End()->GetContentIndex();
763 }
764 }
765 else
766 {
767 return sw::MapModelToView(*m_pMergedPara, pTextNode, redline.first);
768 }
769 }
770 else
771 {
772 return m_pMergedPara
773 ? sw::MapModelToView(*m_pMergedPara, pTextNode, redline.first)
774 : TextFrameIndex(redline.first);
775 }
776 }
777 else
778 {
779 return TextFrameIndex(nNext);
780 }
781 }
782}
783
784namespace {
785
786class SwMinMaxArgs
787{
788public:
790 SwViewShell const* m_pSh;
791 sal_uLong& m_rMin;
792 sal_uLong& m_rAbsMin;
793 tools::Long m_nRowWidth;
794 tools::Long m_nWordWidth;
795 tools::Long m_nWordAdd;
796 sal_Int32 m_nNoLineBreak;
797 SwMinMaxArgs(OutputDevice* pOutI, SwViewShell const* pShI, sal_uLong& rMinI, sal_uLong& rAbsI)
798 : m_pOut(pOutI)
799 , m_pSh(pShI)
800 , m_rMin(rMinI)
801 , m_rAbsMin(rAbsI)
802 , m_nRowWidth(0)
803 , m_nWordWidth(0)
804 , m_nWordAdd(0)
805 , m_nNoLineBreak(COMPLETE_STRING)
806 { }
807 void Minimum( tools::Long nNew ) const {
808 if (static_cast<tools::Long>(m_rMin) < nNew)
809 m_rMin = nNew;
810 }
811 void NewWord() { m_nWordAdd = m_nWordWidth = 0; }
812};
813
814}
815
816static bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const OUString &rText,
817 sal_Int32 nIdx, sal_Int32 nEnd )
818{
819 bool bRet = false;
820 while( nIdx < nEnd )
821 {
822 sal_Int32 nStop = nIdx;
823 LanguageType eLang = pFnt->GetLanguage();
824 assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
825
826 bool bClear = CH_BLANK == rText[ nStop ];
827 Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary( rText, nIdx,
828 g_pBreakIt->GetLocale( eLang ),
829 WordType::DICTIONARY_WORD, true ) );
830 nStop = aBndry.endPos;
831 if (nIdx <= aBndry.startPos && nIdx && nIdx - 1 != rArg.m_nNoLineBreak)
832 rArg.NewWord();
833 if( nStop == nIdx )
834 ++nStop;
835 if( nStop > nEnd )
836 nStop = nEnd;
837
838 SwDrawTextInfo aDrawInf(rArg.m_pSh, *rArg.m_pOut, rText, nIdx, nStop - nIdx);
839 tools::Long nCurrentWidth = pFnt->GetTextSize_( aDrawInf ).Width();
840 rArg.m_nRowWidth += nCurrentWidth;
841 if( bClear )
842 rArg.NewWord();
843 else
844 {
845 rArg.m_nWordWidth += nCurrentWidth;
846 if (static_cast<tools::Long>(rArg.m_rAbsMin) < rArg.m_nWordWidth)
847 rArg.m_rAbsMin = rArg.m_nWordWidth;
848 rArg.Minimum(rArg.m_nWordWidth + rArg.m_nWordAdd);
849 bRet = true;
850 }
851 nIdx = nStop;
852 }
853 return bRet;
854}
855
856bool SwTextNode::IsSymbolAt(const sal_Int32 nBegin) const
857{
858 SwScriptInfo aScriptInfo;
859 SwAttrIter aIter( *const_cast<SwTextNode*>(this), aScriptInfo );
860 aIter.Seek( TextFrameIndex(nBegin) );
861 return aIter.GetFnt()->IsSymbol( getIDocumentLayoutAccess().GetCurrentViewShell() );
862}
863
864namespace {
865
866class SwMinMaxNodeArgs
867{
868public:
869 sal_uLong m_nMaxWidth; // sum of all frame widths
870 tools::Long m_nMinWidth; // biggest frame
871 tools::Long m_nLeftRest; // space not already covered by frames in the left margin
872 tools::Long m_nRightRest; // space not already covered by frames in the right margin
873 tools::Long m_nLeftDiff; // Min/Max-difference of the frame in the left margin
874 tools::Long m_nRightDiff; // Min/Max-difference of the frame in the right margin
875 SwNodeOffset m_nIndex; // index of the node
876 void Minimum( tools::Long nNew ) {
877 if (nNew > m_nMinWidth)
878 m_nMinWidth = nNew;
879 }
880};
881
882}
883
884static void lcl_MinMaxNode(SwFrameFormat* pNd, SwMinMaxNodeArgs& rIn)
885{
886 const SwFormatAnchor& rFormatA = pNd->GetAnchor();
887
888 if ((RndStdIds::FLY_AT_PARA != rFormatA.GetAnchorId()) &&
889 (RndStdIds::FLY_AT_CHAR != rFormatA.GetAnchorId()))
890 {
891 return;
892 }
893
894 const SwPosition *pPos = rFormatA.GetContentAnchor();
895 OSL_ENSURE(pPos, "Unexpected NULL arguments");
896 if (!pPos || rIn.m_nIndex != pPos->GetNodeIndex())
897 return;
898
899 tools::Long nMin, nMax;
900 SwHTMLTableLayout *pLayout = nullptr;
901 const bool bIsDrawFrameFormat = pNd->Which()==RES_DRAWFRMFMT;
902 if( !bIsDrawFrameFormat )
903 {
904 // Does the frame contain a table at the start or the end?
905 const SwNodes& rNodes = pNd->GetDoc()->GetNodes();
906 const SwFormatContent& rFlyContent = pNd->GetContent();
907 SwNodeOffset nStt = rFlyContent.GetContentIdx()->GetIndex();
908 SwTableNode* pTableNd = rNodes[nStt+1]->GetTableNode();
909 if( !pTableNd )
910 {
911 SwNode *pNd2 = rNodes[nStt];
912 pNd2 = rNodes[pNd2->EndOfSectionIndex()-1];
913 if( pNd2->IsEndNode() )
914 pTableNd = pNd2->StartOfSectionNode()->GetTableNode();
915 }
916
917 if( pTableNd )
918 pLayout = pTableNd->GetTable().GetHTMLTableLayout();
919 }
920
921 const SwFormatHoriOrient& rOrient = pNd->GetHoriOrient();
922 sal_Int16 eHoriOri = rOrient.GetHoriOrient();
923
924 tools::Long nDiff;
925 if( pLayout )
926 {
927 nMin = pLayout->GetMin();
928 nMax = pLayout->GetMax();
929 nDiff = nMax - nMin;
930 }
931 else
932 {
933 if( bIsDrawFrameFormat )
934 {
935 const SdrObject* pSObj = pNd->FindSdrObject();
936 if( pSObj )
937 nMin = pSObj->GetCurrentBoundRect().GetWidth();
938 else
939 nMin = 0;
940
941 }
942 else
943 {
944 const SwFormatFrameSize &rSz = pNd->GetFrameSize();
945 nMin = rSz.GetWidth();
946 }
947 nMax = nMin;
948 nDiff = 0;
949 }
950
951 const SvxLRSpaceItem &rLR = pNd->GetLRSpace();
952 nMin += rLR.GetLeft();
953 nMin += rLR.GetRight();
954 nMax += rLR.GetLeft();
955 nMax += rLR.GetRight();
956
957 if( css::text::WrapTextMode_THROUGH == pNd->GetSurround().GetSurround() )
958 {
959 rIn.Minimum( nMin );
960 return;
961 }
962
963 // Frames, which are left- or right-aligned are only party considered
964 // when calculating the maximum, since the border is already being considered.
965 // Only if the frame extends into the text body, this part is being added
966 switch( eHoriOri )
967 {
968 case text::HoriOrientation::RIGHT:
969 {
970 if( nDiff )
971 {
972 rIn.m_nRightRest -= rIn.m_nRightDiff;
973 rIn.m_nRightDiff = nDiff;
974 }
975 if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
976 {
977 if (rIn.m_nRightRest > 0)
978 rIn.m_nRightRest = 0;
979 }
980 rIn.m_nRightRest -= nMin;
981 break;
982 }
983 case text::HoriOrientation::LEFT:
984 {
985 if( nDiff )
986 {
987 rIn.m_nLeftRest -= rIn.m_nLeftDiff;
988 rIn.m_nLeftDiff = nDiff;
989 }
990 if (text::RelOrientation::FRAME != rOrient.GetRelationOrient() && rIn.m_nLeftRest < 0)
991 rIn.m_nLeftRest = 0;
992 rIn.m_nLeftRest -= nMin;
993 break;
994 }
995 default:
996 {
997 rIn.m_nMaxWidth += nMax;
998 rIn.Minimum(nMin);
999 }
1000 }
1001}
1002
1003#define FLYINCNT_MIN_WIDTH 284
1004
1010 sal_uLong& rAbsMin ) const
1011{
1013 OutputDevice* pOut = nullptr;
1014 if( pSh )
1015 pOut = pSh->GetWin()->GetOutDev();
1016 if( !pOut )
1018
1019 MapMode aOldMap( pOut->GetMapMode() );
1020 pOut->SetMapMode( MapMode( MapUnit::MapTwip ) );
1021
1022 rMin = 0;
1023 rMax = 0;
1024 rAbsMin = 0;
1025
1026 const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
1027 tools::Long nLROffset = rSpace.GetTextLeft() + GetLeftMarginWithNum( true );
1028 short nFLOffs;
1029 // For enumerations a negative first line indentation is probably filled already
1030 if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
1031 nLROffset = nFLOffs;
1032
1033 SwMinMaxNodeArgs aNodeArgs;
1034 aNodeArgs.m_nMinWidth = 0;
1035 aNodeArgs.m_nMaxWidth = 0;
1036 aNodeArgs.m_nLeftRest = nLROffset;
1037 aNodeArgs.m_nRightRest = rSpace.GetRight();
1038 aNodeArgs.m_nLeftDiff = 0;
1039 aNodeArgs.m_nRightDiff = 0;
1040 if( nIndex )
1041 {
1042 SwFrameFormats* pTmp = const_cast<SwFrameFormats*>(GetDoc().GetSpzFrameFormats());
1043 if( pTmp )
1044 {
1045 aNodeArgs.m_nIndex = nIndex;
1046 for( SwFrameFormat *pFormat : *pTmp )
1047 lcl_MinMaxNode(pFormat, aNodeArgs);
1048 }
1049 }
1050 if (aNodeArgs.m_nLeftRest < 0)
1051 aNodeArgs.Minimum(nLROffset - aNodeArgs.m_nLeftRest);
1052 aNodeArgs.m_nLeftRest -= aNodeArgs.m_nLeftDiff;
1053 if (aNodeArgs.m_nLeftRest < 0)
1054 aNodeArgs.m_nMaxWidth -= aNodeArgs.m_nLeftRest;
1055
1056 if (aNodeArgs.m_nRightRest < 0)
1057 aNodeArgs.Minimum(rSpace.GetRight() - aNodeArgs.m_nRightRest);
1058 aNodeArgs.m_nRightRest -= aNodeArgs.m_nRightDiff;
1059 if (aNodeArgs.m_nRightRest < 0)
1060 aNodeArgs.m_nMaxWidth -= aNodeArgs.m_nRightRest;
1061
1062 SwScriptInfo aScriptInfo;
1063 SwAttrIter aIter( *const_cast<SwTextNode*>(this), aScriptInfo );
1064 TextFrameIndex nIdx(0);
1065 aIter.SeekAndChgAttrIter( nIdx, pOut );
1066 TextFrameIndex nLen(m_Text.getLength());
1067 tools::Long nCurrentWidth = 0;
1068 tools::Long nAdd = 0;
1069 SwMinMaxArgs aArg( pOut, pSh, rMin, rAbsMin );
1070 while( nIdx < nLen )
1071 {
1072 TextFrameIndex nNextChg = aIter.GetNextAttr();
1073 TextFrameIndex nStop = aScriptInfo.NextScriptChg( nIdx );
1074 if( nNextChg > nStop )
1075 nNextChg = nStop;
1076 SwTextAttr *pHint = nullptr;
1077 sal_Unicode cChar = CH_BLANK;
1078 nStop = nIdx;
1079 while( nStop < nLen && nStop < nNextChg &&
1080 CH_TAB != (cChar = m_Text[sal_Int32(nStop)]) &&
1081 CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
1082 CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
1083 CH_TXT_ATR_INPUTFIELDSTART != cChar &&
1084 CH_TXT_ATR_INPUTFIELDEND != cChar &&
1085 CH_TXT_ATR_FORMELEMENT != cChar &&
1086 CH_TXT_ATR_FIELDSTART != cChar &&
1087 CH_TXT_ATR_FIELDSEP != cChar &&
1088 CH_TXT_ATR_FIELDEND != cChar &&
1089 !pHint )
1090 {
1091 // this looks like some defensive programming to handle dummy char
1092 // with missing hint? but it's rather silly because it may pass the
1093 // dummy char to lcl_MinMaxString in that case...
1094 if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
1095 || ( nullptr == ( pHint = aIter.GetAttr( nStop ) ) ) )
1096 ++nStop;
1097 }
1098 if (lcl_MinMaxString(aArg, aIter.GetFnt(), m_Text, sal_Int32(nIdx), sal_Int32(nStop)))
1099 {
1100 nAdd = 20;
1101 }
1102 nIdx = nStop;
1103 aIter.SeekAndChgAttrIter( nIdx, pOut );
1104 switch( cChar )
1105 {
1106 case CH_BREAK :
1107 {
1108 if (static_cast<tools::Long>(rMax) < aArg.m_nRowWidth)
1109 rMax = aArg.m_nRowWidth;
1110 aArg.m_nRowWidth = 0;
1111 aArg.NewWord();
1112 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1113 }
1114 break;
1115 case CH_TAB :
1116 {
1117 aArg.NewWord();
1118 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1119 }
1120 break;
1121 case CHAR_SOFTHYPHEN:
1122 ++nIdx;
1123 break;
1124 case CHAR_HARDBLANK:
1125 case CHAR_HARDHYPHEN:
1126 {
1127 OUString sTmp( cChar );
1128 SwDrawTextInfo aDrawInf( pSh,
1129 *pOut, sTmp, 0, 1, 0, false );
1130 nCurrentWidth = aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1131 aArg.m_nWordWidth += nCurrentWidth;
1132 aArg.m_nRowWidth += nCurrentWidth;
1133 if (static_cast<tools::Long>(rAbsMin) < aArg.m_nWordWidth)
1134 rAbsMin = aArg.m_nWordWidth;
1135 aArg.Minimum(aArg.m_nWordWidth + aArg.m_nWordAdd);
1136 aArg.m_nNoLineBreak = sal_Int32(nIdx++);
1137 }
1138 break;
1140 case CH_TXTATR_INWORD:
1141 {
1142 if( !pHint )
1143 break;
1144 tools::Long nOldWidth = aArg.m_nWordWidth;
1145 tools::Long nOldAdd = aArg.m_nWordAdd;
1146 aArg.NewWord();
1147
1148 switch( pHint->Which() )
1149 {
1150 case RES_TXTATR_FLYCNT :
1151 {
1152 SwFrameFormat *pFrameFormat = pHint->GetFlyCnt().GetFrameFormat();
1153 const SvxLRSpaceItem &rLR = pFrameFormat->GetLRSpace();
1154 if( RES_DRAWFRMFMT == pFrameFormat->Which() )
1155 {
1156 const SdrObject* pSObj = pFrameFormat->FindSdrObject();
1157 if( pSObj )
1158 nCurrentWidth = pSObj->GetCurrentBoundRect().GetWidth();
1159 else
1160 nCurrentWidth = 0;
1161 }
1162 else
1163 {
1164 const SwFormatFrameSize& rTmpSize = pFrameFormat->GetFrameSize();
1165 if( RES_FLYFRMFMT == pFrameFormat->Which()
1166 && rTmpSize.GetWidthPercent() )
1167 {
1168 // This is a hack for the following situation: In the paragraph there's a
1169 // text frame with relative size. Then let's take 0.5 cm as minimum width
1170 // and USHRT_MAX as maximum width
1171 // It were cleaner and maybe necessary later on to iterate over the content
1172 // of the text frame and call GetMinMaxSize recursively
1173 nCurrentWidth = FLYINCNT_MIN_WIDTH; // 0.5 cm
1174 rMax = std::max(rMax, sal_uLong(USHRT_MAX));
1175 }
1176 else
1177 nCurrentWidth = pFrameFormat->GetFrameSize().GetWidth();
1178 }
1179 nCurrentWidth += rLR.GetLeft();
1180 nCurrentWidth += rLR.GetRight();
1181 aArg.m_nWordAdd = nOldWidth + nOldAdd;
1182 aArg.m_nWordWidth = nCurrentWidth;
1183 aArg.m_nRowWidth += nCurrentWidth;
1184 if (static_cast<tools::Long>(rAbsMin) < aArg.m_nWordWidth)
1185 rAbsMin = aArg.m_nWordWidth;
1186 aArg.Minimum(aArg.m_nWordWidth + aArg.m_nWordAdd);
1187 break;
1188 }
1189 case RES_TXTATR_FTN :
1190 {
1191 const OUString aText = pHint->GetFootnote().GetNumStr();
1192 if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, 0,
1193 aText.getLength() ) )
1194 nAdd = 20;
1195 break;
1196 }
1197
1198 case RES_TXTATR_FIELD :
1200 {
1201 SwField *pField = const_cast<SwField*>(pHint->GetFormatField().GetField());
1202 const OUString aText = pField->ExpandField(true, nullptr);
1203 if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, 0,
1204 aText.getLength() ) )
1205 nAdd = 20;
1206 break;
1207 }
1208 default:
1209 aArg.m_nWordWidth = nOldWidth;
1210 aArg.m_nWordAdd = nOldAdd;
1211 }
1212 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1213 }
1214 break;
1221 { // just skip it and continue with the content...
1222 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
1223 }
1224 break;
1225 }
1226 }
1227 if (static_cast<tools::Long>(rMax) < aArg.m_nRowWidth)
1228 rMax = aArg.m_nRowWidth;
1229
1230 nLROffset += rSpace.GetRight();
1231
1232 rAbsMin += nLROffset;
1233 rAbsMin += nAdd;
1234 rMin += nLROffset;
1235 rMin += nAdd;
1236 if (static_cast<tools::Long>(rMin) < aNodeArgs.m_nMinWidth)
1237 rMin = aNodeArgs.m_nMinWidth;
1238 if (static_cast<tools::Long>(rAbsMin) < aNodeArgs.m_nMinWidth)
1239 rAbsMin = aNodeArgs.m_nMinWidth;
1240 rMax += aNodeArgs.m_nMaxWidth;
1241 rMax += nLROffset;
1242 rMax += nAdd;
1243 if( rMax < rMin ) // e.g. Frames with flow through only contribute to the minimum
1244 rMax = rMin;
1245 pOut->SetMapMode( aOldMap );
1246}
1247
1258 TextFrameIndex nStart, TextFrameIndex nEnd)
1259{
1260 assert(GetOffset() <= nStart && (!GetFollow() || nStart < GetFollow()->GetOffset()));
1261 SwViewShell const*const pSh = getRootFrame()->GetCurrShell();
1262 assert(pSh);
1263 OutputDevice *const pOut = &pSh->GetRefDev();
1264 assert(pOut);
1265
1266 MapMode aOldMap( pOut->GetMapMode() );
1267 pOut->SetMapMode( MapMode( MapUnit::MapTwip ) );
1268
1269 if (nStart == nEnd)
1270 {
1271 assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
1272
1273 SwScriptInfo aScriptInfo;
1274 SwAttrIter aIter(*GetTextNodeFirst(), aScriptInfo, this);
1275 aIter.SeekAndChgAttrIter( nStart, pOut );
1276
1277 Boundary aBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
1278 GetText(), sal_Int32(nStart),
1279 g_pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
1280 WordType::DICTIONARY_WORD, true );
1281
1282 if (sal_Int32(nStart) == aBound.startPos)
1283 {
1284 // cursor is at left or right border of word
1285 pOut->SetMapMode( aOldMap );
1286 return 100;
1287 }
1288
1289 nStart = TextFrameIndex(aBound.startPos);
1290 nEnd = TextFrameIndex(aBound.endPos);
1291
1292 if (nStart == nEnd)
1293 {
1294 pOut->SetMapMode( aOldMap );
1295 return 100;
1296 }
1297 }
1298
1299 SwScriptInfo aScriptInfo;
1300 SwAttrIter aIter(*GetTextNodeFirst(), aScriptInfo, this);
1301
1302 // We do not want scaling attributes to be considered during this
1303 // calculation. For this, we push a temporary scaling attribute with
1304 // scaling value 100 and priority flag on top of the scaling stack
1305 SwAttrHandler& rAH = aIter.GetAttrHandler();
1307 SwTextAttrEnd aAttr( aItem, 0, COMPLETE_STRING );
1308 aAttr.SetPriorityAttr( true );
1309 rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
1310
1311 TextFrameIndex nIdx = nStart;
1312
1313 sal_uLong nWidth = 0;
1314 sal_uLong nProWidth = 0;
1315
1316 while( nIdx < nEnd )
1317 {
1318 aIter.SeekAndChgAttrIter( nIdx, pOut );
1319
1320 // scan for end of portion
1321 TextFrameIndex const nNextChg = std::min(aIter.GetNextAttr(), aScriptInfo.NextScriptChg(nIdx));
1322
1323 TextFrameIndex nStop = nIdx;
1324 sal_Unicode cChar = CH_BLANK;
1325 SwTextAttr* pHint = nullptr;
1326
1327 // stop at special characters in [ nIdx, nNextChg ]
1328 while( nStop < nEnd && nStop < nNextChg )
1329 {
1330 cChar = GetText()[sal_Int32(nStop)];
1331 if (
1332 CH_TAB == cChar ||
1333 CH_BREAK == cChar ||
1334 CHAR_HARDBLANK == cChar ||
1335 CHAR_HARDHYPHEN == cChar ||
1336 CHAR_SOFTHYPHEN == cChar ||
1337 CH_TXT_ATR_INPUTFIELDSTART == cChar ||
1338 CH_TXT_ATR_INPUTFIELDEND == cChar ||
1339 CH_TXT_ATR_FORMELEMENT == cChar ||
1340 CH_TXT_ATR_FIELDSTART == cChar ||
1341 CH_TXT_ATR_FIELDSEP == cChar ||
1342 CH_TXT_ATR_FIELDEND == cChar ||
1343 (
1344 (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
1345 (nullptr == (pHint = aIter.GetAttr(nStop)))
1346 )
1347 )
1348 {
1349 break;
1350 }
1351 else
1352 ++nStop;
1353 }
1354
1355 // calculate text widths up to cChar
1356 if ( nStop > nIdx )
1357 {
1358 SwDrawTextInfo aDrawInf(pSh, *pOut, GetText(), sal_Int32(nIdx), sal_Int32(nStop - nIdx));
1359 nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1360 }
1361
1362 nIdx = nStop;
1363 aIter.SeekAndChgAttrIter( nIdx, pOut );
1364
1365 if ( cChar == CH_BREAK )
1366 {
1367 nWidth = std::max( nWidth, nProWidth );
1368 nProWidth = 0;
1369 nIdx++;
1370 }
1371 else if ( cChar == CH_TAB )
1372 {
1373 // tab receives width of one space
1374 SwDrawTextInfo aDrawInf(pSh, *pOut, OUStringChar(CH_BLANK), 0, 1);
1375 nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1376 nIdx++;
1377 }
1378 else if ( cChar == CHAR_SOFTHYPHEN )
1379 ++nIdx;
1380 else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
1381 {
1382 OUString sTmp( cChar );
1383 SwDrawTextInfo aDrawInf(pSh, *pOut, sTmp, 0, 1);
1384 nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1385 nIdx++;
1386 }
1387 else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || cChar == CH_TXTATR_INWORD ) )
1388 {
1389 switch( pHint->Which() )
1390 {
1391 case RES_TXTATR_FTN :
1392 {
1393 const OUString aText = pHint->GetFootnote().GetNumStr();
1394 SwDrawTextInfo aDrawInf(pSh, *pOut, aText, 0, aText.getLength());
1395
1396 nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1397 break;
1398 }
1399
1400 case RES_TXTATR_FIELD :
1402 {
1403 SwField *pField = const_cast<SwField*>(pHint->GetFormatField().GetField());
1404 OUString const aText = pField->ExpandField(true, getRootFrame());
1405 SwDrawTextInfo aDrawInf(pSh, *pOut, aText, 0, aText.getLength());
1406
1407 nProWidth += aIter.GetFnt()->GetTextSize_( aDrawInf ).Width();
1408 break;
1409 }
1410
1411 default:
1412 {
1413 // any suggestions for a default action?
1414 }
1415 } // end of switch
1416 nIdx++;
1417 }
1418 else if (CH_TXT_ATR_INPUTFIELDSTART == cChar ||
1419 CH_TXT_ATR_INPUTFIELDEND == cChar ||
1420 CH_TXT_ATR_FORMELEMENT == cChar ||
1421 CH_TXT_ATR_FIELDSTART == cChar ||
1422 CH_TXT_ATR_FIELDSEP == cChar ||
1423 CH_TXT_ATR_FIELDEND == cChar)
1424 { // just skip it and continue with the content...
1425 ++nIdx;
1426 }
1427 } // end of while
1428
1429 nWidth = std::max( nWidth, nProWidth );
1430
1431 // search for the line containing nStart
1432 if (HasPara())
1433 {
1434 SwTextInfo aInf(this);
1435 SwTextIter aLine(this, &aInf);
1436 aLine.CharToLine( nStart );
1437 pOut->SetMapMode( aOldMap );
1438 return o3tl::narrowing<sal_uInt16>( nWidth ?
1439 ( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
1440 }
1441 // no frame or no paragraph, we take the height of the character
1442 // at nStart as line height
1443
1444 aIter.SeekAndChgAttrIter( nStart, pOut );
1445 pOut->SetMapMode( aOldMap );
1446
1447 SwDrawTextInfo aDrawInf(pSh, *pOut, GetText(), sal_Int32(nStart), 1);
1448 return o3tl::narrowing<sal_uInt16>( nWidth ? ((100 * aIter.GetFnt()->GetTextSize_( aDrawInf ).Height()) / nWidth ) : 0 );
1449}
1450
1452{
1453 SwTwips nRet = 0;
1454
1455 sal_Int32 nIdx = 0;
1456
1457 while ( nIdx < GetText().getLength() )
1458 {
1459 const sal_Unicode cCh = GetText()[nIdx];
1460 if ( cCh!='\t' && cCh!=' ' )
1461 {
1462 break;
1463 }
1464 ++nIdx;
1465 }
1466
1467 if ( nIdx > 0 )
1468 {
1469 SwPosition aPos( *this );
1470 aPos.nContent += nIdx;
1471
1472 // Find the non-follow text frame:
1474 for( SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() )
1475 {
1476 // Only consider master frames:
1477 if (!pFrame->IsFollow() &&
1478 pFrame->GetTextNodeForFirstText() == this)
1479 {
1480 SwRectFnSet aRectFnSet(pFrame);
1481 SwRect aRect;
1482 pFrame->GetCharRect( aRect, aPos );
1483 nRet = pFrame->IsRightToLeft() ?
1484 aRectFnSet.GetPrtRight(*pFrame) - aRectFnSet.GetRight(aRect) :
1485 aRectFnSet.GetLeft(aRect) - aRectFnSet.GetPrtLeft(*pFrame);
1486 break;
1487 }
1488 }
1489 }
1490
1491 return nRet;
1492}
1493
1494/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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
void InitFontAndAttrHandler(SwTextNode const &rPropsNode, SwTextNode const &rTextNode, OUString const &rText, bool const *pbVertLayout, bool const *pbVertLayoutLRBT)
Definition: redlnitr.cxx:442
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:518
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:731
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
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:742
SwNodes & GetNodes()
Definition: doc.hxx:413
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:406
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:748
Base class of all fields.
Definition: fldbas.hxx:292
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
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:69
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
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
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:83
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:108
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:679
sal_uLong GetMin() const
Definition: htmltbl.hxx:280
sal_uLong GetMax() const
Definition: htmltbl.hxx:281
TElementType * Next()
Definition: calbck.hxx:364
TElementType * First()
Definition: calbck.hxx:356
virtual void Height(const SwTwips nNew, const bool bText=true) override
Definition: porlay.cxx:238
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:171
Base class of the Writer document model elements.
Definition: node.hxx:84
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:876
SwNodeOffset GetIndex() const
Definition: node.hxx:296
SwDoc & GetDoc()
Definition: node.hxx:217
bool IsEndNode() const
Definition: node.hxx:660
bool IsTextNode() const
Definition: node.hxx:664
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:137
SwNodeOffset EndOfSectionIndex() const
Definition: node.hxx:705
SwTableNode * GetTableNode()
Definition: node.hxx:627
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: node.cxx:2143
const SwPosition * End() const
Definition: pam.hxx:271
tools::Long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1411
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1378
tools::Long GetPrtLeft(const SwFrame &rFrame) const
Definition: frame.hxx:1410
tools::Long GetRight(const SwRect &rRect) const
Definition: frame.hxx:1379
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:206
SwFontScript WhichFont(TextFrameIndex nIdx) const
Definition: porlay.cxx:892
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1868
const SwTable & GetTable() const
Definition: node.hxx:521
SwHTMLTableLayout * GetHTMLTableLayout()
Definition: swtable.hxx:177
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:1257
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:86
OUString m_Text
Definition: ndtxt.hxx:102
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:275
tools::Long GetLeftMarginWithNum(bool bTextLeft=false) const
Returns the additional indents of this text node and its numbering.
Definition: ndtxt.cxx:3227
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:856
SwTwips GetWidthOfLeadingTabs() const
Returns the width of leading tabs/blanks in this paragraph.
Definition: itratr.cxx:1451
bool GetFirstLineOfsWithNum(short &rFirstOffset) const
Returns the combined first line indent of this text node and its numbering.
Definition: ndtxt.cxx:3270
void GetMinMaxSize(SwNodeOffset nIndex, sal_uLong &rMin, sal_uLong &rMax, sal_uLong &rAbs) const
Is in itratr.
Definition: itratr.cxx:1009
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:230
const OUString & GetText() const
Definition: ndtxt.hxx:222
vcl::Window * GetWin() const
Definition: viewsh.hxx:346
vcl::RenderContext & GetRefDev() const
Definition: viewsh.cxx:2177
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:183
#define CH_TXT_ATR_INPUTFIELDSTART
Definition: hintids.hxx:177
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:180
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
bool isCHRATR(const sal_uInt16 nWhich)
Definition: hintids.hxx:479
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:174
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:178
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:184
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:182
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:173
sal_Int32 nIndex
#define FLYINCNT_MIN_WIDTH
Definition: itratr.cxx:1003
static bool lcl_MinMaxString(SwMinMaxArgs &rArg, SwFont *pFnt, const OUString &rText, sal_Int32 nIdx, sal_Int32 nEnd)
Definition: itratr.cxx:816
static void lcl_MinMaxNode(SwFrameFormat *pNd, SwMinMaxNodeArgs &rIn)
Definition: itratr.cxx:884
static void InsertCharAttrs(SfxPoolItem const **pAttrs, SfxItemSet const &rItems)
Definition: itratr.cxx:435
static sal_Int32 GetNextAttrImpl(SwTextNode const *pTextNode, size_t nStartIndex, size_t nEndIndex, sal_Int32 nPosition)
Definition: itratr.cxx:671
static bool CanSkipOverRedline(SwTextNode const &rStartNode, sal_Int32 const nStartRedline, SwRangeRedline const &rRedline, size_t &rStartIndex, size_t &rEndIndex, bool const isTheAnswerYes)
Definition: itratr.cxx:454
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
SwNodeOffset GetNodeIndex() const
Definition: pam.hxx:77
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
SwContentIndex nContent
Definition: pam.hxx:39
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:161
tools::Long SwTwips
Definition: swtypes.hxx:51
#define CHAR_SOFTHYPHEN
Definition: swtypes.hxx:163
#define CHAR_HARDHYPHEN
Definition: swtypes.hxx:162
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
sal_uInt16 sal_Unicode
oslFileHandle & pOut
size_t pos