tdf#134709 writerfilter: consider gridBefore for table borders

When the table itself defines borders, those borders should
apply to the first cell in each row - even if some grids
are skipped with gridBefore. (i.e. it won't be a straight line
on the left side).

Most of the changes here are just simplifications,
since the original code import was overly complex.

This commit depends on some refactoring done for bug 129452
in LO 7.1.

A followup commit is needed do the same thing for gridAfter,
but currently gridAfter is not yet populated,
so some foundational work needs to be done first.

Change-Id: Ic7dd17fa80422520f3ccf1b121a2abb288b88ccb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98534
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
This commit is contained in:
Justin Luth 2020-07-10 17:27:51 +03:00 committed by Justin Luth
parent 03803de58b
commit fafc6c0fc3
5 changed files with 37 additions and 16 deletions

Binary file not shown.

View file

@ -127,6 +127,25 @@ DECLARE_OOXMLEXPORT_TEST(testTdf131561_necessaryBorder, "tdf131561_necessaryBord
CPPUNIT_ASSERT_MESSAGE("Border between A3 and B3", (aBorderR.LineWidth + aBorderL.LineWidth) > 0);
}
DECLARE_OOXMLEXPORT_TEST(testTdf134609_gridAfter, "tdf134609_gridAfter.docx")
{
uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
// Table borders (width 159) apply to edge cells, even in uneven cases caused by gridBefore/gridAfter,
table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xTable->getCellByName("A1"), "RightBorder");
//CPPUNIT_ASSERT_MESSAGE("Right border before gridAfter cells", aBorder.LineWidth > 0);
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName("E2"), "LeftBorder");
CPPUNIT_ASSERT_MESSAGE("Left edge border after gridBefore cells", aBorder.LineWidth > 100);
aBorder = getProperty<table::BorderLine2>(xTable->getCellByName("E2"), "TopBorder");
// but only for left/right borders, not top and bottom.
// So somewhat inconsistently, gridBefore/After affects outside edges of columns, but not of rows.
// insideH borders are width 53. (no insideV borders defined to emphasize missing edge borders)
CPPUNIT_ASSERT_MESSAGE("Top border on 'inside' cell", aBorder.LineWidth > 0);
CPPUNIT_ASSERT_MESSAGE("Top border is not an edge border", aBorder.LineWidth < 100);
}
DECLARE_OOXMLEXPORT_TEST(testTdf134063, "tdf134063.docx")
{
CPPUNIT_ASSERT_EQUAL(2, getPages());

View file

@ -103,8 +103,9 @@ static void lcl_mergeBorder( PropertyIds nId, const PropertyMapPtr& pOrig, const
}
static void lcl_computeCellBorders( const PropertyMapPtr& pTableBorders, const PropertyMapPtr& pCellProps,
sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow, bool bMergedVertically )
sal_uInt32 nCell, sal_uInt32 nFirstCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow, bool bMergedVertically )
{
const bool bIsStartCol = nCell == nFirstCell;
std::optional<PropertyMap::Property> pVerticalVal = pCellProps->getProperty(META_PROP_VERTICAL_BORDER);
std::optional<PropertyMap::Property> pHorizontalVal = pCellProps->getProperty(META_PROP_HORIZONTAL_BORDER);
@ -135,28 +136,19 @@ static void lcl_computeCellBorders( const PropertyMapPtr& pTableBorders, const P
pCellProps->Erase( pHorizontalVal->first );
}
if ( nCell == 0 )
{
if ( bIsStartCol )
lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps );
// <w:insideV> counts if there are multiple cells in this row.
if (pVerticalVal && !bIsEndCol)
pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
}
if ( bIsEndCol )
{
lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps );
if ( pVerticalVal )
pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
}
if ( nCell > 0 && !bIsEndCol )
// <w:insideV> counts if there are multiple cells in this row.
if ( pVerticalVal )
{
if ( pVerticalVal )
{
if ( !bIsEndCol && nCell >= nFirstCell )
pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
if ( !bIsStartCol )
pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
}
}
if ( nRow == 0 )
@ -937,7 +929,8 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
}
}
lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow, bMergedVertically );
const sal_uInt32 nFirstCell = m_rDMapper_Impl.getTableManager().getGridBefore(nRow);
lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nFirstCell, nRow, bIsEndCol, bIsEndRow, bMergedVertically );
//now set the default left+right border distance TODO: there's an sprm containing the default distance!
aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE,

View file

@ -49,6 +49,14 @@ void TableManager::openCell(const css::uno::Reference<css::text::XTextRange>& rH
bool TableManager::isIgnore() const { return isRowEnd(); }
sal_uInt32 TableManager::getGridBefore(sal_uInt32 nRow)
{
assert(isInTable());
if (nRow >= mTableDataStack.top()->getRowCount())
return 0;
return mTableDataStack.top()->getRow(nRow)->getGridBefore();
}
sal_uInt32 TableManager::getCurrentGridBefore()
{
return mTableDataStack.top()->getCurrentRow()->getGridBefore();

View file

@ -500,6 +500,7 @@ public:
*/
bool isIgnore() const;
sal_uInt32 getGridBefore(sal_uInt32 nRow);
sal_uInt32 getCurrentGridBefore();
void setCurrentGridBefore( sal_uInt32 nSkipGrids );
std::vector<sal_uInt32> getCurrentGridSpans();