2021-08-02

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 );

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值