summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/viewsh.hxx2
-rw-r--r--sw/source/core/inc/hffrm.hxx6
-rw-r--r--sw/source/core/inc/pagefrm.hxx3
-rw-r--r--sw/source/core/layout/paintfrm.cxx156
-rw-r--r--sw/source/core/view/viewsh.cxx18
5 files changed, 144 insertions, 41 deletions
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 8976452a0dc4..66eec0f5060e 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -188,6 +188,8 @@ class SW_DLLPUBLIC SwViewShell : public sw::Ring<SwViewShell>
SAL_DLLPRIVATE void InvalidateAll(std::vector<LockPaintReason>& rReasons);
+ SAL_DLLPRIVATE void InvalidatePageAndHFSubsidiaryLines();
+
protected:
static ShellResource* spShellRes; ///< Resources for the Shell.
static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > spCareDialog; ///< Avoid this window.
diff --git a/sw/source/core/inc/hffrm.hxx b/sw/source/core/inc/hffrm.hxx
index 32af4dab9e30..4fed2517db1e 100644
--- a/sw/source/core/inc/hffrm.hxx
+++ b/sw/source/core/inc/hffrm.hxx
@@ -22,8 +22,13 @@
#include "layfrm.hxx"
+class SwViewShell;
+
class SwHeadFootFrame : public SwLayoutFrame
{
+private:
+ std::vector<basegfx::B2DPolygon> GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const;
+
protected:
void FormatSize(SwTwips nUL, const SwBorderAttrs * pAttrs);
void FormatPrt(SwTwips & nUL, const SwBorderAttrs * pAttrs);
@@ -37,6 +42,7 @@ public:
virtual SwTwips ShrinkFrame( SwTwips,
bool bTst = false, bool bInfo = false ) override;
virtual void PaintSubsidiaryLines( const SwPageFrame*, const SwRect& ) const override;
+ void AddSubsidiaryLinesBounds(const SwViewShell& rViewShell, RectangleVector& rRects) const;
};
/// Header in the document layout, inside a page.
diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
index d85ddaecd116..53bf27a24bbc 100644
--- a/sw/source/core/inc/pagefrm.hxx
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -123,6 +123,8 @@ class SW_DLLPUBLIC SwPageFrame final: public SwFootnoteBossFrame
/// Calculate the content height of a page (without columns).
size_t GetContentHeight(const tools::Long nTop, const tools::Long nBottom) const;
+ std::vector<basegfx::B2DPolygon> GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const;
+
public:
SwPageFrame( SwFrameFormat*, SwFrame*, SwPageDesc* );
@@ -189,6 +191,7 @@ public:
void PaintDecorators( ) const;
virtual void PaintSubsidiaryLines( const SwPageFrame*, const SwRect& ) const override;
+ void AddSubsidiaryLinesBounds(const SwViewShell& rShell, RectangleVector& rRects) const;
virtual void PaintBreak() const override;
/// Paint line number etc.
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 117ac8eb5e61..7c757e4d19ca 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -18,6 +18,7 @@
*/
#include <utility>
+#include <vcl/canvastools.hxx>
#include <vcl/lazydelete.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/printer.hxx>
@@ -6969,12 +6970,10 @@ static void lcl_RefreshLine( const SwLayoutFrame *pLay,
}
}
-static drawinglayer::primitive2d::Primitive2DContainer lcl_CreatePageAreaDelimiterPrimitives(
- const SwRect& rRect )
+static std::vector<basegfx::B2DPolygon> lcl_CreatePageAreaDelimiterPolygons(const SwRect& rRect)
{
- drawinglayer::primitive2d::Primitive2DContainer aSeq( 4 );
+ std::vector<basegfx::B2DPolygon> aPolygons;
- basegfx::BColor aLineColor = SwViewOption::GetCurrentViewOptions().GetDocBoundariesColor().getBColor();
double nLineLength = 200.0; // in Twips
Point aPoints[] = { rRect.TopLeft(), rRect.TopRight(), rRect.BottomRight(), rRect.BottomLeft() };
@@ -6994,30 +6993,39 @@ static drawinglayer::primitive2d::Primitive2DContainer lcl_CreatePageAreaDelimit
aPolygon.append( aBPoint );
aPolygon.append( aBPoint + aVertVector * nLineLength );
- aSeq[i] = new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
- std::move(aPolygon), aLineColor );
+ aPolygons.emplace_back(aPolygon);
}
- return aSeq;
+ return aPolygons;
}
-static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateRectangleDelimiterPrimitives (
- const SwRect& rRect )
+static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateDelimiterPrimitives(
+ const std::vector<basegfx::B2DPolygon>& rPolygons)
{
- drawinglayer::primitive2d::Primitive2DContainer aSeq( 1 );
+ drawinglayer::primitive2d::Primitive2DContainer aSeq(rPolygons.size());
+
basegfx::BColor aLineColor = SwViewOption::GetCurrentViewOptions().GetDocBoundariesColor().getBColor();
+ for (size_t i = 0; i < rPolygons.size(); ++i)
+ aSeq[i] = new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(rPolygons[i], aLineColor);
- basegfx::B2DPolygon aPolygon;
- aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Top() ) );
- aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Top() ) );
- aPolygon.append( basegfx::B2DPoint( rRect.Right(), rRect.Bottom() ) );
- aPolygon.append( basegfx::B2DPoint( rRect.Left(), rRect.Bottom() ) );
- aPolygon.setClosed( true );
+ return aSeq;
+}
- aSeq[0] = new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
- std::move(aPolygon), aLineColor );
+static std::vector<basegfx::B2DPolygon> lcl_CreateRectangleDelimiterPolygons(const SwRect& rRect)
+{
+ std::vector<basegfx::B2DPolygon> aRet(1);
+ aRet[0].append( basegfx::B2DPoint( rRect.Left(), rRect.Top() ) );
+ aRet[0].append( basegfx::B2DPoint( rRect.Right(), rRect.Top() ) );
+ aRet[0].append( basegfx::B2DPoint( rRect.Right(), rRect.Bottom() ) );
+ aRet[0].append( basegfx::B2DPoint( rRect.Left(), rRect.Bottom() ) );
+ aRet[0].setClosed( true );
+ return aRet;
+}
- return aSeq;
+static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateRectangleDelimiterPrimitives (
+ const SwRect& rRect )
+{
+ return lcl_CreateDelimiterPrimitives(lcl_CreateRectangleDelimiterPolygons(rRect));
}
static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateColumnAreaDelimiterPrimitives(
@@ -7052,14 +7060,12 @@ static drawinglayer::primitive2d::Primitive2DContainer lcl_CreateColumnAreaDelim
return aSeq;
}
-void SwPageFrame::PaintSubsidiaryLines( const SwPageFrame *,
- const SwRect & ) const
+std::vector<basegfx::B2DPolygon> SwPageFrame::GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const
{
- if (!gProp.pSGlobalShell->GetViewOptions()->IsDocBoundaries())
- return;
+ std::vector<basegfx::B2DPolygon> aPolygons;
- if ( gProp.pSGlobalShell->IsHeaderFooterEdit() )
- return;
+ if (!rViewShell.GetViewOptions()->IsDocBoundaries())
+ return aPolygons;
const SwFrame* pLay = Lower();
const SwFrame* pFootnoteCont = nullptr;
@@ -7079,10 +7085,64 @@ void SwPageFrame::PaintSubsidiaryLines( const SwPageFrame *,
if ( pFootnoteCont )
aArea.AddBottom( pFootnoteCont->getFrameArea().Bottom() - aArea.Bottom() );
- if ( !gProp.pSGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
- ProcessPrimitives( lcl_CreatePageAreaDelimiterPrimitives( aArea ) );
+ if (aArea.IsEmpty())
+ return aPolygons;
+
+ if (!rViewShell.GetViewOptions()->IsViewMetaChars())
+ aPolygons = lcl_CreatePageAreaDelimiterPolygons(aArea);
else
- ProcessPrimitives( lcl_CreateRectangleDelimiterPrimitives( aArea ) );
+ aPolygons = lcl_CreateRectangleDelimiterPolygons(aArea);
+
+ return aPolygons;
+}
+
+void SwPageFrame::PaintSubsidiaryLines(const SwPageFrame*, const SwRect&) const
+{
+ if (gProp.pSGlobalShell->IsHeaderFooterEdit())
+ return;
+
+ std::vector<basegfx::B2DPolygon> aPolygons = GetSubsidiaryLinesPolygons(*gProp.pSGlobalShell);
+ if (aPolygons.empty())
+ return;
+
+ ProcessPrimitives(lcl_CreateDelimiterPrimitives(aPolygons));
+}
+
+static void lclAddSubsidiaryLinesBounds(const std::vector<basegfx::B2DPolygon>& rPolygons, RectangleVector& rRects)
+{
+ for (const auto& rPolygon : rPolygons)
+ {
+ tools::Rectangle aRect(vcl::unotools::rectangleFromB2DRectangle(rPolygon.getB2DRange()));
+ aRect.expand(1);
+ if (basegfx::utils::isRectangle(rPolygon) && aRect.GetWidth() > 4 && aRect.GetHeight() > 4)
+ {
+ // turn hairline rectangle into four non-overlapping blocks that cover the borders
+ rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top()), Size(aRect.GetWidth(), 2)));
+ rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top() + 2), Size(2, aRect.GetHeight() - 4)));
+ rRects.emplace_back(tools::Rectangle(Point(aRect.Right() - 2, aRect.Top() + 2), Size(2, aRect.GetHeight() - 4)));
+ rRects.emplace_back(tools::Rectangle(Point(aRect.Left(), aRect.Top() + aRect.GetHeight() - 2), Size(aRect.GetWidth(), 2)));
+ }
+ else
+ rRects.emplace_back(aRect);
+ }
+}
+
+void SwPageFrame::AddSubsidiaryLinesBounds(const SwViewShell& rViewShell, RectangleVector& rRects) const
+{
+ lclAddSubsidiaryLinesBounds(GetSubsidiaryLinesPolygons(rViewShell), rRects);
+
+ const SwFrame *pLow = Lower();
+ while (pLow)
+ {
+ if (pLow->getFrameArea().HasArea())
+ {
+ if (pLow->IsHeaderFrame() || pLow->IsFooterFrame())
+ {
+ static_cast<const SwHeadFootFrame*>(pLow)->AddSubsidiaryLinesBounds(rViewShell, rRects);
+ }
+ }
+ pLow = pLow->GetNext();
+ }
}
void SwColumnFrame::PaintSubsidiaryLines( const SwPageFrame *,
@@ -7148,20 +7208,38 @@ void SwBodyFrame::PaintSubsidiaryLines( const SwPageFrame *,
{
}
-void SwHeadFootFrame::PaintSubsidiaryLines( const SwPageFrame *, const SwRect & ) const
+std::vector<basegfx::B2DPolygon> SwHeadFootFrame::GetSubsidiaryLinesPolygons(const SwViewShell& rViewShell) const
+{
+ std::vector<basegfx::B2DPolygon> aPolygons;
+
+ if (!rViewShell.GetViewOptions()->IsDocBoundaries())
+ return aPolygons;
+
+ SwRect aArea( getFramePrintArea() );
+ aArea.Pos() += getFrameArea().Pos();
+ if (!rViewShell.GetViewOptions()->IsViewMetaChars( ))
+ aPolygons = lcl_CreatePageAreaDelimiterPolygons(aArea);
+ else
+ aPolygons = lcl_CreateRectangleDelimiterPolygons(aArea);
+
+ return aPolygons;
+}
+
+void SwHeadFootFrame::PaintSubsidiaryLines(const SwPageFrame*, const SwRect&) const
{
- if (!gProp.pSGlobalShell->GetViewOptions()->IsDocBoundaries())
+ if (!gProp.pSGlobalShell->IsHeaderFooterEdit())
return;
- if ( gProp.pSGlobalShell->IsHeaderFooterEdit() )
- {
- SwRect aArea( getFramePrintArea() );
- aArea.Pos() += getFrameArea().Pos();
- if ( !gProp.pSGlobalShell->GetViewOptions()->IsViewMetaChars( ) )
- ProcessPrimitives( lcl_CreatePageAreaDelimiterPrimitives( aArea ) );
- else
- ProcessPrimitives( lcl_CreateRectangleDelimiterPrimitives( aArea ) );
- }
+ std::vector<basegfx::B2DPolygon> aPolygons = GetSubsidiaryLinesPolygons(*gProp.pSGlobalShell);
+ if (aPolygons.empty())
+ return;
+
+ ProcessPrimitives(lcl_CreateDelimiterPrimitives(aPolygons));
+}
+
+void SwHeadFootFrame::AddSubsidiaryLinesBounds(const SwViewShell& rViewShell, RectangleVector& rRects) const
+{
+ lclAddSubsidiaryLinesBounds(GetSubsidiaryLinesPolygons(rViewShell), rRects);
}
/**
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index 9074f43ab8b4..a77d0ccc8bcf 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -126,8 +126,22 @@ void SwViewShell::ToggleHeaderFooterEdit()
mbHeaderFooterEdit = false;
}
- // Repaint everything
- GetWin()->Invalidate();
+ InvalidatePageAndHFSubsidiaryLines();
+}
+
+// Invalidate Subsidiary Lines around headers/footers and page frames to repaint
+void SwViewShell::InvalidatePageAndHFSubsidiaryLines()
+{
+ RectangleVector aInvalidRects;
+ SwPageFrame *pPg = static_cast<SwPageFrame*>(GetLayout()->Lower());
+ while (pPg)
+ {
+ pPg->AddSubsidiaryLinesBounds(*this, aInvalidRects);
+ pPg = static_cast<SwPageFrame*>(pPg->GetNext());
+ }
+
+ for (const auto &rRect : aInvalidRects)
+ GetWin()->Invalidate(rRect);
}
void SwViewShell::setOutputToWindow(bool bOutputToWindow)