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