[Libreoffice-commits] core.git: 10 commits - cui/source include/xmloff offapi/com qadevOOo/objdsc sw/qa sw/source xmloff/source

Zolnai Tamás zolnaitamas2000 at gmail.com
Sun Aug 18 00:50:25 PDT 2013


 cui/source/tabpages/border.cxx                                     |    2 
 include/xmloff/txtprmap.hxx                                        |   18 
 offapi/com/sun/star/style/CharacterProperties.idl                  |   36 -
 qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXCellRange.csv       |    9 
 qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextCursor.csv      |    9 
 qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextRange.csv       |    9 
 qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextTableCursor.csv |    9 
 qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextViewCursor.csv  |    9 
 qadevOOo/objdsc/sw/com.sun.star.style.CharacterStyle.csv           |    9 
 sw/qa/extras/inc/swmodeltestbase.hxx                               |   27 
 sw/qa/extras/odfexport/data/charborder.odt                         |binary
 sw/qa/extras/odfexport/data/fdo43807.odt                           |binary
 sw/qa/extras/odfexport/odfexport.cxx                               |  187 +++++
 sw/source/core/inc/swfont.hxx                                      |   27 
 sw/source/core/text/inftxt.cxx                                     |   35 -
 sw/source/core/text/inftxt.hxx                                     |    2 
 sw/source/core/text/itratr.cxx                                     |   72 --
 sw/source/core/text/itratr.hxx                                     |   20 
 sw/source/core/text/itrcrsr.cxx                                    |   14 
 sw/source/core/text/itrform2.cxx                                   |  139 ++++
 sw/source/core/text/itrform2.hxx                                   |   19 
 sw/source/core/text/porexp.cxx                                     |    8 
 sw/source/core/text/portxt.cxx                                     |   29 
 sw/source/core/text/portxt.hxx                                     |   11 
 sw/source/core/text/txtdrop.cxx                                    |   25 
 xmloff/source/text/txtexppr.cxx                                    |  314 ++++++----
 xmloff/source/text/txtimp.cxx                                      |    2 
 xmloff/source/text/txtimppr.cxx                                    |  163 +++--
 xmloff/source/text/txtprmap.cxx                                    |   40 +
 29 files changed, 954 insertions(+), 290 deletions(-)

New commits:
commit d22964a936919faea3ae9734d253ddfd05c01bc8
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sat Aug 17 18:32:23 2013 +0200

    Paint drop cap background only once
    
    Painting default background is unecessary when
    there is a user defined background.
    
    Change-Id: I6564f403f0f7769b5460b07d5f3947be08c0dbf6

diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
index 500b5e0..db5e3ca 100644
--- a/sw/source/core/text/txtdrop.cxx
+++ b/sw/source/core/text/txtdrop.cxx
@@ -273,10 +273,6 @@ bool SwTxtNode::GetDropSize(int& rFontHeight, int& rDropHeight, int& rDropDescen
 
 void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const
 {
-    if ( rInf.OnWin() &&
-        !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings()    )
-        rInf.DrawBackground( *this );
-
     OSL_ENSURE( nDropHeight && pPart && nLines != 1, "Drop Portion painted twice" );
 
     const SwDropPortionPart* pCurrPart = GetPart();
@@ -299,6 +295,13 @@ void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const
         ((SwTxtPaintInfo&)rInf).SetLen( pCurrPart->GetLen() );
         SwFontSave aFontSave( rInf, &pCurrPart->GetFont() );
 
+        if ( rInf.OnWin() &&
+            !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && SwViewOption::IsFieldShadings() &&
+            (!pCurrPart->GetFont().GetBackColor() || *pCurrPart->GetFont().GetBackColor() == Color(COL_TRANSPARENT)) )
+        {
+            rInf.DrawBackground( *this );
+        }
+
         SwTxtPortion::Paint( rInf );
 
         ((SwTxtPaintInfo&)rInf).SetIdx( rInf.GetIdx() + pCurrPart->GetLen() );
commit cc7a94cfa8ec901627e8f9abf28c724923deb520
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Sat Aug 17 17:40:15 2013 +0200

    Reduce text background painting rect with border
    
    Change-Id: I48fa36aafa17b9660c65ed713ae2faf9c0c4d056

diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx
index 82acffd..d7a6eb5 100644
--- a/sw/source/core/inc/swfont.hxx
+++ b/sw/source/core/inc/swfont.hxx
@@ -396,7 +396,12 @@ public:
     sal_uInt16 GetRightBorderDist() const { return m_nRightBorderDist; }
     sal_uInt16 GetLeftBorderDist() const { return m_nLeftBorderDist; }
 
-    // Return with the border width plus spacing
+    sal_uInt16 GetTopBorderWidth() const;
+    sal_uInt16 GetBottomBorderWidth() const;
+    sal_uInt16 GetRightBorderWidth() const;
+    sal_uInt16 GetLeftBorderWidth() const;
+
+    // Return the border width plus spacing
     sal_uInt16 GetTopBorderSpace() const;
     sal_uInt16 GetBottomBorderSpace() const;
     sal_uInt16 GetRightBorderSpace() const;
@@ -881,6 +886,26 @@ inline void SwFont::SetLeftBorderDist( const sal_uInt16 nLeftDist )
     aSub[SW_LATIN].pMagic = aSub[SW_CJK].pMagic = aSub[SW_CTL].pMagic = 0;
 }
 
+inline sal_uInt16 SwFont::GetTopBorderWidth() const
+{
+    return m_aTopBorder ? m_aTopBorder.get().GetScaledWidth() : 0;
+}
+
+inline sal_uInt16 SwFont::GetBottomBorderWidth() const
+{
+    return m_aBottomBorder ? m_aBottomBorder.get().GetScaledWidth() : 0;
+}
+
+inline sal_uInt16 SwFont::GetRightBorderWidth() const
+{
+    return m_aRightBorder ? m_aRightBorder.get().GetScaledWidth() : 0;
+}
+
+inline sal_uInt16 SwFont::GetLeftBorderWidth() const
+{
+    return m_aLeftBorder ? m_aLeftBorder.get().GetScaledWidth() : 0;
+}
+
 inline sal_uInt16 SwFont::GetTopBorderSpace() const
 {
     if( m_aTopBorder )
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index aff0ec9..069cf8f 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -748,9 +748,23 @@ void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPo
 }
 
 void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor,
-                               SwRect* pRect, SwRect* pIntersect ) const
+                               SwRect* pRect, SwRect* pIntersect,
+                               const bool bInsideBorder ) const
 {
-    Size aSize( rPor.Width(), rPor.Height() );
+    KSHORT nPorHeight = rPor.Height();
+    KSHORT nPorAscent = rPor.GetAscent();
+    KSHORT nPorWidth = rPor.Width();
+    SwTwips nX = X();
+
+    if( bInsideBorder )
+    {
+        nPorAscent -= GetFont()->GetTopBorderWidth();
+        nPorHeight -= GetFont()->GetTopBorderWidth() + GetFont()->GetBottomBorderWidth();
+        nPorWidth -= GetFont()->GetRightBorderWidth() + GetFont()->GetLeftBorderWidth();
+        nX += GetFont()->GetLeftBorderWidth();
+    }
+
+    Size aSize( nPorWidth, nPorHeight );
     if( rPor.IsHangingPortion() )
         aSize.Width() = ((SwHangingPortion&)rPor).GetInnerWidth();
     if( rPor.InSpaceGrp() && GetSpaceAdd() )
@@ -770,23 +784,23 @@ void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor,
         aSize.Height() = nTmp;
         if ( 1 == GetDirection() )
         {
-            aPoint.A() = X() - rPor.GetAscent();
+            aPoint.A() = nX - nPorAscent;
             aPoint.B() = Y() - aSize.Height();
         }
         else
         {
-            aPoint.A() = X() - rPor.Height() + rPor.GetAscent();
+            aPoint.A() = nX - nPorHeight + nPorAscent;
             aPoint.B() = Y();
         }
     }
     else
     {
-        aPoint.A() = X();
+        aPoint.A() = nX;
         //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
         if ( GetTxtFrm()->IsVertLR() )
-            aPoint.B() = Y() - rPor.Height() + rPor.GetAscent();
+            aPoint.B() = Y() - nPorHeight + nPorAscent;
         else
-            aPoint.B() = Y() - rPor.GetAscent();
+            aPoint.B() = Y() - nPorAscent;
     }
 
     // Adjust x coordinate if we are inside a bidi portion
@@ -1124,7 +1138,7 @@ void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
     OSL_ENSURE( OnWin(), "SwTxtPaintInfo::DrawBackground: printer pollution ?" );
 
     SwRect aIntersect;
