oox/source/vml/vmlshapecontext.cxx                        |    1 
 sw/qa/extras/ooxmlexport/data/tdf126533_noPageBitmap.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx                |   21 +++++
 writerfilter/source/dmapper/DomainMapper.cxx              |   58 ++++++++++++++
 writerfilter/source/dmapper/DomainMapper_Impl.hxx         |    1 
 writerfilter/source/dmapper/PropertyMap.cxx               |   33 +++++++
 writerfilter/source/ooxml/model.xml                       |    3 
 7 files changed, 115 insertions(+), 2 deletions(-)

New commits:
commit ec36ecb408bd77f1fa2d823454968f50d32f745c
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Sat Feb 3 10:08:56 2024 -0500
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Feb 26 08:42:19 2024 +0100

    tdf#126533 docx import: page background vml fill
    
    This patch imports bitmaps/tiled textures (primarily),
    but also somewhat for gradients
    (because of a gradient2 -> gradient mismatch somewhere)
    and somewhat for patterns
    (because patterns are not well imported in general).
    
    Note that the imported fill likely will NOT match MSO,
    because their background CHANGES BASED ON THE ZOOM LEVEL.
    For example, my primary testing file (A6 landscape)
    has a logo which is only 25% visible in Word 2003 at 100%,
    but shows 90% of the logo at 200%, and many tiles of logos
    when exported as PDF.
    The same is true for gradients etc.
    
    Changing background on zoom is an absolutely bizarre implementation,
    and naturally LO could only accidentally look identical
    (and should never try to do so).
    
    make CppunitTest_sw_ooxmlexport21 \
        CPPUNIT_TEST_NAME=testTdf126533_noPageBitmap
    
    make CppunitTest_sw_ooxmlexport21 \
        CPPUNIT_TEST_NAME=testTdf126533_pageGradient
    
    This is slightly ugly, but I don't know how to make a COPY
    of the XPropertySet UNO junk. All I have is references,
    and dispose deletes everything, even the references.
    
    I took some inspiration from RTF
    which just disposes the shape after grabbing the background color.
    
    Thus, just change the page style known to exist and be used,
    and then simply remove the fill if it isn't needed in the end.
    Any new page styles can just copy the default page style fill.
    
    Change-Id: Id3ea002c685642ff4c289982d0108247a6e9bb8d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162958
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163861
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Justin Luth <jl...@mail.com>

diff --git a/oox/source/vml/vmlshapecontext.cxx 
b/oox/source/vml/vmlshapecontext.cxx
index e3242368a334..20ce2fa37434 100644
--- a/oox/source/vml/vmlshapecontext.cxx
+++ b/oox/source/vml/vmlshapecontext.cxx
@@ -251,6 +251,7 @@ ContextHandlerRef ShapeContextBase::createShapeContext( 
ContextHandler2Helper co
                 return new ShapeContext( rParent, rShapes.createShape< 
BezierShape >(), rAttribs );
             else
                 return new ShapeContext( rParent, rShapes.createShape< 
ComplexShape >(), rAttribs );
+        case VML_TOKEN(background):
         case VML_TOKEN( rect ):
             return new RectangleShapeContext( rParent, rAttribs, 
rShapes.createShape< RectangleShape >() );
         case VML_TOKEN( roundrect ):
diff --git a/sw/qa/core/data/ooxml/pass/fill.docx 
b/sw/qa/extras/ooxmlexport/data/fill.docx
similarity index 100%
rename from sw/qa/core/data/ooxml/pass/fill.docx
rename to sw/qa/extras/ooxmlexport/data/fill.docx
diff --git a/sw/qa/extras/ooxmlexport/data/tdf126533_noPageBitmap.docx 
b/sw/qa/extras/ooxmlexport/data/tdf126533_noPageBitmap.docx
new file mode 100644
index 000000000000..87dfff296be5
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf126533_noPageBitmap.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index cdcdfe778577..ca0cc5438ee6 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -10,6 +10,7 @@
 #include <swmodeltestbase.hxx>
 
 #include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
 #include <com/sun/star/text/XDocumentIndex.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/style/LineSpacing.hpp>
@@ -62,6 +63,26 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159207_footerFramePrBorder)
     // TODO: there SHOULD BE a top border, and even if loaded, it would be 
