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