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 <mst...@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 <caol...@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 <mst...@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 <caol...@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 <mst...@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 <caol...@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 <mst...@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 <caol...@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 );
_______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits