editeng/source/items/frmitems.cxx                        |   97 +++++++-
 include/editeng/boxitem.hxx                              |    7 
 oox/source/token/properties.txt                          |    4 
 sw/qa/extras/ooxmlexport/data/Test_ThemeBorderColor.docx |binary
 sw/qa/extras/ooxmlexport/ooxml_ThemeExport.cxx           |   30 ++
 sw/qa/inc/swmodeltestbase.hxx                            |    9 
 sw/source/core/unocore/unomap1.cxx                       |   12 -
 sw/source/core/unocore/unomapproperties.hxx              |    8 
 sw/source/filter/ww8/docxattributeoutput.cxx             |  180 +++++++--------
 writerfilter/source/dmapper/BorderHandler.cxx            |   34 ++
 writerfilter/source/dmapper/BorderHandler.hxx            |    8 
 writerfilter/source/dmapper/DomainMapper.cxx             |   40 ++-
 writerfilter/source/dmapper/PropertyIds.cxx              |    8 
 writerfilter/source/dmapper/PropertyIds.hxx              |   11 
 writerfilter/source/dmapper/TDefTableHandler.cxx         |   22 +
 writerfilter/source/dmapper/TDefTableHandler.hxx         |   12 -
 16 files changed, 370 insertions(+), 112 deletions(-)

New commits:
commit 92fc0ace46398eeb6c9238c8292459cc78db6694
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Jun 10 22:25:43 2023 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Mon Jun 12 03:54:48 2023 +0200

    ooxml: import and export border theme colors for various props.
    
    This adds support to import and export various border (lines)
    theme color properties.
    
    SvxBoxItem needed to be fixed, because it can happen that the
    BorderLine is not yet initialised and we already set the border's
    ComplexColor. Now there is a maTempComplexColor inside SvxBoxItem,
    which stores the ComplexColor until the specific BorderLine is
    initialized.
    
    In addition add roundtrip test for import and export cycle.
    
    Change-Id: Idd307a3adaf364745aed8fc8540bf72ef4948198
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152833
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/editeng/source/items/frmitems.cxx 
b/editeng/source/items/frmitems.cxx
index 77c497079634..94b7704303ba 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -2301,6 +2301,7 @@ SvxBoxItem::SvxBoxItem(const SvxBoxItem& rCopy)
     , mnBottomDistance(rCopy.mnBottomDistance)
     , mnLeftDistance(rCopy.mnLeftDistance)
     , mnRightDistance(rCopy.mnRightDistance)
+    , maTempComplexColors(rCopy.maTempComplexColors)
     , mbRemoveAdjCellBorder(rCopy.mbRemoveAdjCellBorder)
 {
 }
@@ -2369,6 +2370,7 @@ bool SvxBoxItem::operator==( const SfxPoolItem& rAttr ) 
const
         (mnLeftDistance == rBoxItem.mnLeftDistance) &&
         (mnRightDistance == rBoxItem.mnRightDistance) &&
         (mbRemoveAdjCellBorder == rBoxItem.mbRemoveAdjCellBorder ) &&
+        (maTempComplexColors == rBoxItem.maTempComplexColors) &&
         CompareBorderLine(mpTopBorderLine, rBoxItem.GetTop()) &&
         CompareBorderLine(mpBottomBorderLine, rBoxItem.GetBottom()) &&
         CompareBorderLine(mpLeftBorderLine, rBoxItem.GetLeft()) &&
@@ -2462,8 +2464,11 @@ bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 
nMemberId ) const
         {
             if (mpBottomBorderLine)
             {
-                auto xComplexColor = 
model::color::createXComplexColor(mpBottomBorderLine->getComplexColor());
-                rVal <<= xComplexColor;
+                rVal <<= 
model::color::createXComplexColor(mpBottomBorderLine->getComplexColor());
+            }
+            else if 
(maTempComplexColors[size_t(SvxBoxItemLine::BOTTOM)].getType() != 
model::ColorType::Unused)
+            {
+                rVal <<= 
model::color::createXComplexColor(maTempComplexColors[size_t(SvxBoxItemLine::BOTTOM)]);
             }
             return true;
         }
@@ -2471,8 +2476,11 @@ bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 
nMemberId ) const
         {
             if (mpLeftBorderLine)
             {
-                auto xComplexColor = 
model::color::createXComplexColor(mpLeftBorderLine->getComplexColor());
-                rVal <<= xComplexColor;
+                rVal <<= 
model::color::createXComplexColor(mpLeftBorderLine->getComplexColor());
+            }
+            else if 
(maTempComplexColors[size_t(SvxBoxItemLine::LEFT)].getType() != 
model::ColorType::Unused)
+            {
+                rVal <<= 
model::color::createXComplexColor(maTempComplexColors[size_t(SvxBoxItemLine::LEFT)]);
             }
             return true;
         }
@@ -2480,8 +2488,11 @@ bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 
nMemberId ) const
         {
             if (mpRightBorderLine)
             {
-                auto xComplexColor = 
model::color::createXComplexColor(mpRightBorderLine->getComplexColor());
-                rVal <<= xComplexColor;
+                rVal <<= 
model::color::createXComplexColor(mpRightBorderLine->getComplexColor());
+            }
+            else if 
(maTempComplexColors[size_t(SvxBoxItemLine::RIGHT)].getType() != 
model::ColorType::Unused)
+            {
+                rVal <<= 
model::color::createXComplexColor(maTempComplexColors[size_t(SvxBoxItemLine::RIGHT)]);
             }
             return true;
         }
@@ -2489,8 +2500,11 @@ bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 
nMemberId ) const
         {
             if (mpTopBorderLine)
             {
-                auto xComplexColor = 
model::color::createXComplexColor(mpTopBorderLine->getComplexColor());
-                rVal <<= xComplexColor;
+                rVal <<= 
model::color::createXComplexColor(mpTopBorderLine->getComplexColor());
+            }
+            else if 
(maTempComplexColors[size_t(SvxBoxItemLine::TOP)].getType() != 
model::ColorType::Unused)
+            {
+                rVal <<= 
model::color::createXComplexColor(maTempComplexColors[size_t(SvxBoxItemLine::TOP)]);
             }
             return true;
         }
@@ -2620,6 +2634,7 @@ bool SvxBoxItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
                 {
                     if (!lcl_setLine(aSeq[n], *this, aBorders[n], bConvert))
                         return false;
+                    tryMigrateComplexColor(aBorders[n]);
                 }
 
                 // WTH are the borders and the distances saved in different 
order?
@@ -2722,24 +2737,60 @@ bool SvxBoxItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
         {
             if (mpBottomBorderLine)
                 return mpBottomBorderLine->setComplexColorFromAny(rVal);
+            else
+            {
+                css::uno::Reference<css::util::XComplexColor> xComplexColor;
+                if (!(rVal >>= xComplexColor))
+                    return false;
+
+                if (xComplexColor.is())
+                    maTempComplexColors[size_t(SvxBoxItemLine::BOTTOM)] = 
model::color::getFromXComplexColor(xComplexColor);
+            }
             return true;
         }
         case MID_BORDER_LEFT_COLOR:
         {
             if (mpLeftBorderLine)
                 return mpLeftBorderLine->setComplexColorFromAny(rVal);
+            else
+            {
+                css::uno::Reference<css::util::XComplexColor> xComplexColor;
+                if (!(rVal >>= xComplexColor))
+                    return false;
+
+                if (xComplexColor.is())
+                    maTempComplexColors[size_t(SvxBoxItemLine::LEFT)] = 
model::color::getFromXComplexColor(xComplexColor);
+            }
             return true;
         }
         case MID_BORDER_RIGHT_COLOR:
         {
             if (mpRightBorderLine)
                 return mpRightBorderLine->setComplexColorFromAny(rVal);
+            else
+            {
+                css::uno::Reference<css::util::XComplexColor> xComplexColor;
+                if (!(rVal >>= xComplexColor))
+                    return false;
+
+                if (xComplexColor.is())
+                    maTempComplexColors[size_t(SvxBoxItemLine::RIGHT)] = 
model::color::getFromXComplexColor(xComplexColor);
+            }
             return true;
         }
         case MID_BORDER_TOP_COLOR:
         {
             if (mpTopBorderLine)
                 return mpTopBorderLine->setComplexColorFromAny(rVal);
+            else
+            {
+                css::uno::Reference<css::util::XComplexColor> xComplexColor;
+                if (!(rVal >>= xComplexColor))
+                    return false;
+
+                if (xComplexColor.is())
+                    maTempComplexColors[size_t(SvxBoxItemLine::TOP)] = 
model::color::getFromXComplexColor(xComplexColor);
+            }
             return true;
         }
     }
@@ -2815,6 +2866,7 @@ bool SvxBoxItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
 
         bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
         SetLine(bSet ? &aLine : nullptr, nLine);
+        tryMigrateComplexColor(nLine);
     }
 
     return true;
@@ -3164,6 +3216,35 @@ sal_Int16 SvxBoxItem::CalcLineSpace( SvxBoxItemLine 
nLine, bool bEvenIfNoLine, b
     return nDist;
 }
 
+void SvxBoxItem::tryMigrateComplexColor(SvxBoxItemLine eLine)
+{
+    if (!GetLine(eLine))
+        return;
+
+    auto nIndex = size_t(eLine);
+
+    if (maTempComplexColors[nIndex].getType() == model::ColorType::Unused)
+        return;
+
+    switch (eLine)
+    {
+    case SvxBoxItemLine::TOP:
+        mpTopBorderLine->setComplexColor(maTempComplexColors[nIndex]);
+        break;
+    case SvxBoxItemLine::BOTTOM:
+        mpBottomBorderLine->setComplexColor(maTempComplexColors[nIndex]);
+        break;
+    case SvxBoxItemLine::LEFT:
+        mpLeftBorderLine->setComplexColor(maTempComplexColors[nIndex]);
+        break;
+    case SvxBoxItemLine::RIGHT:
+        mpRightBorderLine->setComplexColor(maTempComplexColors[nIndex]);
+        break;
+    }
+
+    maTempComplexColors[nIndex] = model::ComplexColor();
+}
+
 bool SvxBoxItem::HasBorder( bool bTreatPaddingAsBorder ) const
 {
     return  CalcLineSpace( SvxBoxItemLine::BOTTOM,   bTreatPaddingAsBorder )
diff --git a/include/editeng/boxitem.hxx b/include/editeng/boxitem.hxx
index 4e35aad3a56c..6ceff99268c3 100644
--- a/include/editeng/boxitem.hxx
+++ b/include/editeng/boxitem.hxx
@@ -24,7 +24,9 @@
 #include <editeng/editengdllapi.h>
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <o3tl/typed_flags_set.hxx>
+#include <docmodel/color/ComplexColor.hxx>
 #include <memory>
+#include <array>
 
 
 namespace editeng { class SvxBorderLine; }
@@ -64,8 +66,13 @@ class EDITENG_DLLPUBLIC SvxBoxItem final : public SfxPoolItem
     sal_Int16 mnLeftDistance = 0;
     sal_Int16 mnRightDistance = 0;
 
+    // Store complex colors until lines are created...
+    std::array<model::ComplexColor, 4> maTempComplexColors;
+
     bool mbRemoveAdjCellBorder = false;
 
+    void tryMigrateComplexColor(SvxBoxItemLine eLine);
+
 public:
     static SfxPoolItem* CreateDefault();
 
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index cf8b8781af23..40988ffb0222 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -34,6 +34,7 @@ BorderStyle
 BorderTransparency
 BorderWidth
 BottomBorder
+BottomBorderComplexColor
 BottomBorderDistance
 BottomMargin
 BuiltInUnit
@@ -309,6 +310,7 @@ LabelFillColor
 CustomLabelFields
 LayoutInfo
 LeftBorder
+LeftBorderComplexColor
 LeftBorderDistance
 LeftMargin
 LeftPageFooterContent
@@ -444,6 +446,7 @@ RepeatDelay
 Representation
 RightAngledAxes
 RightBorder
+RightBorderComplexColor
 RightBorderDistance
 RightMargin
 RightPageFooterContent
@@ -570,6 +573,7 @@ Title
 Toggle
 TokenIndex
 TopBorder
+TopBorderComplexColor
 TopBorderDistance
 TopMargin
 TotalsRow
diff --git a/sw/qa/extras/ooxmlexport/data/Test_ThemeBorderColor.docx 
b/sw/qa/extras/ooxmlexport/data/Test_ThemeBorderColor.docx
new file mode 100644
index 000000000000..fe1b1885807e
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/Test_ThemeBorderColor.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxml_ThemeExport.cxx 
b/sw/qa/extras/ooxmlexport/ooxml_ThemeExport.cxx
index e84380105f01..3804f4606187 100644
--- a/sw/qa/extras/ooxmlexport/ooxml_ThemeExport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxml_ThemeExport.cxx
@@ -51,6 +51,36 @@ 
DECLARE_SW_ROUNDTRIP_TEST(testThemePortionLevelCharColor_DOCX,
     CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTransforms[0].mnValue);
 }
 
