chart2/qa/extras/chart2import2.cxx             |   49 +++++++++++++++++++++
 chart2/qa/extras/data/pptx/tdf136754.pptx      |binary
 chart2/qa/extras/data/pptx/tdf60316.pptx       |binary
 oox/source/drawingml/chart/objectformatter.cxx |   18 +++++--
 oox/source/drawingml/chart/plotareacontext.cxx |    2 
 oox/source/drawingml/chart/plotareamodel.cxx   |    3 -
 sw/qa/extras/layout/data/tdf166181.fodt        |   58 +++++++++++++++++++++++++
 sw/qa/extras/layout/layout5.cxx                |   22 +++++++++
 sw/source/core/layout/tabfrm.cxx               |   12 +++--
 9 files changed, 152 insertions(+), 12 deletions(-)

New commits:
commit 5e1037975edc4594b364f740df080603d3581946
Author:     Markus Mohrhard <markus.mohrh...@googlemail.com>
AuthorDate: Wed Jul 9 02:53:09 2025 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Jul 20 13:29:54 2025 +0200

    tdf#136754: handle pptx chart backgrounds provided by the themes correctly
    
    It seems that there is a small undocumented quirk in the OOXML spec
    regarding pptx files. The first 32 themes are handled as if they would
    be specifying a transparent background whereas the spec seems to agree
    with the xlsx/docx handling of using a solid background based on the
    theme colors.
    
    This corresponds to table 3 in 21.2.3.46 ST_Style of the OOXML spec.
    
    This commit also reverts the fix for tdf#60316.
    
    Change-Id: I4187b5740898435941647056a5820fa47a2b3dba
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187759
    Tested-by: Jenkins
    Reviewed-by: Markus Mohrhard <markus.mohrh...@googlemail.com>
    (cherry picked from commit 87350de8737ca91ba71b356ca9f33fea99e74591)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187844
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/chart2/qa/extras/chart2import2.cxx 
b/chart2/qa/extras/chart2import2.cxx
index cdfe94093e4b..f8b17a4f9116 100644
--- a/chart2/qa/extras/chart2import2.cxx
+++ b/chart2/qa/extras/chart2import2.cxx
@@ -18,6 +18,7 @@
 #include <com/sun/star/chart/XAxisXSupplier.hpp>
 #include <com/sun/star/chart/DataLabelPlacement.hpp>
 #include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
 
 class Chart2ImportTest2 : public ChartTest
 {
@@ -958,6 +959,54 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf166428)
     CPPUNIT_ASSERT(xDataSeq.is());
 }
 
+CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf60316)
+{
+    loadFromFile(u"pptx/tdf60316.pptx");
+
+    // 1st chart
+    Reference<chart2::XChartDocument> xChartDoc(getChartDocFromDrawImpress(0, 
0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChartDoc.is());
+
+    Reference<beans::XPropertySet> xPropSet = xChartDoc->getPageBackground();
+    CPPUNIT_ASSERT(xPropSet.is());
+    drawing::FillStyle eStyle
+        = 
xPropSet->getPropertyValue(u"FillStyle"_ustr).get<drawing::FillStyle>();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+        "'Automatic' chart background fill in pptx should be loaded as no fill 
(transparent).",
+        drawing::FillStyle_NONE, eStyle);
+
+    Reference<chart2::XDiagram> xDiagram = xChartDoc->getFirstDiagram();
+    Reference<beans::XPropertySet> xWallPropSet = xDiagram->getWall();
+
+    eStyle = 
xWallPropSet->getPropertyValue(u"FillStyle"_ustr).get<drawing::FillStyle>();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+        "Wall background for styles below 32 shoujld be transparent in pptx",
+        drawing::FillStyle_NONE, eStyle);
+}
+
+CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf136754)
+{
+    loadFromFile(u"pptx/tdf136754.pptx");
+
+    // 1st chart
+    Reference<chart2::XChartDocument> xChartDoc(getChartDocFromDrawImpress(0, 
0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT(xChartDoc.is());
+
+    Reference<beans::XPropertySet> xPropSet = xChartDoc->getPageBackground();
+    CPPUNIT_ASSERT(xPropSet.is());
+    drawing::FillStyle eStyle
+        = 
xPropSet->getPropertyValue(u"FillStyle"_ustr).get<drawing::FillStyle>();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(
+        "'Automatic' chart background fill in pptx should be loaded as no fill 
(transparent).",
+        drawing::FillStyle_NONE, eStyle);
+
+    Reference<chart2::XDiagram> xDiagram = xChartDoc->getFirstDiagram();
+    Reference<beans::XPropertySet> xWallPropSet = xDiagram->getWall();
+    eStyle = 
xWallPropSet->getPropertyValue(u"FillStyle"_ustr).get<drawing::FillStyle>();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Wall background for styles above 32 should 
be solid in pptx",
+                                 drawing::FillStyle_SOLID, eStyle);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/qa/extras/data/pptx/tdf136754.pptx 
b/chart2/qa/extras/data/pptx/tdf136754.pptx
new file mode 100644
index 000000000000..48927e54eba7
Binary files /dev/null and b/chart2/qa/extras/data/pptx/tdf136754.pptx differ
diff --git a/chart2/qa/extras/data/pptx/tdf60316.pptx 
b/chart2/qa/extras/data/pptx/tdf60316.pptx
index d1da03e5fa46..638d7e371b39 100644
Binary files a/chart2/qa/extras/data/pptx/tdf60316.pptx and 
b/chart2/qa/extras/data/pptx/tdf60316.pptx differ
diff --git a/oox/source/drawingml/chart/objectformatter.cxx 
b/oox/source/drawingml/chart/objectformatter.cxx
index 0d746ab783f8..698da92fe8bf 100644
--- a/oox/source/drawingml/chart/objectformatter.cxx
+++ b/oox/source/drawingml/chart/objectformatter.cxx
@@ -636,6 +636,8 @@ public:
                             const PictureOptionsModel* pPicOptions,
                             sal_Int32 nSeriesIdx );
 
+    void                setAutoFill(sal_Int32 nAutoFill);
+
 private:
     FillPropertiesPtr   mxAutoFill;         /// Automatic fill properties.
 };
@@ -871,11 +873,6 @@ FillFormatter::FillFormatter( ObjectFormatterData& rData, 
const AutoFormatEntry*
     if( const Theme* pTheme = mrData.mrFilter.getCurrentTheme() )
         if( const FillProperties* pFillProps = pTheme->getFillStyle( 
pAutoFormatEntry->mnThemedIdx ) )
             *mxAutoFill = *pFillProps;
-
-    if (eObjType == OBJECTTYPE_CHARTSPACE)
-    {
-        mxAutoFill->moFillType = 
rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle();
-    }
 }
 
 void FillFormatter::convertFormatting( ShapePropertyMap& rPropMap, const 
ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, 
sal_Int32 nSeriesIdx )
@@ -890,6 +887,11 @@ void FillFormatter::convertFormatting( ShapePropertyMap& 
rPropMap, const ModelRe
     aFillProps.pushToPropMap( rPropMap, mrData.mrFilter.getGraphicHelper(), 0, 
getPhColor( nSeriesIdx ) );
 }
 
