[Libreoffice-commits] core.git: 13 commits - include/svtools sw/inc sw/qa sw/source writerfilter/source

Zolnai Tamás zolnaitamas2000 at gmail.com
Sun Sep 8 02:24:44 PDT 2013


 include/svtools/rtfkeywd.hxx                   |    3 
 sw/inc/charfmt.hxx                             |    2 
 sw/qa/extras/htmlexport/data/charborder.odt    |binary
 sw/qa/extras/htmlexport/htmlexport.cxx         |   33 +++++
 sw/qa/extras/inc/swmodeltestbase.hxx           |   22 +--
 sw/qa/extras/odfexport/odfexport.cxx           |  146 +++++++++----------------
 sw/qa/extras/ooxmlexport/data/charborder.odt   |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx       |   50 ++++++++
 sw/qa/extras/rtfexport/data/charborder.odt     |binary
 sw/qa/extras/rtfexport/rtfexport.cxx           |   40 ++++++
 sw/qa/extras/ww8export/data/charborder.odt     |binary
 sw/qa/extras/ww8export/ww8export.cxx           |   39 ++++++
 sw/source/core/layout/paintfrm.cxx             |   26 ++++
 sw/source/core/text/inftxt.cxx                 |    2 
 sw/source/core/text/inftxt.hxx                 |    2 
 sw/source/core/text/itrcrsr.cxx                |    5 
 sw/source/core/text/itrform2.cxx               |   22 +--
 sw/source/core/text/itrform2.hxx               |   10 -
 sw/source/core/text/porlin.cxx                 |    4 
 sw/source/core/text/porlin.hxx                 |   13 ++
 sw/source/core/text/portxt.cxx                 |   10 -
 sw/source/core/text/portxt.hxx                 |   11 -
 sw/source/core/text/txttab.cxx                 |    4 
 sw/source/filter/html/css1atr.cxx              |   44 ++++---
 sw/source/filter/html/htmlatr.cxx              |  104 +++++++++++++----
 sw/source/filter/html/htmlcss1.cxx             |   18 +--
 sw/source/filter/html/htmlctxt.cxx             |   18 +++
 sw/source/filter/html/htmltabw.cxx             |    6 -
 sw/source/filter/html/swhtml.hxx               |    3 
 sw/source/filter/html/wrthtml.hxx              |    2 
 sw/source/filter/ww8/attributeoutputbase.hxx   |    7 +
 sw/source/filter/ww8/docxattributeoutput.cxx   |    8 +
 sw/source/filter/ww8/docxattributeoutput.hxx   |    3 
 sw/source/filter/ww8/rtfattributeoutput.cxx    |   11 +
 sw/source/filter/ww8/rtfattributeoutput.hxx    |    3 
 sw/source/filter/ww8/rtfexport.cxx             |   13 ++
 sw/source/filter/ww8/wrtw8nds.cxx              |   28 ++++
 sw/source/filter/ww8/wrtww8.hxx                |    5 
 sw/source/filter/ww8/ww8atr.cxx                |   47 +++++++-
 sw/source/filter/ww8/ww8attributeoutput.hxx    |    3 
 sw/source/filter/ww8/ww8par.hxx                |    3 
 sw/source/filter/ww8/ww8par6.cxx               |   60 ++++++++--
 writerfilter/source/dmapper/DomainMapper.cxx   |   27 ++++
 writerfilter/source/dmapper/PropertyIds.cxx    |    9 +
 writerfilter/source/dmapper/PropertyIds.hxx    |    9 +
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   17 ++
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |    3 
 47 files changed, 662 insertions(+), 233 deletions(-)

New commits:
commit b9a1679f2801448517cf0b2289d0c0cef7b8a08b
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sat Sep 7 19:53:57 2013 +0200

    Remove duplicate defines in rtfkeywd.hxx
    
    Change-Id: Iacb53db9df20d172a9d85fd52a4a41262ea9733c

diff --git a/include/svtools/rtfkeywd.hxx b/include/svtools/rtfkeywd.hxx
index 8eea58a..437329a 100644
--- a/include/svtools/rtfkeywd.hxx
+++ b/include/svtools/rtfkeywd.hxx
@@ -63,7 +63,6 @@
 #define OOO_STRING_SVTOOLS_RTF_BRDRDB "\\brdrdb"
 #define OOO_STRING_SVTOOLS_RTF_BRDRDOT "\\brdrdot"
 #define OOO_STRING_SVTOOLS_RTF_BRDRDASH "\\brdrdash"
-#define OOO_STRING_SVTOOLS_RTF_BRDRDASHSM "\\brdrdashsm"
 #define OOO_STRING_SVTOOLS_RTF_BRDRHAIR "\\brdrhair"
 #define OOO_STRING_SVTOOLS_RTF_BRDRL "\\brdrl"
 #define OOO_STRING_SVTOOLS_RTF_BRDRR "\\brdrr"
@@ -438,7 +437,6 @@
 #define OOO_STRING_SVTOOLS_RTF_AULW "\\aulw"
 #define OOO_STRING_SVTOOLS_RTF_AUP "\\aup"
 #define OOO_STRING_SVTOOLS_RTF_BKMKPUB "\\bkmkpub"
-#define OOO_STRING_SVTOOLS_RTF_BRDRDASH "\\brdrdash"
 #define OOO_STRING_SVTOOLS_RTF_BRKFRM "\\brkfrm"
 #define OOO_STRING_SVTOOLS_RTF_CCHS "\\cchs"
 #define OOO_STRING_SVTOOLS_RTF_CPG "\\cpg"
@@ -995,7 +993,6 @@
 #define OOO_STRING_SVTOOLS_RTF_SHPWRK "\\shpwrk"
 #define OOO_STRING_SVTOOLS_RTF_SHPWR "\\shpwr"
 #define OOO_STRING_SVTOOLS_RTF_SHPZ "\\shpz"
-#define OOO_STRING_SVTOOLS_RTF_SP "\\sp"
 #define OOO_STRING_SVTOOLS_RTF_SPRSBSP "\\sprsbsp"
 #define OOO_STRING_SVTOOLS_RTF_SPRSLNSP "\\sprslnsp"
 #define OOO_STRING_SVTOOLS_RTF_SPRSTSM "\\sprstsm"
commit aa2faee4b3954b57a613963b501ecf611b3a14ca
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sat Sep 7 19:50:25 2013 +0200

    CharBrd 9.4: DOC filters
    
    -WW8 filter is the only MS filter which ignores padding
    of character border.
    
    Change-Id: I17973d8d2ae624d68356729334c701864fe0a10d

diff --git a/sw/qa/extras/ww8export/data/charborder.odt b/sw/qa/extras/ww8export/data/charborder.odt
new file mode 100644
index 0000000..0829c03
Binary files /dev/null and b/sw/qa/extras/ww8export/data/charborder.odt differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index e94dc30..bde2f6c 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -11,6 +11,7 @@
 #include <com/sun/star/drawing/XControlShape.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
 
 #include <swmodeltestbase.hxx>
 
@@ -25,6 +26,7 @@ public:
     void test56513();
     void testNewPageStylesTable();
     void testFdo42144();
+    void testCharacterBorder();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -47,6 +49,7 @@ void Test::run()
         {"fdo56513.doc", &Test::test56513},
         {"new-page-styles.doc", &Test::testNewPageStylesTable},
         {"fdo42144.odt", &Test::testFdo42144},
+        {"charborder.odt", &Test::testCharacterBorder},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -144,6 +147,42 @@ void Test::testFdo42144()
     CPPUNIT_ASSERT_EQUAL(false, bool(getProperty<sal_Bool>(xStyle, "FooterIsOn")));
 }
 
+void Test::testCharacterBorder()
+{
+    uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
+    // WW8 has just one border attribute sprmCBrc for text border so all side has
+    // the same border
+    // Border
+    {
+        const table::BorderLine2 aTopBorder = getProperty<table::BorderLine2>(xRun,"CharTopBorder");
+        CPPUNIT_ASSERT_EQUAL_BORDER(table::BorderLine2(16711680,0,318,0,0,318), aTopBorder);
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
+    }
+
+    // Padding (dptSpace) it is constant 0
+    {
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun,"CharTopBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
+    }
+
+    // Shadow (fShadow)
+    /* WW8 use just one bool value for shadow so the next conversions
+       are made during an export-import round
+       color: any -> black
+       location: any -> bottom-right
+       width: any -> border width */
+    {
+        const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xRun, "CharShadowFormat");
+        CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow.ShadowWidth);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index b082755..7bef91d 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -950,8 +950,6 @@ private:
     static void BuildAnlvBase( WW8_ANLV& rAnlv, sal_uInt8*& rpCh, sal_uInt16& rCharLen,
                    const SwNumRule& rRul, const SwNumFmt& rFmt, sal_uInt8 nSwLevel );
 
-    void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine,
-        sal_uInt16 nDist, sal_uInt16 nSprmNo, bool bShadow);
 
     /// Output the numbering table.
     virtual void WriteNumbering();
@@ -1050,6 +1048,9 @@ public:
                                      const SwFmtPageDesc* pNewPgDescFmt = 0,
                                      const SwPageDesc* pNewPgDesc = 0 );
 
+    void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine,
+        sal_uInt16 nDist, sal_uInt16 nSprmNo, bool bShadow);
+
     void Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow);
     void Out_SwFmtTableBox( ww::bytes& rO, const SvxBoxItem * rBox );
     sal_uInt8 TransCol( const Color& rCol );
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index b504ccf..6cd123c 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -1204,6 +1204,11 @@ void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
     OutputWW8Attribute( 7, rHidden.GetValue() );
 }
 
+void WW8AttributeOutput::CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 /*nDist*/, const bool bShadow )
+{
+    m_rWW8Export.Out_BorderLine( *m_rWW8Export.pO, pAllBorder, 0, NS_sprm::LN_CBrc, bShadow );
+}
+
 void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
 {
     if ( m_rWW8Export.bWrtWW8 )
@@ -5347,9 +5352,10 @@ void AttributeOutputBase::FormatCharBorder( const SvxBoxItem& rBox )
     if( pBorderLine )
     {
         const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
+        const SvxShadowItem* pShadowItem = static_cast<const SvxShadowItem*>(pItem);
         const bool bShadow =
-            pItem &&
-            static_cast<const SvxShadowItem*>(pItem)->GetLocation() != SVX_SHADOW_NONE;
+            pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE &&
+            pShadowItem->GetWidth() > 0;
 
         CharBorder( pBorderLine, nDist, bShadow );
     }
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index d5483ef..c1e0c27 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -294,7 +294,7 @@ protected:
     virtual void CharHidden( const SvxCharHiddenItem& );
 
     /// Sfx item RES_CHRATR_BOX
-    virtual void CharBorder( const SvxBorderLine* /*pAllBorder*/, const sal_uInt16 /*nDist*/, const bool /*bShadow*/ ){};
+    virtual void CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow );
 
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 5c74252..56bfa43 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -1369,7 +1369,7 @@ private:
     void GetBorderDistance(const WW8_BRC* pbrc, Rectangle& rInnerDist) const;
     sal_uInt16 GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing);
     bool SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
-        const WW8_BRC *pbrc) const;
+    const WW8_BRC& aRightBrc) const;
     //returns true is a shadow was set
     bool SetFlyBordersShadow(SfxItemSet& rFlySet, const WW8_BRC *pbrc,
         short *SizeArray=0) const;
@@ -1673,6 +1673,7 @@ public:     // eigentlich private, geht aber leider nur public
     void Read_BoolItem(         sal_uInt16 nId, const sal_uInt8*, short nLen );
 
     void Read_Border(           sal_uInt16 nId, const sal_uInt8* pData, short nLen );