+DECLARE_SW_ROUNDTRIP_TEST(testThemePortionBorderColor_DOCX, 
"Test_ThemeBorderColor.docx", nullptr,
+                          Test)
+{
+    auto xParagraph = getParagraph(1);
+    CPPUNIT_ASSERT(xParagraph.is());
+    {
+        auto xComplexColor
+            = getProperty<uno::Reference<util::XComplexColor>>(xParagraph, 
"TopBorderComplexColor");
+        auto aComplexColor = model::color::getFromXComplexColor(xComplexColor);
+        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent2, 
aComplexColor.getSchemeType());
+        auto const& rTransforms = aComplexColor.getTransformations();
+        CPPUNIT_ASSERT_EQUAL(size_t(1), rTransforms.size());
+        CPPUNIT_ASSERT_EQUAL(model::TransformationType::Tint, 
rTransforms[0].meType);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTransforms[0].mnValue);
+    }
+    {
+        auto xComplexColor = getProperty<uno::Reference<util::XComplexColor>>(
+            xParagraph, "BottomBorderComplexColor");
+        auto aComplexColor = model::color::getFromXComplexColor(xComplexColor);
+        CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent4, 
aComplexColor.getSchemeType());
+        auto const& rTransforms = aComplexColor.getTransformations();
+        CPPUNIT_ASSERT_EQUAL(size_t(1), rTransforms.size());
+        CPPUNIT_ASSERT_EQUAL(model::TransformationType::Tint, 
rTransforms[0].meType);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTransforms[0].mnValue);
+    }
+
+    CPPUNIT_ASSERT(isPropertyVoid(xParagraph, "LeftBorderComplexColor"));
+    CPPUNIT_ASSERT(isPropertyVoid(xParagraph, "RightBorderComplexColor"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/inc/swmodeltestbase.hxx b/sw/qa/inc/swmodeltestbase.hxx
index 097ffbacb7a0..b6ce2f442f8d 100644
--- a/sw/qa/inc/swmodeltestbase.hxx
+++ b/sw/qa/inc/swmodeltestbase.hxx
@@ -214,6 +214,15 @@ protected:
         return data;
     }
 
+    bool isPropertyVoid(const css::uno::Reference<css::uno::XInterface>& 
object, const OUString& name) const
+    {
+        if (!hasProperty(object, name))
+            return false;
+
+        css::uno::Reference< css::beans::XPropertySet > properties(object, 
uno::UNO_QUERY_THROW);
+        return !properties->getPropertyValue(name).hasValue();
+    }
+
     bool hasProperty(const css::uno::Reference<css::uno::XInterface>& obj, 
const OUString& name) const;
 
     css::xml::AttributeData getUserDefineAttribute(const css::uno::Any& obj, 
const OUString& name, const OUString& rValue) const;
diff --git a/sw/source/core/unocore/unomap1.cxx 
b/sw/source/core/unocore/unomap1.cxx
index 31ad710c2fd5..67112cd7a003 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -230,10 +230,10 @@ o3tl::span<const SfxItemPropertyMapEntry> 
SwUnoPropertyMapProvider::GetCharStyle
         { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE 
|CONVERT_TWIPS },
         { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE 
|CONVERT_TWIPS },
         { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 
BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
-        { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX,   
cppu::UnoType<css::util::XComplexColor>::get(),  PROPERTY_NONE, 
MID_BORDER_LEFT_COLOR },
-        { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX,  
cppu::UnoType<css::util::XComplexColor>::get(),  PROPERTY_NONE, 
MID_BORDER_RIGHT_COLOR },
-        { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX,    
cppu::UnoType<css::util::XComplexColor>::get(),  PROPERTY_NONE, 
MID_BORDER_TOP_COLOR },
-        { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, 
cppu::UnoType<css::util::XComplexColor>::get(),  PROPERTY_NONE, 
MID_BORDER_BOTTOM_COLOR },
+        { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX,   
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_LEFT_COLOR },
+        { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX,  
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_RIGHT_COLOR },
+        { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX,    
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_TOP_COLOR },
+        { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, 
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_BOTTOM_COLOR },
         { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, 
cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
         { UNO_NAME_LINK_STYLE, FN_UNO_LINK_STYLE, 
cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
     };
@@ -302,6 +302,10 @@ o3tl::span<const SfxItemPropertyMapEntry>  
SwUnoPropertyMapProvider::GetAutoChar
         { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, RIGHT_BORDER_DISTANCE 
|CONVERT_TWIPS },
         { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE 
|CONVERT_TWIPS },
         { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 
BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },
+        { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX,   
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_LEFT_COLOR },
+        { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, RES_CHRATR_BOX,  
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_RIGHT_COLOR },
+        { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX,    
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_TOP_COLOR },
+        { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, RES_CHRATR_BOX, 
cppu::UnoType<css::util::XComplexColor>::get(),  PropertyAttribute::MAYBEVOID, 
MID_BORDER_BOTTOM_COLOR },
         { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, 
cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},
     };
 
diff --git a/sw/source/core/unocore/unomapproperties.hxx 
b/sw/source/core/unocore/unomapproperties.hxx
index 18aa885a3967..20f2f365651a 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -193,6 +193,10 @@
         { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE,          RES_CHRATR_BOX,        
        cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 
RIGHT_BORDER_DISTANCE  | CONVERT_TWIPS }, \
         { UNO_NAME_CHAR_TOP_BORDER_DISTANCE,            RES_CHRATR_BOX,        
        cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 
TOP_BORDER_DISTANCE    | CONVERT_TWIPS }, \
         { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE,         RES_CHRATR_BOX,        
        cppu::UnoType<sal_Int32>::get(),         PropertyAttribute::MAYBEVOID, 
BOTTOM_BORDER_DISTANCE | CONVERT_TWIPS }, \
+        { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR,      RES_CHRATR_BOX,        
        cppu::UnoType<css::util::XComplexColor>::get(),  
PropertyAttribute::MAYBEVOID, MID_BORDER_LEFT_COLOR }, \
+        { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR,     RES_CHRATR_BOX,        
        cppu::UnoType<css::util::XComplexColor>::get(),  
PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR }, \
+        { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR,       RES_CHRATR_BOX,        
        cppu::UnoType<css::util::XComplexColor>::get(),  
PropertyAttribute::MAYBEVOID, MID_BORDER_TOP_COLOR }, \
+        { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR,    RES_CHRATR_BOX,        
        cppu::UnoType<css::util::XComplexColor>::get(),  
PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR }, \
         { UNO_NAME_CHAR_SHADOW_FORMAT,                  RES_CHRATR_SHADOW,     
        cppu::UnoType<css::table::ShadowFormat>::get(),     
PropertyAttribute::MAYBEVOID, CONVERT_TWIPS                          }, \
         { UNO_NAME_LEFT_BORDER,                         RES_BOX,               
        cppu::UnoType<css::table::BorderLine>::get(),    
PropertyAttribute::MAYBEVOID, LEFT_BORDER            | CONVERT_TWIPS }, \
         { UNO_NAME_RIGHT_BORDER,                        RES_BOX,               
        cppu::UnoType<css::table::BorderLine>::get(),    
PropertyAttribute::MAYBEVOID, RIGHT_BORDER           | CONVERT_TWIPS }, \
@@ -451,6 +455,10 @@
                     { UNO_NAME_CHAR_RIGHT_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(),PROPERTY_NONE, RIGHT_BORDER_DISTANCE 
|CONVERT_TWIPS },\
                     { UNO_NAME_CHAR_TOP_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, TOP_BORDER_DISTANCE 
|CONVERT_TWIPS },\
                     { UNO_NAME_CHAR_BOTTOM_BORDER_DISTANCE, RES_CHRATR_BOX, 
cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 
BOTTOM_BORDER_DISTANCE|CONVERT_TWIPS },\
+                    { UNO_NAME_CHAR_BORDER_LEFT_COMPLEX_COLOR, RES_CHRATR_BOX, 
cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, 
MID_BORDER_LEFT_COLOR }, \
+                    { UNO_NAME_CHAR_BORDER_RIGHT_COMPLEX_COLOR, 
RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 
PropertyAttribute::MAYBEVOID, MID_BORDER_RIGHT_COLOR }, \
+                    { UNO_NAME_CHAR_BORDER_TOP_COMPLEX_COLOR, RES_CHRATR_BOX, 
cppu::UnoType<css::util::XComplexColor>::get(), PropertyAttribute::MAYBEVOID, 
MID_BORDER_TOP_COLOR }, \
+                    { UNO_NAME_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, 
RES_CHRATR_BOX, cppu::UnoType<css::util::XComplexColor>::get(), 
PropertyAttribute::MAYBEVOID, MID_BORDER_BOTTOM_COLOR }, \
                     { UNO_NAME_CHAR_SHADOW_FORMAT, RES_CHRATR_SHADOW, 
cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
                     { UNO_NAME_LEFT_BORDER, RES_BOX,              
cppu::UnoType<css::table::BorderLine>::get(),  0, LEFT_BORDER  |CONVERT_TWIPS 
},\
                     { UNO_NAME_RIGHT_BORDER, RES_BOX,             
cppu::UnoType<css::table::BorderLine>::get(),  0, RIGHT_BORDER |CONVERT_TWIPS 
},\
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 380884cfa51e..f5742eae4515 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -289,8 +289,98 @@ auto 
detachFrom(rtl::Reference<sax_fastparser::FastAttributeList>& src)
 {
     return rtl::Reference(std::move(src));
 }
+
+void 
lclAddThemeColorAttributes(rtl::Reference<sax_fastparser::FastAttributeList>& 
pAttrList, model::ComplexColor const& rComplexColor)
+{
+    static std::unordered_map<model::ThemeColorType, const char*> 
constThemeColorTypeTokenMap = {
+        { model::ThemeColorType::Dark1, "dark1" },
+        { model::ThemeColorType::Light1, "light1" },
+        { model::ThemeColorType::Dark2, "dark2" },
+        { model::ThemeColorType::Light2, "light2" },
+        { model::ThemeColorType::Accent1, "accent1" },
+        { model::ThemeColorType::Accent2, "accent2" },
+        { model::ThemeColorType::Accent3, "accent3" },
+        { model::ThemeColorType::Accent4, "accent4" },
+        { model::ThemeColorType::Accent5, "accent5" },
+        { model::ThemeColorType::Accent6, "accent6" },
+        { model::ThemeColorType::Hyperlink, "hyperlink" },
+        { model::ThemeColorType::FollowedHyperlink, "followedHyperlink" }
+    };
+
+    if (rComplexColor.getType() == model::ColorType::Scheme &&
+        rComplexColor.getSchemeType() != model::ThemeColorType::Unknown)
+    {
+        OString sSchemeType = 
constThemeColorTypeTokenMap[rComplexColor.getSchemeType()];
+        if (rComplexColor.meThemeColorUsage == model::ThemeColorUsage::Text)
+        {
+            if (rComplexColor.getSchemeType() == model::ThemeColorType::Dark1)
+                sSchemeType = "text1";
+            else if (rComplexColor.getSchemeType() == 
model::ThemeColorType::Dark2)
+                sSchemeType = "text2";
+        }
+        else if (rComplexColor.meThemeColorUsage == 
model::ThemeColorUsage::Background)
+        {
+            if (rComplexColor.getSchemeType() == model::ThemeColorType::Light1)
+                sSchemeType = "background1";
+            else if (rComplexColor.getSchemeType() == 
model::ThemeColorType::Light2)
+                sSchemeType = "background2";
+        }
+
+        DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, 
XML_themeColor), sSchemeType);
+
+        sal_Int16 nLumMod = 10'000;
+        sal_Int16 nLumOff = 0;
+        sal_Int16 nTint = 0;
+        sal_Int16 nShade = 0;
+
+        for (auto const& rTransform : rComplexColor.getTransformations())
+        {
+            if (rTransform.meType == model::TransformationType::LumMod)
+                nLumMod = rTransform.mnValue;
+            if (rTransform.meType == model::TransformationType::LumOff)
+                nLumOff = rTransform.mnValue;
+            if (rTransform.meType == model::TransformationType::Tint)
+                nTint = rTransform.mnValue;
+            if (rTransform.meType == model::TransformationType::Shade)
+                nShade = rTransform.mnValue;
+        }
+        if (nLumMod == 10'000 && nLumOff == 0)
+        {
+            if (nTint != 0)
+            {
+                // Convert from 0-100 into 0-255
+                sal_Int16 nTint255 = std::round(255.0 - (double(nTint) / 
10000.0) * 255.0);
+                DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, 
XML_themeTint), OString::number(nTint255, 16));
+            }
+            else if (nShade != 0)
+            {
+                // Convert from 0-100 into 0-255
+                sal_Int16 nShade255 = std::round(255.0 - (double(nShade) / 
10000.0) * 255.0);
+                DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, 
XML_themeShade), OString::number(nShade255, 16));
+            }
+        }
+        else
+        {
+            double nPercentage = 0.0;
+
+            if (nLumOff > 0)
+                nPercentage = double(nLumOff) / 100.0;
+            else
+                nPercentage = (-10'000 + double(nLumMod)) / 100.0;
+
+            // Convert from 0-100 into 0-255
+            sal_Int16 nTintShade255 = std::round(255.0 - 
(std::abs(nPercentage) / 100.0) * 255.0);
+
+            if (nPercentage > 0)
+                DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, 
XML_themeTint), OString::number(nTintShade255, 16));
+            else if (nPercentage < 0)
+                DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, 
XML_themeShade), OString::number(nTintShade255, 16));
+        }
+    }
 }
 
