This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch AOO50X
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit 454dc927f66efcf476e75e71b2be6c1d696f6e39
Author: Jim Jagielski <[email protected]>
AuthorDate: Wed Nov 4 05:13:39 2026 -0500

    xmloff: write Impress table cell fills as style:background-fill in ODF 1.4
---
 main/xmloff/source/style/prstylei.cxx       | 27 +++++++++++-
 main/xmloff/source/style/xmlexppr.cxx       | 66 ++++++++++++++++++++++++++---
 main/xmloff/source/table/XMLTableExport.cxx |  5 ++-
 3 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/main/xmloff/source/style/prstylei.cxx 
b/main/xmloff/source/style/prstylei.cxx
index 945fa8d001..8d6aede563 100644
--- a/main/xmloff/source/style/prstylei.cxx
+++ b/main/xmloff/source/style/prstylei.cxx
@@ -174,6 +174,28 @@ namespace
 {
 const sal_Char s_aExtGraphicNamespace[] = 
"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0";
 
+// ODF 1.4: the fill of a table cell style is in a style:background-fill child 
of its style:table-cell-properties
+class XMLTableCellPropsContext : public SvXMLPropertySetContext
+{
+public:
+    XMLTableCellPropsContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const 
OUString& rLName,
+        const Reference< XAttributeList >& xAttrList, std::vector< 
XMLPropertyState >& rProps,
+        const UniReference< SvXMLImportPropertyMapper >& rMap )
+    :   SvXMLPropertySetContext( rImport, nPrfx, rLName, xAttrList, 
XML_TYPE_PROP_TABLE_CELL, rProps, rMap )
+    {
+    }
+
+    using SvXMLPropertySetContext::CreateChildContext;
+    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const 
OUString& rLocalName,
+        const Reference< XAttributeList >& xAttrList )
+    {
+        if( XML_NAMESPACE_STYLE == nPrefix && IsXMLToken( rLocalName, 
XML_BACKGROUND_FILL ) )
+            return new SvXMLPropertySetContext( GetImport(), nPrefix, 
rLocalName, xAttrList,
+                                                XML_TYPE_PROP_GRAPHIC, 
mrProperties, mxMapper );
+        return SvXMLPropertySetContext::CreateChildContext( nPrefix, 
rLocalName, xAttrList );
+    }
+};
+
 // Keeps the fill only if it is usable and no earlier fill exists; otherwise 
the fallback attributes apply.
 class XMLExtParaFillContext : public SvXMLPropertySetContext
 {
@@ -314,7 +336,10 @@ SvXMLImportContext 
*XMLPropStyleContext::CreateChildContext(
                UniReference < SvXMLImportPropertyMapper > xImpPrMap =
                        ((SvXMLStylesContext 
*)&mxStyles)->GetImportPropertyMapper(
                                                                                
                                GetFamily() );
-               if( xImpPrMap.is() )
+               if( xImpPrMap.is() && nFamily == XML_TYPE_PROP_TABLE_CELL )
+                       pContext = new XMLTableCellPropsContext( GetImport(), 
nPrefix, rLocalName, xAttrList,
+                                                                               
                         maProperties, xImpPrMap );
+               else if( xImpPrMap.is() )
                        pContext = new SvXMLPropertySetContext( GetImport(), 
nPrefix,
                                                                                
                        rLocalName, xAttrList,
                                                                                
                        nFamily,
diff --git a/main/xmloff/source/style/xmlexppr.cxx 
b/main/xmloff/source/style/xmlexppr.cxx
index 3a7c76dd29..45e9bd61ca 100644
--- a/main/xmloff/source/style/xmlexppr.cxx
+++ b/main/xmloff/source/style/xmlexppr.cxx
@@ -104,6 +104,25 @@ static sal_Bool lcl_IsHeaderFooterFill( const 
UniReference< XMLPropertySetMapper
                        IsXMLToken( rMapper->GetEntryXMLName( nIdx ), 
XML_REPEAT ) ) );
 }
 
+// The shape fill entries of an Impress table cell style; ODF 1.4 writes them 
in a style:background-fill child
+// of style:table-cell-properties.
+static sal_Bool lcl_IsTableCellFill( const UniReference< XMLPropertySetMapper 
>& rMapper, sal_Int32 nIdx )
+{
+       return ( rMapper->GetEntryFlags( nIdx ) & XML_TYPE_PROP_MASK ) == 
XML_TYPE_PROP_GRAPHIC &&
+               rMapper->GetEntryAPIName( nIdx ).matchAsciiL( 
RTL_CONSTASCII_STRINGPARAM( "Fill" ) ) &&
+               ( rMapper->GetEntryNameSpace( nIdx ) == XML_NAMESPACE_DRAW ||
+                 ( rMapper->GetEntryNameSpace( nIdx ) == XML_NAMESPACE_STYLE &&
+                       IsXMLToken( rMapper->GetEntryXMLName( nIdx ), 
XML_REPEAT ) ) );
+}
+
+static sal_Bool lcl_HasTableCellProperties( const UniReference< 
XMLPropertySetMapper >& rMapper )
+{
+       for( sal_Int32 n = 0; n < rMapper->GetEntryCount(); ++n )
+               if( ( rMapper->GetEntryFlags( n ) & XML_TYPE_PROP_MASK ) == 
XML_TYPE_PROP_TABLE_CELL )
+                       return sal_True;
+       return sal_False;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 //
 // public methods
@@ -871,7 +890,35 @@ void SvXMLExportPropertyMapper::exportXML(
                sal_Int32 nPropMapStartIdx, sal_Int32 nPropMapEndIdx,
                sal_uInt16 nFlags ) const
 {
-       sal_uInt16 nPropTypeFlags = 0;
+       const SvtSaveOptions::ODFDefaultVersion eVersion( 
SvtSaveOptions().GetODFDefaultVersion() );
+       const bool b014 = eVersion == SvtSaveOptions::ODFVER_014 || eVersion == 
SvtSaveOptions::ODFVER_014_EXT;
+
+       // ODF 1.4: the fill of a table cell style goes into a 
style:background-fill child of its table-cell-properties
+       ::std::vector< XMLPropertyState > aCellMainProps, aCellFillProps;
+       const ::std::vector< XMLPropertyState >* pAllProps = &rProperties;
+       bool bCellFill = false;
+       if( b014 && lcl_HasTableCellProperties( maPropMapper ) )
+       {
+               aCellMainProps = rProperties;
+               aCellFillProps = rProperties;
+               for( size_t n = 0; n < rProperties.size(); ++n )
+               {
+                       const sal_Int32 nIdx = rProperties[n].mnIndex;
+                       if( nIdx == -1 )
+                               continue;
+                       if( lcl_IsTableCellFill( maPropMapper, nIdx ) )
+                       {
+                               aCellMainProps[n].mnIndex = -1;
+                               bCellFill = true;
+                       }
+                       else
+                               aCellFillProps[n].mnIndex = -1;
+               }
+               if( bCellFill )
+                       pAllProps = &aCellMainProps;
+       }
+
+       sal_uInt16 nPropTypeFlags = bCellFill ? ( 1 << GET_PROP_TYPE( 
XML_TYPE_PROP_TABLE_CELL ) ) : 0;
        for( sal_uInt16 i=0; i<MAX_PROP_TYPES; ++i )
        {
                sal_uInt16 nPropType = aPropTokens[i].nType;
@@ -881,12 +928,21 @@ void SvXMLExportPropertyMapper::exportXML(
 
                        // ODF 1.4: header and footer fills go into a 
style:background-fill child
                        ::std::vector< XMLPropertyState > aMainProps, 
aFillProps;
-                       const ::std::vector< XMLPropertyState >* pMainProps = 
&rProperties;
+                       const ::std::vector< XMLPropertyState >* pMainProps = 
pAllProps;
                        SvXMLAttributeList* pFillAttrs = 0;
                        uno::Reference< xml::sax::XAttributeList > xFillAttrs;
-                       const SvtSaveOptions::ODFDefaultVersion eVersion( 
SvtSaveOptions().GetODFDefaultVersion() );
-                       if( aPropTokens[i].eToken == 
XML_HEADER_FOOTER_PROPERTIES &&
-                               ( eVersion == SvtSaveOptions::ODFVER_014 || 
eVersion == SvtSaveOptions::ODFVER_014_EXT ) )
+                       if( bCellFill && aPropTokens[i].eToken == 
XML_TABLE_CELL_PROPERTIES )
+                       {
+                               pFillAttrs = new SvXMLAttributeList;
+                               xFillAttrs = pFillAttrs;
+                               sal_uInt16 nFillTypeFlags = 0;
+                               _exportXML( GET_PROP_TYPE( 
XML_TYPE_PROP_GRAPHIC ), nFillTypeFlags, *pFillAttrs, aCellFillProps,
+                                                       
rExport.GetMM100UnitConverter(),
+                                                       
rExport.GetNamespaceMap(),
+                                                       nFlags, 0,
+                                                       nPropMapStartIdx, 
nPropMapEndIdx );
+                       }
+                       else if( aPropTokens[i].eToken == 
XML_HEADER_FOOTER_PROPERTIES && b014 )
                        {
                                aMainProps = rProperties;
                                aFillProps = rProperties;
diff --git a/main/xmloff/source/table/XMLTableExport.cxx 
b/main/xmloff/source/table/XMLTableExport.cxx
index 29d79d6b4c..ca30a13788 100644
--- a/main/xmloff/source/table/XMLTableExport.cxx
+++ b/main/xmloff/source/table/XMLTableExport.cxx
@@ -126,6 +126,8 @@ protected:
 void XMLTableCellExportPropertyMapper::ContextFilter( std::vector< 
XMLPropertyState >& rProperties, Reference< XPropertySet > rPropSet ) const
 {
        const bool bStrict = SvtSaveOptions::IsODFStrict( 
SvtSaveOptions().GetODFDefaultVersion() );
+       // ODF 1.4 keeps the fill, in a style:background-fill child
+       const bool b014 = SvtSaveOptions().GetODFDefaultVersion() == 
SvtSaveOptions::ODFVER_014;
        bool bSolid = false;
        if( bStrict ) try
        {
@@ -147,7 +149,8 @@ void XMLTableCellExportPropertyMapper::ContextFilter( 
std::vector< XMLPropertySt
                        if( !bSolid )
                                aIter->mnIndex = -1;
                }
-               else if( bStrict && nPropType == XML_TYPE_PROP_GRAPHIC )
+               else if( bStrict && nPropType == XML_TYPE_PROP_GRAPHIC &&
+                                !( b014 && maPropMapper->GetEntryAPIName( 
aIter->mnIndex ).matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Fill" ) ) ) )
                        aIter->mnIndex = -1;
        }
 

Reply via email to