svx/Library_svx.mk                         |    1 
 svx/Library_svxcore.mk                     |    1 
 svx/source/dialog/framelinkarray.cxx       |    1 
 svx/source/table/viewcontactoftableobj.cxx |  197 +++++++++++++----------------
 4 files changed, 92 insertions(+), 108 deletions(-)

New commits:
commit 5288db0d119ae36e712295cf911b690eb45aa1d0
Author: Armin Le Grand <armin.le.gr...@cib.de>
Date:   Wed Jan 24 15:25:40 2018 +0100

    BorderlineFix: Use svx::frame::Array tooling in Draw/Impress
    
    For creating the needed BorderPrimitives for TableCells for the
    Tables used in Draw/Impress, adapt the ViewContactOfTableObj doing
    this to use svx::frame::Array tooling now. This will correct the
    error for not taking the neighboured connects for merged cells
    into account and unify one more space to the same tooling.
    
    Change-Id: I2e6f732985e9b963359f156628bd29ddfec1a80c

diff --git a/svx/Library_svx.mk b/svx/Library_svx.mk
index 6bdbadaf2e3b..ad1b1dc3a423 100644
--- a/svx/Library_svx.mk
+++ b/svx/Library_svx.mk
@@ -128,7 +128,6 @@ $(eval $(call gb_Library_add_exception_objects,svx,\
     svx/source/dialog/fntctrl \
     svx/source/dialog/fontlb \
     svx/source/dialog/fontwork \
-    svx/source/dialog/framelinkarray \
     svx/source/dialog/frmdirlbox \
     svx/source/dialog/frmsel \
     svx/source/dialog/graphctl \
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 5bfbf899034d..603860d7f11b 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -116,6 +116,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
     svx/source/dialog/dlgutil \
     svx/source/dialog/hexcolorcontrol \
     svx/source/dialog/framelink \
+    svx/source/dialog/framelinkarray \
     svx/source/dialog/langbox \
     svx/source/dialog/pagenumberlistbox \
     svx/source/dialog/papersizelistbox \
diff --git a/svx/source/dialog/framelinkarray.cxx 
b/svx/source/dialog/framelinkarray.cxx
index bc8a50a3d3cf..7cd4b26027dc 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -21,6 +21,7 @@
 
 #include <math.h>
 #include <vector>
+#include <set>
 #include <algorithm>
 #include <vcl/outdev.hxx>
 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
diff --git a/svx/source/table/viewcontactoftableobj.cxx 
b/svx/source/table/viewcontactoftableobj.cxx
index 448a0b407f2a..4a5741cd0545 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -36,8 +36,10 @@
 #include <drawinglayer/attribute/sdrlineattribute.hxx>
 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
 #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
 #include <svx/framelink.hxx>
+#include <svx/framelinkarray.hxx>
 
 #include <cell.hxx>
 #include "tablelayouter.hxx"
@@ -196,42 +198,6 @@ namespace sdr
             return svx::frame::Style();
         }
 
-        void createForVector(bool bHor, 
drawinglayer::primitive2d::Primitive2DContainer& rContainer, const 
basegfx::B2DPoint& rOrigin, const basegfx::B2DVector& rX,
-            const svx::frame::Style& rLine,
-            const svx::frame::Style& rLeftA, const svx::frame::Style& rLeftB, 
const svx::frame::Style& rLeftC,
-            const svx::frame::Style& rRightA, const svx::frame::Style& 
rRightB, const svx::frame::Style& rRightC)
-        {
-            /// top-left and bottom-right Style Tables
-            const basegfx::B2DVector 
aY(basegfx::getNormalizedPerpendicular(rX));
-
-            /// Fill top-left Style Table
-            svx::frame::StyleVectorTable aStart;
-
-            aStart.add(rLeftA, rX, -aY, bHor); // bHor ? true : false));
-            aStart.add(rLeftB, rX, -rX, true); // bHor ? true : true));
-            aStart.add(rLeftC, rX, aY, !bHor); // bHor ? false : true));
-            aStart.sort();
-
-            /// Fill bottom-right Style Table
-            svx::frame::StyleVectorTable aEnd;
-            const basegfx::B2DVector aAxis(-rX);
-
-            aEnd.add(rRightA, aAxis, -aY, bHor); // bHor ? true : false));
-            aEnd.add(rRightB, aAxis, rX, false); // bHor ? false : false));
-            aEnd.add(rRightC, aAxis, aY, !bHor); // bHor ? false : true));
-            aEnd.sort();
-
-            CreateBorderPrimitives(
-                rContainer,
-                rOrigin,
-                rX,
-                rLine,
-                aStart,
-                aEnd,
-                nullptr
-            );
-        }
-
         drawinglayer::primitive2d::Primitive2DContainer 
ViewContactOfTableObj::createViewIndependentPrimitive2DSequence() const
         {
             const sdr::table::SdrTableObj& rTableObj = static_cast<const 
sdr::table::SdrTableObj&>(GetSdrObject());
@@ -249,7 +215,7 @@ namespace sdr
 
                 if(nAllCount)
                 {
-                    const sdr::table::TableLayouter& rTableLayouter = 
rTableObj.getTableLayouter();
+                    const sdr::table::TableLayouter& 
rTableLayouter(rTableObj.getTableLayouter());
                     const bool bIsRTL(css::text::WritingMode_RL_TB == 
rTableObj.GetWritingMode());
                     sdr::table::CellPos aCellPos;
                     sdr::table::CellRef xCurrentCell;
@@ -258,19 +224,59 @@ namespace sdr
                     // create range using the model data directly. This is in 
SdrTextObj::aRect which i will access using
                     // GetGeoRect() to not trigger any calculations. It's the 
unrotated geometry.
                     const tools::Rectangle& 
rObjectRectangle(rTableObj.GetGeoRect());
-                    const basegfx::B2DRange 
aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), 
rObjectRectangle.Right(), rObjectRectangle.Bottom());
+                    const basegfx::B2DRange aObjectRange(
+                        rObjectRectangle.Left(), rObjectRectangle.Top(),
+                        rObjectRectangle.Right(), rObjectRectangle.Bottom());
+
+                    // To create the CellBorderPrimitives, use the tolling 
from svx::frame::Array
+                    // which is capable of creating the needed visualization. 
Fill it during the
+                    // anyways needed run over the table.
+                    svx::frame::Array aArray;
 
-                    // for each cell we need potentially a cell primitive and 
a border primitive
-                    // (e.g. single cell). Prepare sequences and input counters
-                    drawinglayer::primitive2d::Primitive2DContainer 
aBorderSequence;
+                    // initialize CellBorderArray for primitive creation
+                    aArray.Initialize(nRowCount, nColCount);
 
                     // create single primitives per cell
                     for(aCellPos.mnRow = 0; aCellPos.mnRow < nRowCount; 
aCellPos.mnRow++)
                     {
+                        // add RowHeight to CellBorderArray for primitive 
creation
+                        aArray.SetRowHeight(aCellPos.mnRow, 
rTableLayouter.getRowHeight(aCellPos.mnRow));
+
                         for(aCellPos.mnCol = 0; aCellPos.mnCol < nColCount; 
aCellPos.mnCol++)
                         {
+                            // add ColWidth to CellBorderArray for primitive 
creation, only
+                            // needs to be done in the 1st run
+                            if(0 == aCellPos.mnRow)
+                            {
+                                aArray.SetColWidth(aCellPos.mnCol, 
rTableLayouter.getColumnWidth(aCellPos.mnCol));
+                            }
+
+                            // access the cell
                             xCurrentCell.set(dynamic_cast< sdr::table::Cell* 
>(xTable->getCellByPosition(aCellPos.mnCol, aCellPos.mnRow).get()));
 
+                            if(xCurrentCell.is())
+                            {
+                                // copy styles for current cell to 
CellBorderArray for primitive creation
+                                aArray.SetCellStyleLeft(aCellPos.mnCol, 
aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow, 
false, nColCount, nRowCount, bIsRTL));
+                                aArray.SetCellStyleRight(aCellPos.mnCol, 
aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol + 1, 
aCellPos.mnRow, false, nColCount, nRowCount, bIsRTL));
+                                aArray.SetCellStyleTop(aCellPos.mnCol, 
aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow, 
true, nColCount, nRowCount, bIsRTL));
+                                aArray.SetCellStyleBottom(aCellPos.mnCol, 
aCellPos.mnRow, impGetLineStyle(rTableLayouter, aCellPos.mnCol, aCellPos.mnRow 
+ 1, true, nColCount, nRowCount, bIsRTL));
+
+                                // ignore merged cells (all except the 
top-left of a merged cell)
+                                if(!xCurrentCell->isMerged())
+                                {
+                                    // check if we are the top-left of a 
merged cell
+                                    const sal_Int32 
nXSpan(xCurrentCell->getColumnSpan());
+                                    const sal_Int32 
nYSpan(xCurrentCell->getRowSpan());
+
+                                    if(nXSpan > 1 || nYSpan > 1)
+                                    {
+                                        // if merged, set so at 
CellBorderArray for primitive creation
+                                        aArray.SetMergedRange(aCellPos.mnCol, 
aCellPos.mnRow, aCellPos.mnCol + nXSpan - 1, aCellPos.mnRow + nYSpan - 1);
+                                    }
+                                }
+                            }
+
                             if(xCurrentCell.is() && !xCurrentCell->isMerged())
                             {
                                 if(rTableLayouter.getCellArea(xCurrentCell, 
aCellPos, aCellArea))
@@ -318,77 +324,54 @@ namespace sdr
                                                 aCellMatrix, aAttribute));
                                         aRetval.append(xCellReference);
                                     }
