oox/source/drawingml/table/tablecell.cxx | 11 ++++++++++- oox/source/drawingml/table/tablecellcontext.cxx | 3 +++ sd/qa/unit/import-tests2.cxx | 4 ++-- svx/qa/unit/table.cxx | 16 ++++++++-------- svx/source/table/cell.cxx | 10 +++++++++- 5 files changed, 32 insertions(+), 12 deletions(-)
New commits: commit a47776a938c4666d4618b5cbf20d4319f64a6ff4 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Thu Mar 27 10:29:42 2025 -0400 Commit: Justin Luth <justin.l...@collabora.com> CommitDate: Mon Mar 31 14:43:18 2025 +0200 tdf#165521 pptx layout: don't use font's leading for cells too This patch also fixes tdf#119951 and perhaps tdf#148039. WARNING: This patch will likely resize the text line height in every table imported from PPTX. Someone must have figured out that Microsoft just ignores the font metrics, and simply adds 20% to the font height to achieve a "single spacing" line height. In LO, that is either termed FontIndependentLineSpacing (a misnomer because it DOES depend on the font ascent/descent) or FixedCellHeight (also a misnomer because it so far hasn't applied to cells/tables and certainly is not restricted to cells/tables since it was implemented for customShapes). With this patch, my particular document now has the right "text/table height" according to a PDF overlay. The theory is that this change is needed for every document. The reason this patch is needed is because svx/source/table/viewcontactoftableobj.cxx's createPrimitive2DSequenceImpl passes rCellItemSet as the ItemSet that will eventually be checked for rSet.Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT), which creates attribute::SdrTextAttribute(bFixedCellHeight) which is used by SdrTextObj::impDecomposeBlockTextPrimitive to set SdrOutliner (and thus EditDoc) with SetFixedCellHeight(rSdrBlockTextPrimitive.isFixedCellHeight()); With FixedCellHeight, impedit3.cxx calculates text/line height using ImplCalculateFontIndependentLineSpacing. make CppunitTest_svx_unit \ CPPUNIT_TEST_NAME=testTdf165521_fixedCellHeight I modified testTdf144092TableHeight, and attached PDF overlay images to tdf#144092 as proof the the table should be taller than originally stated. Change-Id: Ibb4af395b77a3f4d30b5c2e8a08429b701f1ae95 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183130 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx index e6fd01bf43fc..0da7c2092eec 100644 --- a/oox/source/drawingml/table/tablecell.cxx +++ b/oox/source/drawingml/table/tablecell.cxx @@ -273,11 +273,20 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, cons Reference< text::XTextCursor > xAt = xText->createTextCursor(); applyTableCellProperties( rxCell, *this ); + + Reference<XPropertySet> xPropSet(rxCell, UNO_QUERY_THROW); + + PropertyMap& rTextBodyPropertyMap = getTextBody()->getTextProperties().maPropertyMap; + if (rTextBodyPropertyMap.hasProperty(PROP_FontIndependentLineSpacing)) + { + if (rTextBodyPropertyMap.getProperty(PROP_FontIndependentLineSpacing).get<bool>()) + xPropSet->setPropertyValue(u"FontIndependentLineSpacing"_ustr, Any(true)); + } + TextCharacterProperties aTextStyleProps; xAt->gotoStart( true ); xAt->gotoEnd( true ); - Reference< XPropertySet > xPropSet( rxCell, UNO_QUERY_THROW ); oox::drawingml::FillProperties aFillProperties; oox::drawingml::LineProperties aLinePropertiesLeft; oox::drawingml::LineProperties aLinePropertiesRight; diff --git a/oox/source/drawingml/table/tablecellcontext.cxx b/oox/source/drawingml/table/tablecellcontext.cxx index 3c4780f34e3c..3dbcccc19611 100644 --- a/oox/source/drawingml/table/tablecellcontext.cxx +++ b/oox/source/drawingml/table/tablecellcontext.cxx @@ -24,6 +24,7 @@ #include <drawingml/misccontexts.hxx> #include <oox/helper/attributelist.hxx> #include <oox/token/namespaces.hxx> +#include <oox/token/properties.hxx> #include <oox/token/tokens.hxx> using namespace ::oox::core; @@ -56,6 +57,8 @@ TableCellContext::onCreateContext( ::sal_Int32 aElementToken, const AttributeLis case A_TOKEN( txBody ): // CT_TextBody { oox::drawingml::TextBodyPtr xTextBody = std::make_shared<oox::drawingml::TextBody>(); + xTextBody->getTextProperties().maPropertyMap.setProperty( + PROP_FontIndependentLineSpacing, true); mrTableCell.setTextBody( xTextBody ); return new oox::drawingml::TextBodyContext( *this, *xTextBody ); } diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index 364a88471acb..7cdfcb0aea7c 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -1979,10 +1979,10 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf144092TableHeight) uno::Reference<drawing::XShape> xTableShape(getShapeFromPage(0, 0), uno::UNO_QUERY); // Without the accompanying fix in place, this test would have failed with: - // - Expected: 7606 + // - Expected: 7885 // - Actual : 4595 // i.e. the table height wasn't corrected by expanding less than minimum sized rows. - CPPUNIT_ASSERT_EQUAL(sal_Int32(7606), xTableShape->getSize().Height); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7885), xTableShape->getSize().Height); } CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf89928BlackWhiteThreshold) diff --git a/svx/qa/unit/table.cxx b/svx/qa/unit/table.cxx index bb43a984daf7..5f2530d8ae67 100644 --- a/svx/qa/unit/table.cxx +++ b/svx/qa/unit/table.cxx @@ -117,20 +117,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf165521_fixedCellHeight) drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence = renderPageToPrimitives(xDrawPage); - // TODO: Then make sure the text in both table and textbox are the same line height + // Then make sure the text in both table and textbox are the same line height svx::ExtendedPrimitive2dXmlDump aDumper; xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence); - // const char sTextboxPath6[] = "/primitive2D/objectinfo[1]/unhandled/group/sdrblocktext/" - // "texthierarchyblock/texthierarchyparagraph/texthierarchyline[6]/" - // "textsimpleportion"; + const char sTextboxPath6[] = "/primitive2D/objectinfo[1]/unhandled/group/sdrblocktext/" + "texthierarchyblock/texthierarchyparagraph/texthierarchyline[6]/" + "textsimpleportion"; const char sTextboxPath7[] = "/primitive2D/objectinfo[1]/unhandled/group/sdrblocktext/" "texthierarchyblock/texthierarchyparagraph/texthierarchyline[7]/" "textsimpleportion"; CPPUNIT_ASSERT( getXPath(pDocument, sTextboxPath7, "text") .startsWith("Autofit Custom Shape forces Fixed Cell Height even in the table.")); - // const sal_Int32 nTextBoxFontLineHeight = getXPath(pDocument, sTextboxPath7, "y").toInt32() - // - getXPath(pDocument, sTextboxPath6, "y").toInt32(); + const sal_Int32 nTextBoxFontLineHeight = getXPath(pDocument, sTextboxPath7, "y").toInt32() + - getXPath(pDocument, sTextboxPath6, "y").toInt32(); const char sTablePath6[] = "/primitive2D/objectinfo[2]/sdrCell[2]/group/sdrblocktext/" "texthierarchyblock/texthierarchyparagraph/texthierarchyline[6]/" @@ -143,7 +143,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf165521_fixedCellHeight) - getXPath(pDocument, sTablePath6, "y").toInt32(); // Expected: 593. // Actual (without the acompanying patch) 553 - // CPPUNIT_ASSERT_EQUAL(nTextBoxFontLineHeight, nTableFontLineHeight); + CPPUNIT_ASSERT_EQUAL(nTextBoxFontLineHeight, nTableFontLineHeight); // All of the text must fit inside the table, // and the table must be approximately the same size as the lines of text. @@ -152,7 +152,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf165521_fixedCellHeight) "/primitive2D/objectinfo[2]/sdrCell[2]/group/polypolygoncolor/polypolygon", "height") .toInt32(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7 * nTableFontLineHeight, nTableHeight, 1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7 * nTextBoxFontLineHeight, nTableHeight, 1); } CPPUNIT_TEST_FIXTURE(Test, testSvxTableControllerSetAttrToSelectedShape) diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx index a38b3e46315f..e66b2a33f065 100644 --- a/svx/source/table/cell.cxx +++ b/svx/source/table/cell.cxx @@ -39,6 +39,7 @@ #include <sdr/properties/cellproperties.hxx> #include <editeng/outlobj.hxx> #include <editeng/writingmodeitem.hxx> +#include <svx/sdtfchim.hxx> #include <svx/svdotable.hxx> #include <svx/svdoutl.hxx> #include <svx/unoshtxt.hxx> @@ -82,6 +83,7 @@ static const SvxItemPropertySet* ImplGetSvxCellPropertySet() FILL_PROPERTIES // { "HasLevels", OWN_ATTR_HASLEVELS, cppu::UnoType<bool>::get(), css::beans::PropertyAttribute::READONLY, 0}, { u"Style"_ustr, OWN_ATTR_STYLE, cppu::UnoType< css::style::XStyle >::get(), css::beans::PropertyAttribute::MAYBEVOID, 0}, + { UNO_NAME_TEXT_FONTINDEPENDENTLINESPACING, SDRATTR_TEXT_USEFIXEDCELLHEIGHT, cppu::UnoType<bool>::get(), 0, 0}, { UNO_NAME_TEXT_WRITINGMODE, SDRATTR_TEXTDIRECTION, cppu::UnoType<css::text::WritingMode>::get(), 0, 0}, { UNO_NAME_TEXT_HORZADJUST, SDRATTR_TEXT_HORZADJUST, cppu::UnoType<css::drawing::TextHorizontalAdjust>::get(), 0, 0}, { UNO_NAME_TEXT_LEFTDIST, SDRATTR_TEXT_LEFTDIST, cppu::UnoType<sal_Int32>::get(), 0, 0, PropertyMoreFlags::METRIC_ITEM}, @@ -704,15 +706,21 @@ sal_Int32 Cell::getMinimumHeight() { Outliner& rOutliner=rTableObj.ImpGetDrawOutliner(); rOutliner.SetPaperSize(aSize); - rOutliner.SetUpdateLayout(true); ForceOutlinerParaObject( OutlinerMode::TextObject ); if( GetOutlinerParaObject() ) { + rOutliner.SetFixedCellHeight( + GetItemSet().Get(SDRATTR_TEXT_USEFIXEDCELLHEIGHT).GetValue()); rOutliner.SetText(*GetOutlinerParaObject()); } + + rOutliner.SetUpdateLayout(true); nMinimumHeight=rOutliner.GetTextHeight()+1; + + // cleanup outliner rOutliner.Clear(); + rOutliner.SetFixedCellHeight(false); } nMinimumHeight += GetTextUpperDistance() + GetTextLowerDistance();