-    CalcRect( rPor, 0, &aIntersect );
+    CalcRect( rPor, 0, &aIntersect, true );
 
     if ( aIntersect.HasArea() )
     {
@@ -1209,7 +1223,7 @@ void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
     OSL_ENSURE( m_pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
 
     SwRect aIntersect;
-    CalcRect( rPor, 0, &aIntersect );
+    CalcRect( rPor, 0, &aIntersect, true );
 
     if ( aIntersect.HasArea() )
     {
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index c9d5d10..e22ec7a 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -449,7 +449,7 @@ public:
     inline void NotifyURL( const SwLinePortion &rPor ) const
         { if( URLNotify() ) _NotifyURL( rPor ); }
 
-    void CalcRect( const SwLinePortion& rPor, SwRect* pRect, SwRect* pIntersect = 0 ) const;
+    void CalcRect( const SwLinePortion& rPor, SwRect* pRect, SwRect* pIntersect = 0, const bool bInsideBorder = false ) const;
 
     inline SwTwips GetPaintOfst() const;
     inline void SetPaintOfst( const SwTwips nNew );
commit d055f7eba0ad624ff1642a0f1421aa1fbfbbe9c5
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Fri Aug 16 14:46:10 2013 +0200

    Update comment in border.cxx
    
    Change-Id: Ica1adc71f3269a88bcf478931cee56dde565898c

diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
index cf10d12..bceaed1 100644
--- a/cui/source/tabpages/border.cxx
+++ b/cui/source/tabpages/border.cxx
@@ -1075,7 +1075,7 @@ IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl)
         // for tables everything is allowed
         sal_uInt16 nValid = VALID_TOP|VALID_BOTTOM|VALID_LEFT|VALID_RIGHT;
 
-        // for other objects (paragraph, page, frame) the edit is disabled, if there's no border set
+        // for other objects (paragraph, page, frame, character) the edit is disabled, if there's no border set
         if(!(nSWMode & SW_BORDER_MODE_TABLE))
         {
             if(bLineSet)
commit c956bde226ffd646ab6ca0c72d50a375ae52edb3
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Fri Aug 16 14:45:32 2013 +0200

    Make drop caps border a bit more robust
    
    Decrease the minimum size of the drop caps letters to 0
    and handle the case when padding is too big.
    
    Change-Id: I10f76ddffe9d19f82afbe3226ebe3aa8ba70da89

diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
index 49337ba..500b5e0 100644
--- a/sw/source/core/text/txtdrop.cxx
+++ b/sw/source/core/text/txtdrop.cxx
@@ -802,7 +802,7 @@ void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf )
 
         // for growing controll
         long nMax = KSHRT_MAX;
-        long nMin = nFactor / 2;
+        long nMin = 0;
 #if OSL_DEBUG_LEVEL > 1
         long nGrow = 0;
 #endif
@@ -889,6 +889,16 @@ void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf )
                 rFnt.SetProportion( nOldProp );
 
                 // Modify the bounding rectangle with the borders
+                // Robust: If the padding is so big as drop cap letter has no enough space than
+                // remove all padding.
+                if( rFnt.GetTopBorderSpace() + rFnt.GetBottomBorderSpace() >= nWishedHeight )
+                {
+                    rFnt.SetTopBorderDist(0);
+                    rFnt.SetBottomBorderDist(0);
+                    rFnt.SetRightBorderDist(0);
+                    rFnt.SetLeftBorderDist(0);
+                }
+
                 if( rFnt.GetTopBorder() )
                 {
                     aRect.setHeight(aRect.GetHeight() + rFnt.GetTopBorderSpace());
commit 835d9e0da9416c7e586766ad734f45d048886e0a
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Fri Aug 16 13:01:37 2013 +0200

    CharBrd 4.1: merge borders of text portions
    
    Revert
    0d9ddccd8810a81a6f4d737870969d0dcf367d23
    and
    66f3b17013c467b9e0a74497738c90173b7e7b4f
    
    Solve border merge on portions level.
    - Add new members to text portion called m_bJoinBorderWithPrev
    and m_bJoinBorderWithNext which indicate when to skip left or
    right border.
    - Use these members during formating, painting and cursor calculation.
    
    Change-Id: I24f1a848e266207b252a6cd157663edc47c51de6

diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 59bc524..aff0ec9 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -696,7 +696,8 @@ void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPo
 
     // Draw text next to the left border
     Point aFontPos(aPos);
-    if( m_pFnt->GetLeftBorder() )
+    if( m_pFnt->GetLeftBorder() && rPor.InTxtGrp() &&
+        !static_cast<const SwTxtPortion&>(rPor).GetJoinBorderWithPrev() )
     {
         const sal_uInt16 nLeftBorderSpace = m_pFnt->GetLeftBorderSpace();
         switch( m_pFnt->GetOrientation(GetTxtFrm()->IsVertical()) )
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index e674f60..347c196 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -122,12 +122,6 @@ SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPosition ) const
 
 sal_Bool SwAttrIter::SeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut )
 {
-    sal_Bool bRet = ImplSeekAndChgAttrIter(nNewPos, pOut);
-    return MergeCharBorder(false) || bRet;
-}
-
-sal_Bool SwAttrIter::ImplSeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut )
-{
     sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
     if ( pLastOut != pOut )
     {
@@ -160,13 +154,8 @@ sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
 /*************************************************************************
  *                        SwAttrIter::SeekStartAndChg()
  *************************************************************************/
-sal_Bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
-{
-    sal_Bool bRet = ImplSeekStartAndChgAttrIter( pOut, bParaFont );
-    return bParaFont ? bRet : MergeCharBorder(true) || bRet;
-}
 
-sal_Bool SwAttrIter::ImplSeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
+sal_Bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
 {
     if ( pRedln && pRedln->ExtOn() )
         pRedln->LeaveExtend( *pFnt, 0 );
@@ -277,7 +266,7 @@ sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
 
     if( pHints )
     {
-        if( !nNewPos || nNewPos < nPos || m_bPrevSeekRemBorder )
+        if( !nNewPos || nNewPos < nPos )
         {
             if( pRedln )
                 pRedln->Clear( NULL );
@@ -366,63 +355,6 @@ xub_StrLen SwAttrIter::GetNextAttr( ) const
     return nNext;
 }
 
-static bool lcl_HasMergeableBorder(const SwFont& rFirst, const SwFont& rSecond)
-{
-    return
-        rFirst.GetOrientation() == rSecond.GetOrientation() &&
-        rFirst.GetTopBorder() == rSecond.GetTopBorder() &&
-        rFirst.GetBottomBorder() == rSecond.GetBottomBorder() &&
-        rFirst.GetLeftBorder() == rSecond.GetLeftBorder() &&
-        rFirst.GetRightBorder() == rSecond.GetRightBorder();
-}
-
-bool SwAttrIter::MergeCharBorder( const bool bStart )
-{
-    const xub_StrLen nActPos = nPos;
-    bool bRemoveLeft = false;
-    bool bRemoveRight = false;
-    SwFont aTmpFont = *pFnt;
-    const sal_Int32 nTmpStart = nStartIndex;
-
-    // Check whether next neightbour has same border and height
-    if( aTmpFont.GetRightBorder() && pHints && nEndIndex < pHints->GetEndCount() )
-    {
-        ImplSeekAndChgAttrIter(GetNextAttr(), pLastOut);
-        if( aTmpFont.GetHeight(pShell, *pLastOut) == pFnt->GetHeight(pShell, *pLastOut) &&
-            lcl_HasMergeableBorder(aTmpFont, *pFnt) )
-        {
-            bRemoveRight = true;
-        }
-    }
-
-    // Check whether previous neightbour has same border and height
-    if( aTmpFont.GetLeftBorder() && nTmpStart > 0)
-    {
-        ImplSeekAndChgAttrIter(nActPos-1, pLastOut);
-        if( aTmpFont.GetHeight(pShell, *pLastOut) == pFnt->GetHeight(pShell, *pLastOut) &&
-            lcl_HasMergeableBorder(aTmpFont, *pFnt) )
-        {
-            bRemoveLeft = true;
-        }
-    }
-
-    // If the iterator changed its position, than we have to reset it.
-    if( nPos != nActPos )
-    {
-        if( bStart )
-            ImplSeekStartAndChgAttrIter(pLastOut, false);
-        else
-            ImplSeekAndChgAttrIter(nActPos, pLastOut);
-    }
-
-    if( bRemoveRight )
-        pFnt->SetRightBorder(0);
-    if( bRemoveLeft )
-        pFnt->SetLeftBorder(0);
-
-    return (m_bPrevSeekRemBorder = bRemoveLeft || bRemoveRight);
-}
-
 class SwMinMaxArgs
 {
 public:
diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx
index f315303..6b48dc1 100644
--- a/sw/source/core/text/itratr.hxx
+++ b/sw/source/core/text/itratr.hxx
@@ -60,8 +60,6 @@ private:
     const void* aMagicNo[ SW_SCRIPTS ];
     MSHORT aFntIdx[ SW_SCRIPTS ];
     const SwTxtNode* m_pTxtNode;
-    /// previous seek remove left/right border of the current font during merge character border
-    bool m_bPrevSeekRemBorder;
 
     void SeekFwd( const xub_StrLen nPos );
     inline void SetFnt( SwFont* pNew ) { pFnt = pNew; }
@@ -71,17 +69,15 @@ protected:
     void Rst( SwTxtAttr *pHt );
     void CtorInitAttrIter( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf, SwTxtFrm* pFrm = 0 );
     inline SwAttrIter(SwTxtNode* pTxtNode)
-        : pShell(0), pFnt(0), pHints(0), pAttrSet(0), pScriptInfo(0), pLastOut(0), nChgCnt(0), pRedln(0), nPropFont(0), m_pTxtNode(pTxtNode), m_bPrevSeekRemBorder(false) {
+        : pShell(0), pFnt(0), pHints(0), pAttrSet(0), pScriptInfo(0), pLastOut(0), nChgCnt(0), pRedln(0), nPropFont(0), m_pTxtNode(pTxtNode)
+        {
             aMagicNo[SW_LATIN] = aMagicNo[SW_CJK] = aMagicNo[SW_CTL] = NULL;
         }
 
-    /// Implementation of the considering public methods (to avoid recursion)
-    sal_Bool ImplSeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut );
-    sal_Bool ImplSeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont );
 public:
     // Constructor, destructor
     inline SwAttrIter( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf )
-        : pShell(0), pFnt(0), pHints(0), pScriptInfo(0), pLastOut(0), nChgCnt(0), pRedln(0),nPropFont(0), m_pTxtNode(&rTxtNode),m_bPrevSeekRemBorder(false)
+        : pShell(0), pFnt(0), pHints(0), pScriptInfo(0), pLastOut(0), nChgCnt(0), pRedln(0),nPropFont(0), m_pTxtNode(&rTxtNode)
         { CtorInitAttrIter( rTxtNode, rScrInf ); }
 
     virtual ~SwAttrIter();
@@ -102,16 +98,6 @@ public:
     sal_Bool SeekAndChgAttrIter( const xub_StrLen nPos, OutputDevice* pOut );
     sal_Bool SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont = sal_False );
 
-    /** Merge character border with removing left/right border of the font if the
-     *  the neighbours of the current position (nPos) has the same height
-     *  and same kind of border.
-     *  @param      bStart  true if it is called from SeekStartAndChgAttrIter
-     *                      false, otherwise
-     *  @return     true,   if font change (removing some of its borders)
-     *              false,  otherwise
-    **/
-    bool MergeCharBorder( const bool bStart );
-
     // Do we have an attribute change at all?
     inline sal_Bool HasHints() const { return 0 != pHints; }
 
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index d35e47b..0c3f62f 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -931,7 +931,7 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
                         if( aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() )
                         {
                             // Find the current drop portion part and use its right border
-                            if( pPor->IsDropPortion() )
+                            if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
                             {
                                 SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
                                 const SwDropPortionPart* pCurrPart = pDrop->GetPart();
@@ -945,7 +945,8 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
                                     nX -= pCurrPart->GetFont().GetRightBorderSpace();
                                 }
                             }
-                            else if(GetInfo().GetFont()->GetRightBorder())
+                            else if( GetInfo().GetFont()->GetRightBorder() && pPor->InTxtGrp() &&
+                                     !static_cast<const SwTxtPortion*>(pPor)->GetJoinBorderWithNext())
                             {
                                 nX -= GetInfo().GetFont()->GetRightBorderSpace();
                             }
@@ -1110,7 +1111,7 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst,
                 if ( pCMS->pSpecialPos )
                 {
                     // apply attributes to font
-                    SeekAndChgAttrIter( nOfst, aInf.GetOut() );
+                    Seek( nOfst );
                     lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor );
                 }
             }
@@ -1640,7 +1641,7 @@ xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
                                          pPor->GetLen() );
 
                 // Drop portion works like a multi portion, just its parts are not portions
-                if( pPor->IsDropPortion() )
+                if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
                 {
                     SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
                     const SwDropPortionPart* pCurrPart = pDrop->GetPart();
@@ -1663,8 +1664,11 @@ 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 (GetInfo().GetFont()->GetLeftBorder() )
+                else if ( GetInfo().GetFont()->GetLeftBorder() &&
+                          !static_cast<const SwTxtPortion*>(pPor)->GetJoinBorderWithPrev() )
+                {
                     nX = std::max(0, nX - GetInfo().GetFont()->GetLeftBorderSpace());
+                }
 
 
                 aDrawInf.SetOfst( nX );
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index fec3fdd..c7442e6 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -43,6 +43,7 @@
 #include <porfld.hxx>       // SwNumberPortion for CalcAscent()
 #include <porftn.hxx>       // SwFtnPortion
 #include <porhyph.hxx>
+#include <pordrop.hxx>
 #include <guess.hxx>
 #include <blink.hxx>        // pBlink
 #include <ftnfrm.hxx>       // WhichFirstPortion() -> move it
@@ -74,6 +75,9 @@ namespace {
                                     const std::vector<long> &rFlyStarts );
     //! Determine if we need to build hidden portions
     static bool lcl_BuildHiddenPortion( const SwTxtSizeInfo& rInf, xub_StrLen &rPos );
+
+    // Check whether the two font has the same border
+    static bool lcl_HasSameBorder(const SwFont& rFirst, const SwFont& rSecond);
 }
 
 inline void ClearFly( SwTxtFormatInfo &rInf )
