sw/qa/extras/rtfexport/data/tdf167679.fodt |   25 +++++++
 sw/qa/extras/rtfexport/rtfexport8.cxx      |   95 +++++++++++++++++++++++++++++
 sw/source/filter/ww8/ww8atr.cxx            |   16 +---
 3 files changed, 126 insertions(+), 10 deletions(-)

New commits:
commit cf60cb680e85b80821f9ca9adcb0647428e0027f
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Jul 26 21:33:06 2025 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Mon Jul 28 11:12:35 2025 +0200

    tdf#167679: RTF already can export rdrnone
    
    In commit f84b33275f6cce21e93e5dd20f3de5df84df0276 (tdf#129522
    ww8import/export: allow char shadow_NONE overrides, 2020-01-04),
    export of char shadow was implemented, which made CharBorder to
    be called for missing borderline. But it made an exception for
    RTF, because at that time, its code couldn't handle that.
    
    In commit eca3ce35fe9a346965a32f42d02cb6d3f5a3982f (tdf#129631
    writerfilter,sw: RTF import of invalid border..., 2022-08-11),
    RTF export got ability to handle that.
    
    Removal of the exception for RTF fixed missing export of "no
    border" and "no shadow" character formatting.
    
    Change-Id: I5f23b09558d32b403e0c26c727ee01f79374e54d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188418
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/qa/extras/rtfexport/data/tdf167679.fodt 
b/sw/qa/extras/rtfexport/data/tdf167679.fodt
new file mode 100644
index 000000000000..fad1dacf5b45
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf167679.fodt
@@ -0,0 +1,25 @@
+<?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:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:text-properties style:font-name="Liberation Serif" 
fo:font-size="12pt"/>
+  </style:default-style>
+  <style:style style:name="border" style:family="text">
+   <style:text-properties loext:padding="0.5mm" loext:border="0.11pt solid 
#FF0000" loext:shadow="#808080 5pt 5pt"/>
+  </style:style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="T1" style:family="text">
+   <style:text-properties loext:padding="0.5mm" loext:border="none" 
loext:shadow="none"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p>s<text:span text:style-name="border">om<text:span 
text:style-name="T1">eth</text:span>in</text:span>g</text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index 370f069f6f43..471440e02219 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
 #include <com/sun/star/style/TabStop.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
 
 #include <basegfx/utils/gradienttools.hxx>
 #include <comphelper/sequenceashashmap.hxx>
@@ -1080,6 +1081,100 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf167661)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf167679)
+{
+    // Given a document with a char style with a border with a shadow, and a 
direct formatting
+    // applied over it, which turns off the border and the shadow:
+    createSwDoc("tdf167679.fodt");
+
+    {
+        auto xRun = getRun(getParagraph(1), 1, u"s"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 2, u"om"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000, 0, 4, 0, 0, 
4), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, 
aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 3, u"eth"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 4, u"in"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000, 0, 4, 0, 0, 
4), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, 
aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 5, u"g"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+
+    // Check that after export to RTF, the area in the middle still has no 
border
+    saveAndReload(mpFilter);
+
+    {
+        auto xRun = getRun(getParagraph(1), 1, u"s"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+    {
+        // Without a fix, this failed, because the second run was "omethin": 
the middle
+        // direct formatting that cancelled the border didn't round-trip.
+        auto xRun = getRun(getParagraph(1), 2, u"om"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000, 0, 4, 0, 0, 
4), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, 
aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 3, u"eth"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 4, u"in"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF0000, 0, 4, 0, 0, 
4), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, 
aShadow.Location);
+    }
+    {
+        auto xRun = getRun(getParagraph(1), 5, u"g"_ustr);
+        auto aBorder = getProperty<table::BorderLine2>(xRun, 
u"CharTopBorder"_ustr);
+        CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0x000000, 0, 0, 0, 
32767, 0), aBorder);
+
+        auto aShadow = getProperty<table::ShadowFormat>(xRun, 
u"CharShadowFormat"_ustr);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+    }
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 327c4e263422..af56c94140d3 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -6090,17 +6090,13 @@ void AttributeOutputBase::FormatCharBorder( const 
SvxBoxItem& rBox )
        nDist = rBox.GetDistance( SvxBoxItemLine::RIGHT );
     }
 
-    // RTF: avoid regressions since RTF doesn't know how to export a 
border_NONE style-override
-    if( pBorderLine || GetExport().GetExportFormat() != 
MSWordExportBase::ExportFormat::RTF )
-    {
-        const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
-        const SvxShadowItem* pShadowItem = static_cast<const 
SvxShadowItem*>(pItem);
-        const bool bShadow = pBorderLine &&
-            pShadowItem && pShadowItem->GetLocation() != 
SvxShadowLocation::NONE &&
-            pShadowItem->GetWidth() > 0;
+    const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
+    const SvxShadowItem* pShadowItem = static_cast<const 
SvxShadowItem*>(pItem);
+    const bool bShadow = pBorderLine &&
+        pShadowItem && pShadowItem->GetLocation() != SvxShadowLocation::NONE &&
+        pShadowItem->GetWidth() > 0;
 
-        CharBorder( pBorderLine, nDist, bShadow );
-    }
+    CharBorder( pBorderLine, nDist, bShadow );
 }
 
 /*

Reply via email to