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