-
-                                    // handle cell borders
-                                    const sal_Int32 nX(bIsRTL ? nColCount - 
aCellPos.mnCol : aCellPos.mnCol);
-                                    const sal_Int32 nY(aCellPos.mnRow);
-
-                                    // get access values for X,Y at the cell's 
end
-                                    const sal_Int32 
nXSpan(xCurrentCell->getColumnSpan());
-                                    const sal_Int32 
nYSpan(xCurrentCell->getRowSpan());
-                                    const sal_Int32 nXRight(bIsRTL ? nX - 
nXSpan : nX + nXSpan);
-                                    const sal_Int32 nYBottom(nY + nYSpan);
-
-                                    // get basic lines
-                                    const svx::frame::Style 
aLeftLine(impGetLineStyle(rTableLayouter, nX, nY, false, nColCount, nRowCount, 
bIsRTL));
-                                    //To resolve the bug fdo#59117
-                                    //In RTL table as BottomLine & TopLine are 
drawn from Left Side to Right, nX should be nX-1
-                                    const svx::frame::Style 
aBottomLine(impGetLineStyle(rTableLayouter, bIsRTL?nX-1:nX, nYBottom, true, 
nColCount, nRowCount, bIsRTL));
-                                    const svx::frame::Style 
aRightLine(impGetLineStyle(rTableLayouter, nXRight, nY, false, nColCount, 
nRowCount, bIsRTL));
-                                    const svx::frame::Style 
aTopLine(impGetLineStyle(rTableLayouter, bIsRTL?nX-1:nX, nY, true, nColCount, 
nRowCount, bIsRTL));
-
-                                    if(aLeftLine.IsUsed() || 
aBottomLine.IsUsed() || aRightLine.IsUsed() || aTopLine.IsUsed())
-                                    {
-                                        // get the neighbor cells' borders
-                                        const svx::frame::Style 
aLeftFromTLine(impGetLineStyle(rTableLayouter, nX, nY - 1, false, nColCount, 
nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aLeftFromBLine(impGetLineStyle(rTableLayouter, nX, nYBottom, false, nColCount, 
nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aRightFromTLine(impGetLineStyle(rTableLayouter, nXRight, nY - 1, false, 
nColCount, nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aRightFromBLine(impGetLineStyle(rTableLayouter, nXRight, nYBottom, false, 
nColCount, nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aTopFromLLine(impGetLineStyle(rTableLayouter, nX - 1, nY, true, nColCount, 
nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aTopFromRLine(impGetLineStyle(rTableLayouter, nXRight, nY, true, nColCount, 
nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aBottomFromLLine(impGetLineStyle(rTableLayouter, nX - 1, nYBottom, true, 
nColCount, nRowCount, bIsRTL));
-                                        const svx::frame::Style 
aBottomFromRLine(impGetLineStyle(rTableLayouter, nXRight, nYBottom, true, 
nColCount, nRowCount, bIsRTL));
-
-                                        // get cell coordinate system
-                                        const basegfx::B2DPoint 
aOrigin(aCellMatrix * basegfx::B2DPoint(0.0, 0.0));
-                                        const basegfx::B2DVector 
aX(aCellMatrix * basegfx::B2DVector(1.0, 0.0));
-                                        const basegfx::B2DVector 
aY(aCellMatrix * basegfx::B2DVector(0.0, 1.0));
-
-                                        if(aLeftLine.IsUsed())
-                                        {
-                                            createForVector(false, 
aBorderSequence, aOrigin, aY, aLeftLine,
-                                                aTopLine, aLeftFromTLine, 
aTopFromLLine,
-                                                aBottomLine, aLeftFromBLine, 
aBottomFromLLine);
-                                        }
-
-                                        if(aBottomLine.IsUsed())
-                                        {
-                                            createForVector(true, 
aBorderSequence, aOrigin + aY, aX, aBottomLine,
-                                                aLeftLine, aBottomFromLLine, 
aLeftFromBLine,
-                                                aRightLine, aBottomFromRLine, 
aRightFromBLine);
-                                        }
-
-                                        if(aRightLine.IsUsed())
-                                        {
-                                            createForVector(false, 
aBorderSequence, aOrigin + aX, aY, aRightLine,
-                                                aTopFromRLine, 
aRightFromTLine, aTopLine,
-                                                aBottomFromRLine, 
aRightFromBLine, aBottomLine);
-                                        }
-
-                                        if(aTopLine.IsUsed())
-                                        {
-                                            createForVector(true, 
aBorderSequence, aOrigin, aX, aTopLine,
-                                                aLeftFromTLine, aTopFromLLine, 
aLeftLine,
-                                                aRightFromTLine, 
aTopFromRLine, aRightLine);
-                                        }
-                                    }
                                 }
                             }
                         }
                     }
 
-                    // append Border info to target. We want fillings and text 
first
-                    aRetval.append(aBorderSequence);
+                    // now create all CellBorderPrimitives
+                    const drawinglayer::primitive2d::Primitive2DContainer 
aCellBorderPrimitives(aArray.CreateB2DPrimitiveArray());
+
+                    if(!aCellBorderPrimitives.empty())
+                    {
+                        // this is already scaled (due to Table in non-uniform 
coordinates), so
+                        // first transform removing scale
+                        basegfx::B2DHomMatrix aTransform(
+                            basegfx::utils::createScaleB2DHomMatrix(
+                                1.0 / aObjectRange.getWidth(),
+                                1.0 / aObjectRange.getHeight()));
+
+                        // If RTL, mirror the whole unified table in X and 
move right.
+                        // This is much easier than taking this into account 
for the whole
+                        // index calcualtions
+                        if(bIsRTL)
+                        {
+                            aTransform.scale(-1.0, 1.0);
+                            aTransform.translate(1.0, 0.0);
+                        }
+
+                        // create object matrix
+                        const GeoStat& rGeoStat(rTableObj.GetGeoStat());
+                        const double fShearX(rGeoStat.nShearAngle ? tan((36000 
- rGeoStat.nShearAngle) * F_PI18000) : 0.0);
+                        const double fRotate(rGeoStat.nRotationAngle ? (36000 
- rGeoStat.nRotationAngle) * F_PI18000 : 0.0);
+                        const basegfx::B2DHomMatrix 
aObjectMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
+                            aObjectRange.getWidth(), aObjectRange.getHeight(), 
fShearX, fRotate,
+                            aObjectRange.getMinX(), aObjectRange.getMinY()));
+
+                        // add object matrix to transform. By doing so 
theoretically
+                        // CellBorders could be also rotated/sheared for the 
first time ever.
+                        // To completely make that work, the primitives 
already created in
+                        // aRetval would also have to be based on 
ObjectMatrix, not only on
+                        // ObjectRange as it currently is.
+                        aTransform *= aObjectMatrix;
+
+                        // create a transform primitive with this and embed 
CellBorders
+                        // and append to retval
+                        aRetval.append(
+                            new 
drawinglayer::primitive2d::TransformPrimitive2D(
+                                aTransform,
+                                aCellBorderPrimitives));
+                    }
                 }
 
                 if(!aRetval.empty())
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to