diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx index 532ee1ed1789..a57a20f9d3d7 100644 --- a/sw/source/core/inc/swfont.hxx +++ b/sw/source/core/inc/swfont.hxx @@ -379,6 +379,8 @@ public: const boost::optional& GetAbsBottomBorder( const bool bVertLayout ) const; const boost::optional& GetAbsRightBorder( const bool bVertLayout ) const; const boost::optional& GetAbsLeftBorder( const bool bVertLayout ) const; + + bool HasBorder() const; }; inline void SwFont::SetColor( const Color& rColor ) @@ -828,6 +830,11 @@ inline void SwSubFont::SetVertical( const sal_uInt16 nDir, const sal_Bool bVertF Font::SetOrientation( nDir ); } +inline bool SwFont::HasBorder() const +{ + return m_aTopBorder || m_aBottomBorder || m_aLeftBorder || m_aRightBorder; +} + /************************************************************************* * class SwUnderlineFont diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 17b76813fadb..3e97fa7c5a61 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include // SwPageDesc #include @@ -925,9 +926,28 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, // Shift the cursor with the right border width // Note: nX remains positive because GetTxtSize() also include the width of the right border - if( GetInfo().GetFont()->GetRightBorder() && aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() ) + if( aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() ) + { + // Find the current drop portion part and use its right border + if( pPor->IsDropPortion() ) + { + SwDropPortion* pDrop = static_cast(pPor); + const SwDropPortionPart* pCurrPart = pDrop->GetPart(); + sal_Int16 nSumLength = 0; + while( pCurrPart && (nSumLength += pCurrPart->GetLen()) < nOfst - aInf.GetIdx() ) + { + pCurrPart = pCurrPart->GetFollow(); + } + if( pCurrPart && nSumLength != nOfst - aInf.GetIdx() && pCurrPart->GetFont().GetRightBorder() ) + { + nX -= pCurrPart->GetFont().GetRightBorder().get().GetScaledWidth(); + } + } + else if(GetInfo().GetFont()->GetRightBorder()) + { nX -= GetInfo().GetFont()->GetRightBorder().get().GetScaledWidth(); - + } + } } bWidth = sal_False; break; @@ -1088,7 +1108,7 @@ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, if ( pCMS->pSpecialPos ) { // apply attributes to font - Seek( nOfst ); + SeekAndChgAttrIter( nOfst, aInf.GetOut() ); lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor ); } } @@ -1617,10 +1637,34 @@ xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint, aSizeInf.GetIdx(), pPor->GetLen() ); + // Drop portion works like a multi portion, just its parts are not portions + if( pPor->IsDropPortion() ) + { + SwDropPortion* pDrop = static_cast(pPor); + const SwDropPortionPart* pCurrPart = pDrop->GetPart(); + sal_uInt16 nSumWidth = 0; + sal_uInt16 nSumBorderWidth = 0; + // Shift offset with the right and left border of previous parts and left border of actual one + while( pCurrPart && nSumWidth <= nX - nCurrStart ) + { + nSumWidth += pCurrPart->GetWidth(); + if( pCurrPart->GetFont().GetLeftBorder() ) + { + nSumBorderWidth += pCurrPart->GetFont().GetLeftBorder().get().GetScaledWidth(); + } + if( nSumWidth <= nX - nCurrStart && pCurrPart->GetFont().GetRightBorder() ) + { + nSumBorderWidth += pCurrPart->GetFont().GetRightBorder().get().GetScaledWidth(); + } + pCurrPart = pCurrPart->GetFollow(); + } + nX = std::max(0, nX - nSumBorderWidth); + } // Shift the offset with the left border width - if( GetInfo().GetFont()->GetLeftBorder() ) + else if (GetInfo().GetFont()->GetLeftBorder() ) nX = std::max(0, nX - GetInfo().GetFont()->GetLeftBorder().get().GetScaledWidth()); + aDrawInf.SetOfst( nX ); if ( nSpaceAdd ) diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index edc8458689e5..45ec2e9d2b0a 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -27,6 +27,7 @@ #include "porfly.hxx" // SwFlyCntPortion #include // SwHangingPortion #include // SwMultiPortion +#include // SwDropPortion #include #include #include @@ -370,6 +371,14 @@ void SwLineLayout::CalcLine( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf ) } } + // Ignore drop portion height + if( pPos->IsDropPortion() && static_cast(pPos)->GetLines() > 1) + { + pLast = pPos; + pPos = pPos->GetPortion(); + continue; + } + bHasOnlyBlankPortions = false; // We had an attribute change: Sum up/build maxima of length and mass diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx index d708cc67c2c0..5d2d5a2688fc 100644 --- a/sw/source/core/text/txtdrop.cxx +++ b/sw/source/core/text/txtdrop.cxx @@ -281,6 +281,7 @@ void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const const SwDropPortionPart* pCurrPart = GetPart(); const xub_StrLen nOldLen = GetLen(); + const KSHORT nOldWidth = Width(); const KSHORT nOldAscent = GetAscent(); const SwTwips nBasePosY = rInf.Y(); @@ -294,6 +295,7 @@ void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const while ( pCurrPart ) { ((SwDropPortion*)this)->SetLen( pCurrPart->GetLen() ); + ((SwDropPortion*)this)->Width( pCurrPart->GetWidth() ); ((SwTxtPaintInfo&)rInf).SetLen( pCurrPart->GetLen() ); SwFontSave aFontSave( rInf, &pCurrPart->GetFont() ); @@ -305,6 +307,7 @@ void SwDropPortion::PaintTxt( const SwTxtPaintInfo &rInf ) const } ((SwTxtPaintInfo&)rInf).Y( nBasePosY ); + ((SwDropPortion*)this)->Width( nOldWidth ); ((SwDropPortion*)this)->SetLen( nOldLen ); ((SwDropPortion*)this)->SetAscent( nOldAscent ); } @@ -601,7 +604,7 @@ SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf ) while ( nNextChg < nPorLen ) { // check for attribute changes and if the portion has to split: - Seek( nNextChg ); + SeekAndChgAttrIter( nNextChg, rInf.GetOut() ); // the font is deleted in the destructor of the drop portion part SwFont* pTmpFnt = new SwFont( *rInf.GetFont() ); @@ -737,7 +740,7 @@ void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf ) OSL_ENSURE( pDrop->GetPart(),"DropPortion without part during font calculation"); SwDropPortionPart* pCurrPart = pDrop->GetPart(); - const bool bUseCache = ! pCurrPart->GetFollow(); + const bool bUseCache = ! pCurrPart->GetFollow() && !pCurrPart->GetFont().HasBorder(); xub_StrLen nIdx = rInf.GetIdx(); XubString aStr( rInf.GetTxt(), nIdx, pCurrPart->GetLen() ); @@ -885,6 +888,18 @@ void SwDropCapCache::CalcFontSize( SwDropPortion* pDrop, SwTxtFormatInfo &rInf ) rFnt.SetSize( aOldSize, rFnt.GetActual() ); rFnt.SetProportion( nOldProp ); + // Modify the bounding rectangle with the borders + if( rFnt.GetTopBorder() ) + { + aRect.setHeight(aRect.GetHeight() + rFnt.GetTopBorder().get().GetScaledWidth()); + aRect.setY(aRect.getY() - rFnt.GetTopBorder().get().GetScaledWidth()); + } + + if( rFnt.GetBottomBorder() ) + { + aRect.setHeight(aRect.GetHeight() + rFnt.GetBottomBorder().get().GetScaledWidth()); + } + if ( bFirstGlyphRect ) { aCommonRect = aRect;