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