+} // end anonymous namespace
+
 void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ )
 {
     if (bIsRTL)
@@ -4227,7 +4317,10 @@ static void impl_borderLine( FSHelperPtr const & 
pSerializer, sal_Int32 elementT
 
         // Get the color code as an RRGGBB hex value
         OString sColor( msfilter::util::ConvertColor( pBorderLine->GetColor( ) 
) );
-        pAttr->add( FSNS( XML_w, XML_color ), sColor );
+        pAttr->add( FSNS(XML_w, XML_color), sColor);
+
+        model::ComplexColor const& rComplexColor = 
pBorderLine->getComplexColor();
+        lclAddThemeColorAttributes(pAttr, rComplexColor);
     }
 
     if (bWriteShadow)
@@ -7650,21 +7743,6 @@ void DocxAttributeOutput::CharCaseMap( const 
SvxCaseMapItem& rCaseMap )
 
 void DocxAttributeOutput::CharColor(const SvxColorItem& rColorItem)
 {
-    static std::unordered_map<model::ThemeColorType, const char*> 
constThemeColorTypeTokenMap = {
-        { model::ThemeColorType::Dark1, "dark1" },
-        { model::ThemeColorType::Light1, "light1" },
-        { model::ThemeColorType::Dark2, "dark2" },
-        { model::ThemeColorType::Light2, "light2" },
-        { model::ThemeColorType::Accent1, "accent1" },
-        { model::ThemeColorType::Accent2, "accent2" },
-        { model::ThemeColorType::Accent3, "accent3" },
-        { model::ThemeColorType::Accent4, "accent4" },
-        { model::ThemeColorType::Accent5, "accent5" },
-        { model::ThemeColorType::Accent6, "accent6" },
-        { model::ThemeColorType::Hyperlink, "hyperlink" },
-        { model::ThemeColorType::FollowedHyperlink, "followedHyperlink" }
-    };
-
     const Color aColor = rColorItem.getColor();
     const model::ComplexColor aComplexColor = rColorItem.getComplexColor();
 
@@ -7677,75 +7755,7 @@ void DocxAttributeOutput::CharColor(const SvxColorItem& 
rColorItem)
         return;
     }
 
-    if (aComplexColor.getType() == model::ColorType::Scheme &&
-        aComplexColor.getSchemeType() != model::ThemeColorType::Unknown)
-    {
-        OString sSchemeType = 
constThemeColorTypeTokenMap[aComplexColor.getSchemeType()];
-        if (aComplexColor.meThemeColorUsage == model::ThemeColorUsage::Text)
-        {
-            if (aComplexColor.getSchemeType() == model::ThemeColorType::Dark1)
-                sSchemeType = "text1";
-            else if (aComplexColor.getSchemeType() == 
model::ThemeColorType::Dark2)
-                sSchemeType = "text2";
-        }
-        else if (aComplexColor.meThemeColorUsage == 
model::ThemeColorUsage::Background)
-        {
-            if (aComplexColor.getSchemeType() == model::ThemeColorType::Light1)
-                sSchemeType = "background1";
-            else if (aComplexColor.getSchemeType() == 
model::ThemeColorType::Light2)
-                sSchemeType = "background2";
-        }
-        AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_themeColor), 
sSchemeType);
-
-        sal_Int16 nLumMod = 10'000;
-        sal_Int16 nLumOff = 0;
-        sal_Int16 nTint = 0;
-        sal_Int16 nShade = 0;
-
-        for (auto const& rTransform : aComplexColor.getTransformations())
-        {
-            if (rTransform.meType == model::TransformationType::LumMod)
-                nLumMod = rTransform.mnValue;
-            if (rTransform.meType == model::TransformationType::LumOff)
-                nLumOff = rTransform.mnValue;
-            if (rTransform.meType == model::TransformationType::Tint)
-                nTint = rTransform.mnValue;
-            if (rTransform.meType == model::TransformationType::Shade)
-                nShade = rTransform.mnValue;
-        }
-        if (nLumMod == 10'000 && nLumOff == 0)
-        {
-            if (nTint != 0)
-            {
-                // Convert from 0-100 into 0-255
-                sal_Int16 nTint255 = std::round(255.0 - (double(nTint) / 
10000.0) * 255.0);
-                AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_themeTint), 
OString::number(nTint255, 16));
-            }
-            else if (nShade != 0)
-            {
-                // Convert from 0-100 into 0-255
-                sal_Int16 nShade255 = std::round(255.0 - (double(nShade) / 
10000.0) * 255.0);
-                AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_themeShade), 
OString::number(nShade255, 16));
-            }
-        }
-        else
-        {
-            double nPercentage = 0.0;
-
-            if (nLumOff > 0)
-                nPercentage = double(nLumOff) / 100.0;
-            else
-                nPercentage = (-10'000 + double(nLumMod)) / 100.0;
-
-            // Convert from 0-100 into 0-255
-            sal_Int16 nTintShade255 = std::round(255.0 - 
(std::abs(nPercentage) / 100.0) * 255.0);
-
-            if (nPercentage > 0)
-                AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_themeTint), 
OString::number(nTintShade255, 16));
-            else if (nPercentage < 0)
-                AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_themeShade), 
OString::number(nTintShade255, 16));
-        }
-    }
+    lclAddThemeColorAttributes(m_pColorAttrList, aComplexColor);
 
     AddToAttrList(m_pColorAttrList, FSNS(XML_w, XML_val), aColorString);
     m_nCharTransparence = 255 - aColor.GetAlpha();
