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 : #ifndef _TXTFLY_HXX
20 : #define _TXTFLY_HXX
21 :
22 : #include "swtypes.hxx"
23 : #include "swrect.hxx"
24 :
25 : class OutputDevice;
26 : class SwCntntFrm;
27 : class SwPageFrm;
28 : class SwTxtFly;
29 : class SdrObject;
30 : class SwTxtPaintInfo;
31 : class SwFmt;
32 : class TextRanger;
33 : class SwAnchoredObject;
34 :
35 : #include <fmtsrndenum.hxx>
36 :
37 : #include <vector>
38 : typedef std::vector< SwAnchoredObject* > SwAnchoredObjList;
39 :
40 : enum PAGESIDE { LEFT_SIDE, RIGHT_SIDE, DONTKNOW_SIDE };
41 :
42 :
43 : class SwDrawTextInfo;
44 : class SwContourCache;
45 : /** Contour-cache global variable, initialized/destroyed in txtinit.cxx
46 : and needed in txtfly.cxx by text wrapping.
47 : */
48 : extern SwContourCache *pContourCache;
49 : class SwTxtFrm;
50 :
51 : #define POLY_CNT 20
52 : #define POLY_MIN 5
53 : #define POLY_MAX 4000
54 :
55 : class SwContourCache
56 : {
57 : friend void ClrContourCache();
58 : const SdrObject *pSdrObj[ POLY_CNT ];
59 : TextRanger *pTextRanger[ POLY_CNT ];
60 : long nPntCnt;
61 : MSHORT nObjCnt;
62 : const SwRect ContourRect( const SwFmt* pFmt, const SdrObject* pObj,
63 : const SwTxtFrm* pFrm, const SwRect &rLine, const long nXPos,
64 : const sal_Bool bRight );
65 :
66 : public:
67 : SwContourCache();
68 : ~SwContourCache();
69 0 : const SdrObject* GetObject( MSHORT nPos ) const{ return pSdrObj[ nPos ]; }
70 0 : MSHORT GetCount() const { return nObjCnt; }
71 : void ClrObject( MSHORT nPos );
72 :
73 : /**
74 : Computes the rectangle that will cover the object in the given line.
75 :
76 : For _non_ contour-flow objects, this is simply the overlap area of
77 : BoundRect (including spacing), and the line, for contour-flow,
78 : the PolyPolygon of the object gets traversed
79 : */
80 : static const SwRect CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
81 : const SwRect &rLine,
82 : const SwTxtFrm* pFrm,
83 : const long nXPos,
84 : const sal_Bool bRight );
85 : };
86 :
87 : /**
88 : The purpose of this class is to be the universal interface between
89 : formatting/text output and the possibly overlapping free-flying frames.
90 : During formatting the formatter gets the information from SwTxtFly, whether
91 : a certain area is present by the attributes of an overlapping frame.
92 : Such areas are represented by dummy portions.
93 :
94 : The whole text output and touch-up is, again, forwarded to a SwTxtFly.
95 : This one decides, whether parts of the text need to be clipped and splits
96 : the areas for e.g. a DrawRect.
97 :
98 : Please note that all free-flying frames are located in a PtrArray, sorted
99 : by TopLeft.
100 :
101 : Internally we always use document-global values. The IN and OUT parameters
102 : are, however, adjusted to the needs of the LineIter most of the time. That
103 : is: they are converted to frame- and window-local coordinates.
104 : If multiple frames with wrap attributes are located on the same line, we get
105 : the following settings for the text flow:
106 :
107 : L/R P L R N
108 : P -P-P- -P-L -P R- -P N
109 : L -L P- -L L -L R- -L N
110 : R R-P- R-L R R- R N
111 : N N P- N L N R- N N
112 :
113 : (P=parallel, L=left, R=right, N=no wrap)
114 :
115 : We can describe the behaviour as follows:
116 : Every frame can push away text, with the restriction that it only has influence
117 : until the next frame.
118 : */
119 : class SwTxtFly
120 : {
121 : const SwPageFrm * pPage;
122 : const SwAnchoredObject * mpCurrAnchoredObj;
123 : const SwTxtFrm * pCurrFrm;
124 : const SwCntntFrm * pMaster;
125 : SwAnchoredObjList * mpAnchoredObjList;
126 :
127 : long nMinBottom;
128 : long nNextTop; /// Stores the upper edge of the "next" frame
129 : sal_uLong nIndex;
130 :
131 : sal_Bool bOn : 1;
132 : sal_Bool bLeftSide : 1;
133 : sal_Bool bTopRule: 1;
134 : sal_Bool mbIgnoreCurrentFrame: 1;
135 : sal_Bool mbIgnoreContour: 1;
136 :
137 : /** boolean, indicating if objects in page header|footer are considered for
138 : text frames not in page header|footer.
139 : */
140 : sal_Bool mbIgnoreObjsInHeaderFooter: 1;
141 :
142 : /**
143 : This method will be called during the LineIter formatting
144 : \li to compute the position of the next \c FlyPortion
145 : \li remember new overlappings after a change of the line height.
146 :
147 : \param[in] rPortion
148 : Scope: document global.
149 : */
150 : SwRect _GetFrm( const SwRect &rPortion, sal_Bool bTop ) const;
151 :
152 : SwAnchoredObjList* InitAnchoredObjList();
153 :
154 : SwAnchoredObjList* GetAnchoredObjList() const;
155 :
156 : /**
157 : Look for the first object which overlaps with the rectangle.
158 : Iterates over the anchored object list mpAnchoredObjList.
159 : */
160 : sal_Bool ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const;
161 :
162 : /**
163 : \li There is less than 2cm space on both sides for the text:
164 : no surround (SURROUND_NONE)
165 :
166 : \li There is more than 2cm space on only one side:
167 : surround on that side (SURROUND_LEFT or SURROUND_RIGHT)
168 :
169 : \li There is more than 2cm space on both sides, the object is
170 : larger than 1.5cm: surround on the wider side
171 : (SURROUND_LET or SURROUND_RIGHT)
172 :
173 : \li There is more than 2cm space on both sides and the object
174 : width is less than 1.5cm: both sides surround (SURROUND_PARALLEL)
175 : */
176 : SwSurround _GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const;
177 :
178 : /**
179 : The right margin is the right margin or it is determined by the
180 : next object standing on the line.
181 : */
182 : void CalcRightMargin( SwRect &rFly,
183 : SwAnchoredObjList::size_type nPos,
184 : const SwRect &rLine ) const;
185 :
186 : /**
187 : The left margin is the left margin of the current PrintArea or
188 : it is determined by the last FlyFrm, which stands on the line.
189 : */
190 : void CalcLeftMargin( SwRect &rFly,
191 : SwAnchoredObjList::size_type nPos,
192 : const SwRect &rLine ) const;
193 :
194 : /**
195 : \return the position in sorted array
196 : */
197 : SwAnchoredObjList::size_type GetPos( const SwAnchoredObject* pAnchoredObj ) const;
198 :
199 : sal_Bool GetTop( const SwAnchoredObject* _pAnchoredObj,
200 : const sal_Bool bInFtn,
201 : const sal_Bool bInFooterOrHeader );
202 :
203 : SwTwips CalcMinBottom() const;
204 :
205 : const SwCntntFrm* _GetMaster();
206 :
207 : public:
208 :
209 : SwTxtFly();
210 : SwTxtFly( const SwTxtFrm *pFrm );
211 : SwTxtFly( const SwTxtFly& rTxtFly );
212 : ~SwTxtFly();
213 :
214 : void CtorInitTxtFly( const SwTxtFrm *pFrm );
215 :
216 : void SetTopRule();
217 :
218 : SwRect GetFrm( const SwRect &rPortion, sal_Bool bTop = sal_True ) const;
219 : sal_Bool IsOn() const;
220 :
221 : /**
222 : If there is no flying object frame standing in rRect (usually the current row),
223 : then we are turning ourself off.
224 :
225 : \param rRect is global to the document!
226 : */
227 : sal_Bool Relax( const SwRect &rRect );
228 : sal_Bool Relax();
229 :
230 : SwTwips GetMinBottom() const;
231 : const SwCntntFrm* GetMaster() const;
232 :
233 : // This temporary variable needs to be manipulated in const methods
234 : long GetNextTop() const;
235 : void SetNextTop( long nNew ) const;
236 :
237 : /**
238 : Determines the demanded rectangle for an anchored object,
239 : considering its surround for text wrapping.
240 :
241 : \param pAnchoredObj the object for which to get the bounds
242 : \param rLine the bounds of the line to format
243 :
244 : \return the flying object bounds
245 : */
246 : SwRect AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
247 : const SwRect& rRect ) const;
248 :
249 : /**
250 : This method is called by DrawText().
251 :
252 : Ensures that the overlapping frames (except the transparent frames) won't
253 : be scribbled by setting clip regions so that only the portions that are not
254 : in the area of FlyFrms that are opaque and above the current frame will
255 : be output.
256 :
257 : DrawText() takes over the on optimization!
258 : */
259 : sal_Bool DrawTextOpaque( SwDrawTextInfo &rInf );
260 :
261 : /**
262 : Two subtleties needs to be mentioned:
263 : \li DrawRect() is allowed over the ClipRects
264 : \li FlyToRect() returns bigger values than the frame data
265 :
266 : Ensure that the overlapping frames (except the transparent frames)
267 : won't be scribbled
268 : */
269 : void DrawFlyRect( OutputDevice* pOut, const SwRect &rRect,
270 : const SwTxtPaintInfo &rInf, sal_Bool bNoGraphic = sal_False );
271 :
272 : /**
273 : Used to switch off the SwTxtFly when there is no overlapping object (Relax).
274 :
275 : \param[in] the line area
276 : \return whether the line will be overlapped by a frame
277 : */
278 : sal_Bool IsAnyFrm( const SwRect &rLine ) const;
279 :
280 : /**
281 : Same as IsAnyFrm(const SwRect&), but uses the current frame print
282 : area
283 : */
284 : sal_Bool IsAnyFrm() const;
285 :
286 : /**
287 : sal_True when a frame or DrawObj must to be taken in account. The optimizations
288 : like Paint/FormatEmpty for empty sentences or the the virtual OutputDevice can
289 : be used only when sal_False is returned.
290 :
291 : \param rRect
292 : The rectangle can be empty, the current frame is then used. The value is
293 : global to the document.
294 : */
295 : sal_Bool IsAnyObj( const SwRect& rRect ) const;
296 :
297 : void SetIgnoreCurrentFrame( sal_Bool bNew );
298 : void SetIgnoreContour( sal_Bool bNew );
299 :
300 : void SetIgnoreObjsInHeaderFooter( const sal_Bool _bNew );
301 : };
302 :
303 :
304 565 : inline SwAnchoredObjList* SwTxtFly::GetAnchoredObjList() const
305 : {
306 : return mpAnchoredObjList
307 : ? mpAnchoredObjList
308 565 : : const_cast<SwTxtFly*>(this)->InitAnchoredObjList();
309 : }
310 :
311 480 : inline void SwTxtFly::SetTopRule()
312 : {
313 480 : bTopRule = sal_False;
314 480 : }
315 :
316 4009 : inline sal_Bool SwTxtFly::IsOn() const
317 : {
318 4009 : return bOn;
319 : }
320 :
321 0 : inline sal_Bool SwTxtFly::Relax( const SwRect &rRect )
322 : {
323 0 : return 0 != (bOn = bOn && IsAnyFrm( rRect ));
324 : }
325 :
326 475 : inline sal_Bool SwTxtFly::Relax()
327 : {
328 475 : return 0 != (bOn = bOn && IsAnyFrm());
329 : }
330 :
331 662 : inline SwTwips SwTxtFly::GetMinBottom() const
332 : {
333 662 : return mpAnchoredObjList ? nMinBottom : CalcMinBottom();
334 : }
335 :
336 542 : inline const SwCntntFrm* SwTxtFly::GetMaster() const
337 : {
338 542 : return pMaster ? pMaster : ((SwTxtFly*)this)->_GetMaster();
339 : }
340 :
341 2 : inline long SwTxtFly::GetNextTop() const
342 : {
343 2 : return nNextTop;
344 : }
345 :
346 126 : inline void SwTxtFly::SetNextTop( long nNew ) const
347 : {
348 126 : ((SwTxtFly*)this)->nNextTop = nNew;
349 126 : }
350 :
351 1189 : inline SwRect SwTxtFly::GetFrm( const SwRect &rRect, sal_Bool bTop ) const
352 : {
353 1189 : return bOn ? _GetFrm( rRect, bTop ) : SwRect();
354 : }
355 :
356 876 : inline void SwTxtFly::SetIgnoreCurrentFrame( sal_Bool bNew )
357 : {
358 876 : mbIgnoreCurrentFrame = bNew;
359 876 : }
360 :
361 438 : inline void SwTxtFly::SetIgnoreContour( sal_Bool bNew )
362 : {
363 438 : mbIgnoreContour = bNew;
364 438 : }
365 :
366 438 : inline void SwTxtFly::SetIgnoreObjsInHeaderFooter( const sal_Bool _bNew )
367 : {
368 438 : mbIgnoreObjsInHeaderFooter = _bNew;
369 438 : }
370 :
371 : #endif
372 :
373 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|