blob: ef8b7b2b573f5c5b85d151d257efea8e0b718b26 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <viewopt.hxx> // SwViewOptions
#include <SwPortionHandler.hxx>
#include <inftxt.hxx>
#include <porexp.hxx>
/*************************************************************************
* class SwExpandPortion
*************************************************************************/
xub_StrLen SwExpandPortion::GetCrsrOfst( const MSHORT nOfst ) const
{ return SwLinePortion::GetCrsrOfst( nOfst ); }
/*************************************************************************
* virtual SwExpandPortion::GetExpTxt()
*************************************************************************/
sal_Bool SwExpandPortion::GetExpTxt( const SwTxtSizeInfo&,
XubString &rTxt ) const
{
rTxt.Erase();
// Nicht etwa: return 0 != rTxt.Len();
// Weil: leere Felder ersetzen CH_TXTATR gegen einen Leerstring
return sal_True;
}
/*************************************************************************
* virtual SwExpandPortion::HandlePortion()
*************************************************************************/
void SwExpandPortion::HandlePortion( SwPortionHandler& rPH ) const
{
String aString;
rPH.Special( GetLen(), aString, GetWhichPor() );
}
/*************************************************************************
* virtual SwExpandPortion::GetTxtSize()
*************************************************************************/
SwPosSize SwExpandPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const
{
SwTxtSlot aDiffTxt( &rInf, this, false, false );
return rInf.GetTxtSize();
}
/*************************************************************************
* virtual SwExpandPortion::Format()
*************************************************************************/
// 5010: Exp und Tabs
sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf )
{
SwTxtSlot aDiffTxt( &rInf, this, true, false );
const xub_StrLen nFullLen = rInf.GetLen();
// So komisch es aussieht, die Abfrage auf GetLen() muss wegen der
// ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs)
// sal_False returnen wegen SetFull ...
if( !nFullLen )
{
// nicht Init(), weil wir Hoehe und Ascent brauchen
Width(0);
return sal_False;
}
return SwTxtPortion::Format( rInf );
}
/*************************************************************************
* virtual SwExpandPortion::Paint()
*************************************************************************/
void SwExpandPortion::Paint( const SwTxtPaintInfo &rInf ) const
{
SwTxtSlot aDiffTxt( &rInf, this, true, true );
rInf.DrawBackBrush( *this );
// do we have to repaint a post it portion?
if( rInf.OnWin() && pPortion && !pPortion->Width() )
pPortion->PrePaint( rInf, this );
// The contents of field portions is not considered during the
// calculation of the directions. Therefore we let vcl handle
// the calculation by removing the BIDI_STRONG_FLAG temporarily.
SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() );
aLayoutModeModifier.SetAuto();
// ST2
if ( rInf.GetSmartTags() || rInf.GetGrammarCheckList() )
rInf.DrawMarkedText( *this, rInf.GetLen(), sal_False, sal_False,
0 != rInf.GetSmartTags(), 0 != rInf.GetGrammarCheckList() );
else
rInf.DrawText( *this, rInf.GetLen(), sal_False );
}
/*************************************************************************
* class SwBlankPortion
*************************************************************************/
SwLinePortion *SwBlankPortion::Compress() { return this; }
/*************************************************************************
* SwBlankPortion::MayUnderFlow()
*************************************************************************/
// 5497: Es gibt schon Gemeinheiten auf der Welt...
// Wenn eine Zeile voll mit HardBlanks ist und diese ueberlaeuft,
// dann duerfen keine Underflows generiert werden!
// Komplikationen bei Flys...
MSHORT SwBlankPortion::MayUnderFlow( const SwTxtFormatInfo &rInf,
xub_StrLen nIdx, sal_Bool bUnderFlow ) const
{
if( rInf.StopUnderFlow() )
return 0;
const SwLinePortion *pPos = rInf.GetRoot();
if( pPos->GetPortion() )
pPos = pPos->GetPortion();
while( pPos && pPos->IsBlankPortion() )
pPos = pPos->GetPortion();
if( !pPos || !rInf.GetIdx() || ( !pPos->GetLen() && pPos == rInf.GetRoot() ) )
return 0; // Nur noch BlankPortions unterwegs
// Wenn vor uns ein Blank ist, brauchen wir kein Underflow ausloesen,
// wenn hinter uns ein Blank ist, brauchen wir kein Underflow weiterreichen
if( bUnderFlow && CH_BLANK == rInf.GetTxt().GetChar( nIdx + 1) )
return 0;
if( nIdx && !((SwTxtFormatInfo&)rInf).GetFly() )
{
while( pPos && !pPos->IsFlyPortion() )
pPos = pPos->GetPortion();
if( !pPos )
{
//Hier wird ueberprueft, ob es in dieser Zeile noch sinnvolle Umbrueche
//gibt, Blanks oder Felder etc., wenn nicht, kein Underflow.
//Wenn Flys im Spiel sind, lassen wir das Underflow trotzdem zu.
xub_StrLen nBlank = nIdx;
while( --nBlank > rInf.GetLineStart() )
{
const xub_Unicode cCh = rInf.GetChar( nBlank );
if( CH_BLANK == cCh ||
(( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh )
&& rInf.HasHint( nBlank ) ) )
break;
}
if( nBlank <= rInf.GetLineStart() )
return 0;
}
}
xub_Unicode cCh;
if( nIdx < 2 || CH_BLANK == (cCh = rInf.GetChar( nIdx - 1 )) )
return 1;
if( CH_BREAK == cCh )
return 0;
return 2;
}
/*************************************************************************
* virtual SwBlankPortion::FormatEOL()
*************************************************************************/
// Format end of Line
void SwBlankPortion::FormatEOL( SwTxtFormatInfo &rInf )
{
MSHORT nMay = MayUnderFlow( rInf, rInf.GetIdx() - nLineLength, sal_True );
if( nMay )
{
if( nMay > 1 )
{
if( rInf.GetLast() == this )
rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
rInf.X( rInf.X() - PrtWidth() );
rInf.SetIdx( rInf.GetIdx() - GetLen() );
}
Truncate();
rInf.SetUnderFlow( this );
if( rInf.GetLast()->IsKernPortion() )
rInf.SetUnderFlow( rInf.GetLast() );
}
}
/*************************************************************************
* virtual SwBlankPortion::Format()
*************************************************************************/
// 7771: UnderFlows weiterreichen und selbst ausloesen!
sal_Bool SwBlankPortion::Format( SwTxtFormatInfo &rInf )
{
const sal_Bool bFull = rInf.IsUnderFlow() || SwExpandPortion::Format( rInf );
if( bFull && MayUnderFlow( rInf, rInf.GetIdx(), rInf.IsUnderFlow() ) )
{
Truncate();
rInf.SetUnderFlow( this );
if( rInf.GetLast()->IsKernPortion() )
rInf.SetUnderFlow( rInf.GetLast() );
}
return bFull;
}
/*************************************************************************
* virtual SwBlankPortion::Paint()
*************************************************************************/
void SwBlankPortion::Paint( const SwTxtPaintInfo &rInf ) const
{
if( !bMulti ) // No gray background for multiportion brackets
rInf.DrawViewOpt( *this, POR_BLANK );
SwExpandPortion::Paint( rInf );
}
/*************************************************************************
* virtual SwBlankPortion::GetExpTxt()
*************************************************************************/
sal_Bool SwBlankPortion::GetExpTxt( const SwTxtSizeInfo&, XubString &rTxt ) const
{
rTxt = cChar;
return sal_True;
}
/*************************************************************************
* virtual SwBlankPortion::HandlePortion()
*************************************************************************/
void SwBlankPortion::HandlePortion( SwPortionHandler& rPH ) const
{
String aString( cChar );
rPH.Special( GetLen(), aString, GetWhichPor() );
}
/*************************************************************************
* class SwPostItsPortion
*************************************************************************/
SwPostItsPortion::SwPostItsPortion( sal_Bool bScrpt )
: nViewWidth(0), bScript( bScrpt )
{
nLineLength = 1;
SetWhichPor( POR_POSTITS );
}
void SwPostItsPortion::Paint( const SwTxtPaintInfo &rInf ) const
{
if( rInf.OnWin() && Width() )
rInf.DrawPostIts( *this, IsScript() );
}
KSHORT SwPostItsPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
{
// Nicht zu fassen: PostIts sind immer zu sehen.
return rInf.OnWin() ?
(KSHORT)rInf.GetOpt().GetPostItsWidth( rInf.GetOut() ) : 0;
}
/*************************************************************************
* virtual SwPostItsPortion::Format()
*************************************************************************/
sal_Bool SwPostItsPortion::Format( SwTxtFormatInfo &rInf )
{
sal_Bool bRet = SwLinePortion::Format( rInf );
// 32749: PostIts sollen keine Auswirkung auf Zeilenhoehe etc. haben
SetAscent( 1 );
Height( 1 );
return bRet;
}
/*************************************************************************
* virtual SwPostItsPortion::GetExpTxt()
*************************************************************************/
sal_Bool SwPostItsPortion::GetExpTxt( const SwTxtSizeInfo &rInf,
XubString &rTxt ) const
{
if( rInf.OnWin() && rInf.GetOpt().IsPostIts() )
rTxt = ' ';
else
rTxt.Erase();
return sal_True;
}