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 : #ifndef _FRMTOOL_HXX
21 : #define _FRMTOOL_HXX
22 :
23 : #include "swtypes.hxx"
24 : #include "layfrm.hxx"
25 : #include "frmatr.hxx"
26 : #include "swcache.hxx"
27 : // #i96772#
28 : #include <editeng/lrspitem.hxx>
29 :
30 : class SwPageFrm;
31 : class SwFlyFrm;
32 : class SwCntntFrm;
33 : class SwRootFrm;
34 : class SwDoc;
35 : class SwAttrSet;
36 : class SdrObject;
37 : class BigInt;
38 : class SvxBrushItem;
39 : class SdrMarkList;
40 : class SwNodeIndex;
41 : class OutputDevice;
42 : class SwPageDesc;
43 :
44 : #define FAR_AWAY LONG_MAX - 20000 // initial position of a Fly
45 : #define BROWSE_HEIGHT 56700L * 10L // 10 Meters
46 : #define GRFNUM_NO 0
47 : #define GRFNUM_YES 1
48 : #define GRFNUM_REPLACE 2
49 :
50 : // draw background with brush or graphics
51 : // The 6th parameter indicates that the method should consider background
52 : // transparency, saved in the color of the brush item.
53 : void DrawGraphic( const SvxBrushItem *, OutputDevice *,
54 : const SwRect &rOrg, const SwRect &rOut, const sal_uInt8 nGrfNum = GRFNUM_NO,
55 : const sal_Bool bConsiderBackgroundTransparency = sal_False );
56 :
57 : // method to align rectangle.
58 : // Created declaration here to avoid <extern> declarations
59 : void SwAlignRect( SwRect &rRect, const ViewShell *pSh );
60 :
61 : // method to align graphic rectangle
62 : // Created declaration here to avoid <extern> declarations
63 : void SwAlignGrfRect( SwRect *pGrfRect, const OutputDevice &rOut );
64 :
65 : // get Fly, if no List is given use the current shell
66 : // Implementation in feshview.cxx
67 : SwFlyFrm *GetFlyFromMarked( const SdrMarkList *pLst, ViewShell *pSh );
68 :
69 : sal_uLong SqRt( BigInt nX );
70 :
71 : SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart );
72 : void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow );
73 :
74 : // Get CntntNodes, create CntntFrms, and add them to LayFrm.
75 : void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc, sal_uLong nIndex,
76 : sal_Bool bPages = sal_False, sal_uLong nEndIndex = 0,
77 : SwFrm *pPrv = 0 );
78 :
79 : // Creation of frames for a specific section (uses _InsertCnt)
80 : void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
81 : const SwNodeIndex &rEndIdx );
82 :
83 : // prevent creation of Flys in _InsertCnt, e.g. for table headlines
84 : extern bool bDontCreateObjects;
85 :
86 : // for FlyCnts, see SwFlyAtCntFrm::MakeAll()
87 : extern bool bSetCompletePaintOnInvalidate;
88 :
89 : // for table settings via keyboard
90 : long CalcRowRstHeight( SwLayoutFrm *pRow );
91 : long CalcHeightWidthFlys( const SwFrm *pFrm );
92 :
93 : SwPageFrm *InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
94 : bool bOdd, bool bFirst, bool bInsertEmpty, sal_Bool bFtn,
95 : SwFrm *pSibling );
96 :
97 : // connect Flys with page
98 : void RegistFlys( SwPageFrm*, const SwLayoutFrm* );
99 :
100 : // notification of Fly's background if needed
101 : void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
102 : const SwRect* pOldRect = 0 );
103 :
104 : void Notify_Background( const SdrObject* pObj,
105 : SwPageFrm* pPage,
106 : const SwRect& rRect,
107 : const PrepareHint eHint,
108 : const sal_Bool bInva );
109 :
110 : const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos );
111 :
112 : bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj );
113 :
114 : // FIXME: EasyHack (refactoring): rename method and parameter name in all files
115 : const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp );
116 :
117 : bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm );
118 :
119 : const SwFrm * FindPage( const SwRect &rRect, const SwFrm *pPage );
120 :
121 : // used by SwCntntNode::GetFrm and SwFlyFrm::GetFrm
122 : SwFrm* GetFrmOfModify( const SwRootFrm* pLayout,
123 : SwModify const&,
124 : sal_uInt16 const nFrmType,
125 : const Point* = 0,
126 : const SwPosition *pPos = 0,
127 : const sal_Bool bCalcFrm = sal_False );
128 :
129 : // Should extra data (reline stroke, line numbers) be painted?
130 : bool IsExtraData( const SwDoc *pDoc );
131 :
132 : // #i11760# - method declaration <CalcCntnt(..)>
133 : void CalcCntnt( SwLayoutFrm *pLay,
134 : bool bNoColl = false,
135 : bool bNoCalcFollow = false );
136 :
137 : // Notify classes memorize the current sizes in their constructor and do
138 : // the necessary notifications in their destructor if needed
139 : class SwFrmNotify
140 : {
141 : protected:
142 : SwFrm *pFrm;
143 : const SwRect aFrm;
144 : const SwRect aPrt;
145 : SwTwips mnFlyAnchorOfst;
146 : SwTwips mnFlyAnchorOfstNoWrap;
147 : sal_Bool bHadFollow;
148 : sal_Bool bInvaKeep;
149 : sal_Bool bValidSize;
150 : // #i49383#
151 : bool mbFrmDeleted;
152 :
153 : public:
154 : SwFrmNotify( SwFrm *pFrm );
155 : ~SwFrmNotify();
156 :
157 308 : const SwRect &Frm() const { return aFrm; }
158 : const SwRect &Prt() const { return aPrt; }
159 123 : void SetInvaKeep() { bInvaKeep = sal_True; }
160 : // #i49383#
161 : void FrmDeleted()
162 : {
163 : mbFrmDeleted = true;
164 : }
165 : };
166 :
167 : class SwLayNotify : public SwFrmNotify
168 : {
169 : sal_Bool bLowersComplete;
170 :
171 2779 : SwLayoutFrm *GetLay() { return (SwLayoutFrm*)pFrm; }
172 :
173 : public:
174 : SwLayNotify( SwLayoutFrm *pLayFrm );
175 : ~SwLayNotify();
176 :
177 72 : void SetLowersComplete( sal_Bool b ) { bLowersComplete = b; }
178 5019 : sal_Bool IsLowersComplete() { return bLowersComplete; }
179 : };
180 :
181 : class SwFlyNotify : public SwLayNotify
182 : {
183 : SwPageFrm *pOldPage;
184 : const SwRect aFrmAndSpace;
185 831 : SwFlyFrm *GetFly() { return (SwFlyFrm*)pFrm; }
186 :
187 : public:
188 : SwFlyNotify( SwFlyFrm *pFlyFrm );
189 : ~SwFlyNotify();
190 :
191 : SwPageFrm *GetOldPage() const { return pOldPage; }
192 : };
193 :
194 : class SwCntntNotify : public SwFrmNotify
195 : {
196 : private:
197 : // #i11859#
198 : bool mbChkHeightOfLastLine;
199 : SwTwips mnHeightOfLastLine;
200 :
201 : // #i25029#
202 : bool mbInvalidatePrevPrtArea;
203 : bool mbBordersJoinedWithPrev;
204 :
205 1287 : SwCntntFrm *GetCnt() { return (SwCntntFrm*)pFrm; }
206 :
207 : public:
208 : SwCntntNotify( SwCntntFrm *pCntFrm );
209 : ~SwCntntNotify();
210 :
211 : // #i25029#
212 2 : void SetInvalidatePrevPrtArea()
213 : {
214 2 : mbInvalidatePrevPrtArea = true;
215 2 : }
216 :
217 185 : void SetBordersJoinedWithPrev()
218 : {
219 185 : mbBordersJoinedWithPrev = true;
220 185 : }
221 : };
222 :
223 : // SwBorderAttrs encapsulates the calculation for margin attributes including
224 : // border. The whole class is cached.
225 : //
226 : // WARNING! If more attributes should be cached also adjust the method
227 : // Modify::Modify!
228 : class SwBorderAttrs : public SwCacheObj
229 : {
230 : const SwAttrSet &rAttrSet;
231 : const SvxULSpaceItem &rUL;
232 : // #i96772#
233 : SvxLRSpaceItem rLR;
234 : const SvxBoxItem &rBox;
235 : const SvxShadowItem &rShadow;
236 : const Size aFrmSize;
237 :
238 : // Is it a frame that can have a margin without a border?
239 : sal_Bool bBorderDist : 1;
240 :
241 : // the following bool values set the cached values to INVALID - until they
242 : // are calculated for the first time
243 : sal_Bool bTopLine : 1;
244 : sal_Bool bBottomLine : 1;
245 : sal_Bool bLeftLine : 1;
246 : sal_Bool bRightLine : 1;
247 : sal_Bool bTop : 1;
248 : sal_Bool bBottom : 1;
249 : sal_Bool bLine : 1;
250 :
251 : sal_Bool bIsLine : 1; // border on at least one side?
252 :
253 : sal_Bool bCacheGetLine : 1; // cache GetTopLine(), GetBottomLine()?
254 : sal_Bool bCachedGetTopLine : 1; // is GetTopLine() cached?
255 : sal_Bool bCachedGetBottomLine : 1; // is GetBottomLine() cached?
256 : // Booleans indicate that <bJoinedWithPrev> and <bJoinedWithNext> are
257 : // cached and valid.
258 : // Caching depends on value of <bCacheGetLine>.
259 : mutable sal_Bool bCachedJoinedWithPrev : 1;
260 : mutable sal_Bool bCachedJoinedWithNext : 1;
261 : // Booleans indicate that borders are joined with previous/next frame.
262 : sal_Bool bJoinedWithPrev :1;
263 : sal_Bool bJoinedWithNext :1;
264 :
265 : // The cached values (un-defined until calculated for the first time)
266 : sal_uInt16 nTopLine,
267 : nBottomLine,
268 : nLeftLine,
269 : nRightLine,
270 : nTop,
271 : nBottom,
272 : nGetTopLine,
273 : nGetBottomLine;
274 :
275 : // only calculate lines and shadow
276 : void _CalcTopLine();
277 : void _CalcBottomLine();
278 : void _CalcLeftLine();
279 : void _CalcRightLine();
280 :
281 : // lines + shadow + margin
282 : void _CalcTop();
283 : void _CalcBottom();
284 :
285 : void _IsLine();
286 :
287 : // #i25029# - If <_pPrevFrm> is set, its value is taken for testing, if
288 : // borders/shadow have to be joined with previous frame.
289 : void _GetTopLine ( const SwFrm& _rFrm,
290 : const SwFrm* _pPrevFrm = 0L );
291 : void _GetBottomLine( const SwFrm& _rFrm );
292 :
293 : // calculate cached values <bJoinedWithPrev> and <bJoinedWithNext>
294 : // #i25029# - If <_pPrevFrm> is set, its value is taken for testing, if
295 : // borders/shadow have to be joined with previous frame.
296 : void _CalcJoinedWithPrev( const SwFrm& _rFrm,
297 : const SwFrm* _pPrevFrm = 0L );
298 : void _CalcJoinedWithNext( const SwFrm& _rFrm );
299 :
300 : // internal helper method for _CalcJoinedWithPrev and _CalcJoinedWithNext
301 : sal_Bool _JoinWithCmp( const SwFrm& _rCallerFrm,
302 : const SwFrm& _rCmpFrm ) const;
303 :
304 : // Are the left and right line and the LRSpace equal?
305 : sal_Bool CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
306 : const SwFrm *pCaller,
307 : const SwFrm *pCmp ) const;
308 :
309 : public:
310 5084 : DECL_FIXEDMEMPOOL_NEWDEL(SwBorderAttrs)
311 :
312 : SwBorderAttrs( const SwModify *pOwner, const SwFrm *pConstructor );
313 : ~SwBorderAttrs();
314 :
315 1701 : inline const SwAttrSet &GetAttrSet() const { return rAttrSet; }
316 5393 : inline const SvxULSpaceItem &GetULSpace() const { return rUL; }
317 : inline const SvxLRSpaceItem &GetLRSpace() const { return rLR; }
318 7779 : inline const SvxBoxItem &GetBox() const { return rBox; }
319 3070 : inline const SvxShadowItem &GetShadow() const { return rShadow; }
320 :
321 : inline sal_uInt16 CalcTopLine() const;
322 : inline sal_uInt16 CalcBottomLine() const;
323 : inline sal_uInt16 CalcLeftLine() const;
324 : inline sal_uInt16 CalcRightLine() const;
325 : inline sal_uInt16 CalcTop() const;
326 : inline sal_uInt16 CalcBottom() const;
327 : long CalcLeft( const SwFrm *pCaller ) const;
328 : long CalcRight( const SwFrm *pCaller ) const;
329 :
330 : inline sal_Bool IsLine() const;
331 :
332 837 : inline const Size &GetSize() const { return aFrmSize; }
333 :
334 2072 : inline sal_Bool IsBorderDist() const { return bBorderDist; }
335 :
336 : // Should upper (or lower) border be evaluated for this frame?
337 : // #i25029# - If <_pPrevFrm> is set, its value is taken for testing, if
338 : // borders/shadow have to be joined with previous frame.
339 : inline sal_uInt16 GetTopLine ( const SwFrm& _rFrm,
340 : const SwFrm* _pPrevFrm = 0L ) const;
341 : inline sal_uInt16 GetBottomLine( const SwFrm& _rFrm ) const;
342 : inline void SetGetCacheLine( sal_Bool bNew ) const;
343 :
344 : // Accessors for cached values <bJoinedWithPrev> and <bJoinedWithPrev>
345 : // #i25029# - If <_pPrevFrm> is set, its value is taken for testing, if
346 : // borders/shadow have to be joined with previous frame.
347 : sal_Bool JoinedWithPrev( const SwFrm& _rFrm,
348 : const SwFrm* _pPrevFrm = 0L ) const;
349 : sal_Bool JoinedWithNext( const SwFrm& _rFrm ) const;
350 : };
351 :
352 12870 : class SwBorderAttrAccess : public SwCacheAccess
353 : {
354 : const SwFrm *pConstructor; //opt: for passing on to SwBorderAttrs
355 :
356 : protected:
357 : virtual SwCacheObj *NewObj();
358 :
359 : public:
360 : SwBorderAttrAccess( SwCache &rCache, const SwFrm *pOwner );
361 :
362 : SwBorderAttrs *Get();
363 : };
364 :
365 : // Iterator for draw objects of a page. The objects will be iterated sorted by
366 : // their Z-order. Iterating is not cheap since for each operation the _whole_
367 : // SortArray needs to be traversed.
368 : class SwOrderIter
369 : {
370 : const SwPageFrm *pPage;
371 : const SdrObject *pCurrent;
372 : const sal_Bool bFlysOnly;
373 :
374 : public:
375 : SwOrderIter( const SwPageFrm *pPage, sal_Bool bFlysOnly = sal_True );
376 :
377 120 : void Current( const SdrObject *pNew ) { pCurrent = pNew; }
378 : const SdrObject *Current() const { return pCurrent; }
379 578 : const SdrObject *operator()() const { return pCurrent; }
380 : const SdrObject *Top();
381 : const SdrObject *Bottom();
382 : const SdrObject *Next();
383 : const SdrObject *Prev();
384 : };
385 :
386 : class StackHack
387 : {
388 : static sal_uInt8 nCnt;
389 : static sal_Bool bLocked;
390 :
391 : public:
392 5183 : StackHack()
393 : {
394 5183 : if ( ++StackHack::nCnt > 50 )
395 0 : StackHack::bLocked = sal_True;
396 5183 : }
397 5183 : ~StackHack()
398 : {
399 5183 : if ( --StackHack::nCnt < 5 )
400 5147 : StackHack::bLocked = sal_False;
401 5183 : }
402 :
403 1870 : static sal_Bool IsLocked() { return StackHack::bLocked; }
404 130 : static sal_uInt8 Count() { return StackHack::nCnt; }
405 : };
406 :
407 : // Should upper (or lower) border be evaluated for this frame?
408 : // #i25029# - If <_pPrevFrm> is set, its value is taken for testing, if
409 : // borders/shadow have to be joined with previous frame.
410 2376 : inline sal_uInt16 SwBorderAttrs::GetTopLine ( const SwFrm& _rFrm,
411 : const SwFrm* _pPrevFrm ) const
412 : {
413 2376 : if ( !bCachedGetTopLine || _pPrevFrm )
414 : {
415 2376 : const_cast<SwBorderAttrs*>(this)->_GetTopLine( _rFrm, _pPrevFrm );
416 : }
417 2376 : return nGetTopLine;
418 : }
419 1886 : inline sal_uInt16 SwBorderAttrs::GetBottomLine( const SwFrm& _rFrm ) const
420 : {
421 1886 : if ( !bCachedGetBottomLine )
422 1886 : const_cast<SwBorderAttrs*>(this)->_GetBottomLine( _rFrm );
423 1886 : return nGetBottomLine;
424 : }
425 20 : inline void SwBorderAttrs::SetGetCacheLine( sal_Bool bNew ) const
426 : {
427 20 : ((SwBorderAttrs*)this)->bCacheGetLine = bNew;
428 : ((SwBorderAttrs*)this)->bCachedGetBottomLine =
429 20 : ((SwBorderAttrs*)this)->bCachedGetTopLine = sal_False;
430 : // invalidate cache for values <bJoinedWithPrev> and <bJoinedWithNext>
431 20 : bCachedJoinedWithPrev = sal_False;
432 20 : bCachedJoinedWithNext = sal_False;
433 20 : }
434 :
435 3464 : inline sal_uInt16 SwBorderAttrs::CalcTopLine() const
436 : {
437 3464 : if ( bTopLine )
438 1561 : ((SwBorderAttrs*)this)->_CalcTopLine();
439 3464 : return nTopLine;
440 : }
441 3128 : inline sal_uInt16 SwBorderAttrs::CalcBottomLine() const
442 : {
443 3128 : if ( bBottomLine )
444 1560 : ((SwBorderAttrs*)this)->_CalcBottomLine();
445 3128 : return nBottomLine;
446 : }
447 4275 : inline sal_uInt16 SwBorderAttrs::CalcLeftLine() const
448 : {
449 4275 : if ( bLeftLine )
450 1210 : ((SwBorderAttrs*)this)->_CalcLeftLine();
451 4275 : return nLeftLine;
452 : }
453 3881 : inline sal_uInt16 SwBorderAttrs::CalcRightLine() const
454 : {
455 3881 : if ( bRightLine )
456 1210 : ((SwBorderAttrs*)this)->_CalcRightLine();
457 3881 : return nRightLine;
458 : }
459 689 : inline sal_uInt16 SwBorderAttrs::CalcTop() const
460 : {
461 689 : if ( bTop )
462 326 : ((SwBorderAttrs*)this)->_CalcTop();
463 689 : return nTop;
464 : }
465 661 : inline sal_uInt16 SwBorderAttrs::CalcBottom() const
466 : {
467 661 : if ( bBottom )
468 326 : ((SwBorderAttrs*)this)->_CalcBottom();
469 661 : return nBottom;
470 : }
471 1527 : inline sal_Bool SwBorderAttrs::IsLine() const
472 : {
473 1527 : if ( bLine )
474 643 : ((SwBorderAttrs*)this)->_IsLine();
475 1527 : return bIsLine;
476 : }
477 :
478 : /** method to determine the spacing values of a frame
479 :
480 : #i28701#
481 : Values only provided for flow frames (table, section or text frames)
482 : Note: line spacing value is only determined for text frames
483 : #i102458#
484 : Add output parameter <obIsLineSpacingProportional>
485 :
486 : @param rFrm
487 : input parameter - frame, for which the spacing values are determined.
488 :
489 : @param onPrevLowerSpacing
490 : output parameter - lower spacing of the frame in SwTwips
491 :
492 : @param onPrevLineSpacing
493 : output parameter - line spacing of the frame in SwTwips
494 :
495 : @param obIsLineSpacingProportional
496 : */
497 : void GetSpacingValuesOfFrm( const SwFrm& rFrm,
498 : SwTwips& onLowerSpacing,
499 : SwTwips& onLineSpacing,
500 : bool& obIsLineSpacingProportional );
501 :
502 : /** method to get the content of the table cell
503 :
504 : Content from any nested tables will be omitted.
505 : Note: line spacing value is only determined for text frames
506 :
507 : @param rCell_
508 : input parameter - the cell which should be searched for content.
509 :
510 : return
511 : pointer to the found content frame or 0
512 : */
513 :
514 : const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell_ );
515 :
516 :
517 : /** helper class to check if a frame has been deleted during an operation
518 : * WARNING! This should only be used as a last and desperate means to make the
519 : * code robust.
520 : */
521 :
522 : class SwDeletionChecker
523 : {
524 : private:
525 : const SwFrm* mpFrm;
526 : const SwModify* mpRegIn;
527 :
528 : public:
529 8 : SwDeletionChecker( const SwFrm* pFrm )
530 : : mpFrm( pFrm ),
531 8 : mpRegIn( pFrm ? const_cast<SwFrm*>(pFrm)->GetRegisteredIn() : 0 )
532 : {
533 8 : }
534 :
535 : /**
536 : * return
537 : * true if mpFrm != 0 and mpFrm is not client of pRegIn
538 : * false otherwise
539 : */
540 : bool HasBeenDeleted();
541 : };
542 :
543 : #endif
544 :
545 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|