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