lost on re-import...
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf126533_noPageBitmap, 
"tdf126533_noPageBitmap.docx")
+{
+    // given a document with a v:background bitmap, but no w:background 
fillcolor
+    uno::Reference<beans::XPropertySet> 
xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+                                                   uno::UNO_QUERY);
+    // the image (or any fill for that matter) should be ignored.
+    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE,
+                         getProperty<drawing::FillStyle>(xPageStyle, 
"FillStyle"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf126533_pageGradient)
+{
+    // given a document with a gradient page background
+    loadFromFile(u"fill.docx");
+    uno::Reference<beans::XPropertySet> 
xPageStyle(getStyles("PageStyles")->getByName("Standard"),
+                                                   uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT,
+                         getProperty<drawing::FillStyle>(xPageStyle, 
"FillStyle"));
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index bbeafa942de4..50f47439af27 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -32,6 +32,8 @@
 #include <ooxml/resourceids.hxx>
 #include <oox/token/tokens.hxx>
 #include <oox/drawingml/drawingmltypes.hxx>
+
+#include <com/sun/star/awt/Gradient2.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/document/XOOXMLDocumentPropertiesImporter.hpp>
 #include <com/sun/star/drawing/FillStyle.hpp>
@@ -1475,7 +1477,63 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
     switch (rSprm.getId())
     {
     case NS_ooxml::LN_background_background:
+    {
+        // if a VML background has been defined, it was imported into a shape 
to hold the properties
+        uno::Reference<drawing::XShape> xFill(m_pImpl->PopPendingShape());
+        if (xFill.is())
+        {
+            assert(!m_pImpl->GetTopContext());
+            assert(m_pImpl->GetIsFirstParagraphInShape());
+            assert(mbWasShapeInPara);
+            assert(m_pImpl->GetIsFirstParagraphInSection());
+            assert(m_pImpl->IsOutsideAParagraph());
+            if (m_pImpl->GetSettingsTable()->GetDisplayBackgroundShape())
+            {
+                // apply the XATTR_FILL attributes to the default page style
+                const uno::Reference<beans::XPropertySet> 
xFillPropertySet(xFill, uno::UNO_QUERY);
+                const uno::Reference<beans::XPropertySetInfo> xFillInfo
+                    = xFillPropertySet->getPropertySetInfo();
+                uno::Reference<beans::XPropertySet> xPS(
+                    m_pImpl->GetPageStyles()->getByName("Standard"), 
uno::UNO_QUERY_THROW);
+                for (const beans::Property& rProp : 
xPS->getPropertySetInfo()->getProperties())
+                {
+                    if (rProp.Name == "FillComplexColor" || rProp.Name == 
"FillGradientName"
+                        || rProp.Name == "FillGradientStepCount"
+                        || rProp.Name == "FillTransparenceGradientName"
+                        || rProp.Name == "FillBitmapURL" || rProp.Name == 
"FillColor2")
+                    {
+                        // silence exceptions for unsupported stuff when 
appling to page style
+                        continue;
+                    }
+                    if (!rProp.Name.startsWith("Fill"))
+                        continue;
+
+                    if (!xFillInfo->hasPropertyByName(rProp.Name))
+                        continue;
+
+                    try
+                    {
+                        const uno::Any aFillValue = 
xFillPropertySet->getPropertyValue(rProp.Name);
+                        xPS->setPropertyValue(rProp.Name, aFillValue);
+                    }
+                    catch (uno::Exception&)
+                    {
+                        DBG_UNHANDLED_EXCEPTION("writerfilter", "Exception 
setting page background fill");
+                    }
+                }
+
+                m_pImpl->m_bCopyStandardPageStyleFill = true;
+            }
+
+            // The background was unhelpfully imported into the text body: 
remove it
+            uno::Reference<lang::XComponent> xComponent(xFill, 
uno::UNO_QUERY_THROW);
+            xComponent->dispose();
+
+            m_pImpl->SetIsFirstParagraphInShape(false);
+            mbWasShapeInPara = false;
+        }
         return;
+    }
     default:
         break;
     }
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 7db3dbcddcae..0a0bb4cf4f8a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -1141,6 +1141,7 @@ public:
 
     /// Document background color, applied to every page style.
     std::optional<sal_Int32> m_oBackgroundColor;
+    bool m_bCopyStandardPageStyleFill = false;
 
     /// Raw table cell depth.
     sal_Int32 m_nTableCellDepth;
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index 9c3e031e40b0..15ba4bb582e1 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -40,6 +40,7 @@
 #include <com/sun/star/container/XEnumeration.hpp>
 #include <com/sun/star/container/XEnumerationAccess.hpp>
 #include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
 #include <com/sun/star/style/BreakType.hpp>
 #include <com/sun/star/style/PageStyleLayout.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
@@ -1134,7 +1135,37 @@ void 
SectionPropertyMap::HandleMarginsHeaderFooter(DomainMapper_Impl& rDM_Impl)
     Insert( PROP_RIGHT_MARGIN, uno::Any( m_nRightMargin ) );
     Insert(PROP_GUTTER_MARGIN, uno::Any(m_nGutterMargin));
 
-    if ( rDM_Impl.m_oBackgroundColor )
+    // w:background is applied to every page in the document
+    if (!rDM_Impl.m_oBackgroundColor.has_value() && !rDM_Impl.IsRTFImport())
+    {
+        // DOCX has an interesting quirk, where if the fallback background 
color is not defined,
+        // then the fill is not applied either.
+
+        // Disable the imported fill from the default style
+        if (rDM_Impl.m_bCopyStandardPageStyleFill && m_sPageStyleName == 
"Standard")
+        {
+            rDM_Impl.m_bCopyStandardPageStyleFill = false;
+            m_aPageStyle->setPropertyValue("FillStyle", 
uno::Any(drawing::FillStyle_NONE));
+        }
+    }
+    else if (rDM_Impl.m_bCopyStandardPageStyleFill) // complex fill: 
graphics/gradients/patterns
+    {
+        uno::Reference<beans::XPropertySet> xDefaultPageStyle(
+                    rDM_Impl.GetPageStyles()->getByName("Standard"), 
uno::UNO_QUERY_THROW);
+        for (const beans::Property& rProp : 
m_aPageStyle->getPropertySetInfo()->getProperties())
+        {
+            try
+            {
+                const uno::Any aFillValue = 
xDefaultPageStyle->getPropertyValue(rProp.Name);
+                m_aPageStyle->setPropertyValue(rProp.Name, aFillValue);
+            }
+            catch (uno::Exception&)
+            {
+                DBG_UNHANDLED_EXCEPTION("writerfilter", "Exception setting 
page background fill");
+            }
+        }
+    }
+    else if (rDM_Impl.m_oBackgroundColor) // simple, solid color
         Insert( PROP_BACK_COLOR, uno::Any( *rDM_Impl.m_oBackgroundColor ) );
 
     // Check for missing footnote separator only in case there is at least
diff --git a/writerfilter/source/ooxml/model.xml 
b/writerfilter/source/ooxml/model.xml
index 2c174743f990..2f84e72c0615 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -17744,12 +17744,13 @@
       <element name="sectPr" tokenid="ooxml:CT_PPr_sectPr"/>
       <element name="pPrChange" tokenid="ooxml:CT_PPr_pPrChange"/>
     </resource>
-    <resource name="CT_Background" resource="Properties">
+    <resource name="CT_Background" resource="Shape">
       <attribute name="color" tokenid="ooxml:CT_Background_color"/>
       <attribute name="themeColor" tokenid="ooxml:CT_Background_themeColor"/>
       <attribute name="themeTint" tokenid="ooxml:CT_Background_themeTint"/>
       <attribute name="themeShade" tokenid="ooxml:CT_Background_themeShade"/>
       <element name="v:background" tokenid="ooxml:CT_Background_v_background"/>
+      <action name="end" action="sendPropertiesWithId" 
sendtokenid="ooxml:background_background"/>
     </resource>
     <resource name="CT_Rel" resource="Properties">
       <attribute name="r:id" tokenid="ooxml:CT_Rel_id"/>

Reply via email to