Kaydet (Commit) 1e219021 authored tarafından Mark Hung's avatar Mark Hung

tdf#117884: intersect border with paint area of upper frame.

This patch fix regression caused by e87cc12e and allow
table borders rendered in the left or right page margin.

Also add another test case (testTableExtrusion2) to assure
inner table can't have wider border than outer table.

Change-Id: I7a86b379dee08fb2f23385183a42d0ebde007370
Reviewed-on: https://gerrit.libreoffice.org/54862Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMark Hung <marklh9@gmail.com>
üst 4be44a7a
...@@ -20,6 +20,8 @@ public: ...@@ -20,6 +20,8 @@ public:
void testTdf116925(); void testTdf116925();
void testTdf117028(); void testTdf117028();
void testTdf106390(); void testTdf106390();
void testTableExtrusion1();
void testTableExtrusion2();
void testTdf116848(); void testTdf116848();
void testTdf117245(); void testTdf117245();
...@@ -28,6 +30,8 @@ public: ...@@ -28,6 +30,8 @@ public:
CPPUNIT_TEST(testTdf116925); CPPUNIT_TEST(testTdf116925);
CPPUNIT_TEST(testTdf117028); CPPUNIT_TEST(testTdf117028);
CPPUNIT_TEST(testTdf106390); CPPUNIT_TEST(testTdf106390);
CPPUNIT_TEST(testTableExtrusion1);
CPPUNIT_TEST(testTableExtrusion2);
CPPUNIT_TEST(testTdf116848); CPPUNIT_TEST(testTdf116848);
CPPUNIT_TEST(testTdf117245); CPPUNIT_TEST(testTdf117245);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
...@@ -132,6 +136,45 @@ void SwLayoutWriter::testTdf106390() ...@@ -132,6 +136,45 @@ void SwLayoutWriter::testTdf106390()
assertXPath(pXmlDoc, sXPath, 0); assertXPath(pXmlDoc, sXPath, 0);
} }
void SwLayoutWriter::testTableExtrusion1()
{
SwDoc* pDoc = createDoc("table-extrusion1.odt");
SwDocShell* pShell = pDoc->GetDocShell();
// Dump the rendering of the first page as an XML file.
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
MetafileXmlDump dumper;
xmlDocPtr pXmlDoc = dumper.dumpAndParse(*xMetaFile);
CPPUNIT_ASSERT(pXmlDoc);
sal_Int32 nRight = getXPath(pXmlDoc, "//sectrectclipregion", "right").toInt32();
sal_Int32 nLeft = (nRight + getXPath(pXmlDoc, "(//rect)[1]", "right").toInt32()) / 2;
// Expect table borders in right page margin.
const OString sXPath = "//polyline/point[@x>" + OString::number(nLeft) + " and @x<"
+ OString::number(nRight) + "]";
assertXPath(pXmlDoc, sXPath, 4);
}
void SwLayoutWriter::testTableExtrusion2()
{
SwDoc* pDoc = createDoc("table-extrusion2.odt");
SwDocShell* pShell = pDoc->GetDocShell();
// Dump the rendering of the first page as an XML file.
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
MetafileXmlDump dumper;
xmlDocPtr pXmlDoc = dumper.dumpAndParse(*xMetaFile);
CPPUNIT_ASSERT(pXmlDoc);
// End point position of the outer table.
sal_Int32 nX = getXPath(pXmlDoc, "(//polyline[1]/point)[2]", "x").toInt32();
// Do not allow inner table extrude outer table.
const OString sXPath = "//polyline/point[@x>" + OString::number(nX) + "]";
assertXPath(pXmlDoc, sXPath, 0);
}
void SwLayoutWriter::testTdf116848() void SwLayoutWriter::testTdf116848()
{ {
SwDoc* pDoc = createDoc("tdf116848.odt"); SwDoc* pDoc = createDoc("tdf116848.odt");
......
...@@ -2308,8 +2308,8 @@ class SwTabFramePainter ...@@ -2308,8 +2308,8 @@ class SwTabFramePainter
const SwTabFrame& mrTabFrame; const SwTabFrame& mrTabFrame;
void Insert( SwLineEntry&, bool bHori ); void Insert( SwLineEntry&, bool bHori );
void Insert( const SwFrame& rFrame, const SvxBoxItem& rBoxItem ); void Insert(const SwFrame& rFrame, const SvxBoxItem& rBoxItem, const SwRect &rPaintArea);
void HandleFrame( const SwLayoutFrame& rFrame ); void HandleFrame(const SwLayoutFrame& rFrame, const SwRect& rPaintArea);
void FindStylesForLine( const Point&, void FindStylesForLine( const Point&,
const Point&, const Point&,
svx::frame::Style*, svx::frame::Style*,
...@@ -2324,10 +2324,11 @@ public: ...@@ -2324,10 +2324,11 @@ public:
SwTabFramePainter::SwTabFramePainter( const SwTabFrame& rTabFrame ) SwTabFramePainter::SwTabFramePainter( const SwTabFrame& rTabFrame )
: mrTabFrame( rTabFrame ) : mrTabFrame( rTabFrame )
{ {
HandleFrame( rTabFrame ); SwRect aPaintArea = rTabFrame.GetUpper()->GetPaintArea();
HandleFrame(rTabFrame, aPaintArea);
} }
void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame ) void SwTabFramePainter::HandleFrame(const SwLayoutFrame& rLayoutFrame, const SwRect& rPaintArea)
{ {
// Add border lines of cell frames. Skip covered cells. Skip cells // Add border lines of cell frames. Skip covered cells. Skip cells
// in special row span row, which do not have a negative row span: // in special row span row, which do not have a negative row span:
...@@ -2341,7 +2342,7 @@ void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame ) ...@@ -2341,7 +2342,7 @@ void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame )
SwBorderAttrAccess aAccess( SwFrame::GetCache(), &rLayoutFrame ); SwBorderAttrAccess aAccess( SwFrame::GetCache(), &rLayoutFrame );
const SwBorderAttrs& rAttrs = *aAccess.Get(); const SwBorderAttrs& rAttrs = *aAccess.Get();
const SvxBoxItem& rBox = rAttrs.GetBox(); const SvxBoxItem& rBox = rAttrs.GetBox();
Insert( rLayoutFrame, rBox ); Insert(rLayoutFrame, rBox, rPaintArea);
} }
} }
...@@ -2351,7 +2352,7 @@ void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame ) ...@@ -2351,7 +2352,7 @@ void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame )
{ {
const SwLayoutFrame* pLowerLayFrame = dynamic_cast<const SwLayoutFrame*>(pLower); const SwLayoutFrame* pLowerLayFrame = dynamic_cast<const SwLayoutFrame*>(pLower);
if ( pLowerLayFrame && !pLowerLayFrame->IsTabFrame() ) if ( pLowerLayFrame && !pLowerLayFrame->IsTabFrame() )
HandleFrame( *pLowerLayFrame ); HandleFrame(*pLowerLayFrame, rPaintArea);
pLower = pLower->GetNext(); pLower = pLower->GetNext();
} }
...@@ -2725,21 +2726,12 @@ static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines( ...@@ -2725,21 +2726,12 @@ static bool lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
&& rBoxItem.GetBottom()); && rBoxItem.GetBottom());
} }
void SwTabFramePainter::Insert( const SwFrame& rFrame, const SvxBoxItem& rBoxItem ) void SwTabFramePainter::Insert(const SwFrame& rFrame, const SvxBoxItem& rBoxItem, const SwRect& rPaintArea)
{ {
// build 4 line entries for the 4 borders: // build 4 line entries for the 4 borders:
SwRect aBorderRect = rFrame.getFrameArea(); SwRect aBorderRect = rFrame.getFrameArea();
// Frame area of a table might be larger than the containing frame
// so we have to intersect the border rect with upper frames til aBorderRect.Intersection(rPaintArea);
// the first frame that is not part of a table.
const SwLayoutFrame *pUpper = rFrame.GetUpper();
while(pUpper)
{
aBorderRect.Intersection(pUpper->getFrameArea());
if (!pUpper->IsInTab())
break;
pUpper = pUpper->GetUpper();
}
bool const bBottomAsTop(lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines( bool const bBottomAsTop(lcl_IsFirstRowInFollowTableWithoutRepeatedHeadlines(
mrTabFrame, rFrame, rBoxItem)); mrTabFrame, rFrame, rBoxItem));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment