Kaydet (Commit) 5d0c83fd authored tarafından Mike Kaganski's avatar Mike Kaganski

tdf#119885: OOXML import: try to get cell paddings as Word does

Change-Id: I7abd715b6bb71d6e2e01939c4cf849d94eb6a103
Reviewed-on: https://gerrit.libreoffice.org/61843
Tested-by: Jenkins
Reviewed-by: 's avatarMike Kaganski <mike.kaganski@collabora.com>
üst c8b68f7d
......@@ -1160,7 +1160,18 @@ DECLARE_OOXMLEXPORT_TEST( testTableCellMargin, "table-cell-margin.docx" )
cellLeftMarginFromOffice[i], aLeftMargin - 0.5 * aLeftBorderLine.LineWidth, 1 );
// The 'a' in the fourth table should not be partly hidden by the border
if ( i == 3 )
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Incorrect cell padding", 0.5 * aLeftBorderLine.LineWidth, aLeftMargin, 1 );
{
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell left padding",
0.5 * aLeftBorderLine.LineWidth, aLeftMargin, 1);
// tdf#119885: cell's edit area must touch right border
sal_Int32 aRightMargin = -1;
xPropSet->getPropertyValue("RightBorderDistance") >>= aRightMargin;
uno::Any aRightBorder = xPropSet->getPropertyValue("RightBorder");
table::BorderLine2 aRightBorderLine;
aRightBorder >>= aRightBorderLine;
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect cell right padding",
0.5 * aRightBorderLine.LineWidth, aRightMargin, 1);
}
}
}
......
......@@ -754,7 +754,7 @@ DECLARE_RTFEXPORT_TEST(testTdf84832, "tdf84832.docx")
{
uno::Reference<table::XCell> xCell = getCell(getParagraphOrTable(2), "A1");
// This was 0, as left padding wasn't exported.
CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(113)),
CPPUNIT_ASSERT_EQUAL(sal_Int32(convertTwipToMm100(108)),
getProperty<sal_Int32>(xCell, "LeftBorderDistance"));
}
......
......@@ -3175,15 +3175,6 @@ static void impl_cellMargins( FSHelperPtr const & pSerializer, const SvxBoxItem&
continue;
}
if ( aBorders[i] == SvxBoxItemLine::LEFT ) {
// Office's cell margin is measured from the right of the border.
// While LO's cell spacing is measured from the center of the border.
// So we add half left-border width to tblIndent value
const SvxBorderLine* pLn = rBox.GetLine( *pBrd );
if (pLn)
nDist -= pLn->GetWidth() * 0.5;
}
if (!tagWritten) {
pSerializer->startElementNS( XML_w, tag, FSEND );
tagWritten = true;
......
......@@ -266,9 +266,7 @@ void lcl_extractHoriOrient(std::vector<beans::PropertyValue>& rFrameProperties,
}
}
}
static void lcl_DecrementHoriOrientPosition(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount)
void lcl_DecrementHoriOrientPosition(std::vector<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount)
{
// Shifts the frame left by the given value.
for (beans::PropertyValue & rPropertyValue : rFrameProperties)
......@@ -283,6 +281,42 @@ static void lcl_DecrementHoriOrientPosition(std::vector<beans::PropertyValue>& r
}
}
void lcl_adjustBorderDistance(TableInfo& rInfo, const table::BorderLine2& rLeftBorder,
const table::BorderLine2& rRightBorder)
{
// MS Word appears to do these things to adjust the cell horizontal area:
//
// bll = left borderline width
// blr = right borderline width
// cea = cell's edit area rectangle
// cea_w = cea width
// cml = cell's left margin (padding) defined in cell settings
// cmr = cell's right margin (padding) defined in cell settings
// cw = cell width (distance between middles of left borderline and right borderline)
// pad_l = actual cea left padding = (its left pos relative to middle of bll)
// pad_r = actual cea right padding = abs (its right pos relative to middle of blr)
//
// pad_l = max(bll/2, cml) -> cea does not overlap left borderline
// cea_w = cw-max(pad_l+blr/2, cml+cmr) -> cea does not overlap right borderline
// pad_r = max(pad_l+blr/2, cml+cmr) - pad_l
//
// It means that e.g. for border widths of 6 pt (~2.12 mm), left margin 0 mm, and right margin
// 2 mm, actual left and right margins will (unexpectedly) coincide with inner edges of cell's
// borderlines - the right margin won't create spacing between right of edit rectangle and the
// inner edge of right borderline.
const sal_Int32 nActualL
= std::max<sal_Int32>(rLeftBorder.LineWidth / 2, rInfo.nLeftBorderDistance);
const sal_Int32 nActualR
= std::max<sal_Int32>(nActualL + rRightBorder.LineWidth / 2,
rInfo.nLeftBorderDistance + rInfo.nRightBorderDistance)
- nActualL;
rInfo.nLeftBorderDistance = nActualL;
rInfo.nRightBorderDistance = nActualR;
}
}
TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, std::vector<beans::PropertyValue>& rFrameProperties)
{
// will receive the table style if any
......@@ -460,7 +494,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
//table border settings
table::TableBorder aTableBorder;
table::BorderLine2 aBorderLine, aLeftBorder;
table::BorderLine2 aBorderLine, aLeftBorder, aRightBorder;
if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_TOP_BORDER, rInfo, aBorderLine))
{
......@@ -477,9 +511,10 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
aTableBorder.LeftLine = aLeftBorder;
aTableBorder.IsLeftLineValid = true;
}
if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_RIGHT_BORDER, rInfo, aBorderLine))
if (lcl_extractTableBorderProperty(m_aTableProperties.get(), PROP_RIGHT_BORDER, rInfo,
aRightBorder))
{
aTableBorder.RightLine = aBorderLine;
aTableBorder.RightLine = aRightBorder;
aTableBorder.IsRightLineValid = true;
}
if (lcl_extractTableBorderProperty(m_aTableProperties.get(), META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine))
......@@ -510,21 +545,22 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
// Only top level table position depends on border width of Column A.
// TODO: Position based on last row (at least in MSOffice 2016), but first row in Office 2003.
// Export code is also based on first cell, so using first row here...
if ( rInfo.nNestLevel == 1 && !m_aCellProperties.empty() && !m_aCellProperties[0].empty() )
if ( !m_aCellProperties.empty() && !m_aCellProperties[0].empty() )
{
// aLeftBorder already contains tblBorder; overwrite if cell is different.
const boost::optional<PropertyMap::Property> aCellBorder
boost::optional<PropertyMap::Property> aCellBorder
= m_aCellProperties[0][0]->getProperty(PROP_LEFT_BORDER);
if ( aCellBorder )
aCellBorder->second >>= aLeftBorder;
aCellBorder = m_aCellProperties[0][0]->getProperty(PROP_RIGHT_BORDER);
if (aCellBorder)
aCellBorder->second >>= aLeftBorder;
}
if ( rInfo.nNestLevel == 1 && aLeftBorder.LineWidth )
if (rInfo.nNestLevel == 1 && aLeftBorder.LineWidth && !rFrameProperties.empty())
{
if (rFrameProperties.empty())
rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
else
lcl_DecrementHoriOrientPosition(rFrameProperties, aLeftBorder.LineWidth * 0.5);
lcl_DecrementHoriOrientPosition(rFrameProperties, aLeftBorder.LineWidth * 0.5);
}
lcl_adjustBorderDistance(rInfo, aLeftBorder, aRightBorder);
// tdf#106742: since MS Word 2013 (compatibilityMode >= 15), top-level tables are handled the same as nested tables;
// this is also the default behavior in LO when DOCX doesn't define "compatibilityMode" option
......
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