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