writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx                       |   
21 ++++++++++
 writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx 
|binary
 writerfilter/source/dmapper/PropertyMap.cxx                                |   
11 ++++-
 3 files changed, 30 insertions(+), 2 deletions(-)

New commits:
commit 3eb6d764b3023500f2299d36bf1860bc8e67db9f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jan 21 10:06:02 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jan 21 12:31:24 2022 +0100

    DOCX import: floating table with negative top margin has to be a fly frame
    
    The bugdoc has a large header, then part of the table goes into the
    whitespace of the header by specifying a negative vertical position.
    
    Keep this as a floating table as normal tables can't have negative top
    margins.
    
    Change-Id: I95299051f004976778765965971428d9764bef08
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128724
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx 
b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
index 7b552af94bb0..ae32ce1e4dc7 100644
--- a/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
@@ -15,6 +15,7 @@
 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 
 using namespace ::com::sun::star;
 
@@ -87,6 +88,26 @@ CPPUNIT_TEST_FIXTURE(Test, testFollowPageTopMargin)
     // i.e. the top margin on page 2 was too large.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(250), nTopMargin);
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testTableNegativeVerticalPos)
+{
+    // Given a document with a table which has a negative vertical position 
(moves up to overlap
+    // with the header):
+    OUString aURL
+        = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"table-negative-vertical-pos.docx";
+
+    // When loading that document:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure we don't import that as a plain table, which can't have 
a negative top margin:
+    uno::Reference<drawing::XDrawPageSupplier> 
xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage = 
xDrawPageSupplier->getDrawPage();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. this was imported as a plain table, resulting in a 0 top margin (y 
pos too large).
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git 
a/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx 
b/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx
new file mode 100644
index 000000000000..2031f4769877
Binary files /dev/null and 
b/writerfilter/qa/cppunittests/dmapper/data/table-negative-vertical-pos.docx 
differ
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx 
b/writerfilter/source/dmapper/PropertyMap.cxx
index 8634d66e1ae5..58871cc04538 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1146,6 +1146,15 @@ bool SectionPropertyMap::FloatingTableConversion( const 
DomainMapper_Impl& rDM_I
     if (rDM_Impl.m_bConvertedTable && !rDM_Impl.GetIsLastSectionGroup() && 
rInfo.m_nBreakType == NS_ooxml::LN_Value_ST_SectionMark_nextPage)
         return false;
 
+    sal_Int32 nVertOrientPosition = 
rInfo.getPropertyValue(u"VertOrientPosition").get<sal_Int32>();
+    sal_Int16 nHoriOrientRelation = rInfo.getPropertyValue( 
u"HoriOrientRelation" ).get<sal_Int16>();
+    if (nVertOrientPosition < 0 && nHoriOrientRelation != 
text::RelOrientation::PAGE_FRAME)
+    {
+        // Negative vertical position: then need a floating table, as normal 
tables can't have
+        // negative top margins.
+        return true;
+    }
+
     sal_Int32 nPageWidth = GetPageWidth();
     sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin();
     // Count the layout width of the table.
@@ -1161,7 +1170,6 @@ bool SectionPropertyMap::FloatingTableConversion( const 
DomainMapper_Impl& rDM_I
     if ( rInfo.getPropertyValue( u"RightMargin" ) >>= nRightMargin )
         nTableWidth += nRightMargin;
 
-    sal_Int16 nHoriOrientRelation = rInfo.getPropertyValue( 
u"HoriOrientRelation" ).get<sal_Int16>();
     sal_Int16 nVertOrientRelation = rInfo.getPropertyValue( 
u"VertOrientRelation" ).get<sal_Int16>();
     if ( nHoriOrientRelation == text::RelOrientation::PAGE_FRAME && 
nVertOrientRelation == text::RelOrientation::PAGE_FRAME )
     {
@@ -1174,7 +1182,6 @@ bool SectionPropertyMap::FloatingTableConversion( const 
DomainMapper_Impl& rDM_I
             // The more close we are to the bottom, the more likely the table 
will span over to the next page
             // So if we're in the bottom left quarter, don't do any conversion.
             sal_Int32 nHoriOrientPosition = rInfo.getPropertyValue( 
u"HoriOrientPosition" ).get<sal_Int32>();
-            sal_Int32 nVertOrientPosition = rInfo.getPropertyValue( 
u"VertOrientPosition" ).get<sal_Int32>();
             sal_Int32 nPageHeight = getProperty( PROP_HEIGHT 
)->second.get<sal_Int32>();
             if ( nHoriOrientPosition < (nPageWidth / 2) && nVertOrientPosition 
>( nPageHeight / 2 ) )
                 return false;

Reply via email to