[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 4 commits - drawinglayer/source sw/source

Caolán McNamara caolan at kemper.freedesktop.org
Fri Apr 20 06:15:03 PDT 2012


 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx |   22 +
 sw/source/core/layout/paintfrm.cxx                        |  185 ++++++++++++--
 2 files changed, 180 insertions(+), 27 deletions(-)

New commits:
commit e435a78af84f04e1ea8907c70447a87841aa1186
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Apr 16 16:12:36 2012 +0200

    fdo#38215: merge consecutive border lines:
    
    This re-implements the merging that was done by SwLineRects::AddLineRect,
    SwLineRect::MakeUnion with the drawing layer border lines.
    This is used to merge borders of paragraphs and of tables that have the
    "separating" border-model, which fixes both the tiny dividing gaps
    between successive borders in the second bugdoc and the weird subtly
    differently rendered successive borders in the first bugdoc.
    (regression from 0f0896c26fb260d1bbf31d7a886df3f61837f0f2)
    
    (cherry-picked from 0868a0155a2b57daf7b862d120aead0458372b17
     and 44092833d3a0f0d6074c64bd0e64bbdf11109afe)
    
    Conflicts:
    
    	sw/source/core/layout/paintfrm.cxx
    
    Signed-off-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 1fd7013..797f3af 100755
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -132,6 +132,9 @@
 
 using namespace ::editeng;
 using namespace ::com::sun::star;
+using ::drawinglayer::primitive2d::BorderLinePrimitive2D;
+using ::std::pair;
+using ::std::make_pair;
 
 #define GETOBJSHELL()       ((SfxObjectShell*)rSh.GetDoc()->GetDocShell())
 
@@ -223,19 +226,21 @@ public:
 
 class BorderLines
 {
-    ::comphelper::SequenceAsVector<
-         ::drawinglayer::primitive2d::Primitive2DReference> m_Lines;
+    typedef ::comphelper::SequenceAsVector<
+        ::rtl::Reference<BorderLinePrimitive2D> > Lines_t;
+    Lines_t m_Lines;
 public:
-    void AddBorderLine(
-            ::drawinglayer::primitive2d::Primitive2DReference const& xLine)
-    {
-        m_Lines.push_back(xLine);
-    }
+    void AddBorderLine(::rtl::Reference<BorderLinePrimitive2D> const& xLine);
     drawinglayer::primitive2d::Primitive2DSequence GetBorderLines_Clear()
     {
         ::comphelper::SequenceAsVector<
             ::drawinglayer::primitive2d::Primitive2DReference> lines;
-        ::std::swap(m_Lines, lines);
+        for (Lines_t::const_iterator it = m_Lines.begin(); it != m_Lines.end();
+                ++it)
+        {
+            lines.push_back(it->get());
+        }
+        m_Lines.clear();
         return lines.getAsConstList();
     }
 };
@@ -442,6 +447,121 @@ SwSavePaintStatics::~SwSavePaintStatics()
 
 SV_IMPL_VARARR( SwLRects, SwLineRect );
 
+static pair<bool, pair<double, double> >
+lcl_TryMergeLines(pair<double, double> const mergeA,
+                  pair<double, double> const mergeB)
+{
+    double const fMergeGap(nPixelSzW + nHalfPixelSzW); // NOT static!
+    if (   (mergeA.second + fMergeGap >= mergeB.first )
+        && (mergeA.first  - fMergeGap <= mergeB.second))
+    {
+        return make_pair(true, make_pair(
+                                std::min(mergeA.first, mergeB.first),
+                                std::max(mergeA.second, mergeB.second)));
+    }
+    return make_pair(false, make_pair(0, 0));
+}
+
+static ::rtl::Reference<BorderLinePrimitive2D>
+lcl_MergeBorderLines(
+    BorderLinePrimitive2D const& rLine, BorderLinePrimitive2D const& rOther,
+    basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd)
+{
+    return new BorderLinePrimitive2D(rStart, rEnd,
+                rLine.getLeftWidth(),
+                rLine.getDistance(),
+                rLine.getRightWidth(),
+                rLine.getExtendLeftStart(),
+                rOther.getExtendLeftEnd(),
+                rLine.getExtendRightStart(),
+                rOther.getExtendRightEnd(),
+                rLine.getRGBColorLeft(),
+                rLine.getRGBColorGap(),
+                rLine.getRGBColorRight(),
+                rLine.hasGapColor(),
+                rLine.getStyle());
+}
+
+static ::rtl::Reference<BorderLinePrimitive2D>
+lcl_TryMergeBorderLine(BorderLinePrimitive2D const& rThis,
+                       BorderLinePrimitive2D const& rOther)
+{
+    assert(rThis.getEnd().getX() >= rThis.getStart().getX());
+    assert(rThis.getEnd().getY() >= rThis.getStart().getY());
+    assert(rOther.getEnd().getX() >= rOther.getStart().getX());
+    assert(rOther.getEnd().getY() >= rOther.getStart().getY());
+    double thisHeight = rThis.getEnd().getY() - rThis.getStart().getY();
+    double thisWidth  = rThis.getEnd().getX() - rThis.getStart().getX();
+    double otherHeight = rOther.getEnd().getY() -  rOther.getStart().getY();
+    double otherWidth  = rOther.getEnd().getX() -  rOther.getStart().getX();
+    // check for same orientation, same line width and matching colors
+    if (    ((thisHeight > thisWidth) == (otherHeight > otherWidth))
+        &&  (rThis.getLeftWidth()     == rOther.getLeftWidth())
+        &&  (rThis.getDistance()      == rOther.getDistance())
+        &&  (rThis.getRightWidth()    == rOther.getRightWidth())
+        &&  (rThis.getRGBColorLeft()  == rOther.getRGBColorLeft())
+        &&  (rThis.getRGBColorRight() == rOther.getRGBColorRight())
+        &&  (rThis.hasGapColor()      == rOther.hasGapColor())
+        &&  (!rThis.hasGapColor() ||
+             (rThis.getRGBColorGap()  == rOther.getRGBColorGap())))
+    {
+        if (thisHeight > thisWidth) // vertical line
+        {
+            if (rThis.getStart().getX() == rOther.getStart().getX())
+            {
+                assert(rThis.getEnd().getX() == rOther.getEnd().getX());
+                pair<bool, pair<double, double> > const res = lcl_TryMergeLines(
+                    make_pair(rThis.getStart().getY(), rThis.getEnd().getY()),
+                    make_pair(rOther.getStart().getY(),rOther.getEnd().getY()));
+                if (res.first) // merge them
+                {
+                    basegfx::B2DPoint const start(
+                            rThis.getStart().getX(), res.second.first);
+                    basegfx::B2DPoint const end(
+                            rThis.getStart().getX(), res.second.second);
+                    return lcl_MergeBorderLines(rThis, rOther, start, end);
+                }
+            }
+        }
+        else // horizontal line
+        {
+            if (rThis.getStart().getY() == rOther.getStart().getY())
+            {
+                assert(rThis.getEnd().getY() == rOther.getEnd().getY());
+                pair<bool, pair<double, double> > const res = lcl_TryMergeLines(
+                    make_pair(rThis.getStart().getX(), rThis.getEnd().getX()),
+                    make_pair(rOther.getStart().getX(),rOther.getEnd().getX()));
+                if (res.first) // merge them
+                {
+                    basegfx::B2DPoint const start(
+                            res.second.first, rThis.getStart().getY());
+                    basegfx::B2DPoint const end(
+                            res.second.second, rThis.getEnd().getY());
+                    return lcl_MergeBorderLines(rThis, rOther, start, end);
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+void BorderLines::AddBorderLine(
+        rtl::Reference<BorderLinePrimitive2D> const& xLine)
+{
+    for (Lines_t::reverse_iterator it = m_Lines.rbegin(); it != m_Lines.rend();
+         ++it)
+    {
+        ::rtl::Reference<BorderLinePrimitive2D> const xMerged =
+            lcl_TryMergeBorderLine(**it, *xLine);
+        if (xMerged.is())
+        {
+            *it = xMerged; // replace existing line with merged
+            return;
+        }
+    }
+    m_Lines.push_back(xLine);
+}
+
 SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderStyle nStyl,
                         const SwTabFrm *pT, const sal_uInt8 nSCol ) :
     SwRect( rRect ),
@@ -4519,8 +4639,8 @@ void lcl_PaintLeftRightLine( const sal_Bool         _bLeft,
         Color aLeftColor = _bLeft ? pLeftRightBorder->GetColorOut( _bLeft ) : pLeftRightBorder->GetColorIn( _bLeft );
         Color aRightColor = _bLeft ? pLeftRightBorder->GetColorIn( _bLeft ) : pLeftRightBorder->GetColorOut( _bLeft );
 
-        drawinglayer::primitive2d::Primitive2DReference xLine =
-            new drawinglayer::primitive2d::BorderLinePrimitive2D(
+        ::rtl::Reference<BorderLinePrimitive2D> xLine =
+            new BorderLinePrimitive2D(
                 aStart, aEnd, nLeftWidth, pLeftRightBorder->GetDistance(), nRightWidth,
                 nExtentIS, nExtentIE, nExtentOS, nExtentOE,
                 aLeftColor.getBColor(), aRightColor.getBColor(),
@@ -4601,8 +4721,8 @@ void lcl_PaintTopBottomLine( const sal_Bool         _bTop,
         Color aLeftColor = _bTop ? pTopBottomBorder->GetColorOut( _bTop ) : pTopBottomBorder->GetColorIn( _bTop );
         Color aRightColor = _bTop ? pTopBottomBorder->GetColorIn( _bTop ) : pTopBottomBorder->GetColorOut( _bTop );
 
-        drawinglayer::primitive2d::Primitive2DReference xLine =
-            new drawinglayer::primitive2d::BorderLinePrimitive2D(
+        ::rtl::Reference<BorderLinePrimitive2D> xLine =
+            new BorderLinePrimitive2D(
                 aStart, aEnd, nLeftWidth, pTopBottomBorder->GetDistance(), nRightWidth,
                 nExtentIS, nExtentIE, nExtentOS, nExtentOE,
                 aLeftColor.getBColor(), aRightColor.getBColor(),
commit e3cd3c72b20e4e0918e86edf5c9e3c9bd00ae9e3
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Apr 4 22:35:08 2012 +0200

    fdo#45562: paint borders in SwFlyFrm::Paint:
    
    Painting borders of Flys in the heaven layer cannot be done correctly in
    SwRootFrm::Paint, because delaying until then paints over other drawing
    objects that are on top of the frame, so do it in SwFlyFrm::Paint,
    like the old border painting code used to.
    (regression from 804d0a896731629397c5328c13c04a45bc55f459)
    (cherry picked from commit 5913506b2193e93ca2767ab7365ab2e76ed7848f)
    
    Signed-off-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 435571a..1fd7013 100755
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -3031,8 +3031,6 @@ SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
                 if ( bExtraData )
                     pPage->RefreshExtraData( aPaintRect );
 
-                // have to paint frame borders added in heaven layer here...
-                ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
                 DELETEZ(g_pBorderLines);
                 pVout->Leave();
 
@@ -3751,12 +3749,28 @@ void SwCellFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
 void MA_FASTCALL lcl_PaintLowerBorders( const SwLayoutFrm *pLay,
                                const SwRect &rRect, const SwPageFrm *pPage );
 
+struct BorderLinesGuard
+{
+    explicit BorderLinesGuard() : m_pBorderLines(g_pBorderLines)
+    {
+        g_pBorderLines = new BorderLines;
+    }
+    ~BorderLinesGuard()
+    {
+        delete g_pBorderLines;
+        g_pBorderLines = m_pBorderLines;
+    }
+private:
+    BorderLines *const m_pBorderLines;
+};
+
 void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
 {
     //wegen der Ueberlappung von Rahmen und Zeichenobjekten muessen die
     //Flys ihre Umrandung (und die der Innenliegenden) direkt ausgeben.
     //z.B. #33066#
     pLines->LockLines(sal_True);
+    BorderLinesGuard blg; // this should not paint borders added from PaintBaBo
 
     SwRect aRect( rRect );
     aRect._Intersection( Frm() );
@@ -3966,6 +3980,8 @@ void SwFlyFrm::Paint(SwRect const& rRect, SwPrintData const*const) const
     // and then unlock other lines.
     pLines->PaintLines( pOut );
     pLines->LockLines( sal_False );
+    // have to paint frame borders added in heaven layer here...
+    ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
 
     pOut->Pop();
 
commit 9aacf868fa0dbbbfc6e06ae16042a3ec34991843
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Mar 23 14:08:31 2012 +0100

    fdo#42750 fdo#45562 fdo#47717: border paint ordering:
    
    Paint borders after subsidiary lines and hell layer, but before heaven
    layer.
    (cherry picked from commit 1024c172a5bfb3d85a86fcf7a046aa2b03950edd)
    
    Signed-off-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 69e32ff..435571a 100755
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -231,9 +231,12 @@ public:
     {
         m_Lines.push_back(xLine);
     }
-    drawinglayer::primitive2d::Primitive2DSequence GetBorderLines() const
+    drawinglayer::primitive2d::Primitive2DSequence GetBorderLines_Clear()
     {
-        return m_Lines.getAsConstList();
+        ::comphelper::SequenceAsVector<
+            ::drawinglayer::primitive2d::Primitive2DReference> lines;
+        ::std::swap(m_Lines, lines);
+        return lines.getAsConstList();
     }
 };
 
@@ -3002,6 +3005,16 @@ SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
                 }
 
                 pLines->PaintLines( pSh->GetOut() );
+                if ( pSh->GetWin() )
+                {
+                    pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
+                    DELETEZ( pSubsLines );
+                    DELETEZ( pSpecSubsLines );
+                }
+                // fdo#42750: delay painting these until after subsidiary lines
+                // fdo#45562: delay painting these until after hell layer
+                // fdo#47717: but do it before heaven layer
+                ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
 
                 if ( pSh->Imp()->HasDrawView() )
                 {
@@ -3018,14 +3031,8 @@ SwRootFrm::Paint(SwRect const& rRect, SwPrintData const*const pPrintData) const
                 if ( bExtraData )
                     pPage->RefreshExtraData( aPaintRect );
 
-                if ( pSh->GetWin() )
-                {
-                    pSubsLines->PaintSubsidiary( pSh->GetOut(), pLines );
-                    DELETEZ( pSubsLines );
-                    DELETEZ( pSpecSubsLines );
-                }
-                // fdo#42750: delay painting these until after subsidiary lines
-                ProcessPrimitives(g_pBorderLines->GetBorderLines());
+                // have to paint frame borders added in heaven layer here...
+                ProcessPrimitives(g_pBorderLines->GetBorderLines_Clear());
                 DELETEZ(g_pBorderLines);
                 pVout->Leave();
 
commit 339a502e1f78388512cc8b9ba2117b674c770efc
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Apr 18 22:15:19 2012 +0200

    fdo#48647: drawinglayer: fix double hairline borders:
    
    Clipping the border polygon to the region defined by the Extends is
    sufficient to create a nice looking 1 twip double border in Writer.
    (regression from 0f0896c26fb260d1bbf31d7a886df3f61837f0f2)
    (cherry picked from commit 49bd0e4e6bb0ed0671de72d84700ddcc49828f69)
    
    Signed-off-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 1834d36..86f58d6 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -114,9 +114,14 @@ namespace drawinglayer
                             aLeft.append(aTmpStart);
                             aLeft.append(aTmpEnd);
 
-                            xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
-                                aLeft,
-                                getRGBColorLeft()));
+                            basegfx::B2DPolyPolygon const aClipped =
+                                basegfx::tools::clipPolygonOnPolyPolygon(
+                                    aLeft, aClipRegion, true, true);
+
+                            xRetval[nInsert++] =
+                                new PolyPolygonHairlinePrimitive2D(
+                                    aClipped,
+                                    getRGBColorLeft());
 
                             aGap.append( getStart() - getExtendLeftStart() * aVector );
                             aGap.append( getEnd() + getExtendLeftEnd() * aVector );
@@ -159,9 +164,14 @@ namespace drawinglayer
                             aRight.append(aTmpStart);
                             aRight.append(aTmpEnd);
 
-                            xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
-                                aRight,
-                                getRGBColorRight()));
+                            basegfx::B2DPolyPolygon const aClipped =
+                                basegfx::tools::clipPolygonOnPolyPolygon(
+                                    aRight, aClipRegion, true, true);
+
+                            xRetval[nInsert++] =
+                                new PolyPolygonHairlinePrimitive2D(
+                                    aClipped,
+                                    getRGBColorRight());
 
                             aGap.append( getStart() - getExtendRightStart() * aVector );
                             aGap.append( getEnd() + getExtendRightEnd() * aVector );


More information about the Libreoffice-commits mailing list