+void FillFormatter::setAutoFill(sal_Int32 nFillStyle)
+{
+    mxAutoFill->moFillType = nFillStyle;
+}
+
 namespace {
 
 const TextCharacterProperties* lclGetTextProperties( const ModelRef< TextBody 
>& rxTextProp )
@@ -948,6 +950,12 @@ ObjectTypeFormatter::ObjectTypeFormatter( 
ObjectFormatterData& rData, const Obje
     mrModelObjHelper( rData.maModelObjHelper ),
     mrEntry( rEntry )
 {
+    // this seems to be an undocumented quirk in the OOXML spec. Only for pptx 
files the first 32 theme entries
+    // force a transparent background
+    if (rChartSpace.mnStyle <= 32 && (eObjType == OBJECTTYPE_CHARTSPACE || 
eObjType == OBJECTTYPE_PLOTAREA2D))
+    {
+        
maFillFormatter.setAutoFill(rData.mrFilter.getGraphicHelper().getDefaultChartAreaFillStyle());
+    }
 }
 
 void ObjectTypeFormatter::convertFrameFormatting( PropertySet& rPropSet, const 
ModelRef< Shape >& rxShapeProp, const PictureOptionsModel* pPicOptions, 
sal_Int32 nSeriesIdx )
diff --git a/oox/source/drawingml/chart/plotareacontext.cxx 
b/oox/source/drawingml/chart/plotareacontext.cxx
index 00a6a47bde3b..731c23368933 100644
--- a/oox/source/drawingml/chart/plotareacontext.cxx
+++ b/oox/source/drawingml/chart/plotareacontext.cxx
@@ -162,7 +162,7 @@ ContextHandlerRef PlotAreaContext::onCreateContext( 
sal_Int32 nElement, [[maybe_
                 case C_TOKEN( layout ):
                     return new LayoutContext( *this, mrModel.mxLayout.create() 
);
                 case C_TOKEN( spPr ):
-                    return new ShapePropertiesContext( *this, 
mrModel.mxShapeProp.getOrCreate() );
+                    return new ShapePropertiesContext( *this, 
mrModel.mxShapeProp.create() );
                 case C_TOKEN(dTable):
                     return new DataTableContext( *this, 
mrModel.mxDataTable.create() );
             }
diff --git a/oox/source/drawingml/chart/plotareamodel.cxx 
b/oox/source/drawingml/chart/plotareamodel.cxx
index cb4f6383ddfa..cdc3af7f8fef 100644
--- a/oox/source/drawingml/chart/plotareamodel.cxx
+++ b/oox/source/drawingml/chart/plotareamodel.cxx
@@ -18,8 +18,6 @@
  */
 
 #include <drawingml/chart/plotareamodel.hxx>
-#include <drawingml/fillproperties.hxx>
-#include <oox/token/tokens.hxx>
 
 namespace oox::drawingml::chart {
 
@@ -40,7 +38,6 @@ WallFloorModel::~WallFloorModel()
 
 PlotAreaModel::PlotAreaModel()
 {
-    mxShapeProp.create().getFillProperties().moFillType = XML_noFill;
 }
 
 PlotAreaModel::~PlotAreaModel()
commit 619265ffb4da3ae67578b9ea9db3cfa5170fdbc4
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sun Jul 13 22:38:40 2025 +0500
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Jul 20 13:29:41 2025 +0200

    tdf#166181: partial revert of 223a51801f0b75ae5036a8bcecc6eb81d99b113e
    
    A newly created follow row frame for a split row would be passed into
    lcl_GetHeightOfRows with Y position of 0, while the next row frames
    would have Y positions from their previous placement (below the last
    row frame kept on the previous page). Thus we can't use a difference
    between top ot first row and bottom of last row to get sum of heights.
    
    Change-Id: Ia96cd3ec488a6c3e6fb768fb1346bc8d61696118
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187818
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 6a074bd78322d8a8ca3eddd5ea4d4edf8f796a80)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187857
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/layout/data/tdf166181.fodt 
b/sw/qa/extras/layout/data/tdf166181.fodt
new file mode 100644
index 000000000000..2da431f4918f
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf166181.fodt
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+  <style:default-style style:family="table">
+   <style:table-properties table:border-model="collapsing"/>
+  </style:default-style>
+  <style:default-style style:family="table-row">
+   <style:table-row-properties fo:keep-together="auto"/>
+  </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="Table1" style:family="table">
+   <style:table-properties style:width="170mm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table1.1" style:family="table-row">
+   <style:table-row-properties style:min-row-height="248mm"/>
+  </style:style>
+  <style:style style:name="Table1.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="1mm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="210mm" fo:page-height="297mm" 
style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" 
fo:margin-left="2cm" fo:margin-right="2cm"/>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <table:table table:name="Table1" table:style-name="Table1">
+    <table:table-column/>
+    <table:table-column/>
+    <table:table-row table:style-name="Table1.1">
+     <table:table-cell table:style-name="Table1.A1" 
table:number-columns-spanned="2" office:value-type="string">
+      <text:p>A1</text:p>
+     </table:table-cell>
+     <table:covered-table-cell/>
+    </table:table-row>
+    <table:table-row>
+     <table:table-cell table:style-name="Table1.A1" 
table:number-rows-spanned="2" office:value-type="string">
+      <text:p>A2 (merged cell)</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p>B2</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row>
+     <table:covered-table-cell table:style-name="Table1.A1"/>
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p>B3</text:p>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+   <text:p/>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/layout/layout5.cxx b/sw/qa/extras/layout/layout5.cxx
index 21c022b10b16..1b6addbfd638 100644
--- a/sw/qa/extras/layout/layout5.cxx
+++ b/sw/qa/extras/layout/layout5.cxx
@@ -1934,6 +1934,28 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf167540)
     verify_me();
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter5, testTdf166181)
+{
+    // Given a document with a table with a merged cell, which gets split 
across pages:
+    createSwDoc("tdf166181.fodt");
+    CPPUNIT_ASSERT_EQUAL(2, getPages());
+
+    // Make sure that the follow cell has the correct height
+    auto pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "//page", 2);
+    assertXPath(pXmlDoc, "//page[2]/body/tab", 1);
+    assertXPath(pXmlDoc, "//page[2]/body/tab/row", 2);
+    assertXPath(pXmlDoc, "//page[2]/body/tab/row[1]/infos/bounds", "height", 
u"0");
+    // Check that the first cell of the row is a follow (it has a precede)
+    (void)getXPath(pXmlDoc, "//page[2]/body/tab/row[1]/cell[1]", "precede");
+    // Check that it is merged
+    assertXPath(pXmlDoc, "//page[2]/body/tab/row[1]/cell[1]", "rowspan", u"2");
+    // Get cell height
+    OUString height = getXPath(pXmlDoc, 
"//page[2]/body/tab/row[1]/cell[1]/infos/bounds", "height");
+    // Without a fix, this was greater than 16000; it is expected around 400
+    CPPUNIT_ASSERT_LESS(sal_Int32(500), height.toInt32());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 5163661fd3bb..2610815ca2a4 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -225,15 +225,21 @@ static SwTwips lcl_GetHeightOfRows( const SwFrame* 
pStart, tools::Long nCount )
     if ( !nCount || !pStart)
         return 0;
 
+    // There are moments when some rows have correct size, but wrong position: 
e.g., when a merged
+    // cell is split, the 0-height follow of the previous row is inserted, and 
arrives here with a
+    // correct height, but positioned at [0, 0]; the following rows have 
correct position (offset
+    // to the new page's starting Y coordinate). This disallows to simplify 
the height calculation
+    // to just difference between top row's top and bottom row's bottom.
+    SwTwips nRet = 0;
     SwRectFnSet aRectFnSet(pStart);
-    SwTwips nTop = aRectFnSet.GetTop(pStart->getFrameArea());
-    while (pStart->GetNext() && nCount > 1)
+    while (pStart && nCount > 0)
     {
+        nRet += aRectFnSet.GetHeight(pStart->getFrameArea());
         pStart = pStart->GetNext();
         --nCount;
     }
 
-    return -aRectFnSet.BottomDist(pStart->getFrameArea(), nTop);
+    return nRet;
 }
 
 // Local helper function to insert a new follow flow line

Reply via email to