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