CharBrd 4.3: drop caps

-Increase the height with the borders width.
(drop portion calculates the height by own, but width is right)
-Avoid caching when there is a border, because caching work
with height and it can happen that border change, but height not.
-Avoid drop portion height when calculate the line height
(except when there is only one line)
-Drop portion has an own font, so we have to use this
font when change the cursor position.
-When painting text, use the current drop portion
part width.

Change-Id: I3d8f4ef9e6f067e28827453f9b6412184943b72e
This commit is contained in:
Zolnai Tamás
2013-08-01 20:17:41 +02:00
parent 8bdb895587
commit 051b59ca35
4 changed files with 81 additions and 6 deletions

View File

@@ -379,6 +379,8 @@ public:
const boost::optional<editeng::SvxBorderLine>& GetAbsBottomBorder( const bool bVertLayout ) const;
const boost::optional<editeng::SvxBorderLine>& GetAbsRightBorder( const bool bVertLayout ) const;
const boost::optional<editeng::SvxBorderLine>& 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

View File

@@ -29,6 +29,7 @@
#include <editeng/adjustitem.hxx>
#include <editeng/lspcitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/borderline.hxx>
#include <frmatr.hxx>
#include <pagedesc.hxx> // SwPageDesc
#include <tgrditem.hxx>
@@ -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<SwDropPortion*>(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<SwDropPortion*>(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 )

View File

@@ -27,6 +27,7 @@
#include "porfly.hxx" // SwFlyCntPortion
#include <porrst.hxx> // SwHangingPortion
#include <pormulti.hxx> // SwMultiPortion
#include <pordrop.hxx> // SwDropPortion
#include <breakit.hxx>
#include <unicode/uchar.h>
#include <com/sun/star/i18n/ScriptType.hpp>
@@ -370,6 +371,14 @@ void SwLineLayout::CalcLine( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf )
}
}
// Ignore drop portion height
if( pPos->IsDropPortion() && static_cast<SwDropPortion*>(pPos)->GetLines() > 1)
{
pLast = pPos;
pPos = pPos->GetPortion();
continue;
}
bHasOnlyBlankPortions = false;
// We had an attribute change: Sum up/build maxima of length and mass

View File

@@ -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;