+    void Read_CharBorder(sal_uInt16 nId, const sal_uInt8* pData, short nLen );
     void Read_Tab(              sal_uInt16 nId, const sal_uInt8* pData, short nLen );
     void Read_Symbol(sal_uInt16, const sal_uInt8* pData, short nLen);
     void Read_FldVanish(        sal_uInt16 nId, const sal_uInt8* pData, short nLen );
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index e8766e0..28ca3db 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -1290,14 +1290,14 @@ void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt
 }
 
 void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor,
-    sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
+    sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize, const bool bIgnoreSpace)
 {
     sal_uInt8 nCol;
     short nSpace, nIdx;
     short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol,
         &nIdx);
 
-    GetLineIndex(rBox, nLineThickness, nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
+    GetLineIndex(rBox, nLineThickness, bIgnoreSpace ? 0 : nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
 
 }
 
@@ -1365,7 +1365,7 @@ bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
         const WW8_BRC& rB = pbrc[ aIdArr[ i ] ];
         if( !rB.IsEmpty(bVer67))
         {
-            Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray);
+            Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray, false);
             bChange = true;
         }
         else if ( nSetBorders & (1 << aIdArr[i]) )
@@ -1389,18 +1389,18 @@ bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
 
 
 bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
-    const WW8_BRC *pbrc) const
+    const WW8_BRC& aRightBrc) const
 {
     bool bRet = (
-                ( bVer67 ? (pbrc[WW8_RIGHT].aBits1[ 0 ] & 0x20 )
-                         : (pbrc[WW8_RIGHT].aBits2[ 1 ] & 0x20 ) )
+                ( bVer67 ? (aRightBrc.aBits1[ 0 ] & 0x20 )
+                         : (aRightBrc.aBits2[ 1 ] & 0x20 ) )
                 && (pSizeArray && pSizeArray[WW8_RIGHT])
                 );
     if (bRet)
     {
         rShadow.SetColor(Color(COL_BLACK));
     //i120718
-        short nVal = pbrc[WW8_RIGHT].DetermineBorderProperties(bVer67);
+        short nVal = aRightBrc.DetermineBorderProperties(bVer67);
     //End
         if (nVal < 0x10)
             nVal = 0x10;
@@ -1445,7 +1445,7 @@ bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet,
 
         // fShadow
         SvxShadowItem aShadow( RES_SHADOW );
-        if( SetShadow( aShadow, pSizeArray, pbrc ))
+        if( SetShadow( aShadow, pSizeArray, pbrc[WW8_RIGHT] ))
         {
             bShadowed = true;
             rFlySet.Put( aShadow );
@@ -4648,7 +4648,7 @@ sal_uInt32 SwWW8ImplReader::ExtractColour(const sal_uInt8* &rpData, bool bVer67)
     return aShade.aColor.GetColor();
 }
 
-void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8* , short nLen)
+void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8*, short nLen)
 {
     if( nLen < 0 )
     {
@@ -4715,13 +4715,51 @@ void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8* , short nLen)
                 NewAttr( aBox );
 
                 SvxShadowItem aS(RES_SHADOW);
-                if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
+                if( SetShadow( aS, &aSizeArray[0], aBrcs[WW8_RIGHT] ) )
                     NewAttr( aS );
             }
         }
     }
 }
 
+void SwWW8ImplReader::Read_CharBorder(sal_uInt16 /*nId*/, const sal_uInt8* pData, short nLen )
+{
+    //Ignore this old border type
+    if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA72))
+        return;
+
+    if( nLen < 0 )
+    {
+        pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BOX );
+        pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_SHADOW );
+    }
+    else
+    {
+        const SvxBoxItem* pBox
+            = (const SvxBoxItem*)GetFmtAttr( RES_CHRATR_BOX );
+        if( pBox )
+        {
+            SvxBoxItem aBoxItem(RES_CHRATR_BOX);
+            aBoxItem = *pBox;
+            WW8_BRC aBrc;
+            _SetWW8_BRC(bVer67, aBrc, pData);
+
+            Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_TOP, 0, 0, true);
+            Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_BOTTOM, 0, 0, true);
+            Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_LEFT, 0, 0, true);
+            Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_RIGHT, 0, 0, true);
+            NewAttr( aBoxItem );
+
+            short aSizeArray[WW8_RIGHT+1]={0}; aSizeArray[WW8_RIGHT] = 1;
+            SvxShadowItem aShadowItem(RES_CHRATR_SHADOW);
+            if( SetShadow( aShadowItem, &aSizeArray[0], aBrc ) )
+                NewAttr( aShadowItem );
+        }
+    }
+
+
+}
+
 void SwWW8ImplReader::Read_Hyphenation( sal_uInt16, const sal_uInt8* pData, short nLen )
 {
     // set Hyphenation flag
@@ -5802,7 +5840,7 @@ const wwSprmDispatcher *GetWW8SprmDispatcher()
                                                      //sttbRMark;short;
         {0x6864, 0},                                 //"sprmCDttmRMarkDel"
                                                      //chp.dttmRMarkDel;DTTM;long;
-        {0x6865, 0},                                 //"sprmCBrc" chp.brc;BRC;long;
+        {0x6865, &SwWW8ImplReader::Read_CharBorder}, //"sprmCBrc" chp.brc;BRC;long;
         {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short;
         {0x4867, 0},                                 //"sprmCIdslRMarkDel"
                                                      //chp.idslRMReasonDel;an index
commit 05e1439107deacb8416c9aee1b6fb2c72a171eaf
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sun Sep 8 10:46:12 2013 +0200

    CharBrd 9.3: RTF filters
    
    -Use sprm:CBrc attribute for all MS filter (for ooxml too).
    -Extract general code to FormatCharBorder() method, it selects
    the border side and decides whether add shadow to the border.
    -RTF export has a color table, which must be filled with border
    colors before the actual export.temp
    
    Change-Id: Ic3ceae6e19ddc2ed5aaa8de85617f9a592289b4f

diff --git a/sw/qa/extras/ooxmlexport/data/charborder.odt b/sw/qa/extras/ooxmlexport/data/charborder.odt
index 149abfc..67dd89b 100644
Binary files a/sw/qa/extras/ooxmlexport/data/charborder.odt and b/sw/qa/extras/ooxmlexport/data/charborder.odt differ
diff --git a/sw/qa/extras/rtfexport/data/charborder.odt b/sw/qa/extras/rtfexport/data/charborder.odt
new file mode 100644
index 0000000..bea79c1
Binary files /dev/null and b/sw/qa/extras/rtfexport/data/charborder.odt differ
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx
index 81340e4..2cd5cfa 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -68,6 +68,7 @@ public:
     void testTextframeTable();
     void testFdo66682();
     void testParaShadow();
+    void testCharacterBorder();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -125,6 +126,7 @@ void Test::run()
         {"textframe-table.rtf", &Test::testTextframeTable},
         {"fdo66682.rtf", &Test::testFdo66682},
         {"para-shadow.rtf", &Test::testParaShadow},
+        {"charborder.odt", &Test::testCharacterBorder},
     };
     // Don't test the first import of these, for some reason those tests fail
     const char* aBlacklist[] = {
@@ -633,6 +635,44 @@ void Test::testParaShadow()
     CPPUNIT_ASSERT_EQUAL(sal_Int16(TWIP_TO_MM100(60)), aShadow.ShadowWidth);
 }
 
+void Test::testCharacterBorder()
+{
+    uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
+    // RTF has just one border attribute(chbrdr) for text border so all side has
+    // the same border with the same padding
+    // Border
+    {
+        const table::BorderLine2 aTopBorder = getProperty<table::BorderLine2>(xRun,"CharTopBorder");
+        CPPUNIT_ASSERT_EQUAL_BORDER(table::BorderLine2(16737792,0,318,0,0,318), aTopBorder);
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
+    }
+
+    // Padding (brsp)
+    {
+        const sal_Int32 nTopPadding = getProperty<sal_Int32>(xRun,"CharTopBorderDistance");
+        // In the original odt file it is 150, but the unit conversion round it down.
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(141), nTopPadding);
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
+    }
+
+    // Shadow (brdrsh)
+    /* RTF use just one bool value for shadow so the next conversions
+       are made during an export-import round
+       color: any -> black
+       location: any -> bottom-right
+       width: any -> border width */
+    {
+        const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xRun, "CharShadowFormat");
+        CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow.ShadowWidth);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 646030a..259503c 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -118,6 +118,8 @@ class SwLineNumberInfo;
 class SwNumRule;
 class wwFont;
 
+using ::editeng::SvxBorderLine;
+
 class String;
 namespace rtl { class OUString; }
 
@@ -439,7 +441,8 @@ protected:
     virtual void CharHidden( const SvxCharHiddenItem& ) = 0;
 
     /// Sfx item RES_CHRATR_BOX
-    virtual void CharBorder( const SvxBoxItem& rBox ) = 0;
+    void FormatCharBorder( const SvxBoxItem& rBox );
+    virtual void CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow ) = 0;
 
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& ) = 0;
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index cddb20b..c5b78ff 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -112,8 +112,6 @@
 #include <stdio.h>
 #endif
 
-using ::editeng::SvxBorderLine;
-
 using namespace oox;
 using namespace docx;
 using namespace sax_fastparser;
@@ -4081,41 +4079,10 @@ void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
         m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
 }
 
-void DocxAttributeOutput::CharBorder( const SvxBoxItem& rBox )
+void DocxAttributeOutput::CharBorder(
+    const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow )
 {
-    // Get one of the borders (if there is any border then in docx also will be)
-    const SvxBorderLine* pBorderLine = 0;
-    sal_uInt16 nDist = 0;
-    if( rBox.GetTop() )
-    {
-       pBorderLine = rBox.GetTop();
-       nDist = rBox.GetDistance( BOX_LINE_TOP );
-    }
-    else if( rBox.GetLeft() )
-    {
-       pBorderLine = rBox.GetLeft();
-       nDist = rBox.GetDistance( BOX_LINE_LEFT );
-    }
-    else if( rBox.GetBottom() )
-    {
-       pBorderLine = rBox.GetBottom();
-       nDist = rBox.GetDistance( BOX_LINE_BOTTOM );
-    }
-    else if( rBox.GetRight() )
-    {
-       pBorderLine = rBox.GetRight();
-       nDist = rBox.GetDistance( BOX_LINE_RIGHT );
-    }
-
-    if( pBorderLine )
-    {
-        const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
-        const bool bShadow =
-            pItem &&
-            static_cast<const SvxShadowItem*>(pItem)->GetLocation() != SVX_SHADOW_NONE;
-
-        impl_borderLine( m_pSerializer, XML_bdr, pBorderLine, nDist, bShadow );
-    }
+    impl_borderLine( m_pSerializer, XML_bdr, pAllBorder, nDist, bShadow );
 }
 
 void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index c217fb9..8333517 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -473,7 +473,7 @@ protected:
     virtual void CharHidden( const SvxCharHiddenItem& rHidden );
 
     /// Sfx item RES_CHRATR_BOX
-    virtual void CharBorder( const SvxBoxItem& rBox );
+    virtual void CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow );
 
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 065278c..c4d3b29 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -101,7 +101,6 @@
 
 #include <com/sun/star/i18n/ScriptType.hpp>
 
-using ::editeng::SvxBorderLine;
 using namespace nsSwDocInfoSubType;
 using namespace nsFieldFlags;
 using namespace sw::util;
@@ -2361,6 +2360,16 @@ void RtfAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
         m_aStyles.append((sal_Int32)0);
 }
 
