sw/qa/extras/ooxmlexport/ooxmlexport18.cxx    |   11 ++++----
 writerfilter/source/dmapper/GraphicImport.cxx |   32 +++++++++++++++++---------
 2 files changed, 27 insertions(+), 16 deletions(-)

New commits:
commit 0b03dff37f4cad722819f36d5cf3bd39fb46d8ed
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Mon Jan 15 14:36:12 2024 -0500
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jan 22 14:20:31 2024 +0100

    tdf#159158 writerfilter: relativeHeight always under z-index
    
    No matter what z-index I chose, it always ends up being above
    a relativeHeight. Since a heaven z-index is 0+,
    that means that all relativeHeight's need to be treated as negative.
    
    IsInHeaderFooter is a complication, because these are ALWAYS treated
    as if they are below the text, and yet behindDoc relativeHeights
    still need to be below their counterparts.
    
    While this algorithm could never cover all the situations
    (it would require transitioning to a sal_Int64 to do that)
    it should be fine for practical purposes.
    
    Plus, there are some unknown complications surrounding this.
    If I increase the behindDoc relativeHeight by 1 in
    tdf159158_zOrder_behindDocB.docx
    the yellow star actually moves on top of the blue star,
    which totally debunks my theory.
    
    RTF doesn't really use relativeHeight,
    but if it did, these changes should apply anyway.
    
    Change-Id: I62e1f9ae8fe6f99534a2a799692120508204c553
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162234
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index e7040b6d8d0b..5699ecbe7953 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -989,16 +989,15 @@ DECLARE_OOXMLEXPORT_TEST(testTdf159158_zOrder_zIndexWins, 
"tdf159158_zOrder_zInd
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(zOrder0, 
"ZOrder")); // lower
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty<sal_Int32>(zOrder1, 
"ZOrder"));
     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), getProperty<sal_Int32>(zOrder2, 
"ZOrder")); // higher
-    // If zOrder is defined by z-index, it seems that it goes above everything 
set by relativeHeight
-    if (isExported()) // not named on import
-        CPPUNIT_ASSERT_EQUAL_MESSAGE("DID YOU FIX ME? Frame1 really should be 
at the very top",
-                                     OUString("Frame1"), 
getProperty<OUString>(zOrder0,"Name"));
     // I'm puzzled. Somehow 0 is larger than 0EFF FFFF, but not larger than 
0F00 0000
     // and yet the maximum value was established earlier as 1DFF FFFF. 
Something doesn't line up.
     // Perhaps 0 and 1 don't mean maximum value at all, but something 
completely different?
     CPPUNIT_ASSERT_MESSAGE("DID YOU FIX ME? I really should be yellow, not 
blue",
-                            "5-Point Star Yellow" != 
getProperty<OUString>(zOrder1, "Name"));
-    // CPPUNIT_ASSERT_EQUAL(OUString("5-Point Star Blue"), 
getProperty<OUString>(zOrder2,"Name"));
+                            "5-Point Star Yellow" != 
getProperty<OUString>(zOrder0, "Name"));
+    // CPPUNIT_ASSERT_EQUAL(OUString("5-Point Star Blue"), 
getProperty<OUString>(zOrder1,"Name"));
+    // If zOrder is defined by z-index, it seems that it goes above everything 
set by relativeHeight
+    if (isExported()) // not named on import
+        CPPUNIT_ASSERT_EQUAL(OUString("Frame1"), 
getProperty<OUString>(zOrder2,"Name"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTdf159158_zOrder_behindDocA, 
"tdf159158_zOrder_behindDocA.docx")
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx 
b/writerfilter/source/dmapper/GraphicImport.cxx
index b5f6d3385d58..4b0e199d1d17 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -210,7 +210,7 @@ public:
     sal_Int32 m_nTopPosition;
 
     bool      m_bUseSimplePos;
-    sal_Int32 m_zOrder;
+    std::optional<sal_Int32> m_oZOrder;
 
     sal_Int16 m_nHoriOrient;
     sal_Int16 m_nHoriRelation;
@@ -284,7 +284,6 @@ public:
         ,m_nLeftPosition(0)
         ,m_nTopPosition(0)
         ,m_bUseSimplePos(false)
-        ,m_zOrder(-1)
         ,m_nHoriOrient(   text::HoriOrientation::NONE )
         ,m_nHoriRelation( text::RelOrientation::FRAME )
         ,m_nVertOrient(  text::VertOrientation::NONE )
@@ -385,26 +384,33 @@ public:
 
     void applyZOrder(uno::Reference<beans::XPropertySet> const & 
xGraphicObjectProperties) const
     {
-        sal_Int32 nZOrder = m_zOrder;
+        std::optional<sal_Int32> oZOrder = m_oZOrder;
         bool bBehindText = m_bBehindDoc && !m_bOpaque;
         if (m_rGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE
             && !m_rDomainMapper.IsInShape())
         {
-            nZOrder = 0;
+            oZOrder = SAL_MIN_INT32;
+            bBehindText = false;
         }
-        if (nZOrder >= 0)
+        if (oZOrder)
         {
             // tdf#120760 Send objects with behinddoc=true to the back.
+            // Only relativeHeight zOrders have been used if m_bBehindDoc is 
set,
+            // and they have already been set as negative values (to be below 
all z-indexes).
+            // Subtract even more so behindDoc relativeHeights will be behind
+            // other relativeHeights and negative z-indexes (needed for 
IsInHeaderFooter).
+            // relativeHeight removed 0x1E00 0000, so can subtract another 
0x6200 0000
             if (bBehindText)
-                nZOrder -= SAL_MAX_INT32;
+                oZOrder = *oZOrder - 0x62000000;
 
             // TODO: it is possible that RTF has been wrong all along as well. 
Always true here?
             const bool bLastDuplicateWins(!m_rDomainMapper.IsRTFImport()
                 || m_rGraphicImportType == 
GraphicImportType::IMPORT_AS_DETECTED_INLINE);
+
             GraphicZOrderHelper* pZOrderHelper = 
m_rDomainMapper.graphicZOrderHelper();
             
xGraphicObjectProperties->setPropertyValue(getPropertyName(PROP_Z_ORDER),
-                uno::Any(pZOrderHelper->findZOrder(nZOrder, 
bLastDuplicateWins)));
-            pZOrderHelper->addItem(xGraphicObjectProperties, nZOrder);
+                uno::Any(pZOrderHelper->findZOrder(*oZOrder, 
bLastDuplicateWins)));
+            pZOrderHelper->addItem(xGraphicObjectProperties, *oZOrder);
         }
     }
 
@@ -743,9 +749,15 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
             // undocumented - based on testing: both 0 and 1 are equivalent to 
the maximum 503316479
             const sal_Int32 nMaxAllowed = 0x1DFFFFFF;
             if (nIntValue < 2 || nIntValue > nMaxAllowed)
-                m_pImpl->m_zOrder = nMaxAllowed;
+                m_pImpl->m_oZOrder = nMaxAllowed;
             else
-                m_pImpl->m_zOrder = nIntValue;
+                m_pImpl->m_oZOrder = nIntValue;
+
+            // all relativeHeight objects (i.e. DOCX graphics that use 
GraphicImport),
+            // no matter how high their value, are below the lowest z-index 
shape (in same layer)
+            // so emulate that by pretending that they are below text (in the 
hell-layer).
+            // Please be assured that this does not actually place it in the 
hell-layer.
+            m_pImpl->m_oZOrder = *m_pImpl->m_oZOrder - (nMaxAllowed + 1);
         }
         break;
         case NS_ooxml::LN_CT_Anchor_behindDoc:

Reply via email to