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