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 ::com::sun::star
;
38 namespace objectpositioning
40 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject
& _rDrawObj
)
41 : SwAnchoredObjectPosition( _rDrawObj
)
44 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
47 /** calculate position for object position type TO_LAYOUT */
48 void SwToLayoutAnchoredObjectPosition::CalcPosition()
50 const SwRect
aObjBoundRect( GetAnchoredObj().GetObjRect() );
52 SwRectFnSet
aRectFnSet(&GetAnchorFrame());
54 const SwFrameFormat
& rFrameFormat
= GetFrameFormat();
55 const SvxLRSpaceItem
&rLR
= rFrameFormat
.GetLRSpace();
56 const SvxULSpaceItem
&rUL
= rFrameFormat
.GetULSpace();
58 const bool bFlyAtFly
= RndStdIds::FLY_AT_FLY
== rFrameFormat
.GetAnchor().GetAnchorId();
60 // determine position.
61 // 'vertical' and 'horizontal' position are calculated separately
64 // calculate 'vertical' position
65 SwFormatVertOrient
aVert( rFrameFormat
.GetVertOrient() );
67 // to-frame anchored objects are *only* vertical positioned centered or
68 // bottom, if its wrap mode is 'through' and its anchor frame has fixed
69 // size. Otherwise, it's positioned top.
70 sal_Int16 eVertOrient
= aVert
.GetVertOrient();
72 ( eVertOrient
== text::VertOrientation::CENTER
||
73 eVertOrient
== text::VertOrientation::BOTTOM
) &&
74 css::text::WrapTextMode_THROUGH
!= rFrameFormat
.GetSurround().GetSurround() &&
75 !GetAnchorFrame().HasFixSize() )
77 eVertOrient
= text::VertOrientation::TOP
;
79 // #i26791# - get vertical offset to frame anchor position.
80 SwTwips
nVertOffsetToFrameAnchorPos( 0 );
82 GetVertRelPos( GetAnchorFrame(), GetAnchorFrame(), eVertOrient
,
83 aVert
.GetRelationOrient(), aVert
.GetPos(),
84 rLR
, rUL
, nVertOffsetToFrameAnchorPos
);
86 // keep the calculated relative vertical position - needed for filters
87 // (including the xml-filter)
89 SwTwips nAttrRelPosY
= nRelPosY
- nVertOffsetToFrameAnchorPos
;
90 if ( aVert
.GetVertOrient() != text::VertOrientation::NONE
&&
91 aVert
.GetPos() != nAttrRelPosY
)
93 aVert
.SetPos( nAttrRelPosY
);
94 const_cast<SwFrameFormat
&>(rFrameFormat
).LockModify();
95 const_cast<SwFrameFormat
&>(rFrameFormat
).SetFormatAttr( aVert
);
96 const_cast<SwFrameFormat
&>(rFrameFormat
).UnlockModify();
100 // determine absolute 'vertical' position, depending on layout-direction
101 // #i26791# - determine offset to 'vertical' frame
102 // anchor position, depending on layout-direction
103 if( aRectFnSet
.IsVert() )
105 if ( aRectFnSet
.IsVertL2R() )
106 aRelPos
.setX( nRelPosY
);
108 aRelPos
.setX( -nRelPosY
- aObjBoundRect
.Width() );
109 maOffsetToFrameAnchorPos
.setX( nVertOffsetToFrameAnchorPos
);
113 aRelPos
.setY( nRelPosY
);
114 maOffsetToFrameAnchorPos
.setY( nVertOffsetToFrameAnchorPos
);
117 // if in online-layout the bottom of to-page anchored object is beyond
118 // the page bottom, the page frame has to grow by growing its body frame.
119 const SwViewShell
*pSh
= GetAnchorFrame().getRootFrame()->GetCurrShell();
120 if ( !bFlyAtFly
&& GetAnchorFrame().IsPageFrame() &&
121 pSh
&& pSh
->GetViewOptions()->getBrowseMode() )
123 const tools::Long nAnchorBottom
= GetAnchorFrame().getFrameArea().Bottom();
124 const tools::Long nBottom
= GetAnchorFrame().getFrameArea().Top() +
125 aRelPos
.Y() + aObjBoundRect
.Height();
126 if ( nAnchorBottom
< nBottom
)
128 static_cast<SwPageFrame
&>(GetAnchorFrame()).
129 FindBodyCont()->Grow( nBottom
- nAnchorBottom
);
132 } // end of determination of vertical position
134 // calculate 'horizontal' position
135 SwFormatHoriOrient
aHori( rFrameFormat
.GetHoriOrient() );
137 // consider toggle of horizontal position for even pages.
138 const bool bToggle
= aHori
.IsPosToggle() &&
139 !GetAnchorFrame().FindPageFrame()->OnRightPage();
140 sal_Int16 eHoriOrient
= aHori
.GetHoriOrient();
141 sal_Int16 eRelOrient
= aHori
.GetRelationOrient();
142 // toggle orientation
143 ToggleHoriOrientAndAlign( bToggle
, eHoriOrient
, eRelOrient
);
145 // determine alignment values:
146 // <nWidth>: 'width' of the alignment area
147 // <nOffset>: offset of alignment area, relative to 'left' of
148 // frame anchor position
149 SwTwips nWidth
, nOffset
;
151 bool bDummy
; // in this context irrelevant output parameter
152 GetHoriAlignmentValues( GetAnchorFrame(), GetAnchorFrame(),
154 nWidth
, nOffset
, bDummy
);
157 SwTwips nObjWidth
= aRectFnSet
.GetWidth(aObjBoundRect
);
159 // determine relative horizontal position
161 if ( text::HoriOrientation::NONE
== eHoriOrient
)
164 ( !aHori
.IsPosToggle() && GetAnchorFrame().IsRightToLeft() ) )
166 nRelPosX
= nWidth
- nObjWidth
- aHori
.GetPos();
170 nRelPosX
= aHori
.GetPos();
173 else if ( text::HoriOrientation::CENTER
== eHoriOrient
)
174 nRelPosX
= (nWidth
/ 2) - (nObjWidth
/ 2);
175 else if ( text::HoriOrientation::RIGHT
== eHoriOrient
)
176 nRelPosX
= nWidth
- ( nObjWidth
+
177 ( aRectFnSet
.IsVert() ? rUL
.GetLower() : rLR
.GetRight() ) );
179 nRelPosX
= aRectFnSet
.IsVert() ? rUL
.GetUpper() : rLR
.GetLeft();
182 // no 'negative' relative horizontal position
183 // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
184 // to frame anchored objects.
185 if ( !bFlyAtFly
&& nRelPosX
< 0 )
190 // determine absolute 'horizontal' position, depending on layout-direction
191 // #i26791# - determine offset to 'horizontal' frame
192 // anchor position, depending on layout-direction
193 if( aRectFnSet
.IsVert() || aRectFnSet
.IsVertL2R() )
196 aRelPos
.setY( nRelPosX
);
197 maOffsetToFrameAnchorPos
.setY( nOffset
);
201 aRelPos
.setX( nRelPosX
);
202 maOffsetToFrameAnchorPos
.setX( nOffset
);
205 // keep the calculated relative horizontal position - needed for filters
206 // (including the xml-filter)
208 SwTwips nAttrRelPosX
= nRelPosX
- nOffset
;
209 if ( text::HoriOrientation::NONE
!= aHori
.GetHoriOrient() &&
210 aHori
.GetPos() != nAttrRelPosX
)
212 aHori
.SetPos( nAttrRelPosX
);
213 const_cast<SwFrameFormat
&>(rFrameFormat
).LockModify();
214 const_cast<SwFrameFormat
&>(rFrameFormat
).SetFormatAttr( aHori
);
215 const_cast<SwFrameFormat
&>(rFrameFormat
).UnlockModify();
218 } // end of determination of horizontal position
220 // keep calculate relative position
226 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */