// We lock it, to start with
OSL_ENSURE( !IsLocked(), "SwTextFrame::Hyphenate: this is locked" );
// The frame::Frame must have a valid SSize!
Calc(pRenderContext);
GetFormatted();
bool bRet = false; if( !IsEmpty() )
{ // We always need to enable hyphenation // Don't be afraid: the SwTextIter saves the old row in the hyphenate
TextFrameLockGuard aLock( this );
// If we're within the first word of a row, it could've been hyphenated // in the row earlier. // That's why we go one row back. if( aLine.Prev() )
{
SwLinePortion *pPor = aLine.GetCurr()->GetFirstPortion(); while( pPor->GetNextPortion() )
pPor = pPor->GetNextPortion(); if( pPor->GetWhichPor() == PortionType::SoftHyphen ||
pPor->GetWhichPor() == PortionType::SoftHyphenStr )
aLine.Next();
}
// We never need to hyphenate anything in the last row // Except for, if it contains a FlyPortion or if it's the // last row of the Master if( !GetNext() && !rInf.GetTextFly().IsOn() && !m_pFrame->GetFollow() ) returnfalse;
TextFrameIndex nWrdStart = m_nStart;
// We need to retain the old row // E.g.: The attribute for hyphenation was not set, but // it's always set in SwTextFrame::Hyphenate, because we want // to set breakpoints.
SwLineLayout *pOldCurr = m_pCurr;
InitCntHyph();
// 5298: IsParaLine() (ex.IsFirstLine) calls GetParaPortion(). // We have to create the same conditions: in the first line // we format SwParaPortions... if( pOldCurr->IsParaPortion() )
{
SwParaPortion *pPara = new SwParaPortion();
SetParaPortion( &rInf, pPara );
m_pCurr = pPara;
OSL_ENSURE( IsParaLine(), "SwTextFormatter::Hyphenate: not the first" );
} else
m_pCurr = new SwLineLayout();
nWrdStart = FormatLine( nWrdStart );
// You always should keep in mind that for example there are fields // which can be hyphenated if( m_pCurr->PrtWidth() && m_pCurr->GetLen() )
{ // We must be prepared that there are FlyFrames in the line, // at which line breaking is possible. So we search for the first // HyphPortion in the specified range.
SwLinePortion *pPos = m_pCurr->GetNextPortion(); const TextFrameIndex nPamStart = rHyphInf.m_nStart;
nWrdStart = m_nStart; const TextFrameIndex nEnd = rHyphInf.m_nEnd; while( pPos )
{ // Either we are above or we are running into a HyphPortion // at the end of line or before a Fly. if( nWrdStart >= nEnd )
{
nWrdStart = TextFrameIndex(0); break;
}
nWrdStart = nWrdStart + pPos->GetLen();
pPos = pPos->GetNextPortion();
} // When pPos is null, no hyphen position was found. if( !pPos )
nWrdStart = TextFrameIndex(0);
} else // In case the whole line is zero-length, that's the same situation as // above when the portion iteration ends without explicitly breaking // from the loop.
nWrdStart = TextFrameIndex(0);
// the old LineLayout is set again ... delete m_pCurr;
m_pCurr = pOldCurr;
if( pOldCurr->IsParaPortion() )
{
SetParaPortion( &rInf, static_cast<SwParaPortion*>(pOldCurr) );
OSL_ENSURE( IsParaLine(), "SwTextFormatter::Hyphenate: even not the first" );
}
if (nWrdStart == TextFrameIndex(0)) returnfalse;
// nWrdStart contains the position in string that should be hyphenated
rHyphInf.m_nWordStart = nWrdStart;
OSL_ENSURE( !mpNextPortion, "SwTextPortion::CreateHyphen(): another portion, another planet..." );
OSL_ENSURE( xHyphWord.is(), "SwTextPortion::CreateHyphen(): You are lucky! The code is robust here." );
// first case: hyphenated word has alternative spelling if ( xHyphWord->isAlternativeSpelling() )
{
SvxAlternativeSpelling aAltSpell = SvxGetAltSpelling( xHyphWord );
OSL_ENSURE( aAltSpell.bIsAltSpelling, "no alternative spelling" );
// values required for this
nPorEnd = TextFrameIndex(xHyphWord->getHyphenPos() + 1)
+ rGuess.BreakStart() - rGuess.FieldDiff();
}
// portion end must be in front of us // we do not put hyphens at start of line if ( nPorEnd > rInf.GetIdx() ||
( nPorEnd == rInf.GetIdx() && rInf.GetLineStart() != rInf.GetIdx() ) )
{
aInf.SetLen( nPorEnd - rInf.GetIdx() ); if (auto stClampedContext = aInf.GetLayoutContext(); stClampedContext.has_value())
{
stClampedContext->m_nEnd = nPorEnd.get();
aInf.SetLayoutContext(stClampedContext);
}
SwTwips SwSoftHyphPortion::GetViewWidth(const SwTextSizeInfo& rInf) const
{ // Although we're in the const, nViewWidth should be calculated at // the last possible moment if( !Width() && rInf.OnWin() && rInf.GetOpt().IsSoftHyph() && !IsExpand() )
{ if( !m_nViewWidth ) const_cast<SwSoftHyphPortion*>(this)->m_nViewWidth
= rInf.GetTextSize(OUString('-')).Width();
} else const_cast<SwSoftHyphPortion*>(this)->m_nViewWidth = 0; return m_nViewWidth;
}
// special case for old German spelling if( rInf.IsUnderflow() )
{ if( rInf.GetSoftHyphPos() ) returntrue;
constbool bHyph = rInf.ChgHyph( true ); if( rInf.IsHyphenate() )
{
rInf.SetSoftHyphPos( rInf.GetIdx() );
Width(0); // if the soft hyphened word has an alternative spelling // when hyphenated (old German spelling), the soft hyphen // portion has to trigger an underflow
SwTextGuess aGuess;
bFull = rInf.IsInterHyph() ||
!aGuess.AlternativeSpelling(rInf, rInf.GetIdx() - TextFrameIndex(1));
}
rInf.ChgHyph( bHyph );
rInf.SetSoftHyphPos(TextFrameIndex(0));
SetExpand( true );
bFull = SwHyphPortion::Format( rInf );
SetExpand( false ); if( !bFull )
{ // By default, we do not have a width, but we do have a height
Width(0);
} return bFull;
}
// We need to reset the old values const SwTwips nOldX = rInf.X();
TextFrameIndex const nOldIdx = rInf.GetIdx();
rInf.X( rInf.X() - PrtWidth() );
rInf.SetIdx( rInf.GetIdx() - GetLen() ); constbool bFull = SwHyphPortion::Format( rInf );
// Shady business: We're allowed to get wider, but a Fly is also // being processed, which needs a correct X position if( bFull || !rInf.GetFly() )
rInf.X( nOldX ); else
rInf.X( nOldX + Width() );
rInf.SetIdx( nOldIdx );
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.