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