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