@@ -102,6 +106,7 @@ void SwTxtFormatter::CtorInitTxtFormatter( SwTxtFrm *pNewFrm, SwTxtFormatInfo *p
     nLeftScanIdx = STRING_LEN;
     nRightScanIdx = 0;
     m_nHintEndIndex = 0;
+    m_pFirstOfBorderMerge = 0;
 
     if( nStart > GetInfo().GetTxt().getLength() )
     {
@@ -546,6 +551,9 @@ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
                 InsertPortion( rInf, pGridKernPortion );
         }
 
+        if( pPor->IsDropPortion() )
+            MergeCharacterBorder(*static_cast<SwDropPortion*>(pPor));
+
         // the multi-portion has it's own format function
         if( pPor->IsMultiPortion() && ( !pMulti || pMulti->IsBidi() ) )
             bFull = BuildMultiPortion( rInf, *((SwMultiPortion*)pPor) );
@@ -699,6 +707,9 @@ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf )
 
         rInf.SetFull( bFull );
 
+        if( pPor->InTxtGrp() && !pPor->IsDropPortion() )
+            MergeCharacterBorder(*static_cast<SwTxtPortion*>(pPor), rInf);
+
         // Restportions from fields with multiple lines don't yet have the right ascent
         if ( !pPor->GetLen() && !pPor->IsFlyPortion()
             && !pPor->IsGrfNumPortion() && ! pPor->InNumberGrp()
@@ -2588,6 +2599,120 @@ SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf,
     return pRet;
 }
 
+/* Drop portion is a special case, because it has parts which aren't portions
+   but we have handle them just like portions */
+void SwTxtFormatter::MergeCharacterBorder( SwDropPortion& rPortion )
+{
+    if( rPortion.GetLines() > 1 )
+    {
+        SwDropPortionPart* pCurrPart = rPortion.GetPart();
+        bool bJoinWithPrev = false;
+        while( pCurrPart )
+        {
+            const bool bJoinWithNext =
+                pCurrPart->GetFollow() &&
+                ::lcl_HasSameBorder(pCurrPart->GetFont(), pCurrPart->GetFollow()->GetFont());
+
+            if( bJoinWithPrev )
+                pCurrPart->GetFont().SetLeftBorder(0);
+
+            if( bJoinWithNext )
+            {
+                pCurrPart->GetFont().SetRightBorder(0);
+                bJoinWithPrev = true;
+            }
+            else
+            {
+                bJoinWithPrev = false;
+            }
+            pCurrPart = pCurrPart->GetFollow();
+        }
+    }
+}
+
+void SwTxtFormatter::MergeCharacterBorder( SwTxtPortion& 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())
+        {
+            rPortion.SetJoinBorderWithPrev(true);
+            rPortion.Width(rPortion.Width() - aCurFont.GetLeftBorderSpace());
+        }
+        else
+        {
+            rPortion.SetJoinBorderWithPrev(false);
+            m_pFirstOfBorderMerge = &rPortion;
+        }
+
+        // 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());
+
+        // 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 this is the last portion of the merge group than make the real height merge
+        else
+        {
+            rPortion.SetJoinBorderWithNext(false);
+            if( m_pFirstOfBorderMerge != &rPortion )
+            {
+                // Calculate maximum height and ascent
+                SwLinePortion* pActPor = m_pFirstOfBorderMerge;
+                sal_uInt16 nMaxAscent = 0;
+                sal_uInt16 nMaxHeight = 0;
+                bool bReachCurrent = false;
+                while( pActPor )
+                {
+                    if( nMaxHeight < pActPor->Height() )
+                        nMaxHeight = pActPor->Height();
+                    if( nMaxAscent < pActPor->GetAscent() )
+                        nMaxAscent = pActPor->GetAscent();
+
+                    pActPor = pActPor->GetPortion();
+                    if( !pActPor && !bReachCurrent )
+                    {
+                        pActPor = &rPortion;
+                        bReachCurrent = true;
+                    }
+                }
+
+                // Change all portion's height and ascent
+                pActPor = m_pFirstOfBorderMerge;
+                bReachCurrent = false;
+                while( pActPor )
+                {
+                    if( nMaxHeight > pActPor->Height() )
+                        pActPor->Height(nMaxHeight);
+                    if( nMaxAscent > pActPor->GetAscent() )
+                        pActPor->SetAscent(nMaxAscent);
+
+                    pActPor = pActPor->GetPortion();
+                    if( !pActPor && !bReachCurrent )
+                    {
+                        pActPor = &rPortion;
+                        bReachCurrent = true;
+                    }
+                }
+                m_pFirstOfBorderMerge = 0;
+            }
+        }
+        Seek(rInf.GetIdx());
+    }
+}
+
 namespace {
     /*************************************************************************
     *                      ::CalcOptRepaint()
@@ -2729,6 +2854,20 @@ namespace {
         return false;
     }
 
+    bool lcl_HasSameBorder(const SwFont& rFirst, const SwFont& rSecond)
+    {
+        return
+            rFirst.GetTopBorder() == rSecond.GetTopBorder() &&
+            rFirst.GetBottomBorder() == rSecond.GetBottomBorder() &&
+            rFirst.GetLeftBorder() == rSecond.GetLeftBorder() &&
+            rFirst.GetRightBorder() == rSecond.GetRightBorder() &&
+            rFirst.GetTopBorderDist() == rSecond.GetTopBorderDist() &&
+            rFirst.GetBottomBorderDist() == rSecond.GetBottomBorderDist() &&
+            rFirst.GetLeftBorderDist() == rSecond.GetLeftBorderDist() &&
+            rFirst.GetRightBorderDist() == rSecond.GetRightBorderDist() &&
+            rFirst.GetOrientation() == rSecond.GetOrientation();
+    }
+
 } //end unnamed namespace
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx
index 832c95c..786276b 100644
--- a/sw/source/core/text/itrform2.hxx
+++ b/sw/source/core/text/itrform2.hxx
@@ -46,6 +46,8 @@ 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 *NewPortion( SwTxtFormatInfo &rInf );
     SwTxtPortion  *NewTxtPortion( SwTxtFormatInfo &rInf );
     SwLinePortion *NewExtraPortion( SwTxtFormatInfo &rInf );
@@ -220,6 +222,23 @@ public:
     inline const sal_uInt8 &CntMidHyph() const { return nCntMidHyph; }
     inline sal_uInt8 &CntEndHyph() { return nCntEndHyph; }
     inline sal_uInt8 &CntMidHyph() { return nCntMidHyph; }
+
+    /**
+     * Merge border of the drop portion with modifying the font of
+     * the portions' part. Removing left or right border.
+     * @param   rPortion    drop portion for merge
+    **/
+    void MergeCharacterBorder( SwDropPortion& rPortion );
+
+    /**
+     * Merge border of the text portion with setting the text portions
+     * m_bJoinBorderWidthNext and m_bJoinBorderWidthPrev members and
+     * changing the size (width, height and ascent) of the text portion
+     * to get a merged border.
+     * @param   rPortion    text portion for merge
+     * @param   rInf        contain information
+    **/
+    void MergeCharacterBorder( SwTxtPortion& rPortion, SwTxtFormatInfo& rInf );
 };
 
 
diff --git a/sw/source/core/text/porexp.cxx b/sw/source/core/text/porexp.cxx
index 450d308..4108c72 100644
--- a/sw/source/core/text/porexp.cxx
+++ b/sw/source/core/text/porexp.cxx
@@ -91,6 +91,11 @@ sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf )
 void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
 {
     SwTxtSlot aDiffTxt( &rInf, this, true, true );
+    const SwFont aOldFont = *rInf.GetFont();
+    if( GetJoinBorderWithPrev() )
+        const_cast<SwTxtPaintInfo&>(rInf).GetFont()->SetLeftBorder(0);
+    if( GetJoinBorderWithNext() )
+        const_cast<SwTxtPaintInfo&>(rInf).GetFont()->SetRightBorder(0);
 
     rInf.DrawBackBrush( *this );
     rInf.DrawBorder( *this );
@@ -111,6 +116,9 @@ void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
             0 != rInf.GetSmartTags(), 0 != rInf.GetGrammarCheckList() );
     else
         rInf.DrawText( *this, rInf.GetLen(), sal_False );
