1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef SVX_FRAMELINKARRAY_HXX 25 #define SVX_FRAMELINKARRAY_HXX 26 27 #include <svx/framelink.hxx> 28 29 #include <memory> 30 31 #include <vector> 32 #include "svx/svxdllapi.h" 33 34 namespace svx { 35 namespace frame { 36 37 // ============================================================================ 38 39 40 struct Cell 41 { 42 Style maLeft; 43 Style maRight; 44 Style maTop; 45 Style maBottom; 46 Style maTLBR; 47 Style maBLTR; 48 long mnAddLeft; 49 long mnAddRight; 50 long mnAddTop; 51 long mnAddBottom; 52 bool mbMergeOrig; 53 bool mbOverlapX; 54 bool mbOverlapY; 55 56 explicit Cell(); 57 IsMergedsvx::frame::Cell58 inline bool IsMerged() const { return mbMergeOrig || mbOverlapX || mbOverlapY; } IsOverlappedsvx::frame::Cell59 inline bool IsOverlapped() const { return mbOverlapX || mbOverlapY; } 60 61 void MirrorSelfX( bool bMirrorStyles, bool bSwapDiag ); 62 void MirrorSelfY( bool bMirrorStyles, bool bSwapDiag ); 63 }; 64 65 typedef std::vector< long > LongVec; 66 typedef std::vector< Cell > CellVec; 67 68 struct ArrayImpl 69 { 70 CellVec maCells; 71 LongVec maWidths; 72 LongVec maHeights; 73 mutable LongVec maXCoords; 74 mutable LongVec maYCoords; 75 size_t mnWidth; 76 size_t mnHeight; 77 size_t mnFirstClipCol; 78 size_t mnFirstClipRow; 79 size_t mnLastClipCol; 80 size_t mnLastClipRow; 81 mutable bool mbXCoordsDirty; 82 mutable bool mbYCoordsDirty; 83 bool mbDiagDblClip; 84 85 explicit ArrayImpl( size_t nWidth, size_t nHeight, bool bDiagDblClip ); 86 IsValidPossvx::frame::ArrayImpl87 inline bool IsValidPos( size_t nCol, size_t nRow ) const 88 { return (nCol < mnWidth) && (nRow < mnHeight); } GetIndexsvx::frame::ArrayImpl89 inline size_t GetIndex( size_t nCol, size_t nRow ) const 90 { return nRow * mnWidth + nCol; } 91 92 const Cell& GetCell( size_t nCol, size_t nRow ) const; 93 Cell& GetCellAcc( size_t nCol, size_t nRow ); 94 95 size_t GetMergedFirstCol( size_t nCol, size_t nRow ) const; 96 size_t GetMergedFirstRow( size_t nCol, size_t nRow ) const; 97 size_t GetMergedLastCol( size_t nCol, size_t nRow ) const; 98 size_t GetMergedLastRow( size_t nCol, size_t nRow ) const; 99 100 const Cell& GetMergedOriginCell( size_t nCol, size_t nRow ) const; 101 Cell& GetMergedOriginCellAcc( size_t nCol, size_t nRow ); 102 103 bool IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const; 104 bool IsMergedOverlappedRight( size_t nCol, size_t nRow ) const; 105 bool IsMergedOverlappedTop( size_t nCol, size_t nRow ) const; 106 bool IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const; 107 108 bool IsInClipRange( size_t nCol, size_t nRow ) const; 109 bool IsColInClipRange( size_t nCol ) const; 110 bool IsRowInClipRange( size_t nRow ) const; 111 GetMirrorColsvx::frame::ArrayImpl112 inline size_t GetMirrorCol( size_t nCol ) const { return mnWidth - nCol - 1; } GetMirrorRowsvx::frame::ArrayImpl113 inline size_t GetMirrorRow( size_t nRow ) const { return mnHeight - nRow - 1; } 114 115 long GetColPosition( size_t nCol ) const; 116 long GetRowPosition( size_t nRow ) const; 117 118 long GetColWidth( size_t nFirstCol, size_t nLastCol ) const; 119 long GetRowHeight( size_t nFirstRow, size_t nLastRow ) const; 120 121 double GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const; 122 double GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const; 123 }; 124 125 /** Stores frame styles of an array of cells, supports merged ranges. 126 127 This class is able to store the frame styles of an array of cells and to 128 draw the entire array or parts of it to any output device. 129 130 Every cell contains the style of the left, right, top, bottom, top-left to 131 bottom-right, and bottom-left to top-right frame border. 132 133 On drawing, the thicker frame border of neighbored cells is selected 134 automatically. All borders are drawn "connected", that means, the correct 135 start and end coordinates of all lines of the borders are calculated, 136 especaially, if they are drawn together with diagonal frame borders. 137 138 This array fully supports merged cell ranges. In a merged range, the frame 139 borders of the top-left cell is extended to the entire range, and all other 140 cells in that range are overlapped. Again, all connected frame borders, 141 also diagonals and frame borders from adjacent merged ranges, are handled 142 automatically. 143 144 Additionally, a clipping range can be set. If such a range is used, all 145 frame borders outside this range are completely ignored, and are not used 146 in the connected border calculation anymore. 147 148 The array can be mirrored in both directions. It is possible to specify, 149 whether to mirror the double frame styles, and whether to swap diagonal 150 frame borders. 151 */ 152 class SVX_DLLPUBLIC Array 153 { 154 public: 155 /** Constructs an empty array. */ 156 explicit Array(); 157 158 /** Constructs an array with the specified width and height. */ 159 explicit Array( size_t nWidth, size_t nHeight ); 160 161 /** Destructs the array. */ 162 ~Array(); 163 164 // array size and column/row indexes -------------------------------------- 165 166 /** Reinitializes the array with the specified size. Clears all styles. */ 167 void Initialize( size_t nWidth, size_t nHeight ); 168 169 /** Clears all line styles, column widths, row heights, merge data, and the clip range. */ 170 void Clear(); 171 172 /** Returns the number of columns in the array. */ 173 size_t GetColCount() const; 174 175 /** Returns the number of rows in the array. */ 176 size_t GetRowCount() const; 177 178 /** Returns the number of cells in the array. */ 179 size_t GetCellCount() const; 180 181 /** Returns the column index of the specified cell index. */ 182 size_t GetColFromIndex( size_t nCellIndex ) const; 183 184 /** Returns the row index of the specified cell index. */ 185 size_t GetRowFromIndex( size_t nCellIndex ) const; 186 187 /** Returns the cell index from the cell address (nCol,nRow). */ 188 size_t GetCellIndex( size_t nCol, size_t nRow, bool bRTL = false) const; 189 190 // cell border styles ----------------------------------------------------- 191 192 /** Sets the left frame style of the cell (nCol,nRow). Ignores merged ranges. */ 193 void SetCellStyleLeft( size_t nCol, size_t nRow, const Style& rStyle ); 194 195 /** Sets the right frame style of the cell (nCol,nRow). Ignores merged ranges. */ 196 void SetCellStyleRight( size_t nCol, size_t nRow, const Style& rStyle ); 197 198 /** Sets the top frame style of the cell (nCol,nRow). Ignores merged ranges. */ 199 void SetCellStyleTop( size_t nCol, size_t nRow, const Style& rStyle ); 200 201 /** Sets the bottom frame style of the specified cell (nCol,nRow). Ignores merged ranges. */ 202 void SetCellStyleBottom( size_t nCol, size_t nRow, const Style& rStyle ); 203 204 /** Sets the top-left to bottom-right frame style of the cell (nCol,nRow). Ignores merged ranges. */ 205 void SetCellStyleTLBR( size_t nCol, size_t nRow, const Style& rStyle ); 206 207 /** Sets the bottom-left to top-right frame style of the cell (nCol,nRow). Ignores merged ranges. */ 208 void SetCellStyleBLTR( size_t nCol, size_t nRow, const Style& rStyle ); 209 210 /** Sets both diagonal frame styles of the specified cell (nCol,nRow). Ignores merged ranges. */ 211 void SetCellStyleDiag( size_t nCol, size_t nRow, const Style& rTLBR, const Style& rBLTR ); 212 213 /** Sets the left frame style of the specified column. Ignores merged ranges. */ 214 void SetColumnStyleLeft( size_t nCol, const Style& rStyle ); 215 216 /** Sets the right frame style of the specified column. Ignores merged ranges. */ 217 void SetColumnStyleRight( size_t nCol, const Style& rStyle ); 218 219 /** Sets the top frame style of the specified row. Ignores merged ranges. */ 220 void SetRowStyleTop( size_t nRow, const Style& rStyle ); 221 222 /** Sets the bottom frame style of the specified row. Ignores merged ranges. */ 223 void SetRowStyleBottom( size_t nRow, const Style& rStyle ); 224 225 /** Returns the left frame style of the cell (nCol,nRow). 226 @param bSimple 227 true = Ignores merged ranges and neighbor cells; 228 false = Returns thicker of own left style or right style of the cell to the left. 229 Returns the style only if visible (i.e. at left border of a merged range). 230 @return 231 The left frame style or an invisible style for invalid cell addresses. */ 232 const Style& GetCellStyleLeft( size_t nCol, size_t nRow, bool bSimple = false ) const; 233 234 /** Returns the right frame style of the cell (nCol,nRow). 235 @param bSimple 236 true = Ignores merged ranges and neighbor cells; 237 false = Returns thicker of own right style or left style of the cell to the right. 238 Returns the style only if visible (i.e. at right border of a merged range). 239 @return 240 The left frame style or an invisible style for invalid cell addresses. */ 241 const Style& GetCellStyleRight( size_t nCol, size_t nRow, bool bSimple = false ) const; 242 243 /** Returns the top frame style of the cell (nCol,nRow). 244 @param bSimple 245 true = Ignores merged ranges and neighbor cells; 246 false = Returns thicker of own top style or bottom style of the cell above. 247 Returns the style only if visible (i.e. at top border of a merged range). 248 @return 249 The top frame style or an invisible style for invalid cell addresses. */ 250 const Style& GetCellStyleTop( size_t nCol, size_t nRow, bool bSimple = false ) const; 251 252 /** Returns the top frame style of the cell (nCol,nRow). 253 @param bSimple 254 true = Ignores merged ranges and neighbor cells; 255 false = Returns thicker of own top style or bottom style of the cell above. 256 Returns the style only if visible (i.e. at top border of a merged range). 257 @return 258 The top frame style or an invisible style for invalid cell addresses. */ 259 const Style& GetCellStyleBottom( size_t nCol, size_t nRow, bool bSimple = false ) const; 260 261 /** Returns the top-left to bottom-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 top-left to bottom-right frame style or an invisible style for invalid cell addresses. */ 267 const Style& GetCellStyleTLBR( size_t nCol, size_t nRow, bool bSimple = false ) const; 268 269 /** Returns the bottom-left to top-right frame style of the cell (nCol,nRow). 270 @param bSimple 271 true = Ignores merged ranges; 272 false = Returns the visible style (i.e. from top-left corner of a merged range). 273 @return 274 The bottom-left to top-right frame style or an invisible style for invalid cell addresses. */ 275 const Style& GetCellStyleBLTR( size_t nCol, size_t nRow, bool bSimple = false ) 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 top-left corner of a merged 281 range (useful to find connected frame styles). 282 An invisible style for invalid cell addresses. */ 283 const Style& GetCellStyleTL( size_t nCol, size_t nRow ) const; 284 285 /** Returns the top-left to bottom-right frame style of the cell (nCol,nRow). 286 @return 287 The top-left to bottom-right frame style, if the cell is not part of 288 a merged range, or if (nCol,nRow) is the bottom-right corner of a 289 merged range (useful to find connected frame styles). 290 An invisible style for invalid cell addresses. */ 291 const Style& GetCellStyleBR( 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 bottom-left corner of a 297 merged range (useful to find connected frame styles). 298 An invisible style for invalid cell addresses. */ 299 const Style& GetCellStyleBL( size_t nCol, size_t nRow ) const; 300 301 /** Returns the bottom-left to top-right frame style of the cell (nCol,nRow). 302 @return 303 The bottom-left to top-right frame style, if the cell is not part of 304 a merged range, or if (nCol,nRow) is the top-right corner of a 305 merged range (useful to find connected frame styles). 306 An invisible style for invalid cell addresses. */ 307 const Style& GetCellStyleTR( size_t nCol, size_t nRow ) const; 308 309 // cell merging ----------------------------------------------------------- 310 311 /** Inserts a new merged cell range. 312 @precond The range must not intersect other merged ranges. */ 313 void SetMergedRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow ); 314 315 /** Removes the merged cell range that contains (nCol,nRow). */ 316 void RemoveMergedRange( size_t nCol, size_t nRow ); 317 318 /** Sets an additional left width for the merged range that contains (nCol,nRow). 319 @descr Useful to handle merged ranges that are not completely part of the array. 320 @precond The merged range must be at the left border of the array. */ 321 void SetAddMergedLeftSize( size_t nCol, size_t nRow, long nAddSize ); 322 323 /** Sets an additional right width for the merged range that contains (nCol,nRow). 324 @descr Useful to handle merged ranges that are not completely part of the array. 325 @precond The merged range must be at the right border of the array. */ 326 void SetAddMergedRightSize( size_t nCol, size_t nRow, long nAddSize ); 327 328 /** Sets an additional top height for the merged range that contains (nCol,nRow). 329 @descr Useful to handle merged ranges that are not completely part of the array. 330 @precond The merged range must be at the top border of the array. */ 331 void SetAddMergedTopSize( size_t nCol, size_t nRow, long nAddSize ); 332 333 /** Sets an additional bottom height for the merged range that contains (nCol,nRow). 334 @descr Useful to handle merged ranges that are not completely part of the array. 335 @precond The merged range must be at the bottom border of the array. */ 336 void SetAddMergedBottomSize( size_t nCol, size_t nRow, long nAddSize ); 337 338 /** Returns true, if the cell (nCol,nRow) is part of a merged range. */ 339 bool IsMerged( size_t nCol, size_t nRow ) const; 340 341 /** Returns true, if the cell (nCol,nRow) is the top-left corner of a merged range. */ 342 bool IsMergedOrigin( size_t nCol, size_t nRow ) const; 343 344 /** Returns true, if the cell (nCol,nRow) is overlapped by a merged range. */ 345 bool IsMergedOverlapped( size_t nCol, size_t nRow ) const; 346 347 /** Returns true, if the left border of the cell (nCol,nRow) is overlapped by a merged range. */ 348 bool IsMergedOverlappedLeft( size_t nCol, size_t nRow ) const; 349 350 /** Returns true, if the right border of the cell (nCol,nRow) is overlapped by a merged range. */ 351 bool IsMergedOverlappedRight( size_t nCol, size_t nRow ) const; 352 353 /** Returns true, if the top border of the cell (nCol,nRow) is overlapped by a merged range. */ 354 bool IsMergedOverlappedTop( size_t nCol, size_t nRow ) const; 355 356 /** Returns true, if the bottom border of the cell (nCol,nRow) is overlapped by a merged range. */ 357 bool IsMergedOverlappedBottom( size_t nCol, size_t nRow ) const; 358 359 /** Returns the address of the top-left cell of the merged range that contains (nCol,nRow). */ 360 void GetMergedOrigin( size_t& rnFirstCol, size_t& rnFirstRow, size_t nCol, size_t nRow ) const; 361 362 /** Returns the range size of the merged range thst contains (nCol,nRow). */ 363 void GetMergedSize( size_t& rnWidth, size_t& rnHeight, size_t nCol, size_t nRow ) const; 364 365 /** Returns the top-left and bottom-right address of the merged range that contains (nCol,nRow). */ 366 void GetMergedRange( size_t& rnFirstCol, size_t& rnFirstRow, 367 size_t& rnLastCol, size_t& rnLastRow, size_t nCol, size_t nRow ) const; 368 369 // clipping --------------------------------------------------------------- 370 371 /** Sets a clipping range. 372 @descr 373 No cell borders outside of this clipping range will be drawn. In 374 difference to simply using the DrawRange() function with the same 375 range, a clipping range causes the drawing functions to completely 376 ignore the frame styles connected from outside. This is used i.e. 377 in Calc to print single pages and to draw the print preview. 378 Partly visible diagonal frame borders in merged ranges are correctly 379 clipped too. This array can handle only one clip range at a time. */ 380 void SetClipRange( size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow ); 381 382 /** Removes the clipping range set with the SetClipRange() function. */ 383 void RemoveClipRange(); 384 385 /** Returns true, if the cell (bCol,nRow) is inside the current clip range. */ 386 bool IsInClipRange( size_t nCol, size_t nRow ) const; 387 388 /** Returns the rectangle (output coordinates) of the current clipping range. */ 389 Rectangle GetClipRangeRectangle() const; 390 391 // cell coordinates ------------------------------------------------------- 392 393 /** Sets the X output coordinate of the left column. */ 394 void SetXOffset( long nXOffset ); 395 396 /** Sets the Y output coordinate of the top row. */ 397 void SetYOffset( long nYOffset ); 398 399 /** Sets the output width of the specified column. */ 400 void SetColWidth( size_t nCol, long nWidth ); 401 402 /** Sets the output height of the specified row. */ 403 void SetRowHeight( size_t nRow, long nHeight ); 404 405 /** Sets the same output width for all columns. */ 406 void SetAllColWidths( long nWidth ); 407 408 /** Sets the same output height for all rows. */ 409 void SetAllRowHeights( long nHeight ); 410 411 /** Returns the X output coordinate of the left border of the specified column. 412 @descr The column index <array-width> returns the X output coordinate 413 of the right array border. */ 414 long GetColPosition( size_t nCol ) const; 415 416 /** Returns the Y output coordinate of the top border of the specified row. 417 @descr The row index <array-height> returns the Y output coordinate 418 of the bottom array border. */ 419 long GetRowPosition( size_t nRow ) const; 420 421 /** Returns the output width of the specified column. */ 422 long GetColWidth( size_t nCol ) const; 423 424 /** Returns the output width of the specified range of columns. */ 425 long GetColWidth( size_t nFirstCol, size_t nLastCol ) const; 426 427 /** Returns the output height of the specified row. */ 428 long GetRowHeight( size_t nRow ) const; 429 430 /** Returns the output height of the specified range of rows. */ 431 long GetRowHeight( size_t nFirstRow, size_t nLastRow ) const; 432 433 /** Returns the output width of the entire array. */ 434 long GetWidth() const; 435 436 /** Returns the output height of the entire array. */ 437 long GetHeight() const; 438 439 /** Returns the top-left output position of the cell (nCol,nRow). 440 @param bSimple 441 true = Ignores merged ranges; 442 false = Returns output position of top-left corner of merged ranges. */ 443 Point GetCellPosition( size_t nCol, size_t nRow, bool bSimple = false ) const; 444 445 /** Returns the output size of the cell (nCol,nRow). 446 @param bSimple 447 true = Ignores merged ranges; 448 false = Returns total output size of merged ranges. */ 449 Size GetCellSize( size_t nCol, size_t nRow, bool bSimple = false ) const; 450 451 /** Returns the output rectangle of the cell (nCol,nRow). 452 @param bSimple 453 true = Ignores merged ranges; 454 false = Returns total output rectangle of merged ranges. */ 455 Rectangle GetCellRect( size_t nCol, size_t nRow, bool bSimple = false ) const; 456 457 // diagonal frame borders ------------------------------------------------- 458 459 /** Returns the angle between horizontal and diagonal border of the cell (nCol,nRow). 460 @param bSimple 461 true = Ignores merged ranges; 462 false = Returns the horizontal angle of merged ranges. */ 463 double GetHorDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const; 464 465 /** Returns the angle between vertical and diagonal border of the cell (nCol,nRow). 466 @param bSimple 467 true = Ignores merged ranges; 468 false = Returns the vertical angle of merged ranges. */ 469 double GetVerDiagAngle( size_t nCol, size_t nRow, bool bSimple = false ) const; 470 471 /** Specifies whether to use polygon clipping to draw diagonal frame borders. 472 @descr 473 If enabled, diagonal frame borders are drawn interrupted, if they are 474 crossed by a double frame border. Polygon clipping is very expensive 475 and should only be used for very small output devices (i.e. in the 476 Border tab page). Default after construction is OFF. */ 477 void SetUseDiagDoubleClipping( bool bSet ); 478 479 /** Returns true, if polygon clipping is used to draw diagonal frame borders. */ 480 bool GetUseDiagDoubleClipping() const; 481 482 // mirroring -------------------------------------------------------------- 483 484 /** Mirrors the entire array horizontally. 485 @param bMirrorStyles 486 true = Swap primary and secondary line of all vertical double frame borders. 487 @param bSwapDiag 488 true = Swap top-left to bottom-right and bottom-left to top-right frame borders. */ 489 void MirrorSelfX( bool bMirrorStyles, bool bSwapDiag ); 490 491 /** Mirrors the entire array vertically. 492 @param bMirrorStyles 493 true = Swap primary and secondary line of all horizontal double frame borders. 494 @param bSwapDiag 495 true = Swap top-left to bottom-right and bottom-left to top-right frame borders. */ 496 void MirrorSelfY( bool bMirrorStyles, bool bSwapDiag ); 497 498 // drawing ---------------------------------------------------------------- 499 500 /** Draws the cell (nCol,nRow), if it is inside the clipping range. 501 @param pForceColor 502 If not NULL, only this color will be used to draw all frame borders. */ 503 void DrawCell( OutputDevice& rDev, size_t nCol, size_t nRow, 504 const Color* pForceColor = 0 ) const; 505 506 /** Draws the part of the specified range, that is inside the clipping range. 507 @param pForceColor 508 If not NULL, only this color will be used to draw all frame borders. */ 509 void DrawRange( OutputDevice& rDev, 510 size_t nFirstCol, size_t nFirstRow, 511 size_t nLastCol, size_t nLastRow, 512 const Color* pForceColor = 0 ) const; 513 514 /** Draws the part of the array, that is inside the clipping range. 515 @param pForceColor 516 If not NULL, only this color will be used to draw all frame borders. */ 517 void DrawArray( OutputDevice& rDev, const Color* pForceColor = 0 ) const; 518 519 // ------------------------------------------------------------------------ 520 521 private: 522 typedef std::auto_ptr< ArrayImpl > ArrayImplPtr; 523 524 ArrayImplPtr mxImpl; 525 }; 526 527 // ============================================================================ 528 529 } // namespace frame 530 } // namespace svx 531 532 #endif 533 534