summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorZolnai Tamás <tamas.zolnai@collabora.com>2014-03-05 22:15:09 +0100
committerZolnai Tamás <tamas.zolnai@collabora.com>2014-03-05 22:15:09 +0100
commitcb19042f4395c97d123a27c6960d5e30d666c010 (patch)
treecd14733e3eef222d07175108615df079dcced458 /sw
parent80d1a46e0f3b57f1bbaf7bc4c8aac81195ea8f4d (diff)
New feature: vertical alignment for text frames: Layout part
- Introduce a new attribute (content position) for fly frames. Content position specify the top-left corner of the content area (where frame content can be placed). Add methods and members for invalidation. - Extract content's height calculation from SwFlyFrm::Format() to a funtction so we can use this inside SwFlyFrm::MakeContentPos. Change-Id: I64abb70afb652ad5c11aa69b5ba12a85210e215b
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/inc/flyfrm.hxx13
-rw-r--r--sw/source/core/inc/frame.hxx2
-rw-r--r--sw/source/core/layout/calcmove.cxx15
-rw-r--r--sw/source/core/layout/fly.cxx181
-rw-r--r--sw/source/core/layout/flylay.cxx8
5 files changed, 161 insertions, 58 deletions
diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx
index 234e94d5dae3..a666a9da1df3 100644
--- a/sw/source/core/inc/flyfrm.hxx
+++ b/sw/source/core/inc/flyfrm.hxx
@@ -118,8 +118,12 @@ protected:
friend class SwNoTxtFrm; // is allowed to call NotifyBackground
+ Point m_aContentPos; // content area's position relatively to Frm
+ bool m_bValidContentPos;
+
virtual void Format( const SwBorderAttrs *pAttrs = 0 );
void MakePrtArea( const SwBorderAttrs &rAttrs );
+ void MakeContentPos( const SwBorderAttrs &rAttrs );
void Lock() { bLocked = sal_True; }
void Unlock() { bLocked = sal_False; }
@@ -147,6 +151,8 @@ protected:
virtual const IDocumentDrawModelAccess* getIDocumentDrawModelAccess( );
+ SwTwips CalcContentHeight(const SwBorderAttrs *pAttrs, const SwTwips nMinHeight, const SwTwips nUL);
+
public:
// #i26791#
TYPEINFO();
@@ -279,6 +285,13 @@ public:
virtual SwFlyFrmFmt *GetFmt();
virtual void dumpAsXml( xmlTextWriterPtr writer ) { SwLayoutFrm::dumpAsXml( writer ); };
+
+ virtual void Calc() const;
+
+ const Point& ContentPos() const { return m_aContentPos; }
+ Point& ContentPos() { return m_aContentPos; }
+
+ void InvalidateContentPos();
};
#endif
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index c78614ab2c5e..73b32f8d7747 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -682,7 +682,7 @@ public:
inline SwLayoutFrm *GetPrevLayoutLeaf();
inline SwLayoutFrm *GetNextLayoutLeaf();
- inline void Calc() const; // here might be "formatted"
+ virtual void Calc() const; // here might be "formatted"
inline void OptCalc() const; // here we assume (for optimization) that
// the predecessors are already formatted
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index b8e9b12ca2c4..88be7b681d74 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -25,6 +25,7 @@
#include "fmtftn.hxx"
#include <editeng/ulspitem.hxx>
#include <editeng/keepitem.hxx>
+#include <svx/sdtaitm.hxx>
#include <fmtfsize.hxx>
#include <fmtanchr.hxx>
@@ -581,7 +582,11 @@ void SwFrm::MakePos()
else
{
maFrm.Pos( GetUpper()->Frm().Pos() );
- maFrm.Pos() += GetUpper()->Prt().Pos();
+ if( GetUpper()->IsFlyFrm() )
+ maFrm.Pos() += static_cast<SwFlyFrm*>(GetUpper())->ContentPos();
+ else
+ maFrm.Pos() += GetUpper()->Prt().Pos();
+
if( FRM_NEIGHBOUR & nMyType && IsRightToLeft() )
{
if( bVert )
@@ -1335,6 +1340,14 @@ void SwCntntFrm::MakeAll()
if ( nConsequetiveFormatsWithoutChange <= cnStopFormat )
{
Format();
+
+ // When a lower of a vertically aligned fly frame changes it's size we need to recalculate content pos.
+ if( GetUpper() && GetUpper()->IsFlyFrm() &&
+ GetUpper()->GetFmt()->GetTextVertAdjust().GetValue() != SDRTEXTVERTADJUST_TOP )
+ {
+ static_cast<SwFlyFrm*>(GetUpper())->InvalidateContentPos();
+ GetUpper()->SetCompletePaint();
+ }
}
#if OSL_DEBUG_LEVEL > 0
else
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index df97a354ff3e..5d0aede3b8a5 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -72,7 +72,8 @@ SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
bLayout( sal_False ),
bAutoPosition( sal_False ),
bNoShrink( sal_False ),
- bLockDeleteContent( sal_False )
+ bLockDeleteContent( sal_False ),
+ m_bValidContentPos( false )
{
mnType = FRMC_FLY;
@@ -931,6 +932,13 @@ void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
}
break;
+ case RES_TEXT_VERT_ADJUST:
+ {
+ InvalidateContentPos();
+ rInvFlags |= 0x10;
+ }
+ break;
+
case RES_BOX:
case RES_SHADOW:
rInvFlags |= 0x17;
@@ -1232,7 +1240,7 @@ void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
- Size aRelSize( CalcRel( rFrmSz ) );
+ Size aRelSize( CalcRel( rFrmSz ) );
OSL_ENSURE( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "FrameAttr height is 0." );
OSL_ENSURE( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "FrameAttr width is 0." );
@@ -1240,62 +1248,11 @@ void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
SWRECTFN( this )
if( !HasFixSize() )
{
- SwTwips nRemaining = 0;
-
long nMinHeight = 0;
if( IsMinHeight() )
nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
- if ( Lower() )
- {
- if ( Lower()->IsColumnFrm() )
- {
- FormatWidthCols( *pAttrs, nUL, nMinHeight );
- nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
- }
- else
- {
- SwFrm *pFrm = Lower();
- while ( pFrm )
- {
- nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
- if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
- // This TxtFrm would like to be a bit larger
- nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
- - (pFrm->Prt().*fnRect->fnGetHeight)();
- else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
- nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
- pFrm = pFrm->GetNext();
- }
- }
- if ( GetDrawObjs() )
- {
- sal_uInt32 nCnt = GetDrawObjs()->Count();
- SwTwips nTop = (Frm().*fnRect->fnGetTop)();
- SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
- (Prt().*fnRect->fnGetHeight)();
- for ( sal_uInt16 i = 0; i < nCnt; ++i )
- {
- SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
- if ( pAnchoredObj->ISA(SwFlyFrm) )
- {
- SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
- // OD 06.11.2003 #i22305# - consider
- // only Writer fly frames, which follow the text flow.
- if ( pFly->IsFlyLayFrm() &&
- pFly->Frm().Top() != FAR_AWAY &&
- pFly->GetFmt()->GetFollowTextFlow().GetValue() )
- {
- SwTwips nDist = -(pFly->Frm().*fnRect->
- fnBottomDist)( nTop );
- if( nDist > nBorder + nRemaining )
- nRemaining = nDist - nBorder;
- }
- }
- }
- }
- }
-
+ SwTwips nRemaining = CalcContentHeight(pAttrs, nMinHeight, nUL);
if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
nRemaining = nMinHeight - nUL;
// Because the Grow/Shrink of the Flys does not directly
@@ -1304,8 +1261,10 @@ void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
// Notification is running along already.
// As we already got a lot of zeros per attribute, we block them
// from now on.
+
if ( nRemaining < MINFLY )
nRemaining = MINFLY;
+
(Prt().*fnRect->fnSetHeight)( nRemaining );
nRemaining -= (Frm().*fnRect->fnGetHeight)();
(Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
@@ -1715,7 +1674,6 @@ void SwFlyFrm::MakeObjPos()
void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
{
-
if ( !mbValidPrtArea )
{
mbValidPrtArea = sal_True;
@@ -1729,6 +1687,55 @@ void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
}
}
+void SwFlyFrm::MakeContentPos( const SwBorderAttrs &rAttrs )
+{
+ if ( !m_bValidContentPos )
+ {
+ m_bValidContentPos = true;
+
+ const SwTwips nUL = rAttrs.CalcTopLine() + rAttrs.CalcBottomLine();
+ Size aRelSize( CalcRel( GetFmt()->GetFrmSize() ) );
+
+ SWRECTFN( this )
+ long nMinHeight = 0;
+ if( IsMinHeight() )
+ nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
+
+ Point aNewContentPos;
+ aNewContentPos = Prt().Pos();
+ const SdrTextVertAdjust nAdjust = GetFmt()->GetTextVertAdjust().GetValue();
+ if( nAdjust != SDRTEXTVERTADJUST_TOP )
+ {
+ SwTwips nDiff = (Prt().*fnRect->fnGetHeight)() - CalcContentHeight(&rAttrs, nMinHeight, nUL);
+ if( nDiff > 0 )
+ {
+ if( nAdjust == SDRTEXTVERTADJUST_CENTER )
+ {
+ aNewContentPos.setY(aNewContentPos.getY() + nDiff/2);
+ }
+ else if( nAdjust == SDRTEXTVERTADJUST_BOTTOM )
+ {
+ aNewContentPos.setY(aNewContentPos.getY() + nDiff);
+ }
+ }
+ }
+ if( aNewContentPos != ContentPos() )
+ {
+ ContentPos() = aNewContentPos;
+ for( SwFrm *pFrm = Lower(); pFrm; pFrm = pFrm->GetNext())
+ {
+ pFrm->InvalidatePos();
+ }
+ }
+ }
+}
+
+void SwFlyFrm::InvalidateContentPos()
+{
+ m_bValidContentPos = false;
+ _Invalidate();
+}
+
SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
{
SWRECTFN( this )
@@ -2613,4 +2620,68 @@ SwFlyFrmFmt * SwFlyFrm::GetFmt()
return static_cast< SwFlyFrmFmt * >( GetDep() );
}
+void SwFlyFrm::Calc() const
+{
+ if ( !m_bValidContentPos )
+ ((SwFlyFrm*)this)->PrepareMake();
+ else
+ SwLayoutFrm::Calc();
+}
+
+SwTwips SwFlyFrm::CalcContentHeight(const SwBorderAttrs *pAttrs, const SwTwips nMinHeight, const SwTwips nUL)
+{
+ SWRECTFN( this )
+ SwTwips nHeight = 0;
+ if ( Lower() )
+ {
+ if ( Lower()->IsColumnFrm() )
+ {
+ FormatWidthCols( *pAttrs, nUL, nMinHeight );
+ nHeight = (Lower()->Frm().*fnRect->fnGetHeight)();
+ }
+ else
+ {
+ SwFrm *pFrm = Lower();
+ while ( pFrm )
+ {
+ nHeight += (pFrm->Frm().*fnRect->fnGetHeight)();
+ if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
+ // This TxtFrm would like to be a bit larger
+ nHeight += ((SwTxtFrm*)pFrm)->GetParHeight()
+ - (pFrm->Prt().*fnRect->fnGetHeight)();
+ else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
+ nHeight += ((SwSectionFrm*)pFrm)->Undersize();
+ pFrm = pFrm->GetNext();
+ }
+ }
+ if ( GetDrawObjs() )
+ {
+ sal_uInt32 nCnt = GetDrawObjs()->Count();
+ SwTwips nTop = (Frm().*fnRect->fnGetTop)();
+ SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
+ (Prt().*fnRect->fnGetHeight)();
+ for ( sal_uInt16 i = 0; i < nCnt; ++i )
+ {
+ SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
+ if ( pAnchoredObj->ISA(SwFlyFrm) )
+ {
+ SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
+ // OD 06.11.2003 #i22305# - consider
+ // only Writer fly frames, which follow the text flow.
+ if ( pFly->IsFlyLayFrm() &&
+ pFly->Frm().Top() != FAR_AWAY &&
+ pFly->GetFmt()->GetFollowTextFlow().GetValue() )
+ {
+ SwTwips nDist = -(pFly->Frm().*fnRect->
+ fnBottomDist)( nTop );
+ if( nDist > nBorder + nHeight )
+ nHeight = nDist - nBorder;
+ }
+ }
+ }
+ }
+ }
+ return nHeight;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index ce7e0e94a1e1..554f3a4f590d 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -140,7 +140,7 @@ void SwFlyFreeFrm::MakeAll()
sal_uInt16 nLoopControlRuns = 0;
const sal_uInt16 nLoopControlMax = 10;
- while ( !mbValidPos || !mbValidSize || !mbValidPrtArea || bFormatHeightOnly )
+ while ( !mbValidPos || !mbValidSize || !mbValidPrtArea || bFormatHeightOnly || !m_bValidContentPos )
{
SWRECTFN( this )
const SwFmtFrmSize *pSz;
@@ -157,7 +157,10 @@ void SwFlyFreeFrm::MakeAll()
}
if ( !mbValidPrtArea )
+ {
MakePrtArea( rAttrs );
+ m_bValidContentPos = false;
+ }
if ( !mbValidSize || bFormatHeightOnly )
{
@@ -185,6 +188,9 @@ void SwFlyFreeFrm::MakeAll()
else
mbValidSize = sal_False;
}
+
+ if ( !m_bValidContentPos )
+ MakeContentPos( rAttrs );
}
if ( mbValidPos && mbValidSize )