docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / sw / source / core / layout / ssfrm.cxx
blob32c11f4522a1ed5039f5fe7ce31b8740c6ccefa6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_wasm_strip.h>
22 #include <pagefrm.hxx>
23 #include <rootfrm.hxx>
24 #include <dcontact.hxx>
25 #include <flyfrm.hxx>
26 #include <tabfrm.hxx>
27 #include <txtfrm.hxx>
28 #include <cellfrm.hxx>
29 #include <swtable.hxx>
30 #include <fmtfsize.hxx>
31 #include <editeng/boxitem.hxx>
32 #include <editeng/shaditem.hxx>
33 #include <IDocumentRedlineAccess.hxx>
34 #include <IDocumentMarkAccess.hxx>
35 #include <fmtclds.hxx>
36 #include <viewimp.hxx>
37 #include <sortedobjs.hxx>
38 #include <hints.hxx>
39 #include <frmtool.hxx>
40 #include <ndtxt.hxx>
41 #include <osl/diagnose.h>
43 // No inline cause we need the function pointers
44 tools::Long SwFrame::GetTopMargin() const
45 { return getFramePrintArea().Top(); }
46 tools::Long SwFrame::GetBottomMargin() const
47 { return getFrameArea().Height() -getFramePrintArea().Height() -getFramePrintArea().Top(); }
48 tools::Long SwFrame::GetLeftMargin() const
49 { return getFramePrintArea().Left(); }
50 tools::Long SwFrame::GetRightMargin() const
51 { return getFrameArea().Width() - getFramePrintArea().Width() - getFramePrintArea().Left(); }
52 tools::Long SwFrame::GetPrtLeft() const
53 { return getFrameArea().Left() + getFramePrintArea().Left(); }
54 tools::Long SwFrame::GetPrtBottom() const
55 { return getFrameArea().Top() + getFramePrintArea().Height() + getFramePrintArea().Top(); }
56 tools::Long SwFrame::GetPrtRight() const
57 { return getFrameArea().Left() + getFramePrintArea().Width() + getFramePrintArea().Left(); }
58 tools::Long SwFrame::GetPrtTop() const
59 { return getFrameArea().Top() + getFramePrintArea().Top(); }
61 bool SwFrame::SetMinLeft( tools::Long nDeadline )
63 SwTwips nDiff = nDeadline - getFrameArea().Left();
64 if( nDiff > 0 )
66 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
67 aFrm.Left( nDeadline );
69 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
70 aPrt.Width( aPrt.Width() - nDiff );
72 return true;
74 return false;
77 bool SwFrame::SetMaxBottom( tools::Long nDeadline )
79 SwTwips nDiff = getFrameArea().Top() + getFrameArea().Height() - nDeadline;
80 if( nDiff > 0 )
82 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
83 aFrm.Height( aFrm.Height() - nDiff );
85 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
86 aPrt.Height( aPrt.Height() - nDiff );
88 return true;
90 return false;
93 bool SwFrame::SetMaxRight( tools::Long nDeadline )
95 SwTwips nDiff = getFrameArea().Left() + getFrameArea().Width() - nDeadline;
96 if( nDiff > 0 )
98 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
99 aFrm.Width( aFrm.Width() - nDiff );
101 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
102 aPrt.Width( aPrt.Width() - nDiff );
104 return true;
106 return false;
109 void SwFrame::MakeBelowPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
111 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
113 if( pPrv )
115 aFrm.Pos( pPrv->getFrameArea().Pos() );
116 aFrm.Pos().AdjustY(pPrv->getFrameArea().Height() );
118 else
120 aFrm.Pos( pUp->getFrameArea().Pos() );
121 aFrm.Pos() += pUp->getFramePrintArea().Pos();
124 if( bNotify )
126 aFrm.Pos().AdjustY(1 );
130 void SwFrame::MakeLeftPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
132 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
134 if( pPrv )
136 aFrm.Pos( pPrv->getFrameArea().Pos() );
137 aFrm.Pos().AdjustX( -(aFrm.Width()) );
139 else
141 aFrm.Pos( pUp->getFrameArea().Pos() );
142 aFrm.Pos() += pUp->getFramePrintArea().Pos();
143 aFrm.Pos().AdjustX(pUp->getFramePrintArea().Width() - aFrm.Width() );
146 if( bNotify )
148 aFrm.Pos().AdjustX( -1 );
152 void SwFrame::MakeRightPos( const SwFrame* pUp, const SwFrame* pPrv, bool bNotify )
154 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
156 if( pPrv )
158 aFrm.Pos( pPrv->getFrameArea().Pos() );
159 aFrm.Pos().AdjustX(pPrv->getFrameArea().Width() );
161 else
163 aFrm.Pos( pUp->getFrameArea().Pos() );
164 aFrm.Pos() += pUp->getFramePrintArea().Pos();
167 if( bNotify )
169 aFrm.Pos().AdjustX(1 );
173 void SwFrame::SetTopBottomMargins( tools::Long nTop, tools::Long nBot )
175 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
176 aPrt.Top( nTop );
177 aPrt.Height( getFrameArea().Height() - nTop - nBot );
180 void SwFrame::SetLeftRightMargins( tools::Long nLeft, tools::Long nRight)
182 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
183 aPrt.Left( nLeft );
184 aPrt.Width( getFrameArea().Width() - nLeft - nRight );
187 void SwFrame::SetRightLeftMargins( tools::Long nRight, tools::Long nLeft)
189 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
190 aPrt.Left( nLeft );
191 aPrt.Width( getFrameArea().Width() - nLeft - nRight );
194 /// checks the layout direction and invalidates the lower frames recursively, if necessary.
195 void SwFrame::CheckDirChange()
197 bool bOldVert = mbVertical;
198 bool bOldR2L = mbRightToLeft;
199 SetInvalidVert( true );
200 mbInvalidR2L = true;
201 bool bChg = bOldR2L != IsRightToLeft();
202 bool bOldVertL2R = IsVertLR();
203 if( !(( IsVertical() != bOldVert ) || bChg || bOldVertL2R != IsVertLR()) )
204 return;
206 InvalidateAll();
207 if( IsLayoutFrame() )
209 // set minimum row height for vertical cells in horizontal table:
210 if ( IsCellFrame() && GetUpper() )
212 if ( IsVertical() != GetUpper()->IsVertical() &&
213 static_cast<SwCellFrame*>(this)->GetTabBox()->getRowSpan() == 1 )
215 enum {
216 MIN_VERT_CELL_HEIGHT = 1135
219 SwTableLine* pLine = const_cast<SwTableLine*>(static_cast<SwCellFrame*>(this)->GetTabBox()->GetUpper());
220 SwFrameFormat* pFrameFormat = pLine->GetFrameFormat();
221 SwFormatFrameSize aNew( pFrameFormat->GetFrameSize() );
222 if ( SwFrameSize::Fixed != aNew.GetHeightSizeType() )
223 aNew.SetHeightSizeType( SwFrameSize::Minimum );
224 if ( aNew.GetHeight() < MIN_VERT_CELL_HEIGHT )
225 aNew.SetHeight( MIN_VERT_CELL_HEIGHT );
226 SwDoc* pDoc = pFrameFormat->GetDoc();
227 pDoc->SetAttr( aNew, *pLine->ClaimFrameFormat() );
231 SwFrame* pFrame = static_cast<SwLayoutFrame*>(this)->Lower();
232 const SwFormatCol* pCol = nullptr;
233 SwLayoutFrame* pBody = nullptr;
234 if( pFrame )
236 if( IsPageFrame() )
238 // If we're a page frame and we change our layout direction,
239 // we have to look for columns and rearrange them.
240 pBody = static_cast<SwPageFrame*>(this)->FindBodyCont();
241 SwFrame* pLower = pBody ? pBody->Lower() : nullptr;
242 if(pLower && pLower->IsColumnFrame())
243 pCol = &static_cast<SwPageFrame*>(this)->GetFormat()->GetCol();
245 else if( pFrame->IsColumnFrame() )
247 pBody = static_cast<SwLayoutFrame*>(this);
248 const SwFrameFormat *pFormat = pBody->GetFormat();
249 if( pFormat )
250 pCol = &pFormat->GetCol();
253 while( pFrame )
255 pFrame->CheckDirChange();
256 pFrame = pFrame->GetNext();
258 if( pCol )
259 pBody->AdjustColumns( pCol, true );
261 else if( IsTextFrame() )
262 static_cast<SwTextFrame*>(this)->Prepare();
264 // #i31698# - notify anchored objects also for page frames.
265 // Remove code above for special handling of page frames
266 if ( !GetDrawObjs() )
267 return;
269 const SwSortedObjs *pObjs = GetDrawObjs();
270 const size_t nCnt = pObjs->size();
271 for ( size_t i = 0; i < nCnt; ++i )
273 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
274 if( auto pFlyFrame = pAnchoredObj->DynCastFlyFrame() )
275 pFlyFrame->CheckDirChange();
276 else
278 // OD 2004-04-06 #i26791# - direct object
279 // positioning no longer needed. Instead
280 // invalidate
281 pAnchoredObj->InvalidateObjPos();
283 // #i31698# - update layout direction of
284 // anchored object
286 ::setContextWritingMode( pAnchoredObj->DrawObj(), pAnchoredObj->GetAnchorFrameContainingAnchPos() );
287 pAnchoredObj->UpdateLayoutDir();
292 /// returns the position for anchors based on frame direction
293 // OD 2004-03-10 #i11860# - consider lower space and line spacing of
294 // previous frame according to new option 'Use former object positioning'
295 Point SwFrame::GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const
297 Point aAnchor = getFrameArea().Pos();
299 if ( ( IsVertical() && !IsVertLR() ) || IsRightToLeft() )
300 aAnchor.AdjustX(getFrameArea().Width() );
302 if ( IsTextFrame() )
304 SwTwips nBaseOfstForFly =
305 static_cast<const SwTextFrame*>(this)->GetBaseOffsetForFly( bIgnoreFlysAnchoredAtThisFrame );
306 if ( IsVertical() )
307 aAnchor.AdjustY(nBaseOfstForFly );
308 else
309 aAnchor.AdjustX(nBaseOfstForFly );
311 // OD 2004-03-10 #i11860# - if option 'Use former object positioning'
312 // is OFF, consider the lower space and the line spacing of the
313 // previous frame and the spacing considered for the page grid
314 const SwTextFrame* pThisTextFrame = static_cast<const SwTextFrame*>(this);
315 const SwTwips nUpperSpaceAmountConsideredForPrevFrameAndPageGrid =
316 pThisTextFrame->GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid();
317 if ( IsVertical() )
319 aAnchor.AdjustX( -nUpperSpaceAmountConsideredForPrevFrameAndPageGrid );
321 else
323 aAnchor.AdjustY(nUpperSpaceAmountConsideredForPrevFrameAndPageGrid );
327 return aAnchor;
330 void SwFrame::DestroyImpl()
332 mbInDtor = true;
334 // accessible objects for fly and cell frames have been already disposed
335 // by the destructors of the derived classes.
336 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
337 if (IsAccessibleFrame() && !(IsFlyFrame() || IsCellFrame())
338 && (GetDep() || IsTextFrame())) // sw_redlinehide: text frame may not have Dep!
340 assert(!IsTextFrame() || GetDep() || static_cast<SwTextFrame*>(this)->GetMergedPara());
341 const bool bInDocDtor = IsTabFrame() && static_cast<SwTabFrame*>(this)->GetFormat()->GetDoc()->IsInDtor();
342 SwRootFrame *pRootFrame = getRootFrame();
343 if( !bInDocDtor && pRootFrame && pRootFrame->IsAnyShellAccessible() )
345 SwViewShell *pVSh = pRootFrame->GetCurrShell();
346 if( pVSh && pVSh->Imp() )
348 OSL_ENSURE( !GetLower(), "Lowers should be dispose already!" );
349 pVSh->Imp()->DisposeAccessibleFrame( this );
353 #endif
355 if (!m_pDrawObjs)
356 return;
358 for (size_t i = m_pDrawObjs->size(); i; )
360 SwAnchoredObject* pAnchoredObj = (*m_pDrawObjs)[--i];
361 if ( auto pFlyFrame = pAnchoredObj->DynCastFlyFrame() )
363 SwFrame::DestroyFrame(pFlyFrame);
365 else
367 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
368 SwDrawContact* pContact =
369 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
370 OSL_ENSURE( pContact,
371 "<SwFrame::~SwFrame> - missing contact for drawing object" );
372 if ( pContact )
374 pContact->DisconnectObjFromLayout( pSdrObj );
378 m_pDrawObjs.reset();
381 SwFrame::~SwFrame()
383 assert(m_isInDestroy); // check that only DestroySwFrame does "delete"
384 assert(!IsDeleteForbidden()); // check that it's not deleted while deletes are forbidden
385 #if OSL_DEBUG_LEVEL > 0
386 // JP 15.10.2001: for detection of access to deleted frames
387 mpRoot = reinterpret_cast<SwRootFrame*>(0x33333333);
388 #endif
391 void SwFrame::DestroyFrame(SwFrame *const pFrame)
393 if (pFrame)
395 pFrame->m_isInDestroy = true;
396 pFrame->DestroyImpl();
397 assert(pFrame->mbInDtor); // check that nobody forgot to call base class
398 delete pFrame;
402 const SwFrameFormat * SwLayoutFrame::GetFormat() const
404 return static_cast< const SwFrameFormat * >( GetDep() );
407 SwFrameFormat * SwLayoutFrame::GetFormat()
409 return static_cast< SwFrameFormat * >( GetDep() );
412 void SwLayoutFrame::SetFrameFormat(SwFrameFormat* pNew)
414 SwFrameFormat* pOldFormat = GetFormat();
415 if(pNew == pOldFormat)
416 return;
417 pNew->Add(*this);
418 SwClientNotify(*pNew, SwFormatChangeHint(pOldFormat, pNew));
421 SwContentFrame::SwContentFrame( SwContentNode * const pContent, SwFrame* pSib ) :
422 SwFrame( pContent, pSib ),
423 SwFlowFrame( static_cast<SwFrame&>(*this) )
425 assert(!getRootFrame()->HasMergedParas() || pContent->IsCreateFrameWhenHidingRedlines());
428 void SwContentFrame::DestroyImpl()
430 const SwContentNode* pCNd(dynamic_cast<SwContentNode*>(GetDep()));
431 if (nullptr == pCNd && IsTextFrame())
433 pCNd = static_cast<SwTextFrame*>(this)->GetTextNodeFirst();
435 // IsInDtor shouldn't be happening with ViewShell owning layout
436 assert(nullptr == pCNd || !pCNd->GetDoc().IsInDtor());
437 if (nullptr != pCNd && !pCNd->GetDoc().IsInDtor())
439 //Unregister from root if I'm still in turbo there.
440 SwRootFrame *pRoot = getRootFrame();
441 if( pRoot && pRoot->GetTurbo() == this )
443 pRoot->DisallowTurbo();
444 pRoot->ResetTurbo();
448 SwFrame::DestroyImpl();
451 SwContentFrame::~SwContentFrame()
455 void SwTextFrame::RegisterToNode(SwTextNode & rNode, bool const isForceNodeAsFirst)
457 if (isForceNodeAsFirst && m_pMergedPara)
458 { // nothing registered here, in particular no delete redlines (insert
459 // redline might end on empty node where delete rl starts, should be ok)
460 assert(m_pMergedPara->pFirstNode->GetIndex() + 1 == rNode.GetIndex());
461 assert(rNode.GetDoc().getIDocumentRedlineAccess().GetRedlinePos(
462 *m_pMergedPara->pFirstNode, RedlineType::Delete) == SwRedlineTable::npos);
463 assert(std::find_if(
464 rNode.GetDoc().getIDocumentMarkAccess()->getFieldmarksBegin(),
465 rNode.GetDoc().getIDocumentMarkAccess()->getFieldmarksEnd(),
466 [this](::sw::mark::MarkBase const*const pMark) {
467 return pMark->GetMarkStart().GetNode() == *m_pMergedPara->pFirstNode
468 && pMark->GetMarkEnd().GetNode() != *m_pMergedPara->pFirstNode;
469 }) == rNode.GetDoc().getIDocumentMarkAccess()->getFieldmarksEnd());
471 assert(&rNode != GetDep());
472 assert(!m_pMergedPara
473 || (m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
474 || (rNode.GetIndex() + 1 == m_pMergedPara->pFirstNode->GetIndex()));
475 SwTextNode & rFirstNode(
476 (!isForceNodeAsFirst && m_pMergedPara && m_pMergedPara->pFirstNode->GetIndex() < rNode.GetIndex())
477 ? *m_pMergedPara->pFirstNode
478 : rNode);
479 // sw_redlinehide: use New here, because the only caller also calls lcl_ChangeFootnoteRef
480 m_pMergedPara = sw::CheckParaRedlineMerge(*this, rFirstNode, sw::FrameMode::New);
481 if (!m_pMergedPara)
483 rNode.Add(*this);
487 void SwLayoutFrame::DestroyImpl()
489 while (!m_VertPosOrientFramesFor.empty())
491 SwAnchoredObject *pObj = *m_VertPosOrientFramesFor.begin();
492 pObj->ClearVertPosOrientFrame();
495 assert(m_VertPosOrientFramesFor.empty());
497 SwFrame *pFrame = m_pLower;
499 if( GetFormat() && !GetFormat()->GetDoc()->IsInDtor() )
501 while ( pFrame )
503 //First delete the Objs of the Frame because they can't unregister
504 //from the page after remove.
505 //We don't want to create an endless loop only because one couldn't
506 //unregister.
508 while ( pFrame->GetDrawObjs() && pFrame->GetDrawObjs()->size() )
510 const size_t nCnt = pFrame->GetDrawObjs()->size();
511 // #i28701#
512 SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[0];
513 if (SwFlyFrame* pFlyFrame = pAnchoredObj->DynCastFlyFrame())
515 SwFrame::DestroyFrame(pFlyFrame);
516 assert(!pFrame->GetDrawObjs() || nCnt > pFrame->GetDrawObjs()->size());
518 else
520 pAnchoredObj->ClearTmpConsiderWrapInfluence();
521 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
522 SwDrawContact* pContact =
523 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
524 OSL_ENSURE( pContact,
525 "<SwFrame::~SwFrame> - missing contact for drawing object" );
526 if ( pContact )
528 pContact->DisconnectObjFromLayout( pSdrObj );
531 if ( pFrame->GetDrawObjs() &&
532 nCnt == pFrame->GetDrawObjs()->size() )
534 pFrame->GetDrawObjs()->Remove( *pAnchoredObj );
538 pFrame->RemoveFromLayout();
539 SwFrame::DestroyFrame(pFrame);
540 pFrame = m_pLower;
542 //Delete the Flys, the last one also deletes the array.
543 while ( GetDrawObjs() && GetDrawObjs()->size() )
545 const size_t nCnt = GetDrawObjs()->size();
547 // #i28701#
548 SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[0];
549 if ( auto pFlyFrame = pAnchoredObj->DynCastFlyFrame() )
551 SwFrame::DestroyFrame(pFlyFrame);
552 assert(!GetDrawObjs() || nCnt > GetDrawObjs()->size());
554 else
556 SdrObject* pSdrObj = pAnchoredObj->DrawObj();
557 SwDrawContact* pContact =
558 static_cast<SwDrawContact*>(pSdrObj->GetUserCall());
559 OSL_ENSURE( pContact,
560 "<SwFrame::~SwFrame> - missing contact for drawing object" );
561 if ( pContact )
563 pContact->DisconnectObjFromLayout( pSdrObj );
566 if ( GetDrawObjs() && nCnt == GetDrawObjs()->size() )
568 GetDrawObjs()->Remove( *pAnchoredObj );
573 else
575 while( pFrame )
577 SwFrame *pNxt = pFrame->GetNext();
578 SwFrame::DestroyFrame(pFrame);
579 pFrame = pNxt;
583 SwFrame::DestroyImpl();
586 SwLayoutFrame::~SwLayoutFrame()
591 |* The paintarea is the area, in which the content of a frame is allowed
592 |* to be displayed. This region could be larger than the printarea (getFramePrintArea())
593 |* of the upper, it includes e.g. often the margin of the page.
595 SwRect SwFrame::GetPaintArea() const
597 // NEW TABLES
598 // Cell frames may not leave their upper:
599 SwRect aRect = IsRowFrame() ? GetUpper()->getFrameArea() : getFrameArea();
600 SwRectFnSet aRectFnSet(this);
601 tools::Long nRight = aRectFnSet.GetRight(aRect);
602 tools::Long nLeft = aRectFnSet.GetLeft(aRect);
603 const SwFrame* pTmp = this;
604 bool bLeft = true;
605 bool bRight = true;
606 tools::Long nRowSpan = 0;
607 while( pTmp )
609 if( pTmp->IsCellFrame() && pTmp->GetUpper() &&
610 pTmp->GetUpper()->IsVertical() != pTmp->IsVertical() )
611 nRowSpan = static_cast<const SwCellFrame*>(pTmp)->GetTabBox()->getRowSpan();
612 tools::Long nTmpRight = aRectFnSet.GetRight(pTmp->getFrameArea());
613 tools::Long nTmpLeft = aRectFnSet.GetLeft(pTmp->getFrameArea());
614 if( pTmp->IsRowFrame() && nRowSpan > 1 )
616 const SwFrame* pNxt = pTmp;
617 while( --nRowSpan > 0 && pNxt->GetNext() )
618 pNxt = pNxt->GetNext();
619 if( pTmp->IsVertical() )
620 nTmpLeft = aRectFnSet.GetLeft(pNxt->getFrameArea());
621 else
623 // pTmp is a row frame, but it's not vertical.
624 if (IsVertLRBT())
626 // This frame cell is OK to expand towards the physical down direction.
627 // Physical down is left.
628 nTmpLeft = aRectFnSet.GetLeft(pNxt->getFrameArea());
630 else
632 nTmpRight = aRectFnSet.GetRight(pNxt->getFrameArea());
636 OSL_ENSURE( pTmp, "GetPaintArea lost in time and space" );
637 if( pTmp->IsPageFrame() || pTmp->IsFlyFrame() ||
638 pTmp->IsCellFrame() || pTmp->IsRowFrame() || //nobody leaves a table!
639 pTmp->IsRootFrame() )
641 // BTLR is OK to expand towards the physical down direction. Physical down is left.
642 if( bLeft || (aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 && !IsVertLRBT()) )
643 nLeft = nTmpLeft;
644 if( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 )
645 nRight = nTmpRight;
646 if( pTmp->IsPageFrame() || pTmp->IsFlyFrame() || pTmp->IsRootFrame() )
647 break;
648 bLeft = false;
649 bRight = false;
651 else if( pTmp->IsColumnFrame() ) // nobody enters neighbour columns
653 bool bR2L = pTmp->IsRightToLeft();
654 // the first column has _no_ influence to the left range
655 if( bR2L ? pTmp->GetNext() : pTmp->GetPrev() )
657 if( bLeft || aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 )
658 nLeft = nTmpLeft;
659 bLeft = false;
661 // the last column has _no_ influence to the right range
662 if( bR2L ? pTmp->GetPrev() : pTmp->GetNext() )
664 if( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 )
665 nRight = nTmpRight;
666 bRight = false;
669 else if (aRectFnSet.IsVert() && pTmp->IsBodyFrame())
671 // Header and footer frames have always horizontal direction and
672 // limit the body frame.
673 // A previous frame of a body frame must be a header,
674 // the next frame of a body frame may be a footnotecontainer or
675 // a footer. The footnotecontainer has the same direction like
676 // the body frame.
677 if( pTmp->GetPrev() && ( bLeft || aRectFnSet.XDiff(nTmpLeft, nLeft) > 0 ) )
679 nLeft = nTmpLeft;
680 bLeft = false;
682 if( pTmp->GetNext() &&
683 ( pTmp->GetNext()->IsFooterFrame() || pTmp->GetNext()->GetNext() )
684 && ( bRight || aRectFnSet.XDiff(nRight, nTmpRight) > 0 ) )
686 nRight = nTmpRight;
687 bRight = false;
690 pTmp = pTmp->GetUpper();
692 aRectFnSet.SetLeft(aRect, nLeft);
693 aRectFnSet.SetRight(aRect, nRight);
694 return aRect;
698 |* The unionframe is the framearea (getFrameArea()) of a frame expanded by the
699 |* printarea, if there's a negative margin at the left or right side.
701 SwRect SwFrame::UnionFrame( bool bBorder ) const
703 SwRectFnSet aRectFnSet(this);
704 tools::Long nLeft = aRectFnSet.GetLeft(getFrameArea());
705 tools::Long nWidth = aRectFnSet.GetWidth(getFrameArea());
706 tools::Long nPrtLeft = aRectFnSet.GetLeft(getFramePrintArea());
707 tools::Long nPrtWidth = aRectFnSet.GetWidth(getFramePrintArea());
708 if (aRectFnSet.XInc(nPrtLeft, nPrtWidth) > nWidth)
709 nWidth = nPrtLeft + nPrtWidth;
710 if( nPrtLeft < 0 )
712 nLeft += nPrtLeft;
713 nWidth -= nPrtLeft;
715 SwTwips nRight = aRectFnSet.XInc(nLeft, nWidth);
716 tools::Long nAdd = 0;
717 if( bBorder )
719 SwBorderAttrAccess aAccess( SwFrame::GetCache(), this );
720 const SwBorderAttrs &rAttrs = *aAccess.Get();
721 const SvxBoxItem &rBox = rAttrs.GetBox();
722 if ( rBox.GetLeft() )
723 nLeft -= rBox.CalcLineSpace( SvxBoxItemLine::LEFT );
724 else
725 nLeft -= rBox.GetDistance( SvxBoxItemLine::LEFT ) + 1;
726 if ( rBox.GetRight() )
727 nAdd += rBox.CalcLineSpace( SvxBoxItemLine::RIGHT );
728 else
729 nAdd += rBox.GetDistance( SvxBoxItemLine::RIGHT ) + 1;
730 if( rAttrs.GetShadow().GetLocation() != SvxShadowLocation::NONE )
732 const SvxShadowItem &rShadow = rAttrs.GetShadow();
733 nLeft -= rShadow.CalcShadowSpace( SvxShadowItemSide::LEFT );
734 nAdd += rShadow.CalcShadowSpace( SvxShadowItemSide::RIGHT );
737 if( IsTextFrame() && static_cast<const SwTextFrame*>(this)->HasPara() )
739 tools::Long nTmp = static_cast<const SwTextFrame*>(this)->HangingMargin();
740 if( nTmp > nAdd )
741 nAdd = nTmp;
743 nWidth = aRectFnSet.XDiff(aRectFnSet.XInc(nRight, nAdd), nLeft);
744 SwRect aRet( getFrameArea() );
745 aRectFnSet.SetLeft(aRet, nLeft);
746 aRectFnSet.SetWidth(aRet, nWidth);
747 return aRet;
750 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */