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