+
+    if( GetJoinBorderWithPrev() || GetJoinBorderWithNext() )
+        *const_cast<SwTxtPaintInfo&>(rInf).GetFont() = aOldFont;
 }
 
 /*************************************************************************
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 254f93f..c04c60b 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -34,6 +34,7 @@
 #include <viewsh.hxx>
 #include <IDocumentSettingAccess.hxx>
 #include <viewopt.hxx>  // SwViewOptions
+#include <editeng/borderline.hxx>
 
 #include <IMark.hxx>
 #include <pam.hxx>
@@ -218,6 +219,12 @@ 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;
+    }
 }
 
 /*************************************************************************
@@ -536,7 +543,18 @@ xub_StrLen SwTxtPortion::GetCrsrOfst( const KSHORT nOfst ) const
 
 SwPosSize SwTxtPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
 {
-    return rInf.GetTxtSize();
+    const SwFont aOldFont = *rInf.GetFont();
+    if( m_bJoinBorderWithPrev )
+        const_cast<SwTxtSizeInfo&>(rInf).GetFont()->SetLeftBorder(0);
+    if( m_bJoinBorderWithNext )
+        const_cast<SwTxtSizeInfo&>(rInf).GetFont()->SetRightBorder(0);
+
+    const SwPosSize aSize = rInf.GetTxtSize();
+
+    if( m_bJoinBorderWithPrev || m_bJoinBorderWithNext )
+        *const_cast<SwTxtSizeInfo&>(rInf).GetFont() = aOldFont;
+
+    return aSize;
 }
 
 /*************************************************************************
@@ -544,6 +562,12 @@ SwPosSize SwTxtPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
  *************************************************************************/
 void SwTxtPortion::Paint( const SwTxtPaintInfo &rInf ) const
 {
+    const SwFont aOldFont = *rInf.GetFont();
+    if( m_bJoinBorderWithPrev )
+        const_cast<SwTxtPaintInfo&>(rInf).GetFont()->SetLeftBorder(0);
+    if( m_bJoinBorderWithNext )
+        const_cast<SwTxtPaintInfo&>(rInf).GetFont()->SetRightBorder(0);
+
     if (rInf.OnWin() && 1==rInf.GetLen() && CH_TXT_ATR_FIELDEND==rInf.GetTxt()[rInf.GetIdx()])
     {
         rInf.DrawBackBrush( *this );
@@ -579,6 +603,9 @@ void SwTxtPortion::Paint( const SwTxtPaintInfo &rInf ) const
         else
             rInf.DrawText( *this, rInf.GetLen(), sal_False );
     }
+
+    if( m_bJoinBorderWithPrev || m_bJoinBorderWithNext )
+        *const_cast<SwTxtPaintInfo&>(rInf).GetFont() = aOldFont;
 }
 
 /*************************************************************************
diff --git a/sw/source/core/text/portxt.hxx b/sw/source/core/text/portxt.hxx
index d201c74..4c029a3 100644
--- a/sw/source/core/text/portxt.hxx
+++ b/sw/source/core/text/portxt.hxx
@@ -36,8 +36,11 @@ class SwTxtPortion : public SwLinePortion
     void BreakUnderflow( SwTxtFormatInfo &rInf );
     sal_Bool _Format( SwTxtFormatInfo &rInf );
 
+    bool m_bJoinBorderWithPrev;
+    bool m_bJoinBorderWithNext;
+
 public:
-    inline SwTxtPortion(){ SetWhichPor( POR_TXT ); }
+    inline SwTxtPortion(): m_bJoinBorderWithPrev(false), m_bJoinBorderWithNext(false) { SetWhichPor( POR_TXT ); }
     SwTxtPortion( const SwLinePortion &rPortion );
     virtual void Paint( const SwTxtPaintInfo &rInf ) const;
     virtual sal_Bool Format( SwTxtFormatInfo &rInf );
@@ -55,6 +58,12 @@ 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
     DECL_FIXEDMEMPOOL_NEWDEL(SwTxtPortion)
 };
diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
index cb956b3..49337ba 100644
--- a/sw/source/core/text/txtdrop.cxx
+++ b/sw/source/core/text/txtdrop.cxx
@@ -604,7 +604,7 @@ SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf )
     while ( nNextChg  < nPorLen )
     {
         // check for attribute changes and if the portion has to split:
-        SeekAndChgAttrIter( nNextChg, rInf.GetOut() );
+        Seek( nNextChg );
 
         // the font is deleted in the destructor of the drop portion part
         SwFont* pTmpFnt = new SwFont( *rInf.GetFont() );
commit cc978cda8cc1d25f5f11758ff42d7c2137daf638
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Wed Aug 14 18:11:13 2013 +0200

    Add test for drop caps odf filter
    
    Change-Id: I52735c222e14e725fc01caa156cb8ea9671a36cc

diff --git a/sw/qa/extras/odfexport/data/fdo43807.odt b/sw/qa/extras/odfexport/data/fdo43807.odt
new file mode 100644
index 0000000..ae03c59
Binary files /dev/null and b/sw/qa/extras/odfexport/data/fdo43807.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 3fbf196..3a248b2 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -20,6 +20,7 @@ public:
     void testFdo60769();
     void testFdo58949();
     void testCharacterBorder();
+    void testFdo43807();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -40,6 +41,7 @@ void Test::run()
         {"fdo60769.odt", &Test::testFdo60769},
         {"fdo58949.docx", &Test::testFdo58949},
         {"charborder.odt", &Test::testCharacterBorder },
+        {"fdo43807.odt", &Test::testFdo43807 },
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -338,6 +340,15 @@ void Test::testCharacterBorder()
     }
 }
 
+void Test::testFdo43807()
+{
+    uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("Drop Caps"),getProperty<OUString>(xSet,"DropCapCharStyleName"));
+
+    xSet = uno::Reference<beans::XPropertySet>(getParagraph(2), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("User Defined Drop Caps"),getProperty<OUString>(xSet,"DropCapCharStyleName"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 932901224ea8473bbcae6feced953340d489bcc5
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Wed Aug 14 16:28:09 2013 +0200

    fdo#43807: Fix import of drop caps character style
    
    Export works and import has just a little typo.
    
    Change-Id: I570d70423b5a626f21117971fb7eff030eae20af

diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx
index eb74f00..2798ab0 100644
--- a/xmloff/source/text/txtimp.cxx
+++ b/xmloff/source/text/txtimp.cxx
@@ -1676,7 +1676,7 @@ OUString XMLTextImportHelper::SetStyleAndAttrs(
                                 XML_STYLE_FAMILY_TEXT_TEXT,
                                 pStyle->GetDropCapStyleName()) );
             if (m_pImpl->m_xTextStyles->hasByName(sDisplayName) &&
-                xPropSetInfo->hasPropertyByName( sDisplayName ) )
+                xPropSetInfo->hasPropertyByName( pStyle->sDropCapCharStyleName ) )
             {
                 xPropSet->setPropertyValue( pStyle->sDropCapCharStyleName, makeAny(sDisplayName) );
             }
commit ea358f5d5b04a2a8e11a73d35643cd0afc5cb63b
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Tue Aug 13 18:04:14 2013 +0200

    CharBrd 8.2: Tests for UNO API and ODF filter
    
    Use just those API tests which still alive.
    Export filter test use import so no need for distinct
    import tests.
    
    Change-Id: Idddc2ece10e20027551538f4e8c224edffa9bfe8

diff --git a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXCellRange.csv b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXCellRange.csv
index 13c319cf4..bbf37c1 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXCellRange.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXCellRange.csv
@@ -134,6 +134,15 @@
 "SwXCellRange";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "SwXCellRange";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "SwXCellRange";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"SwXCellRange";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "SwXCellRange";"com::sun::star::sheet::XCellRangeData#optional";"getDataArray()"
 "SwXCellRange";"com::sun::star::sheet::XCellRangeData#optional";"setDataArray()"
 "SwXCellRange";"com::sun::star::style::ParagraphPropertiesAsian#optional";"ParaIsHangingPunctuation"
diff --git a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextCursor.csv b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextCursor.csv
index 4082ae2..fd964f8 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextCursor.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextCursor.csv
@@ -156,6 +156,15 @@
 "SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "SwXTextCursor";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"SwXTextCursor";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "SwXTextCursor";"com::sun::star::document::XDocumentInsertable#optional";"insertDocumentFromURL()"
 "SwXTextCursor";"com::sun::star::beans::XPropertySet";"getPropertySetInfo()"
 "SwXTextCursor";"com::sun::star::beans::XPropertySet";"setPropertyValue()"
diff --git a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextRange.csv b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextRange.csv
index c93369a..2618653 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextRange.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextRange.csv
@@ -130,6 +130,15 @@
 "SwXTextRange";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "SwXTextRange";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "SwXTextRange";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"SwXTextRange";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "SwXTextRange";"com::sun::star::beans::XPropertySet";"getPropertySetInfo()"
 "SwXTextRange";"com::sun::star::beans::XPropertySet";"setPropertyValue()"
 "SwXTextRange";"com::sun::star::beans::XPropertySet";"getPropertyValue()"
diff --git a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextTableCursor.csv b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextTableCursor.csv
index 2f2e52f..b2fbb91 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextTableCursor.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextTableCursor.csv
@@ -133,6 +133,15 @@
 "SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"SwXTextTableCursor";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "SwXTextTableCursor";"com::sun::star::beans::XPropertySet";"getPropertySetInfo()"
 "SwXTextTableCursor";"com::sun::star::beans::XPropertySet";"setPropertyValue()"
 "SwXTextTableCursor";"com::sun::star::beans::XPropertySet";"getPropertyValue()"
diff --git a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextViewCursor.csv b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextViewCursor.csv
index 524fd0f..6ecd7ca 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextViewCursor.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.comp.office.SwXTextViewCursor.csv
@@ -166,6 +166,15 @@
 "SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"SwXTextViewCursor";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "SwXTextViewCursor";"com::sun::star::document::XDocumentInsertable#optional";"insertDocumentFromURL()"
 "SwXTextViewCursor";"com::sun::star::beans::XPropertySet";"getPropertySetInfo()"
 "SwXTextViewCursor";"com::sun::star::beans::XPropertySet";"setPropertyValue()"
diff --git a/qadevOOo/objdsc/sw/com.sun.star.style.CharacterStyle.csv b/qadevOOo/objdsc/sw/com.sun.star.style.CharacterStyle.csv
index f9dbb50..c7d16cd 100644
--- a/qadevOOo/objdsc/sw/com.sun.star.style.CharacterStyle.csv
+++ b/qadevOOo/objdsc/sw/com.sun.star.style.CharacterStyle.csv
@@ -92,6 +92,15 @@
 "CharacterStyle";"com::sun::star::style::CharacterProperties";"CharStyleNames#optional"
 "CharacterStyle";"com::sun::star::style::CharacterProperties";"CharHidden#optional"
 "CharacterStyle";"com::sun::star::style::CharacterProperties";"TextUserDefinedAttributes#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharLeftBorder#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharRightBorder#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharBottomBorder#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharTopBorder#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharBorderDistance#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharLeftBorderDistance#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharRightBorderDistance#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharBottomBorderDistance#optional"
+"CharacterStyle";"com::sun::star::style::CharacterProperties";"CharTopBorderDistance#optional"
 "CharacterStyle";"com::sun::star::beans::XPropertySet";"getPropertySetInfo()"
 "CharacterStyle";"com::sun::star::beans::XPropertySet";"setPropertyValue()"
 "CharacterStyle";"com::sun::star::beans::XPropertySet";"getPropertyValue()"
diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index 38c5a47..9bd8a46 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -10,12 +10,15 @@
 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/style/XAutoStylesSupplier.hpp>
+#include <com/sun/star/style/XAutoStyleFamily.hpp>
 #include <com/sun/star/text/XPageCursor.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextRange.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 #include <com/sun/star/table/XCell.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
 
 #include <test/bootstrapfixture.hxx>
 #include <unotest/macros_test.hxx>
@@ -120,6 +123,15 @@ protected:
         return xStyleFamily;
     }
 
+    /// Get a family of auto styles, see com.sun.star.style.StyleFamilies for possible values.
+    uno::Reference<style::XAutoStyleFamily> getAutoStyles(OUString aFamily)
+    {
+        uno::Reference< style::XAutoStylesSupplier > xAutoStylesSupplier(mxComponent, uno::UNO_QUERY);
+        uno::Reference< style::XAutoStyles > xAutoStyles(xAutoStylesSupplier->getAutoStyles());
+        uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(xAutoStyles->getByName(aFamily), uno::UNO_QUERY);
+        return xAutoStyleFamily;
+    }
+
     /**
      * Extract a value from the layout dump using an XPath expression and an attribute name.
      *
@@ -326,6 +338,21 @@ 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/data/charborder.odt b/sw/qa/extras/odfexport/data/charborder.odt
new file mode 100644
index 0000000..9f37d58
Binary files /dev/null and b/sw/qa/extras/odfexport/data/charborder.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index efbd931..3fbf196 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -19,6 +19,7 @@ public:
     void testTextframeGradient();
     void testFdo60769();
     void testFdo58949();
+    void testCharacterBorder();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -38,6 +39,7 @@ void Test::run()
         {"textframe-gradient.odt", &Test::testTextframeGradient},
         {"fdo60769.odt", &Test::testFdo60769},
         {"fdo58949.docx", &Test::testFdo58949},
+        {"charborder.odt", &Test::testCharacterBorder },
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -162,6 +164,180 @@ void Test::testFdo58949()
     CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("Obj102")));
 }
 
+void Test::testCharacterBorder()
+{
+    // Make sure paragraph and character attributes don't interfere
+    // First paragraph has a paragraph border and a character border included by the paragraph style
+
+    // Paragraph border of first paragraph
+    {
+        const table::BorderLine2 aFirstParTopBorder(6711039,0,26,26,7,53);
+        const sal_Int32 aFirstParTopPadding(150);
+        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"));
+
+        // Bottom border (same as top border)
+        assertEqualBorder(
+            aFirstParTopBorder, aFirstParTopPadding,
+            getProperty<table::BorderLine2>(xSet,"BottomBorder"),
+            getProperty<sal_Int32>(xSet,"BottomBorderDistance"));
+
+        // Left border (same as top border)
+        assertEqualBorder(
+            aFirstParTopBorder, aFirstParTopPadding,
+            getProperty<table::BorderLine2>(xSet,"LeftBorder"),
+            getProperty<sal_Int32>(xSet,"LeftBorderDistance"));
+
+        // Right border (same as top border)
+        assertEqualBorder(
+            aFirstParTopBorder, aFirstParTopPadding,
+            getProperty<table::BorderLine2>(xSet,"RightBorder"),
+            getProperty<sal_Int32>(xSet,"RightBorderDistance"));
+    }
+
+    // Character border for first paragraph
+    {
+        const table::BorderLine2 aFirstParCharTopBorder(16724787,0,37,0,2,37);
+        const sal_Int32 aFirstParCharTopPadding(450);
+        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"));
+
+        // Bottom border (same as top border)
+        assertEqualBorder(
+            aFirstParCharTopBorder, aFirstParCharTopPadding,
+            getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
+            getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+
+        // Left border (same as top border)
+        assertEqualBorder(
+            aFirstParCharTopBorder, aFirstParCharTopPadding,
+            getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
+            getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+
+        // Right border (same as top border)
+        assertEqualBorder(
+            aFirstParCharTopBorder, aFirstParCharTopPadding,
+            getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
+            getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+
+        // Check autostyle
+        {
+            uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(getAutoStyles("ParagraphStyles"));
+            uno::Reference < container::XEnumeration > xAutoStylesEnum( xAutoStyleFamily->createEnumeration() );
+            CPPUNIT_ASSERT_EQUAL((bool)xAutoStylesEnum->hasMoreElements(), true);
+
+            // First paragraph autostyle
+            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"));
+
+            // Bottom border
+            assertEqualBorder(
+                aFirstParCharTopBorder, aFirstParCharTopPadding,
+                getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
+                getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+
+            // Left border
+            assertEqualBorder(
+                aFirstParCharTopBorder, aFirstParCharTopPadding,
+                getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
+                getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+
+            // Right border
+            assertEqualBorder(
+                aFirstParCharTopBorder, aFirstParCharTopPadding,
+                getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
+                getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+        }
+    }
+
+    // Second paragraph's second text portion has a character style named CharDiffBor
+    // This style includes border with different sides
+    {
+
+        table::BorderLine2 aBorderArray[4] =
+        {
+            table::BorderLine2(16724787,26,2,4,13,35),     // Top
+            table::BorderLine2(10092390,26,26,53,11,106),  // Bottom
+            table::BorderLine2(6711039,9,26,9,12,71),      // Left
+            table::BorderLine2(0,0,0,0,0,0)                // Right
+        };
+
+        sal_Int32 aDistances[4] = { 400 /*Top*/, 300 /*Bottom*/, 250 /*Left*/, 0 /*Right*/ };
+
+        // Get second text portion of second paragraph
+        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"));
+
+        // Bottom border
+        assertEqualBorder(
+            aBorderArray[1], aDistances[1],
+            getProperty<table::BorderLine2>(xSet,"CharBottomBorder"),
+            getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
+
+        // Left border
+        assertEqualBorder(
+            aBorderArray[2], aDistances[2],
+            getProperty<table::BorderLine2>(xSet,"CharLeftBorder"),
+            getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
+
+        // Right border
+        assertEqualBorder(
+            aBorderArray[3], aDistances[3],
+            getProperty<table::BorderLine2>(xSet,"CharRightBorder"),
+            getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
+
+        // Check character style
+        {
+            uno::Reference< container::XNameAccess > xStyleFamily(getStyles("CharacterStyles"), uno::UNO_QUERY);
+            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"));
+
+            // Bottom border
+            assertEqualBorder(
+                aBorderArray[1], aDistances[1],
+                getProperty<table::BorderLine2>(xStyleSet,"CharBottomBorder"),
+                getProperty<sal_Int32>(xStyleSet,"CharBottomBorderDistance"));
+
+            // Left border
+            assertEqualBorder(
+                aBorderArray[2], aDistances[2],
+                getProperty<table::BorderLine2>(xStyleSet,"CharLeftBorder"),
+                getProperty<sal_Int32>(xStyleSet,"CharLeftBorderDistance"));
+
+            // Right border
+            assertEqualBorder(
+                aBorderArray[3], aDistances[3],
+                getProperty<table::BorderLine2>(xStyleSet,"CharRightBorder"),
+                getProperty<sal_Int32>(xStyleSet,"CharRightBorderDistance"));
+        }
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 47e24bfed80342ae3f1c45e745b717aa8f557ec0
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Tue Aug 13 14:18:35 2013 +0200

    CharBrd 8.1: ODF filters
    
    Change-Id: Ib1a79678ffce7764638378b4002f5e87ae749d00

diff --git a/include/xmloff/txtprmap.hxx b/include/xmloff/txtprmap.hxx
index 92285911..348f925 100644
--- a/include/xmloff/txtprmap.hxx
+++ b/include/xmloff/txtprmap.hxx
@@ -177,6 +177,24 @@
 #define CTF_MARGINRIGHT                     (XML_TEXT_CTF_START + 150)
 #define CTF_MARGINTOP                       (XML_TEXT_CTF_START + 151)
 #define CTF_MARGINBOTTOM                    (XML_TEXT_CTF_START + 152)
+/* CTF ids for character border to avoid interference between
+   paragraph and character attributes */
+#define CTF_CHARALLBORDERWIDTH              (XML_TEXT_CTF_START + 153)
+#define CTF_CHARLEFTBORDERWIDTH             (XML_TEXT_CTF_START + 154)
+#define CTF_CHARRIGHTBORDERWIDTH            (XML_TEXT_CTF_START + 155)
+#define CTF_CHARTOPBORDERWIDTH              (XML_TEXT_CTF_START + 156)
+#define CTF_CHARBOTTOMBORDERWIDTH           (XML_TEXT_CTF_START + 157)
+#define CTF_CHARALLBORDERDISTANCE           (XML_TEXT_CTF_START + 158)
+#define CTF_CHARLEFTBORDERDISTANCE          (XML_TEXT_CTF_START + 159)
+#define CTF_CHARRIGHTBORDERDISTANCE         (XML_TEXT_CTF_START + 160)
+#define CTF_CHARTOPBORDERDISTANCE           (XML_TEXT_CTF_START + 161)
+#define CTF_CHARBOTTOMBORDERDISTANCE        (XML_TEXT_CTF_START + 162)
+#define CTF_CHARALLBORDER                   (XML_TEXT_CTF_START + 163)
+#define CTF_CHARLEFTBORDER                  (XML_TEXT_CTF_START + 164)
+#define CTF_CHARRIGHTBORDER                 (XML_TEXT_CTF_START + 165)
+#define CTF_CHARTOPBORDER                   (XML_TEXT_CTF_START + 166)
+#define CTF_CHARBOTTOMBORDER                (XML_TEXT_CTF_START + 167)
+
 
 #define TEXT_PROP_MAP_TEXT 0
 #define TEXT_PROP_MAP_PARA 1
diff --git a/xmloff/source/text/txtexppr.cxx b/xmloff/source/text/txtexppr.cxx
index 41c1397..7c978f8 100644
--- a/xmloff/source/text/txtexppr.cxx
+++ b/xmloff/source/text/txtexppr.cxx
@@ -287,6 +287,8 @@ void XMLTextExportPropertySetMapper::ContextFontHeightFilter(
 
 }
 
+namespace {
+
 // helper method; implementation below
 static bool lcl_IsOutlineStyle(const SvXMLExport&, const OUString&);
 
@@ -311,6 +313,143 @@ lcl_checkMultiProperty(XMLPropertyState *const pState,
     }
 }
 
+static void lcl_FilterBorders(
+    XMLPropertyState* pAllBorderWidthState, XMLPropertyState* pLeftBorderWidthState,
+    XMLPropertyState* pRightBorderWidthState, XMLPropertyState* pTopBorderWidthState,
+    XMLPropertyState* pBottomBorderWidthState, XMLPropertyState* pAllBorderDistanceState,
+    XMLPropertyState* pLeftBorderDistanceState, XMLPropertyState* pRightBorderDistanceState,
+    XMLPropertyState* pTopBorderDistanceState, XMLPropertyState* pBottomBorderDistanceState,
+    XMLPropertyState* pAllBorderState, XMLPropertyState* pLeftBorderState,
+    XMLPropertyState* pRightBorderState,XMLPropertyState* pTopBorderState,
+    XMLPropertyState* pBottomBorderState )
+{
+    if( pAllBorderWidthState )
+    {
+        if( pLeftBorderWidthState && pRightBorderWidthState && pTopBorderWidthState && pBottomBorderWidthState )
+        {
+            table::BorderLine2 aLeft, aRight, aTop, aBottom;
+
+            pLeftBorderWidthState->maValue >>= aLeft;
+            pRightBorderWidthState->maValue >>= aRight;
+            pTopBorderWidthState->maValue >>= aTop;
+            pBottomBorderWidthState->maValue >>= aBottom;
+            if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
+                aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
+                aLeft.LineStyle == aRight.LineStyle &&
+                aLeft.LineWidth == aRight.LineWidth &&
+                aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+                aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+                aLeft.LineStyle == aTop.LineStyle &&
+                aLeft.LineWidth == aTop.LineWidth &&
+                aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
+                aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance &&
+                aLeft.LineStyle == aBottom.LineStyle &&
+                aLeft.LineWidth == aBottom.LineWidth )
+            {
+                pLeftBorderWidthState->mnIndex = -1;
+                pLeftBorderWidthState->maValue.clear();
+                pRightBorderWidthState->mnIndex = -1;
+                pRightBorderWidthState->maValue.clear();
+                pTopBorderWidthState->mnIndex = -1;
+                pTopBorderWidthState->maValue.clear();
+                pBottomBorderWidthState->mnIndex = -1;
+                pBottomBorderWidthState->maValue.clear();
+            }
+            else
+            {
+                pAllBorderWidthState->mnIndex = -1;
+                pAllBorderWidthState->maValue.clear();
+            }
+        }
+        else
+        {
+            pAllBorderWidthState->mnIndex = -1;
+            pAllBorderWidthState->maValue.clear();
+        }
+    }
+
+    if( pAllBorderDistanceState )
+    {
+        if( pLeftBorderDistanceState && pRightBorderDistanceState && pTopBorderDistanceState && pBottomBorderDistanceState )
+        {
+            sal_Int32 aLeft = 0, aRight = 0, aTop = 0, aBottom = 0;
+
+            pLeftBorderDistanceState->maValue >>= aLeft;
+            pRightBorderDistanceState->maValue >>= aRight;
+            pTopBorderDistanceState->maValue >>= aTop;
+            pBottomBorderDistanceState->maValue >>= aBottom;
+            if( aLeft == aRight && aLeft == aTop && aLeft == aBottom )
+            {
+                pLeftBorderDistanceState->mnIndex = -1;
+                pLeftBorderDistanceState->maValue.clear();
+                pRightBorderDistanceState->mnIndex = -1;
+                pRightBorderDistanceState->maValue.clear();
+                pTopBorderDistanceState->mnIndex = -1;
+                pTopBorderDistanceState->maValue.clear();
+                pBottomBorderDistanceState->mnIndex = -1;
+                pBottomBorderDistanceState->maValue.clear();
+            }
+            else
+            {
+                pAllBorderDistanceState->mnIndex = -1;
+                pAllBorderDistanceState->maValue.clear();
+            }
+        }
+        else
+        {
+            pAllBorderDistanceState->mnIndex = -1;
+            pAllBorderDistanceState->maValue.clear();
+        }
+    }
+
+    if( pAllBorderState )
+    {
+        if( pLeftBorderState && pRightBorderState && pTopBorderState && pBottomBorderState )
+        {
+            table::BorderLine2 aLeft, aRight, aTop, aBottom;
+
+            pLeftBorderState->maValue >>= aLeft;
+            pRightBorderState->maValue >>= aRight;
+            pTopBorderState->maValue >>= aTop;
+            pBottomBorderState->maValue >>= aBottom;
+            if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
+                aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
+                aLeft.LineStyle == aRight.LineStyle &&
+                aLeft.LineWidth == aRight.LineWidth &&
+                aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
+                aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
+                aLeft.LineStyle == aTop.LineStyle  &&
+                aLeft.LineWidth == aTop.LineWidth  &&
+                aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
+                aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance &&
+                aLeft.LineWidth == aBottom.LineWidth &&
+                aLeft.LineStyle == aBottom.LineStyle )
+            {
+                pLeftBorderState->mnIndex = -1;
+                pLeftBorderState->maValue.clear();
+                pRightBorderState->mnIndex = -1;
+                pRightBorderState->maValue.clear();
+                pTopBorderState->mnIndex = -1;
+                pTopBorderState->maValue.clear();
+                pBottomBorderState->mnIndex = -1;
+                pBottomBorderState->maValue.clear();
+            }
+            else
+            {
+                pAllBorderState->mnIndex = -1;
+                pAllBorderState->maValue.clear();
+            }
+        }
+        else
+        {
+            pAllBorderState->mnIndex = -1;
+            pAllBorderState->maValue.clear();
+        }
+    }
+}
+
+}
+
 void XMLTextExportPropertySetMapper::ContextFilter(
     ::std::vector< XMLPropertyState >& rProperties,
     Reference< XPropertySet > rPropSet ) const
