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 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include "viewcontactoftableobj.hxx" 32 #include <svx/svdotable.hxx> 33 #include <com/sun/star/table/XTable.hpp> 34 #include <basegfx/polygon/b2dpolygontools.hxx> 35 #include <basegfx/polygon/b2dpolygon.hxx> 36 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 37 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 38 #include <drawinglayer/primitive2d/groupprimitive2d.hxx> 39 #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> 40 #include <svx/sdr/primitive2d/sdrattributecreator.hxx> 41 #include <basegfx/matrix/b2dhommatrix.hxx> 42 #include <svx/sdr/attribute/sdrtextattribute.hxx> 43 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> 44 #include <editeng/borderline.hxx> 45 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx> 46 #include <svx/sdr/attribute/sdrfilltextattribute.hxx> 47 #include <drawinglayer/attribute/sdrlineattribute.hxx> 48 #include <drawinglayer/attribute/sdrshadowattribute.hxx> 49 #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> 50 #include <basegfx/matrix/b2dhommatrixtools.hxx> 51 52 #include "cell.hxx" 53 #include "tablelayouter.hxx" 54 55 ////////////////////////////////////////////////////////////////////////////// 56 57 using namespace com::sun::star; 58 59 ////////////////////////////////////////////////////////////////////////////// 60 61 namespace drawinglayer 62 { 63 namespace primitive2d 64 { 65 class SdrCellPrimitive2D : public BufferedDecompositionPrimitive2D 66 { 67 private: 68 basegfx::B2DHomMatrix maTransform; 69 attribute::SdrFillTextAttribute maSdrFTAttribute; 70 71 protected: 72 // local decomposition. 73 virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const; 74 75 public: 76 SdrCellPrimitive2D( 77 const basegfx::B2DHomMatrix& rTransform, 78 const attribute::SdrFillTextAttribute& rSdrFTAttribute) 79 : BufferedDecompositionPrimitive2D(), 80 maTransform(rTransform), 81 maSdrFTAttribute(rSdrFTAttribute) 82 { 83 } 84 85 // data access 86 const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } 87 const attribute::SdrFillTextAttribute& getSdrFTAttribute() const { return maSdrFTAttribute; } 88 89 // compare operator 90 virtual bool operator==(const BasePrimitive2D& rPrimitive) const; 91 92 // provide unique ID 93 DeclPrimitrive2DIDBlock() 94 }; 95 96 Primitive2DSequence SdrCellPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const 97 { 98 // prepare unit polygon 99 Primitive2DSequence aRetval; 100 const basegfx::B2DPolyPolygon aUnitPolyPolygon(basegfx::tools::createUnitPolygon()); 101 102 // add fill 103 if(!getSdrFTAttribute().getFill().isDefault()) 104 { 105 appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 106 createPolyPolygonFillPrimitive( 107 aUnitPolyPolygon, 108 getTransform(), 109 getSdrFTAttribute().getFill(), 110 getSdrFTAttribute().getFillFloatTransGradient())); 111 } 112 else 113 { 114 // if no fill create one for HitTest and BoundRect fallback 115 appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 116 createHiddenGeometryPrimitives2D( 117 true, 118 aUnitPolyPolygon, 119 getTransform())); 120 } 121 122 // add text 123 if(!getSdrFTAttribute().getText().isDefault()) 124 { 125 appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, 126 createTextPrimitive( 127 aUnitPolyPolygon, 128 getTransform(), 129 getSdrFTAttribute().getText(), 130 attribute::SdrLineAttribute(), 131 true, 132 false, 133 false)); 134 } 135 136 return aRetval; 137 } 138 139 bool SdrCellPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 140 { 141 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 142 { 143 const SdrCellPrimitive2D& rCompare = (SdrCellPrimitive2D&)rPrimitive; 144 145 return (getTransform() == rCompare.getTransform() 146 && getSdrFTAttribute() == rCompare.getSdrFTAttribute()); 147 } 148 149 return false; 150 } 151 152 // provide unique ID 153 ImplPrimitrive2DIDBlock(SdrCellPrimitive2D, PRIMITIVE2D_ID_SDRCELLPRIMITIVE2D) 154 155 } // end of namespace primitive2d 156 } // end of namespace drawinglayer 157 158 ////////////////////////////////////////////////////////////////////////////// 159 160 namespace drawinglayer 161 { 162 namespace primitive2d 163 { 164 class SdrBorderlinePrimitive2D : public BufferedDecompositionPrimitive2D 165 { 166 private: 167 basegfx::B2DHomMatrix maTransform; 168 SvxBorderLine maLeftLine; 169 SvxBorderLine maBottomLine; 170 SvxBorderLine maRightLine; 171 SvxBorderLine maTopLine; 172 173 // bitfield 174 unsigned mbLeftIsOutside : 1; 175 unsigned mbBottomIsOutside : 1; 176 unsigned mbRightIsOutside : 1; 177 unsigned mbTopIsOutside : 1; 178 unsigned mbInTwips : 1; 179 180 protected: 181 // local decomposition. 182 virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const; 183 184 public: 185 SdrBorderlinePrimitive2D( 186 const basegfx::B2DHomMatrix& rTransform, 187 const SvxBorderLine& rLeftLine, 188 const SvxBorderLine& rBottomLine, 189 const SvxBorderLine& rRightLine, 190 const SvxBorderLine& rTopLine, 191 bool bLeftIsOutside, 192 bool bBottomIsOutside, 193 bool bRightIsOutside, 194 bool bTopIsOutside, 195 bool bInTwips) 196 : BufferedDecompositionPrimitive2D(), 197 maTransform(rTransform), 198 maLeftLine(rLeftLine), 199 maBottomLine(rBottomLine), 200 maRightLine(rRightLine), 201 maTopLine(rTopLine), 202 mbLeftIsOutside(bLeftIsOutside), 203 mbBottomIsOutside(bBottomIsOutside), 204 mbRightIsOutside(bRightIsOutside), 205 mbTopIsOutside(bTopIsOutside), 206 mbInTwips(bInTwips) 207 { 208 } 209 210 211 // data access 212 const basegfx::B2DHomMatrix& getTransform() const { return maTransform; } 213 const SvxBorderLine& getLeftLine() const { return maLeftLine; } 214 const SvxBorderLine& getBottomLine() const { return maBottomLine; } 215 const SvxBorderLine& getRightLine() const { return maRightLine; } 216 const SvxBorderLine& getTopLine() const { return maTopLine; } 217 bool getLeftIsOutside() const { return mbLeftIsOutside; } 218 bool getBottomIsOutside() const { return mbBottomIsOutside; } 219 bool getRightIsOutside() const { return mbRightIsOutside; } 220 bool getTopIsOutside() const { return mbTopIsOutside; } 221 bool getInTwips() const { return mbInTwips; } 222 223 // compare operator 224 virtual bool operator==(const BasePrimitive2D& rPrimitive) const; 225 226 // provide unique ID 227 DeclPrimitrive2DIDBlock() 228 }; 229 230 sal_uInt16 getBorderLineOutWidth(const SvxBorderLine& rLineA) 231 { 232 return (1 == rLineA.GetOutWidth() ? 0 : rLineA.GetOutWidth()); 233 } 234 235 sal_uInt16 getBorderLineDistance(const SvxBorderLine& rLineA) 236 { 237 return (1 == rLineA.GetDistance() ? 0 : rLineA.GetDistance()); 238 } 239 240 sal_uInt16 getBorderLineInWidth(const SvxBorderLine& rLineA) 241 { 242 return (1 == rLineA.GetInWidth() ? 0 : rLineA.GetInWidth()); 243 } 244 245 sal_uInt16 getBorderLineWidth(const SvxBorderLine& rLineA) 246 { 247 return getBorderLineOutWidth(rLineA) + getBorderLineDistance(rLineA) + getBorderLineInWidth(rLineA); 248 } 249 250 double getInnerExtend(const SvxBorderLine& rLineA, bool bSideToUse) 251 { 252 if(!rLineA.isEmpty()) 253 { 254 if(rLineA.isDouble()) 255 { 256 // reduce to inner edge of associated matching line 257 return -((getBorderLineWidth(rLineA) / 2.0) - (bSideToUse ? getBorderLineOutWidth(rLineA) : getBorderLineInWidth(rLineA))); 258 } 259 else 260 { 261 // extend to overlap with single line 262 return getBorderLineWidth(rLineA) / 2.0; 263 } 264 } 265 266 return 0.0; 267 } 268 269 double getOuterExtend(const SvxBorderLine& rLineA) 270 { 271 if(!rLineA.isEmpty()) 272 { 273 // extend to overlap with single line 274 return getBorderLineWidth(rLineA) / 2.0; 275 } 276 277 return 0.0; 278 } 279 280 double getChangedValue(sal_uInt16 nValue, bool bChangeToMM) 281 { 282 if(1 == nValue) 283 return 1.0; 284 285 if(bChangeToMM) 286 return nValue * (127.0 / 72.0); 287 288 return (double)nValue; 289 } 290 291 Primitive2DSequence SdrBorderlinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const 292 { 293 Primitive2DSequence xRetval(4); 294 sal_uInt32 nInsert(0); 295 const double fTwipsToMM(getInTwips() ? (127.0 / 72.0) : 1.0); 296 297 if(!getLeftLine().isEmpty()) 298 { 299 // create left line from top to bottom 300 const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0)); 301 const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(0.0, 1.0)); 302 303 if(!aStart.equal(aEnd)) 304 { 305 const double fExtendIS(getInnerExtend(getTopLine(), false)); 306 const double fExtendIE(getInnerExtend(getBottomLine(), true)); 307 double fExtendOS(0.0); 308 double fExtendOE(0.0); 309 310 if(getLeftIsOutside()) 311 { 312 if(getTopIsOutside()) 313 { 314 fExtendOS = getOuterExtend(getTopLine()); 315 } 316 317 if(getBottomIsOutside()) 318 { 319 fExtendOE = getOuterExtend(getBottomLine()); 320 } 321 } 322 323 xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D( 324 aStart, 325 aEnd, 326 getChangedValue(getLeftLine().GetOutWidth(), getInTwips()), 327 getChangedValue(getLeftLine().GetDistance(), getInTwips()), 328 getChangedValue(getLeftLine().GetInWidth(), getInTwips()), 329 fExtendIS * fTwipsToMM, 330 fExtendIE * fTwipsToMM, 331 fExtendOS * fTwipsToMM, 332 fExtendOE * fTwipsToMM, 333 true, 334 getLeftIsOutside(), 335 getLeftLine().GetColor().getBColor())); 336 } 337 } 338 339 if(!getBottomLine().isEmpty()) 340 { 341 // create bottom line from left to right 342 const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 1.0)); 343 const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 1.0)); 344 345 if(!aStart.equal(aEnd)) 346 { 347 const double fExtendIS(getInnerExtend(getLeftLine(), true)); 348 const double fExtendIE(getInnerExtend(getRightLine(), false)); 349 double fExtendOS(0.0); 350 double fExtendOE(0.0); 351 352 if(getBottomIsOutside()) 353 { 354 if(getLeftIsOutside()) 355 { 356 fExtendOS = getOuterExtend(getLeftLine()); 357 } 358 359 if(getRightIsOutside()) 360 { 361 fExtendOE = getOuterExtend(getRightLine()); 362 } 363 } 364 365 xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D( 366 aStart, 367 aEnd, 368 getChangedValue(getBottomLine().GetOutWidth(), getInTwips()), 369 getChangedValue(getBottomLine().GetDistance(), getInTwips()), 370 getChangedValue(getBottomLine().GetInWidth(), getInTwips()), 371 fExtendIS * fTwipsToMM, 372 fExtendIE * fTwipsToMM, 373 fExtendOS * fTwipsToMM, 374 fExtendOE * fTwipsToMM, 375 true, 376 getBottomIsOutside(), 377 getBottomLine().GetColor().getBColor())); 378 } 379 } 380 381 if(!getRightLine().isEmpty()) 382 { 383 // create right line from top to bottom 384 const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(1.0, 0.0)); 385 const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 1.0)); 386 387 if(!aStart.equal(aEnd)) 388 { 389 const double fExtendIS(getInnerExtend(getTopLine(), false)); 390 const double fExtendIE(getInnerExtend(getBottomLine(), true)); 391 double fExtendOS(0.0); 392 double fExtendOE(0.0); 393 394 if(getRightIsOutside()) 395 { 396 if(getTopIsOutside()) 397 { 398 fExtendOS = getOuterExtend(getTopLine()); 399 } 400 401 if(getBottomIsOutside()) 402 { 403 fExtendOE = getOuterExtend(getBottomLine()); 404 } 405 } 406 407 xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D( 408 aStart, 409 aEnd, 410 getChangedValue(getRightLine().GetOutWidth(), getInTwips()), 411 getChangedValue(getRightLine().GetDistance(), getInTwips()), 412 getChangedValue(getRightLine().GetInWidth(), getInTwips()), 413 fExtendOS * fTwipsToMM, 414 fExtendOE * fTwipsToMM, 415 fExtendIS * fTwipsToMM, 416 fExtendIE * fTwipsToMM, 417 getRightIsOutside(), 418 true, 419 getRightLine().GetColor().getBColor())); 420 } 421 } 422 423 if(!getTopLine().isEmpty()) 424 { 425 // create top line from left to right 426 const basegfx::B2DPoint aStart(getTransform() * basegfx::B2DPoint(0.0, 0.0)); 427 const basegfx::B2DPoint aEnd(getTransform() * basegfx::B2DPoint(1.0, 0.0)); 428 429 if(!aStart.equal(aEnd)) 430 { 431 const double fExtendIS(getInnerExtend(getLeftLine(), true)); 432 const double fExtendIE(getInnerExtend(getRightLine(), false)); 433 double fExtendOS(0.0); 434 double fExtendOE(0.0); 435 436 if(getTopIsOutside()) 437 { 438 if(getLeftIsOutside()) 439 { 440 fExtendOS = getOuterExtend(getLeftLine()); 441 } 442 443 if(getRightIsOutside()) 444 { 445 fExtendOE = getOuterExtend(getRightLine()); 446 } 447 } 448 449 xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D( 450 aStart, 451 aEnd, 452 getChangedValue(getTopLine().GetOutWidth(), getInTwips()), 453 getChangedValue(getTopLine().GetDistance(), getInTwips()), 454 getChangedValue(getTopLine().GetInWidth(), getInTwips()), 455 fExtendOS * fTwipsToMM, 456 fExtendOE * fTwipsToMM, 457 fExtendIS * fTwipsToMM, 458 fExtendIE * fTwipsToMM, 459 getTopIsOutside(), 460 true, 461 getTopLine().GetColor().getBColor())); 462 } 463 } 464 465 xRetval.realloc(nInsert); 466 return xRetval; 467 } 468 469 bool SdrBorderlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 470 { 471 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 472 { 473 const SdrBorderlinePrimitive2D& rCompare = (SdrBorderlinePrimitive2D&)rPrimitive; 474 475 return (getTransform() == rCompare.getTransform() 476 && getLeftLine() == rCompare.getLeftLine() 477 && getBottomLine() == rCompare.getBottomLine() 478 && getRightLine() == rCompare.getRightLine() 479 && getTopLine() == rCompare.getTopLine() 480 && getLeftIsOutside() == rCompare.getLeftIsOutside() 481 && getBottomIsOutside() == rCompare.getBottomIsOutside() 482 && getRightIsOutside() == rCompare.getRightIsOutside() 483 && getTopIsOutside() == rCompare.getTopIsOutside() 484 && getInTwips() == rCompare.getInTwips()); 485 } 486 487 return false; 488 } 489 490 // provide unique ID 491 ImplPrimitrive2DIDBlock(SdrBorderlinePrimitive2D, PRIMITIVE2D_ID_SDRBORDERLINEPRIMITIVE2D) 492 493 } // end of namespace primitive2d 494 } // end of namespace drawinglayer 495 496 ////////////////////////////////////////////////////////////////////////////// 497 498 namespace sdr 499 { 500 namespace contact 501 { 502 void impGetLine(SvxBorderLine& aLine, const sdr::table::TableLayouter& rLayouter, sal_Int32 nX, sal_Int32 nY, bool bHorizontal, sal_Int32 nColCount, sal_Int32 nRowCount, bool bIsRTL) 503 { 504 if(nX >= 0 && nX <= nColCount && nY >= 0 && nY <= nRowCount) 505 { 506 const SvxBorderLine* pLine = rLayouter.getBorderLine(nX, nY, bHorizontal); 507 508 if(pLine) 509 { 510 // copy line content 511 aLine = *pLine; 512 513 // check for mirroring. This shall always be done when it is 514 // not a top- or rightmost line 515 bool bMirror(aLine.isDouble()); 516 517 if(bMirror) 518 { 519 if(bHorizontal) 520 { 521 // mirror all bottom lines 522 bMirror = (0 != nY); 523 } 524 else 525 { 526 // mirror all left lines 527 bMirror = (bIsRTL ? 0 != nX : nX != nColCount); 528 } 529 } 530 531 if(bMirror) 532 { 533 aLine.SetOutWidth(pLine->GetInWidth()); 534 aLine.SetInWidth(pLine->GetOutWidth()); 535 } 536 537 return; 538 } 539 } 540 541 // no success, copy empty line 542 const SvxBorderLine aEmptyLine; 543 aLine = aEmptyLine; 544 } 545 546 drawinglayer::primitive2d::Primitive2DSequence ViewContactOfTableObj::createViewIndependentPrimitive2DSequence() const 547 { 548 const sdr::table::SdrTableObj& rTableObj = GetTableObj(); 549 const uno::Reference< com::sun::star::table::XTable > xTable = rTableObj.getTable(); 550 551 if(xTable.is()) 552 { 553 // create primitive representation for table 554 drawinglayer::primitive2d::Primitive2DSequence xRetval; 555 const sal_Int32 nRowCount(xTable->getRowCount()); 556 const sal_Int32 nColCount(xTable->getColumnCount()); 557 const sal_Int32 nAllCount(nRowCount * nColCount); 558 559 if(nAllCount) 560 { 561 const sdr::table::TableLayouter& rTableLayouter = rTableObj.getTableLayouter(); 562 const bool bIsRTL(com::sun::star::text::WritingMode_RL_TB == rTableObj.GetWritingMode()); 563 sdr::table::CellPos aCellPos; 564 sdr::table::CellRef xCurrentCell; 565 basegfx::B2IRectangle aCellArea; 566 567 // create range using the model data directly. This is in SdrTextObj::aRect which i will access using 568 // GetGeoRect() to not trigger any calculations. It's the unrotated geometry. 569 const Rectangle& rObjectRectangle(rTableObj.GetGeoRect()); 570 const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom()); 571 572 // for each cell we need potentially a cell primitive and a border primitive 573 // (e.g. single cell). Prepare sequences and input counters 574 drawinglayer::primitive2d::Primitive2DSequence xCellSequence(nAllCount); 575 drawinglayer::primitive2d::Primitive2DSequence xBorderSequence(nAllCount); 576 sal_uInt32 nCellInsert(0); 577 sal_uInt32 nBorderInsert(0); 578 579 // variables for border lines 580 SvxBorderLine aLeftLine; 581 SvxBorderLine aBottomLine; 582 SvxBorderLine aRightLine; 583 SvxBorderLine aTopLine; 584 585 // create single primitives per cell 586 for(aCellPos.mnRow = 0; aCellPos.mnRow < nRowCount; aCellPos.mnRow++) 587 { 588 for(aCellPos.mnCol = 0; aCellPos.mnCol < nColCount; aCellPos.mnCol++) 589 { 590 xCurrentCell.set(dynamic_cast< sdr::table::Cell* >(xTable->getCellByPosition(aCellPos.mnCol, aCellPos.mnRow).get())); 591 592 if(xCurrentCell.is() && !xCurrentCell->isMerged()) 593 { 594 if(rTableLayouter.getCellArea(aCellPos, aCellArea)) 595 { 596 // create cell transformation matrix 597 basegfx::B2DHomMatrix aCellMatrix; 598 aCellMatrix.set(0, 0, (double)aCellArea.getWidth()); 599 aCellMatrix.set(1, 1, (double)aCellArea.getHeight()); 600 aCellMatrix.set(0, 2, (double)aCellArea.getMinX() + aObjectRange.getMinX()); 601 aCellMatrix.set(1, 2, (double)aCellArea.getMinY() + aObjectRange.getMinY()); 602 603 // handle cell fillings and text 604 const SfxItemSet& rCellItemSet = xCurrentCell->GetItemSet(); 605 const sal_uInt32 nTextIndex(nColCount * aCellPos.mnRow + aCellPos.mnCol); 606 const SdrText* pSdrText = rTableObj.getText(nTextIndex); 607 drawinglayer::attribute::SdrFillTextAttribute aAttribute; 608 609 if(pSdrText) 610 { 611 // #i101508# take cell's local text frame distances into account 612 const sal_Int32 nLeft(xCurrentCell->GetTextLeftDistance()); 613 const sal_Int32 nRight(xCurrentCell->GetTextRightDistance()); 614 const sal_Int32 nUpper(xCurrentCell->GetTextUpperDistance()); 615 const sal_Int32 nLower(xCurrentCell->GetTextLowerDistance()); 616 617 aAttribute = drawinglayer::primitive2d::createNewSdrFillTextAttribute( 618 rCellItemSet, 619 pSdrText, 620 &nLeft, 621 &nUpper, 622 &nRight, 623 &nLower); 624 } 625 else 626 { 627 aAttribute = drawinglayer::primitive2d::createNewSdrFillTextAttribute( 628 rCellItemSet, 629 pSdrText); 630 } 631 632 // always create cell primitives for BoundRect and HitTest 633 { 634 const drawinglayer::primitive2d::Primitive2DReference xCellReference( 635 new drawinglayer::primitive2d::SdrCellPrimitive2D( 636 aCellMatrix, aAttribute)); 637 xCellSequence[nCellInsert++] = xCellReference; 638 } 639 640 // handle cell borders 641 const sal_Int32 nX(bIsRTL ? nColCount - aCellPos.mnCol : aCellPos.mnCol); 642 const sal_Int32 nY(aCellPos.mnRow); 643 644 // get access values for X,Y at the cell's end 645 const sal_Int32 nXSpan(xCurrentCell->getColumnSpan()); 646 const sal_Int32 nYSpan(xCurrentCell->getRowSpan()); 647 const sal_Int32 nXRight(bIsRTL ? nX - nXSpan : nX + nXSpan); 648 const sal_Int32 nYBottom(nY + nYSpan); 649 650 // get basic lines 651 impGetLine(aLeftLine, rTableLayouter, nX, nY, false, nColCount, nRowCount, bIsRTL); 652 impGetLine(aBottomLine, rTableLayouter, nX, nYBottom, true, nColCount, nRowCount, bIsRTL); 653 impGetLine(aRightLine, rTableLayouter, nXRight, nY, false, nColCount, nRowCount, bIsRTL); 654 impGetLine(aTopLine, rTableLayouter, nX, nY, true, nColCount, nRowCount, bIsRTL); 655 656 // create the primtive containing all data for one cell with borders 657 xBorderSequence[nBorderInsert++] = drawinglayer::primitive2d::Primitive2DReference( 658 new drawinglayer::primitive2d::SdrBorderlinePrimitive2D( 659 aCellMatrix, 660 aLeftLine, 661 aBottomLine, 662 aRightLine, 663 aTopLine, 664 bIsRTL ? nX == nColCount : 0 == nX, 665 nRowCount == nYBottom, 666 bIsRTL ? 0 == nXRight : nXRight == nColCount, 667 0 == nY, 668 true)); 669 } 670 } 671 } 672 } 673 674 // no empty references; reallocate sequences by used count 675 xCellSequence.realloc(nCellInsert); 676 xBorderSequence.realloc(nBorderInsert); 677 678 // append to target. We want fillings and text first 679 xRetval = xCellSequence; 680 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xBorderSequence); 681 } 682 683 if(xRetval.hasElements()) 684 { 685 // check and create evtl. shadow for created content 686 const SfxItemSet& rObjectItemSet = rTableObj.GetMergedItemSet(); 687 const drawinglayer::attribute::SdrShadowAttribute aNewShadowAttribute( 688 drawinglayer::primitive2d::createNewSdrShadowAttribute(rObjectItemSet)); 689 690 if(!aNewShadowAttribute.isDefault()) 691 { 692 xRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(xRetval, aNewShadowAttribute); 693 } 694 } 695 696 return xRetval; 697 } 698 else 699 { 700 // take unrotated snap rect (direct model data) for position and size 701 const Rectangle& rRectangle = rTableObj.GetGeoRect(); 702 const basegfx::B2DRange aObjectRange( 703 rRectangle.Left(), rRectangle.Top(), 704 rRectangle.Right(), rRectangle.Bottom()); 705 706 // create object matrix 707 const GeoStat& rGeoStat(rTableObj.GetGeoStat()); 708 const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); 709 const double fRotate(rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0); 710 const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( 711 aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate, 712 aObjectRange.getMinX(), aObjectRange.getMinY())); 713 714 // credate an invisible outline for the cases where no visible content exists 715 const drawinglayer::primitive2d::Primitive2DReference xReference( 716 drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( 717 false, 718 aObjectMatrix)); 719 720 return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); 721 } 722 } 723 724 ViewContactOfTableObj::ViewContactOfTableObj(::sdr::table::SdrTableObj& rTableObj) 725 : ViewContactOfSdrObj(rTableObj) 726 { 727 } 728 729 ViewContactOfTableObj::~ViewContactOfTableObj() 730 { 731 } 732 } // end of namespace contact 733 } // end of namespace sdr 734 735 ////////////////////////////////////////////////////////////////////////////// 736 // eof 737