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