diff --git a/writerfilter/source/dmapper/BorderHandler.cxx 
b/writerfilter/source/dmapper/BorderHandler.cxx
index cb8e38c7512e..21bf0f66a340 100644
--- a/writerfilter/source/dmapper/BorderHandler.cxx
+++ b/writerfilter/source/dmapper/BorderHandler.cxx
@@ -76,12 +76,20 @@ void BorderHandler::lcl_attribute(Id rName, Value & rVal)
             m_bShadow = nIntValue;
         break;
         case NS_ooxml::LN_CT_Border_frame:
+            appendGrabBag("frame", OUString::number(nIntValue, 16));
+        break;
         case NS_ooxml::LN_CT_Border_themeTint:
+            m_nThemeTint = nIntValue;
             appendGrabBag("themeTint", OUString::number(nIntValue, 16));
-            break;
+        break;
+        case NS_ooxml::LN_CT_Border_themeShade:
+            m_nThemeShade = nIntValue;
+            appendGrabBag("themeShade", OUString::number(nIntValue, 16));
+        break;
         case NS_ooxml::LN_CT_Border_themeColor:
+            m_eThemeColorType = 
TDefTableHandler::getThemeColorTypeIndex(nIntValue);
             appendGrabBag("themeColor", 
TDefTableHandler::getThemeColorTypeString(nIntValue));
-            break;
+        break;
         default:
             OSL_FAIL( "unknown attribute");
     }
