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 47 SwToLayoutAnchoredObjectPosition::SwToLayoutAnchoredObjectPosition( SdrObject& _rDrawObj ) 48 : SwAnchoredObjectPosition( _rDrawObj ), 49 maRelPos( Point() ), 50 // --> OD 2004-06-17 #i26791# 51 maOffsetToFrmAnchorPos( Point() ) 52 {} 53 54 SwToLayoutAnchoredObjectPosition::~SwToLayoutAnchoredObjectPosition() 55 {} 56 57 /** calculate position for object position type TO_LAYOUT 58 59 @author OD 60 */ 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 */ 247 Point SwToLayoutAnchoredObjectPosition::GetRelPos() const 248 { 249 return maRelPos; 250 } 251 252