1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tolayoutanchoredobjectposition.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <tolayoutanchoredobjectposition.hxx>
34 #include <anchoredobject.hxx>
36 #include <pagefrm.hxx>
37 #ifndef _SVX_SVDOBJ_HXX
38 #include <svx/svdobj.hxx>
41 #include <fmtanchr.hxx>
42 #include <fmtornt.hxx>
43 #include <fmtsrnd.hxx>
44 #include <IDocumentSettingAccess.hxx>
46 #include <svx/lrspitem.hxx>
47 #include <svx/ulspitem.hxx>
49 using namespace objectpositioning
;
50 using namespace ::com::sun::star
;
53 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject
& _rDrawObj
)
54 : SwAnchoredObjectPosition( _rDrawObj
),
56 // --> OD 2004-06-17 #i26791#
57 maOffsetToFrmAnchorPos( Point() )
60 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
63 /** calculate position for object position type TO_LAYOUT
67 void SwToLayoutAnchoredObjectPosition::CalcPosition()
69 const SwRect
aObjBoundRect( GetAnchoredObj().GetObjRect() );
71 SWRECTFN( (&GetAnchorFrm()) );
73 const SwFrmFmt
& rFrmFmt
= GetFrmFmt();
74 const SvxLRSpaceItem
&rLR
= rFrmFmt
.GetLRSpace();
75 const SvxULSpaceItem
&rUL
= rFrmFmt
.GetULSpace();
77 const bool bFlyAtFly
= FLY_AT_FLY
== rFrmFmt
.GetAnchor().GetAnchorId();
79 // determine position.
80 // 'vertical' and 'horizontal' position are calculated separately
83 // calculate 'vertical' position
84 SwFmtVertOrient
aVert( rFrmFmt
.GetVertOrient() );
86 // to-frame anchored objects are *only* vertical positioned centered or
87 // bottom, if its wrap mode is 'throught' and its anchor frame has fixed
88 // size. Otherwise, it's positioned top.
89 sal_Int16 eVertOrient
= aVert
.GetVertOrient();
91 ( eVertOrient
== text::VertOrientation::CENTER
||
92 eVertOrient
== text::VertOrientation::BOTTOM
) &&
93 SURROUND_THROUGHT
!= rFrmFmt
.GetSurround().GetSurround() &&
94 !GetAnchorFrm().HasFixSize() ) )
96 eVertOrient
= text::VertOrientation::TOP
;
98 // --> OD 2004-06-17 #i26791# - get vertical offset to frame anchor position.
99 SwTwips
nVertOffsetToFrmAnchorPos( 0L );
101 _GetVertRelPos( GetAnchorFrm(), GetAnchorFrm(), eVertOrient
,
102 aVert
.GetRelationOrient(), aVert
.GetPos(),
103 rLR
, rUL
, nVertOffsetToFrmAnchorPos
);
106 // keep the calculated relative vertical position - needed for filters
107 // (including the xml-filter)
109 SwTwips nAttrRelPosY
= nRelPosY
- nVertOffsetToFrmAnchorPos
;
110 if ( aVert
.GetVertOrient() != text::VertOrientation::NONE
&&
111 aVert
.GetPos() != nAttrRelPosY
)
113 aVert
.SetPos( nAttrRelPosY
);
114 const_cast<SwFrmFmt
&>(rFrmFmt
).LockModify();
115 const_cast<SwFrmFmt
&>(rFrmFmt
).SetFmtAttr( aVert
);
116 const_cast<SwFrmFmt
&>(rFrmFmt
).UnlockModify();
120 // determine absolute 'vertical' position, depending on layout-direction
121 // --> OD 2004-06-17 #i26791# - determine offset to 'vertical' frame
122 // anchor position, depending on layout-direction
125 ASSERT( !bRev
, "<SwToLayoutAnchoredObjectPosition::CalcPosition()> - reverse layout set." );
126 aRelPos
.X() = -nRelPosY
- aObjBoundRect
.Width();
127 maOffsetToFrmAnchorPos
.X() = nVertOffsetToFrmAnchorPos
;
131 aRelPos
.Y() = nRelPosY
;
132 maOffsetToFrmAnchorPos
.Y() = nVertOffsetToFrmAnchorPos
;
135 // if in online-layout the bottom of to-page anchored object is beyond
136 // the page bottom, the page frame has to grow by growing its body frame.
137 if ( !bFlyAtFly
&& GetAnchorFrm().IsPageFrm() &&
138 rFrmFmt
.getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE
) )
140 const long nAnchorBottom
= GetAnchorFrm().Frm().Bottom();
141 const long nBottom
= GetAnchorFrm().Frm().Top() +
142 aRelPos
.Y() + aObjBoundRect
.Height();
143 if ( nAnchorBottom
< nBottom
)
145 static_cast<SwPageFrm
&>(GetAnchorFrm()).
146 FindBodyCont()->Grow( nBottom
- nAnchorBottom
);
149 } // end of determination of vertical position
151 // calculate 'horizontal' position
152 SwFmtHoriOrient
aHori( rFrmFmt
.GetHoriOrient() );
154 // consider toggle of horizontal position for even pages.
155 const bool bToggle
= aHori
.IsPosToggle() &&
156 !GetAnchorFrm().FindPageFrm()->OnRightPage();
157 sal_Int16 eHoriOrient
= aHori
.GetHoriOrient();
158 sal_Int16 eRelOrient
= aHori
.GetRelationOrient();
159 // toggle orientation
160 _ToggleHoriOrientAndAlign( bToggle
, eHoriOrient
, eRelOrient
);
162 // determine alignment values:
163 // <nWidth>: 'width' of the alignment area
164 // <nOffset>: offset of alignment area, relative to 'left' of
165 // frame anchor position
166 SwTwips nWidth
, nOffset
;
168 bool bDummy
; // in this context irrelevant output parameter
169 _GetHoriAlignmentValues( GetAnchorFrm(), GetAnchorFrm(),
171 nWidth
, nOffset
, bDummy
);
174 SwTwips nObjWidth
= (aObjBoundRect
.*fnRect
->fnGetWidth
)();
176 // determine relative horizontal position
178 if ( text::HoriOrientation::NONE
== eHoriOrient
)
181 ( !aHori
.IsPosToggle() && GetAnchorFrm().IsRightToLeft() ) )
183 nRelPosX
= nWidth
- nObjWidth
- aHori
.GetPos();
187 nRelPosX
= aHori
.GetPos();
190 else if ( text::HoriOrientation::CENTER
== eHoriOrient
)
191 nRelPosX
= (nWidth
/ 2) - (nObjWidth
/ 2);
192 else if ( text::HoriOrientation::RIGHT
== eHoriOrient
)
193 nRelPosX
= nWidth
- ( nObjWidth
+
194 ( bVert
? rUL
.GetLower() : rLR
.GetRight() ) );
196 nRelPosX
= bVert
? rUL
.GetUpper() : rLR
.GetLeft();
199 // no 'negative' relative horizontal position
200 // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
201 // to frame anchored objects.
202 if ( !bFlyAtFly
&& nRelPosX
< 0 )
207 // determine absolute 'horizontal' position, depending on layout-direction
208 // --> OD 2004-06-17 #i26791# - determine offset to 'horizontal' frame
209 // anchor position, depending on layout-direction
212 aRelPos
.Y() = nRelPosX
;
213 maOffsetToFrmAnchorPos
.Y() = nOffset
;
217 aRelPos
.X() = nRelPosX
;
218 maOffsetToFrmAnchorPos
.X() = nOffset
;
221 // keep the calculated relative horizontal position - needed for filters
222 // (including the xml-filter)
224 SwTwips nAttrRelPosX
= nRelPosX
- nOffset
;
225 if ( text::HoriOrientation::NONE
!= aHori
.GetHoriOrient() &&
226 aHori
.GetPos() != nAttrRelPosX
)
228 aHori
.SetPos( nAttrRelPosX
);
229 const_cast<SwFrmFmt
&>(rFrmFmt
).LockModify();
230 const_cast<SwFrmFmt
&>(rFrmFmt
).SetFmtAttr( aHori
);
231 const_cast<SwFrmFmt
&>(rFrmFmt
).UnlockModify();
234 } // end of determination of horizontal position
236 // keep calculate relative position
240 /** calculated relative position for object position
244 Point
SwToLayoutAnchoredObjectPosition::GetRelPos() const