@@ -208,6 +216,28 @@ void BorderHandler::appendGrabBag(const OUString& aKey, 
const OUString& aValue)
     m_aInteropGrabBag.push_back(aProperty);
 }
 
+model::ComplexColor BorderHandler::getComplexColor() const
+{
+    model::ComplexColor aComplexColor;
+    if (m_eThemeColorType == model::ThemeColorType::Unknown)
+        return aComplexColor;
+
+    aComplexColor.setSchemeColor(m_eThemeColorType);
+
+    if (m_nThemeTint > 0 )
+    {
+        sal_Int16 nTint = sal_Int16((255.0 - m_nThemeTint) * 10000.0 / 255.0);
+        aComplexColor.addTransformation({model::TransformationType::Tint, 
nTint});
+    }
+    if (m_nThemeShade > 0)
+    {
+        sal_Int16 nShade = sal_Int16((255.0 - m_nThemeShade) * 10000 / 255.0);
+        aComplexColor.addTransformation({model::TransformationType::Shade, 
nShade});
+    }
+
+    return aComplexColor;
+}
+
 } //namespace writerfilter::dmapper
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/BorderHandler.hxx 
b/writerfilter/source/dmapper/BorderHandler.hxx
index 6c607ca5aea2..9a523bffc576 100644
--- a/writerfilter/source/dmapper/BorderHandler.hxx
+++ b/writerfilter/source/dmapper/BorderHandler.hxx
@@ -24,6 +24,8 @@
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <o3tl/enumarray.hxx>
+#include <docmodel/theme/ThemeColorType.hxx>
+#include <docmodel/color/ComplexColor.hxx>
 
 namespace writerfilter::dmapper
 {
@@ -50,6 +52,9 @@ private:
     sal_Int32       m_nLineDistance;
     bool            m_bShadow;
     bool            m_bOOXML;
+    model::ThemeColorType m_eThemeColorType = model::ThemeColorType::Unknown;
+    sal_Int32 m_nThemeShade = 0;
+    sal_Int32 m_nThemeTint = 0;
 
     o3tl::enumarray<BorderPosition, bool> m_aFilledLines;
     o3tl::enumarray<BorderPosition, css::table::BorderLine2> m_aBorderLines;
@@ -72,6 +77,9 @@ public:
     bool                                        getShadow() const { return 
m_bShadow;}
     void enableInteropGrabBag(const OUString& aName);
     css::beans::PropertyValue getInteropGrabBag(const OUString& aName = 
OUString());
+
+    model::ComplexColor getComplexColor() const;
+
 };
 }
 
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index 93903f8c07de..21f1f782736e 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1553,25 +1553,30 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
         {
             auto pBorderHandler = std::make_shared<BorderHandler>( true );
             pProperties->resolve(*pBorderHandler);
-            PropertyIds eBorderId = PropertyIds( 0 );
-            PropertyIds eBorderDistId = PropertyIds( 0 );
+            PropertyIds eBorderId = PropertyIds::INVALID;
+            PropertyIds eBorderComplexColorId = PropertyIds::INVALID;
+            PropertyIds eBorderDistId = PropertyIds::INVALID;
             switch( nSprmId )
             {
             case NS_ooxml::LN_CT_PBdr_top:
                 eBorderId = PROP_TOP_BORDER;
+                eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
                 eBorderDistId = PROP_TOP_BORDER_DISTANCE;
                 break;
             case NS_ooxml::LN_CT_PBdr_left:
                 eBorderId = PROP_LEFT_BORDER;
+                eBorderComplexColorId = PROP_BORDER_LEFT_COMPLEX_COLOR;
                 eBorderDistId = PROP_LEFT_BORDER_DISTANCE;
                 break;
             case NS_ooxml::LN_CT_PBdr_bottom:
-                eBorderId = PROP_BOTTOM_BORDER         ;
+                eBorderId = PROP_BOTTOM_BORDER;
+                eBorderComplexColorId = PROP_BORDER_BOTTOM_COMPLEX_COLOR;
                 eBorderDistId = PROP_BOTTOM_BORDER_DISTANCE;
                 break;
             case NS_ooxml::LN_CT_PBdr_right:
                 eBorderId = PROP_RIGHT_BORDER;
-                eBorderDistId = PROP_RIGHT_BORDER_DISTANCE ;
+                eBorderComplexColorId = PROP_BORDER_RIGHT_COMPLEX_COLOR;
+                eBorderDistId = PROP_RIGHT_BORDER_DISTANCE;
                 break;
             case NS_ooxml::LN_CT_PBdr_between:
                 if (m_pImpl->handlePreviousParagraphBorderInBetween())
@@ -1580,6 +1585,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                     // then it is possible to emulate this border as top border
                     // for current paragraph
                     eBorderId = PROP_TOP_BORDER;
+                    eBorderComplexColorId = PROP_BORDER_TOP_COMPLEX_COLOR;
                     eBorderDistId = PROP_TOP_BORDER_DISTANCE;
                 }
                 // Since there are borders in between, each paragraph will 
have own borders. No more joining
@@ -1587,10 +1593,21 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 break;
             default:;
             }
