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