xref: /AOO41X/main/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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