@@ -387,6 +526,27 @@ void XMLTextExportPropertySetMapper::ContextFilter(
     XMLPropertyState* pTopBorderState = NULL;
     XMLPropertyState* pBottomBorderState = NULL;
 
+    // filter Char(Left|Right|Top|Bottom|)BorderWidth
+    XMLPropertyState* pCharAllBorderWidthState = NULL;
+    XMLPropertyState* pCharLeftBorderWidthState = NULL;
+    XMLPropertyState* pCharRightBorderWidthState = NULL;
+    XMLPropertyState* pCharTopBorderWidthState = NULL;
+    XMLPropertyState* pCharBottomBorderWidthState = NULL;
+
+    // filter Char(Left|Right|Top|)BorderDistance
+    XMLPropertyState* pCharAllBorderDistanceState = NULL;
+    XMLPropertyState* pCharLeftBorderDistanceState = NULL;
+    XMLPropertyState* pCharRightBorderDistanceState = NULL;
+    XMLPropertyState* pCharTopBorderDistanceState = NULL;
+    XMLPropertyState* pCharBottomBorderDistanceState = NULL;
+
+    // filter Char(Left|Right|Top|Bottom|)Border
+    XMLPropertyState* pCharAllBorderState = NULL;
+    XMLPropertyState* pCharLeftBorderState = NULL;
+    XMLPropertyState* pCharRightBorderState = NULL;
+    XMLPropertyState* pCharTopBorderState = NULL;
+    XMLPropertyState* pCharBottomBorderState = NULL;
+
     // filter height properties
     XMLPropertyState* pHeightMinAbsState = NULL;
     XMLPropertyState* pHeightMinRelState = NULL;
@@ -486,6 +646,7 @@ void XMLTextExportPropertySetMapper::ContextFilter(
         case CTF_PARATOPMARGIN_REL:     pParaTopMarginRelState = propertie; break;
         case CTF_PARABOTTOMMARGIN:      pParaBottomMarginState = propertie; break;
         case CTF_PARABOTTOMMARGIN_REL:  pParaBottomMarginRelState = propertie; break;
+
         case CTF_ALLBORDERWIDTH:        pAllBorderWidthState = propertie; break;
         case CTF_LEFTBORDERWIDTH:       pLeftBorderWidthState = propertie; break;
         case CTF_RIGHTBORDERWIDTH:      pRightBorderWidthState = propertie; break;
@@ -502,6 +663,22 @@ void XMLTextExportPropertySetMapper::ContextFilter(
         case CTF_TOPBORDER:             pTopBorderState = propertie; break;
         case CTF_BOTTOMBORDER:          pBottomBorderState = propertie; break;
 
+        case CTF_CHARALLBORDERWIDTH:        pCharAllBorderWidthState = propertie; break;
+        case CTF_CHARLEFTBORDERWIDTH:       pCharLeftBorderWidthState = propertie; break;
+        case CTF_CHARRIGHTBORDERWIDTH:      pCharRightBorderWidthState = propertie; break;
+        case CTF_CHARTOPBORDERWIDTH:        pCharTopBorderWidthState = propertie; break;
+        case CTF_CHARBOTTOMBORDERWIDTH:     pCharBottomBorderWidthState = propertie; break;
+        case CTF_CHARALLBORDERDISTANCE:     pCharAllBorderDistanceState = propertie; break;
+        case CTF_CHARLEFTBORDERDISTANCE:    pCharLeftBorderDistanceState = propertie; break;
+        case CTF_CHARRIGHTBORDERDISTANCE:   pCharRightBorderDistanceState = propertie; break;
+        case CTF_CHARTOPBORDERDISTANCE:     pCharTopBorderDistanceState = propertie; break;
+        case CTF_CHARBOTTOMBORDERDISTANCE:  pCharBottomBorderDistanceState = propertie; break;
+        case CTF_CHARALLBORDER:             pCharAllBorderState = propertie; break;
+        case CTF_CHARLEFTBORDER:            pCharLeftBorderState = propertie; break;
+        case CTF_CHARRIGHTBORDER:           pCharRightBorderState = propertie; break;
+        case CTF_CHARTOPBORDER:             pCharTopBorderState = propertie; break;
+        case CTF_CHARBOTTOMBORDER:          pCharBottomBorderState = propertie; break;
+
         case CTF_FRAMEHEIGHT_MIN_ABS:   pHeightMinAbsState = propertie; break;
         case CTF_FRAMEHEIGHT_MIN_REL:   pHeightMinRelState = propertie; break;
         case CTF_FRAMEHEIGHT_ABS:       pHeightAbsState = propertie; break;
@@ -639,129 +816,19 @@ void XMLTextExportPropertySetMapper::ContextFilter(
         pAllMargin->maValue.clear();
     }
 
-    if( pAllBorderWidthState )
-    {
-        if( pLeftBorderWidthState && pRightBorderWidthState && pTopBorderWidthState && pBottomBorderWidthState )
-        {
-            table::BorderLine2 aLeft, aRight, aTop, aBottom;
-
-            pLeftBorderWidthState->maValue >>= aLeft;
-            pRightBorderWidthState->maValue >>= aRight;
-            pTopBorderWidthState->maValue >>= aTop;
-            pBottomBorderWidthState->maValue >>= aBottom;
-            if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
-                aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
-                aLeft.LineStyle == aRight.LineStyle &&
-                aLeft.LineWidth == aRight.LineWidth &&
-                aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
-                aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
-                aLeft.LineStyle == aTop.LineStyle &&
-                aLeft.LineWidth == aTop.LineWidth &&
-                aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
-                aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance &&
-                aLeft.LineStyle == aBottom.LineStyle &&
-                aLeft.LineWidth == aBottom.LineWidth )
-            {
-                pLeftBorderWidthState->mnIndex = -1;
-                pLeftBorderWidthState->maValue.clear();
-                pRightBorderWidthState->mnIndex = -1;
-                pRightBorderWidthState->maValue.clear();
-                pTopBorderWidthState->mnIndex = -1;
-                pTopBorderWidthState->maValue.clear();
-                pBottomBorderWidthState->mnIndex = -1;
-                pBottomBorderWidthState->maValue.clear();
-            }
-            else
-            {
-                pAllBorderWidthState->mnIndex = -1;
-                pAllBorderWidthState->maValue.clear();
-            }
-        }
-        else
-        {
-            pAllBorderWidthState->mnIndex = -1;
-            pAllBorderWidthState->maValue.clear();
-        }
-    }
-
-    if( pAllBorderDistanceState )
-    {
-        if( pLeftBorderDistanceState && pRightBorderDistanceState && pTopBorderDistanceState && pBottomBorderDistanceState )
-        {
-            sal_Int32 aLeft = 0, aRight = 0, aTop = 0, aBottom = 0;
-
-            pLeftBorderDistanceState->maValue >>= aLeft;
-            pRightBorderDistanceState->maValue >>= aRight;
-            pTopBorderDistanceState->maValue >>= aTop;
-            pBottomBorderDistanceState->maValue >>= aBottom;
-            if( aLeft == aRight && aLeft == aTop && aLeft == aBottom )
-            {
-                pLeftBorderDistanceState->mnIndex = -1;
-                pLeftBorderDistanceState->maValue.clear();
-                pRightBorderDistanceState->mnIndex = -1;
-                pRightBorderDistanceState->maValue.clear();
-                pTopBorderDistanceState->mnIndex = -1;
-                pTopBorderDistanceState->maValue.clear();
-                pBottomBorderDistanceState->mnIndex = -1;
-                pBottomBorderDistanceState->maValue.clear();
-            }
-            else
-            {
-                pAllBorderDistanceState->mnIndex = -1;
-                pAllBorderDistanceState->maValue.clear();
-            }
-        }
-        else
-        {
-            pAllBorderDistanceState->mnIndex = -1;
-            pAllBorderDistanceState->maValue.clear();
-        }
-    }
-
-    if( pAllBorderState )
-    {
-        if( pLeftBorderState && pRightBorderState && pTopBorderState && pBottomBorderState )
-        {
-            table::BorderLine2 aLeft, aRight, aTop, aBottom;
+    lcl_FilterBorders(
+        pAllBorderWidthState, pLeftBorderWidthState, pRightBorderWidthState,
+        pTopBorderWidthState, pBottomBorderWidthState, pAllBorderDistanceState,
+        pLeftBorderDistanceState, pRightBorderDistanceState, pTopBorderDistanceState,
+        pBottomBorderDistanceState, pAllBorderState, pLeftBorderState,
+        pRightBorderState, pTopBorderState, pBottomBorderState);
 
-            pLeftBorderState->maValue >>= aLeft;
-            pRightBorderState->maValue >>= aRight;
-            pTopBorderState->maValue >>= aTop;
-            pBottomBorderState->maValue >>= aBottom;
-            if( aLeft.Color == aRight.Color && aLeft.InnerLineWidth == aRight.InnerLineWidth &&
-                aLeft.OuterLineWidth == aRight.OuterLineWidth && aLeft.LineDistance == aRight.LineDistance &&
-                aLeft.LineStyle == aRight.LineStyle &&
-                aLeft.LineWidth == aRight.LineWidth &&
-                aLeft.Color == aTop.Color && aLeft.InnerLineWidth == aTop.InnerLineWidth &&
-                aLeft.OuterLineWidth == aTop.OuterLineWidth && aLeft.LineDistance == aTop.LineDistance &&
-                aLeft.LineStyle == aTop.LineStyle  &&
-                aLeft.LineWidth == aTop.LineWidth  &&
-                aLeft.Color == aBottom.Color && aLeft.InnerLineWidth == aBottom.InnerLineWidth &&
-                aLeft.OuterLineWidth == aBottom.OuterLineWidth && aLeft.LineDistance == aBottom.LineDistance &&
-                aLeft.LineWidth == aBottom.LineWidth &&
-                aLeft.LineStyle == aBottom.LineStyle )
-            {
-                pLeftBorderState->mnIndex = -1;
-                pLeftBorderState->maValue.clear();
-                pRightBorderState->mnIndex = -1;
-                pRightBorderState->maValue.clear();
-                pTopBorderState->mnIndex = -1;
-                pTopBorderState->maValue.clear();
-                pBottomBorderState->mnIndex = -1;
-                pBottomBorderState->maValue.clear();
-            }
-            else
-            {
-                pAllBorderState->mnIndex = -1;
-                pAllBorderState->maValue.clear();
-            }
-        }
-        else
-        {
-            pAllBorderState->mnIndex = -1;
-            pAllBorderState->maValue.clear();
-        }
-    }
+    lcl_FilterBorders(
+        pCharAllBorderWidthState, pCharLeftBorderWidthState, pCharRightBorderWidthState,
+        pCharTopBorderWidthState, pCharBottomBorderWidthState, pCharAllBorderDistanceState,
+        pCharLeftBorderDistanceState, pCharRightBorderDistanceState, pCharTopBorderDistanceState,
+        pCharBottomBorderDistanceState, pCharAllBorderState, pCharLeftBorderState,
+        pCharRightBorderState, pCharTopBorderState, pCharBottomBorderState);
 
     sal_Int16 nSizeType = SizeType::FIX;
     if( pSizeTypeState )
@@ -963,6 +1030,7 @@ void XMLTextExportPropertySetMapper::ContextFilter(
     SvXMLExportPropertyMapper::ContextFilter(rProperties,rPropSet);
 }
 
+namespace {
 
 static bool lcl_IsOutlineStyle(const SvXMLExport &rExport, const OUString & rName)
 {
@@ -986,4 +1054,6 @@ static bool lcl_IsOutlineStyle(const SvXMLExport &rExport, const OUString & rNam
     return rName == sOutlineName;
 }
 
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/txtimppr.cxx b/xmloff/source/text/txtimppr.cxx
index 40f5dc2..1e7ec03 100644
--- a/xmloff/source/text/txtimppr.cxx
+++ b/xmloff/source/text/txtimppr.cxx
@@ -247,6 +247,7 @@ void XMLTextImportPropertyMapper::FontDefaultsCheck(
     }
 }
 
+namespace {
 //fdo#58730 The [UL|LR]Space class has a deficiency where "100%" also serves as
 //a flag that the value is an absolute value so we can't truly handle an
 //up/lower space property which wants to specify its 200% upper but 100% lower
@@ -267,6 +268,67 @@ isNotDefaultRelSize(const XMLPropertyState* pRelState, const UniReference<XMLPro
     return true;
 }
 
+static void lcl_SeparateBorder(
+    sal_uInt16 nIndex, XMLPropertyState* pAllBorderDistance,
+    XMLPropertyState* pBorderDistances[4], XMLPropertyState* pNewBorderDistances[4],
+    XMLPropertyState* pAllBorder, XMLPropertyState* pBorders[4],
+    XMLPropertyState* pNewBorders[4], XMLPropertyState* pAllBorderWidth,
+    XMLPropertyState* pBorderWidths[4]
+#ifdef DBG_UTIL
+    , const UniReference< XMLPropertySetMapper >& rMapper
+#endif
+)
+{
+    if( pAllBorderDistance && !pBorderDistances[nIndex] )
+    {
+#ifdef DBG_UTIL
+        sal_Int16 nTmp = rMapper->GetEntryContextId(
+                                    pAllBorderDistance->mnIndex + nIndex + 1 );
+        DBG_ASSERT( nTmp >= CTF_LEFTBORDERDISTANCE &&
+                    nTmp <= CTF_BOTTOMBORDERDISTANCE,
+                    "wrong property context id" );
+#endif
+        pNewBorderDistances[nIndex] =
+            new XMLPropertyState( pAllBorderDistance->mnIndex + nIndex + 1,
+                                    pAllBorderDistance->maValue );
+        pBorderDistances[nIndex] = pNewBorderDistances[nIndex];
+    }
+    if( pAllBorder && !pBorders[nIndex] )
+    {
+#ifdef DBG_UTIL
+        sal_Int16 nTmp = rMapper->GetEntryContextId(
+                                        pAllBorder->mnIndex + nIndex + 1 );
+        DBG_ASSERT( nTmp >= CTF_LEFTBORDER && nTmp <= CTF_BOTTOMBORDER,
+                    "wrong property context id" );
+#endif
+        pNewBorders[nIndex] = new XMLPropertyState( pAllBorder->mnIndex + nIndex + 1,
+                                                   pAllBorder->maValue );
+        pBorders[nIndex] = pNewBorders[nIndex];
+    }
+    if( !pBorderWidths[nIndex] )
+        pBorderWidths[nIndex] = pAllBorderWidth;
+    else
+        pBorderWidths[nIndex]->mnIndex = -1;
+
+    if( pBorders[nIndex] && pBorderWidths[nIndex] )
+    {
+        table::BorderLine2 aBorderLine;
+        pBorders[nIndex]->maValue >>= aBorderLine;
+
+        table::BorderLine2 aBorderLineWidth;
+        pBorderWidths[nIndex]->maValue >>= aBorderLineWidth;
+
+        aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
+        aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
+        aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
+        aBorderLine.LineWidth = aBorderLineWidth.LineWidth;
+
+        pBorders[nIndex]->maValue <<= aBorderLine;
+    }
+}
+
+}
+
 void XMLTextImportPropertyMapper::finished(
             ::std::vector< XMLPropertyState >& rProperties,
             sal_Int32 /*nStartIndex*/, sal_Int32 /*nEndIndex*/ ) const
@@ -311,6 +373,14 @@ void XMLTextImportPropertyMapper::finished(
     XMLPropertyState* pNewBorders[4] = { 0, 0, 0, 0 };
     XMLPropertyState* pAllBorderWidth = 0;
     XMLPropertyState* pBorderWidths[4] = { 0, 0, 0, 0 };
+    XMLPropertyState* pCharAllBorderDistance = 0;
+    XMLPropertyState* pCharBorderDistances[4] = { 0, 0, 0, 0 };
+    XMLPropertyState* pCharNewBorderDistances[4] = { 0, 0, 0, 0 };
+    XMLPropertyState* pCharAllBorder = 0;
+    XMLPropertyState* pCharBorders[4] = { 0, 0, 0, 0 };
+    XMLPropertyState* pCharNewBorders[4] = { 0, 0, 0, 0 };
+    XMLPropertyState* pCharAllBorderWidth = 0;
+    XMLPropertyState* pCharBorderWidths[4] = { 0, 0, 0, 0 };
     XMLPropertyState* pVertOrient = 0;
     XMLPropertyState* pVertOrientRelAsChar = 0;
     XMLPropertyState* pBackTransparency = NULL; // transparency in %
@@ -364,12 +434,28 @@ void XMLTextImportPropertyMapper::finished(
         case CTF_RIGHTBORDER:           pBorders[XML_LINE_RIGHT] = property; break;
         case CTF_TOPBORDER:             pBorders[XML_LINE_TOP] = property; break;
         case CTF_BOTTOMBORDER:          pBorders[XML_LINE_BOTTOM] = property; break;
-
         case CTF_ALLBORDERWIDTH:        pAllBorderWidth = property; break;
         case CTF_LEFTBORDERWIDTH:       pBorderWidths[XML_LINE_LEFT] = property; break;
         case CTF_RIGHTBORDERWIDTH:      pBorderWidths[XML_LINE_RIGHT] = property; break;
         case CTF_TOPBORDERWIDTH:        pBorderWidths[XML_LINE_TOP] = property; break;
         case CTF_BOTTOMBORDERWIDTH:     pBorderWidths[XML_LINE_BOTTOM] = property; break;
+
+        case CTF_CHARALLBORDERDISTANCE:     pCharAllBorderDistance = property; break;
+        case CTF_CHARLEFTBORDERDISTANCE:    pCharBorderDistances[XML_LINE_LEFT] = property; break;
+        case CTF_CHARRIGHTBORDERDISTANCE:   pCharBorderDistances[XML_LINE_RIGHT] = property; break;
+        case CTF_CHARTOPBORDERDISTANCE:     pCharBorderDistances[XML_LINE_TOP] = property; break;
+        case CTF_CHARBOTTOMBORDERDISTANCE:  pCharBorderDistances[XML_LINE_BOTTOM] = property; break;
+        case CTF_CHARALLBORDER:             pCharAllBorder = property; break;
+        case CTF_CHARLEFTBORDER:            pCharBorders[XML_LINE_LEFT] = property; break;
+        case CTF_CHARRIGHTBORDER:           pCharBorders[XML_LINE_RIGHT] = property; break;
+        case CTF_CHARTOPBORDER:             pCharBorders[XML_LINE_TOP] = property; break;
+        case CTF_CHARBOTTOMBORDER:          pCharBorders[XML_LINE_BOTTOM] = property; break;
+        case CTF_CHARALLBORDERWIDTH:        pCharAllBorderWidth = property; break;
+        case CTF_CHARLEFTBORDERWIDTH:       pCharBorderWidths[XML_LINE_LEFT] = property; break;
+        case CTF_CHARRIGHTBORDERWIDTH:      pCharBorderWidths[XML_LINE_RIGHT] = property; break;
+        case CTF_CHARTOPBORDERWIDTH:        pCharBorderWidths[XML_LINE_TOP] = property; break;
+        case CTF_CHARBOTTOMBORDERWIDTH:     pCharBorderWidths[XML_LINE_BOTTOM] = property; break;
+
         case CTF_ANCHORTYPE:            break;
         case CTF_VERTICALPOS:           pVertOrient = property; break;
         case CTF_VERTICALREL_ASCHAR:    pVertOrientRelAsChar = property; break;
@@ -459,52 +545,24 @@ void XMLTextImportPropertyMapper::finished(
             pNewMargins[i].reset(new XMLPropertyState(
                 pAllMargin->mnIndex + i + 1, pAllMargin->maValue));
         }
-        if( pAllBorderDistance && !pBorderDistances[i] )
-        {
+
+        lcl_SeparateBorder(
+            i, pAllBorderDistance, pBorderDistances, pNewBorderDistances,
+            pAllBorder, pBorders, pNewBorders,
+            pAllBorderWidth, pBorderWidths
 #ifdef DBG_UTIL
-            sal_Int16 nTmp = getPropertySetMapper()->GetEntryContextId(
-                                        pAllBorderDistance->mnIndex + i + 1 );
-            DBG_ASSERT( nTmp >= CTF_LEFTBORDERDISTANCE &&
-                        nTmp <= CTF_BOTTOMBORDERDISTANCE,
-                        "wrong property context id" );
+            , getPropertySetMapper()
 #endif
-            pNewBorderDistances[i] =
-                new XMLPropertyState( pAllBorderDistance->mnIndex + i + 1,
-                                      pAllBorderDistance->maValue );
-            pBorderDistances[i] = pNewBorderDistances[i];
-        }
-        if( pAllBorder && !pBorders[i] )
-        {
+            );
+
+        lcl_SeparateBorder(
+            i, pCharAllBorderDistance, pCharBorderDistances,
+            pCharNewBorderDistances, pCharAllBorder, pCharBorders,
+            pCharNewBorders, pCharAllBorderWidth, pCharBorderWidths
 #ifdef DBG_UTIL
-            sal_Int16 nTmp = getPropertySetMapper()->GetEntryContextId(
-                                            pAllBorder->mnIndex + i + 1 );
-            DBG_ASSERT( nTmp >= CTF_LEFTBORDER && nTmp <= CTF_BOTTOMBORDER,
-                        "wrong property context id" );
+            , getPropertySetMapper()
 #endif
-            pNewBorders[i] = new XMLPropertyState( pAllBorder->mnIndex + i + 1,
-                                                   pAllBorder->maValue );
-            pBorders[i] = pNewBorders[i];
-        }
-        if( !pBorderWidths[i] )
-            pBorderWidths[i] = pAllBorderWidth;
-        else
-            pBorderWidths[i]->mnIndex = -1;
-
-        if( pBorders[i] && pBorderWidths[i] )
-        {
-            table::BorderLine2 aBorderLine;
-            pBorders[i]->maValue >>= aBorderLine;
-
-            table::BorderLine2 aBorderLineWidth;
-            pBorderWidths[i]->maValue >>= aBorderLineWidth;
-
-            aBorderLine.OuterLineWidth = aBorderLineWidth.OuterLineWidth;
-            aBorderLine.InnerLineWidth = aBorderLineWidth.InnerLineWidth;
-            aBorderLine.LineDistance = aBorderLineWidth.LineDistance;
-            aBorderLine.LineWidth = aBorderLineWidth.LineWidth;
-
-            pBorders[i]->maValue <<= aBorderLine;
-        }
+            );
     }
 
     if (pAllParaMargin)
@@ -525,6 +583,15 @@ void XMLTextImportPropertyMapper::finished(
     if( pAllBorderWidth )
         pAllBorderWidth->mnIndex = -1;
 
+    if( pCharAllBorderDistance )
+        pCharAllBorderDistance->mnIndex = -1;
+
+    if( pCharAllBorder )
+        pCharAllBorder->mnIndex = -1;
+
+    if( pCharAllBorderWidth )
+        pCharAllBorderWidth->mnIndex = -1;
+
     if( pVertOrient && pVertOrientRelAsChar )
     {
         sal_Int16 nVertOrient;
@@ -679,6 +746,16 @@ void XMLTextImportPropertyMapper::finished(
             rProperties.push_back( *pNewBorders[i] );
             delete pNewBorders[i];
         }
+        if( pCharNewBorderDistances[i] )
+        {
+            rProperties.push_back( *pCharNewBorderDistances[i] );
+            delete pCharNewBorderDistances[i];
+        }
+        if( pCharNewBorders[i] )
+        {
+            rProperties.push_back( *pCharNewBorders[i] );
+            delete pCharNewBorders[i];
+        }
     }
 
     if( bHasAnyHeight )
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index 21e5aaf..64430ee 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -44,6 +44,8 @@ using namespace ::xmloff::token;
     _M_E( a, p, l, (t|XML_TYPE_PROP_TEXT), c )
 #define MT_ED( a, p, l, t, c ) \
     _M_ED( a, p, l, (t|XML_TYPE_PROP_TEXT), c )
+#define MT_EV( a, p, l, t, c, v ) \
+    _M_EV( a, p, l, (t|XML_TYPE_PROP_TEXT), c, v )
 
 // paragraph properties
 #define MP_E( a, p, l, t, c ) \
@@ -218,7 +220,24 @@ XMLPropertyMapEntry aXMLParaPropMap[] =
     MT_E( "CharOverline",   STYLE,  TEXT_OVERLINE_WIDTH,        XML_TYPE_TEXT_OVERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_E( "CharOverlineColor",  STYLE,  TEXT_OVERLINE_COLOR,        XML_TYPE_TEXT_OVERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
     MT_E( "CharOverlineHasColor",   STYLE,  TEXT_OVERLINE_COLOR,        XML_TYPE_TEXT_OVERLINE_HASCOLOR|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
-
+    // RES_CHRATR_BOX
+    MT_EV( "CharLeftBorder", STYLE, BORDER_LINE_WIDTH, XML_TYPE_BORDER_WIDTH, CTF_CHARALLBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorder", STYLE, BORDER_LINE_WIDTH_LEFT, XML_TYPE_BORDER_WIDTH, CTF_CHARLEFTBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorder", STYLE, BORDER_LINE_WIDTH_RIGHT, XML_TYPE_BORDER_WIDTH, CTF_CHARRIGHTBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorder", STYLE, BORDER_LINE_WIDTH_TOP, XML_TYPE_BORDER_WIDTH, CTF_CHARTOPBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorder", STYLE, BORDER_LINE_WIDTH_BOTTOM, XML_TYPE_BORDER_WIDTH, CTF_CHARBOTTOMBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+
+    MT_EV( "CharLeftBorderDistance", FO, PADDING, XML_TYPE_MEASURE, CTF_CHARALLBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorderDistance", FO, PADDING_LEFT, XML_TYPE_MEASURE, CTF_CHARLEFTBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorderDistance", FO, PADDING_RIGHT, XML_TYPE_MEASURE, CTF_CHARRIGHTBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorderDistance",  FO, PADDING_TOP, XML_TYPE_MEASURE, CTF_CHARTOPBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorderDistance",FO, PADDING_BOTTOM, XML_TYPE_MEASURE, CTF_CHARBOTTOMBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+
+    MT_EV( "CharLeftBorder", FO, BORDER, XML_TYPE_BORDER, CTF_CHARALLBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorder", FO, BORDER_LEFT, XML_TYPE_BORDER, CTF_CHARLEFTBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorder", FO, BORDER_RIGHT, XML_TYPE_BORDER, CTF_CHARRIGHTBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorder", FO, BORDER_TOP, XML_TYPE_BORDER, CTF_CHARTOPBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorder", FO, BORDER_BOTTOM, XML_TYPE_BORDER, CTF_CHARBOTTOMBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
     // RES_TXTATR_INETFMT
     // TODO
     // RES_TXTATR_REFMARK
@@ -525,7 +544,24 @@ XMLPropertyMapEntry aXMLTextPropMap[] =
     MT_E( "CharOverline",   STYLE,  TEXT_OVERLINE_WIDTH,        XML_TYPE_TEXT_OVERLINE_WIDTH|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_E( "CharOverlineColor",  STYLE,  TEXT_OVERLINE_COLOR,        XML_TYPE_TEXT_OVERLINE_COLOR|MID_FLAG_MULTI_PROPERTY, 0 ),
     MT_E( "CharOverlineHasColor",   STYLE,  TEXT_OVERLINE_COLOR,        XML_TYPE_TEXT_OVERLINE_HASCOLOR|MID_FLAG_MERGE_ATTRIBUTE, 0 ),
-
+    // RES_CHRATR_BOX
+    MT_EV( "CharLeftBorder", STYLE, BORDER_LINE_WIDTH, XML_TYPE_BORDER_WIDTH, CTF_CHARALLBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorder", STYLE, BORDER_LINE_WIDTH_LEFT, XML_TYPE_BORDER_WIDTH, CTF_CHARLEFTBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorder", STYLE, BORDER_LINE_WIDTH_RIGHT, XML_TYPE_BORDER_WIDTH, CTF_CHARRIGHTBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorder", STYLE, BORDER_LINE_WIDTH_TOP, XML_TYPE_BORDER_WIDTH, CTF_CHARTOPBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorder", STYLE, BORDER_LINE_WIDTH_BOTTOM, XML_TYPE_BORDER_WIDTH, CTF_CHARBOTTOMBORDERWIDTH, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+
+    MT_EV( "CharLeftBorderDistance", FO, PADDING, XML_TYPE_MEASURE, CTF_CHARALLBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorderDistance", FO, PADDING_LEFT, XML_TYPE_MEASURE, CTF_CHARLEFTBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorderDistance", FO, PADDING_RIGHT, XML_TYPE_MEASURE, CTF_CHARRIGHTBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorderDistance", FO, PADDING_TOP, XML_TYPE_MEASURE, CTF_CHARTOPBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorderDistance",FO, PADDING_BOTTOM, XML_TYPE_MEASURE, CTF_CHARBOTTOMBORDERDISTANCE, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+
+    MT_EV( "CharLeftBorder", FO, BORDER, XML_TYPE_BORDER, CTF_CHARALLBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharLeftBorder", FO, BORDER_LEFT, XML_TYPE_BORDER, CTF_CHARLEFTBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharRightBorder", FO, BORDER_RIGHT, XML_TYPE_BORDER, CTF_CHARRIGHTBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharTopBorder", FO, BORDER_TOP, XML_TYPE_BORDER, CTF_CHARTOPBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
+    MT_EV( "CharBottomBorder", FO, BORDER_BOTTOM, XML_TYPE_BORDER, CTF_CHARBOTTOMBORDER, SvtSaveOptions::ODFVER_012_EXT_COMPAT ),
     // RES_TXTATR_INETFMT
     MT_E( "HyperLinkURL",           TEXT,       XMLNS,                      XML_TYPE_STRING|MID_FLAG_NO_PROPERTY_IMPORT,    CTF_HYPERLINK_URL ),
     // RES_TXTATR_REFMARK
commit 54d13384deaeb545011c12720a131554bf40da7d
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date:   Mon Aug 12 18:49:06 2013 +0200

    Add since to character border idl
    
    Change-Id: I06064b1145578579c8748b6e5326090303aa670e

diff --git a/offapi/com/sun/star/style/CharacterProperties.idl b/offapi/com/sun/star/style/CharacterProperties.idl
index d03a302..920c55d 100644
--- a/offapi/com/sun/star/style/CharacterProperties.idl
+++ b/offapi/com/sun/star/style/CharacterProperties.idl
@@ -375,39 +375,57 @@ published service CharacterProperties
     [optional, property] com::sun::star::container::XNameContainer  TextUserDefinedAttributes;
 
     /** This property contains the left border of the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] com::sun::star::table::BorderLine2 CharLeftBorder;
 
     /** This property contains the right border of the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] com::sun::star::table::BorderLine2 CharRightBorder;
 
     /** This property contains the top border of the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] com::sun::star::table::BorderLine2 CharTopBorder;
 
     /** This property contains the bottom border of the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] com::sun::star::table::BorderLine2 CharBottomBorder;
 
     /** This property contains the distance from the border to the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] long CharBorderDistance;
 
     /** This property contains the distance from the left border to the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] long CharLeftBorderDistance;
 
     /** This property contains the distance from the right border to the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] long CharRightBorderDistance;
 
     /** This property contains the distance from the top border to the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] long CharTopBorderDistance;
 
     /** This property contains the distance from the bottom border to the object.
-     */
+     *
+     *  @since LibreOffice 4.2
+    **/
     [property, optional] long CharBottomBorderDistance;
 
 };


More information about the Libreoffice-commits mailing list