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