Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef SVX_FRAMELINKARRAY_HXX
30 : : #define SVX_FRAMELINKARRAY_HXX
31 : :
32 : : #include <svx/framelink.hxx>
33 : : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
34 : :
35 : : #include <memory>
36 : :
37 : : #include <vector>
38 : : #include "svx/svxdllapi.h"
39 : :
40 : : namespace svx {
41 : : namespace frame {
42 : :
43 : : // ============================================================================
44 : :
45 : :
46 : : struct Cell
47 : : {
48 : : Style maLeft;
49 : : Style maRight;
50 : : Style maTop;
51 : : Style maBottom;
52 : : Style maTLBR;
53 : : Style maBLTR;
54 : : long mnAddLeft;
55 : : long mnAddRight;
56 : : long mnAddTop;
57 : : long mnAddBottom;
58 : : bool mbMergeOrig;
59 : : bool mbOverlapX;
60 : : bool mbOverlapY;
61 : :
62 : : explicit Cell();
63 : :
64 [ + + ][ + + ]: 2253750 : inline bool IsMerged() const { return mbMergeOrig || mbOverlapX || mbOverlapY; }
[ + + ]
65 : : inline bool IsOverlapped() const { return mbOverlapX || mbOverlapY; }
66 : :
67 : : void MirrorSelfX( bool bMirrorStyles, bool bSwapDiag );
68 : : };
69 : :
70 : : typedef std::vector< long > LongVec;
71 : : typedef std::vector< Cell > CellVec;
72 : :
73 : 10340 : struct ArrayImpl
74 : : {
75 : : CellVec maCells;
76 : : LongVec maWidths;
77 : : LongVec maHeights;
78 : : mutable LongVec maXCoords;
79 : : mutable LongVec maYCoords;
80 : : size_t mnWidth;
81 : : size_t mnHeight;
82 : : size_t mnFirstClipCol;
83 : : size_t mnFirstClipRow;
84 : : size_t mnLastClipCol;
85 : : size_t mnLastClipRow;
86 : : mutable bool mbXCoordsDirty;
87 : : mutable bool mbYCoordsDirty;
88 : : bool mbDiagDblClip;
89 : :
90 : : explicit ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip );
91 : :
92 : 25637859 : inline bool IsValidPos( size_t nCol, size_t nRow ) const
93 [ + - ][ + - ]: 25637859 : { return (nCol < mnWidth) && (nRow < mnHeight); }
94 : 24978133 : inline size_t GetIndex( size_t nCol, size_t nRow ) const
95 : 24978133 : { return nRow * mnWidth + nCol; }
96 : :
97 : : const Cell& GetCell( size_t nCol, size_t nRow ) const;
98 : : Cell& GetCellAcc( size_t nCol, size_t nRow );
99 : :
100 : : size_t GetMergedFirstCol( size_t nCol, size_t nRow ) const;
101 : : size_t GetMergedFirstRow( size_t nCol, size_t nRow ) const;
102 : : size_t GetMergedLastCol( size_t nCol, size_t nRow ) const;
103 : : size_t GetMergedLastRow( size_t nCol, size_t nRow ) const;
104 : :
105 : : const Cell& GetMergedOriginCell( size_t nCol, size_t nRow ) const;
106 : :
107 : : bool IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const;
108 : : bool IsMergedOverlappedRight( size_t nCol, size_t nRow ) const;
109 : : bool IsMergedOverlappedTop( size_t nCol, size_t nRow ) const;
110 : : bool IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const;
111 : :
112 : : bool IsInClipRange( size_t nCol, size_t nRow ) const;
113 : : bool IsColInClipRange( size_t nCol ) const;
114 : : bool IsRowInClipRange( size_t nRow ) const;
115 : :
116 : 1392 : inline size_t GetMirrorCol( size_t nCol ) const { return mnWidth - nCol - 1; }
117 : : inline size_t GetMirrorRow( size_t nRow ) const { return mnHeight - nRow - 1; }
118 : :
119 : : long GetColPosition( size_t nCol ) const;
120 : : long GetRowPosition( size_t nRow ) const;
121 : :
122 : : long GetColWidth( size_t nFirstCol, size_t nLastCol ) const;
123 : : long GetRowHeight( size_t nFirstRow, size_t nLastRow ) const;
124 : :
125 : : double GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const;
126 : : double GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const;
127 : : };
128 : :
129 : : /** Stores frame styles of an array of cells, supports merged ranges.
130 : :
131 : : This class is able to store the frame styles of an array of cells and to
132 : : draw the entire array or parts of it to any output device.
133 : :
134 : : Every cell contains the style of the left, right, top, bottom, top-left to
135 : : bottom-right, and bottom-left to top-right frame border.
136 : :
137 : : On drawing, the thicker frame border of neighbored cells is selected
138 : : automatically. All borders are drawn "connected", that means, the correct
139 : : start and end coordinates of all lines of the borders are calculated,
140 : : especaially, if they are drawn together with diagonal frame borders.
141 : :
142 : : This array fully supports merged cell ranges. In a merged range, the frame
143 : : borders of the top-left cell is extended to the entire range, and all other
144 : : cells in that range are overlapped. Again, all connected frame borders,
145 : : also diagonals and frame borders from adjacent merged ranges, are handled
146 : : automatically.
147 : :
148 : : Additionally, a clipping range can be set. If such a range is used, all
149 : : frame borders outside this range are completely ignored, and are not used
150 : : in the connected border calculation anymore.
151 : :
152 : : The array can be mirrored in both directions. It is possible to specify,
153 : : whether to mirror the double frame styles, and whether to swap diagonal
154 : : frame borders.
155 : : */
156 : : class SVX_DLLPUBLIC Array
157 : : {
158 : : public:
159 : : /** Constructs an empty array. */
160 : : explicit Array();
161 : :
162 : : /** Destructs the array. */
163 : : ~Array();
164 : :
165 : : // array size and column/row indexes --------------------------------------
166 : :
167 : : /** Reinitializes the array with the specified size. Clears all styles. */
168 : : void Initialize( size_t nWidth, size_t nHeight );
169 : :
170 : : /** Returns the number of columns in the array. */
171 : : size_t GetColCount() const;
172 : :
173 : : /** Returns the number of rows in the array. */
174 : : size_t GetRowCount() const;
175 : :
176 : : /** Returns the number of cells in the array. */
177 : : size_t GetCellCount() const;
178 : :
179 : : /** Returns the cell index from the cell address (nCol,nRow). */
180 : : size_t GetCellIndex( size_t nCol, size_t nRow, bool bRTL = false) const;
181 : :
182 : : // cell border styles -----------------------------------------------------
183 : :
184 : : /** Sets the left frame style of the cell (nCol,nRow). Ignores merged ranges. */
185 : : void SetCellStyleLeft( size_t nCol, size_t nRow, const Style& rStyle );
186 : :
187 : : /** Sets the right frame style of the cell (nCol,nRow). Ignores merged ranges. */
188 : : void SetCellStyleRight( size_t nCol, size_t nRow, const Style& rStyle );
189 : :
190 : : /** Sets the top frame style of the cell (nCol,nRow). Ignores merged ranges. */
191 : : void SetCellStyleTop( size_t nCol, size_t nRow, const Style& rStyle );
192 : :
193 : : /** Sets the bottom frame style of the specified cell (nCol,nRow). Ignores merged ranges. */
194 : : void SetCellStyleBottom( size_t nCol, size_t nRow, const Style& rStyle );
195 : :
196 : : /** Sets the top-left to bottom-right frame style of the cell (nCol,nRow). Ignores merged ranges. */
197 : : void SetCellStyleTLBR( size_t nCol, size_t nRow, const Style& rStyle );
198 : :
199 : : /** Sets the bottom-left to top-right frame style of the cell (nCol,nRow). Ignores merged ranges. */
200 : : void SetCellStyleBLTR( size_t nCol, size_t nRow, const Style& rStyle );
201 : :
202 : : /** Sets both diagonal frame styles of the specified cell (nCol,nRow). Ignores merged ranges. */
203 : : void SetCellStyleDiag( size_t nCol, size_t nRow, const Style& rTLBR, const Style& rBLTR );
204 : :
205 : : /** Sets the left frame style of the specified column. Ignores merged ranges. */
206 : : void SetColumnStyleLeft( size_t nCol, const Style& rStyle );
207 : :
208 : : /** Sets the right frame style of the specified column. Ignores merged ranges. */
209 : : void SetColumnStyleRight( size_t nCol, const Style& rStyle );
210 : :
211 : : /** Sets the top frame style of the specified row. Ignores merged ranges. */
212 : : void SetRowStyleTop( size_t nRow, const Style& rStyle );
213 : :
214 : : /** Sets the bottom frame style of the specified row. Ignores merged ranges. */
215 : : void SetRowStyleBottom( size_t nRow, const Style& rStyle );
216 : :
217 : : /** Returns the left frame style of the cell (nCol,nRow).
218 : : @param bSimple
219 : : true = Ignores merged ranges and neighbor cells;
220 : : false = Returns thicker of own left style or right style of the cell to the left.
221 : : Returns the style only if visible (i.e. at left border of a merged range).
222 : : @return
223 : : The left frame style or an invisible style for invalid cell addresses. */
224 : : const Style& GetCellStyleLeft( size_t nCol, size_t nRow, bool bSimple = false ) const;
225 : :
226 : : /** Returns the right frame style of the cell (nCol,nRow).
227 : : @param bSimple
228 : : true = Ignores merged ranges and neighbor cells;
229 : : false = Returns thicker of own right style or left style of the cell to the right.
230 : : Returns the style only if visible (i.e. at right border of a merged range).
231 : : @return
232 : : The left frame style or an invisible style for invalid cell addresses. */
233 : : const Style& GetCellStyleRight( size_t nCol, size_t nRow, bool bSimple = false ) const;
234 : :
235 : : /** Returns the top frame style of the cell (nCol,nRow).
236 : : @param bSimple
237 : : true = Ignores merged ranges and neighbor cells;
238 : : false = Returns thicker of own top style or bottom style of the cell above.
239 : : Returns the style only if visible (i.e. at top border of a merged range).
240 : : @return
241 : : The top frame style or an invisible style for invalid cell addresses. */
242 : : const Style& GetCellStyleTop( size_t nCol, size_t nRow, bool bSimple = false ) const;
243 : :
244 : : /** Returns the top frame style of the cell (nCol,nRow).
245 : : @param bSimple
246 : : true = Ignores merged ranges and neighbor cells;
247 : : false = Returns thicker of own top style or bottom style of the cell above.
248 : : Returns the style only if visible (i.e. at top border of a merged range).
249 : : @return
250 : : The top frame style or an invisible style for invalid cell addresses. */
251 : : const Style& GetCellStyleBottom( size_t nCol, size_t nRow, bool bSimple = false ) const;
252 : :
253 : : /** Returns the top-left to bottom-right frame style of the cell (nCol,nRow).
254 : : @param bSimple
255 : : true = Ignores merged ranges;
256 : : false = Returns the visible style (i.e. from top-left corner of a merged range).
257 : : @return
258 : : The top-left to bottom-right frame style or an invisible style for invalid cell addresses. */
259 : : const Style& GetCellStyleTLBR( size_t nCol, size_t nRow, bool bSimple = false ) const;
260 : :
261 : : /** Returns the bottom-left to top-right frame style of the cell (nCol,nRow).
262 : : @param bSimple
263 : : true = Ignores merged ranges;
264 : : false = Returns the visible style (i.e. from top-left corner of a merged range).
265 : : @return
266 : : The bottom-left to top-right frame style or an invisible style for invalid cell addresses. */
267 : : const Style& GetCellStyleBLTR( size_t nCol, size_t nRow, bool bSimple = false ) const;
268 : :
269 : : /** Returns the top-left to bottom-right frame style of the cell (nCol,nRow).
270 : : @return
271 : : The top-left to bottom-right frame style, if the cell is not part of
272 : : a merged range, or if (nCol,nRow) is the top-left corner of a merged
273 : : range (useful to find connected frame styles).
274 : : An invisible style for invalid cell addresses. */
275 : : const Style& GetCellStyleTL( size_t nCol, size_t nRow ) const;
276 : :
277 : : /** Returns the top-left to bottom-right frame style of the cell (nCol,nRow).
278 : : @return
279 : : The top-left to bottom-right frame style, if the cell is not part of
280 : : a merged range, or if (nCol,nRow) is the bottom-right corner of a
281 : : merged range (useful to find connected frame styles).
282 : : An invisible style for invalid cell addresses. */
283 : : const Style& GetCellStyleBR( size_t nCol, size_t nRow ) const;
284 : :
285 : : /** Returns the bottom-left to top-right frame style of the cell (nCol,nRow).
286 : : @return
287 : : The bottom-left to top-right frame style, if the cell is not part of
288 : : a merged range, or if (nCol,nRow) is the bottom-left corner of a
289 : : merged range (useful to find connected frame styles).
290 : : An invisible style for invalid cell addresses. */
291 : : const Style& GetCellStyleBL( size_t nCol, size_t nRow ) const;
292 : :
293 : : /** Returns the bottom-left to top-right frame style of the cell (nCol,nRow).
294 : : @return
295 : : The bottom-left to top-right frame style, if the cell is not part of
296 : : a merged range, or if (nCol,nRow) is the top-right corner of a
297 : : merged range (useful to find connected frame styles).
298 : : An invisible style for invalid cell addresses. */
299 : : const Style& GetCellStyleTR( size_t nCol, size_t nRow ) const;
300 : :
301 : : // cell merging -----------------------------------------------------------
302 : :
303 : : /** Inserts a new merged cell range.
304 : : @precond The range must not intersect other merged ranges. */
305 : : void SetMergedRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow );
306 : :
307 : : /** Sets an additional left width for the merged range that contains (nCol,nRow).
308 : : @descr Useful to handle merged ranges that are not completely part of the array.
309 : : @precond The merged range must be at the left border of the array. */
310 : : void SetAddMergedLeftSize( size_t nCol, size_t nRow, long nAddSize );
311 : :
312 : : /** Sets an additional right width for the merged range that contains (nCol,nRow).
313 : : @descr Useful to handle merged ranges that are not completely part of the array.
314 : : @precond The merged range must be at the right border of the array. */
315 : : void SetAddMergedRightSize( size_t nCol, size_t nRow, long nAddSize );
316 : :
317 : : /** Sets an additional top height for the merged range that contains (nCol,nRow).
318 : : @descr Useful to handle merged ranges that are not completely part of the array.
319 : : @precond The merged range must be at the top border of the array. */
320 : : void SetAddMergedTopSize( size_t nCol, size_t nRow, long nAddSize );
321 : :
322 : : /** Sets an additional bottom height for the merged range that contains (nCol,nRow).
323 : : @descr Useful to handle merged ranges that are not completely part of the array.
324 : : @precond The merged range must be at the bottom border of the array. */
325 : : void SetAddMergedBottomSize( size_t nCol, size_t nRow, long nAddSize );
326 : :
327 : : /** Returns true, if the cell (nCol,nRow) is part of a merged range. */
328 : : bool IsMerged( size_t nCol, size_t nRow ) const;
329 : :
330 : : /** Returns true, if the left border of the cell (nCol,nRow) is overlapped by a merged range. */
331 : : bool IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const;
332 : :
333 : : /** Returns true, if the right border of the cell (nCol,nRow) is overlapped by a merged range. */
334 : : bool IsMergedOverlappedRight( size_t nCol, size_t nRow ) const;
335 : :
336 : : /** Returns the address of the top-left cell of the merged range that contains (nCol,nRow). */
337 : : void GetMergedOrigin( size_t& rnFirstCol, size_t& rnFirstRow, size_t nCol, size_t nRow ) const;
338 : :
339 : : /** Returns the top-left and bottom-right address of the merged range that contains (nCol,nRow). */
340 : : void GetMergedRange( size_t& rnFirstCol, size_t& rnFirstRow,
341 : : size_t& rnLastCol, size_t& rnLastRow, size_t nCol, size_t nRow ) const;
342 : :
343 : : // clipping ---------------------------------------------------------------
344 : :
345 : : /** Sets a clipping range.
346 : : @descr
347 : : No cell borders outside of this clipping range will be drawn. In
348 : : difference to simply using the DrawRange() function with the same
349 : : range, a clipping range causes the drawing functions to completely
350 : : ignore the frame styles connected from outside. This is used i.e.
351 : : in Calc to print single pages and to draw the print preview.
352 : : Partly visible diagonal frame borders in merged ranges are correctly
353 : : clipped too. This array can handle only one clip range at a time. */
354 : : void SetClipRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow );
355 : :
356 : : /** Returns the rectangle (output coordinates) of the current clipping range. */
357 : : Rectangle GetClipRangeRectangle() const;
358 : :
359 : : // cell coordinates -------------------------------------------------------
360 : :
361 : : /** Sets the X output coordinate of the left column. */
362 : : void SetXOffset( long nXOffset );
363 : :
364 : : /** Sets the Y output coordinate of the top row. */
365 : : void SetYOffset( long nYOffset );
366 : :
367 : : /** Sets the output width of the specified column. */
368 : : void SetColWidth( size_t nCol, long nWidth );
369 : :
370 : : /** Sets the output height of the specified row. */
371 : : void SetRowHeight( size_t nRow, long nHeight );
372 : :
373 : : /** Sets the same output width for all columns. */
374 : : void SetAllColWidths( long nWidth );
375 : :
376 : : /** Sets the same output height for all rows. */
377 : : void SetAllRowHeights( long nHeight );
378 : :
379 : : /** Returns the X output coordinate of the left border of the specified column.
380 : : @descr The column index <array-width> returns the X output coordinate
381 : : of the right array border. */
382 : : long GetColPosition( size_t nCol ) const;
383 : :
384 : : /** Returns the Y output coordinate of the top border of the specified row.
385 : : @descr The row index <array-height> returns the Y output coordinate
386 : : of the bottom array border. */
387 : : long GetRowPosition( size_t nRow ) const;
388 : :
389 : : /** Returns the output width of the specified range of columns. */
390 : : long GetColWidth( size_t nFirstCol, size_t nLastCol ) const;
391 : :
392 : : /** Returns the output height of the specified range of rows. */
393 : : long GetRowHeight( size_t nFirstRow, size_t nLastRow ) const;
394 : :
395 : : /** Returns the output width of the entire array. */
396 : : long GetWidth() const;
397 : :
398 : : /** Returns the output height of the entire array. */
399 : : long GetHeight() const;
400 : :
401 : : /** Returns the top-left output position of the cell (nCol,nRow).
402 : : @param bSimple
403 : : true = Ignores merged ranges;
404 : : false = Returns output position of top-left corner of merged ranges. */
405 : : Point GetCellPosition( size_t nCol, size_t nRow, bool bSimple = false ) const;
406 : :
407 : : /** Returns the output size of the cell (nCol,nRow).
408 : : @param bSimple
409 : : true = Ignores merged ranges;
410 : : false = Returns total output size of merged ranges. */
411 : : Size GetCellSize( size_t nCol, size_t nRow, bool bSimple = false ) const;
412 : :
413 : : /** Returns the output rectangle of the cell (nCol,nRow).
414 : : @param bSimple
415 : : true = Ignores merged ranges;
416 : : false = Returns total output rectangle of merged ranges. */
417 : : Rectangle GetCellRect( size_t nCol, size_t nRow, bool bSimple = false ) const;
418 : :
419 : : // diagonal frame borders -------------------------------------------------
420 : :
421 : : /** Returns the angle between horizontal and diagonal border of the cell (nCol,nRow).
422 : : @param bSimple
423 : : true = Ignores merged ranges;
424 : : false = Returns the horizontal angle of merged ranges. */
425 : : double GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const;
426 : :
427 : : /** Returns the angle between vertical and diagonal border of the cell (nCol,nRow).
428 : : @param bSimple
429 : : true = Ignores merged ranges;
430 : : false = Returns the vertical angle of merged ranges. */
431 : : double GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const;
432 : :
433 : : /** Specifies whether to use polygon clipping to draw diagonal frame borders.
434 : : @descr
435 : : If enabled, diagonal frame borders are drawn interrupted, if they are
436 : : crossed by a double frame border. Polygon clipping is very expensive
437 : : and should only be used for very small output devices (i.e. in the
438 : : Border tab page). Default after construction is OFF. */
439 : : void SetUseDiagDoubleClipping( bool bSet );
440 : :
441 : : // mirroring --------------------------------------------------------------
442 : :
443 : : /** Mirrors the entire array horizontally.
444 : : @param bMirrorStyles
445 : : true = Swap primary and secondary line of all vertical double frame borders.
446 : : @param bSwapDiag
447 : : true = Swap top-left to bottom-right and bottom-left to top-right frame borders. */
448 : : void MirrorSelfX( bool bMirrorStyles, bool bSwapDiag );
449 : :
450 : : // drawing ----------------------------------------------------------------
451 : :
452 : : /** Draws the part of the specified range, that is inside the clipping range.
453 : : @param pForceColor
454 : : If not NULL, only this color will be used to draw all frame borders. */
455 : : void DrawRange( drawinglayer::processor2d::BaseProcessor2D* rDev,
456 : : size_t nFirstCol, size_t nFirstRow,
457 : : size_t nLastCol, size_t nLastRow,
458 : : const Color* pForceColor = 0 ) const;
459 : :
460 : : /** Draws the part of the specified range, that is inside the clipping range.
461 : : @param pForceColor
462 : : If not NULL, only this color will be used to draw all frame borders. */
463 : : void DrawRange( OutputDevice& rDev,
464 : : size_t nFirstCol, size_t nFirstRow,
465 : : size_t nLastCol, size_t nLastRow,
466 : : const Color* pForceColor = 0 ) const;
467 : :
468 : : /** Draws the part of the array, that is inside the clipping range.
469 : : @param pForceColor
470 : : If not NULL, only this color will be used to draw all frame borders. */
471 : : void DrawArray( OutputDevice& rDev, const Color* pForceColor = 0 ) const;
472 : :
473 : : // ------------------------------------------------------------------------
474 : :
475 : : private:
476 : : typedef std::auto_ptr< ArrayImpl > ArrayImplPtr;
477 : :
478 : : ArrayImplPtr mxImpl;
479 : : };
480 : :
481 : : // ============================================================================
482 : :
483 : : } // namespace frame
484 : : } // namespace svx
485 : :
486 : : #endif
487 : :
488 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|