1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <tolayoutanchoredobjectposition.hxx>
21 #include <anchoredobject.hxx>
23 #include <pagefrm.hxx>
24 #include <svx/svdobj.hxx>
26 #include <fmtanchr.hxx>
27 #include <fmtornt.hxx>
28 #include <fmtsrnd.hxx>
31 #include <viewopt.hxx>
32 #include <rootfrm.hxx>
33 #include <editeng/lrspitem.hxx>
34 #include <editeng/ulspitem.hxx>
36 using namespace objectpositioning
;
37 using namespace ::com::sun::star
;
39 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject
& _rDrawObj
)
40 : SwAnchoredObjectPosition( _rDrawObj
),
43 maOffsetToFrameAnchorPos( Point() )
46 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
49 /** calculate position for object position type TO_LAYOUT */
50 void SwToLayoutAnchoredObjectPosition::CalcPosition()
52 const SwRect
aObjBoundRect( GetAnchoredObj().GetObjRect() );
54 SwRectFnSet
aRectFnSet(&GetAnchorFrame());
56 const SwFrameFormat
& rFrameFormat
= GetFrameFormat();
57 const SvxLRSpaceItem
&rLR
= rFrameFormat
.GetLRSpace();
58 const SvxULSpaceItem
&rUL
= rFrameFormat
.GetULSpace();
60 const bool bFlyAtFly
= RndStdIds::FLY_AT_FLY
== rFrameFormat
.GetAnchor().GetAnchorId();
62 // determine position.
63 // 'vertical' and 'horizontal' position are calculated separately
66 // calculate 'vertical' position
67 SwFormatVertOrient
aVert( rFrameFormat
.GetVertOrient() );
69 // to-frame anchored objects are *only* vertical positioned centered or
70 // bottom, if its wrap mode is 'through' and its anchor frame has fixed
71 // size. Otherwise, it's positioned top.
72 sal_Int16 eVertOrient
= aVert
.GetVertOrient();
74 ( eVertOrient
== text::VertOrientation::CENTER
||
75 eVertOrient
== text::VertOrientation::BOTTOM
) &&
76 css::text::WrapTextMode_THROUGH
!= rFrameFormat
.GetSurround().GetSurround() &&
77 !GetAnchorFrame().HasFixSize() )
79 eVertOrient
= text::VertOrientation::TOP
;
81 // #i26791# - get vertical offset to frame anchor position.
82 SwTwips
nVertOffsetToFrameAnchorPos( 0 );
84 GetVertRelPos( GetAnchorFrame(), GetAnchorFrame(), eVertOrient
,
85 aVert
.GetRelationOrient(), aVert
.GetPos(),
86 rLR
, rUL
, nVertOffsetToFrameAnchorPos
);
88 // keep the calculated relative vertical position - needed for filters
89 // (including the xml-filter)
91 SwTwips nAttrRelPosY
= nRelPosY
- nVertOffsetToFrameAnchorPos
;
92 if ( aVert
.GetVertOrient() != text::VertOrientation::NONE
&&
93 aVert
.GetPos() != nAttrRelPosY
)
95 aVert
.SetPos( nAttrRelPosY
);
96 const_cast<SwFrameFormat
&>(rFrameFormat
).LockModify();
97 const_cast<SwFrameFormat
&>(rFrameFormat
).SetFormatAttr( aVert
);
98 const_cast<SwFrameFormat
&>(rFrameFormat
).UnlockModify();
102 // determine absolute 'vertical' position, depending on layout-direction
103 // #i26791# - determine offset to 'vertical' frame
104 // anchor position, depending on layout-direction
105 if( aRectFnSet
.IsVert() )
107 if ( aRectFnSet
.IsVertL2R() )
108 aRelPos
.setX( nRelPosY
);
110 aRelPos
.setX( -nRelPosY
- aObjBoundRect
.Width() );
111 maOffsetToFrameAnchorPos
.setX( nVertOffsetToFrameAnchorPos
);
115 aRelPos
.setY( nRelPosY
);
116 maOffsetToFrameAnchorPos
.setY( nVertOffsetToFrameAnchorPos
);
119 // if in online-layout the bottom of to-page anchored object is beyond
120 // the page bottom, the page frame has to grow by growing its body frame.
121 const SwViewShell
*pSh
= GetAnchorFrame().getRootFrame()->GetCurrShell();
122 if ( !bFlyAtFly
&& GetAnchorFrame().IsPageFrame() &&
123 pSh
&& pSh
->GetViewOptions()->getBrowseMode() )
125 const tools::Long nAnchorBottom
= GetAnchorFrame().getFrameArea().Bottom();
126 const tools::Long nBottom
= GetAnchorFrame().getFrameArea().Top() +
127 aRelPos
.Y() + aObjBoundRect
.Height();
128 if ( nAnchorBottom
< nBottom
)
130 static_cast<SwPageFrame
&>(GetAnchorFrame()).
131 FindBodyCont()->Grow( nBottom
- nAnchorBottom
);
134 } // end of determination of vertical position
136 // calculate 'horizontal' position
137 SwFormatHoriOrient
aHori( rFrameFormat
.GetHoriOrient() );
139 // consider toggle of horizontal position for even pages.
140 const bool bToggle
= aHori
.IsPosToggle() &&
141 !GetAnchorFrame().FindPageFrame()->OnRightPage();
142 sal_Int16 eHoriOrient
= aHori
.GetHoriOrient();
143 sal_Int16 eRelOrient
= aHori
.GetRelationOrient();
144 // toggle orientation
145 ToggleHoriOrientAndAlign( bToggle
, eHoriOrient
, eRelOrient
);
147 // determine alignment values:
148 // <nWidth>: 'width' of the alignment area
149 // <nOffset>: offset of alignment area, relative to 'left' of
150 // frame anchor position
151 SwTwips nWidth
, nOffset
;
153 bool bDummy
; // in this context irrelevant output parameter
154 GetHoriAlignmentValues( GetAnchorFrame(), GetAnchorFrame(),
156 nWidth
, nOffset
, bDummy
);
159 SwTwips nObjWidth
= aRectFnSet
.GetWidth(aObjBoundRect
);
161 // determine relative horizontal position
163 if ( text::HoriOrientation::NONE
== eHoriOrient
)
166 ( !aHori
.IsPosToggle() && GetAnchorFrame().IsRightToLeft() ) )
168 nRelPosX
= nWidth
- nObjWidth
- aHori
.GetPos();
172 nRelPosX
= aHori
.GetPos();
175 else if ( text::HoriOrientation::CENTER
== eHoriOrient
)
176 nRelPosX
= (nWidth
/ 2) - (nObjWidth
/ 2);
177 else if ( text::HoriOrientation::RIGHT
== eHoriOrient
)
178 nRelPosX
= nWidth
- ( nObjWidth
+
179 ( aRectFnSet
.IsVert() ? rUL
.GetLower() : rLR
.GetRight() ) );
181 nRelPosX
= aRectFnSet
.IsVert() ? rUL
.GetUpper() : rLR
.GetLeft();
184 // no 'negative' relative horizontal position
185 // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
186 // to frame anchored objects.
187 if ( !bFlyAtFly
&& nRelPosX
< 0 )
192 // determine absolute 'horizontal' position, depending on layout-direction
193 // #i26791# - determine offset to 'horizontal' frame
194 // anchor position, depending on layout-direction
195 if( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
198 aRelPos
.setY( nRelPosX
);
199 maOffsetToFrameAnchorPos
.setY( nOffset
);
203 aRelPos
.setX( nRelPosX
);
204 maOffsetToFrameAnchorPos
.setX( nOffset
);
207 // keep the calculated relative horizontal position - needed for filters
208 // (including the xml-filter)
210 SwTwips nAttrRelPosX
= nRelPosX
- nOffset
;
211 if ( text::HoriOrientation::NONE
!= aHori
.GetHoriOrient() &&
212 aHori
.GetPos() != nAttrRelPosX
)
214 aHori
.SetPos( nAttrRelPosX
);
215 const_cast<SwFrameFormat
&>(rFrameFormat
).LockModify();
216 const_cast<SwFrameFormat
&>(rFrameFormat
).SetFormatAttr( aHori
);
217 const_cast<SwFrameFormat
&>(rFrameFormat
).UnlockModify();
220 } // end of determination of horizontal position
222 // keep calculate relative position
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */