xref: /AOO41X/main/sw/source/core/objectpositioning/anchoredobjectposition.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 <anchoredobjectposition.hxx>
31 #ifndef _ENVIRONMENTOFANCHOREDOBJECT
32 #include <environmentofanchoredobject.hxx>
33 #endif
34 #include <flyfrm.hxx>
35 #include <flyfrms.hxx>
36 #include <txtfrm.hxx>
37 #include <pagefrm.hxx>
38 #include <frmtool.hxx>
39 #ifndef _SVX_SVDOBJ_HXX
40 #include <svx/svdobj.hxx>
41 #endif
42 #include <dflyobj.hxx>
43 #include <dcontact.hxx>
44 #include <frmfmt.hxx>
45 #include <fmtornt.hxx>
46 // --> OD 2006-03-15 #i62875#
47 #include <fmtfollowtextflow.hxx>
48 // <--
49 #include <editeng/lrspitem.hxx>
50 #include <editeng/ulspitem.hxx>
51 #include <ndtxt.hxx>
52 #include <IDocumentSettingAccess.hxx>
53 
54 using namespace ::com::sun::star;
55 using namespace objectpositioning;
56 
57 // **************************************************************************
58 // constructor, destructor, initialization
59 // **************************************************************************
60 SwAnchoredObjectPosition::SwAnchoredObjectPosition( SdrObject& _rDrawObj )
61     : mrDrawObj( _rDrawObj ),
62       mbIsObjFly( false ),
63       mpAnchoredObj( 0 ),
64       mpAnchorFrm( 0 ),
65       mpContact( 0 ),
66       // --> OD 2006-03-15 #i62875#
67       mbFollowTextFlow( false ),
68       mbDoNotCaptureAnchoredObj( false )
69       // <--
70 {
71 #if OSL_DEBUG_LEVEL > 1
72     // assert, if object isn't of excepted type
73     const bool bObjOfExceptedType =
74             mrDrawObj.ISA(SwVirtFlyDrawObj) || // object representing fly frame
75             mrDrawObj.ISA(SwDrawVirtObj)    || // 'virtual' drawing object
76             ( !mrDrawObj.ISA(SdrVirtObj) &&    // 'master' drawing object
77               !mrDrawObj.ISA(SwFlyDrawObj) );  // - indirectly checked
78     (void) bObjOfExceptedType;
79     ASSERT( bObjOfExceptedType,
80             "SwAnchoredObjectPosition(..) - object of unexcepted type!" );
81 #endif
82 
83     _GetInfoAboutObj();
84 }
85 
86 /** determine information about object
87 
88     OD 30.07.2003 #110978#
89     members <mbIsObjFly>, <mpFrmOfObj>, <mpAnchorFrm>, <mpContact>,
90     <mbFollowTextFlow> and <mbDoNotCaptureAnchoredObj> are set
91 
92     @author OD
93 */
94 void SwAnchoredObjectPosition::_GetInfoAboutObj()
95 {
96     // determine, if object represents a fly frame
97     {
98         mbIsObjFly = mrDrawObj.ISA(SwVirtFlyDrawObj);
99     }
100 
101     // determine contact object
102     {
103         mpContact = static_cast<SwContact*>(GetUserCall( &mrDrawObj ));
104         ASSERT( mpContact,
105                 "SwAnchoredObjectPosition::_GetInfoAboutObj() - missing SwContact-object." );
106     }
107 
108     // determine anchored object, the object belongs to
109     {
110         // OD 2004-03-30 #i26791#
111         mpAnchoredObj = mpContact->GetAnchoredObj( &mrDrawObj );
112         ASSERT( mpAnchoredObj,
113                 "SwAnchoredObjectPosition::_GetInfoAboutObj() - missing anchored object." );
114     }
115 
116     // determine frame, the object is anchored at
117     {
118         // OD 2004-03-23 #i26791#
119         mpAnchorFrm = mpAnchoredObj->AnchorFrm();
120         ASSERT( mpAnchorFrm,
121                 "SwAnchoredObjectPosition::_GetInfoAboutObj() - missing anchor frame." );
122     }
123 
124     // determine format the object belongs to
125     {
126         // --> OD 2004-07-01 #i28701#
127         mpFrmFmt = &mpAnchoredObj->GetFrmFmt();
128         ASSERT( mpFrmFmt,
129                 "<SwAnchoredObjectPosition::_GetInfoAboutObj() - missing frame format." );
130     }
131 
132     // --> OD 2006-03-15 #i62875#
133     // determine attribute value of <Follow-Text-Flow>
134     {
135         mbFollowTextFlow = mpFrmFmt->GetFollowTextFlow().GetValue();
136     }
137 
138     // determine, if anchored object has not to be captured on the page.
139     // the following conditions must be hold to *not* capture it:
140     // - corresponding document compatibility flag is set
141     // - it's a drawing object
142     // - it doesn't follow the text flow
143     {
144         mbDoNotCaptureAnchoredObj = !mbIsObjFly && !mbFollowTextFlow &&
145                                     mpFrmFmt->getIDocumentSettingAccess()->get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE);
146     }
147     // <--
148 }
149 
150 SwAnchoredObjectPosition::~SwAnchoredObjectPosition()
151 {}
152 
153 bool SwAnchoredObjectPosition::IsAnchoredToChar() const
154 {
155     return false;
156 }
157 
158 const SwFrm* SwAnchoredObjectPosition::ToCharOrientFrm() const
159 {
160     return NULL;
161 }
162 
163 const SwRect* SwAnchoredObjectPosition::ToCharRect() const
164 {
165     return NULL;
166 }
167 
168 // OD 12.11.2003 #i22341#
169 SwTwips SwAnchoredObjectPosition::ToCharTopOfLine() const
170 {
171     return 0L;
172 }
173 
174 /** helper method to determine top of a frame for the vertical
175     object positioning
176 
177     OD 2004-03-11 #i11860#
178 
179     @author OD
180 */
181 SwTwips SwAnchoredObjectPosition::_GetTopForObjPos( const SwFrm& _rFrm,
182                                                     const SwRectFn& _fnRect,
183                                                     const bool _bVert ) const
184 {
185     SwTwips nTopOfFrmForObjPos = (_rFrm.Frm().*_fnRect->fnGetTop)();
186 
187     if ( _rFrm.IsTxtFrm() )
188     {
189         const SwTxtFrm& rTxtFrm = static_cast<const SwTxtFrm&>(_rFrm);
190         if ( _bVert )
191         {
192             nTopOfFrmForObjPos -=
193                 rTxtFrm.GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid();
194         }
195         else
196         {
197             nTopOfFrmForObjPos +=
198                 rTxtFrm.GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid();
199         }
200     }
201 
202     return nTopOfFrmForObjPos;
203 }
204 
205 void SwAnchoredObjectPosition::_GetVertAlignmentValues(
206                                         const SwFrm& _rVertOrientFrm,
207                                         const SwFrm& _rPageAlignLayFrm,
208                                         const sal_Int16 _eRelOrient,
209                                         SwTwips&      _orAlignAreaHeight,
210                                         SwTwips&      _orAlignAreaOffset ) const
211 {
212     SwTwips nHeight = 0;
213     SwTwips nOffset = 0;
214     SWRECTFN( (&_rVertOrientFrm) )
215     // OD 2004-03-11 #i11860# - top of <_rVertOrientFrm> for object positioning
216     const SwTwips nVertOrientTop = _GetTopForObjPos( _rVertOrientFrm, fnRect, bVert );
217     // OD 2004-03-11 #i11860# - upper space amount of <_rVertOrientFrm> considered
218     // for previous frame
219     const SwTwips nVertOrientUpperSpaceForPrevFrmAndPageGrid =
220             _rVertOrientFrm.IsTxtFrm()
221             ? static_cast<const SwTxtFrm&>(_rVertOrientFrm).
222                         GetUpperSpaceAmountConsideredForPrevFrmAndPageGrid()
223             : 0;
224     switch ( _eRelOrient )
225     {
226         case text::RelOrientation::FRAME:
227         {
228             // OD 2004-03-11 #i11860# - consider upper space of previous frame
229             nHeight = (_rVertOrientFrm.Frm().*fnRect->fnGetHeight)() -
230                       nVertOrientUpperSpaceForPrevFrmAndPageGrid;
231             nOffset = 0;
232         }
233         break;
234         case text::RelOrientation::PRINT_AREA:
235         {
236             nHeight = (_rVertOrientFrm.Prt().*fnRect->fnGetHeight)();
237             // OD 2004-03-11 #i11860# - consider upper space of previous frame
238             nOffset = (_rVertOrientFrm.*fnRect->fnGetTopMargin)() -
239                       nVertOrientUpperSpaceForPrevFrmAndPageGrid;
240             // if aligned to page in horizontal layout, consider header and
241             // footer frame height appropriately.
242             if( _rVertOrientFrm.IsPageFrm() && !bVert )
243             {
244                 const SwFrm* pPrtFrm =
245                         static_cast<const SwPageFrm&>(_rVertOrientFrm).Lower();
246                 while( pPrtFrm )
247                 {
248                     if( pPrtFrm->IsHeaderFrm() )
249                     {
250                         nHeight -= pPrtFrm->Frm().Height();
251                         nOffset += pPrtFrm->Frm().Height();
252                     }
253                     else if( pPrtFrm->IsFooterFrm() )
254                     {
255                         nHeight -= pPrtFrm->Frm().Height();
256                     }
257                     pPrtFrm = pPrtFrm->GetNext();
258                 }
259             }
260         }
261         break;
262         case text::RelOrientation::PAGE_FRAME:
263         {
264             nHeight = (_rPageAlignLayFrm.Frm().*fnRect->fnGetHeight)();
265             nOffset = (*fnRect->fnYDiff)(
266                         (_rPageAlignLayFrm.Frm().*fnRect->fnGetTop)(),
267                         nVertOrientTop );
268         }
269         break;
270         case text::RelOrientation::PAGE_PRINT_AREA:
271         {
272             nHeight = (_rPageAlignLayFrm.Prt().*fnRect->fnGetHeight)();
273             nOffset = (_rPageAlignLayFrm.*fnRect->fnGetTopMargin)() +
274                       (*fnRect->fnYDiff)(
275                         (_rPageAlignLayFrm.Frm().*fnRect->fnGetTop)(),
276                         nVertOrientTop );
277             // if aligned to page in horizontal layout, consider header and
278             // footer frame height appropriately.
279             if( _rPageAlignLayFrm.IsPageFrm() && !bVert )
280             {
281                 const SwFrm* pPrtFrm =
282                         static_cast<const SwPageFrm&>(_rPageAlignLayFrm).Lower();
283                 while( pPrtFrm )
284                 {
285                     if( pPrtFrm->IsHeaderFrm() )
286                     {
287                         nHeight -= pPrtFrm->Frm().Height();
288                         nOffset += pPrtFrm->Frm().Height();
289                     }
290                     else if( pPrtFrm->IsFooterFrm() )
291                     {
292                         nHeight -= pPrtFrm->Frm().Height();
293                     }
294                     pPrtFrm = pPrtFrm->GetNext();
295                 }
296             }
297         }
298         break;
299         // OD 12.11.2003 #i22341# - vertical alignment at top of line
300         case text::RelOrientation::TEXT_LINE:
301         {
302             if ( IsAnchoredToChar() )
303             {
304                 nHeight = 0;
305                 nOffset = (*fnRect->fnYDiff)( ToCharTopOfLine(), nVertOrientTop );
306             }
307             else
308             {
309                 ASSERT( false,
310                         "<SwAnchoredObjectPosition::_GetVertAlignmentValues(..)> - invalid relative alignment" );
311             }
312         }
313         break;
314         case text::RelOrientation::CHAR:
315         {
316             if ( IsAnchoredToChar() )
317             {
318                 nHeight = (ToCharRect()->*fnRect->fnGetHeight)();
319                 nOffset = (*fnRect->fnYDiff)( (ToCharRect()->*fnRect->fnGetTop)(),
320                                               nVertOrientTop );
321             }
322             else
323             {
324                 ASSERT( false,
325                         "<SwAnchoredObjectPosition::_GetVertAlignmentValues(..)> - invalid relative alignment" );
326             }
327         }
328         break;
329         // no break here, because text::RelOrientation::CHAR is invalid, if !mbAnchorToChar
330         default:
331         //case text::RelOrientation::PAGE_LEFT:     not valid for vertical alignment
332         //case text::RelOrientation::PAGE_RIGHT:    not valid for vertical alignment
333         //case text::RelOrientation::FRAME_LEFT:    not valid for vertical alignment
334         //case text::RelOrientation::FRAME_RIGHT:   not valid for vertical alignment
335         {
336             ASSERT( false,
337                     "<SwAnchoredObjectPosition::_GetVertAlignmentValues(..)> - invalid relative alignment" );
338         }
339     }
340 
341     _orAlignAreaHeight = nHeight;
342     _orAlignAreaOffset = nOffset;
343 }
344 
345 // --> OD 2004-06-17 #i26791# - add output parameter <_roVertOffsetToFrmAnchorPos>
346 SwTwips SwAnchoredObjectPosition::_GetVertRelPos(
347                                     const SwFrm& _rVertOrientFrm,
348                                     const SwFrm& _rPageAlignLayFrm,
349                                     const sal_Int16 _eVertOrient,
350                                     const sal_Int16 _eRelOrient,
351                                     const SwTwips          _nVertPos,
352                                     const SvxLRSpaceItem& _rLRSpacing,
353                                     const SvxULSpaceItem& _rULSpacing,
354                                     SwTwips& _roVertOffsetToFrmAnchorPos ) const
355 {
356     SwTwips nRelPosY = 0;
357     SWRECTFN( (&_rVertOrientFrm) );
358 
359     SwTwips nAlignAreaHeight;
360     SwTwips nAlignAreaOffset;
361     _GetVertAlignmentValues( _rVertOrientFrm, _rPageAlignLayFrm,
362                              _eRelOrient, nAlignAreaHeight, nAlignAreaOffset );
363 
364     nRelPosY = nAlignAreaOffset;
365     const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
366     const SwTwips nObjHeight = (aObjBoundRect.*fnRect->fnGetHeight)();
367 
368     switch ( _eVertOrient )
369     {
370         case text::VertOrientation::NONE:
371         {
372             // 'manual' vertical position
373             nRelPosY += _nVertPos;
374         }
375         break;
376         case text::VertOrientation::TOP:
377         {
378             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
379               nRelPosY +=   bVert
380                             ? ( bVertL2R
381                                 ? _rLRSpacing.GetLeft()
382                                 : _rLRSpacing.GetRight() )
383                             : _rULSpacing.GetUpper();
384         }
385         break;
386         case text::VertOrientation::CENTER:
387         {
388             nRelPosY += (nAlignAreaHeight / 2) - (nObjHeight / 2);
389         }
390         break;
391         case text::VertOrientation::BOTTOM:
392         {
393             //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
394             nRelPosY += nAlignAreaHeight -
395                         ( nObjHeight + ( bVert
396                                          ? ( bVertL2R
397                                              ? _rLRSpacing.GetRight()
398                                              : _rLRSpacing.GetLeft() )
399                                          : _rULSpacing.GetLower() ) );
400         }
401         break;
402         default:
403         {
404             ASSERT( false,
405                     "<SwAnchoredObjectPosition::_GetVertRelPos(..) - invalid vertical positioning" );
406         }
407     }
408 
409     // --> OD 2004-06-17 #i26791#
410     _roVertOffsetToFrmAnchorPos = nAlignAreaOffset;
411 
412     return nRelPosY;
413 }
414 
415 /** adjust calculated vertical in order to keep object inside
416     'page' alignment layout frame.
417 
418     OD 2004-07-01 #i28701# - parameter <nTopOfAnch> and <bVert> added
419     OD 2004-07-22 #i31805# - add parameter <bCheckBottom>
420     OD 2004-10-08 #i26945# - add parameter <bFollowTextFlow>
421     OD 2006-03-15 #i62875# - method now private and renamed.
422     OD 2009-09-01 #mongolianlayout# - add parameter <bVertL2R>
423 
424     @author OD
425 */
426 SwTwips SwAnchoredObjectPosition::_ImplAdjustVertRelPos( const SwTwips nTopOfAnch,
427                                                          const bool bVert,
428                                                          const bool bVertL2R,
429                                                          const SwFrm& rPageAlignLayFrm,
430                                                          const SwTwips nProposedRelPosY,
431                                                          const bool bFollowTextFlow,
432                                                          const bool bCheckBottom ) const
433 {
434     SwTwips nAdjustedRelPosY = nProposedRelPosY;
435 
436     const Size aObjSize( GetAnchoredObj().GetObjRect().SSize() );
437 
438     // determine the area of 'page' alignment frame, to which the vertical
439     // position is restricted.
440     // --> OD 2004-07-06 #i28701# - Extend restricted area for the vertical
441     // position to area of the page frame, if wrapping style influence is
442     // considered on object positioning. Needed to avoid layout loops in the
443     // object positioning algorithm considering the wrapping style influence
444     // caused by objects, which follow the text flow and thus are restricted
445     // to its environment (e.g. page header/footer).
446     SwRect aPgAlignArea;
447     {
448         // --> OD 2004-10-08 #i26945# - no extension of restricted area, if
449         // object's attribute follow text flow is set and its inside a table
450         if ( GetFrmFmt().getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
451              ( !bFollowTextFlow ||
452                !GetAnchoredObj().GetAnchorFrm()->IsInTab() ) )
453         {
454             aPgAlignArea = rPageAlignLayFrm.FindPageFrm()->Frm();
455         }
456         else
457         {
458             aPgAlignArea = rPageAlignLayFrm.Frm();
459         }
460     }
461 
462     if ( bVert )
463     {
464         // --> OD 2009-09-01 #mongolianlayout#
465         if ( !bVertL2R )
466         // <--
467         {
468             if ( bCheckBottom &&
469                  nTopOfAnch - nAdjustedRelPosY - aObjSize.Width() <
470                     aPgAlignArea.Left() )
471             {
472                 nAdjustedRelPosY = aPgAlignArea.Left() +
473                                    nTopOfAnch -
474                                    aObjSize.Width();
475             }
476             if ( nTopOfAnch - nAdjustedRelPosY > aPgAlignArea.Right() )
477             {
478                 nAdjustedRelPosY = nTopOfAnch - aPgAlignArea.Right();
479             }
480         }
481         // --> OD 2009-09-01 #mongolianlayout#
482         else
483         {
484             if ( bCheckBottom &&
485                  nTopOfAnch + nAdjustedRelPosY + aObjSize.Width() >
486                     aPgAlignArea.Right() )
487             {
488                 nAdjustedRelPosY = aPgAlignArea.Right() -
489                                    nTopOfAnch -
490                                    aObjSize.Width();
491             }
492             if ( nTopOfAnch + nAdjustedRelPosY < aPgAlignArea.Left() )
493             {
494                 nAdjustedRelPosY = aPgAlignArea.Left() - nTopOfAnch;
495             }
496         }
497         // <--
498     }
499     else
500     {
501         if ( bCheckBottom &&
502              nTopOfAnch + nAdjustedRelPosY + aObjSize.Height() >
503                 aPgAlignArea.Top() + aPgAlignArea.Height() )
504         {
505             nAdjustedRelPosY = aPgAlignArea.Top() + aPgAlignArea.Height() -
506                                nTopOfAnch -
507                                aObjSize.Height();
508         }
509         if ( nTopOfAnch + nAdjustedRelPosY < aPgAlignArea.Top() )
510         {
511             nAdjustedRelPosY = aPgAlignArea.Top() - nTopOfAnch;
512         }
513     }
514 
515     return nAdjustedRelPosY;
516 }
517 
518 /** adjust calculated horizontal in order to keep object inside
519     'page' alignment layout frame.
520 
521     OD 2006-03-15 #i62875# - method now private and renamed.
522 
523     @author OD
524 */
525 SwTwips SwAnchoredObjectPosition::_ImplAdjustHoriRelPos(
526                                         const SwFrm&  _rPageAlignLayFrm,
527                                         const SwTwips _nProposedRelPosX ) const
528 {
529     SwTwips nAdjustedRelPosX = _nProposedRelPosX;
530 
531     const SwFrm& rAnchorFrm = GetAnchorFrm();
532     const bool bVert = rAnchorFrm.IsVertical();
533 
534     const Size aObjSize( GetAnchoredObj().GetObjRect().SSize() );
535 
536     if( bVert )
537     {
538         if ( rAnchorFrm.Frm().Top() + nAdjustedRelPosX + aObjSize.Height() >
539                 _rPageAlignLayFrm.Frm().Bottom() )
540         {
541             nAdjustedRelPosX = _rPageAlignLayFrm.Frm().Bottom() -
542                                rAnchorFrm.Frm().Top() -
543                                aObjSize.Height();
544         }
545         if ( rAnchorFrm.Frm().Top() + nAdjustedRelPosX <
546                 _rPageAlignLayFrm.Frm().Top() )
547         {
548             nAdjustedRelPosX = _rPageAlignLayFrm.Frm().Top() -
549                                rAnchorFrm.Frm().Top();
550         }
551     }
552     else
553     {
554         if ( rAnchorFrm.Frm().Left() + nAdjustedRelPosX + aObjSize.Width() >
555                 _rPageAlignLayFrm.Frm().Right() )
556         {
557             nAdjustedRelPosX = _rPageAlignLayFrm.Frm().Right() -
558                                rAnchorFrm.Frm().Left() -
559                                aObjSize.Width();
560         }
561         if ( rAnchorFrm.Frm().Left() + nAdjustedRelPosX <
562                 _rPageAlignLayFrm.Frm().Left() )
563         {
564             nAdjustedRelPosX = _rPageAlignLayFrm.Frm().Left() -
565                                rAnchorFrm.Frm().Left();
566         }
567     }
568 
569     return nAdjustedRelPosX;
570 }
571 
572 /** determine alignment value for horizontal position of object
573 
574     @author OD
575 */
576 void SwAnchoredObjectPosition::_GetHoriAlignmentValues( const SwFrm&  _rHoriOrientFrm,
577                                                         const SwFrm&  _rPageAlignLayFrm,
578                                                         const sal_Int16 _eRelOrient,
579                                                         const bool    _bObjWrapThrough,
580                                                         SwTwips&      _orAlignAreaWidth,
581                                                         SwTwips&      _orAlignAreaOffset,
582                                                         bool&         _obAlignedRelToPage ) const
583 {
584     SwTwips nWidth = 0;
585     SwTwips nOffset = 0;
586     SWRECTFN( (&_rHoriOrientFrm) )
587     switch ( _eRelOrient )
588     {
589         case text::RelOrientation::PRINT_AREA:
590         {
591             nWidth = (_rHoriOrientFrm.Prt().*fnRect->fnGetWidth)();
592             nOffset = (_rHoriOrientFrm.*fnRect->fnGetLeftMargin)();
593             if ( _rHoriOrientFrm.IsTxtFrm() )
594             {
595                 // consider movement of text frame left
596                 nOffset += static_cast<const SwTxtFrm&>(_rHoriOrientFrm).GetBaseOfstForFly( !_bObjWrapThrough );
597             }
598             else if ( _rHoriOrientFrm.IsPageFrm() && bVert )
599             {
600                 // for to-page anchored objects, consider header/footer frame
601                 // in vertical layout
602                 const SwFrm* pPrtFrm =
603                         static_cast<const SwPageFrm&>(_rHoriOrientFrm).Lower();
604                 while( pPrtFrm )
605                 {
606                     if( pPrtFrm->IsHeaderFrm() )
607                     {
608                         nWidth -= pPrtFrm->Frm().Height();
609                         nOffset += pPrtFrm->Frm().Height();
610                     }
611                     else if( pPrtFrm->IsFooterFrm() )
612                     {
613                         nWidth -= pPrtFrm->Frm().Height();
614                     }
615                     pPrtFrm = pPrtFrm->GetNext();
616                 }
617             }
618             break;
619         }
620         case text::RelOrientation::PAGE_LEFT:
621         {
622             // align at left border of page frame/fly frame/cell frame
623             nWidth = (_rPageAlignLayFrm.*fnRect->fnGetLeftMargin)();
624             nOffset = (*fnRect->fnXDiff)(
625                       (_rPageAlignLayFrm.Frm().*fnRect->fnGetLeft)(),
626                       (_rHoriOrientFrm.Frm().*fnRect->fnGetLeft)() );
627             _obAlignedRelToPage = true;
628         }
629         break;
630         case text::RelOrientation::PAGE_RIGHT:
631         {
632             // align at right border of page frame/fly frame/cell frame
633             nWidth = (_rPageAlignLayFrm.*fnRect->fnGetRightMargin)();
634             nOffset = (*fnRect->fnXDiff)(
635                       (_rPageAlignLayFrm.*fnRect->fnGetPrtRight)(),
636                       (_rHoriOrientFrm.Frm().*fnRect->fnGetLeft)() );
637             _obAlignedRelToPage = true;
638         }
639         break;
640         case text::RelOrientation::FRAME_LEFT:
641         {
642             // align at left border of anchor frame
643             nWidth = (_rHoriOrientFrm.*fnRect->fnGetLeftMargin)();
644             nOffset = 0;
645         }
646         break;
647         case text::RelOrientation::FRAME_RIGHT:
648         {
649             // align at right border of anchor frame
650             // OD 19.08.2003 #110978# - unify and simplify
651             nWidth = (_rHoriOrientFrm.*fnRect->fnGetRightMargin)();
652             //nOffset = (_rHoriOrientFrm.Frm().*fnRect->fnGetWidth)() -
653             //          nWidth;
654             nOffset = (_rHoriOrientFrm.Prt().*fnRect->fnGetRight)();
655         }
656         break;
657         case text::RelOrientation::CHAR:
658         {
659             // alignment relative to character - assure, that corresponding
660             // character rectangle is set.
661             if ( IsAnchoredToChar() )
662             {
663                 nWidth = 0;
664                 nOffset = (*fnRect->fnXDiff)(
665                             (ToCharRect()->*fnRect->fnGetLeft)(),
666                             (ToCharOrientFrm()->Frm().*fnRect->fnGetLeft)() );
667                 break;
668             }
669             // no break!
670         }
671         case text::RelOrientation::PAGE_PRINT_AREA:
672         {
673             nWidth = (_rPageAlignLayFrm.Prt().*fnRect->fnGetWidth)();
674             nOffset = (*fnRect->fnXDiff)(
675                         (_rPageAlignLayFrm.*fnRect->fnGetPrtLeft)(),
676                         (_rHoriOrientFrm.Frm().*fnRect->fnGetLeft)() );
677             if ( _rHoriOrientFrm.IsPageFrm() && bVert )
678             {
679                 // for to-page anchored objects, consider header/footer frame
680                 // in vertical layout
681                 const SwFrm* pPrtFrm =
682                         static_cast<const SwPageFrm&>(_rHoriOrientFrm).Lower();
683                 while( pPrtFrm )
684                 {
685                     if( pPrtFrm->IsHeaderFrm() )
686                     {
687                         nWidth -= pPrtFrm->Frm().Height();
688                         nOffset += pPrtFrm->Frm().Height();
689                     }
690                     else if( pPrtFrm->IsFooterFrm() )
691                     {
692                         nWidth -= pPrtFrm->Frm().Height();
693                     }
694                     pPrtFrm = pPrtFrm->GetNext();
695                 }
696             }
697             _obAlignedRelToPage = true;
698             break;
699         }
700         case text::RelOrientation::PAGE_FRAME:
701         {
702             nWidth = (_rPageAlignLayFrm.Frm().*fnRect->fnGetWidth)();
703             nOffset = (*fnRect->fnXDiff)(
704                         (_rPageAlignLayFrm.Frm().*fnRect->fnGetLeft)(),
705                         (_rHoriOrientFrm.Frm().*fnRect->fnGetLeft)() );
706             _obAlignedRelToPage = true;
707             break;
708         }
709         default:
710         // case text::RelOrientation::FRAME:
711         {
712             nWidth = (_rHoriOrientFrm.Frm().*fnRect->fnGetWidth)();
713             nOffset = _rHoriOrientFrm.IsTxtFrm() ?
714                    static_cast<const SwTxtFrm&>(_rHoriOrientFrm).GetBaseOfstForFly( !_bObjWrapThrough ) :
715                    0;
716             break;
717         }
718     }
719 
720     _orAlignAreaWidth = nWidth;
721     _orAlignAreaOffset = nOffset;
722 }
723 
724 /** toggle given horizontal orientation and relative alignment
725 
726     @author OD
727 */
728 void SwAnchoredObjectPosition::_ToggleHoriOrientAndAlign(
729                                         const bool _bToggleLeftRight,
730                                         sal_Int16& _ioeHoriOrient,
731                                         sal_Int16& _iopeRelOrient
732                                       ) const
733 {
734     if( _bToggleLeftRight )
735     {
736         // toggle orientation
737         switch ( _ioeHoriOrient )
738         {
739             case text::HoriOrientation::RIGHT :
740                 {
741                     _ioeHoriOrient = text::HoriOrientation::LEFT;
742                 }
743                 break;
744             case text::HoriOrientation::LEFT :
745                 {
746                     _ioeHoriOrient = text::HoriOrientation::RIGHT;
747                 }
748                 break;
749             default:
750                 break;
751         }
752 
753         // toggle relative alignment
754         switch ( _iopeRelOrient )
755         {
756             case text::RelOrientation::PAGE_RIGHT :
757                 {
758                     _iopeRelOrient = text::RelOrientation::PAGE_LEFT;
759                 }
760                 break;
761             case text::RelOrientation::PAGE_LEFT :
762                 {
763                     _iopeRelOrient = text::RelOrientation::PAGE_RIGHT;
764                 }
765                 break;
766             case text::RelOrientation::FRAME_RIGHT :
767                 {
768                     _iopeRelOrient = text::RelOrientation::FRAME_LEFT;
769                 }
770                 break;
771             case text::RelOrientation::FRAME_LEFT :
772                 {
773                     _iopeRelOrient = text::RelOrientation::FRAME_RIGHT;
774                 }
775                 break;
776             default:
777                 break;
778         }
779     }
780 }
781 
782 /** calculate relative horizontal position
783 
784     @author OD
785 */
786 SwTwips SwAnchoredObjectPosition::_CalcRelPosX(
787                                 const SwFrm& _rHoriOrientFrm,
788                                 const SwEnvironmentOfAnchoredObject& _rEnvOfObj,
789                                 const SwFmtHoriOrient& _rHoriOrient,
790                                 const SvxLRSpaceItem& _rLRSpacing,
791                                 const SvxULSpaceItem& _rULSpacing,
792                                 const bool _bObjWrapThrough,
793                                 const SwTwips _nRelPosY,
794                                 SwTwips& _roHoriOffsetToFrmAnchorPos
795                               ) const
796 {
797     // determine 'page' alignment layout frame
798     const SwFrm& rPageAlignLayFrm =
799             _rEnvOfObj.GetHoriEnvironmentLayoutFrm( _rHoriOrientFrm );
800 
801     const bool bEvenPage = !rPageAlignLayFrm.OnRightPage();
802     const bool bToggle = _rHoriOrient.IsPosToggle() && bEvenPage;
803 
804     // determine orientation and relative alignment
805     sal_Int16 eHoriOrient = _rHoriOrient.GetHoriOrient();
806     sal_Int16 eRelOrient = _rHoriOrient.GetRelationOrient();
807     // toggle orientation and relative alignment
808     _ToggleHoriOrientAndAlign( bToggle, eHoriOrient, eRelOrient );
809 
810     // determine alignment parameter
811     // <nWidth>:  'width' of alignment area
812     // <nOffset>: offset of alignment area, relative to 'left' of anchor frame
813     SwTwips nWidth = 0;
814     SwTwips nOffset = 0;
815     bool bAlignedRelToPage = false;
816     _GetHoriAlignmentValues( _rHoriOrientFrm, rPageAlignLayFrm,
817                              eRelOrient, _bObjWrapThrough,
818                              nWidth, nOffset, bAlignedRelToPage );
819 
820     const SwFrm& rAnchorFrm = GetAnchorFrm();
821     SWRECTFN( (&_rHoriOrientFrm) )
822     SwTwips nObjWidth = (GetAnchoredObj().GetObjRect().*fnRect->fnGetWidth)();
823     SwTwips nRelPosX = nOffset;
824     if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE )
825     {
826         // 'manual' horizonal position
827         const bool bR2L = rAnchorFrm.IsRightToLeft();
828         if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient )
829         {
830             if( bR2L )
831                 nRelPosX -= _rHoriOrient.GetPos();
832             else
833                 nRelPosX += _rHoriOrient.GetPos();
834         }
835         else if ( bToggle || ( !_rHoriOrient.IsPosToggle() && bR2L ) )
836         {
837             // OD 04.08.2003 #110978# - correction: consider <nOffset> also for
838             // toggling from left to right.
839             nRelPosX += nWidth - nObjWidth - _rHoriOrient.GetPos();
840         }
841         else
842         {
843             nRelPosX += _rHoriOrient.GetPos();
844         }
845     }
846     else if ( text::HoriOrientation::CENTER == eHoriOrient )
847         nRelPosX += (nWidth / 2) - (nObjWidth / 2);
848     else if ( text::HoriOrientation::RIGHT == eHoriOrient )
849         nRelPosX += nWidth -
850                     ( nObjWidth +
851                       ( bVert ? _rULSpacing.GetLower() : _rLRSpacing.GetRight() ) );
852     else
853         nRelPosX += bVert ? _rULSpacing.GetUpper() : _rLRSpacing.GetLeft();
854 
855     // adjust relative position by distance between anchor frame and
856     // the frame, the object is oriented at.
857     if ( &rAnchorFrm != &_rHoriOrientFrm )
858     {
859         SwTwips nLeftOrient = (_rHoriOrientFrm.Frm().*fnRect->fnGetLeft)();
860         SwTwips nLeftAnchor = (rAnchorFrm.Frm().*fnRect->fnGetLeft)();
861         nRelPosX += (*fnRect->fnXDiff)( nLeftOrient, nLeftAnchor );
862     }
863 
864     // OD 2004-05-21 #i28701# - deactivate follow code
865 //    // adjust relative horizontal position, if object is manual horizontal
866 //    // positioned (not 'page' aligned) and orients not at the anchor frame,
867 //    // but it overlaps anchor frame.
868 //    if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE && !bAlignedRelToPage &&
869 //         &rAnchorFrm != &_rHoriOrientFrm )
870 //    {
871 //        // E.g.: consider a columned page/section with an horizontal
872 //        //       negative positioned object.
873 //        // OD 2004-03-23 #i26791#
874 //        const SwRect& rObjRect = GetAnchoredObj().GetObjRect();
875 //        if( bVert )
876 //        {
877 //            if( _rHoriOrientFrm.Frm().Top() > rAnchorFrm.Frm().Bottom() &&
878 //                rObjRect.Right() > rAnchorFrm.Frm().Left() )
879 //            {
880 //                const SwTwips nProposedPosX = nRelPosX + rAnchorFrm.Frm().Top();
881 //                if ( nProposedPosX < rAnchorFrm.Frm().Bottom() )
882 //                    nRelPosX = rAnchorFrm.Frm().Height() + 1;
883 //            }
884 //        }
885 //        else
886 //        {
887 //            if( _rHoriOrientFrm.Frm().Left() > rAnchorFrm.Frm().Right() &&
888 //                rObjRect.Top() < rAnchorFrm.Frm().Bottom() )
889 //            {
890 //                // OD 04.08.2003 #110978# - correction: use <nRelPosX>
891 //                // instead of <aRelPos.X()>
892 //                const SwTwips nProposedPosX = nRelPosX + rAnchorFrm.Frm().Left();
893 //                if ( nProposedPosX < rAnchorFrm.Frm().Right() )
894 //                    nRelPosX = rAnchorFrm.Frm().Width() + 1;
895 //            }
896 //        }
897 //    }
898     // adjust calculated relative horizontal position, in order to
899     // keep object inside 'page' alignment layout frame
900     const SwFrm& rEnvironmentLayFrm =
901             _rEnvOfObj.GetHoriEnvironmentLayoutFrm( _rHoriOrientFrm );
902     nRelPosX = _AdjustHoriRelPos( rEnvironmentLayFrm, nRelPosX );
903 
904     // if object is a Writer fly frame and it's anchored to a content and
905     // it is horizontal positioned left or right, but not relative to character,
906     // it has to be drawn aside another object, which have the same horizontal
907     // position and lay below it.
908     if ( GetAnchoredObj().ISA(SwFlyFrm) &&
909          ( GetContact().ObjAnchoredAtPara() || GetContact().ObjAnchoredAtChar() ) &&
910          ( eHoriOrient == text::HoriOrientation::LEFT || eHoriOrient == text::HoriOrientation::RIGHT ) &&
911          eRelOrient != text::RelOrientation::CHAR )
912     {
913         nRelPosX = _AdjustHoriRelPosForDrawAside( _rHoriOrientFrm,
914                                                   nRelPosX, _nRelPosY,
915                                                   eHoriOrient, eRelOrient,
916                                                   _rLRSpacing, _rULSpacing,
917                                                   bEvenPage );
918     }
919 
920     // --> OD 2004-06-17 #i26791#
921     _roHoriOffsetToFrmAnchorPos = nOffset;
922 
923     return nRelPosX;
924 }
925 
926 // **************************************************************************
927 // method incl. helper methods for adjusting proposed horizontal position,
928 // if object has to draw aside another object.
929 // **************************************************************************
930 /** adjust calculated horizontal position in order to draw object
931     aside other objects with same positioning
932 
933     @author OD
934 */
935 SwTwips SwAnchoredObjectPosition::_AdjustHoriRelPosForDrawAside(
936                                             const SwFrm&  _rHoriOrientFrm,
937                                             const SwTwips _nProposedRelPosX,
938                                             const SwTwips _nRelPosY,
939                                             const sal_Int16 _eHoriOrient,
940                                             const sal_Int16 _eRelOrient,
941                                             const SvxLRSpaceItem& _rLRSpacing,
942                                             const SvxULSpaceItem& _rULSpacing,
943                                             const bool _bEvenPage
944                                           ) const
945 {
946     // OD 2004-03-23 #i26791#
947     if ( !GetAnchorFrm().ISA(SwTxtFrm) ||
948          !GetAnchoredObj().ISA(SwFlyAtCntFrm) )
949     {
950         ASSERT( false,
951                 "<SwAnchoredObjectPosition::_AdjustHoriRelPosForDrawAside(..) - usage for wrong anchor type" );
952         return _nProposedRelPosX;
953     }
954 
955     const SwTxtFrm& rAnchorTxtFrm = static_cast<const SwTxtFrm&>(GetAnchorFrm());
956     // OD 2004-03-23 #i26791#
957     const SwFlyAtCntFrm& rFlyAtCntFrm =
958                         static_cast<const SwFlyAtCntFrm&>(GetAnchoredObj());
959     const SwRect aObjBoundRect( GetAnchoredObj().GetObjRect() );
960     SWRECTFN( (&_rHoriOrientFrm) )
961 
962     SwTwips nAdjustedRelPosX = _nProposedRelPosX;
963 
964     // determine proposed object bound rectangle
965     Point aTmpPos = (rAnchorTxtFrm.Frm().*fnRect->fnGetPos)();
966     if( bVert )
967     {
968         aTmpPos.X() -= _nRelPosY + aObjBoundRect.Width();
969         aTmpPos.Y() += nAdjustedRelPosX;
970     }
971     else
972     {
973         aTmpPos.X() += nAdjustedRelPosX;
974         aTmpPos.Y() += _nRelPosY;
975     }
976     SwRect aTmpObjRect( aTmpPos, aObjBoundRect.SSize() );
977 
978     const sal_uInt32 nObjOrdNum = GetObject().GetOrdNum();
979     const SwPageFrm* pObjPage = rFlyAtCntFrm.FindPageFrm();
980     const SwFrm* pObjContext = ::FindKontext( &rAnchorTxtFrm, FRM_COLUMN );
981     sal_uLong nObjIndex = rAnchorTxtFrm.GetTxtNode()->GetIndex();
982     SwOrderIter aIter( pObjPage, sal_True );
983     const SwFlyFrm* pFly = ((SwVirtFlyDrawObj*)aIter.Bottom())->GetFlyFrm();
984     while ( pFly && nObjOrdNum > pFly->GetVirtDrawObj()->GetOrdNumDirect() )
985     {
986         if ( _DrawAsideFly( pFly, aTmpObjRect, pObjContext, nObjIndex,
987                            _bEvenPage, _eHoriOrient, _eRelOrient ) )
988         {
989             if( bVert )
990             {
991                 const SvxULSpaceItem& rOtherUL = pFly->GetFmt()->GetULSpace();
992                 const SwTwips nOtherTop = pFly->Frm().Top() - rOtherUL.GetUpper();
993                 const SwTwips nOtherBot = pFly->Frm().Bottom() + rOtherUL.GetLower();
994                 if ( nOtherTop <= aTmpObjRect.Bottom() + _rULSpacing.GetLower() &&
995                      nOtherBot >= aTmpObjRect.Top() - _rULSpacing.GetUpper() )
996                 {
997                     if ( _eHoriOrient == text::HoriOrientation::LEFT )
998                     {
999                         SwTwips nTmp = nOtherBot + 1 + _rULSpacing.GetUpper() -
1000                                        rAnchorTxtFrm.Frm().Top();
1001                         if ( nTmp > nAdjustedRelPosX &&
1002                              rAnchorTxtFrm.Frm().Top() + nTmp +
1003                              aObjBoundRect.Height() + _rULSpacing.GetLower()
1004                              <= pObjPage->Frm().Height() + pObjPage->Frm().Top() )
1005                         {
1006                             nAdjustedRelPosX = nTmp;
1007                         }
1008                     }
1009                     else if ( _eHoriOrient == text::HoriOrientation::RIGHT )
1010                     {
1011                         SwTwips nTmp = nOtherTop - 1 - _rULSpacing.GetLower() -
1012                                        aObjBoundRect.Height() -
1013                                        rAnchorTxtFrm.Frm().Top();
1014                         if ( nTmp < nAdjustedRelPosX &&
1015                              rAnchorTxtFrm.Frm().Top() + nTmp - _rULSpacing.GetUpper()
1016                               >= pObjPage->Frm().Top() )
1017                         {
1018                             nAdjustedRelPosX = nTmp;
1019                         }
1020                     }
1021                     aTmpObjRect.Pos().Y() = rAnchorTxtFrm.Frm().Top() +
1022                                             nAdjustedRelPosX;
1023                 }
1024             }
1025             else
1026             {
1027                 const SvxLRSpaceItem& rOtherLR = pFly->GetFmt()->GetLRSpace();
1028                 const SwTwips nOtherLeft = pFly->Frm().Left() - rOtherLR.GetLeft();
1029                 const SwTwips nOtherRight = pFly->Frm().Right() + rOtherLR.GetRight();
1030                 if( nOtherLeft <= aTmpObjRect.Right() + _rLRSpacing.GetRight() &&
1031                     nOtherRight >= aTmpObjRect.Left() - _rLRSpacing.GetLeft() )
1032                 {
1033                     if ( _eHoriOrient == text::HoriOrientation::LEFT )
1034                     {
1035                         SwTwips nTmp = nOtherRight + 1 + _rLRSpacing.GetLeft() -
1036                                        rAnchorTxtFrm.Frm().Left();
1037                         if ( nTmp > nAdjustedRelPosX &&
1038                              rAnchorTxtFrm.Frm().Left() + nTmp +
1039                              aObjBoundRect.Width() + _rLRSpacing.GetRight()
1040                              <= pObjPage->Frm().Width() + pObjPage->Frm().Left() )
1041                         {
1042                             nAdjustedRelPosX = nTmp;
1043                         }
1044                     }
1045                     else if ( _eHoriOrient == text::HoriOrientation::RIGHT )
1046                     {
1047                         SwTwips nTmp = nOtherLeft - 1 - _rLRSpacing.GetRight() -
1048                                        aObjBoundRect.Width() -
1049                                        rAnchorTxtFrm.Frm().Left();
1050                         if ( nTmp < nAdjustedRelPosX &&
1051                              rAnchorTxtFrm.Frm().Left() + nTmp - _rLRSpacing.GetLeft()
1052                              >= pObjPage->Frm().Left() )
1053                         {
1054                             nAdjustedRelPosX = nTmp;
1055                         }
1056                     }
1057                     aTmpObjRect.Pos().X() = rAnchorTxtFrm.Frm().Left() +
1058                                             nAdjustedRelPosX;
1059                 }
1060             } // end of <if (bVert)>
1061         } // end of <if _DrawAsideFly(..)>
1062 
1063         pFly = ((SwVirtFlyDrawObj*)aIter.Next())->GetFlyFrm();
1064     } // end of <loop on fly frames
1065 
1066     return nAdjustedRelPosX;
1067 }
1068 
1069 /** detemine, if object has to draw aside given fly frame
1070 
1071     method used by <_AdjustHoriRelPosForDrawAside(..)>
1072 
1073     @author OD
1074 */
1075 bool SwAnchoredObjectPosition::_DrawAsideFly( const SwFlyFrm* _pFly,
1076                                               const SwRect&   _rObjRect,
1077                                               const SwFrm*    _pObjContext,
1078                                               const sal_uLong     _nObjIndex,
1079                                               const bool      _bEvenPage,
1080                                               const sal_Int16 _eHoriOrient,
1081                                               const sal_Int16 _eRelOrient
1082                                             ) const
1083 {
1084     bool bRetVal = false;
1085 
1086     SWRECTFN( (&GetAnchorFrm()) )
1087 
1088     if ( _pFly->IsFlyAtCntFrm() &&
1089          (_pFly->Frm().*fnRect->fnBottomDist)( (_rObjRect.*fnRect->fnGetTop)() ) < 0 &&
1090          (_rObjRect.*fnRect->fnBottomDist)( (_pFly->Frm().*fnRect->fnGetTop)() ) < 0 &&
1091          ::FindKontext( _pFly->GetAnchorFrm(), FRM_COLUMN ) == _pObjContext )
1092     {
1093         sal_uLong nOtherIndex =
1094             static_cast<const SwTxtFrm*>(_pFly->GetAnchorFrm())->GetTxtNode()->GetIndex();
1095         if( _nObjIndex >= nOtherIndex )
1096         {
1097             const SwFmtHoriOrient& rHori = _pFly->GetFmt()->GetHoriOrient();
1098             sal_Int16 eOtherRelOrient = rHori.GetRelationOrient();
1099             if( text::RelOrientation::CHAR != eOtherRelOrient )
1100             {
1101                 sal_Int16 eOtherHoriOrient = rHori.GetHoriOrient();
1102                 _ToggleHoriOrientAndAlign( _bEvenPage && rHori.IsPosToggle(),
1103                                            eOtherHoriOrient,
1104                                            eOtherRelOrient );
1105                 if ( eOtherHoriOrient == _eHoriOrient &&
1106                     _Minor( _eRelOrient, eOtherRelOrient, text::HoriOrientation::LEFT == _eHoriOrient ) )
1107                 {
1108                     bRetVal = true;
1109                 }
1110             }
1111         }
1112     }
1113 
1114     return bRetVal;
1115 }
1116 
1117 /** determine, if object has to draw aside another object
1118 
1119     the different alignments of the objects determines, if one has
1120     to draw aside another one. Thus, the given alignment are checked
1121     against each other, which one has to be drawn aside the other one.
1122     depending on parameter _bLeft check is done for left or right
1123     positioning.
1124     method used by <_DrawAsideFly(..)>
1125 
1126     @author OD
1127 */
1128 bool SwAnchoredObjectPosition::_Minor( sal_Int16 _eRelOrient1,
1129                                        sal_Int16 _eRelOrient2,
1130                                        bool             _bLeft ) const
1131 {
1132     bool bRetVal;
1133 
1134     // draw aside order for left horizontal position
1135     //! one array entry for each value in text::RelOrientation
1136     static sal_uInt16 __READONLY_DATA aLeft[ 10 ] =
1137         { 5, 6, 0, 1, 8, 4, 7, 2, 3, 9 };
1138     // draw aside order for right horizontal position
1139     //! one array entry for each value in text::RelOrientation
1140     static sal_uInt16 __READONLY_DATA aRight[ 10 ] =
1141         { 5, 6, 0, 8, 1, 7, 4, 2, 3, 9 };
1142 
1143     // decide depending on given order, which frame has to draw aside another frame
1144     if( _bLeft )
1145         bRetVal = aLeft[ _eRelOrient1 ] >= aLeft[ _eRelOrient2 ];
1146     else
1147         bRetVal = aRight[ _eRelOrient1 ] >= aRight[ _eRelOrient2 ];
1148 
1149     return bRetVal;
1150 }
1151