1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <tolayoutanchoredobjectposition.hxx>
27 #include <anchoredobject.hxx>
28 #include <frame.hxx>
29 #include <pagefrm.hxx>
30 #include <svx/svdobj.hxx>
31 #include <frmfmt.hxx>
32 #include <fmtanchr.hxx>
33 #include <fmtornt.hxx>
34 #include <fmtsrnd.hxx>
35 #include <IDocumentSettingAccess.hxx>
36 #include <frmatr.hxx>
37 #include "viewsh.hxx"
38 #include "viewopt.hxx"
39 #include "rootfrm.hxx"
40 #include <editeng/lrspitem.hxx>
41 #include <editeng/ulspitem.hxx>
42
43 using namespace objectpositioning;
44 using namespace ::com::sun::star;
45
46
SwToLayoutAnchoredObjectPosition(SdrObject & _rDrawObj)47 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject& _rDrawObj )
48 : SwAnchoredObjectPosition( _rDrawObj ),
49 maRelPos( Point() ),
50 // --> OD 2004-06-17 #i26791#
51 maOffsetToFrmAnchorPos( Point() )
52 {}
53
~SwToLayoutAnchoredObjectPosition()54 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition()
55 {}
56
57 /** calculate position for object position type TO_LAYOUT
58
59 @author OD
60 */
CalcPosition()61 void SwToLayoutAnchoredObjectPosition::CalcPosition()
62 {
63 const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
64
65 SWRECTFN( (&GetAnchorFrm()) );
66
67 const SwFrmFmt& rFrmFmt = GetFrmFmt();
68 const SvxLRSpaceItem &rLR = rFrmFmt.GetLRSpace();
69 const SvxULSpaceItem &rUL = rFrmFmt.GetULSpace();
70
71 const bool bFlyAtFly = FLY_AT_FLY == rFrmFmt.GetAnchor().GetAnchorId();
72
73 // determine position.
74 // 'vertical' and 'horizontal' position are calculated separately
75 Point aRelPos;
76
77 // calculate 'vertical' position
78 SwFmtVertOrient aVert( rFrmFmt.GetVertOrient() );
79 {
80 // to-frame anchored objects are *only* vertical positioned centered or
81 // bottom, if its wrap mode is 'throught' and its anchor frame has fixed
82 // size. Otherwise, it's positioned top.
83 sal_Int16 eVertOrient = aVert.GetVertOrient();
84 if ( ( bFlyAtFly &&
85 ( eVertOrient == text::VertOrientation::CENTER ||
86 eVertOrient == text::VertOrientation::BOTTOM ) &&
87 SURROUND_THROUGHT != rFrmFmt.GetSurround().GetSurround() &&
88 !GetAnchorFrm().HasFixSize() ) )
89 {
90 eVertOrient = text::VertOrientation::TOP;
91 }
92 // --> OD 2004-06-17 #i26791# - get vertical offset to frame anchor position.
93 SwTwips nVertOffsetToFrmAnchorPos( 0L );
94 SwTwips nRelPosY =
95 _GetVertRelPos( GetAnchorFrm(), GetAnchorFrm(), eVertOrient,
96 aVert.GetRelationOrient(), aVert.GetPos(),
97 rLR, rUL, nVertOffsetToFrmAnchorPos );
98
99
100 // keep the calculated relative vertical position - needed for filters
101 // (including the xml-filter)
102 {
103 SwTwips nAttrRelPosY = nRelPosY - nVertOffsetToFrmAnchorPos;
104 if ( aVert.GetVertOrient() != text::VertOrientation::NONE &&
105 aVert.GetPos() != nAttrRelPosY )
106 {
107 aVert.SetPos( nAttrRelPosY );
108 const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
109 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aVert );
110 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
111 }
112 }
113
114 // determine absolute 'vertical' position, depending on layout-direction
115 // --> OD 2004-06-17 #i26791# - determine offset to 'vertical' frame
116 // anchor position, depending on layout-direction
117 if( bVert )
118 {
119 ASSERT( !bRev, "<SwToLayoutAnchoredObjectPosition::CalcPosition()> - reverse layout set." );
120 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
121 if ( bVertL2R )
122 aRelPos.X() = nRelPosY;
123 else
124 aRelPos.X() = -nRelPosY - aObjBoundRect.Width();
125 maOffsetToFrmAnchorPos.X() = nVertOffsetToFrmAnchorPos;
126 }
127 else
128 {
129 aRelPos.Y() = nRelPosY;
130 maOffsetToFrmAnchorPos.Y() = nVertOffsetToFrmAnchorPos;
131 }
132
133 // if in online-layout the bottom of to-page anchored object is beyond
134 // the page bottom, the page frame has to grow by growing its body frame.
135 const ViewShell *pSh = GetAnchorFrm().getRootFrm()->GetCurrShell();
136 if ( !bFlyAtFly && GetAnchorFrm().IsPageFrm() &&
137 pSh && pSh->GetViewOptions()->getBrowseMode() )
138 {
139 const long nAnchorBottom = GetAnchorFrm().Frm().Bottom();
140 const long nBottom = GetAnchorFrm().Frm().Top() +
141 aRelPos.Y() + aObjBoundRect.Height();
142 if ( nAnchorBottom < nBottom )
143 {
144 static_cast<SwPageFrm&>(GetAnchorFrm()).
145 FindBodyCont()->Grow( nBottom - nAnchorBottom );
146 }
147 }
148 } // end of determination of vertical position
149
150 // calculate 'horizontal' position
151 SwFmtHoriOrient aHori( rFrmFmt.GetHoriOrient() );
152 {
153 // consider toggle of horizontal position for even pages.
154 const bool bToggle = aHori.IsPosToggle() &&
155 !GetAnchorFrm().FindPageFrm()->OnRightPage();
156 sal_Int16 eHoriOrient = aHori.GetHoriOrient();
157 sal_Int16 eRelOrient = aHori.GetRelationOrient();
158 // toggle orientation
159 _ToggleHoriOrientAndAlign( bToggle, eHoriOrient, eRelOrient );
160
161 // determine alignment values:
162 // <nWidth>: 'width' of the alignment area
163 // <nOffset>: offset of alignment area, relative to 'left' of
164 // frame anchor position
165 SwTwips nWidth, nOffset;
166 {
167 bool bDummy; // in this context irrelevant output parameter
168 _GetHoriAlignmentValues( GetAnchorFrm(), GetAnchorFrm(),
169 eRelOrient, false,
170 nWidth, nOffset, bDummy );
171 }
172
173 SwTwips nObjWidth = (aObjBoundRect.*fnRect->fnGetWidth)();
174
175 // determine relative horizontal position
176 SwTwips nRelPosX;
177 if ( text::HoriOrientation::NONE == eHoriOrient )
178 {
179 if( bToggle ||
180 ( !aHori.IsPosToggle() && GetAnchorFrm().IsRightToLeft() ) )
181 {
182 nRelPosX = nWidth - nObjWidth - aHori.GetPos();
183 }
184 else
185 {
186 nRelPosX = aHori.GetPos();
187 }
188 }
189 else if ( text::HoriOrientation::CENTER == eHoriOrient )
190 nRelPosX = (nWidth / 2) - (nObjWidth / 2);
191 else if ( text::HoriOrientation::RIGHT == eHoriOrient )
192 nRelPosX = nWidth - ( nObjWidth +
193 ( bVert ? rUL.GetLower() : rLR.GetRight() ) );
194 else
195 nRelPosX = bVert ? rUL.GetUpper() : rLR.GetLeft();
196 nRelPosX += nOffset;
197
198 // no 'negative' relative horizontal position
199 // OD 06.11.2003 #FollowTextFlowAtFrame# - negative positions allow for
200 // to frame anchored objects.
201 if ( !bFlyAtFly && nRelPosX < 0 )
202 {
203 nRelPosX = 0;
204 }
205
206 // determine absolute 'horizontal' position, depending on layout-direction
207 // --> OD 2004-06-17 #i26791# - determine offset to 'horizontal' frame
208 // anchor position, depending on layout-direction
209 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
210 // --> OD 2009-09-04 #mongolianlayout#
211 if( bVert || bVertL2R )
212 // <--
213 {
214
215 aRelPos.Y() = nRelPosX;
216 maOffsetToFrmAnchorPos.Y() = nOffset;
217 }
218 else
219 {
220 aRelPos.X() = nRelPosX;
221 maOffsetToFrmAnchorPos.X() = nOffset;
222 }
223
224 // keep the calculated relative horizontal position - needed for filters
225 // (including the xml-filter)
226 {
227 SwTwips nAttrRelPosX = nRelPosX - nOffset;
228 if ( text::HoriOrientation::NONE != aHori.GetHoriOrient() &&
229 aHori.GetPos() != nAttrRelPosX )
230 {
231 aHori.SetPos( nAttrRelPosX );
232 const_cast<SwFrmFmt&>(rFrmFmt).LockModify();
233 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aHori );
234 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify();
235 }
236 }
237 } // end of determination of horizontal position
238
239 // keep calculate relative position
240 maRelPos = aRelPos;
241 }
242
243 /** calculated relative position for object position
244
245 @author OD
246 */
GetRelPos() const247 Point SwToLayoutAnchoredObjectPosition::GetRelPos() const
248 {
249 return maRelPos;
250 }
251
252