-            if( eBorderId )
-                rContext->Insert( eBorderId, uno::Any( 
pBorderHandler->getBorderLine()) );
-            if(eBorderDistId)
-                rContext->Insert(eBorderDistId, uno::Any( 
pBorderHandler->getLineDistance()));
+
+            if (eBorderId != PropertyIds::INVALID)
+            {
+                rContext->Insert(eBorderId, 
uno::Any(pBorderHandler->getBorderLine()));
+            }
+            if (eBorderComplexColorId != PropertyIds::INVALID)
+            {
+                auto aComplexColor = pBorderHandler->getComplexColor();
+                auto xComplexColor = 
model::color::createXComplexColor(aComplexColor);
+                rContext->Insert(eBorderComplexColorId, 
uno::Any(xComplexColor));
+            }
+            if (eBorderDistId != PropertyIds::INVALID)
+            {
+                rContext->Insert(eBorderDistId, 
uno::Any(pBorderHandler->getLineDistance()));
+            }
             if ( nSprmId == NS_ooxml::LN_CT_PBdr_right )
             {
                 table::ShadowFormat aFormat;
@@ -2198,6 +2215,13 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
                 rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::Any( 
pBorderHandler->getLineDistance()));
                 rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::Any( 
pBorderHandler->getLineDistance()));
 
+                auto xComplexColor = 
model::color::createXComplexColor(pBorderHandler->getComplexColor());
+
+                rContext->Insert( PROP_CHAR_BORDER_TOP_COMPLEX_COLOR, 
uno::Any(xComplexColor));
+                rContext->Insert( PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, 
uno::Any(xComplexColor));
+                rContext->Insert( PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR, 
uno::Any(xComplexColor));
+                rContext->Insert( PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR, 
uno::Any(xComplexColor));
+
                 table::ShadowFormat aFormat;
                 // Word only allows shadows on visible borders
                 if ( pBorderHandler->getShadow() && 
pBorderHandler->getBorderLine().LineStyle != table::BorderLineStyle::NONE )
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index e945dc2609b2..47126a3af5b5 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -75,6 +75,10 @@ const OUString & getPropertyName( PropertyIds eId )
         { PROP_CHAR_RIGHT_BORDER_DISTANCE, u"CharRightBorderDistance"},
         { PROP_CHAR_TOP_BORDER_DISTANCE, u"CharTopBorderDistance"},
         { PROP_CHAR_BOTTOM_BORDER_DISTANCE, u"CharBottomBorderDistance"},
+        { PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR, u"CharLeftBorderComplexColor"},
+        { PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR, 
u"CharRightBorderComplexColor"},
+        { PROP_CHAR_BORDER_TOP_COMPLEX_COLOR, u"CharTopBorderComplexColor"},
+        { PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR, 
u"CharBottomBorderComplexColor"},
         { PROP_CHAR_SHADOW_FORMAT, u"CharShadowFormat"},
         { PROP_CHAR_HIGHLIGHT, u"CharHighlight"},
         { PROP_PARA_STYLE_NAME, u"ParaStyleName"},
@@ -115,6 +119,10 @@ const OUString & getPropertyName( PropertyIds eId )
         { PROP_RIGHT_BORDER, u"RightBorder"},
         { PROP_TOP_BORDER, u"TopBorder"},
         { PROP_BOTTOM_BORDER, u"BottomBorder"},
