diff options
-rw-r--r-- | oox/inc/drawingml/table/tableproperties.hxx | 3 | ||||
-rw-r--r-- | oox/inc/drawingml/textbody.hxx | 2 | ||||
-rw-r--r-- | oox/inc/drawingml/textbodyproperties.hxx | 4 | ||||
-rw-r--r-- | oox/inc/drawingml/textcharacterproperties.hxx | 2 | ||||
-rw-r--r-- | oox/source/drawingml/table/tableproperties.cxx | 48 | ||||
-rw-r--r-- | oox/source/drawingml/textbody.cxx | 5 | ||||
-rw-r--r-- | oox/source/drawingml/textbodypropertiescontext.cxx | 5 | ||||
-rw-r--r-- | oox/source/drawingml/textcharacterproperties.cxx | 3 | ||||
-rw-r--r-- | oox/source/ppt/pptshape.cxx | 18 | ||||
-rw-r--r-- | sd/qa/unit/data/pptx/tdf120028.pptx | bin | 0 -> 30465 bytes | |||
-rw-r--r-- | sd/qa/unit/data/pptx/tdf120028b.pptx | bin | 0 -> 29838 bytes | |||
-rw-r--r-- | sd/qa/unit/import-tests.cxx | 77 |
12 files changed, 166 insertions, 1 deletions
diff --git a/oox/inc/drawingml/table/tableproperties.hxx b/oox/inc/drawingml/table/tableproperties.hxx index 578230daa876..cdd905b809ff 100644 --- a/oox/inc/drawingml/table/tableproperties.hxx +++ b/oox/inc/drawingml/table/tableproperties.hxx @@ -60,6 +60,9 @@ public: const css::uno::Reference < css::beans::XPropertySet > & xPropSet, const ::oox::drawingml::TextListStylePtr& pMasterTextListStyle ); + /// Distributes text body with multiple columns in table cells. + void pullFromTextBody(oox::drawingml::TextBodyPtr pTextBody, sal_Int32 nShapeWidth); + private: const TableStyle& getUsedTableStyle(const ::oox::core::XmlFilterBase& rFilterBase, TableStyle*& rTableStyleToDelete); diff --git a/oox/inc/drawingml/textbody.hxx b/oox/inc/drawingml/textbody.hxx index c2b0c5acc762..835f1c34b792 100644 --- a/oox/inc/drawingml/textbody.hxx +++ b/oox/inc/drawingml/textbody.hxx @@ -45,6 +45,8 @@ public: const TextParagraphVector& getParagraphs() const { return maParagraphs; } TextParagraph& addParagraph(); + /// Appends an existing paragraph to this text body. + void appendParagraph(std::shared_ptr<TextParagraph> pTextParagraph); const TextListStyle& getTextListStyle() const { return maTextListStyle; } TextListStyle& getTextListStyle() { return maTextListStyle; } diff --git a/oox/inc/drawingml/textbodyproperties.hxx b/oox/inc/drawingml/textbodyproperties.hxx index 62ee3190ae58..785f117568a9 100644 --- a/oox/inc/drawingml/textbodyproperties.hxx +++ b/oox/inc/drawingml/textbodyproperties.hxx @@ -42,6 +42,10 @@ struct TextBodyProperties boost::optional< sal_Int32 > moTextOffRight; css::drawing::TextVerticalAdjust meVA; OUString msPrst; + /// Number of requested columns. + sal_Int32 mnNumCol = 1; + /// Normal autofit: font scale (default: 100%). + sal_Int32 mnFontScale = 100000; explicit TextBodyProperties(); diff --git a/oox/inc/drawingml/textcharacterproperties.hxx b/oox/inc/drawingml/textcharacterproperties.hxx index 4dfab74e3c1f..a034121e47d0 100644 --- a/oox/inc/drawingml/textcharacterproperties.hxx +++ b/oox/inc/drawingml/textcharacterproperties.hxx @@ -47,6 +47,8 @@ struct TextCharacterProperties Color maHighlightColor; OptValue< OUString > moLang; OptValue< sal_Int32 > moHeight; + /// If a font scale has to be applied manually to moHeight. + OptValue< double > moFontScale; OptValue< sal_Int32 > moSpacing; OptValue< sal_Int32 > moUnderline; OptValue< sal_Int32 > moBaseline; diff --git a/oox/source/drawingml/table/tableproperties.cxx b/oox/source/drawingml/table/tableproperties.cxx index 527b65829d17..8f8993ad0035 100644 --- a/oox/source/drawingml/table/tableproperties.cxx +++ b/oox/source/drawingml/table/tableproperties.cxx @@ -19,6 +19,8 @@ #include <drawingml/table/tableproperties.hxx> #include <drawingml/table/tablestylelist.hxx> +#include <drawingml/textbody.hxx> +#include <drawingml/textparagraph.hxx> #include <oox/drawingml/drawingmltypes.hxx> #include <com/sun/star/table/XTable.hpp> #include <com/sun/star/container/XNameContainer.hpp> @@ -311,6 +313,52 @@ void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBa delete pTableStyleToDelete; } +void TableProperties::pullFromTextBody(oox::drawingml::TextBodyPtr pTextBody, sal_Int32 nShapeWidth) +{ + // Create table grid and a single row. + sal_Int32 nNumCol = pTextBody->getTextProperties().mnNumCol; + std::vector<sal_Int32>& rTableGrid(getTableGrid()); + sal_Int32 nColWidth = nShapeWidth / nNumCol; + for (sal_Int32 nCol = 0; nCol < nNumCol; ++nCol) + rTableGrid.push_back(nColWidth); + std::vector<drawingml::table::TableRow>& rTableRows(getTableRows()); + rTableRows.emplace_back(); + oox::drawingml::table::TableRow& rTableRow = rTableRows.back(); + std::vector<oox::drawingml::table::TableCell>& rTableCells = rTableRow.getTableCells(); + + // Create the cells and distribute the paragraphs from pTextBody. + sal_Int32 nNumPara = pTextBody->getParagraphs().size(); + sal_Int32 nParaPerCol = std::ceil(double(nNumPara) / nNumCol); + // Font scale of text body will be applied at a text run level. + sal_Int32 nFontScale = pTextBody->getTextProperties().mnFontScale; + size_t nPara = 0; + for (sal_Int32 nCol = 0; nCol < nNumCol; ++nCol) + { + rTableCells.emplace_back(); + oox::drawingml::table::TableCell& rTableCell = rTableCells.back(); + TextBodyPtr pCellTextBody(new TextBody); + rTableCell.setTextBody(pCellTextBody); + + // Copy properties provided by <a:lstStyle>. + pCellTextBody->getTextListStyle() = pTextBody->getTextListStyle(); + + for (sal_Int32 nParaInCol = 0; nParaInCol < nParaPerCol; ++nParaInCol) + { + if (nPara < pTextBody->getParagraphs().size()) + { + std::shared_ptr<oox::drawingml::TextParagraph> pParagraph + = pTextBody->getParagraphs()[nPara]; + if (nFontScale != 100000) + { + for (auto& pRun : pParagraph->getRuns()) + pRun->getTextCharacterProperties().moFontScale = nFontScale; + } + pCellTextBody->appendParagraph(pParagraph); + } + ++nPara; + } + } +} } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/textbody.cxx b/oox/source/drawingml/textbody.cxx index eb27bda831ac..72b7ef752c07 100644 --- a/oox/source/drawingml/textbody.cxx +++ b/oox/source/drawingml/textbody.cxx @@ -54,6 +54,11 @@ TextParagraph& TextBody::addParagraph() return *xPara; } +void TextBody::appendParagraph(std::shared_ptr<TextParagraph> pTextParagraph) +{ + maParagraphs.push_back(pTextParagraph); +} + void TextBody::insertAt( const ::oox::core::XmlFilterBase& rFilterBase, const Reference < XText > & xText, diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx index e564cf04d149..b19d349e92d9 100644 --- a/oox/source/drawingml/textbodypropertiescontext.cxx +++ b/oox/source/drawingml/textbodypropertiescontext.cxx @@ -90,7 +90,7 @@ TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper cons // sal_Int32 nVertOverflow = rAttribs.getToken( XML_vertOverflow, XML_overflow ); // ST_TextColumnCount -// sal_Int32 nNumCol = rAttribs.getInteger( XML_numCol, 1 ); + mrTextBodyProp.mnNumCol = rAttribs.getInteger( XML_numCol, 1 ); // ST_Angle mrTextBodyProp.moRotation = rAttribs.getInteger( XML_rot ); @@ -155,9 +155,12 @@ ContextHandlerRef TextBodyPropertiesContext::onCreateContext( sal_Int32 aElement mrTextBodyProp.maPropertyMap.setProperty( PROP_TextAutoGrowHeight, false); // CT_TextNoAutofit break; case A_TOKEN( normAutofit ): // CT_TextNormalAutofit + { mrTextBodyProp.maPropertyMap.setProperty( PROP_TextFitToSize, TextFitToSizeType_AUTOFIT); mrTextBodyProp.maPropertyMap.setProperty( PROP_TextAutoGrowHeight, false); + mrTextBodyProp.mnFontScale = rAttribs.getInteger(XML_fontScale, 100000); break; + } case A_TOKEN( spAutoFit ): { const sal_Int32 tVert = mrTextBodyProp.moVert.get( XML_horz ); diff --git a/oox/source/drawingml/textcharacterproperties.cxx b/oox/source/drawingml/textcharacterproperties.cxx index b389d74c225f..ed110a1e3005 100644 --- a/oox/source/drawingml/textcharacterproperties.cxx +++ b/oox/source/drawingml/textcharacterproperties.cxx @@ -52,6 +52,7 @@ void TextCharacterProperties::assignUsed( const TextCharacterProperties& rSource maHighlightColor.assignIfUsed( rSourceProps.maHighlightColor ); maUnderlineColor.assignIfUsed( rSourceProps.maUnderlineColor ); moHeight.assignIfUsed( rSourceProps.moHeight ); + moFontScale.assignIfUsed(rSourceProps.moFontScale); moSpacing.assignIfUsed( rSourceProps.moSpacing ); moUnderline.assignIfUsed( rSourceProps.moUnderline ); moBaseline.assignIfUsed( rSourceProps.moBaseline ); @@ -117,6 +118,8 @@ void TextCharacterProperties::pushToPropMap( PropertyMap& rPropMap, const XmlFil if( moHeight.has() ) { float fHeight = GetFontHeight( moHeight.get() ); + if (moFontScale.has()) + fHeight *= (moFontScale.get() / 100000); rPropMap.setProperty( PROP_CharHeight, fHeight); rPropMap.setProperty( PROP_CharHeightAsian, fHeight); rPropMap.setProperty( PROP_CharHeightComplex, fHeight); diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx index e0cea6729fc2..1657e2a18a95 100644 --- a/oox/source/ppt/pptshape.cxx +++ b/oox/source/ppt/pptshape.cxx @@ -20,6 +20,7 @@ #include <oox/ppt/pptshape.hxx> #include <oox/core/xmlfilterbase.hxx> #include <drawingml/textbody.hxx> +#include <drawingml/table/tableproperties.hxx> #include <com/sun/star/awt/Rectangle.hpp> #include <com/sun/star/container/XNamed.hpp> @@ -223,6 +224,23 @@ void PPTShape::addShape( } } + if (sServiceName != "com.sun.star.drawing.TableShape") + { + if (TextBodyPtr pTextBody = getTextBody()) + { + sal_Int32 nNumCol = pTextBody->getTextProperties().mnNumCol; + if (nNumCol > 1) + { + // This shape is not a table, but has multiple columns, + // represent that as a table. + sServiceName = "com.sun.star.drawing.TableShape"; + oox::drawingml::table::TablePropertiesPtr pTableProperties = getTableProperties(); + pTableProperties->pullFromTextBody(pTextBody, maSize.Width); + setTextBody(nullptr); + } + } + } + SAL_INFO("oox.ppt","shape service: " << sServiceName); if (mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout) diff --git a/sd/qa/unit/data/pptx/tdf120028.pptx b/sd/qa/unit/data/pptx/tdf120028.pptx Binary files differnew file mode 100644 index 000000000000..035c36730663 --- /dev/null +++ b/sd/qa/unit/data/pptx/tdf120028.pptx diff --git a/sd/qa/unit/data/pptx/tdf120028b.pptx b/sd/qa/unit/data/pptx/tdf120028b.pptx Binary files differnew file mode 100644 index 000000000000..7d50da36c120 --- /dev/null +++ b/sd/qa/unit/data/pptx/tdf120028b.pptx diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx index f8ead710e9bf..f65322707958 100644 --- a/sd/qa/unit/import-tests.cxx +++ b/sd/qa/unit/import-tests.cxx @@ -178,6 +178,8 @@ public: bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected); void testPatternImport(); void testTdf119015(); + void testTdf120028(); + void testTdf120028b(); CPPUNIT_TEST_SUITE(SdImportTest); @@ -255,6 +257,8 @@ public: CPPUNIT_TEST(testTdf116266); CPPUNIT_TEST(testTdf114821); CPPUNIT_TEST(testTdf119015); + CPPUNIT_TEST(testTdf120028); + CPPUNIT_TEST(testTdf120028b); CPPUNIT_TEST_SUITE_END(); }; @@ -2472,6 +2476,79 @@ void SdImportTest::testTdf119015() xDocShRef->DoClose(); } +void SdImportTest::testTdf120028() +{ + // Check that the table shape has 4 columns. + ::sd::DrawDocShellRef xDocShRef + = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028.pptx"), PPTX); + uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xDoc.is()); + + uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xPage.is()); + + // This failed, shape was not a table, all text was rendered in a single + // column. + uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage)); + uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xModel.is()); + + uno::Reference<table::XTableColumns> xColumns = xModel->getColumns(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount()); + + // Check font size in the A1 cell. + uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell)); + uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph)); + uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY); + double fCharHeight = 0; + xPropSet->getPropertyValue("CharHeight") >>= fCharHeight; + // This failed, non-scaled height was 13.5. + CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, fCharHeight, 1E-12); + + xDocShRef->DoClose(); +} + +void SdImportTest::testTdf120028b() +{ + // Check that the table shape has 4 columns. + ::sd::DrawDocShellRef xDocShRef + = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028b.pptx"), PPTX); + uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xDoc.is()); + + uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xPage.is()); + + uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage)); + CPPUNIT_ASSERT(xShape.is()); + + uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xModel.is()); + + uno::Reference<table::XTableColumns> xColumns = xModel->getColumns(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount()); + + // Check font color in the A1 cell. + uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell)); + uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph)); + uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY); + sal_Int32 nCharColor = 0; + xPropSet->getPropertyValue("CharColor") >>= nCharColor; + // This was 0x1f497d, not white: text list style from placeholder shape + // from slide layout was ignored. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), nCharColor); + + xDocShRef->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest); CPPUNIT_PLUGIN_IMPLEMENT(); |