+void RtfAttributeOutput::CharBorder(
+    const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow )
+{
+    SAL_INFO("sw.rtf", OSL_THIS_FUNC);
+
+    m_aStyles.append(
+        OutBorderLine(m_rExport, pAllBorder, OOO_STRING_SVTOOLS_RTF_CHBRDR,
+                      nDist, bShadow ? SVX_SHADOW_BOTTOMRIGHT : SVX_SHADOW_NONE));
+}
+
 void RtfAttributeOutput::TextINetFormat( const SwFmtINetFmt& rURL )
 {
     SAL_INFO("sw.rtf", OSL_THIS_FUNC);
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index b332dd3..51fdcef 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -313,7 +313,7 @@ protected:
     virtual void CharHidden( const SvxCharHiddenItem& rHidden );
 
     /// Sfx item RES_CHRATR_BOX
-    virtual void CharBorder( const SvxBoxItem& /*rBox*/ ){};
+    virtual void CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow );
 
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 0787f37..87dd8d3 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -1005,7 +1005,20 @@ void RtfExport::OutColorTable()
         {
             if( 0 != (pBox = (const SvxBoxItem*)rPool.GetItem2( RES_BOX, n ) ))
                 InsColorLine( *pBox );
+        }
     }
+
+    {
+        const SvxBoxItem* pCharBox;
+        if( 0 != ( pCharBox = (const SvxBoxItem*)rPool.GetPoolDefaultItem(
+                        RES_CHRATR_BOX ) ))
+            InsColorLine( *pCharBox );
+        nMaxItem = rPool.GetItemCount2(RES_CHRATR_BOX);
+        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
+        {
+            if( 0 != (pCharBox = (const SvxBoxItem*)rPool.GetItem2( RES_CHRATR_BOX, n ) ))
+                InsColorLine( *pCharBox );
+        }
     }
 
     for (size_t n = 0; n < m_aColTbl.size(); ++n)
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 1df63f7..0c34fc7 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -463,7 +463,7 @@ void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
     sw::PoolItems aExportItems;
     GetPoolItems( aExportSet, aExportItems, false );
 
-    if( nSwPos == 0 )
+    if( rNd.GetpSwpHints() == 0 )
         m_rExport.SetCurItemSet(&aExportSet);
 
     sw::cPoolItemIter aEnd = aRangeItems.end();
@@ -486,7 +486,7 @@ void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
         m_rExport.pOutFmtNode = pOldMod;
     }
 
-    if( nSwPos == 0 )
+    if( rNd.GetpSwpHints() == 0 )
         m_rExport.SetCurItemSet(0);
 
     OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index fef7f4f..b504ccf 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -5149,7 +5149,7 @@ void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt )
             CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) );
             break;
         case RES_CHRATR_BOX:
-            CharBorder( static_cast< const SvxBoxItem& >( rHt ) );
+            FormatCharBorder( static_cast< const SvxBoxItem& >( rHt ) );
             break;
 
         case RES_TXTATR_INETFMT:
@@ -5318,4 +5318,41 @@ void AttributeOutputBase::OutputStyleItemSet( const SfxItemSet& rSet, sal_Bool b
     }
 }
 
+void AttributeOutputBase::FormatCharBorder( const SvxBoxItem& rBox )
+{
+    // Get one of the borders (if there is any border then in docx also will be)
+    const SvxBorderLine* pBorderLine = 0;
+    sal_uInt16 nDist = 0;
+    if( rBox.GetTop() )
+    {
+       pBorderLine = rBox.GetTop();
+       nDist = rBox.GetDistance( BOX_LINE_TOP );
+    }
+    else if( rBox.GetLeft() )
+    {
+       pBorderLine = rBox.GetLeft();
+       nDist = rBox.GetDistance( BOX_LINE_LEFT );
+    }
+    else if( rBox.GetBottom() )
+    {
+       pBorderLine = rBox.GetBottom();
+       nDist = rBox.GetDistance( BOX_LINE_BOTTOM );
+    }
+    else if( rBox.GetRight() )
+    {
+       pBorderLine = rBox.GetRight();
+       nDist = rBox.GetDistance( BOX_LINE_RIGHT );
+    }
+
+    if( pBorderLine )
+    {
+        const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
+        const bool bShadow =
+            pItem &&
+            static_cast<const SvxShadowItem*>(pItem)->GetLocation() != SVX_SHADOW_NONE;
+
+        CharBorder( pBorderLine, nDist, bShadow );
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 3ab2e79..d5483ef 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -294,7 +294,7 @@ protected:
     virtual void CharHidden( const SvxCharHiddenItem& );
 
     /// Sfx item RES_CHRATR_BOX
-    virtual void CharBorder( const SvxBoxItem& /*rBox*/ ){};
+    virtual void CharBorder( const SvxBorderLine* /*pAllBorder*/, const sal_uInt16 /*nDist*/, const bool /*bShadow*/ ){};
 
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index b0835e1..d73c5bd 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -140,6 +140,15 @@ static void lcl_putBorderProperty(std::stack<RTFParserState>& aStates, Id nId, R
                 rAttributes.set(nId, pValue);
             }
         }
+    else if (aStates.top().nBorderState == BORDER_CHARACTER)
+    {
+        RTFValue::Pointer_t pPointer = aStates.top().aCharacterSprms.find(NS_ooxml::LN_EG_RPrBase_bdr);
+        if (pPointer.get())
+        {
+            RTFSprms& rAttributes = pPointer->getAttributes();
+            rAttributes.set(nId, pValue);
+        }
+    }
     // Attributes of the last border type
     else if (aStates.top().nBorderState == BORDER_PARAGRAPH)
         pAttributes = &lcl_getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
@@ -2414,6 +2423,14 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
                 m_aStates.top().nBorderState = BORDER_PARAGRAPH;
             }
             break;
+        case RTF_CHBRDR:
+            {
+                RTFSprms aAttributes;
+                RTFValue::Pointer_t pValue(new RTFValue(aAttributes));
+                m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_bdr, pValue);
+                m_aStates.top().nBorderState = BORDER_CHARACTER;
+            }
+            break;
         case RTF_CLVMGF:
             {
                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 276ca93..a0b1076 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -36,7 +36,8 @@ namespace writerfilter {
             BORDER_PARAGRAPH,
             BORDER_PARAGRAPH_BOX,
             BORDER_CELL,
-            BORDER_PAGE
+            BORDER_PAGE,
+            BORDER_CHARACTER
         };
 
         /// Minimalistic buffer of elements for nested cells.
commit cfc64c7e895d990023400573d8416ce80cf0da29
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sun Sep 8 10:44:40 2013 +0200

    CharBrd 9.2: DOCX filters
    
    - Modify HasTextItem() method to able to get
    character attributes during export.
    (in this case RES_CHARTR_SHADOW)
    - Only one side of the border can be exported.
    Selecting order: (top, left, bottom, right)
    - During import set all four side and use the Word
    default shadow type (back, bottom-right, border width wide)
    
    Change-Id: I3e1e27a2ef2d77b397f2ca8efe578e09271bcf8c

diff --git a/sw/inc/charfmt.hxx b/sw/inc/charfmt.hxx
index 06a865c..0bc2ff0 100644
--- a/sw/inc/charfmt.hxx
+++ b/sw/inc/charfmt.hxx
@@ -42,7 +42,7 @@ public:
 
 namespace CharFmt
 {
-    extern const SfxItemSet* GetItemSet( const SfxPoolItem& rAttr );
+    SW_DLLPUBLIC extern const SfxItemSet* GetItemSet( const SfxPoolItem& rAttr );
     extern const SfxPoolItem* GetItem( const SwTxtAttr& rAttr, sal_uInt16 nWhich );
     extern bool IsItemIncluded( const sal_uInt16 nWhich, const SwTxtAttr *pAttr );
 }
diff --git a/sw/qa/extras/ooxmlexport/data/charborder.odt b/sw/qa/extras/ooxmlexport/data/charborder.odt
new file mode 100644
index 0000000..149abfc
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/charborder.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 5dc83f5..a2f7a55 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -116,6 +116,7 @@ public:
     void testFdo68418();
     void testA4AndBorders();
     void testFdo68787();
+    void testCharacterBorder();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -208,6 +209,7 @@ void Test::run()
         {"fdo68418.docx", &Test::testFdo68418},
         {"a4andborders.docx", &Test::testA4AndBorders},
         {"fdo68787.docx", &Test::testFdo68787},
+        {"charborder.odt", &Test::testCharacterBorder},
     };
     // Don't test the first import of these, for some reason those tests fail
     const char* aBlacklist[] = {
@@ -1273,6 +1275,54 @@ void Test::testFdo68787()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xPageStyle, "FootnoteLineRelativeWidth"));
 }
 
+void Test::testCharacterBorder()
+{
+    uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
+    // OOXML has just one border attribute(<w:bdr>) for text border so all side has
+    // the same border with the same padding
+    // Border
+    {
+        const table::BorderLine2 aTopBorder = getProperty<table::BorderLine2>(xRun,"CharTopBorder");
+        CPPUNIT_ASSERT_EQUAL_BORDER(table::BorderLine2(16737792,0,318,0,0,318), aTopBorder);
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aTopBorder, getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
+    }
+
+    // Padding (w:space)
+    {
+        const sal_Int32 nTopPadding = getProperty<sal_Int32>(xRun,"CharTopBorderDistance");
+        // In the original odt file it is 150, but the unit conversion round it down.
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(141), nTopPadding);
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(nTopPadding, getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
+    }
+
+    // Shadow (w:shadow)
+    /* OOXML use just one bool value for shadow so the next conversions
+       are made during an export-import round
+       color: any -> black
+       location: any -> bottom-right
+       width: any -> border width */
+    {
+        const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xRun, "CharShadowFormat");
+        CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow.ShadowWidth);
+    }
+
+    // Also check shadow when it is in middle of the paragraph
+    // (problem can be during export with SwWW8AttrIter::HasTextItem())
+    {
+        uno::Reference<beans::XPropertySet> xMiddleRun(getRun(getParagraph(2),2), uno::UNO_QUERY);
+        const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xMiddleRun, "CharShadowFormat");
+        CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow.ShadowWidth);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index c415d3c..646030a 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -68,6 +68,7 @@ class SvxTwoLinesItem;
 class SvxCharScaleWidthItem;
 class SvxCharReliefItem;
 class SvxCharHiddenItem;
+class SvxBoxItem;
 class SwFmtINetFmt;
 class SwFmtCharFmt;
 class SwFmtFld;
@@ -437,6 +438,9 @@ protected:
     /// Sfx item RES_CHRATR_HIDDEN
     virtual void CharHidden( const SvxCharHiddenItem& ) = 0;
 
+    /// Sfx item RES_CHRATR_BOX
+    virtual void CharBorder( const SvxBoxItem& rBox ) = 0;
+
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& ) = 0;
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index b7c528a..cddb20b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4081,6 +4081,43 @@ void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
         m_pSerializer->singleElementNS( XML_w, XML_vanish, FSNS( XML_w, XML_val ), "false", FSEND );
 }
 
