diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2018-10-16 18:00:45 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2018-10-16 19:53:32 +0200 |
commit | 5d0c83fd4cf91083805f60f49e4fafd3d6ac73d4 (patch) | |
tree | 98fc6da2e4507d2de93da9c2d848b9c23feb76de | |
parent | c8b68f7d63df9335ab4ef90441d3d2815bb4ddd6 (diff) |
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: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport10.cxx | 13 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/rtfexport.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 9 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 62 |
4 files changed, 62 insertions, 24 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx index 4db28720e0fa..794a76245525 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx @@ -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); + } } } diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index 009cd00eb14d..8b6ecdb27f85 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -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")); } diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 0c9e4a04c63b..3d539978f096 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -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; diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index ced27a0b80fa..fe8553e83cd9 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -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 |