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 INCLUDED_SW_SOURCE_CORE_INC_TXTFLY_HXX
20 : #define INCLUDED_SW_SOURCE_CORE_INC_TXTFLY_HXX
21 :
22 : #include "swtypes.hxx"
23 : #include "swrect.hxx"
24 : #include <fmtsrndenum.hxx>
25 : #include <vector>
26 :
27 : class OutputDevice;
28 : class SwContentFrm;
29 : class SwPageFrm;
30 : class SwTextFly;
31 : class SdrObject;
32 : class SwTextPaintInfo;
33 : class SwFormat;
34 : class TextRanger;
35 : class SwAnchoredObject;
36 : class SwTextFrm;
37 : class SwDrawTextInfo;
38 : class SwContourCache;
39 :
40 : typedef std::vector< SwAnchoredObject* > SwAnchoredObjList;
41 :
42 : enum PAGESIDE { LEFT_SIDE, RIGHT_SIDE, DONTKNOW_SIDE };
43 :
44 : /** Contour-cache global variable, initialized/destroyed in txtinit.cxx
45 : and needed in txtfly.cxx by text wrapping.
46 : */
47 : extern SwContourCache *pContourCache;
48 :
49 : #define POLY_CNT 20
50 : #define POLY_MIN 5
51 : #define POLY_MAX 4000
52 :
53 : void ClrContourCache( const SdrObject *pObj );
54 :
55 : class SwContourCache
56 : {
57 : friend void ClrContourCache();
58 : const SdrObject *pSdrObj[ POLY_CNT ];
59 : TextRanger *pTextRanger[ POLY_CNT ];
60 : long nPntCnt;
61 : sal_uInt16 nObjCnt;
62 : const SwRect ContourRect( const SwFormat* pFormat, const SdrObject* pObj,
63 : const SwTextFrm* pFrm, const SwRect &rLine, const long nXPos,
64 : const bool bRight );
65 :
66 : public:
67 : SwContourCache();
68 : ~SwContourCache();
69 10 : const SdrObject* GetObject( sal_uInt16 nPos ) const{ return pSdrObj[ nPos ]; }
70 1807 : sal_uInt16 GetCount() const { return nObjCnt; }
71 : void ClrObject( sal_uInt16 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 tools::PolyPolygon of the object gets traversed
79 : */
80 : static const SwRect CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
81 : const SwRect &rLine,
82 : const SwTextFrm* pFrm,
83 : const long nXPos,
84 : const 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 SwTextFly, 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 SwTextFly.
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 SwTextFly
120 : {
121 : const SwPageFrm * pPage;
122 : const SwAnchoredObject * mpCurrAnchoredObj;
123 : const SwTextFrm * pCurrFrm;
124 : const SwContentFrm * 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 : bool bOn : 1;
132 : bool bTopRule: 1;
133 : bool mbIgnoreCurrentFrame: 1;
134 : bool mbIgnoreContour: 1;
135 :
136 : /** boolean, indicating if objects in page header|footer are considered for
137 : text frames not in page header|footer.
138 : */
139 : bool mbIgnoreObjsInHeaderFooter: 1;
140 :
141 : /**
142 : This method will be called during the LineIter formatting
143 : \li to compute the position of the next \c FlyPortion
144 : \li remember new overlappings after a change of the line height.
145 :
146 : \param[in] rPortion
147 : Scope: document global.
148 : */
149 : SwRect _GetFrm( const SwRect &rPortion, bool bTop ) const;
150 :
151 : SwAnchoredObjList* InitAnchoredObjList();
152 :
153 : SwAnchoredObjList* GetAnchoredObjList() const;
154 :
155 : /**
156 : Look for the first object which overlaps with the rectangle.
157 : Iterates over the anchored object list mpAnchoredObjList.
158 : */
159 : bool ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const;
160 :
161 : /**
162 : \li There is less than 2cm space on both sides for the text:
163 : no surround (SURROUND_NONE)
164 :
165 : \li There is more than 2cm space on only one side:
166 : surround on that side (SURROUND_LEFT or SURROUND_RIGHT)
167 :
168 : \li There is more than 2cm space on both sides, the object is
169 : larger than 1.5cm: surround on the wider side
170 : (SURROUND_LET or SURROUND_RIGHT)
171 :
172 : \li There is more than 2cm space on both sides and the object
173 : width is less than 1.5cm: both sides surround (SURROUND_PARALLEL)
174 : */
175 : SwSurround _GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const;
176 :
177 : /**
178 : The right margin is the right margin or it is determined by the
179 : next object standing on the line.
180 : */
181 : void CalcRightMargin( SwRect &rFly,
182 : SwAnchoredObjList::size_type nPos,
183 : const SwRect &rLine ) const;
184 :
185 : /**
186 : The left margin is the left margin of the current PrintArea or
187 : it is determined by the last FlyFrm, which stands on the line.
188 : */
189 : void CalcLeftMargin( SwRect &rFly,
190 : SwAnchoredObjList::size_type nPos,
191 : const SwRect &rLine ) const;
192 :
193 : /**
194 : \return the position in sorted array
195 : */
196 : SwAnchoredObjList::size_type GetPos( const SwAnchoredObject* pAnchoredObj ) const;
197 :
198 : bool GetTop( const SwAnchoredObject* _pAnchoredObj,
199 : const bool bInFootnote,
200 : const bool bInFooterOrHeader );
201 :
202 : SwTwips CalcMinBottom() const;
203 :
204 : const SwContentFrm* _GetMaster();
205 :
206 : public:
207 :
208 : SwTextFly();
209 : SwTextFly( const SwTextFrm *pFrm );
210 : SwTextFly( const SwTextFly& rTextFly );
211 : ~SwTextFly();
212 :
213 : void CtorInitTextFly( const SwTextFrm *pFrm );
214 :
215 : void SetTopRule();
216 :
217 : SwRect GetFrm( const SwRect &rPortion, bool bTop = true ) const;
218 : bool IsOn() const;
219 :
220 : /**
221 : If there is no flying object frame standing in rRect (usually the current row),
222 : then we are turning ourself off.
223 :
224 : \param rRect is global to the document!
225 : */
226 : bool Relax( const SwRect &rRect );
227 : bool Relax();
228 :
229 : SwTwips GetMinBottom() const;
230 : const SwContentFrm* GetMaster() const;
231 :
232 : // This temporary variable needs to be manipulated in const methods
233 : long GetNextTop() const;
234 : void SetNextTop( long nNew ) const;
235 :
236 : /**
237 : Determines the demanded rectangle for an anchored object,
238 : considering its surround for text wrapping.
239 :
240 : \param pAnchoredObj the object for which to get the bounds
241 : \param rLine the bounds of the line to format
242 :
243 : \return the flying object bounds
244 : */
245 : SwRect AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
246 : const SwRect& rRect ) const;
247 :
248 : /**
249 : This method is called by DrawText().
250 :
251 : Ensures that the overlapping frames (except the transparent frames) won't
252 : be scribbled by setting clip regions so that only the portions that are not
253 : in the area of FlyFrms that are opaque and above the current frame will
254 : be output.
255 :
256 : DrawText() takes over the on optimization!
257 : */
258 : bool DrawTextOpaque( SwDrawTextInfo &rInf );
259 :
260 : /**
261 : Two subtleties needs to be mentioned:
262 : \li DrawRect() is allowed over the ClipRects
263 : \li FlyToRect() returns bigger values than the frame data
264 :
265 : Ensure that the overlapping frames (except the transparent frames)
266 : won't be scribbled
267 : */
268 : void DrawFlyRect( OutputDevice* pOut, const SwRect &rRect,
269 : const SwTextPaintInfo &rInf, bool bNoGraphic = false );
270 :
271 : /**
272 : Used to switch off the SwTextFly when there is no overlapping object (Relax).
273 :
274 : \param[in] the line area
275 : \return whether the line will be overlapped by a frame
276 : */
277 : bool IsAnyFrm( const SwRect &rLine ) const;
278 :
279 : /**
280 : Same as IsAnyFrm(const SwRect&), but uses the current frame print
281 : area
282 : */
283 : bool IsAnyFrm() const;
284 :
285 : /**
286 : true when a frame or DrawObj must to be taken in account. The optimizations
287 : like Paint/FormatEmpty for empty sentences or the virtual OutputDevice can
288 : be used only when false is returned.
289 :
290 : \param rRect
291 : The rectangle can be empty, the current frame is then used. The value is
292 : global to the document.
293 : */
294 : bool IsAnyObj( const SwRect& rRect ) const;
295 :
296 : void SetIgnoreCurrentFrame( bool bNew );
297 : void SetIgnoreContour( bool bNew );
298 :
299 : void SetIgnoreObjsInHeaderFooter( const bool bNew );
300 : };
301 :
302 85484 : inline SwAnchoredObjList* SwTextFly::GetAnchoredObjList() const
303 : {
304 : return mpAnchoredObjList
305 : ? mpAnchoredObjList
306 85484 : : const_cast<SwTextFly*>(this)->InitAnchoredObjList();
307 : }
308 :
309 12744 : inline void SwTextFly::SetTopRule()
310 : {
311 12744 : bTopRule = false;
312 12744 : }
313 :
314 400777 : inline bool SwTextFly::IsOn() const
315 : {
316 400777 : return bOn;
317 : }
318 :
319 0 : inline bool SwTextFly::Relax( const SwRect &rRect )
320 : {
321 0 : if (bOn)
322 : {
323 0 : bOn = IsAnyFrm( rRect );
324 : }
325 0 : return bOn;
326 : }
327 :
328 16428 : inline bool SwTextFly::Relax()
329 : {
330 16428 : if (bOn)
331 : {
332 5577 : bOn = IsAnyFrm();
333 : }
334 16428 : return bOn;
335 : }
336 :
337 51395 : inline SwTwips SwTextFly::GetMinBottom() const
338 : {
339 51395 : return mpAnchoredObjList ? nMinBottom : CalcMinBottom();
340 : }
341 :
342 30844 : inline const SwContentFrm* SwTextFly::GetMaster() const
343 : {
344 30844 : return pMaster ? pMaster : const_cast<SwTextFly*>(this)->_GetMaster();
345 : }
346 :
347 164 : inline long SwTextFly::GetNextTop() const
348 : {
349 164 : return nNextTop;
350 : }
351 :
352 2977 : inline void SwTextFly::SetNextTop( long nNew ) const
353 : {
354 2977 : const_cast<SwTextFly*>(this)->nNextTop = nNew;
355 2977 : }
356 :
357 160894 : inline SwRect SwTextFly::GetFrm( const SwRect &rRect, bool bTop ) const
358 : {
359 160894 : return bOn ? _GetFrm( rRect, bTop ) : SwRect();
360 : }
361 :
362 109250 : inline void SwTextFly::SetIgnoreCurrentFrame( bool bNew )
363 : {
364 109250 : mbIgnoreCurrentFrame = bNew;
365 109250 : }
366 :
367 54625 : inline void SwTextFly::SetIgnoreContour( bool bNew )
368 : {
369 54625 : mbIgnoreContour = bNew;
370 54625 : }
371 :
372 54625 : inline void SwTextFly::SetIgnoreObjsInHeaderFooter( const bool bNew )
373 : {
374 54625 : mbIgnoreObjsInHeaderFooter = bNew;
375 54625 : }
376 :
377 : #endif
378 :
379 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|