+void DocxAttributeOutput::CharBorder( const SvxBoxItem& rBox )
+{
+    // Get one of the borders (if there is any border then in docx also will be)
+    const SvxBorderLine* pBorderLine = 0;
+    sal_uInt16 nDist = 0;
+    if( rBox.GetTop() )
+    {
+       pBorderLine = rBox.GetTop();
+       nDist = rBox.GetDistance( BOX_LINE_TOP );
+    }
+    else if( rBox.GetLeft() )
+    {
+       pBorderLine = rBox.GetLeft();
+       nDist = rBox.GetDistance( BOX_LINE_LEFT );
+    }
+    else if( rBox.GetBottom() )
+    {
+       pBorderLine = rBox.GetBottom();
+       nDist = rBox.GetDistance( BOX_LINE_BOTTOM );
+    }
+    else if( rBox.GetRight() )
+    {
+       pBorderLine = rBox.GetRight();
+       nDist = rBox.GetDistance( BOX_LINE_RIGHT );
+    }
+
+    if( pBorderLine )
+    {
+        const SfxPoolItem* pItem = GetExport().HasItem( RES_CHRATR_SHADOW );
+        const bool bShadow =
+            pItem &&
+            static_cast<const SvxShadowItem*>(pItem)->GetLocation() != SVX_SHADOW_NONE;
+
+        impl_borderLine( m_pSerializer, XML_bdr, pBorderLine, nDist, bShadow );
+    }
+}
+
 void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
 {
     const SwTxtINetFmt* pINetFmt = rLink.GetTxtINetFmt();
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 5e297aa..c217fb9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -472,6 +472,9 @@ protected:
     /// Sfx item RES_CHRATR_HIDDEN
     virtual void CharHidden( const SvxCharHiddenItem& rHidden );
 
+    /// Sfx item RES_CHRATR_BOX
+    virtual void CharBorder( const SvxBoxItem& rBox );
+
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
 
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index ea115bf..b332dd3 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -312,6 +312,9 @@ protected:
     /// Sfx item RES_CHRATR_HIDDEN
     virtual void CharHidden( const SvxCharHiddenItem& rHidden );
 
+    /// Sfx item RES_CHRATR_BOX
+    virtual void CharBorder( const SvxBoxItem& /*rBox*/ ){};
+
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
 
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 4664938..1df63f7 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -463,6 +463,9 @@ void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
     sw::PoolItems aExportItems;
     GetPoolItems( aExportSet, aExportItems, false );
 
+    if( nSwPos == 0 )
+        m_rExport.SetCurItemSet(&aExportSet);
+
     sw::cPoolItemIter aEnd = aRangeItems.end();
     for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI )
     {
@@ -483,6 +486,9 @@ void SwWW8AttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
         m_rExport.pOutFmtNode = pOldMod;
     }
 
