1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 #include <tocntntanchoredobjectposition.hxx> 31 #include <anchoredobject.hxx> 32 #include <frame.hxx> 33 #include <txtfrm.hxx> 34 #include <pagefrm.hxx> 35 #include <sectfrm.hxx> 36 // --> OD 2004-10-15 #i26945# 37 #include <tabfrm.hxx> 38 // <-- 39 #include "rootfrm.hxx" 40 #include "viewopt.hxx" 41 #include "viewsh.hxx" 42 #include <frmfmt.hxx> 43 #include <IDocumentSettingAccess.hxx> 44 #include <fmtsrnd.hxx> 45 #include <fmtfsize.hxx> 46 #include <fmtanchr.hxx> 47 #include <fmtornt.hxx> 48 #include <editeng/lrspitem.hxx> 49 #include <editeng/ulspitem.hxx> 50 #include <svx/svdobj.hxx> 51 #include <pam.hxx> 52 #include <environmentofanchoredobject.hxx> 53 #include <frmtool.hxx> 54 #include <ndtxt.hxx> 55 #include <dflyobj.hxx> 56 57 using namespace objectpositioning; 58 using namespace ::com::sun::star; 59 60 61 SwToCntntAnchoredObjectPosition::SwToCntntAnchoredObjectPosition( SdrObject& _rDrawObj ) 62 : SwAnchoredObjectPosition ( _rDrawObj ), 63 mpVertPosOrientFrm( 0 ), 64 // --> OD 2004-06-17 #i26791# 65 maOffsetToFrmAnchorPos( Point() ), 66 mbAnchorToChar ( false ), 67 mpToCharOrientFrm( 0 ), 68 mpToCharRect( 0 ), 69 // OD 12.11.2003 #i22341# 70 mnToCharTopOfLine( 0 ) 71 {} 72 73 SwToCntntAnchoredObjectPosition::~SwToCntntAnchoredObjectPosition() 74 {} 75 76 bool SwToCntntAnchoredObjectPosition::IsAnchoredToChar() const 77 { 78 return mbAnchorToChar; 79 } 80 81 const SwFrm* SwToCntntAnchoredObjectPosition::ToCharOrientFrm() const 82 { 83 return mpToCharOrientFrm; 84 } 85 86 const SwRect* SwToCntntAnchoredObjectPosition::ToCharRect() const 87 { 88 return mpToCharRect; 89 } 90 91 // OD 12.11.2003 #i22341# 92 SwTwips SwToCntntAnchoredObjectPosition::ToCharTopOfLine() const 93 { 94 return mnToCharTopOfLine; 95 } 96 97 SwTxtFrm& SwToCntntAnchoredObjectPosition::GetAnchorTxtFrm() const 98 { 99 ASSERT( GetAnchorFrm().ISA(SwTxtFrm), 100 "SwToCntntAnchoredObjectPosition::GetAnchorTxtFrm() - wrong anchor frame type" ); 101 102 return static_cast<SwTxtFrm&>(GetAnchorFrm()); 103 } 104 105 // --> OD 2004-07-20 #i23512# 106 bool lcl_DoesVertPosFits( const SwTwips _nRelPosY, 107 const SwTwips _nAvail, 108 const SwLayoutFrm* _pUpperOfOrientFrm, 109 const bool _bBrowse, 110 const bool _bGrowInTable, 111 SwLayoutFrm*& _orpLayoutFrmToGrow ) 112 { 113 bool bVertPosFits = false; 114 115 if ( _nRelPosY <= _nAvail ) 116 { 117 bVertPosFits = true; 118 } 119 else if ( _bBrowse ) 120 { 121 if ( _pUpperOfOrientFrm->IsInSct() ) 122 { 123 SwSectionFrm* pSctFrm = 124 const_cast<SwSectionFrm*>(_pUpperOfOrientFrm->FindSctFrm()); 125 bVertPosFits = pSctFrm->GetUpper()->Grow( _nRelPosY - _nAvail, sal_True ) > 0; 126 // Note: do not provide a layout frame for a grow. 127 } 128 else 129 { 130 bVertPosFits = const_cast<SwLayoutFrm*>(_pUpperOfOrientFrm)-> 131 Grow( _nRelPosY - _nAvail, sal_True ) > 0; 132 if ( bVertPosFits ) 133 _orpLayoutFrmToGrow = const_cast<SwLayoutFrm*>(_pUpperOfOrientFrm); 134 } 135 } 136 else if ( _pUpperOfOrientFrm->IsInTab() && _bGrowInTable ) 137 { 138 // --> OD 2005-06-08 #i45085# - check, if upper frame would grow the 139 // excepted amount of twips. 140 const SwTwips nTwipsGrown = const_cast<SwLayoutFrm*>(_pUpperOfOrientFrm)-> 141 Grow( _nRelPosY - _nAvail, sal_True ) > 0; 142 bVertPosFits = ( nTwipsGrown == ( _nRelPosY - _nAvail ) ); 143 // <-- 144 if ( bVertPosFits ) 145 _orpLayoutFrmToGrow = const_cast<SwLayoutFrm*>(_pUpperOfOrientFrm); 146 } 147 148 return bVertPosFits; 149 } 150 // <-- 151 152 void SwToCntntAnchoredObjectPosition::CalcPosition() 153 { 154 // get format of object 155 const SwFrmFmt& rFrmFmt = GetFrmFmt(); 156 157 // declare and set <pFooter> to footer frame, if object is anchored 158 // at a frame belonging to the footer. 159 const SwFrm* pFooter = GetAnchorFrm().FindFooterOrHeader(); 160 if ( pFooter && !pFooter->IsFooterFrm() ) 161 pFooter = NULL; 162 163 // declare and set <bBrowse> to true, if document is in browser mode and 164 // object is anchored at the body, but not at frame belonging to a table. 165 bool bBrowse = GetAnchorFrm().IsInDocBody() && !GetAnchorFrm().IsInTab(); 166 if( bBrowse ) 167 { 168 const ViewShell *pSh = GetAnchorFrm().getRootFrm()->GetCurrShell(); 169 if( !pSh || !pSh->GetViewOptions()->getBrowseMode() ) 170 bBrowse = false; 171 } 172 173 // determine left/right and its upper/lower spacing. 174 const SvxLRSpaceItem &rLR = rFrmFmt.GetLRSpace(); 175 const SvxULSpaceItem &rUL = rFrmFmt.GetULSpace(); 176 177 // determine, if object has no surrounding. 178 const SwFmtSurround& rSurround = rFrmFmt.GetSurround(); 179 const bool bNoSurround = rSurround.GetSurround() == SURROUND_NONE; 180 const bool bWrapThrough = rSurround.GetSurround() == SURROUND_THROUGHT; 181 182 // OD 29.10.2003 #110978# - new class <SwEnvironmentOfAnchoredObject> 183 SwEnvironmentOfAnchoredObject aEnvOfObj( DoesObjFollowsTextFlow() ); 184 185 // OD 30.09.2003 #i18732# - grow only, if object has to follow the text flow 186 const bool bGrow = DoesObjFollowsTextFlow() && 187 ( !GetAnchorFrm().IsInTab() || 188 !rFrmFmt.GetFrmSize().GetHeightPercent() ); 189 190 // get text frame the object is anchored at 191 const SwTxtFrm& rAnchorTxtFrm = GetAnchorTxtFrm(); 192 SWRECTFN( (&rAnchorTxtFrm) ) 193 194 const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() ); 195 196 // local variable keeping the calculated relative position; initialized with 197 // current relative position. 198 // OD 2004-03-24 #i26791# - use new object instance of <SwAnchoredObject> 199 Point aRelPos( GetAnchoredObj().GetCurrRelPos() ); 200 201 SwTwips nRelDiff = 0; 202 203 bool bMoveable = rAnchorTxtFrm.IsMoveable(); 204 205 // determine frame the object position has to be oriented at. 206 const SwTxtFrm* pOrientFrm = &rAnchorTxtFrm; 207 const SwTxtFrm* pAnchorFrmForVertPos = &rAnchorTxtFrm; 208 { 209 // if object is at-character anchored, determine character-rectangle 210 // and frame, position has to be oriented at. 211 mbAnchorToChar = (FLY_AT_CHAR == rFrmFmt.GetAnchor().GetAnchorId()); 212 if ( mbAnchorToChar ) 213 { 214 const SwFmtAnchor& rAnch = rFrmFmt.GetAnchor(); 215 // OD 2004-03-24 #i26791# - use new object instance of <SwAnchoredObject> 216 // OD 2005-01-12 - Due to table break algorithm the character 217 // rectangle can have no height. Thus, check also the width 218 if ( ( !GetAnchoredObj().GetLastCharRect().Height() && 219 !GetAnchoredObj().GetLastCharRect().Width() ) || 220 !GetAnchoredObj().GetLastTopOfLine() ) 221 { 222 // --> OD 2010-07-02 #i111886# 223 // Check existence of paragraph portion information in order 224 // to avoid formatting which could cause deletion of follow frames. 225 GetAnchoredObj().CheckCharRectAndTopOfLine(); 226 // <-- 227 // OD 2005-01-12 - Due to table break algorithm the character 228 // rectangle can have no height. Thus, check also the width 229 if ( ( !GetAnchoredObj().GetLastCharRect().Height() && 230 !GetAnchoredObj().GetLastCharRect().Width() ) || 231 !GetAnchoredObj().GetLastTopOfLine() ) 232 { 233 // --> OD 2005-01-12 - get default for <mpVertPosOrientFrm>, 234 // if it's not set. 235 if ( !mpVertPosOrientFrm ) 236 { 237 mpVertPosOrientFrm = rAnchorTxtFrm.GetUpper(); 238 } 239 // <-- 240 return; 241 } 242 } 243 mpToCharRect = &(GetAnchoredObj().GetLastCharRect()); 244 // OD 12.11.2003 #i22341# - get top of line, in which the anchor 245 // character is. 246 mnToCharTopOfLine = GetAnchoredObj().GetLastTopOfLine(); 247 pOrientFrm = &(const_cast<SwTxtFrm&>(rAnchorTxtFrm).GetFrmAtOfst( 248 rAnch.GetCntntAnchor()->nContent.GetIndex() ) ); 249 mpToCharOrientFrm = pOrientFrm; 250 } 251 } 252 SWREFRESHFN( pOrientFrm ) 253 254 // determine vertical position 255 { 256 257 // determine vertical positioning and alignment attributes 258 SwFmtVertOrient aVert( rFrmFmt.GetVertOrient() ); 259 260 // OD 22.09.2003 #i18732# - determine layout frame for vertical 261 // positions aligned to 'page areas'. 262 const SwLayoutFrm& rPageAlignLayFrm = 263 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pOrientFrm ); 264 265 if ( aVert.GetVertOrient() != text::VertOrientation::NONE ) 266 { 267 // OD 22.09.2003 #i18732# - adjustments for follow text flow or not 268 // AND vertical alignment at 'page areas'. 269 SwTwips nAlignAreaHeight; 270 SwTwips nAlignAreaOffset; 271 _GetVertAlignmentValues( *pOrientFrm, rPageAlignLayFrm, 272 aVert.GetRelationOrient(), 273 nAlignAreaHeight, nAlignAreaOffset ); 274 275 // determine relative vertical position 276 SwTwips nRelPosY = nAlignAreaOffset; 277 const SwTwips nObjHeight = (aObjBoundRect.*fnRect->fnGetHeight)(); 278 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 279 const SwTwips nUpperSpace = bVert 280 ? ( bVertL2R 281 ? rLR.GetLeft() 282 : rLR.GetRight() ) 283 : rUL.GetUpper(); 284 // --> OD 2009-08-31 #monglianlayout# 285 const SwTwips nLowerSpace = bVert 286 ? ( bVertL2R 287 ? rLR.GetLeft() 288 : rLR.GetRight() ) 289 : rUL.GetLower(); 290 // <-- 291 switch ( aVert.GetVertOrient() ) 292 { 293 case text::VertOrientation::CHAR_BOTTOM: 294 { 295 if ( mbAnchorToChar ) 296 { 297 // bottom (to character anchored) 298 nRelPosY += nAlignAreaHeight + nUpperSpace; 299 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 300 if ( bVert && !bVertL2R ) 301 { 302 nRelPosY += nObjHeight; 303 } 304 break; 305 } 306 } 307 // no break here 308 case text::VertOrientation::TOP: 309 { 310 // OD 12.11.2003 #i22341# - special case for vertical 311 // alignment at top of line 312 if ( mbAnchorToChar && 313 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 314 { 315 nRelPosY -= (nObjHeight + nLowerSpace); 316 } 317 else 318 { 319 nRelPosY += nUpperSpace; 320 } 321 } 322 break; 323 // OD 14.11.2003 #i22341# 324 case text::VertOrientation::LINE_TOP: 325 { 326 if ( mbAnchorToChar && 327 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 328 { 329 nRelPosY -= (nObjHeight + nLowerSpace); 330 } 331 else 332 { 333 ASSERT( false, 334 "<SwToCntntAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." ); 335 } 336 } 337 break; 338 case text::VertOrientation::CENTER: 339 { 340 nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2); 341 } 342 break; 343 // OD 14.11.2003 #i22341# 344 case text::VertOrientation::LINE_CENTER: 345 { 346 if ( mbAnchorToChar && 347 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 348 { 349 nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2); 350 } 351 else 352 { 353 ASSERT( false, 354 "<SwToCntntAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." ); 355 } 356 } 357 break; 358 case text::VertOrientation::BOTTOM: 359 { 360 if ( ( aVert.GetRelationOrient() == text::RelOrientation::FRAME || 361 aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) && 362 bNoSurround ) 363 { 364 // bottom (aligned to 'paragraph areas') 365 nRelPosY += nAlignAreaHeight + nUpperSpace; 366 } 367 else 368 { 369 // OD 12.11.2003 #i22341# - special case for vertical 370 // alignment at top of line 371 if ( mbAnchorToChar && 372 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 373 { 374 nRelPosY += nUpperSpace; 375 } 376 else 377 { 378 nRelPosY += nAlignAreaHeight - 379 ( nObjHeight + nLowerSpace ); 380 } 381 } 382 } 383 break; 384 // OD 14.11.2003 #i22341# 385 case text::VertOrientation::LINE_BOTTOM: 386 { 387 if ( mbAnchorToChar && 388 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 389 { 390 nRelPosY += nUpperSpace; 391 } 392 else 393 { 394 ASSERT( false, 395 "<SwToCntntAnchoredObjectPosition::CalcPosition()> - unknown combination of vertical position and vertical alignment." ); 396 } 397 } 398 break; 399 default: 400 break; 401 } 402 403 // adjust relative position by distance between anchor frame and 404 // the frame, the object is oriented at. 405 // OD 2004-05-21 #i28701# - correction: adjust relative position, 406 // only if the floating screen object has to follow the text flow. 407 if ( DoesObjFollowsTextFlow() && pOrientFrm != &rAnchorTxtFrm ) 408 { 409 // OD 2004-03-11 #i11860# - use new method <_GetTopForObjPos> 410 // to get top of frame for object positioning. 411 const SwTwips nTopOfOrient = _GetTopForObjPos( *pOrientFrm, fnRect, bVert ); 412 nRelPosY += (*fnRect->fnYDiff)( nTopOfOrient, 413 _GetTopForObjPos( rAnchorTxtFrm, fnRect, bVert ) ); 414 } 415 416 // --> OD 2005-02-07 #i42124# - capture object inside vertical 417 // layout environment. 418 { 419 const SwTwips nTopOfAnch = 420 _GetTopForObjPos( *pOrientFrm, fnRect, bVert ); 421 const SwLayoutFrm& rVertEnvironLayFrm = 422 aEnvOfObj.GetVertEnvironmentLayoutFrm( 423 *(pOrientFrm->GetUpper()) ); 424 const bool bCheckBottom = !DoesObjFollowsTextFlow(); 425 nRelPosY = _AdjustVertRelPos( nTopOfAnch, bVert, bVertL2R, 426 rVertEnvironLayFrm, nRelPosY, 427 DoesObjFollowsTextFlow(), 428 bCheckBottom ); 429 } 430 // <-- 431 // keep calculated relative vertical position - needed for filters 432 // (including the xml-filter) 433 { 434 // determine position 435 SwTwips nAttrRelPosY = nRelPosY - nAlignAreaOffset; 436 // set 437 if ( nAttrRelPosY != aVert.GetPos() ) 438 { 439 aVert.SetPos( nAttrRelPosY ); 440 const_cast<SwFrmFmt&>(rFrmFmt).LockModify(); 441 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aVert ); 442 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify(); 443 } 444 } 445 446 // determine absolute 'vertical' position, depending on layout-direction 447 // --> OD 2004-06-17 #i26791# - determine offset to 'vertical' frame 448 // anchor position, depending on layout-direction 449 if ( bVert ) 450 { 451 aRelPos.X() = nRelPosY; 452 maOffsetToFrmAnchorPos.X() = nAlignAreaOffset; 453 } 454 else 455 { 456 aRelPos.Y() = nRelPosY; 457 maOffsetToFrmAnchorPos.Y() = nAlignAreaOffset; 458 } 459 } 460 461 // OD 29.10.2003 #110978# - determine upper of frame vertical position 462 // is oriented at. 463 // OD 2004-05-21 #i28701# - determine 'virtual' anchor frame. 464 // This frame is used in the following instead of the 'real' anchor 465 // frame <rAnchorTxtFrm> for the 'vertical' position in all cases. 466 const SwLayoutFrm* pUpperOfOrientFrm = 0L; 467 { 468 // OD 2004-05-21 #i28701# - As long as the anchor frame is on the 469 // same page as <pOrientFrm> and the vertical position isn't aligned 470 // automatic at the anchor character or the top of the line of the 471 // anchor character, the anchor frame determines the vertical position. 472 if ( &rAnchorTxtFrm == pOrientFrm || 473 ( rAnchorTxtFrm.FindPageFrm() == pOrientFrm->FindPageFrm() && 474 aVert.GetVertOrient() == text::VertOrientation::NONE && 475 aVert.GetRelationOrient() != text::RelOrientation::CHAR && 476 aVert.GetRelationOrient() != text::RelOrientation::TEXT_LINE ) ) 477 { 478 pUpperOfOrientFrm = rAnchorTxtFrm.GetUpper(); 479 pAnchorFrmForVertPos = &rAnchorTxtFrm; 480 } 481 else 482 { 483 pUpperOfOrientFrm = pOrientFrm->GetUpper(); 484 pAnchorFrmForVertPos = pOrientFrm; 485 } 486 } 487 488 // ignore one-column sections. 489 // --> OD 2004-07-20 #i23512# - correction: also ignore one-columned 490 // sections with footnotes/endnotes 491 if ( pUpperOfOrientFrm->IsInSct() ) 492 { 493 const SwSectionFrm* pSctFrm = pUpperOfOrientFrm->FindSctFrm(); 494 const bool bIgnoreSection = pUpperOfOrientFrm->IsSctFrm() || 495 ( pSctFrm->Lower()->IsColumnFrm() && 496 !pSctFrm->Lower()->GetNext() ); 497 if ( bIgnoreSection ) 498 pUpperOfOrientFrm = pSctFrm->GetUpper(); 499 } 500 501 if ( aVert.GetVertOrient() == text::VertOrientation::NONE ) 502 { 503 // local variable <nRelPosY> for calculation of relative vertical 504 // distance to anchor. 505 SwTwips nRelPosY = 0; 506 // --> OD 2004-06-17 #i26791# - local variable <nVertOffsetToFrmAnchorPos> 507 // for determination of the 'vertical' offset to the frame anchor 508 // position 509 SwTwips nVertOffsetToFrmAnchorPos( 0L ); 510 // OD 12.11.2003 #i22341# - add special case for vertical alignment 511 // at top of line. 512 if ( mbAnchorToChar && 513 ( aVert.GetRelationOrient() == text::RelOrientation::CHAR || 514 aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE ) ) 515 { 516 // OD 2004-03-11 #i11860# - use new method <_GetTopForObjPos> 517 // to get top of frame for object positioning. 518 SwTwips nTopOfOrient = _GetTopForObjPos( *pOrientFrm, fnRect, bVert ); 519 if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ) 520 { 521 nVertOffsetToFrmAnchorPos = (*fnRect->fnYDiff)( 522 (ToCharRect()->*fnRect->fnGetBottom)(), 523 nTopOfOrient ); 524 } 525 else 526 { 527 nVertOffsetToFrmAnchorPos = (*fnRect->fnYDiff)( ToCharTopOfLine(), 528 nTopOfOrient ); 529 } 530 nRelPosY = nVertOffsetToFrmAnchorPos - aVert.GetPos(); 531 } 532 else 533 { 534 // OD 2004-05-21 #i28701# - correction: use <pAnchorFrmForVertPos> 535 // instead of <pOrientFrm> and do not adjust relative position 536 // to get correct vertical position. 537 nVertOffsetToFrmAnchorPos = 0L; 538 // OD 2004-03-11 #i11860# - use new method <_GetTopForObjPos> 539 // to get top of frame for object positioning. 540 const SwTwips nTopOfOrient = 541 _GetTopForObjPos( *pAnchorFrmForVertPos, fnRect, bVert ); 542 // OD 02.10.2002 #102646# - increase <nRelPosY> by margin height, 543 // if position is vertical aligned to "paragraph text area" 544 if ( aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) 545 { 546 // OD 2004-03-11 #i11860# - consider upper space amount 547 // of previous frame 548 SwTwips nTopMargin = (pAnchorFrmForVertPos->*fnRect->fnGetTopMargin)(); 549 if ( pAnchorFrmForVertPos->IsTxtFrm() ) 550 { 551 nTopMargin -= static_cast<const SwTxtFrm*>(pAnchorFrmForVertPos)-> 552 GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid(); 553 } 554 nVertOffsetToFrmAnchorPos += nTopMargin; 555 } 556 // OD 22.09.2003 #i18732# - adjust <nRelPosY> by difference 557 // between 'page area' and 'anchor' frame, if position is 558 // vertical aligned to 'page areas' 559 else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ) 560 { 561 nVertOffsetToFrmAnchorPos += (*fnRect->fnYDiff)( 562 (rPageAlignLayFrm.Frm().*fnRect->fnGetTop)(), 563 nTopOfOrient ); 564 } 565 else if ( aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) 566 { 567 SwRect aPgPrtRect( rPageAlignLayFrm.Frm() ); 568 if ( rPageAlignLayFrm.IsPageFrm() ) 569 { 570 aPgPrtRect = 571 static_cast<const SwPageFrm&>(rPageAlignLayFrm).PrtWithoutHeaderAndFooter(); 572 } 573 nVertOffsetToFrmAnchorPos += (*fnRect->fnYDiff)( 574 (aPgPrtRect.*fnRect->fnGetTop)(), 575 nTopOfOrient ); 576 } 577 nRelPosY = nVertOffsetToFrmAnchorPos + aVert.GetPos(); 578 } 579 580 // <pUpperOfOrientFrm>: layout frame, at which the position has to 581 // is oriented at 582 // <nRelPosY>: rest of the relative distance in the current 583 // layout frame 584 // <nAvail>: space, which is available in the current 585 // layout frame 586 587 // --> OD 2004-06-17 #i26791# - determine offset to 'vertical' 588 // frame anchor position, depending on layout-direction 589 if ( bVert ) 590 maOffsetToFrmAnchorPos.X() = nVertOffsetToFrmAnchorPos; 591 else 592 maOffsetToFrmAnchorPos.Y() = nVertOffsetToFrmAnchorPos; 593 // <-- 594 // OD 2004-03-11 #i11860# - use new method <_GetTopForObjPos> 595 // to get top of frame for object positioning. 596 const SwTwips nTopOfAnch = _GetTopForObjPos( *pAnchorFrmForVertPos, fnRect, bVert ); 597 if( nRelPosY <= 0 ) 598 { 599 // OD 08.09.2003 #110354# - allow negative position, but keep it 600 // inside environment layout frame. 601 const SwLayoutFrm& rVertEnvironLayFrm = 602 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pUpperOfOrientFrm ); 603 // --> OD 2004-07-22 #i31805# - do not check, if bottom of 604 // anchored object would fit into environment layout frame, if 605 // anchored object has to follow the text flow. 606 const bool bCheckBottom = !DoesObjFollowsTextFlow(); 607 nRelPosY = _AdjustVertRelPos( nTopOfAnch, bVert, bVertL2R, 608 rVertEnvironLayFrm, nRelPosY, 609 DoesObjFollowsTextFlow(), 610 bCheckBottom ); 611 // <-- 612 if ( bVert ) 613 aRelPos.X() = nRelPosY; 614 else 615 aRelPos.Y() = nRelPosY; 616 } 617 else 618 { 619 SWREFRESHFN( pAnchorFrmForVertPos ) 620 SwTwips nAvail = 621 (*fnRect->fnYDiff)( (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)(), 622 nTopOfAnch ); 623 const bool bInFtn = pAnchorFrmForVertPos->IsInFtn(); 624 while ( nRelPosY ) 625 { 626 // --> OD 2004-07-20 #i23512# - correction: 627 // consider section frame for grow in online layout. 628 // use new local method <lcl_DoesVertPosFits(..)> 629 SwLayoutFrm* pLayoutFrmToGrow = 0L; 630 const bool bDoesVertPosFits = lcl_DoesVertPosFits( 631 nRelPosY, nAvail, pUpperOfOrientFrm, bBrowse, 632 bGrow, pLayoutFrmToGrow ); 633 634 if ( bDoesVertPosFits ) 635 { 636 SwTwips nTmpRelPosY = 637 (*fnRect->fnYDiff)( (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)(), 638 nTopOfAnch ) - 639 nAvail + nRelPosY; 640 // --> OD 2004-07-06 #i28701# - adjust calculated 641 // relative vertical position to object's environment. 642 const SwFrm& rVertEnvironLayFrm = 643 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pUpperOfOrientFrm ); 644 // --> OD 2004-08-20 - do not check, if bottom of 645 // anchored object would fit into environment layout 646 // frame, if anchored object has to follow the text flow. 647 const bool bCheckBottom = !DoesObjFollowsTextFlow(); 648 nTmpRelPosY = _AdjustVertRelPos( nTopOfAnch, bVert, bVertL2R, 649 rVertEnvironLayFrm, 650 nTmpRelPosY, 651 DoesObjFollowsTextFlow(), 652 bCheckBottom ); 653 // <-- 654 if ( bVert ) 655 aRelPos.X() = nTmpRelPosY; 656 else 657 aRelPos.Y() = nTmpRelPosY; 658 659 // --> OD 2004-07-20 #i23512# - use local variable 660 // <pLayoutFrmToGrow> provided by new method 661 // <lcl_DoesVertPosFits(..)>. 662 if ( pLayoutFrmToGrow ) 663 { 664 pLayoutFrmToGrow->Grow( nRelPosY - nAvail ); 665 } 666 // <-- 667 nRelPosY = 0; 668 } 669 else 670 { 671 // --> OD 2004-10-04 #i26495# - floating screen objects, 672 // which are anchored inside a table, doesn't follow 673 // the text flow. 674 if ( DoesObjFollowsTextFlow() && 675 !( aVert.GetRelationOrient() == text::RelOrientation::PAGE_FRAME || 676 aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) && 677 !GetAnchorFrm().IsInTab() ) 678 // <-- 679 { 680 if ( bMoveable ) 681 { 682 // follow the text flow 683 nRelPosY -= nAvail; 684 MakePageType eMakePage = bInFtn ? MAKEPAGE_NONE 685 : MAKEPAGE_APPEND; 686 const bool bInSct = pUpperOfOrientFrm->IsInSct(); 687 if( bInSct ) 688 eMakePage = MAKEPAGE_NOSECTION; 689 690 const SwLayoutFrm* pTmp = 691 pUpperOfOrientFrm->GetLeaf( eMakePage, sal_True, &rAnchorTxtFrm ); 692 if ( pTmp && 693 ( !bInSct || 694 pUpperOfOrientFrm->FindSctFrm()->IsAnFollow( pTmp->FindSctFrm() ) ) ) 695 { 696 pUpperOfOrientFrm = pTmp; 697 bMoveable = rAnchorTxtFrm.IsMoveable( (SwLayoutFrm*)pUpperOfOrientFrm ); 698 SWREFRESHFN( pUpperOfOrientFrm ) 699 nAvail = (pUpperOfOrientFrm->Prt().*fnRect->fnGetHeight)(); 700 } 701 else 702 { 703 // if there isn't enough space in the (colmuned) 704 // section, leave it and set available space <nAvail> 705 // to the space below the section. 706 // if the new available space isn't also enough, 707 // new pages can be created. 708 if( bInSct ) 709 { 710 const SwFrm* pSct = pUpperOfOrientFrm->FindSctFrm(); 711 pUpperOfOrientFrm = pSct->GetUpper(); 712 nAvail = (*fnRect->fnYDiff)( 713 (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)(), 714 (pSct->*fnRect->fnGetPrtBottom)() ); 715 } 716 else 717 { 718 #if OSL_DEBUG_LEVEL > 1 719 ASSERT( false, "<SwToCntntAnchoredObjectPosition::CalcPosition()> - code under investigation by OD, please inform OD about this assertion!" ); 720 #endif 721 nRelDiff = nRelPosY; 722 nRelPosY = 0; 723 } 724 } 725 } 726 else 727 { 728 nRelPosY = 0; 729 } 730 } 731 else 732 { 733 // OD 06.10.2003 #i18732# - do not follow text flow respectively 734 // align at 'page areas', but stay inside given environment 735 const SwFrm& rVertEnvironLayFrm = 736 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pUpperOfOrientFrm ); 737 nRelPosY = _AdjustVertRelPos( nTopOfAnch, bVert, bVertL2R, 738 rVertEnvironLayFrm, 739 nRelPosY, 740 DoesObjFollowsTextFlow() ); 741 if( bVert ) 742 aRelPos.X() = nRelPosY; 743 else 744 aRelPos.Y() = nRelPosY; 745 nRelPosY = 0; 746 } 747 } 748 } // end of <while ( nRelPosY )> 749 } // end of else <nRelPosY <= 0> 750 } // end of <aVert.GetVertOrient() == text::VertOrientation::NONE> 751 752 //Damit das Teil ggf. auf die richtige Seite gestellt und in die 753 //PrtArea des LayLeaf gezogen werden kann, muss hier seine 754 //absolute Position berechnet werden. 755 const SwTwips nTopOfAnch = _GetTopForObjPos( *pAnchorFrmForVertPos, fnRect, bVert ); 756 if( bVert ) 757 { 758 // --> OD 2009-08-31 #monglianlayout# 759 if ( !bVertL2R ) 760 { 761 GetAnchoredObj().SetObjLeft( nTopOfAnch - 762 ( aRelPos.X() - nRelDiff ) - 763 aObjBoundRect.Width() ); 764 } 765 else 766 { 767 GetAnchoredObj().SetObjLeft( nTopOfAnch + 768 ( aRelPos.X() - nRelDiff ) ); 769 } 770 // <-- 771 } 772 else 773 { 774 GetAnchoredObj().SetObjTop( nTopOfAnch + 775 ( aRelPos.Y() - nRelDiff ) ); 776 } 777 778 // grow environment under certain conditions 779 // ignore one-column sections. 780 // --> OD 2004-07-20 #i23512# - correction: also ignore one-columned 781 // sections with footnotes/endnotes 782 if ( pUpperOfOrientFrm->IsInSct() ) 783 { 784 const SwSectionFrm* pSctFrm = pUpperOfOrientFrm->FindSctFrm(); 785 const bool bIgnoreSection = pUpperOfOrientFrm->IsSctFrm() || 786 ( pSctFrm->Lower()->IsColumnFrm() && 787 !pSctFrm->Lower()->GetNext() ); 788 if ( bIgnoreSection ) 789 pUpperOfOrientFrm = pSctFrm->GetUpper(); 790 } 791 SwTwips nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 792 (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)() ); 793 if( nDist < 0 ) 794 { 795 // --> OD 2004-07-20 #i23512# - correction: 796 // consider section frame for grow in online layout and 797 // consider page alignment for grow in table. 798 SwLayoutFrm* pLayoutFrmToGrow = 0L; 799 if ( bBrowse && rAnchorTxtFrm.IsMoveable() ) 800 { 801 if ( pUpperOfOrientFrm->IsInSct() ) 802 { 803 pLayoutFrmToGrow = const_cast<SwLayoutFrm*>( 804 pUpperOfOrientFrm->FindSctFrm()->GetUpper()); 805 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 806 (pLayoutFrmToGrow->*fnRect->fnGetPrtBottom)() ); 807 if ( nDist >= 0 ) 808 { 809 pLayoutFrmToGrow = 0L; 810 } 811 } 812 else 813 { 814 pLayoutFrmToGrow = 815 const_cast<SwLayoutFrm*>(pUpperOfOrientFrm); 816 } 817 } 818 else if ( rAnchorTxtFrm.IsInTab() && bGrow ) 819 { 820 pLayoutFrmToGrow = const_cast<SwLayoutFrm*>(pUpperOfOrientFrm); 821 } 822 if ( pLayoutFrmToGrow ) 823 { 824 pLayoutFrmToGrow->Grow( -nDist ); 825 } 826 // <-- 827 } 828 829 if ( DoesObjFollowsTextFlow() && 830 !( aVert.GetRelationOrient() == text::RelOrientation::PAGE_FRAME || 831 aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) ) 832 { 833 834 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 835 (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)() ); 836 // --> OD 2004-10-04 #i26945# - floating screen objects, which are 837 // anchored inside a table, doesn't follow the text flow. But, they 838 // have to stay inside its layout environment. 839 if ( nDist < 0 && pOrientFrm->IsInTab() ) 840 { 841 // If the anchor frame is the first content of the table cell 842 // and has no follow, the table frame is notified, 843 // that the object doesn't fit into the table cell. 844 // Adjustment of position isn't needed in this case. 845 if ( pOrientFrm == &rAnchorTxtFrm && 846 !pOrientFrm->GetFollow() && 847 !pOrientFrm->GetIndPrev() ) 848 { 849 const_cast<SwTabFrm*>(pOrientFrm->FindTabFrm()) 850 ->SetDoesObjsFit( sal_False ); 851 } 852 else 853 { 854 SwTwips nTmpRelPosY( 0L ); 855 if ( bVert ) 856 nTmpRelPosY = aRelPos.X() - nDist; 857 else 858 nTmpRelPosY = aRelPos.Y() + nDist; 859 const SwLayoutFrm& rVertEnvironLayFrm = 860 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pUpperOfOrientFrm ); 861 nTmpRelPosY = _AdjustVertRelPos( nTopOfAnch, bVert, bVertL2R, 862 rVertEnvironLayFrm, 863 nTmpRelPosY, 864 DoesObjFollowsTextFlow(), 865 false ); 866 if ( bVert ) 867 { 868 aRelPos.X() = nTmpRelPosY; 869 // --> OD 2009-08-31 #mongolianlayout# 870 if ( !bVertL2R ) 871 { 872 GetAnchoredObj().SetObjLeft( nTopOfAnch - 873 aRelPos.X() - 874 aObjBoundRect.Width() ); 875 } 876 else 877 { 878 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() ); 879 } 880 // <-- 881 } 882 else 883 { 884 aRelPos.Y() = nTmpRelPosY; 885 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() ); 886 } 887 // If the anchor frame is the first content of the table cell 888 // and the object still doesn't fit, the table frame is notified, 889 // that the object doesn't fit into the table cell. 890 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 891 (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)() ); 892 if ( nDist < 0 && 893 pOrientFrm == &rAnchorTxtFrm && !pOrientFrm->GetIndPrev() ) 894 { 895 const_cast<SwTabFrm*>(pOrientFrm->FindTabFrm()) 896 ->SetDoesObjsFit( sal_False ); 897 } 898 } 899 } 900 else 901 { 902 // <-- 903 // follow text flow 904 const bool bInFtn = rAnchorTxtFrm.IsInFtn(); 905 while( bMoveable && nDist < 0 ) 906 { 907 bool bInSct = pUpperOfOrientFrm->IsInSct(); 908 if ( bInSct ) 909 { 910 const SwLayoutFrm* pTmp = pUpperOfOrientFrm->FindSctFrm()->GetUpper(); 911 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 912 (pTmp->*fnRect->fnGetPrtBottom)() ); 913 // --> OD 2004-11-01 #i23129# - Try to flow into next 914 // section|section column. Thus, do *not* leave section 915 // area, if anchored object doesn't fit into upper of section. 916 // But the anchored object is allowed to overlap bottom 917 // section|section column. 918 if ( nDist >= 0 ) 919 { 920 break; 921 } 922 // <-- 923 } 924 if ( !bInSct && 925 (GetAnchoredObj().GetObjRect().*fnRect->fnGetTop)() == 926 (pUpperOfOrientFrm->*fnRect->fnGetPrtTop)() ) 927 //Das teil passt nimmer, da hilft auch kein moven. 928 break; 929 930 const SwLayoutFrm* pNextLay = pUpperOfOrientFrm->GetLeaf( 931 ( bInSct 932 ? MAKEPAGE_NOSECTION 933 : ( bInFtn ? MAKEPAGE_NONE : MAKEPAGE_APPEND ) ), 934 sal_True, &rAnchorTxtFrm ); 935 // OD 06.10.2003 #110978# - correction: 936 // If anchor is in footnote and proposed next layout environment 937 // isn't a footnote frame, object can't follow the text flow 938 if ( bInFtn && pNextLay && !pNextLay->IsFtnFrm() ) 939 { 940 pNextLay = 0L; 941 } 942 if ( pNextLay ) 943 { 944 SWRECTFNX( pNextLay ) 945 if ( !bInSct || 946 ( pUpperOfOrientFrm->FindSctFrm()->IsAnFollow( pNextLay->FindSctFrm() ) && 947 (pNextLay->Prt().*fnRectX->fnGetHeight)() ) ) 948 { 949 SwTwips nTmpRelPosY = 950 (*fnRect->fnYDiff)( (pNextLay->*fnRect->fnGetPrtTop)(), 951 nTopOfAnch ); 952 if ( bVert ) 953 aRelPos.X() = nTmpRelPosY; 954 else 955 aRelPos.Y() = nTmpRelPosY; 956 pUpperOfOrientFrm = pNextLay; 957 SWREFRESHFN( pUpperOfOrientFrm ) 958 bMoveable = rAnchorTxtFrm.IsMoveable( (SwLayoutFrm*)pUpperOfOrientFrm ); 959 if( bVertX ) 960 { 961 // --> OD 2009-08-31 #mongolianlayout# 962 if ( !bVertL2R ) 963 { 964 GetAnchoredObj().SetObjLeft( nTopOfAnch - 965 aRelPos.X() - 966 aObjBoundRect.Width() ); 967 } 968 else 969 { 970 GetAnchoredObj().SetObjLeft( nTopOfAnch + 971 aRelPos.X() ); 972 } 973 // <-- 974 } 975 else 976 GetAnchoredObj().SetObjTop( nTopOfAnch + 977 aRelPos.Y() ); 978 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 979 (pUpperOfOrientFrm->*fnRect->fnGetPrtBottom)() ); 980 } 981 // --> OD 2004-11-01 #i23129# - leave section area 982 else if ( bInSct ) 983 { 984 const SwLayoutFrm* pTmp = pUpperOfOrientFrm->FindSctFrm()->GetUpper(); 985 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 986 (pTmp->*fnRect->fnGetPrtBottom)() ); 987 if( nDist < 0 ) 988 pUpperOfOrientFrm = pTmp; 989 else 990 break; 991 } 992 // <-- 993 } 994 else if ( bInSct ) 995 { 996 // Wenn wir innerhalb des Bereich nicht genug Platz haben, gucken 997 // wir uns mal die Seite an. 998 const SwLayoutFrm* pTmp = pUpperOfOrientFrm->FindSctFrm()->GetUpper(); 999 nDist = (GetAnchoredObj().GetObjRect().*fnRect->fnBottomDist)( 1000 (pTmp->*fnRect->fnGetPrtBottom)() ); 1001 if( nDist < 0 ) 1002 pUpperOfOrientFrm = pTmp; 1003 else 1004 break; 1005 } 1006 else 1007 bMoveable = false; 1008 } 1009 } 1010 } 1011 1012 // keep layout frame vertical position is oriented at. 1013 mpVertPosOrientFrm = pUpperOfOrientFrm; 1014 1015 } 1016 1017 // determine 'horizontal' position 1018 { 1019 // determine horizontal positioning and alignment attributes 1020 SwFmtHoriOrient aHori( rFrmFmt.GetHoriOrient() ); 1021 1022 // set calculated vertical position in order to determine correct 1023 // frame, the horizontal position is oriented at. 1024 const SwTwips nTopOfAnch = _GetTopForObjPos( *pAnchorFrmForVertPos, fnRect, bVert ); 1025 if( bVert ) 1026 { 1027 // --> OD 2009-08-31 #mongolianlayout# 1028 if ( !bVertL2R ) 1029 { 1030 GetAnchoredObj().SetObjLeft( nTopOfAnch - 1031 aRelPos.X() - aObjBoundRect.Width() ); 1032 } 1033 else 1034 { 1035 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() ); 1036 } 1037 // <-- 1038 } 1039 else 1040 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() ); 1041 1042 // determine frame, horizontal position is oriented at. 1043 // OD 2004-05-21 #i28701# - If floating screen object doesn't follow 1044 // the text flow, its horizontal position is oriented at <pOrientFrm>. 1045 const SwFrm* pHoriOrientFrm = DoesObjFollowsTextFlow() 1046 ? &_GetHoriVirtualAnchor( *mpVertPosOrientFrm ) 1047 : pOrientFrm; 1048 1049 // --> OD 2004-06-17 #i26791# - get 'horizontal' offset to frame anchor position. 1050 SwTwips nHoriOffsetToFrmAnchorPos( 0L ); 1051 SwTwips nRelPosX = _CalcRelPosX( *pHoriOrientFrm, aEnvOfObj, 1052 aHori, rLR, rUL, bWrapThrough, 1053 ( bVert ? aRelPos.X() : aRelPos.Y() ), 1054 nHoriOffsetToFrmAnchorPos ); 1055 1056 // --> OD 2004-06-17 #i26791# - determine offset to 'horizontal' frame 1057 // anchor position, depending on layout-direction 1058 if ( bVert ) 1059 { 1060 aRelPos.Y() = nRelPosX; 1061 maOffsetToFrmAnchorPos.Y() = nHoriOffsetToFrmAnchorPos; 1062 } 1063 else 1064 { 1065 aRelPos.X() = nRelPosX; 1066 maOffsetToFrmAnchorPos.X() = nHoriOffsetToFrmAnchorPos; 1067 } 1068 1069 // save calculated horizontal position - needed for filters 1070 // (including the xml-filter) 1071 { 1072 SwTwips nAttrRelPosX = nRelPosX - nHoriOffsetToFrmAnchorPos; 1073 if ( aHori.GetHoriOrient() != text::HoriOrientation::NONE && 1074 aHori.GetPos() != nAttrRelPosX ) 1075 { 1076 aHori.SetPos( nAttrRelPosX ); 1077 const_cast<SwFrmFmt&>(rFrmFmt).LockModify(); 1078 const_cast<SwFrmFmt&>(rFrmFmt).SetFmtAttr( aHori ); 1079 const_cast<SwFrmFmt&>(rFrmFmt).UnlockModify(); 1080 } 1081 } 1082 } 1083 1084 // set absolute position at object 1085 const SwTwips nTopOfAnch = _GetTopForObjPos( *pAnchorFrmForVertPos, fnRect, bVert ); 1086 if( bVert ) 1087 { 1088 // --> OD 2009-08-31 #mongolianlayout# 1089 if ( !bVertL2R ) 1090 { 1091 GetAnchoredObj().SetObjLeft( nTopOfAnch - 1092 aRelPos.X() - aObjBoundRect.Width() ); 1093 } 1094 else 1095 { 1096 GetAnchoredObj().SetObjLeft( nTopOfAnch + aRelPos.X() ); 1097 } 1098 // <-- 1099 GetAnchoredObj().SetObjTop( rAnchorTxtFrm.Frm().Top() + 1100 aRelPos.Y() ); 1101 } 1102 else 1103 { 1104 GetAnchoredObj().SetObjLeft( rAnchorTxtFrm.Frm().Left() + 1105 aRelPos.X() ); 1106 GetAnchoredObj().SetObjTop( nTopOfAnch + aRelPos.Y() ); 1107 } 1108 1109 // set relative position at object 1110 GetAnchoredObj().SetCurrRelPos( aRelPos ); 1111 } 1112 1113 /** determine frame for horizontal position 1114 1115 @author OD 1116 */ 1117 const SwFrm& SwToCntntAnchoredObjectPosition::_GetHoriVirtualAnchor( 1118 const SwLayoutFrm& _rProposedFrm ) const 1119 { 1120 const SwFrm* pHoriVirtAnchFrm = &_rProposedFrm; 1121 1122 // Search for first lower content frame, which is the anchor or a follow 1123 // of the anchor (Note: <Anchor.IsAnFollow( Anchor )> is true) 1124 // If none found, <_rProposedFrm> is returned. 1125 const SwFrm* pFrm = _rProposedFrm.Lower(); 1126 while ( pFrm ) 1127 { 1128 if ( pFrm->IsCntntFrm() && 1129 GetAnchorTxtFrm().IsAnFollow( static_cast<const SwCntntFrm*>(pFrm) ) ) 1130 { 1131 pHoriVirtAnchFrm = pFrm; 1132 break; 1133 } 1134 pFrm = pFrm->GetNext(); 1135 } 1136 1137 return *pHoriVirtAnchFrm; 1138 } 1139 1140 const SwLayoutFrm& SwToCntntAnchoredObjectPosition::GetVertPosOrientFrm() const 1141 { 1142 return *mpVertPosOrientFrm; 1143 } 1144 1145