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