xref: /trunk/main/svx/source/table/viewcontactoftableobj.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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