LibreOffice Module sw (master) 1
laycache.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
21#include <sal/log.hxx>
22#include <osl/diagnose.h>
23#include <tools/stream.hxx>
24#include <doc.hxx>
27#include <docstat.hxx>
28#include <fmtpdsc.hxx>
29#include <laycache.hxx>
30#include "layhelp.hxx"
31#include <pagefrm.hxx>
32#include <rootfrm.hxx>
33#include <txtfrm.hxx>
34#include <swtable.hxx>
35#include <tabfrm.hxx>
36#include <rowfrm.hxx>
37#include <sectfrm.hxx>
38#include <fmtcntnt.hxx>
39#include <pagedesc.hxx>
40#include <frmtool.hxx>
41#include <dflyobj.hxx>
42#include <dcontact.hxx>
43#include <viewopt.hxx>
44#include <flyfrm.hxx>
45#include <sortedobjs.hxx>
46#include <ndindex.hxx>
47#include <node.hxx>
48#include <ndtxt.hxx>
49#include <frameformats.hxx>
50
51#include <limits>
52
53using namespace ::com::sun::star;
54
55SwLayoutCache::SwLayoutCache() : m_nLockCount( 0 ) {}
56
57/*
58 * Reading and writing of the layout cache.
59 * The layout cache is not necessary, but it improves
60 * the performance and reduces the text flow during
61 * the formatting.
62 * The layout cache contains the index of the paragraphs/tables
63 * at the top of every page, so it's possible to create
64 * the right count of pages and to distribute the document content
65 * to this pages before the formatting starts.
66 */
67
69{
70 if( !m_pImpl )
71 {
72 m_pImpl.reset( new SwLayCacheImpl );
73 if( !m_pImpl->Read( rStream ) )
74 {
75 m_pImpl.reset();
76 }
77 }
78}
79
80void SwLayCacheImpl::Insert( sal_uInt16 nType, SwNodeOffset nIndex, sal_Int32 nOffset )
81{
82 m_aType.push_back( nType );
83 mIndices.push_back( nIndex );
84 m_aOffset.push_back( nOffset );
85}
86
88{
89 SwLayCacheIoImpl aIo( rStream, false );
91 return false;
92
93 // Due to an evil bug in the layout cache (#102759#), we cannot trust the
94 // sizes of fly frames which have been written using the "old" layout cache.
95 // This flag should indicate that we do not want to trust the width and
96 // height of fly frames
98
100 aIo.OpenFlagRec();
101 aIo.CloseFlagRec();
102 while( aIo.BytesLeft() && !aIo.HasError() )
103 {
104 sal_uInt32 nIndex(0), nOffset(0);
105
106 switch( aIo.Peek() )
107 {
109 {
111 sal_uInt8 cFlags = aIo.OpenFlagRec();
112 aIo.GetStream().ReadUInt32( nIndex );
113 if( (cFlags & 0x01) != 0 )
114 aIo.GetStream().ReadUInt32( nOffset );
115 else
116 nOffset = COMPLETE_STRING;
117 aIo.CloseFlagRec();
118 Insert( SW_LAYCACHE_IO_REC_PARA, SwNodeOffset(nIndex), static_cast<sal_Int32>(nOffset) );
119 aIo.CloseRec();
120 break;
121 }
124 aIo.OpenFlagRec();
126 .ReadUInt32( nOffset );
127 Insert( SW_LAYCACHE_IO_REC_TABLE, SwNodeOffset(nIndex), static_cast<sal_Int32>(nOffset) );
128 aIo.CloseFlagRec();
129 aIo.CloseRec();
130 break;
132 {
134 aIo.OpenFlagRec();
135 aIo.CloseFlagRec();
136 sal_Int32 nX(0), nY(0), nW(0), nH(0);
137 sal_uInt16 nPgNum(0);
139 .ReadInt32( nX ).ReadInt32( nY ).ReadInt32( nW ).ReadInt32( nH );
140 m_FlyCache.emplace_back( nPgNum, nIndex, nX, nY, nW, nH );
141 aIo.CloseRec();
142 break;
143 }
144 default:
145 aIo.SkipRec();
146 break;
147 }
148 }
149 aIo.CloseRec();
150
151 return !aIo.HasError();
152}
153
163void SwLayoutCache::Write( SvStream &rStream, const SwDoc& rDoc )
164{
165 if( !rDoc.getIDocumentLayoutAccess().GetCurrentLayout() ) // the layout itself ..
166 return;
167
168 SwLayCacheIoImpl aIo( rStream, true );
169 // We want to save the relative index, so we need the index
170 // of the first content
171 SwNodeOffset nStartOfContent = rDoc.GetNodes().GetEndOfContent().
172 StartOfSectionNode()->GetIndex();
173 // The first page...
174 SwPageFrame* pPage = const_cast<SwPageFrame*>(static_cast<const SwPageFrame*>(rDoc.getIDocumentLayoutAccess().GetCurrentLayout()->Lower()));
175
177 aIo.OpenFlagRec( 0, 0 );
178 aIo.CloseFlagRec();
179 while( pPage )
180 {
181 if( pPage->GetPrev() )
182 {
183 SwLayoutFrame* pLay = pPage->FindBodyCont();
184 SwFrame* pTmp = pLay ? pLay->ContainsAny() : nullptr;
185 // We are only interested in paragraph or table frames,
186 // a section frames contains paragraphs/tables.
187 if( pTmp && pTmp->IsSctFrame() )
188 pTmp = static_cast<SwSectionFrame*>(pTmp)->ContainsAny();
189
190 if( pTmp ) // any content
191 {
192 if( pTmp->IsTextFrame() )
193 {
194 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pTmp));
195 assert(!pFrame->GetMergedPara());
196 SwNodeOffset nNdIdx = pFrame->GetTextNodeFirst()->GetIndex();
197 if( nNdIdx > nStartOfContent )
198 {
199 /* Open Paragraph Record */
201 bool bFollow = static_cast<SwTextFrame*>(pTmp)->IsFollow();
202 aIo.OpenFlagRec( bFollow ? 0x01 : 0x00,
203 bFollow ? 8 : 4 );
204 nNdIdx -= nStartOfContent;
205 aIo.GetStream().WriteUInt32( sal_Int32(nNdIdx) );
206 if( bFollow )
207 aIo.GetStream().WriteUInt32( sal_Int32(static_cast<SwTextFrame*>(pTmp)->GetOffset()) );
208 aIo.CloseFlagRec();
209 /* Close Paragraph Record */
210 aIo.CloseRec();
211 }
212 }
213 else if( pTmp->IsTabFrame() )
214 {
215 SwTabFrame* pTab = static_cast<SwTabFrame*>(pTmp);
217 if( pTab->IsFollow() )
218 {
219 // If the table is a follow, we have to look for the
220 // master and to count all rows to get the row number
221 nOfst = 0;
222 if( pTab->IsFollow() )
223 pTab = pTab->FindMaster( true );
224 while( pTab != pTmp )
225 {
226 SwFrame* pSub = pTab->Lower();
227 while( pSub )
228 {
229 ++nOfst;
230 pSub = pSub->GetNext();
231 }
232 pTab = pTab->GetFollow();
233 assert(pTab && "Table follow without master");
234 }
235 }
236 while (true)
237 {
238 SwNodeOffset nNdIdx =
239 pTab->GetTable()->GetTableNode()->GetIndex();
240 if( nNdIdx > nStartOfContent )
241 {
242 /* Open Table Record */
244 aIo.OpenFlagRec( 0, 8 );
245 nNdIdx -= nStartOfContent;
246 aIo.GetStream().WriteUInt32( sal_Int32(nNdIdx) )
247 .WriteUInt32( nOfst );
248 aIo.CloseFlagRec();
249 /* Close Table Record */
250 aIo.CloseRec();
251 }
252 // If the table has a follow on the next page,
253 // we know already the row number and store this
254 // immediately.
255 if( pTab->GetFollow() )
256 {
257 if( nOfst == sal_uLong(COMPLETE_STRING) )
258 nOfst = 0;
259 do
260 {
261 SwFrame* pSub = pTab->Lower();
262 while( pSub )
263 {
264 ++nOfst;
265 pSub = pSub->GetNext();
266 }
267 pTab = pTab->GetFollow();
268 SwPageFrame *pTabPage = pTab->FindPageFrame();
269 if( pTabPage != pPage )
270 {
271 OSL_ENSURE( pPage->GetPhyPageNum() <
272 pTabPage->GetPhyPageNum(),
273 "Looping Tableframes" );
274 pPage = pTabPage;
275 break;
276 }
277 } while ( pTab->GetFollow() );
278 }
279 else
280 break;
281 }
282 }
283 }
284 }
285 if( pPage->GetSortedObjs() )
286 {
287 SwSortedObjs &rObjs = *pPage->GetSortedObjs();
288 for (SwAnchoredObject* pAnchoredObj : rObjs)
289 {
290 if (SwFlyFrame *pFly = pAnchoredObj->DynCastFlyFrame())
291 {
292 if( pFly->getFrameArea().Left() != FAR_AWAY &&
293 !pFly->GetAnchorFrame()->FindFooterOrHeader() )
294 {
295 const SwContact *pC =
296 ::GetUserCall(pAnchoredObj->GetDrawObj());
297 if( pC )
298 {
299 sal_uInt32 nOrdNum = pAnchoredObj->GetDrawObj()->GetOrdNum();
300 sal_uInt16 nPageNum = pPage->GetPhyPageNum();
301 /* Open Fly Record */
303 aIo.OpenFlagRec( 0, 0 );
304 aIo.CloseFlagRec();
305 const SwRect& rRct = pFly->getFrameArea();
306 sal_Int32 nX = rRct.Left() - pPage->getFrameArea().Left();
307 sal_Int32 nY = rRct.Top() - pPage->getFrameArea().Top();
308 aIo.GetStream().WriteUInt16( nPageNum ).WriteUInt32( nOrdNum )
309 .WriteInt32( nX ).WriteInt32( nY )
310 .WriteInt32( rRct.Width() )
311 .WriteInt32( rRct.Height() );
312 /* Close Fly Record */
313 aIo.CloseRec();
314 }
315 }
316 }
317 }
318 }
319 pPage = static_cast<SwPageFrame*>(pPage->GetNext());
320 }
321 aIo.CloseRec();
322}
323
324#ifdef DBG_UTIL
325bool SwLayoutCache::CompareLayout( const SwDoc& rDoc ) const
326{
327 if( !m_pImpl )
328 return true;
329 const SwRootFrame *pRootFrame = rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
330 if( pRootFrame )
331 {
332 size_t nIndex = 0;
333 SwNodeOffset nStartOfContent = rDoc.GetNodes().GetEndOfContent().
334 StartOfSectionNode()->GetIndex();
335 const SwPageFrame* pPage = static_cast<const SwPageFrame*>(pRootFrame->Lower());
336 if( pPage )
337 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
338 while( pPage )
339 {
340 if( nIndex >= m_pImpl->size() )
341 return false;
342
343 const SwLayoutFrame* pLay = pPage->FindBodyCont();
344 const SwFrame* pTmp = pLay ? pLay->ContainsAny() : nullptr;
345 if( pTmp && pTmp->IsSctFrame() )
346 pTmp = static_cast<const SwSectionFrame*>(pTmp)->ContainsAny();
347 if( pTmp )
348 {
349 if( pTmp->IsTextFrame() )
350 {
351
352 SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(pTmp));
353 assert(!pFrame->GetMergedPara());
354 SwNodeOffset nNdIdx = pFrame->GetTextNodeFirst()->GetIndex();
355 if( nNdIdx > nStartOfContent )
356 {
357 bool bFollow = static_cast<const SwTextFrame*>(pTmp)->IsFollow();
358 nNdIdx -= nStartOfContent;
359 if( m_pImpl->GetBreakIndex( nIndex ) != nNdIdx ||
361 m_pImpl->GetBreakType( nIndex ) ||
362 (bFollow
363 ? sal_Int32(static_cast<const SwTextFrame*>(pTmp)->GetOffset())
364 : COMPLETE_STRING) != m_pImpl->GetBreakOfst(nIndex))
365 {
366 return false;
367 }
368 ++nIndex;
369 }
370 }
371 else if( pTmp->IsTabFrame() )
372 {
373 const SwTabFrame* pTab = static_cast<const SwTabFrame*>(pTmp);
374 sal_Int32 nOfst = COMPLETE_STRING;
375 if( pTab->IsFollow() )
376 {
377 nOfst = 0;
378 if( pTab->IsFollow() )
379 pTab = pTab->FindMaster( true );
380 while( pTab != pTmp )
381 {
382 const SwFrame* pSub = pTab->Lower();
383 while( pSub )
384 {
385 ++nOfst;
386 pSub = pSub->GetNext();
387 }
388 pTab = pTab->GetFollow();
389 }
390 }
391 do
392 {
393 SwNodeOffset nNdIdx =
394 pTab->GetTable()->GetTableNode()->GetIndex();
395 if( nNdIdx > nStartOfContent )
396 {
397 nNdIdx -= nStartOfContent;
398 if( m_pImpl->GetBreakIndex( nIndex ) != nNdIdx ||
400 m_pImpl->GetBreakType( nIndex ) ||
401 nOfst != m_pImpl->GetBreakOfst( nIndex ) )
402 {
403 return false;
404 }
405 ++nIndex;
406 }
407 if( pTab->GetFollow() )
408 {
409 if( nOfst == COMPLETE_STRING )
410 nOfst = 0;
411 do
412 {
413 const SwFrame* pSub = pTab->Lower();
414 while( pSub )
415 {
416 ++nOfst;
417 pSub = pSub->GetNext();
418 }
419 pTab = pTab->GetFollow();
420 const SwPageFrame *pTabPage = pTab->FindPageFrame();
421 if( pTabPage != pPage )
422 {
423 pPage = pTabPage;
424 break;
425 }
426 } while ( pTab->GetFollow() );
427 }
428 else
429 break;
430 } while( pTab );
431 }
432 }
433 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
434 }
435 }
436 return true;
437}
438#endif
439
441{
442 if( !IsLocked() )
443 {
444 m_pImpl.reset();
445 }
446}
447
449{
450 OSL_ENSURE( !m_nLockCount, "Deleting a locked SwLayoutCache!?" );
451}
452
455 SwSectionFrame *pSect,
456 SwSectionNode *pNd ) :
457 m_pUpper( pUp ),
458 m_pSectFrame( pSect ),
459 m_pSectNode( pNd )
460{
461 if ( !m_pSectNode )
462 {
463 const SwNodeIndex *pIndex = pSect->GetFormat()->GetContent().GetContentIdx();
464 m_pSectNode = pIndex->GetNode().FindSectionNode();
465 }
466}
467
468namespace {
469
470bool sanityCheckLayoutCache(SwLayCacheImpl const& rCache,
471 SwNodes const& rNodes, SwNodeOffset nNodeIndex)
472{
473 auto const nStartOfContent(rNodes.GetEndOfContent().StartOfSectionNode()->GetIndex());
474 nNodeIndex -= nStartOfContent;
475 auto const nMaxIndex(rNodes.GetEndOfContent().GetIndex() - nStartOfContent);
476 for (size_t nIndex = 0; nIndex < rCache.size(); ++nIndex)
477 {
478 auto const nBreakIndex(rCache.GetBreakIndex(nIndex));
479 if (nBreakIndex < nNodeIndex || nMaxIndex <= nBreakIndex)
480 {
481 SAL_WARN("sw.layout",
482 "invalid node index in layout-cache: " << nBreakIndex);
483 return false;
484 }
485 auto const nBreakType(rCache.GetBreakType(nIndex));
486 switch (nBreakType)
487 {
489 if (!rNodes[nBreakIndex + nStartOfContent]->IsTextNode())
490 {
491 SAL_WARN("sw.layout",
492 "invalid node of type 'P' in layout-cache");
493 return false;
494 }
495 break;
497 if (!rNodes[nBreakIndex + nStartOfContent]->IsTableNode())
498 {
499 SAL_WARN("sw.layout",
500 "invalid node of type 'T' in layout-cache");
501 return false;
502 }
503 break;
504 default:
505 assert(false); // Read shouldn't have inserted that
506 }
507 }
508 return true;
509}
510
511} // namespace
512
520 SwLayoutFrame* &rpL, std::unique_ptr<SwActualSection> &rpA,
521 SwNodeOffset nNodeIndex, bool bCache )
522 : mrpFrame( rpF )
523 , mrpPrv( rpP )
524 , mrpPage( rpPg )
525 , mrpLay( rpL )
526 , mrpActualSection( rpA )
527 , mbBreakAfter(false)
528 , mpDoc(pD)
529 , mnMaxParaPerPage( 25 )
530 , mnParagraphCnt( bCache ? 0 : USHRT_MAX )
531 , mnFlyIdx( 0 )
532 , mbFirst( bCache )
533{
535 if( mpImpl )
536 {
537 SwNodes const& rNodes(mpDoc->GetNodes());
538 if (sanityCheckLayoutCache(*mpImpl, rNodes, nNodeIndex))
539 {
540 mnIndex = 0;
542 mnMaxParaPerPage = 1000;
543 }
544 else
545 {
547 mpImpl = nullptr;
548 mnIndex = std::numeric_limits<size_t>::max();
549 mnStartOfContent = SwNodeOffset(USHRT_MAX);
550 }
551 }
552 else
553 {
554 mnIndex = std::numeric_limits<size_t>::max();
556 }
557}
558
560{
561 if( mpImpl )
562 {
563 OSL_ENSURE( mpDoc && mpDoc->GetLayoutCache(), "Missing layoutcache" );
565 }
566}
567
573{
574 sal_uLong nPgCount;
575 SwLayCacheImpl *pCache = mpDoc->GetLayoutCache() ?
576 mpDoc->GetLayoutCache()->LockImpl() : nullptr;
577 if( pCache )
578 {
579 nPgCount = pCache->size() + 1;
581 }
582 else
583 {
585 if ( nPgCount <= 10 ) // no page insertion for less than 10 pages
586 nPgCount = 0;
587 sal_Int32 nNdCount = mpDoc->getIDocumentStatistics().GetDocStat().nPara;
588 if ( nNdCount <= 1 )
589 {
590 //Estimates the number of paragraphs.
593 //Tables have a little overhead...
594 nTmp -= SwNodeOffset(mpDoc->GetTableFrameFormats()->size() * 25);
595 //Fly frames, too ..
596 nTmp -= (mpDoc->GetNodes().GetEndOfAutotext().GetIndex() -
598 if ( nTmp > SwNodeOffset(0) )
599 nNdCount = sal_Int32(nTmp);
600 }
601 if ( nNdCount > 100 ) // no estimation below this value
602 {
603 if ( nPgCount > 0 )
604 { // tdf#129529 avoid 0...
605 mnMaxParaPerPage = std::max<sal_uLong>(3, nNdCount / nPgCount);
606 }
607 else
608 {
609 mnMaxParaPerPage = std::max( sal_uLong(20),
610 sal_uLong(20 + nNdCount / 1000 * 3) );
611 const sal_uLong nMax = 53;
613 nPgCount = nNdCount / mnMaxParaPerPage;
614 }
615 if ( nNdCount < 1000 )
616 nPgCount = 0;// no progress bar for small documents
617 SwViewShell *pSh = nullptr;
618 if( mrpLay && mrpLay->getRootFrame() )
619 pSh = mrpLay->getRootFrame()->GetCurrShell();
620 if( pSh && pSh->GetViewOptions()->getBrowseMode() )
621 mnMaxParaPerPage *= 6;
622 }
623 }
624 return nPgCount;
625}
626
637{
638 bool bEnd = nullptr == mrpPage->GetNext();
640 const SwFormatPageDesc& rDesc = mrpFrame->GetPageDescItem();
641 // #118195# Do not evaluate page description if frame
642 // is a follow frame!
643 const SwPageDesc* pDesc = mrpFrame->IsFlowFrame() &&
644 SwFlowFrame::CastFlowFrame( mrpFrame )->IsFollow() ?
645 nullptr :
646 rDesc.GetPageDesc();
647
649 mbBreakAfter = rBrk.GetBreak() == SvxBreak::PageAfter ||
650 rBrk.GetBreak() == SvxBreak::PageBoth;
651 if ( !bBrk )
652 bBrk = rBrk.GetBreak() == SvxBreak::PageBefore ||
653 rBrk.GetBreak() == SvxBreak::PageBoth;
654
655 if ( bBrk || pDesc )
656 {
657 ::std::optional<sal_uInt16> oPgNum;
658 if ( !pDesc )
659 {
660 pDesc = mrpPage->GetPageDesc()->GetFollow();
661 }
662 else
663 {
664 oPgNum = rDesc.GetNumOffset();
665 if ( oPgNum )
666 static_cast<SwRootFrame*>(mrpPage->GetUpper())->SetVirtPageNum(true);
667 }
668 bool bNextPageRight = !mrpPage->OnRightPage();
669 bool bInsertEmpty = false;
670 assert(mrpPage->GetUpper()->GetLower());
671 if (oPgNum && bNextPageRight != IsRightPageByNumber(
672 *static_cast<SwRootFrame*>(mrpPage->GetUpper()), *oPgNum))
673 {
674 bNextPageRight = !bNextPageRight;
675 bInsertEmpty = true;
676 }
677 // If the page style is changing, we'll have a first page.
678 bool bNextPageFirst = pDesc != mrpPage->GetPageDesc();
679 ::InsertNewPage( const_cast<SwPageDesc&>(*pDesc), mrpPage->GetUpper(),
680 bNextPageRight, bNextPageFirst, bInsertEmpty, false, mrpPage->GetNext());
681 if ( bEnd )
682 {
683 OSL_ENSURE( mrpPage->GetNext(), "No new page?" );
684 do
685 { mrpPage = static_cast<SwPageFrame*>(mrpPage->GetNext());
686 } while ( mrpPage->GetNext() );
687 }
688 else
689 {
690 OSL_ENSURE( mrpPage->GetNext(), "No new page?" );
691 mrpPage = static_cast<SwPageFrame*>(mrpPage->GetNext());
692 if ( mrpPage->IsEmptyPage() )
693 {
694 OSL_ENSURE( mrpPage->GetNext(), "No new page?" );
695 mrpPage = static_cast<SwPageFrame*>(mrpPage->GetNext());
696 }
697 }
699 while( mrpLay->Lower() )
700 mrpLay = static_cast<SwLayoutFrame*>(mrpLay->Lower());
701 return true;
702 }
703 return false;
704}
705
714{
715 bool bRet = false;
716 bool bLongTab = false;
717 sal_uLong nMaxRowPerPage( 0 );
718 nNodeIndex -= mnStartOfContent;
719 sal_uInt16 nRows( 0 );
720 if( mrpFrame->IsTabFrame() )
721 {
722 //Inside a table counts every row as a paragraph
723 SwFrame *pLow = static_cast<SwTabFrame*>(mrpFrame)->Lower();
724 nRows = 0;
725 do
726 {
727 ++nRows;
728 pLow = pLow->GetNext();
729 } while ( pLow );
730 mnParagraphCnt += nRows;
731 if( !mpImpl && mnParagraphCnt > mnMaxParaPerPage + 10 )
732 {
733 // OD 09.04.2003 #108698# - improve heuristics:
734 // Assume that a table, which has more than three times the quantity
735 // of maximal paragraphs per page rows, consists of rows, which have
736 // the height of a normal paragraph. Thus, allow as much rows per page
737 // as much paragraphs are allowed.
738 if ( nRows > ( 3*mnMaxParaPerPage ) )
739 {
740 nMaxRowPerPage = mnMaxParaPerPage;
741 }
742 else
743 {
744 SwFrame *pTmp = static_cast<SwTabFrame*>(mrpFrame)->Lower();
745 if( pTmp->GetNext() )
746 pTmp = pTmp->GetNext();
747 pTmp = static_cast<SwRowFrame*>(pTmp)->Lower();
748 sal_uInt16 nCnt = 0;
749 do
750 {
751 ++nCnt;
752 pTmp = pTmp->GetNext();
753 } while( pTmp );
754 nMaxRowPerPage = std::max( sal_uLong(2), mnMaxParaPerPage / nCnt );
755 }
756 bLongTab = true;
757 }
758 }
759 else
761 if( mbFirst && mpImpl && mnIndex < mpImpl->size() &&
762 mpImpl->GetBreakIndex( mnIndex ) == nNodeIndex &&
764 ( ++mnIndex < mpImpl->size() &&
765 mpImpl->GetBreakIndex( mnIndex ) == nNodeIndex ) ) )
766 mbFirst = false;
767 // OD 09.04.2003 #108698# - always split a big tables.
768 if ( !mbFirst ||
769 ( mrpFrame->IsTabFrame() && bLongTab )
770 )
771 {
772 sal_Int32 nRowCount = 0;
773 do
774 {
775 if( mpImpl || bLongTab )
776 {
777 sal_Int32 nOfst = COMPLETE_STRING;
778 sal_uInt16 nType = SW_LAYCACHE_IO_REC_PAGES;
779 if( bLongTab )
780 {
781 mbBreakAfter = true;
782 nOfst = static_cast<sal_Int32>(nRowCount + nMaxRowPerPage);
783 }
784 else
785 {
786 while( mnIndex < mpImpl->size() &&
787 mpImpl->GetBreakIndex(mnIndex) < nNodeIndex)
788 ++mnIndex;
789 if( mnIndex < mpImpl->size() &&
790 mpImpl->GetBreakIndex(mnIndex) == nNodeIndex )
791 {
793 nOfst = mpImpl->GetBreakOfst( mnIndex++ );
794 mbBreakAfter = true;
795 }
796 }
797
798 if( nOfst < COMPLETE_STRING )
799 {
800 bool bSplit = false;
801 sal_uInt16 nRepeat( 0 );
802 if( !bLongTab && mrpFrame->IsTextFrame() &&
804 nOfst < static_cast<SwTextFrame*>(mrpFrame)->GetText().getLength())
805 bSplit = true;
806 else if( mrpFrame->IsTabFrame() && nRowCount < nOfst &&
807 ( bLongTab || SW_LAYCACHE_IO_REC_TABLE == nType ) )
808 {
809 nRepeat = static_cast<SwTabFrame*>(mrpFrame)->
810 GetTable()->GetRowsToRepeat();
811 bSplit = nOfst < nRows && nRowCount + nRepeat < nOfst;
812 bLongTab = bLongTab && bSplit;
813 }
814 if( bSplit )
815 {
817
818 {
820 aFrm.Pos() = mrpLay->getFrameArea().Pos();
821 aFrm.Pos().AdjustY(1 );
822 }
823
825 if( mrpFrame->IsTabFrame() )
826 {
827 SwTabFrame* pTab = static_cast<SwTabFrame*>(mrpFrame);
828 // #i33629#, #i29955#
829 ::RegistFlys( pTab->FindPageFrame(), pTab );
830 SwFrame *pRow = pTab->Lower();
831 SwTabFrame *pFoll = new SwTabFrame( *pTab );
832
833 SwFrame *pPrv;
834 if( nRepeat > 0 )
835 {
836 sw::FlyCreationSuppressor aSuppressor;
837 // Insert new headlines:
838 sal_uInt16 nRowIdx = 0;
839 SwRowFrame* pHeadline = nullptr;
840 while( nRowIdx < nRepeat )
841 {
842 OSL_ENSURE( pTab->GetTable()->GetTabLines()[ nRowIdx ], "Table without rows?" );
843 pHeadline =
844 new SwRowFrame( *pTab->GetTable()->GetTabLines()[ nRowIdx ], pTab );
845 pHeadline->SetRepeatedHeadline( true );
846 pHeadline->InsertBefore( pFoll, nullptr );
847 pHeadline->RegistFlys();
848
849 ++nRowIdx;
850 }
851 pPrv = pHeadline;
852 nRows = nRows + nRepeat;
853 }
854 else
855 pPrv = nullptr;
856 while( pRow && nRowCount < nOfst )
857 {
858 pRow = pRow->GetNext();
859 ++nRowCount;
860 }
861 while ( pRow )
862 {
863 SwFrame* pNxt = pRow->GetNext();
864 pRow->RemoveFromLayout();
865 pRow->InsertBehind( pFoll, pPrv );
866 pPrv = pRow;
867 pRow = pNxt;
868 }
869 mrpFrame = pFoll;
870 }
871 else
872 {
873 SwTextFrame *const pNew = static_cast<SwTextFrame*>(
874 static_cast<SwTextFrame*>(mrpFrame)
875 ->GetTextNodeFirst()->MakeFrame(mrpFrame));
876 pNew->ManipOfst( TextFrameIndex(nOfst) );
877 pNew->SetFollow( static_cast<SwTextFrame*>(mrpFrame)->GetFollow() );
878 static_cast<SwTextFrame*>(mrpFrame)->SetFollow( pNew );
879 mrpFrame = pNew;
880 }
881 }
882 }
883 }
884
885 SwPageFrame* pLastPage = mrpPage;
886 if( CheckInsertPage() )
887 {
888 CheckFlyCache_( pLastPage );
890 {
893 }
894
895 bRet = true;
896 mrpPrv = nullptr;
897 mnParagraphCnt = 0;
898
899 if ( mrpActualSection )
900 {
901 //Did the SectionFrame even have a content? If not, we can
902 //directly put it somewhere else
903 SwSectionFrame *pSct;
904 bool bInit = false;
905 if ( !mrpActualSection->GetSectionFrame()->ContainsContent())
906 {
907 pSct = mrpActualSection->GetSectionFrame();
908 pSct->RemoveFromLayout();
909 }
910 else
911 {
912 pSct = new SwSectionFrame(
913 *mrpActualSection->GetSectionFrame(), false );
914 mrpActualSection->GetSectionFrame()->SimpleFormat();
915 bInit = true;
916 }
917 mrpActualSection->SetSectionFrame( pSct );
918 pSct->InsertBehind( mrpLay, nullptr );
919
920 if( bInit )
921 {
922 pSct->Init();
923 }
924
925 {
927 aFrm.Pos() = mrpLay->getFrameArea().Pos();
928 aFrm.Pos().AdjustY(1 ); //because of the notifications
929 }
930
931 mrpLay = pSct;
932 if ( mrpLay->Lower() && mrpLay->Lower()->IsLayoutFrame() )
934 }
935 }
936 } while( bLongTab || ( mpImpl && mnIndex < mpImpl->size() &&
937 mpImpl->GetBreakIndex( mnIndex ) == nNodeIndex ) );
938 }
939 mbFirst = false;
940 return bRet;
941}
942
943namespace {
944
945struct SdrObjectCompare
946{
947 bool operator()( const SdrObject* pF1, const SdrObject* pF2 ) const
948 {
949 return pF1->GetOrdNum() < pF2->GetOrdNum();
950 }
951};
952
953struct FlyCacheCompare
954{
955 bool operator()( const SwFlyCache* pC1, const SwFlyCache* pC2 ) const
956 {
957 return pC1->nOrdNum < pC2->nOrdNum;
958 }
959};
960
961}
962
969{
970 if( !mpImpl || !pPage )
971 return;
972 const size_t nFlyCount = mpImpl->GetFlyCount();
973 // Any text frames at the page, fly cache available?
974 if( !(pPage->GetSortedObjs() && mnFlyIdx < nFlyCount) )
975 return;
976
977 SwSortedObjs &rObjs = *pPage->GetSortedObjs();
978 sal_uInt16 nPgNum = pPage->GetPhyPageNum();
979
980 // NOTE: Here we do not use the absolute ordnums but
981 // relative ordnums for the objects on this page.
982
983 // skip fly frames from pages before the current page
984 while( mnFlyIdx < nFlyCount &&
986 ++mnFlyIdx;
987
988 // sort cached objects on this page by ordnum
990 size_t nIdx = mnFlyIdx;
991
992 SwFlyCache* pFlyC;
993 while( nIdx < nFlyCount &&
994 ( pFlyC = &mpImpl->GetFlyCache( nIdx ) )->nPageNum == nPgNum )
995 {
996 aFlyCacheSet.insert( pFlyC );
997 ++nIdx;
998 }
999
1000 // sort objects on this page by ordnum
1002 for (SwAnchoredObject* pAnchoredObj : rObjs)
1003 {
1004 if (SwFlyFrame *pFly = pAnchoredObj->DynCastFlyFrame()) // a text frame?
1005 {
1006 if( pFly->GetAnchorFrame() &&
1007 !pFly->GetAnchorFrame()->FindFooterOrHeader() )
1008 {
1009 const SwContact *pC = ::GetUserCall( pAnchoredObj->GetDrawObj() );
1010 if( pC )
1011 {
1012 aFlySet.insert( pAnchoredObj->GetDrawObj() );
1013 }
1014 }
1015 }
1016 }
1017
1018 if ( aFlyCacheSet.size() != aFlySet.size() )
1019 return;
1020
1021 auto aFlySetIt = aFlySet.begin();
1022
1023 for ( const SwFlyCache* pFlyCache : aFlyCacheSet )
1024 {
1025 SwFlyFrame* pFly = const_cast<SwVirtFlyDrawObj*>(static_cast<const SwVirtFlyDrawObj*>(*aFlySetIt))->GetFlyFrame();
1026
1027 if ( pFly->getFrameArea().Left() == FAR_AWAY )
1028 {
1029 // we get the stored information
1031 aFrm.Pos().setX( pFlyCache->Left() + pPage->getFrameArea().Left() );
1032 aFrm.Pos().setY( pFlyCache->Top() + pPage->getFrameArea().Top() );
1033
1034 if ( mpImpl->IsUseFlyCache() )
1035 {
1036 aFrm.Width( pFlyCache->Width() );
1037 aFrm.Height( pFlyCache->Height() );
1038 }
1039 }
1040
1041 ++aFlySetIt;
1042 }
1043}
1044
1046 m_pStream( &rStrm ),
1047 m_nFlagRecEnd ( 0 ),
1048 m_nMajorVersion(SW_LAYCACHE_IO_VERSION_MAJOR),
1049 m_nMinorVersion(SW_LAYCACHE_IO_VERSION_MINOR),
1050 m_bWriteMode( bWrtMd ),
1051 m_bError( false )
1052{
1053 if( m_bWriteMode )
1056
1057 else
1060}
1061
1063{
1064 sal_uInt32 nPos = m_pStream->Tell();
1065 if( m_bWriteMode )
1066 {
1067 m_aRecords.emplace_back(cType, nPos );
1068 m_pStream->WriteUInt32( 0 );
1069 }
1070 else
1071 {
1072 sal_uInt32 nVal(0);
1073 m_pStream->ReadUInt32( nVal );
1074 sal_uInt8 cRecTyp = static_cast<sal_uInt8>(nVal);
1075 if (!nVal || cRecTyp != cType || !m_pStream->good())
1076 {
1077 OSL_ENSURE( nVal, "OpenRec: Record-Header is 0" );
1078 OSL_ENSURE( cRecTyp == cType, "OpenRec: Wrong Record Type" );
1079 m_aRecords.emplace_back(0, m_pStream->Tell() );
1080 m_bError = true;
1081 }
1082 else
1083 {
1084 sal_uInt32 nSize = nVal >> 8;
1085 m_aRecords.emplace_back(cRecTyp, nPos+nSize );
1086 }
1087 }
1088}
1089
1090// Close record
1092{
1093 bool bRes = true;
1094 OSL_ENSURE( !m_aRecords.empty(), "CloseRec: no levels" );
1095 if( !m_aRecords.empty() )
1096 {
1097 sal_uInt32 nPos = m_pStream->Tell();
1098 if( m_bWriteMode )
1099 {
1100 sal_uInt32 nBgn = m_aRecords.back().size;
1101 m_pStream->Seek( nBgn );
1102 sal_uInt32 nSize = nPos - nBgn;
1103 sal_uInt32 nVal = ( nSize << 8 ) | m_aRecords.back().type;
1104 m_pStream->WriteUInt32( nVal );
1105 m_pStream->Seek( nPos );
1106 if( m_pStream->GetError() != ERRCODE_NONE )
1107 bRes = false;
1108 }
1109 else
1110 {
1111 sal_uInt32 n = m_aRecords.back().size;
1112 OSL_ENSURE( n >= nPos, "CloseRec: too much data read" );
1113 if( n != nPos )
1114 {
1115 m_pStream->Seek( n );
1116 if( n < nPos )
1117 bRes = false;
1118 }
1120 bRes = false;
1121 }
1122 m_aRecords.pop_back();
1123 }
1124
1125 if( !bRes )
1126 m_bError = true;
1127}
1128
1130{
1131 sal_uInt32 n = 0;
1132 if( !m_bError && !m_aRecords.empty() )
1133 {
1134 sal_uInt32 nEndPos = m_aRecords.back().size;
1135 sal_uInt32 nPos = m_pStream->Tell();
1136 if( nEndPos > nPos )
1137 n = nEndPos - nPos;
1138 }
1139 return n;
1140}
1141
1143{
1144 sal_uInt8 c(0);
1145 if( !m_bError )
1146 {
1147 sal_uInt32 nPos = m_pStream->Tell();
1148 m_pStream->ReadUChar( c );
1149 m_pStream->Seek( nPos );
1151 {
1152 c = 0;
1153 m_bError = true;
1154 }
1155 }
1156 return c;
1157}
1158
1160{
1161 sal_uInt8 c = Peek();
1162 OpenRec( c );
1163 m_pStream->Seek( m_aRecords.back().size );
1164 CloseRec();
1165}
1166
1168{
1169 OSL_ENSURE( !m_bWriteMode, "OpenFlagRec illegal in write mode" );
1170 sal_uInt8 cFlags(0);
1171 m_pStream->ReadUChar( cFlags );
1172 m_nFlagRecEnd = m_pStream->Tell() + ( cFlags & 0x0F );
1173 return (cFlags >> 4);
1174}
1175
1177{
1178 OSL_ENSURE( m_bWriteMode, "OpenFlagRec illegal in read mode" );
1179 OSL_ENSURE( (nFlags & 0xF0) == 0, "illegal flags set" );
1180 OSL_ENSURE( nLen < 16, "wrong flag record length" );
1181 sal_uInt8 cFlags = (nFlags << 4) + nLen;
1182 m_pStream->WriteUChar( cFlags );
1183 m_nFlagRecEnd = m_pStream->Tell() + nLen;
1184}
1185
1187{
1188 if( m_bWriteMode )
1189 {
1190 OSL_ENSURE( m_pStream->Tell() == m_nFlagRecEnd, "Wrong amount of data written" );
1191 }
1192 else
1193 {
1194 OSL_ENSURE( m_pStream->Tell() <= m_nFlagRecEnd, "Too many data read" );
1195 if( m_pStream->Tell() != m_nFlagRecEnd )
1197 }
1198}
1199
1200/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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...
bool m_bError
virtual const SwRootFrame * GetCurrentLayout() const =0
virtual const SwDocStat & GetDocStat() const =0
Document - Statistics.
sal_uInt32 GetOrdNum() const
SvStream & WriteInt32(sal_Int32 nInt32)
sal_uInt64 Tell() const
bool good() const
SvStream & WriteUChar(unsigned char nChar)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadInt32(sal_Int32 &rInt32)
ErrCode GetError() const
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
ErrCode const & GetErrorCode() const
SvStream & ReadUChar(unsigned char &rChar)
SvxBreak GetBreak() const
SwSectionNode * m_pSectNode
Definition: layhelp.hxx:89
SwActualSection(SwActualSection *pUpper, SwSectionFrame *pSect, SwSectionNode *pNd)
helper class to create not nested section frames for nested sections.
Definition: laycache.cxx:454
wrapper class for the positioning of Writer fly frames and drawing objects
Base class for the following contact objects (frame + draw objects).
Definition: dcontact.hxx:67
Definition: doc.hxx:194
SwLayoutCache * GetLayoutCache() const
Definition: doc.hxx:1558
SwNodes & GetNodes()
Definition: doc.hxx:417
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:411
const SwFrameFormats * GetTableFrameFormats() const
Definition: doc.hxx:819
IDocumentStatistics const & getIDocumentStatistics() const
Definition: doc.cxx:379
sal_uInt16 nPageNum
page number
Definition: layhelp.hxx:211
sal_uLong nOrdNum
Id to recognize text frames.
Definition: layhelp.hxx:210
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
virtual const SwFlyFrame * DynCastFlyFrame() const override
Definition: fly.cxx:2989
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:46
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:36
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:61
const ::std::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:64
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
bool isFrameAreaSizeValid() const
Definition: frame.hxx:167
size_t size() const
Base class of the Writer layout elements.
Definition: frame.hxx:315
bool OnRightPage() const
Definition: frame.hxx:733
void InsertBehind(SwLayoutFrame *pParent, SwFrame *pBefore)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:872
bool IsTextFrame() const
Definition: frame.hxx:1234
SwFrame * GetNext()
Definition: frame.hxx:676
bool IsTabFrame() const
Definition: frame.hxx:1218
SwFrame * GetLower()
Definition: findfrm.cxx:194
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:836
void RemoveFromLayout()
Definition: wsfrm.cxx:1013
bool IsFlowFrame() const
Definition: frame.hxx:1242
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:1020
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
virtual const SvxFormatBreakItem & GetBreakItem() const
Definition: findfrm.cxx:711
SwFrame * GetPrev()
Definition: frame.hxx:677
bool IsSctFrame() const
Definition: frame.hxx:1214
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:716
bool IsLayoutFrame() const
Definition: frame.hxx:1170
sal_Int32 GetBreakOfst(size_t nIdx) const
Definition: layhelp.hxx:74
bool m_bUseFlyCache
Definition: layhelp.hxx:63
sal_uInt16 GetBreakType(size_t nIdx) const
Definition: layhelp.hxx:75
std::vector< sal_uInt16 > m_aType
Definition: layhelp.hxx:61
size_t GetFlyCount() const
Definition: layhelp.hxx:218
SwPageFlyCache m_FlyCache
Definition: layhelp.hxx:62
std::vector< SwNodeOffset > mIndices
Definition: layhelp.hxx:58
bool IsUseFlyCache() const
Definition: layhelp.hxx:80
std::deque< sal_Int32 > m_aOffset
either a textframe character offset, or a row index inside a table
Definition: layhelp.hxx:60
SwFlyCache & GetFlyCache(size_t nIdx)
Definition: layhelp.hxx:220
bool Read(SvStream &rStream)
Definition: laycache.cxx:87
void Insert(sal_uInt16 nType, SwNodeOffset nIndex, sal_Int32 nOffset)
Definition: laycache.cxx:80
SwNodeOffset GetBreakIndex(size_t nIdx) const
Definition: layhelp.hxx:73
size_t size() const
Definition: layhelp.hxx:69
sal_uInt16 GetMajorVersion() const
Definition: layhelp.hxx:202
void CloseRec()
Close a record.
Definition: laycache.cxx:1091
std::vector< RecTypeSize > m_aRecords
Definition: layhelp.hxx:154
sal_uInt16 GetMinorVersion() const
Definition: layhelp.hxx:203
sal_uInt8 OpenFlagRec()
Open a flag record for reading.
Definition: laycache.cxx:1167
sal_uInt32 BytesLeft()
Return the number of bytes contained in the current record that haven't been read by now.
Definition: laycache.cxx:1129
SvStream & GetStream() const
Get input or output stream.
Definition: layhelp.hxx:170
sal_uLong m_nFlagRecEnd
Definition: layhelp.hxx:158
sal_uInt16 m_nMajorVersion
Definition: layhelp.hxx:160
void OpenRec(sal_uInt8 nType)
Open a record of type "nType".
Definition: laycache.cxx:1062
void CloseFlagRec()
Close a flag record. Any bytes left are skipped.
Definition: laycache.cxx:1186
SvStream * m_pStream
Definition: layhelp.hxx:156
sal_uInt8 Peek()
Return the current record's type.
Definition: laycache.cxx:1142
void SkipRec()
Skip the current record.
Definition: laycache.cxx:1159
sal_uInt16 m_nMinorVersion
Definition: layhelp.hxx:161
bool HasError() const
Definition: layhelp.hxx:200
SwLayCacheIoImpl(SvStream &rStrm, bool bWrtMd)
Definition: laycache.cxx:1045
sal_uLong CalcPageCount()
Does NOT really calculate the page count, it returns the page count value from the layout cache,...
Definition: laycache.cxx:572
bool mbFirst
Definition: layhelp.hxx:119
sal_uLong mnParagraphCnt
Definition: layhelp.hxx:115
SwPageFrame *& mrpPage
Definition: layhelp.hxx:108
size_t mnFlyIdx
the index in the fly cache array
Definition: layhelp.hxx:118
SwFrame *& mrpFrame
Definition: layhelp.hxx:106
SwLayCacheImpl * mpImpl
Definition: layhelp.hxx:113
SwNodeOffset mnStartOfContent
Definition: layhelp.hxx:116
bool CheckInsert(SwNodeOffset nNodeIndex)
entry point for the InsertCnt_-function.
Definition: laycache.cxx:713
SwLayHelper(SwDoc *pD, SwFrame *&rpF, SwFrame *&rpP, SwPageFrame *&rpPg, SwLayoutFrame *&rpL, std::unique_ptr< SwActualSection > &rpA, SwNodeOffset nNodeIndex, bool bCache)
helper class, which utilizes the layout cache information to distribute the document content to the r...
Definition: laycache.cxx:519
SwLayoutFrame *& mrpLay
Definition: layhelp.hxx:109
void CheckFlyCache_(SwPageFrame *pPage)
If a new page is inserted, the last page is analysed.
Definition: laycache.cxx:968
bool mbBreakAfter
Definition: layhelp.hxx:111
size_t mnIndex
the index in the page break array
Definition: layhelp.hxx:117
sal_uLong mnMaxParaPerPage
Definition: layhelp.hxx:114
std::unique_ptr< SwActualSection > & mrpActualSection
Definition: layhelp.hxx:110
SwFrame *& mrpPrv
Definition: layhelp.hxx:107
bool CheckInsertPage()
inserts a page and return true, if
Definition: laycache.cxx:636
SwDoc * mpDoc
Definition: layhelp.hxx:112
void ClearImpl()
Definition: laycache.cxx:440
std::unique_ptr< SwLayCacheImpl > m_pImpl
Definition: laycache.hxx:43
void UnlockImpl()
Definition: laycache.hxx:61
sal_uInt16 m_nLockCount
Definition: laycache.hxx:44
SwLayCacheImpl * LockImpl()
Definition: laycache.hxx:56
void Read(SvStream &rStream)
Definition: laycache.cxx:68
static void Write(SvStream &rStream, const SwDoc &rDoc)
writes the index (more precise: the difference between the index and the first index of the document ...
Definition: laycache.cxx:163
bool IsLocked() const
Definition: laycache.hxx:54
bool CompareLayout(const SwDoc &rDoc) const
Definition: laycache.cxx:325
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:399
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method <ContainsAny()> doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:129
const SwFrame * Lower() const
Definition: layfrm.hxx:101
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
SwNodeOffset GetIndex() const
Definition: node.hxx:312
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:974
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:153
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:158
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:165
SwNode & GetEndOfInserts() const
Section for all footnotes.
Definition: ndarr.hxx:156
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:267
A page of the document layout.
Definition: pagefrm.hxx:58
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:132
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:143
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Height(tools::Long nNew)
Definition: swrect.hxx:193
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void Pos(const Point &rNew)
Definition: swrect.hxx:171
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
SwRowFrame is one table row in the document layout.
Definition: rowfrm.hxx:29
void SetRepeatedHeadline(bool bNew)
Definition: rowfrm.hxx:91
void RegistFlys(SwPageFrame *pPage=nullptr)
Register Flys after a line was created AND inserted Must be called by the creator; the Fly is inserte...
Definition: tabfrm.cxx:3949
class for collecting anchored objects
Definition: sortedobjs.hxx:49
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:47
SwTabFrame * FindMaster(bool bFirstMaster=false) const
Definition: flowfrm.cxx:773
const SwTabFrame * GetFollow() const
Definition: tabfrm.hxx:250
const SwTable * GetTable() const
Definition: tabfrm.hxx:158
SwTableNode * GetTableNode() const
Definition: swtable.cxx:2142
SwTableLines & GetTabLines()
Definition: swtable.hxx:204
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:456
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:463
void ManipOfst(TextFrameIndex const nNewOfst)
Definition: txtfrm.hxx:447
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1293
bool getBrowseMode() const
Definition: viewopt.hxx:580
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:433
const_iterator begin() const
size_type size() const
std::pair< const_iterator, bool > insert(Value &&x)
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:172
#define ERRCODE_NONE
void RegistFlys(SwPageFrame *, const SwLayoutFrame *)
Definition: frmtool.cxx:3227
SwPageFrame * InsertNewPage(SwPageDesc &rDesc, SwFrame *pUpper, bool isRightPage, bool bFirst, bool bInsertEmpty, bool bFootnote, SwFrame *pSibling, bool bVeryFirstPage=false)
Definition: frmtool.cxx:3122
#define FAR_AWAY
Definition: frmtool.hxx:53
GtkMediaStream * m_pStream
sal_Int32 nIndex
sal_Int64 n
#define SW_LAYCACHE_IO_VERSION_MINOR
Definition: layhelp.hxx:144
#define SW_LAYCACHE_IO_REC_PAGES
Definition: layhelp.hxx:138
#define SW_LAYCACHE_IO_REC_TABLE
Definition: layhelp.hxx:140
#define SW_LAYCACHE_IO_REC_PARA
Definition: layhelp.hxx:139
#define SW_LAYCACHE_IO_VERSION_MAJOR
Definition: layhelp.hxx:143
#define SW_LAYCACHE_IO_REC_FLY
Definition: layhelp.hxx:141
sal_uInt16 nPos
#define SAL_WARN(area, stream)
size
void SvStream & rStrm
bool IsRightPageByNumber(SwRootFrame const &rLayout, sal_uInt16 nPageNum)
Definition: frmtool.cxx:3111
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
constexpr SwNodeOffset NODE_OFFSET_MAX(SAL_MAX_INT32)
QPRO_FUNC_TYPE nType
sal_uIntPtr sal_uLong
sal_uLong nPara
paragraphs for document statistic: non-empty and non-hidden ones
Definition: docstat.hxx:32
sal_uLong nPage
Definition: docstat.hxx:30
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
unsigned char sal_uInt8
static sal_uInt16 nPgNum
Definition: viewport.cxx:52