chart2/qa/extras/chart2import.cxx | 31 ++++++++++++++++++++++++ chart2/qa/extras/data/xlsx/bartest-stroke.xlsx |binary chart2/qa/extras/data/xlsx/color_funnel.xlsx |binary oox/inc/drawingml/linepropertiescontext.hxx | 3 +- oox/inc/drawingml/shapepropertiescontext.hxx | 4 ++- oox/source/drawingml/chart/seriescontext.cxx | 3 +- oox/source/drawingml/linepropertiescontext.cxx | 11 ++++++-- oox/source/drawingml/shapepropertiescontext.cxx | 5 ++- oox/source/token/tokens.txt | 1 9 files changed, 51 insertions(+), 7 deletions(-)
New commits: commit 1abd106a51db4040ba50a58ca1c253c391b2c230 Author: Kurt Nordback <kurt.nordb...@collabora.com> AuthorDate: Mon Jun 16 11:52:08 2025 -0600 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Jul 4 17:14:06 2025 +0200 tdf#165742 Step 4.6: Establish a narrow export path for chartex This is a subtask of tdf#165742: Chartex charts are lost on input from OOXML and re-export. Fix an existing bug in chart import, which results in the incorrect default value for stroke width on chart shapes. This was discovered in testing chartex and can be reproduced in a hand-edited pre-2016 file (<c> namespace), but may not manifest there in practice since it appears MS Office may always output an explicit stroke width for pre-2016 charts. Change-Id: I458ae6ad0eaf28bf933c8ae0baed36e48df114b7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186582 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins (cherry picked from commit c8b26350d9aaf9cc8f8202ab66d199700f3be604) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187380 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/chart2/qa/extras/chart2import.cxx b/chart2/qa/extras/chart2import.cxx index 054ca5a86fd1..0eb9b9375b6f 100644 --- a/chart2/qa/extras/chart2import.cxx +++ b/chart2/qa/extras/chart2import.cxx @@ -1219,6 +1219,37 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testNumberFormatsDOCX) } } +CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testShapePropsDefaultStrokeWidthXLSX) +{ + // Bar chart, for which rendering code is implemented + loadFromFile(u"xlsx/bartest-stroke.xlsx"); + { + uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet(0); + CPPUNIT_ASSERT(xChartDoc.is()); + + css::uno::Reference<chart2::XDiagram> xDiagram(xChartDoc->getFirstDiagram(), UNO_SET_THROW); + Reference<chart2::XDataSeries> xDataSeries = getDataSeriesFromDoc(xChartDoc, 0); + uno::Reference<beans::XPropertySet> xPropertySet(xDataSeries, uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xPropertySet.is()); + sal_Int32 nWidth = xPropertySet->getPropertyValue(u"BorderWidth"_ustr).get<sal_Int32>(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Default bar stroke width should be 12700 emu (0.35mm)", sal_Int32(35), nWidth); + } + + // Funnel chart, for which rendering code is not yet implemented + loadFromFile(u"xlsx/color_funnel.xlsx"); + { + uno::Reference< chart2::XChartDocument > xChartDoc = getChartDocFromSheet(0); + CPPUNIT_ASSERT(xChartDoc.is()); + + css::uno::Reference<chart2::XDiagram> xDiagram(xChartDoc->getFirstDiagram(), UNO_SET_THROW); + Reference<chart2::XDataSeries> xDataSeries = getDataSeriesFromDoc(xChartDoc, 0); + uno::Reference<beans::XPropertySet> xPropertySet(xDataSeries, uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xPropertySet.is()); + sal_Int32 nWidth = xPropertySet->getPropertyValue(u"BorderWidth"_ustr).get<sal_Int32>(); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Default bar stroke width should be 12700 emu (0.35mm)", sal_Int32(35), nWidth); + } +} + CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testPercentageNumberFormatsDOCX) { loadFromFile(u"docx/tdf133632.docx"); diff --git a/chart2/qa/extras/data/xlsx/bartest-stroke.xlsx b/chart2/qa/extras/data/xlsx/bartest-stroke.xlsx new file mode 100644 index 000000000000..de8f59afe830 Binary files /dev/null and b/chart2/qa/extras/data/xlsx/bartest-stroke.xlsx differ diff --git a/chart2/qa/extras/data/xlsx/color_funnel.xlsx b/chart2/qa/extras/data/xlsx/color_funnel.xlsx new file mode 100644 index 000000000000..80d16d5d1b84 Binary files /dev/null and b/chart2/qa/extras/data/xlsx/color_funnel.xlsx differ diff --git a/oox/inc/drawingml/linepropertiescontext.hxx b/oox/inc/drawingml/linepropertiescontext.hxx index 041f50bf0d73..3617bffb8a75 100644 --- a/oox/inc/drawingml/linepropertiescontext.hxx +++ b/oox/inc/drawingml/linepropertiescontext.hxx @@ -33,7 +33,8 @@ class LinePropertiesContext final : public ::oox::core::ContextHandler2 { public: LinePropertiesContext(::oox::core::ContextHandler2Helper const & rParent, const ::oox::AttributeList& rAttributes, - LineProperties& rLineProperties, model::LineStyle* pLineStyle = nullptr) noexcept; + LineProperties& rLineProperties, model::LineStyle* pLineStyle = nullptr, + bool bForChart = false) noexcept; virtual ~LinePropertiesContext() override; virtual ::oox::core::ContextHandlerRef diff --git a/oox/inc/drawingml/shapepropertiescontext.hxx b/oox/inc/drawingml/shapepropertiescontext.hxx index 9d047c15c224..e8f0afb3bc03 100644 --- a/oox/inc/drawingml/shapepropertiescontext.hxx +++ b/oox/inc/drawingml/shapepropertiescontext.hxx @@ -28,13 +28,15 @@ namespace oox::drawingml class ShapePropertiesContext : public ::oox::core::ContextHandler2 { public: - ShapePropertiesContext(::oox::core::ContextHandler2Helper const& rParent, Shape& rShape); + ShapePropertiesContext(::oox::core::ContextHandler2Helper const& rParent, Shape& rShape, + bool bForChart = false); virtual ::oox::core::ContextHandlerRef onCreateContext(::sal_Int32 Element, const ::oox::AttributeList& rAttribs) override; protected: Shape& mrShape; + bool mbForChart; }; } diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx index 4b3d18624c8c..88688642bebe 100644 --- a/oox/source/drawingml/chart/seriescontext.cxx +++ b/oox/source/drawingml/chart/seriescontext.cxx @@ -421,7 +421,8 @@ ContextHandlerRef SeriesContextBase::onCreateContext( sal_Int32 nElement, const return nullptr; case C_TOKEN( spPr ): case CX_TOKEN( spPr ): - return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); + return new ShapePropertiesContext( *this, + mrModel.mxShapeProp.create(), true ); case C_TOKEN( tx ): case CX_TOKEN( tx ): return new TextContext( *this, mrModel.mxText.create() ); diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx index 5a4c1fe449b8..00d2d50a093d 100644 --- a/oox/source/drawingml/linepropertiescontext.cxx +++ b/oox/source/drawingml/linepropertiescontext.cxx @@ -32,12 +32,19 @@ using namespace ::oox::core; namespace oox::drawingml { LinePropertiesContext::LinePropertiesContext( ContextHandler2Helper const & rParent, const AttributeList& rAttribs, - LineProperties& rLineProperties, model::LineStyle* pLineStyle) noexcept + LineProperties& rLineProperties, model::LineStyle* pLineStyle, + bool bForChart) noexcept : ContextHandler2(rParent) , mpLineStyle(pLineStyle) , mrLineProperties(rLineProperties) { - mrLineProperties.moLineWidth = rAttribs.getInteger( XML_w ); + if (bForChart) { + // If width is not specified, then charts seem to assume a default line + // width of 12700 emu + mrLineProperties.moLineWidth = rAttribs.getInteger( XML_w, 12700 ); + } else { + mrLineProperties.moLineWidth = rAttribs.getInteger( XML_w ); + } mrLineProperties.moLineCompound = rAttribs.getToken( XML_cmpd ); mrLineProperties.moLineCap = rAttribs.getToken( XML_cap ); diff --git a/oox/source/drawingml/shapepropertiescontext.cxx b/oox/source/drawingml/shapepropertiescontext.cxx index 3a9e474ba931..619f19ed3387 100644 --- a/oox/source/drawingml/shapepropertiescontext.cxx +++ b/oox/source/drawingml/shapepropertiescontext.cxx @@ -38,9 +38,10 @@ using namespace ::com::sun::star::drawing; namespace oox::drawingml { // CT_ShapeProperties -ShapePropertiesContext::ShapePropertiesContext( ContextHandler2Helper const & rParent, Shape& rShape ) +ShapePropertiesContext::ShapePropertiesContext( ContextHandler2Helper const & rParent, Shape& rShape, bool bForChart ) : ContextHandler2( rParent ) , mrShape( rShape ) +, mbForChart(bForChart) { } @@ -76,7 +77,7 @@ ContextHandlerRef ShapePropertiesContext::onCreateContext( sal_Int32 aElementTok // CT_LineProperties case A_TOKEN( ln ): - return new LinePropertiesContext( *this, rAttribs, mrShape.getLineProperties() ); + return new LinePropertiesContext( *this, rAttribs, mrShape.getLineProperties(), nullptr, mbForChart ); // EffectPropertiesGroup // todo not supported by core diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 87d642f57f3a..9c35dd0c22f9 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -5051,6 +5051,7 @@ stored stp str strCache +strDim strLit strRef strVal