+        { PROP_BORDER_LEFT_COMPLEX_COLOR, u"LeftBorderComplexColor"},
+        { PROP_BORDER_RIGHT_COMPLEX_COLOR, u"RightBorderComplexColor"},
+        { PROP_BORDER_TOP_COMPLEX_COLOR, u"TopBorderComplexColor"},
+        { PROP_BORDER_BOTTOM_COMPLEX_COLOR, u"BottomBorderComplexColor"},
         { PROP_TABLE_BORDER, u"TableBorder"},
         { PROP_TABLE_ROW_DELETE, u"TableRowDelete"},
         { PROP_TABLE_ROW_INSERT, u"TableRowInsert"},
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index 083051f8d9e7..575633c68313 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -24,7 +24,8 @@ namespace writerfilter::dmapper{
 // Ensure that Character Properties are placed between PROP_CHARACTER_STYLES 
and PROP_CHARACTER_END
 enum PropertyIds
     {
-        PROP_ID_START = 1
+        INVALID = 0
+        ,PROP_ID_START = 1
         ,META_PROP_CELL_MAR_BOTTOM = PROP_ID_START
         ,META_PROP_CELL_MAR_LEFT
         ,META_PROP_CELL_MAR_RIGHT
@@ -42,6 +43,10 @@ enum PropertyIds
         ,PROP_BACK_COLOR
         ,PROP_BACK_COLOR_TRANSPARENCY
         ,PROP_BITMAP
+        ,PROP_BORDER_LEFT_COMPLEX_COLOR
+        ,PROP_BORDER_RIGHT_COMPLEX_COLOR
+        ,PROP_BORDER_TOP_COMPLEX_COLOR
+        ,PROP_BORDER_BOTTOM_COMPLEX_COLOR
         ,PROP_BOTTOM_BORDER
         ,PROP_BOTTOM_BORDER_DISTANCE
         ,PROP_BOTTOM_MARGIN
@@ -68,6 +73,10 @@ enum PropertyIds
         ,PROP_CHAR_RIGHT_BORDER_DISTANCE
         ,PROP_CHAR_TOP_BORDER_DISTANCE
         ,PROP_CHAR_BOTTOM_BORDER_DISTANCE
+        ,PROP_CHAR_BORDER_LEFT_COMPLEX_COLOR
+        ,PROP_CHAR_BORDER_RIGHT_COMPLEX_COLOR
+        ,PROP_CHAR_BORDER_TOP_COMPLEX_COLOR
+        ,PROP_CHAR_BORDER_BOTTOM_COMPLEX_COLOR
         ,PROP_CHAR_EMPHASIS
         ,PROP_CHAR_ESCAPEMENT
         ,PROP_CHAR_ESCAPEMENT_HEIGHT
diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx 
b/writerfilter/source/dmapper/TDefTableHandler.cxx
index fb4b9922ae50..288a08f26502 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.cxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.cxx
@@ -357,10 +357,13 @@ void TDefTableHandler::lcl_attribute(Id rName, Value & 
rVal)
         break;
         case NS_ooxml::LN_CT_Border_themeColor:
             appendGrabBag("themeColor", 
TDefTableHandler::getThemeColorTypeString(nIntValue));
+            m_eThemeColorType = 
TDefTableHandler::getThemeColorTypeIndex(nIntValue);
         break;
         case NS_ooxml::LN_CT_Border_themeTint:
+            m_nThemeTint = nIntValue;
+        break;
         case NS_ooxml::LN_CT_Border_themeShade:
-            // ignored
+            m_nThemeShade = nIntValue;
         break;
         default:
             OSL_FAIL("unknown attribute");
@@ -484,6 +487,23 @@ void TDefTableHandler::fillCellProperties( const 
::tools::SvRef< TablePropertyMa
         pCellProperties->Insert( META_PROP_HORIZONTAL_BORDER, uno::Any( 
m_aInsideHBorderLines[0] ) );
     if( !m_aInsideVBorderLines.empty() )
         pCellProperties->Insert( META_PROP_VERTICAL_BORDER, uno::Any( 
m_aInsideVBorderLines[0] ) );
+
+    if (m_eThemeColorType != model::ThemeColorType::Unknown)
+    {
+        model::ComplexColor aComplexColor;
+        aComplexColor.setSchemeColor(m_eThemeColorType);
+
+        if (m_nThemeTint > 0 )
+        {
+            sal_Int16 nTint = sal_Int16((255.0 - m_nThemeTint) * 10000.0 / 
255.0);
+            aComplexColor.addTransformation({model::TransformationType::Tint, 
nTint});
+        }
+        if (m_nThemeShade > 0)
+        {
+            sal_Int16 nShade = sal_Int16((255.0 - m_nThemeShade) * 10000.0 / 
255.0);
+            aComplexColor.addTransformation({model::TransformationType::Shade, 
nShade});
+        }
+    }
 }
 
 
diff --git a/writerfilter/source/dmapper/TDefTableHandler.hxx 
b/writerfilter/source/dmapper/TDefTableHandler.hxx
index c3e098694314..7b02d4ae0907 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.hxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.hxx
@@ -21,6 +21,7 @@
 #include "LoggedResources.hxx"
 #include <vector>
 #include <docmodel/theme/ThemeColorType.hxx>
+#include <docmodel/color/ComplexColor.hxx>
 
 namespace com::sun::star{
     namespace table {
@@ -45,9 +46,13 @@ class TDefTableHandler : public LoggedProperties
     std::vector<css::table::BorderLine2> m_aInsideVBorderLines;
 
     //values of the current border
-    sal_Int32                                           m_nLineWidth;
-    sal_Int32                                           m_nLineType;
-    sal_Int32                                           m_nLineColor;
+    sal_Int32 m_nLineWidth;
+    sal_Int32 m_nLineType;
+    sal_Int32 m_nLineColor;
+
+    model::ThemeColorType m_eThemeColorType = model::ThemeColorType::Unknown;
+    sal_Int32 m_nThemeShade = 0;
+    sal_Int32 m_nThemeTint = 0;
 
     OUString m_aInteropGrabBagName;
     std::vector<css::beans::PropertyValue> m_aInteropGrabBag;
@@ -66,6 +71,7 @@ public:
     void fillCellProperties( const ::tools::SvRef< TablePropertyMap >& 
pCellProperties) const;
     void enableInteropGrabBag(const OUString& aName);
     css::beans::PropertyValue getInteropGrabBag(const OUString& aName = 
OUString());
+
     static OUString getBorderTypeString(sal_Int32 nType);
     static OUString getThemeColorTypeString(sal_Int32 nType);
     static model::ThemeColorType getThemeColorTypeIndex(sal_Int32 nType);

Reply via email to