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