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