+    if( nSwPos == 0 )
+        m_rExport.SetCurItemSet(0);
+
     OSL_ENSURE( pFont, "must be *some* font associated with this txtnode" );
     if ( pFont )
     {
@@ -584,7 +590,6 @@ const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
 {
     const SfxPoolItem* pRet = 0;
     const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
-
     if (pTxtAttrs && !m_rExport.m_aCurrentCharPropStarts.empty())
     {
         xub_StrLen nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.top();
@@ -594,11 +599,26 @@ const SfxPoolItem* SwWW8AttrIter::HasTextItem( sal_uInt16 nWhich ) const
             const SfxPoolItem* pItem = &pHt->GetAttr();
             const xub_StrLen* pAtrEnd = 0;
             if( 0 != ( pAtrEnd = pHt->GetEnd() ) &&     // only Attr with an end
-                nWhich == pItem->Which() &&
                 nTmpSwPos >= *pHt->GetStart() && nTmpSwPos < *pAtrEnd )
             {
-                pRet = pItem;       // found it
-                break;
+                if ( nWhich == pItem->Which() )
+                {
+                    pRet = pItem;       // found it
+                    break;
+                }
+                else if( RES_TXTATR_INETFMT == pHt->Which() ||
+                         RES_TXTATR_CHARFMT == pHt->Which() ||
+                         RES_TXTATR_AUTOFMT == pHt->Which() )
+                {
+                    const SfxItemSet* pSet = CharFmt::GetItemSet( pHt->GetAttr() );
+                    const SfxPoolItem* pCharItem;
+                    if ( pSet &&
+                         SFX_ITEM_SET == pSet->GetItemState( nWhich, pHt->Which() != RES_TXTATR_AUTOFMT, &pCharItem ) )
+                    {
+                        pRet = pCharItem;       // found it
+                        break;
+                    }
+                }
             }
             else if (nTmpSwPos < *pHt->GetStart())
                 break;              // nothing more to come
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 188b995..fef7f4f 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -287,7 +287,6 @@ void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool
         GetPoolItems( rSet, aItems, bExportParentItemSet );
         if ( bChpFmt )
             ExportPoolItemsToCHP(aItems, nScript);
-
         if ( bPapFmt )
         {
             sw::cPoolItemIter aEnd = aItems.end();
@@ -5149,6 +5148,9 @@ void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt )
         case RES_CHRATR_HIDDEN:
             CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) );
             break;
+        case RES_CHRATR_BOX:
+            CharBorder( static_cast< const SvxBoxItem& >( rHt ) );
+            break;
 
         case RES_TXTATR_INETFMT:
             TextINetFormat( static_cast< const SwFmtINetFmt& >( rHt ) );
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index 3ffb2aa..3ab2e79 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -293,6 +293,9 @@ protected:
     /// Sfx item RES_CHRATR_HIDDEN
     virtual void CharHidden( const SvxCharHiddenItem& );
 
+    /// Sfx item RES_CHRATR_BOX
+    virtual void CharBorder( const SvxBoxItem& /*rBox*/ ){};
+
     /// Sfx item RES_TXTATR_INETFMT
     virtual void TextINetFormat( const SwFmtINetFmt& );
 
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 0dc4667..4652a40 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -2933,10 +2933,35 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
     case NS_ooxml::LN_CT_DocDefaults_rPrDefault:
         GetStyleSheetTable()->sprm( rSprm );
     break;
+    case NS_ooxml::LN_EG_RPrBase_bdr:
+        {
+            writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+            if( pProperties.get())
+            {
+                BorderHandlerPtr pBorderHandler( new BorderHandler( true ) );
+                pProperties->resolve(*pBorderHandler);
+
+                rContext->Insert( PROP_CHAR_TOP_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
+                rContext->Insert( PROP_CHAR_BOTTOM_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
+                rContext->Insert( PROP_CHAR_LEFT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
+                rContext->Insert( PROP_CHAR_RIGHT_BORDER, uno::makeAny( pBorderHandler->getBorderLine()));
+
+                rContext->Insert( PROP_CHAR_TOP_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
+                rContext->Insert( PROP_CHAR_BOTTOM_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
+                rContext->Insert( PROP_CHAR_LEFT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
+                rContext->Insert( PROP_CHAR_RIGHT_BORDER_DISTANCE, uno::makeAny( pBorderHandler->getLineDistance()));
+
+                if( pBorderHandler->getShadow() )
+                {
+                    table::ShadowFormat aFormat = rContext->getShadowFromBorder(pBorderHandler->getBorderLine());
+                    rContext->Insert(PROP_CHAR_SHADOW_FORMAT, uno::makeAny(aFormat));
+                }
+            }
+        }
+        break;
     case NS_ooxml::LN_CT_PPr_sectPr:
     case NS_ooxml::LN_EG_RPrBase_color:
     case NS_ooxml::LN_EG_RPrBase_rFonts:
-    case NS_ooxml::LN_EG_RPrBase_bdr:
     case NS_ooxml::LN_EG_RPrBase_eastAsianLayout:
     case NS_ooxml::LN_EG_RPrBase_u:
     case NS_ooxml::LN_EG_RPrBase_lang:
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 27ebabc..598f97e 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -105,6 +105,15 @@ const OUString& PropertyNameSupplier::GetName( PropertyIds eId ) const
             case PROP_CHAR_ROTATION:     sName = "CharRotation"; break;
             case PROP_CHAR_ROTATION_IS_FIT_TO_LINE:     sName = "CharRotationIsFitToLine"; break;
             case PROP_CHAR_FLASH:     sName = "CharFlash"; break;
+            case PROP_CHAR_LEFT_BORDER: sName = "CharLeftBorder";break;
+            case PROP_CHAR_RIGHT_BORDER: sName = "CharRightBorder";break;
+            case PROP_CHAR_TOP_BORDER: sName = "CharTopBorder";break;
+            case PROP_CHAR_BOTTOM_BORDER: sName = "CharBottomBorder";break;
+            case PROP_CHAR_LEFT_BORDER_DISTANCE: sName = "CharLeftBorderDistance"; break;
+            case PROP_CHAR_RIGHT_BORDER_DISTANCE: sName = "CharRightBorderDistance"; break;
+            case PROP_CHAR_TOP_BORDER_DISTANCE: sName = "CharTopBorderDistance";break;
+            case PROP_CHAR_BOTTOM_BORDER_DISTANCE: sName = "CharBottomBorderDistance"; break;
+            case PROP_CHAR_SHADOW_FORMAT: sName = "CharShadowFormat"; break;
 
             case PROP_PARA_STYLE_NAME:      sName = "ParaStyleName"; break;
             case PROP_PARA_ADJUST:     sName = "ParaAdjust"; break;
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index f35cdfd..059fc5e 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -60,6 +60,14 @@ enum PropertyIds
         ,PROP_CHAR_COMBINE_PREFIX
         ,PROP_CHAR_COMBINE_SUFFIX
         ,PROP_CHAR_CONTOURED
+        ,PROP_CHAR_LEFT_BORDER
+        ,PROP_CHAR_RIGHT_BORDER
+        ,PROP_CHAR_TOP_BORDER
+        ,PROP_CHAR_BOTTOM_BORDER
+        ,PROP_CHAR_LEFT_BORDER_DISTANCE
+        ,PROP_CHAR_RIGHT_BORDER_DISTANCE
+        ,PROP_CHAR_TOP_BORDER_DISTANCE
+        ,PROP_CHAR_BOTTOM_BORDER_DISTANCE
         ,PROP_CHAR_EMPHASIS
         ,PROP_CHAR_ESCAPEMENT
         ,PROP_CHAR_ESCAPEMENT_HEIGHT
@@ -95,6 +103,7 @@ enum PropertyIds
         ,PROP_CHAR_RELIEF
         ,PROP_CHAR_ROTATION
         ,PROP_CHAR_ROTATION_IS_FIT_TO_LINE
+        ,PROP_CHAR_SHADOW_FORMAT
         ,PROP_CHAR_SCALE_WIDTH
         ,PROP_CHAR_SHADOWED
         ,PROP_CHAR_STRIKEOUT
commit b94b1fe936ddc4a9b86fbeb9c9c6ab0fca52f0bc
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sun Sep 8 10:39:31 2013 +0200

    CharBrd 9.1: HTML filters
    
    -I don't implement shadow because HTML filter use css1 attributes
    and there isn't box-shadow in css1.
    -Border merge: skip span open and close tags to get the
    right result.
    
    Change-Id: I17edc2e1cc42359b5f1721b8891350c528c7793e

diff --git a/sw/qa/extras/htmlexport/data/charborder.odt b/sw/qa/extras/htmlexport/data/charborder.odt
new file mode 100644
index 0000000..e9667b2
Binary files /dev/null and b/sw/qa/extras/htmlexport/data/charborder.odt differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 34cd2ee..3b02f2b 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -15,6 +15,7 @@ class Test : public SwModelTestBase
 {
 public:
     void testFdo62336();
+    void testCharBorder();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -30,6 +31,7 @@ void Test::run()
 {
     MethodEntry<Test> aMethods[] = {
         {"fdo62336.docx", &Test::testFdo62336},
+        {"charborder.odt", &Test::testCharBorder},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -49,6 +51,37 @@ void Test::testFdo62336()
     // The problem was essentially a crash during table export as docx/rtf/html
 }
 
+void Test::testCharBorder()
+{
+
+    uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY);
+    // Different Border
+    {
+        CPPUNIT_ASSERT_EQUAL_BORDER(
+            table::BorderLine2(6711039,12,12,12,3,37),
+            getProperty<table::BorderLine2>(xRun,"CharTopBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(
+            table::BorderLine2(16750848,0,99,0,2,99),
+            getProperty<table::BorderLine2>(xRun,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(
+            table::BorderLine2(16711680,0,169,0,1,169),
+            getProperty<table::BorderLine2>(xRun,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(
+            table::BorderLine2(255,0,169,0,0,169),
+            getProperty<table::BorderLine2>(xRun,"CharRightBorder"));
+    }
+
+    // Different Padding
+    {
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(450), getProperty<sal_Int32>(xRun,"CharTopBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(550), getProperty<sal_Int32>(xRun,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xRun,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xRun,"CharRightBorderDistance"));
+    }
+
+    // No shadow
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 98ef8d4..7e82dab 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -3500,6 +3500,25 @@ Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
 {
     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
 
+    // Avoid interference between character and paragraph attributes
+    if( rHt.Which() < RES_CHRATR_END &&
+        rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
+        return rWrt;
+
+    if( rHt.Which() == RES_CHRATR_BOX )
+    {
+        if( rHTMLWrt.bTagOn )
+        {
+            // Inline-block to make the line height changing correspond to the character border
+            rHTMLWrt.OutCSS1_PropertyAscii(sCSS1_P_display, "inline-block");
+        }
+        else
+        {
+            HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
+            return rWrt;
+        }
+    }
+
     const SvxBoxItem& rBoxItem = (const SvxBoxItem&)rHt;
     const SvxBorderLine *pTop = rBoxItem.GetTop();
     const SvxBorderLine *pBottom = rBoxItem.GetBottom();
@@ -3630,7 +3649,7 @@ SwAttrFnTab aCSS1AttrFnTab = {
 /* RES_CHRATR_HIDDEN */             OutCSS1_SvxHidden,
 /* RES_CHRATR_OVERLINE */           OutCSS1_SvxOverline,
 /* RES_CHRATR_RSID */               0,
-/* RES_CHRATR_BOX */                0,
+/* RES_CHRATR_BOX */                OutCSS1_SvxBox,
 /* RES_CHRATR_SHADOW */             0,
 /* RES_CHRATR_DUMMY1 */             0,
 /* RES_CHRATR_DUMMY2 */             0,
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index 1f141bc..4ec590c 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -1384,6 +1384,11 @@ HTMLOnOffState HTMLEndPosLst::GetHTMLItemState( const SfxPoolItem& rItem )
     case RES_PARATR_DROP:
         eState = HTML_DROPCAP_VALUE;
         break;
+
+    case RES_CHRATR_BOX:
+        if( IsHTMLMode(HTMLMODE_SOME_STYLES) )
+            eState = HTML_STYLE_VALUE;
+        break;
     }
 
     return eState;
@@ -1703,6 +1708,7 @@ void HTMLEndPosLst::InsertNoScript( const SfxPoolItem& rItem,
             bSet = bOutStyles &&
                    (!bParaAttrs
                   || rItem.Which()==RES_CHRATR_BACKGROUND
+                  || rItem.Which()==RES_CHRATR_BOX
                   || rItem.Which()==RES_CHRATR_OVERLINE);
             break;
 
@@ -1951,10 +1957,31 @@ void HTMLEndPosLst::OutStartAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
 {
     rHWrt.bTagOn = sal_True;
 
+    // Character border attribute must be the first which is written out
+    // because of border merge.
+    sal_uInt16 nCharBoxIndex = 0;
+    while( nCharBoxIndex < aStartLst.size() &&
+           aStartLst[nCharBoxIndex]->GetItem()->Which() != RES_CHRATR_BOX )
+    {
+        ++nCharBoxIndex;
+    }
+
     // die Attribute in der Start-Liste sind aufsteigend sortiert
     for( sal_uInt16 i=0; i< aStartLst.size(); i++ )
     {
-        HTMLSttEndPos *pPos = aStartLst[i];
+        HTMLSttEndPos *pPos = 0;
+        if( nCharBoxIndex < aStartLst.size() )
+        {
+            if( i == 0 )
+                pPos = aStartLst[nCharBoxIndex];
+            else if( i == nCharBoxIndex )
+                pPos = aStartLst[0];
+            else
+                pPos = aStartLst[i];
+        }
+        else
+            pPos = aStartLst[i];
+
         sal_Int32 nStart = pPos->GetStart();
         if( nStart > nPos )
         {
@@ -2002,7 +2029,27 @@ void HTMLEndPosLst::OutEndAttrs( SwHTMLWriter& rHWrt, sal_Int32 nPos,
                 HTMLOutFuncs::FlushToAscii( rHWrt.Strm(), *pContext );
                 pContext = 0; // one time ony
             }
-            Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+            // Skip closing span if next character span has the same border (border merge)
+            bool bSkipOut = false;
+            if( pPos->GetItem()->Which() == RES_CHRATR_BOX )
+            {
+                for(sal_uInt16 nIndex = _FindStartPos(pPos) + 1; nIndex < aStartLst.size(); ++nIndex )
+                {
+                    HTMLSttEndPos *pEndPos = aStartLst[nIndex];
+                    if( pEndPos->GetItem()->Which() == RES_CHRATR_BOX &&
+                        *static_cast<const SvxBoxItem*>(pEndPos->GetItem()) ==
+                        *static_cast<const SvxBoxItem*>(pPos->GetItem()) )
+                    {
+                        pEndPos->SetStart(pPos->GetStart());
+                        bSkipOut = true;
+                        break;
+                    }
+                }
+            }
+            if( !bSkipOut )
+            {
+                Out( aHTMLAttrFnTab, *pPos->GetItem(), rHWrt );
+            }
             _RemoveItem( i );
         }
         else if( nEnd > nPos )
@@ -2386,13 +2433,14 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
         sal_Int32 nPreSplitPos = 0;
         for( ; nStrPos < nEnde; nStrPos++ )
         {
-            aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
-
             // Die an der aktuellen Position verankerten Rahmen ausgeben
             if( bFlysLeft )
+            {
+                aEndPosLst.OutEndAttrs( rHTMLWrt, nStrPos + nOffset, &aContext );
                 bFlysLeft = rHTMLWrt.OutFlyFrm( rNode.GetIndex(),
                                                 nStrPos, HTML_POS_INSIDE,
                                                 &aContext );
+            }
 
             sal_Bool bOutChar = sal_True;
             const SwTxtAttr * pTxtHt = 0;
@@ -3226,7 +3274,7 @@ SwAttrFnTab aHTMLAttrFnTab = {
 /* RES_CHRATR_HIDDEN */             OutHTML_CSS1Attr,
 /* RES_CHRATR_OVERLINE */           OutHTML_CSS1Attr,
 /* RES_CHRATR_RSID */               0,
-/* RES_CHRATR_BOX */                0,
+/* RES_CHRATR_BOX */                OutHTML_CSS1Attr,
 /* RES_CHRATR_SHADOW */             0,
 /* RES_CHRATR_DUMMY1 */             0,
 /* RES_CHRATR_DUMMY2 */             0,
diff --git a/sw/source/filter/html/htmlcss1.cxx b/sw/source/filter/html/htmlcss1.cxx
index ee84ac3..ebef8ff 100644
--- a/sw/source/filter/html/htmlcss1.cxx
+++ b/sw/source/filter/html/htmlcss1.cxx
@@ -218,6 +218,13 @@ static void SetCharFmtAttrs( SwCharFmt *pCharFmt, SfxItemSet& rItemSet )
         aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
         pCharFmt->SetFmtAttr( aBrushItem );
     }
+
+    if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, sal_False, &pItem ) )
+    {
+        SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
+        aBoxItem.SetWhich( RES_CHRATR_BOX );
+        pCharFmt->SetFmtAttr( aBoxItem );
+    }
 }
 
 void SwCSS1Parser::SetLinkCharFmts()
@@ -1623,6 +1630,9 @@ _HTMLAttr **SwHTMLParser::GetAttrTabEntry( sal_uInt16 nWhich )
     case RES_CHRATR_BACKGROUND:
         ppAttr = &aAttrTab.pCharBrush;
         break;
+    case RES_CHRATR_BOX:
+        ppAttr = &aAttrTab.pCharBox;
+        break;
 
     case RES_PARATR_LINESPACING:
         ppAttr = &aAttrTab.pLineSpacing;
diff --git a/sw/source/filter/html/htmlctxt.cxx b/sw/source/filter/html/htmlctxt.cxx
index 423c0b5..fb07766 100644
--- a/sw/source/filter/html/htmlctxt.cxx
+++ b/sw/source/filter/html/htmlctxt.cxx
@@ -24,6 +24,7 @@
 #include <editeng/brushitem.hxx>
 #include <editeng/fhgtitem.hxx>
 #include <svtools/htmltokn.h>
+#include <editeng/boxitem.hxx>
 
 #include "doc.hxx"
 #include "pam.hxx"
@@ -666,6 +667,23 @@ void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
             }
             break;
 
+        case RES_BOX:
+            if( bCharLvl )
+            {
+                SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
+                aBoxItem.SetWhich( RES_CHRATR_BOX );
+
+                NewAttr( &aAttrTab.pCharBox, aBoxItem );
+
+                _HTMLAttrs &rAttrs = pContext->GetAttrs();
+                rAttrs.push_back( aAttrTab.pCharBox );
+            }
+            else
+            {
+                ppAttr = &aAttrTab.pBox;
+            }
+            break;
+
         default:
             // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
             ppAttr = GetAttrTabEntry( pItem->Which() );
diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx
index 5104878..f2f1147 100644
--- a/sw/source/filter/html/swhtml.hxx
+++ b/sw/source/filter/html/swhtml.hxx
@@ -177,7 +177,8 @@ struct _HTMLAttrTable
                 *pCharBrush,    // Zeichen-Hintergrund
                 *pLanguage,
                 *pLanguageCJK,
-                *pLanguageCTL
+                *pLanguageCTL,
+                *pCharBox
                 ;
 };
 
commit 6a71bea7cf19c7b6a5031734354073d82ae8916e
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Wed Sep 4 14:15:06 2013 +0200

    Revert "It seems lcl_ExtendLeftAndRight is just a workaround"
    
    This reverts commit 9ece71a185c93845e38c25eae91bc1955d60bfed.
    I solved some bug which were hide by the usage of this method,
    but there are other cases where it is neccessary.
    
    Conflicts:
    	sw/source/core/layout/paintfrm.cxx
    
    Change-Id: I01f27c812890d7bc4d47e645f25213ba67a955d5

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 9209f7f..3f9ca4a 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1468,6 +1468,25 @@ static void lcl_CalcBorderRect( SwRect &rRect, const SwFrm *pFrm,
     ::SwAlignRect( rRect, pGlobalShell );
 }
 
+static void lcl_ExtendLeftAndRight( SwRect&                _rRect,
+                                         const SwFrm&           _rFrm,
+                                         const SwBorderAttrs&   _rAttrs,
+                                         const SwRectFn&        _rRectFn )
+{
+    // Extend left/right border/shadow rectangle to bottom of previous frame/to
+    // top of next frame, if border/shadow is joined with previous/next frame.
+    if ( _rAttrs.JoinedWithPrev( _rFrm ) )
+    {
+        const SwFrm* pPrevFrm = _rFrm.GetPrev();
+        (_rRect.*_rRectFn->fnSetTop)( (pPrevFrm->*_rRectFn->fnGetPrtBottom)() );
+    }
+    if ( _rAttrs.JoinedWithNext( _rFrm ) )
+    {
+        const SwFrm* pNextFrm = _rFrm.GetNext();
+        (_rRect.*_rRectFn->fnSetBottom)( (pNextFrm->*_rRectFn->fnGetPrtTop)() );
+    }
+}
+
 static void lcl_SubtractFlys( const SwFrm *pFrm, const SwPageFrm *pPage,
                            const SwRect &rRect, SwRegionRects &rRegion )
 {
@@ -4474,7 +4493,10 @@ void SwFrm::PaintShadow( const SwRect& rRect, SwRect& rOutRect,
               (static_cast<const SwLayoutFrm*>(this))->GetFmt()->IsBackgroundTransparent()
             );
 
-   lcl_PaintShadow(rRect, rOutRect, rShadow, bDrawFullShadowRectangle, bTop, bBottom, true, true);
+    SWRECTFN( this );
+    ::lcl_ExtendLeftAndRight( rOutRect, *(this), rAttrs, fnRect );
+
+    lcl_PaintShadow(rRect, rOutRect, rShadow, bDrawFullShadowRectangle, bTop, bBottom, true, true);
 }
 
 /*************************************************************************
@@ -4795,6 +4817,8 @@ static void lcl_PaintLeftRightLine( const bool         _bLeft,
 
     if ( _rFrm.IsCntntFrm() )
     {
+        ::lcl_ExtendLeftAndRight( aRect, _rFrm, _rAttrs, _rRectFn );
+
         // No Top / bottom borders for joint borders
         if ( _rAttrs.JoinedWithPrev( _rFrm ) ) pTopBorder = NULL;
         if ( _rAttrs.JoinedWithNext( _rFrm ) ) pBottomBorder = NULL;
commit 96e4cc87513c170c73121b4cdd8365bf56b8a3af
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Tue Sep 3 19:14:28 2013 +0200

    Fix expected and actual order in odf export test
    
    Change-Id: Ib8168112e297571cc99b39fbf365d888e2247da5

diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index efd49df..300594b 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -198,10 +198,10 @@ void Test::testCharacterBorder()
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"ParaShadowFormat");
-        CPPUNIT_ASSERT_EQUAL(aShadow.Color, sal_Int32(0));
-        CPPUNIT_ASSERT_EQUAL((bool)aShadow.IsTransparent, false);
-        CPPUNIT_ASSERT_EQUAL(aShadow.Location, table::ShadowLocation(0));
-        CPPUNIT_ASSERT_EQUAL(aShadow.ShadowWidth, sal_Int16(0));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aShadow.Color);
+        CPPUNIT_ASSERT_EQUAL(false, (bool)aShadow.IsTransparent);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(0), aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aShadow.ShadowWidth);
     }
 
     // Character border for first paragraph
@@ -228,16 +228,16 @@ void Test::testCharacterBorder()
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
-        CPPUNIT_ASSERT_EQUAL(aShadow.Color, sal_Int32(16724787));
-        CPPUNIT_ASSERT_EQUAL((bool)aShadow.IsTransparent, false);
-        CPPUNIT_ASSERT_EQUAL(aShadow.Location, table::ShadowLocation(2));
-        CPPUNIT_ASSERT_EQUAL(aShadow.ShadowWidth, sal_Int16(280));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(16724787), aShadow.Color);
+        CPPUNIT_ASSERT_EQUAL(false, (bool)aShadow.IsTransparent);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(2), aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(280), aShadow.ShadowWidth);
 
         // Check autostyle
         {
             uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(getAutoStyles("ParagraphStyles"));
             uno::Reference < container::XEnumeration > xAutoStylesEnum( xAutoStyleFamily->createEnumeration() );
-            CPPUNIT_ASSERT_EQUAL((bool)xAutoStylesEnum->hasMoreElements(), true);
+            CPPUNIT_ASSERT_EQUAL(true, (bool)xAutoStylesEnum->hasMoreElements());
 
             // First paragraph autostyle
             uno::Reference < beans::XPropertySet > xPSet( xAutoStylesEnum->nextElement(), uno::UNO_QUERY );
@@ -295,10 +295,10 @@ void Test::testCharacterBorder()
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
-        CPPUNIT_ASSERT_EQUAL(aShadow.Color, sal_Int32(0));
-        CPPUNIT_ASSERT_EQUAL((bool)aShadow.IsTransparent, false);
-        CPPUNIT_ASSERT_EQUAL(aShadow.Location, table::ShadowLocation(3));
-        CPPUNIT_ASSERT_EQUAL(aShadow.ShadowWidth, sal_Int16(79));
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aShadow.Color);
+        CPPUNIT_ASSERT_EQUAL(false, (bool)aShadow.IsTransparent);
+        CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(3), aShadow.Location);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(79), aShadow.ShadowWidth);
 
         // Check character style
         {
commit d21dd2889199030f3500ce2142182ebb8eb5f18f
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sun Sep 8 10:36:44 2013 +0200

    Improve border equal check in filter tests
    
    With macro the error message will point to the right line.
    Check padding distinct.
    
    Change-Id: Id09fbf65350a7a3708923eb07d673068c2943b50

diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index 895c096..254aabe 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -37,6 +37,13 @@
 using namespace com::sun::star;
 
 #define DEFAULT_STYLE "Default Style"
+#define CPPUNIT_ASSERT_EQUAL_BORDER(aExpected, aActual) \
+        CPPUNIT_ASSERT_EQUAL(aExpected.Color, aActual.Color); \
+        CPPUNIT_ASSERT_EQUAL(aExpected.InnerLineWidth, aActual.InnerLineWidth); \
+        CPPUNIT_ASSERT_EQUAL(aExpected.LineDistance, aActual.LineDistance); \
+        CPPUNIT_ASSERT_EQUAL(aExpected.LineStyle, aActual.LineStyle); \
+        CPPUNIT_ASSERT_EQUAL(aExpected.LineWidth, aActual.LineWidth); \
+        CPPUNIT_ASSERT_EQUAL(aExpected.OuterLineWidth, aActual.OuterLineWidth);
 
 /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
 class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest
@@ -347,21 +354,6 @@ protected:
         return xCursor->getPage();
     }
 
-    void assertEqualBorder(
-        const table::BorderLine2& rLeft, const sal_Int32 nLeftDist,
-        const table::BorderLine2& rRight, const sal_Int32 nRightDist )
-    {
-        // Border
-        CPPUNIT_ASSERT_EQUAL(rLeft.Color, rRight.Color);
-        CPPUNIT_ASSERT_EQUAL(rLeft.InnerLineWidth, rRight.InnerLineWidth);
-        CPPUNIT_ASSERT_EQUAL(rLeft.LineDistance, rRight.LineDistance);
-        CPPUNIT_ASSERT_EQUAL(rLeft.LineStyle, rRight.LineStyle);
-        CPPUNIT_ASSERT_EQUAL(rLeft.LineWidth, rRight.LineWidth);
-        CPPUNIT_ASSERT_EQUAL(rLeft.OuterLineWidth, rRight.OuterLineWidth);
-        // Padding
-        CPPUNIT_ASSERT_EQUAL(nLeftDist, nRightDist);
-    }
-
     uno::Reference<lang::XComponent> mxComponent;
     xmlBufferPtr mpXmlBuffer;
 
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 0b104d1..efd49df 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -181,28 +181,20 @@ void Test::testCharacterBorder()
         uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
 
         // Top border
-        assertEqualBorder(
-            aFirstParTopBorder, aFirstParTopPadding,
-            getProperty<table::BorderLine2>(xSet,"TopBorder"),
-            getProperty<sal_Int32>(xSet,"TopBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"TopBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"TopBorderDistance"));
 
         // Bottom border (same as top border)
-        assertEqualBorder(
-            aFirstParTopBorder, aFirstParTopPadding,
-            getProperty<table::BorderLine2>(xSet,"BottomBorder"),
-            getProperty<sal_Int32>(xSet,"BottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"BottomBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"BottomBorderDistance"));
 
         // Left border (same as top border)
-        assertEqualBorder(
-            aFirstParTopBorder, aFirstParTopPadding,
-            getProperty<table::BorderLine2>(xSet,"LeftBorder"),
-            getProperty<sal_Int32>(xSet,"LeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"LeftBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"LeftBorderDistance"));
 
         // Right border (same as top border)
-        assertEqualBorder(
-            aFirstParTopBorder, aFirstParTopPadding,
-            getProperty<table::BorderLine2>(xSet,"RightBorder"),
-            getProperty<sal_Int32>(xSet,"RightBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"RightBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"RightBorderDistance"));
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"ParaShadowFormat");
@@ -219,28 +211,20 @@ void Test::testCharacterBorder()
         uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
 
         // Top border
-        assertEqualBorder(
-            aFirstParCharTopBorder, aFirstParCharTopPadding,
-            getProperty<table::BorderLine2>(xSet,"CharTopBorder"),
-            getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
 
         // Bottom border (same as top border)
-        assertEqualBorder(
-            aFirstParCharTopBorder, aFirstParCharTopPadding,
-            getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
-            getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
 
         // Left border (same as top border)
-        assertEqualBorder(
-            aFirstParCharTopBorder, aFirstParCharTopPadding,
-            getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
-            getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
 
         // Right border (same as top border)
-        assertEqualBorder(
-            aFirstParCharTopBorder, aFirstParCharTopPadding,
-            getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
-            getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
+        CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
@@ -259,28 +243,20 @@ void Test::testCharacterBorder()
             uno::Reference < beans::XPropertySet > xPSet( xAutoStylesEnum->nextElement(), uno::UNO_QUERY );
 
             // Top border
-            assertEqualBorder(
-                aFirstParCharTopBorder, aFirstParCharTopPadding,
-                getProperty<table::BorderLine2>(xSet,"CharTopBorder"),
-                getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
+            CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
 
             // Bottom border
-            assertEqualBorder(
-                aFirstParCharTopBorder, aFirstParCharTopPadding,
-                getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
-                getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
+            CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
 
             // Left border
-            assertEqualBorder(
-                aFirstParCharTopBorder, aFirstParCharTopPadding,
-                getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
-                getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
+            CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
 
             // Right border
-            assertEqualBorder(
-                aFirstParCharTopBorder, aFirstParCharTopPadding,
-                getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
-                getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
+            CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
         }
     }
 
@@ -302,28 +278,20 @@ void Test::testCharacterBorder()
         uno::Reference < beans::XPropertySet > xSet( getRun(getParagraph(2),2), uno::UNO_QUERY );
 
         // Top border
-        assertEqualBorder(
-            aBorderArray[0], aDistances[0],
-            getProperty<table::BorderLine2>(xSet,"CharTopBorder"),
-            getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[0], getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
+        CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
 
         // Bottom border
-        assertEqualBorder(
-            aBorderArray[1], aDistances[1],
-            getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
-            getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[1], getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
+        CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
 
         // Left border
-        assertEqualBorder(
-            aBorderArray[2], aDistances[2],
-            getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
-            getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[2], getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
+        CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
 
         // Right border
-        assertEqualBorder(
-            aBorderArray[3], aDistances[3],
-            getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
-            getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+        CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[3], getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
+        CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
 
         // Shadow
         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
@@ -338,28 +306,20 @@ void Test::testCharacterBorder()
             uno::Reference < beans::XPropertySet > xStyleSet(xStyleFamily->getByName("CharDiffBor"), uno::UNO_QUERY);
 
             // Top border
-            assertEqualBorder(
-                aBorderArray[0], aDistances[0],
-                getProperty<table::BorderLine2>(xStyleSet,"CharTopBorder"),
-                getProperty<sal_Int32>(xStyleSet,"CharTopBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[0], getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
+            CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
 
             // Bottom border
-            assertEqualBorder(
-                aBorderArray[1], aDistances[1],
-                getProperty<table::BorderLine2>(xStyleSet,"CharBottomBorder"),
-                getProperty<sal_Int32>(xStyleSet,"CharBottomBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[1], getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
+            CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
 
             // Left border
-            assertEqualBorder(
-                aBorderArray[2], aDistances[2],
-                getProperty<table::BorderLine2>(xStyleSet,"CharLeftBorder"),
-                getProperty<sal_Int32>(xStyleSet,"CharLeftBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[2], getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
+            CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
 
             // Right border
-            assertEqualBorder(
-                aBorderArray[3], aDistances[3],
-                getProperty<table::BorderLine2>(xStyleSet,"CharRightBorder"),
-                getProperty<sal_Int32>(xStyleSet,"CharRightBorderDistance"));
+            CPPUNIT_ASSERT_EQUAL_BORDER(aBorderArray[3], getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
+            CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
         }
     }
 }
commit 77df2ac92687496a3ae027451364ff833df47e68
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Thu Aug 29 10:37:44 2013 +0200

    Generalize SwHTMLWriter::ToPixel method
    
    Change-Id: Iba4c292a3130f33792ef39b97d774a48c181359a

diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 03fde66..98ef8d4 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -454,16 +454,7 @@ void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal )
 void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal,
                                           sal_Bool bVert )
 {
-    if( nVal && Application::GetDefaultDevice() )
-    {
-        Size aSz( bVert ? 0 : nVal, bVert ? nVal : 0 );
-        aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode( MAP_TWIP) );
-        nVal = bVert ? aSz.Height() : aSz.Width();
-        if( !nVal )
-            nVal = 1;
-    }
-
-    OString sOut(OString::number(nVal) + sCSS1_UNIT_px);
+    OString sOut(OString::number(ToPixel(nVal,bVert)) + sCSS1_UNIT_px);
     OutCSS1_PropertyAscii(pProp, sOut);
 }
 
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index c107939..1f141bc 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -2092,7 +2092,7 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width)
                     .append('=');
                 rWrt.Strm() << sOut.makeStringAndClear().getStr();
-                rWrt.OutULong( rHTMLWrt.ToPixel(nPageWidth-nLeft-nRight) );
+                rWrt.OutULong( rHTMLWrt.ToPixel(nPageWidth-nLeft-nRight,false) );
 
                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align)
                     .append('=');
@@ -2115,7 +2115,7 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_size)
                     .append('=');
                 rWrt.Strm() << sOut.makeStringAndClear().getStr();
-                rWrt.OutULong( rHTMLWrt.ToPixel(nWidth) );
+                rWrt.OutULong( rHTMLWrt.ToPixel(nWidth,false) );
 
                 const Color& rBorderColor = pBorderLine->GetColor();
                 if( !rBorderColor.IsRGBEqual( Color(COL_GRAY) ) )
@@ -2613,12 +2613,13 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
 }
 
 
-sal_uInt32 SwHTMLWriter::ToPixel( sal_uInt32 nVal ) const
+sal_uInt32 SwHTMLWriter::ToPixel( sal_uInt32 nVal, const bool bVert ) const
 {
     if( Application::GetDefaultDevice() && nVal )
     {
-        nVal = Application::GetDefaultDevice()->LogicToPixel(
-                    Size( nVal, nVal ), MapMode( MAP_TWIP ) ).Width();
+        Size aSz( bVert ? 0 : nVal, bVert ? nVal : 0 );
+        aSz = Application::GetDefaultDevice()->LogicToPixel(aSz, MapMode( MAP_TWIP ));
+        nVal = bVert ? aSz.Height() : aSz.Width();
         if( !nVal )     // wo ein Twip ist sollte auch ein Pixel sein
             nVal = 1;
     }
diff --git a/sw/source/filter/html/htmltabw.cxx b/sw/source/filter/html/htmltabw.cxx
index bc016c6..e55e7e6 100644
--- a/sw/source/filter/html/htmltabw.cxx
+++ b/sw/source/filter/html/htmltabw.cxx
@@ -716,11 +716,11 @@ void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
 
     // CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellpadding).
-        append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellPadding)));
+        append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellPadding,false)));
 
     // CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
     sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing).
-        append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellSpacing)));
+        append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellSpacing,false)));
 
     rWrt.Strm() << sOut.makeStringAndClear().getStr();
 
@@ -792,7 +792,7 @@ void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
             if( bRel )
                 sOutStr.append(static_cast<sal_Int32>(nWidth)).append('*');
             else
-                sOutStr.append(static_cast<sal_Int32>(rWrt.ToPixel(nWidth)));
+                sOutStr.append(static_cast<sal_Int32>(rWrt.ToPixel(nWidth,false)));
             sOutStr.append('>');
             rWrt.Strm() << sOutStr.makeStringAndClear().getStr();
 
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index a7aa3b7..66f368d 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -490,7 +490,7 @@ public:
     SwPaM* GetEndPaM() { return pOrigPam; }
     void SetEndPaM( SwPaM* pPam ) { pOrigPam = pPam; }
 
-    sal_uInt32 ToPixel( sal_uInt32 nVal ) const;
+    sal_uInt32 ToPixel( sal_uInt32 nVal, const bool bVert ) const;
 
     sal_uInt16 GuessFrmType( const SwFrmFmt& rFrmFmt,
                          const SdrObject*& rpStrObj );
commit 49019082c5c10be1158a6d8a43c10f4be2eb3642
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Thu Aug 29 10:06:14 2013 +0200

    Use the equivalent GetScaledWidth()
    
    Change-Id: I621f9ad1a7f1aa47450da86d3462daec4e8fe124

diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index 9930a82..c107939 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -2111,9 +2111,7 @@ Writer& OutHTML_SwTxtNode( Writer& rWrt, const SwCntntNode& rNode )
             const editeng::SvxBorderLine* pBorderLine = pBoxItem->GetBottom();
             if( pBorderLine )
             {
-                sal_uInt16 nWidth = pBorderLine->GetOutWidth() +
-                                pBorderLine->GetInWidth() +
-                                pBorderLine->GetDistance();
+                sal_uInt16 nWidth = pBorderLine->GetScaledWidth();
                 sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_size)
                     .append('=');
                 rWrt.Strm() << sOut.makeStringAndClear().getStr();
commit bf98269524920077547e1b85aac1d593fc49fd16
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sun Sep 8 10:32:52 2013 +0200

    Update attribute table of html filter
    
    If these lists are not updated with new hintids,
    it can break the filters.
    
    Change-Id: I5f5408679cbfbf0922d7926de16122c0d21fc5e3

diff --git a/sw/source/filter/html/css1atr.cxx b/sw/source/filter/html/css1atr.cxx
index 4fae564..03fde66 100644
--- a/sw/source/filter/html/css1atr.cxx
+++ b/sw/source/filter/html/css1atr.cxx
@@ -3724,13 +3724,15 @@ SwAttrFnTab aCSS1AttrFnTab = {
 /* RES_COLUMNBALANCE */             0,
 /* RES_FRAMEDIR */                  OutCSS1_SvxFrameDirection,
 /* RES_HEADER_FOOTER_EAT_SPACING */ 0,
-/* RES_FRMATR_DUMMY9 */             0, // Dummy:
+/* RES_ROW_SPLIT */                 0,
 /* RES_FOLLOW_TEXT_FLOW */          0,
+/* RES_COLLAPSING_BORDERS */        0,
 /* RES_WRAP_INFLUENCE_ON_OBJPOS */  0,
-/* RES_FRMATR_DUMMY2 */             0, // Dummy:
-/* RES_AUTO_STYLE */                0, // Dummy:
-/* RES_FRMATR_DUMMY4 */             0, // Dummy:
-/* RES_FRMATR_DUMMY5 */             0, // Dummy:
+/* RES_AUTO_STYLE */                0,
+/* RES_FRMATR_STYLE_NAME */         0,
+/* RES_FRMATR_CONDITIONAL_STYLE_NAME */ 0,
+/* RES_FILL_STYLE */                0,
+/* RES_FILL_GRADIENT */             0,
 
 /* RES_GRFATR_MIRRORGRF */          0,
 /* RES_GRFATR_CROPGRF   */          0,
diff --git a/sw/source/filter/html/htmlatr.cxx b/sw/source/filter/html/htmlatr.cxx
index f2b7615..9930a82 100644
--- a/sw/source/filter/html/htmlatr.cxx
+++ b/sw/source/filter/html/htmlatr.cxx
@@ -3268,6 +3268,9 @@ SwAttrFnTab aHTMLAttrFnTab = {
 /* RES_PARATR_VERTALIGN */          0, // new
 /* RES_PARATR_SNAPTOGRID*/          0, // new
 /* RES_PARATR_CONNECT_TO_BORDER */  0, // new
+/* RES_PARATR_OUTLINELEVEL */       0,
+/* RES_PARATR_RSID */               0,
+/* RES_PARATR_GRABBAG */            0,
 
 /* RES_PARATR_LIST_ID */            0, // new
 /* RES_PARATR_LIST_LEVEL */         0, // new
@@ -3301,21 +3304,23 @@ SwAttrFnTab aHTMLAttrFnTab = {
 /* RES_URL */                       0,
 /* RES_EDIT_IN_READONLY */          0,
 /* RES_LAYOUT_SPLIT */              0,
-/* RES_FRMATR_DUMMY1 */             0, // Dummy:
-/* RES_FRMATR_DUMMY2 */             0, // Dummy:
-/* RES_AUTO_STYLE */                0, // Dummy:
-/* RES_FRMATR_DUMMY4 */             0, // Dummy:
-/* RES_FRMATR_DUMMY5 */             0, // Dummy:
-/* RES_FRMATR_DUMMY6 */             0, // Dummy:
-/* RES_FRMATR_DUMMY7 */             0, // Dummy:
-/* RES_FRMATR_DUMMY8 */             0, // Dummy:
-/* RES_FRMATR_DUMMY9 */             0, // Dummy:
+/* RES_CHAIN */                     0,
+/* RES_TEXTGRID */                  0,
+/* RES_LINENUMBER */                0,
+/* RES_FTN_AT_TXTEND */             0,
+/* RES_END_AT_TXTEND */             0,
+/* RES_COLUMNBALANCE */             0,
+/* RES_FRAMEDIR */                  0,
+/* RES_HEADER_FOOTER_EAT_SPACING */ 0,
+/* RES_ROW_SPLIT */                 0,
 /* RES_FOLLOW_TEXT_FLOW */          0,
+/* RES_COLLAPSING_BORDERS */        0,
 /* RES_WRAP_INFLUENCE_ON_OBJPOS */  0,
-/* RES_FRMATR_DUMMY2 */             0, // Dummy:
-/* RES_AUTO_STYLE */                0, // Dummy:
-/* RES_FRMATR_DUMMY4 */             0, // Dummy:
-/* RES_FRMATR_DUMMY5 */             0, // Dummy:
+/* RES_AUTO_STYLE */                0,
+/* RES_FRMATR_STYLE_NAME */         0,
+/* RES_FRMATR_CONDITIONAL_STYLE_NAME */ 0,
+/* RES_FILL_STYLE */                0,
+/* RES_FILL_GRADIENT */             0,
 
 /* RES_GRFATR_MIRRORGRF */          0,
 /* RES_GRFATR_CROPGRF   */          0,
commit 58e4ff203e8f2703ab9433a3f49861ab306c8e4b
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Thu Aug 29 08:27:54 2013 +0200

    Paint character border for tabulator
    
    It seems tab portion is not a text portion so
    we have to move text portion join members to
    line portion.
    Avoid painting border for tabulator after numbering
    portion.
    
    Change-Id: Ic773dd14a8e90fd68980c5a0220c6ac14da0a693

diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 75085e1..ece87be 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1185,7 +1185,7 @@ void SwTxtPaintInfo::DrawBackBrush( const SwLinePortion &rPor ) const
     }
 }
 
-void SwTxtPaintInfo::DrawBorder( const SwTxtPortion &rPor ) const
+void SwTxtPaintInfo::DrawBorder( const SwLinePortion &rPor ) const
 {
     SwRect aDrawArea;
     CalcRect( rPor, &aDrawArea );
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index 544f56f..1396c7a 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -440,7 +440,7 @@ public:
     void DrawViewOpt( const SwLinePortion &rPor, const MSHORT nWhich ) const;
     void DrawBackBrush( const SwLinePortion &rPor ) const;
 
-    void DrawBorder( const SwTxtPortion &rPor ) const;
+    void DrawBorder( const SwLinePortion &rPor ) const;
 
     void DrawCheckBox( const SwFieldFormPortion &rPor, bool checked) const;
 
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 8b1aba8..e524c5e 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -945,8 +945,7 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
                                     nX -= pCurrPart->GetFont().GetRightBorderSpace();
                                 }
                             }
-                            else if( pPor->InTxtGrp() &&
-                                     !static_cast<const SwTxtPortion*>(pPor)->GetJoinBorderWithNext())
+                            else if( !pPor->GetJoinBorderWithNext())
                             {
                                 nX -= GetInfo().GetFont()->GetRightBorderSpace();
                             }
@@ -1664,7 +1663,7 @@ xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
                     nX = std::max(0, nX - nSumBorderWidth);
                 }
                 // Shift the offset with the left border width
-                else if( !static_cast<const SwTxtPortion*>(pPor)->GetJoinBorderWithPrev() )
+                else if( !pPor->GetJoinBorderWithPrev() )
                 {
                     nX = std::max(0, nX - GetInfo().GetFont()->GetLeftBorderSpace());
                 }
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index ef2cbc5..6408d5d 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -707,8 +707,8 @@ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
 
         rInf.SetFull( bFull );
 
-        if( pPor->InTxtGrp() && !pPor->IsDropPortion() )
-            MergeCharacterBorder(*static_cast<SwTxtPortion*>(pPor), rInf);
+        if( !pPor->IsDropPortion() )
+            MergeCharacterBorder(*pPor, rInf);
 
         // Restportions from fields with multiple lines don't yet have the right ascent
         if ( !pPor->GetLen() && !pPor->IsFlyPortion()
@@ -2631,20 +2631,19 @@ void SwTxtFormatter::MergeCharacterBorder( SwDropPortion& rPortion )
     }
 }
 
-void SwTxtFormatter::MergeCharacterBorder( SwTxtPortion& rPortion, SwTxtFormatInfo& rInf )
+void SwTxtFormatter::MergeCharacterBorder( SwLinePortion& rPortion, SwTxtFormatInfo& rInf )
 {
-
     const SwFont aCurFont = *rInf.GetFont();
     if( aCurFont.HasBorder() )
     {
         // The current portion isn't inserted into the portion chain yet, so the info's
         // last portion will be the previous one
-        if( rInf.GetLast() && rInf.GetLast()->InTxtGrp() &&
-            rInf.GetLast() != &rPortion && // For para portion (special case)
-            static_cast<SwTxtPortion*>(rInf.GetLast())->GetJoinBorderWithNext())
+        if( rInf.GetLast() && rInf.GetLast() != &rPortion && // For para portion (special case)
+            rInf.GetLast()->GetJoinBorderWithNext())
         {
             rPortion.SetJoinBorderWithPrev(true);
-            rPortion.Width(rPortion.Width() - aCurFont.GetLeftBorderSpace());
+            if( rPortion.InTxtGrp() && rPortion.Width() > aCurFont.GetLeftBorderSpace() )
+                rPortion.Width(rPortion.Width() - aCurFont.GetLeftBorderSpace());
         }
         else
         {
@@ -2655,14 +2654,15 @@ void SwTxtFormatter::MergeCharacterBorder( SwTxtPortion& rPortion, SwTxtFormatIn
         // Get next portion's font
         bool bSeek = false;
         if( !rInf.IsFull() // Last portion of the line (in case of line break)
-            && rInf.GetIdx() + rInf.GetLen() != rInf.GetTxt().getLength() ) // Last portion of the paragraph
-            bSeek = Seek(rInf.GetIdx() + rInf.GetLen());
+            && rInf.GetIdx() + rPortion.GetLen() != rInf.GetTxt().getLength() ) // Last portion of the paragraph
+            bSeek = Seek(rInf.GetIdx() + rPortion.GetLen());
 
         // If next portion has the same font then merge
         if( bSeek && GetFnt()->HasBorder() && ::lcl_HasSameBorder(aCurFont, *GetFnt()) )
         {
             rPortion.SetJoinBorderWithNext(true);
-            rPortion.Width(rPortion.Width() - aCurFont.GetRightBorderSpace());
+            if( rPortion.InTxtGrp() && rPortion.Width() > aCurFont.GetRightBorderSpace() )
+                rPortion.Width(rPortion.Width() - aCurFont.GetRightBorderSpace());
         }
         // If this is the last portion of the merge group than make the real height merge
         else
diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx
index 786276b..d463317 100644
--- a/sw/source/core/text/itrform2.hxx
+++ b/sw/source/core/text/itrform2.hxx
@@ -46,7 +46,7 @@ class SwTxtFormatter : public SwTxtPainter
     sal_Bool bTruncLines : 1; // Flag for extending the repaint rect, if needed
     sal_Bool bUnclipped : 1; // Flag whether repaint is larger than the fixed line height
     sal_uInt16 m_nHintEndIndex; // HACK for TryNewNoLengthPortion
-    SwTxtPortion* m_pFirstOfBorderMerge; // The first text portion of a joined border (during portion bulding)
+    SwLinePortion* m_pFirstOfBorderMerge; // The first text portion of a joined border (during portion bulding)
 
     SwLinePortion *NewPortion( SwTxtFormatInfo &rInf );
     SwTxtPortion  *NewTxtPortion( SwTxtFormatInfo &rInf );
@@ -231,14 +231,14 @@ public:
     void MergeCharacterBorder( SwDropPortion& rPortion );
 
     /**
-     * Merge border of the text portion with setting the text portions
+     * Merge border of the line portion with setting the portion's
      * m_bJoinBorderWidthNext and m_bJoinBorderWidthPrev members and
-     * changing the size (width, height and ascent) of the text portion
+     * changing the size (width, height and ascent) of the portion
      * to get a merged border.
-     * @param   rPortion    text portion for merge
+     * @param   rPortion    portion for merge
      * @param   rInf        contain information
     **/
-    void MergeCharacterBorder( SwTxtPortion& rPortion, SwTxtFormatInfo& rInf );
+    void MergeCharacterBorder( SwLinePortion& rPortion, SwTxtFormatInfo& rInf );
 };
 
 
diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx
index 586f037..adbc4ac 100644
--- a/sw/source/core/text/porlin.cxx
+++ b/sw/source/core/text/porlin.cxx
@@ -76,7 +76,9 @@ KSHORT SwLinePortion::GetViewWidth( const SwTxtSizeInfo & ) const
 SwLinePortion::SwLinePortion( ) :
     pPortion( NULL ),
     nLineLength( 0 ),
-    nAscent( 0 )
+    nAscent( 0 ),
+    m_bJoinBorderWithPrev(false),
+    m_bJoinBorderWithNext(false)
 {
 }
 
diff --git a/sw/source/core/text/porlin.hxx b/sw/source/core/text/porlin.hxx
index 68b93d7..fb8065c 100644
--- a/sw/source/core/text/porlin.hxx
+++ b/sw/source/core/text/porlin.hxx
@@ -72,6 +72,8 @@ protected:
     SwLinePortion();
 private:
     MSHORT nWhichPor;       // Who's who?
+    bool m_bJoinBorderWithPrev;
+    bool m_bJoinBorderWithNext;
 
     void _Truncate();
 
@@ -186,6 +188,11 @@ public:
     // Accessibility: pass information about this portion to the PortionHandler
     virtual void HandlePortion( SwPortionHandler& rPH ) const;
 
+    bool GetJoinBorderWithPrev() const { return m_bJoinBorderWithPrev; }
+    bool GetJoinBorderWithNext() const { return m_bJoinBorderWithNext; }
+    void SetJoinBorderWithPrev( const bool bJoinPrev ) { m_bJoinBorderWithPrev = bJoinPrev; }
+    void SetJoinBorderWithNext( const bool bJoinNext ) { m_bJoinBorderWithNext = bJoinNext; }
+
     OUTPUT_OPERATOR
 };
 
@@ -200,6 +207,8 @@ inline SwLinePortion &SwLinePortion::operator=(const SwLinePortion &rPortion)
     nLineLength = rPortion.nLineLength;
     nAscent = rPortion.nAscent;
     nWhichPor = rPortion.nWhichPor;
+    m_bJoinBorderWithPrev = rPortion.m_bJoinBorderWithPrev;
+    m_bJoinBorderWithNext = rPortion.m_bJoinBorderWithNext;
     return *this;
 }
 
@@ -216,7 +225,9 @@ inline SwLinePortion::SwLinePortion(const SwLinePortion &rPortion) :
     pPortion( 0 ),
     nLineLength( rPortion.nLineLength ),
     nAscent( rPortion.nAscent ),
-    nWhichPor( rPortion.nWhichPor )
+    nWhichPor( rPortion.nWhichPor ),
+    m_bJoinBorderWithPrev( rPortion.m_bJoinBorderWithPrev ),
+    m_bJoinBorderWithNext( rPortion.m_bJoinBorderWithNext )
 {
 }
 
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index d41649b..31c93f1 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -219,12 +219,6 @@ SwTxtPortion::SwTxtPortion( const SwLinePortion &rPortion )
   : SwLinePortion( rPortion )
 {
     SetWhichPor( POR_TXT );
-    if( rPortion.InTxtGrp() )
-    {
-        const SwTxtPortion& rPor = static_cast<const SwTxtPortion&>(rPortion);
-        m_bJoinBorderWithPrev = rPor.m_bJoinBorderWithPrev;
-        m_bJoinBorderWithNext = rPor.m_bJoinBorderWithNext;
-    }
 }
 
 /*************************************************************************
@@ -544,9 +538,9 @@ xub_StrLen SwTxtPortion::GetCrsrOfst( const KSHORT nOfst ) const
 SwPosSize SwTxtPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
 {
     SwPosSize aSize = rInf.GetTxtSize();
-    if( !m_bJoinBorderWithPrev )
+    if( !GetJoinBorderWithPrev() )
         aSize.Width(aSize.Width() + rInf.GetFont()->GetLeftBorderSpace() );
-    if( !m_bJoinBorderWithNext )
+    if( !GetJoinBorderWithNext() )
         aSize.Width(aSize.Width() + rInf.GetFont()->GetRightBorderSpace() );
 
     aSize.Height(aSize.Height() +
diff --git a/sw/source/core/text/portxt.hxx b/sw/source/core/text/portxt.hxx
index 4c029a3..d201c74 100644
--- a/sw/source/core/text/portxt.hxx
+++ b/sw/source/core/text/portxt.hxx
@@ -36,11 +36,8 @@ class SwTxtPortion : public SwLinePortion
     void BreakUnderflow( SwTxtFormatInfo &rInf );
     sal_Bool _Format( SwTxtFormatInfo &rInf );
 
-    bool m_bJoinBorderWithPrev;
-    bool m_bJoinBorderWithNext;
-
 public:
-    inline SwTxtPortion(): m_bJoinBorderWithPrev(false), m_bJoinBorderWithNext(false) { SetWhichPor( POR_TXT ); }
+    inline SwTxtPortion(){ SetWhichPor( POR_TXT ); }
     SwTxtPortion( const SwLinePortion &rPortion );

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list