D:\office\source\core_v7.0\sw\source\core\layout\frmtool.cxx
void InsertCnt_( SwLayoutFrame *pLay, SwDoc *pDoc,
sal_uLong nIndex, bool bPages, sal_uLong nEndIndex,
SwFrame *pPrv, sw::FrameMode const eMode )
堆栈信息
swlo.dll!SetLastPage(SwPageFrame * pPage) 行 843 C++
swlo.dll!SwPageFrame::Cut() 行 899 C++
swlo.dll!SwRootFrame::RemovePage(SwPageFrame * * pDelRef, SwRemoveResult eResult) 行 1434 C++
swlo.dll!SwRootFrame::RemoveSuperfluous() 行 1541 C++
swlo.dll!SwLayAction::InternalAction(OutputDevice * pRenderContext) 行 491 C++
swlo.dll!SwLayAction::Action(OutputDevice * pRenderContext) 行 346 C++
swlo.dll!SwViewShell::ImplEndAction(const bool bIdleEnd) 行 286 C++
swlo.dll!SwViewShell::EndAction(const bool bIdleEnd) 行 599 C++
swlo.dll!SwViewShell::MakeVisible(const SwRect & rRect) 行 584 C++
swlo.dll!SwCursorShell::MakeSelVisible() 行 3103 C++
swlo.dll!SwFEShell::MakeSelVisible() 行 2594 C++
swlo.dll!SwCursorShell::UpdateCursor(unsigned short eFlags, bool bIdleEnd) 行 2002 C++
swlo.dll!SwCursorShell::EndAction(const bool bIdleEnd, const bool DoSetPosX) 行 282 C++
swlo.dll!SwCursorShell::EndCursorMove(const bool bIdleEnd) 行 316 C++
swlo.dll!SwLayIdle::SwLayIdle(SwRootFrame * pRt, SwViewShellImp * pI) 行 2255 C++
swlo.dll!SwViewShell::LayoutIdle() 行 715 C++
swlo.dll!sw::DocumentTimerManager::DoIdleJobs(Timer * __formal) 行 179 C++
swlo.dll!sw::DocumentTimerManager::LinkStubDoIdleJobs(void * instance, Timer * data) 行 158 C++
vcllo.dll!Link<Timer *,void>::Call(Timer * data) 行 111 C++
vcllo.dll!Timer::Invoke() 行 76 C++
vcllo.dll!Scheduler::ProcessTaskScheduling() 行 478 C++
vcllo.dll!Scheduler::CallbackTaskScheduling() 行 288 C++
vcllo.dll!SalTimer::CallCallback() 行 55 C++
vclplug_winlo.dll!WinSalTimer::ImplHandleElapsedTimer() 行 164 C++
vclplug_winlo.dll!ImplSalYield(bool bWait, bool bHandleAllCurrentEvents) 行 481 C++
vclplug_winlo.dll!WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents) 行 527 C++
vcllo.dll!ImplYield(bool i_bWait, bool i_bAllEvents) 行 455 C++
vcllo.dll!Application::Yield() 行 520 C++
vcllo.dll!Application::Execute() 行 434 C++
sofficeapp.dll!desktop::Desktop::Main() 行 1607 C++
vcllo.dll!ImplSVMain() 行 263 C++
vcllo.dll!SVMain() 行 296 C++
sofficeapp.dll!soffice_main() 行 98 C++
LanShanOffice.bin!sal_main() 行 48 C
frmform.cxx
void SwTextFrame::AdjustFollow_( SwTextFormatter &rLine,
const TextFrameIndex nOffset, const TextFrameIndex nEnd,
const sal_uInt8 nMode )
绘制内容:
\sw\source\core\layout\layact.cxx
void SwLayAction::PaintContent( const SwContentFrame *pCnt,
const SwPageFrame *pPage,
const SwRect &rOldRect,
long nOldBottom )
{
SwRectFnSet aRectFnSet(pCnt);
if ( pCnt->IsCompletePaint() || !pCnt->IsTextFrame() )
{
SwRect aPaint( pCnt->GetPaintArea() );
if ( !PaintContent_( pCnt, pPage, aPaint ) )
pCnt->ResetCompletePaint();
}
else
{
// paint the area between printing bottom and frame bottom and
// the area left and right beside the frame, if its height changed.
long nOldHeight = aRectFnSet.GetHeight(rOldRect);
long nNewHeight = aRectFnSet.GetHeight(pCnt->getFrameArea());
const bool bHeightDiff = nOldHeight != nNewHeight;
if( bHeightDiff )
{
// consider whole potential paint area.
SwRect aDrawRect( pCnt->GetPaintArea() );
if( nOldHeight > nNewHeight )
nOldBottom = aRectFnSet.GetPrtBottom(*pCnt);
aRectFnSet.SetTop( aDrawRect, nOldBottom );
PaintContent_( pCnt, pPage, aDrawRect );
}
// paint content area
SwRect aPaintRect = static_cast<SwTextFrame*>(const_cast<SwContentFrame*>(pCnt))->GetPaintSwRect();
PaintContent_( pCnt, pPage, aPaintRect );
}
if ( pCnt->IsRetouche() && !pCnt->GetNext() )
{
const SwFrame *pTmp = pCnt;
if( pCnt->IsInSct() )
{
const SwSectionFrame* pSct = pCnt->FindSctFrame();
if( pSct->IsRetouche() && !pSct->GetNext() )
pTmp = pSct;
}
SwRect aRect( pTmp->GetUpper()->GetPaintArea() );
aRectFnSet.SetTop( aRect, aRectFnSet.GetPrtBottom(*pTmp) );
if ( !PaintContent_( pCnt, pPage, aRect ) )
pCnt->ResetRetouche();
}
}
sw\source\core\layout\pgchg.cxx
// Calculate how the pages have to be positioned
void SwRootFrame::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea )
{
SwViewShell* pSh = GetCurrShell();
vcl::RenderContext* pRenderContext = pSh ? pSh->GetOut() : nullptr;
// #i91432#
// No calculation of page positions, if only an empty page is present.
// This situation occurs when instance is in construction
// and the document contains only left pages.
if ( Lower()->GetNext() == nullptr &&
static_cast<SwPageFrame*>(Lower())->IsEmptyPage() )
{
return;
}
if ( !pVisArea )
{
// no early return for bNewPage
if ( mnViewWidth < 0 )
mnViewWidth = 0;
}
else
{
assert(pViewOpt && "CheckViewLayout required ViewOptions");
const sal_uInt16 nColumns = pViewOpt->GetViewLayoutColumns();
const bool bBookMode = pViewOpt->IsViewLayoutBookMode();
if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged )
return;
mnColumns = nColumns;
mbBookMode = bBookMode;
mnViewWidth = pVisArea->Width();
mbSidebarChanged = false;
}
if( GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE ) )
{
mnColumns = 1;
mbBookMode = false;
}
Calc(pRenderContext);
const bool bOldCallbackActionEnabled = IsCallbackActionEnabled();
SetCallbackActionEnabled( false );
maPageRects.clear();
const long nBorder = getFrameArea().Pos().getX();
const long nVisWidth = mnViewWidth - 2 * nBorder;
const long nGapBetweenPages = pViewOpt ? pViewOpt->GetGapBetweenPages()
: (pSh ? pSh->GetViewOptions()->GetGapBetweenPages()
: SwViewOption::defGapBetweenPages);
// check how many pages fit into the first page layout row:
SwPageFrame* pPageFrame = static_cast<SwPageFrame*>(Lower());
// will contain the number of pages per row. 0 means that
// the page does not fit.
long nWidthRemain = nVisWidth;
// after one row has been processed, these variables contain
// the width of the row and the maximum of the page heights
long nCurrentRowHeight = 0;
long nCurrentRowWidth = 0;
// these variables are used to finally set the size of the
// root frame
long nSumRowHeight = 0;
SwTwips nMinPageLeft = TWIPS_MAX;
SwTwips nMaxPageRight = 0;
SwPageFrame* pStartOfRow = pPageFrame;
sal_uInt16 nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page
bool bFirstRow = true;
bool bPageChanged = false;
const bool bRTL = !IsLeftToRightViewLayout();
const SwTwips nSidebarWidth = SwPageFrame::GetSidebarBorderWidth( pSh );
while ( pPageFrame )
{
// we consider the current page to be "start of row" if
// 1. it is the first page in the current row or
// 2. it is the second page in the row and the first page is an empty page in non-book view:
const bool bStartOfRow = pPageFrame == pStartOfRow ||
( pStartOfRow->IsEmptyPage() && pPageFrame == pStartOfRow->GetNext() && !mbBookMode );
const bool bEmptyPage = pPageFrame->IsEmptyPage() && !mbBookMode;
// no half doc border space for first page in each row and
long nPageWidth = 0;
long nPageHeight = 0;
if ( mbBookMode )
{
const SwFrame& rFormatPage = pPageFrame->GetFormatPage();
nPageWidth = rFormatPage.getFrameArea().Width() + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrame->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages);
nPageHeight = rFormatPage.getFrameArea().Height() + nGapBetweenPages;
}
else
{
if ( !pPageFrame->IsEmptyPage() )
{
nPageWidth = pPageFrame->getFrameArea().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages);
nPageHeight = pPageFrame->getFrameArea().Height() + nGapBetweenPages;
}
}
if ( !bEmptyPage )
++nNumberOfPagesInRow;
// finish current row if
// 1. in dynamic mode the current page does not fit anymore or
// 2. the current page exceeds the maximum number of columns
bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) ||
(0 != mnColumns && mnColumns < nNumberOfPagesInRow);
// make sure that at least one page goes to the current row:
if ( !bRowFinished || bStartOfRow )
{
// current page is allowed to be in current row
nWidthRemain = nWidthRemain - nPageWidth;
nCurrentRowWidth = nCurrentRowWidth + nPageWidth;
nCurrentRowHeight = std::max( nCurrentRowHeight, nPageHeight );
pPageFrame = static_cast<SwPageFrame*>(pPageFrame->GetNext());
if ( !pPageFrame )
bRowFinished = true;
}
if ( bRowFinished )
{
// pPageFrame now points to the first page in the new row or null
// pStartOfRow points to the first page in the current row
// special centering for last row. pretend to fill the last row with virtual copies of the last page before centering:
if ( !pPageFrame && nWidthRemain > 0 )
{
// find last page in current row:
const SwPageFrame* pLastPageInCurrentRow = pStartOfRow;
while( pLastPageInCurrentRow->GetNext() )
pLastPageInCurrentRow = static_cast<const SwPageFrame*>(pLastPageInCurrentRow->GetNext());
if ( pLastPageInCurrentRow->IsEmptyPage() )
pLastPageInCurrentRow = static_cast<const SwPageFrame*>(pLastPageInCurrentRow->GetPrev());
// check how many times the last page would still fit into the remaining space:
sal_uInt16 nNumberOfVirtualPages = 0;
const sal_uInt16 nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX;
SwTwips nRemain = nWidthRemain;
SwTwips nVirtualPagesWidth = 0;
SwTwips nLastPageWidth = pLastPageInCurrentRow->getFrameArea().Width() + nSidebarWidth;
while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages )
{
SwTwips nLastPageWidthWithGap = nLastPageWidth;
if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) )
nLastPageWidthWithGap += nGapBetweenPages;
if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain )
{
++nNumberOfVirtualPages;
nVirtualPagesWidth += nLastPageWidthWithGap;
}
nRemain = nRemain - nLastPageWidthWithGap;
}
nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth;
}
// first page in book mode is always special:
if ( bFirstRow && mbBookMode )
{
// #i88036#
nCurrentRowWidth +=
pStartOfRow->GetFormatPage().getFrameArea().Width() + nSidebarWidth;
}
// center page if possible
long nSizeDiff = 0;
if (nVisWidth > nCurrentRowWidth && !comphelper::LibreOfficeKit::isActive())
nSizeDiff = ( nVisWidth - nCurrentRowWidth ) / 2;
// adjust positions of pages in current row
long nX = nSizeDiff;
const long nRowStart = nBorder + nSizeDiff;
const long nRowEnd = nRowStart + nCurrentRowWidth;
if ( bFirstRow && mbBookMode )
{
// #i88036#
nX += pStartOfRow->GetFormatPage().getFrameArea().Width() + nSidebarWidth;
}
SwPageFrame* pEndOfRow = pPageFrame;
SwPageFrame* pPageToAdjust = pStartOfRow;
do
{
const SwPageFrame* pFormatPage = pPageToAdjust;
if ( mbBookMode )
pFormatPage = &pPageToAdjust->GetFormatPage();
const SwTwips nCurrentPageWidth = pFormatPage->getFrameArea().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth);
const Point aOldPagePos = pPageToAdjust->getFrameArea().Pos();
const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SidebarPosition::LEFT;
const SwTwips nLeftPageAddOffset = bLeftSidebar ?
nSidebarWidth :
0;
Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight );
Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight );
// RTL view layout: Calculate mirrored page position
if ( bRTL )
{
const long nXOffsetInRow = aNewPagePos.getX() - nRowStart;
aNewPagePos.setX(nRowEnd - nXOffsetInRow - nCurrentPageWidth);
aNewPagePosWithLeftOffset = aNewPagePos;
aNewPagePosWithLeftOffset.setX(aNewPagePosWithLeftOffset.getX() + nLeftPageAddOffset);
}
if ( aNewPagePosWithLeftOffset != aOldPagePos )
{
lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos );
pPageToAdjust->SetCompletePaint();
bPageChanged = true;
}
// calculate area covered by the current page and store to
// maPageRects. This is used e.g., for cursor setting
const bool bFirstColumn = pPageToAdjust == pStartOfRow;
const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow;
const bool bLastRow = !pEndOfRow;
nMinPageLeft = std::min( nMinPageLeft, aNewPagePos.getX() );
nMaxPageRight = std::max( nMaxPageRight, aNewPagePos.getX() + nCurrentPageWidth);
// border of nGapBetweenPages around the current page:
SwRect aPageRectWithBorders( aNewPagePos.getX() - nGapBetweenPages,
aNewPagePos.getY(),
pPageToAdjust->getFrameArea().SSize().Width() + nGapBetweenPages + nSidebarWidth,
nCurrentRowHeight );
static const long nOuterClickDiff = 1000000;
// adjust borders for these special cases:
if ( (bFirstColumn && !bRTL) || (bLastColumn && bRTL) )
aPageRectWithBorders.SubLeft( nOuterClickDiff );
if ( (bLastColumn && !bRTL) || (bFirstColumn && bRTL) )
aPageRectWithBorders.AddRight( nOuterClickDiff );
if ( bFirstRow )
aPageRectWithBorders.SubTop( nOuterClickDiff );
if ( bLastRow )
aPageRectWithBorders.AddBottom( nOuterClickDiff );
maPageRects.push_back( aPageRectWithBorders );
nX = nX + nCurrentPageWidth;
pPageToAdjust = static_cast<SwPageFrame*>(pPageToAdjust->GetNext());
// distance to next page
if ( pPageToAdjust && pPageToAdjust != pEndOfRow )
{
// in book view, we add the x gap before left (even) pages:
if ( mbBookMode )
{
if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) )
nX = nX + nGapBetweenPages;
}
else
{
// in non-book view, don't add x gap before
// 1. the last empty page in a row
// 2. after an empty page
const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) ||
( static_cast<SwPageFrame*>(pPageToAdjust->GetPrev())->IsEmptyPage() );
if ( !bDontAddGap )
nX = nX + nGapBetweenPages;
}
}
}
while (pPageToAdjust && pPageToAdjust != pEndOfRow);
// adjust values for root frame size
nSumRowHeight = nSumRowHeight + nCurrentRowHeight;
// start new row:
nCurrentRowHeight = 0;
nCurrentRowWidth = 0;
pStartOfRow = pEndOfRow;
nWidthRemain = nVisWidth;
nNumberOfPagesInRow = 0;
bFirstRow = false;
} // end row finished
} // end while
// set size of root frame:
const Size aOldSize( getFrameArea().SSize() );
const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages );
if ( bPageChanged || aNewSize != aOldSize )
{
ChgSize( aNewSize );
::AdjustSizeChgNotify( this );
Calc(pRenderContext);
if ( pSh && pSh->GetDoc()->GetDocShell() )
{
pSh->SetFirstVisPageInvalid();
if (bOldCallbackActionEnabled)
{
pSh->InvalidateWindows( SwRect( 0, 0, SAL_MAX_INT32, SAL_MAX_INT32 ) );
pSh->GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged));
}
}
}
maPagesArea.Pos( getFrameArea().Pos() );
maPagesArea.SSize( aNewSize );
if ( TWIPS_MAX != nMinPageLeft )
maPagesArea.Left_( nMinPageLeft );
SetCallbackActionEnabled( bOldCallbackActionEnabled );
}