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