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