diff options
author | Andreas Martens <ama@openoffice.org> | 2000-11-06 08:20:28 +0000 |
---|---|---|
committer | Andreas Martens <ama@openoffice.org> | 2000-11-06 08:20:28 +0000 |
commit | 2b7d5c9aca976b787790d8837d2a884ed6cef594 (patch) | |
tree | 99f0b5747cc0210449fa84b74778fa90f7281fa1 /sw/source/core | |
parent | 8c15e5398f5a3e59cb41c462f5b8d9e11aaf6268 (diff) |
New: phonetic character aside the main text
Diffstat (limited to 'sw/source/core')
-rw-r--r-- | sw/source/core/text/frmform.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/text/inftxt.hxx | 11 | ||||
-rw-r--r-- | sw/source/core/text/itradj.cxx | 23 | ||||
-rw-r--r-- | sw/source/core/text/itrcrsr.cxx | 19 | ||||
-rw-r--r-- | sw/source/core/text/itrform2.cxx | 35 | ||||
-rw-r--r-- | sw/source/core/text/pormulti.cxx | 534 | ||||
-rw-r--r-- | sw/source/core/text/pormulti.hxx | 104 |
7 files changed, 557 insertions, 178 deletions
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 2406c7eee8d7..7e38678dc577 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -2,9 +2,9 @@ * * $RCSfile: frmform.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: ama $ $Date: 2000-10-26 07:36:20 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:13:07 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -1330,9 +1330,10 @@ void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf, if( GetOfst() && 0 != (pTwoLines = rInf.GetTwoLines( GetOfst()-1) ) ) { - SwMultiPortion* pTmp = - new SwMultiPortion( *pTwoLines->GetEnd() ); + SwDoubleLinePortion* pTmp = + new SwDoubleLinePortion( *pTwoLines->GetEnd() ); #ifdef DEBUG + //pTmp->SetRuby( pRest ); pTmp->SetBrackets( 0, ']' ); #endif pTmp->SetFldRest( pRest ); diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx index b29dc687c3ee..12fd1d0fe4ef 100644 --- a/sw/source/core/text/inftxt.hxx +++ b/sw/source/core/text/inftxt.hxx @@ -2,9 +2,9 @@ * * $RCSfile: inftxt.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: ama $ $Date: 2000-10-30 10:06:45 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:20:28 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -61,7 +61,7 @@ #ifndef _INFTXT_HXX #define _INFTXT_HXX -#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> +#include <com/sun/star/linguistic/XHyphenatedWord.hpp> #include "swtypes.hxx" #include "txttypes.hxx" @@ -191,6 +191,7 @@ protected: sal_Bool bFtnInside : 1; // the current line contains a footnote sal_Bool bMulti : 1; // inside a multiportion sal_Bool bFirstMulti : 1; // the multiportion is the first lineportion + sal_Bool bRuby : 1; // during the formatting of a phonetic line protected: void _NoteAnimation(); @@ -229,6 +230,8 @@ public: inline void SetMulti( const sal_Bool bNew ) { bMulti = bNew; } inline sal_Bool IsFirstMulti() const { return bFirstMulti; } inline void SetFirstMulti( const sal_Bool bNew ) { bFirstMulti = bNew; } + inline sal_Bool IsRuby() const { return bRuby; } + inline void SetRuby( const sal_Bool bNew ) { bRuby = bNew; } inline ViewShell *GetVsh() { return pVsh; } inline const ViewShell *GetVsh() const { return pVsh; } inline OutputDevice *GetOut() { return pOut; } @@ -591,7 +594,7 @@ public: void RestoreHyphOptions(); // ruft HyphenateWord() des Hyphenators ::com::sun::star::uno::Reference< - ::com::sun::star::linguistic2::XHyphenatedWord > + ::com::sun::star::linguistic::XHyphenatedWord > HyphWord( const String &rTxt, const USHORT nMinTrail ); sal_Bool CheckFtnPortion( SwLineLayout* pCurr ) diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx index bbe255958a31..2c0c876a928f 100644 --- a/sw/source/core/text/itradj.cxx +++ b/sw/source/core/text/itradj.cxx @@ -2,9 +2,9 @@ * * $RCSfile: itradj.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: ama $ $Date: 2000-10-30 09:58:58 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:13:59 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -198,6 +198,10 @@ void SwTxtAdjuster::CalcNewBlock( SwLineLayout *pCurr, else if( pPos->IsMultiPortion() ) { SwMultiPortion* pMulti = (SwMultiPortion*)pPos; + // a multiportion with a tabulator inside breaks the text adjustment + // a ruby portion will not be stretched by text adjustment + // a double line portion takes additional space for each blank + // in the wider line if( pMulti->HasTabulator() ) { if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() ) @@ -206,8 +210,8 @@ void SwTxtAdjuster::CalcNewBlock( SwLineLayout *pCurr, nGluePortion = 0; nCharCnt = 0; } - else - nGluePortion += pMulti->GetSpaceCnt(); + else if( pMulti->IsDouble() ) + nGluePortion += ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt(); } if( pPos->InGlueGrp() ) @@ -310,8 +314,6 @@ SwMarginPortion *SwTxtAdjuster::CalcRightMargin( SwLineLayout *pCurr, void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr ) { - const SwRect aLineRect( GetLeftMargin(), Y(), - ((SwFrm*)pFrm)->Prt().Width(), GetLineHeight() ); // 1) Es wird ein linker Rand eingefuegt: SwMarginPortion *pLeft = pCurr->CalcLeftMargin(); SwGluePortion *pGlue = pLeft; // die letzte GluePortion @@ -322,10 +324,6 @@ void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr ) // FlyFrms. CalcRightMargin( pCurr ); -#ifdef USED - pCurr->PackFlys(); -#endif - SwLinePortion *pPos = pLeft->GetPortion(); xub_StrLen nLen = 0; @@ -382,11 +380,6 @@ void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr ) if( SVX_ADJUST_RIGHT == GetAdjust() ) pLeft->AdjustRight(); - -#ifdef DEBUG - // um einen Breakpoint setzen zu koennen: - nLen = 0; -#endif } /************************************************************************* diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx index 43af01e467eb..e1dca6b03f68 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -2,9 +2,9 @@ * * $RCSfile: itrcrsr.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: ama $ $Date: 2000-10-30 09:59:14 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:15:00 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -400,7 +400,7 @@ sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, bNoTxt = sal_False; nFirst = nX; } - if( pPor->IsMultiPortion() && + if( pPor->IsMultiPortion() && pSpaceAdd && ((SwMultiPortion*)pPor)->HasTabulator() ) { if ( ++nSpaceIdx < pSpaceAdd->Count() ) @@ -466,7 +466,7 @@ sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, !pPor->GetPortion()->IsMarginPortion() ) ) nX += pPor->PrtWidth(); } - if( pPor->IsMultiPortion() && + if( pPor->IsMultiPortion() && pSpaceAdd && ((SwMultiPortion*)pPor)->HasTabulator() ) { if ( ++nSpaceIdx < pSpaceAdd->Count() ) @@ -492,16 +492,17 @@ sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, if( nStart + pCurr->GetLen() <= nOfst ) Next(); sal_Bool bSpaceChg = ((SwMultiPortion*)pPor)-> - ChangeSpaceAdd( pCurr, nSpaceAdd ); + ChgSpaceAdd( pCurr, nSpaceAdd ); bRet = GetCharRect( pOrig, nOfst, pCMS, nMax ); pOrig->Pos().X() += nX; if( ((SwMultiPortion*)pPor)->HasBrackets() ) pOrig->Pos().X() += - ((SwMultiPortion*)pPor)->PreWidth(); + ((SwDoubleLinePortion*)pPor)->PreWidth(); if( bSpaceChg ) - SwMultiPortion::ResetSpaceAdd( pCurr ); + SwDoubleLinePortion::ResetSpaceAdd( pCurr ); pCurr = pOldCurr; nStart = nOldStart; + bPrev = sal_False; return bRet; } if ( pPor->PrtWidth() ) @@ -593,7 +594,7 @@ sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, !pPor->GetPortion()->IsMarginPortion() ) ) nX += pPor->PrtWidth(); } - if( pPor->IsMultiPortion() && + if( pPor->IsMultiPortion() && pSpaceAdd && ((SwMultiPortion*)pPor)->HasTabulator() ) { if ( ++nSpaceIdx < pSpaceAdd->Count() ) @@ -926,7 +927,7 @@ xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint, SwTxtCursorSave aSave( (SwTxtCursor*)this, (SwMultiPortion*)pPor, rPoint.Y(), nCurrStart, nSpaceAdd ); if( ((SwMultiPortion*)pPor)->HasBrackets() ) - nX -= ((SwMultiPortion*)pPor)->PreWidth(); + nX -= ((SwDoubleLinePortion*)pPor)->PreWidth(); return GetCrsrOfst( pPos, Point( nLeftMargin + nX, rPoint.Y() ), nChgNode, pCMS ); } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index 13183ad0118c..daa32a8ef233 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -2,9 +2,9 @@ * * $RCSfile: itrform2.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: ama $ $Date: 2000-10-26 07:39:36 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:16:33 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -759,6 +759,9 @@ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf ) else bFull = pPor->Format( rInf ); + if( rInf.IsRuby() && !rInf.GetRest() ) + bFull = sal_True; + // Vorsicht: ein Fly im Blocksatz, dann kann das Repaint nur komplett // hinter ihm oder vom Zeilenbeginn sein. #ifdef DEBUG @@ -808,7 +811,7 @@ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf ) // Restportions von mehrzeiligen Feldern haben bisher noch // nicht den richtigen Ascent. if ( !pPor->GetLen() && !pPor->IsFlyPortion() - && !pPor->IsGrfNumPortion() ) + && !pPor->IsGrfNumPortion() && !pPor->IsMultiPortion() ) CalcAscent( rInf, pPor ); InsertPortion( rInf, pPor ); @@ -1132,9 +1135,12 @@ sal_Bool lcl_OldFieldRest( const SwLineLayout* pCurr ) return sal_False; const SwLinePortion *pPor = pCurr->GetNext()->GetPortion(); sal_Bool bRet = sal_False; - while( pPor && !bRet && !pPor->GetLen() ) + while( pPor && !bRet ) { - bRet = pPor->InFldGrp(); + bRet = (pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()) || + (pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsFollowFld()); + if( !pPor->GetLen() ) + break; pPor = pPor->GetPortion(); } return bRet; @@ -1245,9 +1251,24 @@ SwLinePortion *SwTxtFormatter::NewPortion( SwTxtFormatInfo &rInf ) const SwTxtAttr* pTwoLines = rInf.GetTwoLines( rInf.GetIdx() ); if( pTwoLines ) { - SwMultiPortion* pTmp = new SwMultiPortion(*pTwoLines->GetEnd()); + SwMultiPortion* pTmp = NULL; + //pTmp = new SwDoubleLinePortion(*pTwoLines->GetEnd()); #ifdef DEBUG - pTmp->SetBrackets( '(', ')' ); + static BOOL bOnTop = sal_False; + pTmp = new SwRubyPortion(*pTwoLines->GetEnd(), 1, bOnTop ); + SwFont *pRubyFont = new SwFont( *rInf.GetFont() ); + pRubyFont->SetProportion( 50 ); + String aStr( String::CreateFromAscii( "Ein Ruby Test Elch" ) ); + SwFldPortion *pFld = new SwFldPortion( aStr, pRubyFont ); + pFld->SetFollow( sal_True ); + if( bOnTop ) + pTmp->GetRoot().SetPortion( pFld ); + else + { + pTmp->GetRoot().SetNext( new SwLineLayout() ); + pTmp->GetRoot().GetNext()->SetPortion( pFld ); + } + //pTmp->SetBrackets( '(', ')' ); #endif return pTmp; } diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx index 51df2e8378cd..8529b721e8cb 100644 --- a/sw/source/core/text/pormulti.cxx +++ b/sw/source/core/text/pormulti.cxx @@ -2,9 +2,9 @@ * * $RCSfile: pormulti.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: jp $ $Date: 2000-11-02 17:19:18 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:11:49 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -86,6 +86,9 @@ #ifndef _PORFLD_HXX #include <porfld.hxx> // SwFldPortion #endif +#ifndef _PORGLUE_HXX +#include <porglue.hxx> +#endif /*-----------------10.10.00 15:23------------------- * class SwMultiPortion @@ -99,7 +102,6 @@ SwMultiPortion::~SwMultiPortion() { delete pFldRest; - delete pBracket; } void SwMultiPortion::Paint( const SwTxtPaintInfo &rInf ) const @@ -122,14 +124,78 @@ void SwMultiPortion::CalcSize( SwTxtFormatter& rLine ) do { pLay->CalcLine( rLine ); + if( IsRuby() && ( OnTop() == ( pLay == &GetRoot() ) ) ) + { + if( OnTop() ) + SetAscent( GetAscent() + pLay->Height() ); + } + else + SetAscent( GetAscent() + pLay->GetAscent() ); Height( Height() + pLay->Height() ); - SetAscent( GetAscent() + pLay->GetAscent() ); if( Width() < pLay->Width() ) Width( pLay->Width() ); pLay = pLay->GetNext(); } while ( pLay ); } +long SwMultiPortion::CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) + const +{ + return 0; +} + +/*-----------------01.11.00 14:21------------------- + * SwMultiPortion::ActualizeTabulator() + * sets the tabulator-flag, if there's any tabulator-portion inside. + * --------------------------------------------------*/ + +void SwMultiPortion::ActualizeTabulator() +{ + SwLinePortion* pPor = GetRoot().GetFirstPortion(); + // First line + for( bTabulator = sal_False; pPor; pPor = pPor->GetPortion() ) + if( pPor->InTabGrp() ) + SetTabulator( sal_True ); + if( GetRoot().GetNext() ) + { + // Second line + pPor = GetRoot().GetNext()->GetFirstPortion(); + do + { + if( pPor->InTabGrp() ) + SetTabulator( sal_True ); + pPor = pPor->GetPortion(); + } while ( pPor ); + } +} + +/*-----------------01.11.00 14:22------------------- + * SwDoubleLinePortion::SwDoubleLinePortion + * This constructor is for the continuation of a doubleline portion + * in the next line. + * It takes the same brackets and if the original has no content except + * brackets, these will be deleted. + * --------------------------------------------------*/ + +SwDoubleLinePortion::SwDoubleLinePortion( SwDoubleLinePortion& rDouble, + xub_StrLen nEnd ) : SwMultiPortion( nEnd ), pBracket( 0 ) +{ + SetDouble(); + if( rDouble.GetBrackets() ) + { + SetBrackets( rDouble ); + // An empty multiportion needs no brackets. + // Notice: GetLen() might be zero, if the multiportion contains + // the second part of a field and the width might be zero, if + // it contains a note only. In this cases the brackets are okay. + // But if the length and the width are both zero, the portion + // is really empty. + if( !rDouble.GetLen() && rDouble.Width() == rDouble.BracketWidth() ) + rDouble.ClearBrackets(); + } +} + + /*-----------------25.10.00 09:51------------------- * SwMultiPortion::PaintBracket paints the wished bracket, * if the multiportion has surrounding brackets. @@ -138,8 +204,8 @@ void SwMultiPortion::CalcSize( SwTxtFormatter& rLine ) * the close bracket in front of itself. * --------------------------------------------------*/ -void SwMultiPortion::PaintBracket( const SwTxtPaintInfo &rInf, - sal_Bool bOpen ) const +void SwDoubleLinePortion::PaintBracket( SwTxtPaintInfo &rInf, + short nSpaceAdd, sal_Bool bOpen ) const { sal_Unicode cCh = bOpen ? pBracket->cPre : pBracket->cPost; if( !cCh ) @@ -147,22 +213,31 @@ void SwMultiPortion::PaintBracket( const SwTxtPaintInfo &rInf, KSHORT nChWidth = bOpen ? PreWidth() : PostWidth(); if( !nChWidth ) return; + if( !bOpen ) + rInf.X( rInf.X() + Width() - PostWidth() + + ( nSpaceAdd > 0 ? CalcSpacing( nSpaceAdd, rInf ) : 0 ) ); + SwBlankPortion aBlank( cCh, sal_True ); aBlank.SetAscent( pBracket->nAscent ); aBlank.Width( nChWidth ); aBlank.Height( pBracket->nHeight ); - SwFont* pTmpFnt = new SwFont( *rInf.GetFont() ); - pTmpFnt->SetProportion( 100 ); - SwFontSave aSave( rInf, pTmpFnt ); - aBlank.Paint( rInf ); + { + SwFont* pTmpFnt = new SwFont( *rInf.GetFont() ); + pTmpFnt->SetProportion( 100 ); + SwFontSave aSave( rInf, pTmpFnt ); + aBlank.Paint( rInf ); + delete pTmpFnt; + } + if( bOpen ) + rInf.X( rInf.X() + PreWidth() ); } /*-----------------25.10.00 16:26------------------- - * SwMultiPortion::SetBrackets creates the bracket-structur + * SwDoubleLinePortion::SetBrackets creates the bracket-structur * and fills it, if not both characters are 0x00. * --------------------------------------------------*/ -void SwMultiPortion::SetBrackets( sal_Unicode cPre, sal_Unicode cPost ) +void SwDoubleLinePortion::SetBrackets( sal_Unicode cPre, sal_Unicode cPost ) { if( cPre || cPost ) { @@ -173,13 +248,13 @@ void SwMultiPortion::SetBrackets( sal_Unicode cPre, sal_Unicode cPost ) } /*-----------------25.10.00 16:29------------------- - * SwMultiPortion::FormatBrackets + * SwDoubleLinePortion::FormatBrackets * calculates the size of the brackets => pBracket, * reduces the nMaxWidth-parameter ( minus bracket-width ) * and moves the rInf-x-position behind the opening bracket. * --------------------------------------------------*/ -void SwMultiPortion::FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth ) +void SwDoubleLinePortion::FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth ) { nMaxWidth -= rInf.X(); SwFont* pTmpFnt = new SwFont( *rInf.GetFont() ); @@ -227,31 +302,31 @@ void SwMultiPortion::FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth ) } /*-----------------26.10.00 10:36------------------- - * SwMultiPortion::CalcBlanks + * SwDoubleLinePortion::CalcBlanks * calculates the number of blanks in each line and * the difference of the width of the two lines. * These results are used from the text adjustment. * --------------------------------------------------*/ -void SwMultiPortion::CalcBlanks( SwTxtFormatInfo &rInf ) +void SwDoubleLinePortion::CalcBlanks( SwTxtFormatInfo &rInf ) { - SwLinePortion* pPor = aRoot.GetFirstPortion(); + SwLinePortion* pPor = GetRoot().GetFirstPortion(); xub_StrLen nNull = 0; xub_StrLen nStart = rInf.GetIdx(); - bTabulator = sal_False; + SetTabulator( sal_False ); for( nBlank1 = 0; pPor; pPor = pPor->GetPortion() ) { if( pPor->InTxtGrp() ) nBlank1 += ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull ); rInf.SetIdx( rInf.GetIdx() + pPor->GetLen() ); if( pPor->InTabGrp() ) - bTabulator = sal_True; + SetTabulator( sal_True ); } - nLineDiff = aRoot.Width(); - if( aRoot.GetNext() ) + nLineDiff = GetRoot().Width(); + if( GetRoot().GetNext() ) { - pPor = aRoot.GetNext()->GetFirstPortion(); - nLineDiff -= aRoot.GetNext()->Width(); + pPor = GetRoot().GetNext()->GetFirstPortion(); + nLineDiff -= GetRoot().GetNext()->Width(); } for( nBlank2 = 0; pPor; pPor = pPor->GetPortion() ) { @@ -259,23 +334,33 @@ void SwMultiPortion::CalcBlanks( SwTxtFormatInfo &rInf ) nBlank2 += ((SwTxtPortion*)pPor)->GetSpaceCnt( rInf, nNull ); rInf.SetIdx( rInf.GetIdx() + pPor->GetLen() ); if( pPor->InTabGrp() ) - bTabulator = sal_True; + SetTabulator( sal_True ); } rInf.SetIdx( nStart ); } -long SwMultiPortion::CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const +long SwDoubleLinePortion::CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const { return HasTabulator() ? 0 : GetSpaceCnt() * nSpaceAdd; } -sal_Bool SwMultiPortion::ChangeSpaceAdd( SwLineLayout* pCurr, short nSpaceAdd ) +/*-----------------01.11.00 14:29------------------- + * SwDoubleLinePortion::ChangeSpaceAdd(..) + * merges the spaces for text adjustment from the inner and outer part. + * Inside the doubleline portion the wider line has no spaceadd-array, the + * smaller line has such an array to reach width of the wider line. + * If the surrounding line has text adjustment and the doubleline portion + * contains no tabulator, it is necessary to create/manipulate the inner + * space arrays. + * --------------------------------------------------*/ + +sal_Bool SwDoubleLinePortion::ChangeSpaceAdd( SwLineLayout* pCurr, short nSpaceAdd ) { sal_Bool bRet = sal_False; if( !HasTabulator() && nSpaceAdd > 0 ) { if( pCurr->IsNoSpaceAdd() ) - { + { // The wider line gets the spaceadd from the surrounding line direct pCurr->CreateSpaceAdd(); ( pCurr->GetSpaceAdd() )[0] = nSpaceAdd; bRet = sal_True; @@ -297,14 +382,66 @@ sal_Bool SwMultiPortion::ChangeSpaceAdd( SwLineLayout* pCurr, short nSpaceAdd ) } return bRet; } +/*-----------------01.11.00 14:29------------------- + * SwDoubleLinePortion::ResetSpaceAdd(..) + * cancels the manipulation from SwDoubleLinePortion::ChangeSpaceAdd(..) + * --------------------------------------------------*/ -void SwMultiPortion::ResetSpaceAdd( SwLineLayout* pCurr ) +void SwDoubleLinePortion::ResetSpaceAdd( SwLineLayout* pCurr ) { pCurr->GetSpaceAdd().Remove(0); if( !pCurr->GetSpaceAdd().Count() ) pCurr->FinishSpaceAdd(); } +SwDoubleLinePortion::~SwDoubleLinePortion() +{ + delete pBracket; +} + +void SwRubyPortion::_Adjust() +{ + SwTwips nLineDiff = GetRoot().Width() - GetRoot().GetNext()->Width(); + if( !nLineDiff ) + return; + SwLineLayout *pCurr; + if( nLineDiff < 0 ) + { + pCurr = &GetRoot(); + nLineDiff = -nLineDiff; + } + else + pCurr = GetRoot().GetNext(); + + KSHORT nLeft = 0; + KSHORT nRight = 0; + switch ( nAdjustment ) + { + case 1: nLeft = nLineDiff/2; // no break + case 2: nRight = nLineDiff - nLeft; break; + case 3: break; + default: ASSERT( sal_False, "New ruby adjustment" ); + } + if( nLeft || nRight ) + { + if( !pCurr->GetPortion() ) + pCurr->SetPortion( new SwTxtPortion( *pCurr ) ); + SwMarginPortion *pMarg = new SwMarginPortion( 0 ); + if( nLeft ) + { + pMarg->AddPrtWidth( nLeft ); + pMarg->SetPortion( pCurr->GetPortion() ); + pCurr->SetPortion( pMarg ); + } + if( nRight ) + { + pMarg = new SwMarginPortion( 0 ); + pMarg->AddPrtWidth( nRight ); + pCurr->FindLastPortion()->Append( pMarg ); + } + } +} + /*-----------------13.10.00 16:22------------------- * If we're inside a two-line-attribute, @@ -336,6 +473,90 @@ const SwTxtAttr* SwTxtSizeInfo::GetTwoLines( const xub_StrLen nPos ) const return NULL; } +/*-----------------01.11.00 14:52------------------- + * SwSpaceManipulator + * is a little helper class to manage the spaceadd-arrays of the text adjustment + * during a PaintMultiPortion. + * The constructor prepares the array for the first line of multiportion, + * the SecondLine-function restores the values for the first line and prepares + * the second line. + * The destructor restores the values of the last manipulation. + * --------------------------------------------------*/ + +class SwSpaceManipulator +{ + SwTxtPaintInfo& rInfo; + SwMultiPortion& rMulti; + SvShorts *pOldSpaceAdd; + MSHORT nOldSpIdx; + short nSpaceAdd; + sal_Bool bSpaceChg; +public: + SwSpaceManipulator( SwTxtPaintInfo& rInf, SwMultiPortion& rMult ); + ~SwSpaceManipulator(); + void SecondLine(); + inline short GetSpaceAdd() const { return nSpaceAdd; } +}; + +SwSpaceManipulator::SwSpaceManipulator( SwTxtPaintInfo& rInf, + SwMultiPortion& rMult ) : rInfo( rInf ), rMulti( rMult ) +{ + pOldSpaceAdd = rInfo.GetpSpaceAdd(); + nOldSpIdx = rInfo.GetSpaceIdx(); + bSpaceChg = sal_False; + if( rMulti.IsDouble() ) + { + nSpaceAdd = ( pOldSpaceAdd && !rMulti.HasTabulator() ) ? + rInfo.GetSpaceAdd() : 0; + if( rMulti.GetRoot().GetpSpaceAdd() ) + { + rInfo.SetSpaceAdd( rMulti.GetRoot().GetpSpaceAdd() ); + rInfo.ResetSpaceIdx(); + bSpaceChg = rMulti.ChgSpaceAdd( &rMulti.GetRoot(), nSpaceAdd ); + } + else if( rMulti.HasTabulator() ) + rInfo.SetSpaceAdd( NULL ); + } + else + { + rInfo.SetSpaceAdd( rMulti.GetRoot().GetpSpaceAdd() ); + rInfo.ResetSpaceIdx(); + } +} + +void SwSpaceManipulator::SecondLine() +{ + if( bSpaceChg ) + { + rInfo.GetpSpaceAdd()->Remove( 0 ); + bSpaceChg = sal_False; + } + SwLineLayout *pLay = rMulti.GetRoot().GetNext(); + if( pLay->GetpSpaceAdd() ) + { + rInfo.SetSpaceAdd( pLay->GetpSpaceAdd() ); + rInfo.ResetSpaceIdx(); + bSpaceChg = rMulti.ChgSpaceAdd( pLay, nSpaceAdd ); + } + else + { + rInfo.SetSpaceAdd( (!rMulti.IsDouble() || rMulti.HasTabulator() ) ? + 0 : pOldSpaceAdd ); + rInfo.SetSpaceIdx( nOldSpIdx); + } +} + +SwSpaceManipulator::~SwSpaceManipulator() +{ + if( bSpaceChg ) + { + rInfo.GetpSpaceAdd()->Remove( 0 ); + bSpaceChg = sal_False; + } + rInfo.SetSpaceAdd( pOldSpaceAdd ); + rInfo.SetSpaceIdx( nOldSpIdx); +} + /*-----------------13.10.00 16:24------------------- * SwTxtPainter::PaintMultiPortion manages the paint for a SwMultiPortion. * External, for the calling function, it seems to be a normal Paint-function, @@ -350,24 +571,13 @@ void SwTxtPainter::PaintMultiPortion( const SwRect &rPaint, KSHORT nOldX = GetInfo().X(); KSHORT nOldY = GetInfo().Y(); xub_StrLen nOldIdx = GetInfo().GetIdx(); - SvShorts *pOldSpaceAdd = GetInfo().GetpSpaceAdd(); - MSHORT nOldSpIdx = GetInfo().GetSpaceIdx(); - sal_Bool bSpaceChg = sal_False; - short nSpaceAdd = ( pOldSpaceAdd && !rMulti.HasTabulator() ) ? - GetInfo().GetSpaceAdd() : 0; - if( rMulti.GetRoot().GetpSpaceAdd() ) - { - GetInfo().SetSpaceAdd( rMulti.GetRoot().GetpSpaceAdd() ); - GetInfo().ResetSpaceIdx(); - bSpaceChg = rMulti.ChangeSpaceAdd( &rMulti.GetRoot(), nSpaceAdd ); - } - else if( rMulti.HasTabulator() ) - GetInfo().SetSpaceAdd( NULL ); + + SwSpaceManipulator aManip( GetInfo(), rMulti ); + if( rMulti.HasBrackets() ) { SeekAndChg( GetInfo() ); - rMulti.PaintBracket( GetInfo(), sal_True ); - GetInfo().X( GetInfo().X() + rMulti.PreWidth() ); + ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(), 0, sal_True ); } KSHORT nTmpX = GetInfo().X(); @@ -428,48 +638,26 @@ void SwTxtPainter::PaintMultiPortion( const SwRect &rPaint, pPor = pLay->GetFirstPortion(); bRest = pLay->IsRest(); GetInfo().X( nTmpX ); - if( bSpaceChg ) - { - GetInfo().GetpSpaceAdd()->Remove( 0 ); - bSpaceChg = sal_False; - } - if( pLay->GetpSpaceAdd() ) - { - GetInfo().SetSpaceAdd( pLay->GetpSpaceAdd() ); - GetInfo().ResetSpaceIdx(); - bSpaceChg = rMulti.ChangeSpaceAdd( pLay, nSpaceAdd ); - } - else - { - GetInfo().SetSpaceAdd( rMulti.HasTabulator() ? 0:pOldSpaceAdd ); - GetInfo().SetSpaceIdx( nOldSpIdx); - } + aManip.SecondLine(); // We switch to the baseline of the next inner line GetInfo().Y( GetInfo().Y() + rMulti.GetRoot().Height() - rMulti.GetRoot().GetAscent() + pLay->GetAscent() ); } } while( pPor ); - if( bSpaceChg ) - { - GetInfo().GetpSpaceAdd()->Remove( 0 ); - bSpaceChg = sal_False; - } GetInfo().SetIdx( nOldIdx ); GetInfo().Y( nOldY ); if( rMulti.HasBrackets() ) { SeekAndChg( GetInfo() ); - GetInfo().X( nOldX + rMulti.Width() - rMulti.PostWidth() + - ( nSpaceAdd > 0 ? rMulti.CalcSpacing( nSpaceAdd, GetInfo() ) :0 ) ); - rMulti.PaintBracket( GetInfo(), sal_False ); + GetInfo().X( nOldX ); + ((SwDoubleLinePortion&)rMulti).PaintBracket( GetInfo(), + aManip.GetSpaceAdd(), sal_False ); } // Restore the saved values GetInfo().X( nOldX ); GetInfo().SetLen( nOldLen ); - GetInfo().SetSpaceAdd( pOldSpaceAdd ); - GetInfo().SetSpaceIdx( nOldSpIdx); } /*-----------------13.10.00 16:46------------------- @@ -478,13 +666,37 @@ void SwTxtPainter::PaintMultiPortion( const SwRect &rPaint, * internal it is like a SwTxtFrm::_Format with multiple BuildPortions * --------------------------------------------------*/ +sal_Bool lcl_ExtractFieldFollow( SwLineLayout* pLine, SwLinePortion* &rpFld ) +{ + SwLinePortion* pLast = pLine; + rpFld = pLine->GetPortion(); + while( rpFld && !rpFld->InFldGrp() ) + { + pLast = rpFld; + rpFld = rpFld->GetPortion(); + } + sal_Bool bRet = rpFld != 0; + if( bRet ) + { + if( ((SwFldPortion*)rpFld)->IsFollow() ) + { + rpFld->Truncate(); + pLast->SetPortion( NULL ); + } + else + rpFld = NULL; + } + pLine->Truncate(); + return bRet; +} + BOOL SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf, SwMultiPortion& rMulti ) { SwTwips nMaxWidth = rInf.Width(); SeekAndChg( rInf ); if( rMulti.HasBrackets() ) - rMulti.FormatBrackets( rInf, nMaxWidth ); + ((SwDoubleLinePortion&)rMulti).FormatBrackets( rInf, nMaxWidth ); SwTwips nTmpX = rInf.X(); @@ -493,10 +705,41 @@ BOOL SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf, xub_StrLen nOldStart = GetStart(); SwTwips nMinWidth = nTmpX + 1; SwTwips nActWidth = nMaxWidth; + xub_StrLen nStartIdx = rInf.GetIdx(); + xub_StrLen nMultiLen = rMulti.GetLen(); + + SwLinePortion *pFirstRest; + SwLinePortion *pSecondRest; + if( rMulti.IsFormatted() ) + { + if( !lcl_ExtractFieldFollow( &rMulti.GetRoot(), pFirstRest ) + && rMulti.IsDouble() && rMulti.GetRoot().GetNext() ) + lcl_ExtractFieldFollow( rMulti.GetRoot().GetNext(), pFirstRest ); + if( !rMulti.IsDouble() && rMulti.GetRoot().GetNext() ) + lcl_ExtractFieldFollow( rMulti.GetRoot().GetNext(), pSecondRest ); + else + pSecondRest = NULL; + } + else + { + pFirstRest = rMulti.GetRoot().GetPortion(); + pSecondRest = rMulti.GetRoot().GetNext() ? + rMulti.GetRoot().GetNext()->GetPortion() : NULL; + if( pFirstRest ) + rMulti.GetRoot().SetPortion( NULL ); + if( pSecondRest ) + rMulti.GetRoot().GetNext()->SetPortion( NULL ); + rMulti.SetFormatted(); + nMultiLen -= rInf.GetIdx(); + } + + const XubString* pOldTxt = &(rInf.GetTxt()); + XubString aMultiStr( rInf.GetTxt(), 0, nMultiLen + rInf.GetIdx() ); + rInf.SetTxt( aMultiStr ); SwTxtFormatInfo aInf( rInf, rMulti.GetRoot(), nActWidth ); - xub_StrLen nStartIdx = aInf.GetIdx(); - xub_StrLen nMultiLen = rMulti.GetLen() - rInf.GetIdx(); - SwLinePortion *pRest = NULL; + + SwLinePortion *pNextFirst = NULL; + SwLinePortion *pNextSecond = NULL; BOOL bRet = FALSE; do { @@ -506,33 +749,56 @@ BOOL SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf, FormatReset( aInf ); aInf.X( nTmpX ); aInf.Width( nActWidth ); - if( rMulti.GetFldRest() ) + if( pFirstRest ) { + ASSERT( pFirstRest->InFldGrp(), "BuildMulti: Fieldrest exspected"); SwFldPortion *pFld = - rMulti.GetFldRest()->Clone( rMulti.GetFldRest()->GetExp() ); + ((SwFldPortion*)pFirstRest)->Clone( + ((SwFldPortion*)pFirstRest)->GetExp() ); pFld->SetFollow( sal_True ); aInf.SetRest( pFld ); } + aInf.SetRuby( rMulti.IsRuby() && rMulti.OnTop() ); BuildPortions( aInf ); rMulti.CalcSize( *this ); pCurr->SetRealHeight( pCurr->Height() ); - if( pCurr->GetLen() < nMultiLen || aInf.GetRest() ) + if( pCurr->GetLen() < nMultiLen || rMulti.IsRuby() || aInf.GetRest() ) { xub_StrLen nFirstLen = pCurr->GetLen(); + delete pCurr->GetNext(); pCurr->SetNext( new SwLineLayout() ); pCurr = pCurr->GetNext(); nStart = aInf.GetIdx(); aInf.X( nTmpX ); SwTxtFormatInfo aTmp( aInf, *pCurr, nActWidth ); - aTmp.SetRest( aInf.GetRest() ); + if( rMulti.IsRuby() ) + { + aTmp.SetRuby( !rMulti.OnTop() ); + pNextFirst = aInf.GetRest(); + aTmp.SetRest( pSecondRest ); + if( !rMulti.OnTop() && nFirstLen < nMultiLen ) + bRet = sal_True; + } + else + aTmp.SetRest( aInf.GetRest() ); aInf.SetRest( NULL ); BuildPortions( aTmp ); rMulti.CalcSize( *this ); pCurr->SetRealHeight( pCurr->Height() ); - pRest = aTmp.GetRest(); - if( nFirstLen + pCurr->GetLen() < nMultiLen || pRest ) - bRet = TRUE; + if( rMulti.IsRuby() ) + { + pNextSecond = aTmp.GetRest(); + if( pNextFirst ) + bRet = sal_True; + } + else + pNextFirst = aTmp.GetRest(); + if( ( !aTmp.IsRuby() && nFirstLen + pCurr->GetLen() < nMultiLen ) + || aTmp.GetRest() ) + bRet = sal_True; } + if( rMulti.IsRuby() ) + break; if( bRet ) { nMinWidth = nActWidth; @@ -549,54 +815,86 @@ BOOL SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf, if( nActWidth >= nMaxWidth ) break; } - delete pRest; - pRest = NULL; + delete pNextFirst; + pNextFirst = NULL; } while ( TRUE ); pMulti = NULL; pCurr = pOldCurr; nStart = nOldStart; rMulti.SetLen( rMulti.GetRoot().GetLen() + ( rMulti.GetRoot().GetNext() ? rMulti.GetRoot().GetNext()->GetLen() : 0 ) ); - rMulti.CalcBlanks( rInf ); - if( rMulti.GetLineDiff() ) + if( rMulti.IsDouble() ) { - SwLineLayout* pLine = &rMulti.GetRoot(); - if( rMulti.GetLineDiff() > 0 ) + ((SwDoubleLinePortion&)rMulti).CalcBlanks( rInf ); + if( ((SwDoubleLinePortion&)rMulti).GetLineDiff() ) { - rInf.SetIdx( nStartIdx + pLine->GetLen() ); - pLine = pLine->GetNext(); - } - if( pLine ) - { - GetInfo().SetMulti( sal_True ); - CalcNewBlock( pLine, NULL, rMulti.Width() ); - GetInfo().SetMulti( sal_False ); + SwLineLayout* pLine = &rMulti.GetRoot(); + if( ((SwDoubleLinePortion&)rMulti).GetLineDiff() > 0 ) + { + rInf.SetIdx( nStartIdx + pLine->GetLen() ); + pLine = pLine->GetNext(); + } + if( pLine ) + { + GetInfo().SetMulti( sal_True ); + CalcNewBlock( pLine, NULL, rMulti.Width() ); + GetInfo().SetMulti( sal_False ); + } + rInf.SetIdx( nStartIdx ); } - rInf.SetIdx( nStartIdx ); + if( ((SwDoubleLinePortion&)rMulti).GetBrackets() ) + rMulti.Width( rMulti.Width() + + ((SwDoubleLinePortion&)rMulti).BracketWidth() ); + } + else + { + rMulti.ActualizeTabulator(); + if( rMulti.IsRuby() ) + ((SwRubyPortion&)rMulti).Adjust(); } - if( rMulti.HasBrackets() ) - rMulti.Width( rMulti.Width() + rMulti.BracketWidth() ); if( bRet ) { - SwMultiPortion *pTmp = new SwMultiPortion( nMultiLen + rInf.GetIdx() ); - if( rMulti.HasBrackets() ) + SwMultiPortion *pTmp; + if( rMulti.IsDouble() ) + pTmp = new SwDoubleLinePortion( ((SwDoubleLinePortion&)rMulti), + nMultiLen + rInf.GetIdx() ); + ASSERT( !pNextFirst || pNextFirst->InFldGrp(), + "BuildMultiPortion: Surprising restportion, field exspected" ); + if( rMulti.IsRuby() ) { - pTmp->SetBrackets( rMulti ); - // An empty multiportion needs no brackets. - // Notice: GetLen() might be zero, if the multiportion contains - // the second part of a field and the width might be zero, if - // it contains a note only. In this cases the brackets are okay. - // But if the length and the width are both zero, the multiportion - // is really empty. - if( !rMulti.GetLen() && rMulti.Width() == rMulti.BracketWidth() ) - rMulti.ClearBrackets(); + ASSERT( !pNextSecond || pNextSecond->InFldGrp(), + "BuildMultiPortion: Surprising restportion, field exspected" ); + pTmp = new SwRubyPortion( nMultiLen + rInf.GetIdx(), + 3 - ((SwRubyPortion&)rMulti).GetAdjustment(), rMulti.OnTop() ); + if( pTmp->OnTop() ) + { + if( !pNextFirst && pFirstRest ) + { + pNextFirst = ((SwFldPortion*)pFirstRest)->Clone(aEmptyStr); + ((SwFldPortion*)pNextFirst)->SetFollow( sal_True ); + } + } + else if( !pNextSecond && pSecondRest ) + { + pNextSecond = ((SwFldPortion*)pSecondRest)->Clone(aEmptyStr); + ((SwFldPortion*)pNextSecond)->SetFollow( sal_True ); + } + if( pNextSecond ) + { + pTmp->GetRoot().SetNext( new SwLineLayout() ); + pTmp->GetRoot().GetNext()->SetPortion( pNextSecond ); + } + pTmp->SetFollowFld(); + } + if( pNextFirst ) + { + pTmp->SetFollowFld(); + pTmp->GetRoot().SetPortion( pNextFirst ); } - ASSERT( !pRest || pRest->InFldGrp(), - "BuildMultiPortion: Surprising restportion, field exspected" ); - pTmp->SetFldRest( (SwFldPortion*) pRest ); rInf.SetRest( pTmp ); } + rInf.SetTxt( *pOldTxt ); return bRet; } @@ -617,16 +915,22 @@ SwTxtCursorSave::SwTxtCursorSave( SwTxtCursor* pTxtCursor, while( pTxtCursor->Y() + pTxtCursor->GetLineHeight() < nY && pTxtCursor->Next() ) ; // nothing - bSpaceChg = pMulti->ChangeSpaceAdd( pTxtCursor->pCurr, nSpaceAdd ); nWidth = pTxtCursor->pCurr->Width(); - if( nSpaceAdd > 0 && !pMulti->HasTabulator() ) - pTxtCursor->pCurr->Width( nWidth + nSpaceAdd * pMulti->GetSpaceCnt() ); + if( pMulti->IsDouble() ) + { + bSpaceChg = pMulti->ChgSpaceAdd( pTxtCursor->pCurr, nSpaceAdd ); + if( nSpaceAdd > 0 && !pMulti->HasTabulator() ) + pTxtCursor->pCurr->Width( nWidth + nSpaceAdd * + ((SwDoubleLinePortion*)pMulti)->GetSpaceCnt() ); + } + else + bSpaceChg = sal_False; } SwTxtCursorSave::~SwTxtCursorSave() { if( bSpaceChg ) - SwMultiPortion::ResetSpaceAdd( pTxtCrsr->pCurr ); + SwDoubleLinePortion::ResetSpaceAdd( pTxtCrsr->pCurr ); pTxtCrsr->pCurr->Width( nWidth ); pTxtCrsr->pCurr = pCurr; pTxtCrsr->nStart = nStart; diff --git a/sw/source/core/text/pormulti.hxx b/sw/source/core/text/pormulti.hxx index a029c94fb549..ed67a275a889 100644 --- a/sw/source/core/text/pormulti.hxx +++ b/sw/source/core/text/pormulti.hxx @@ -2,9 +2,9 @@ * * $RCSfile: pormulti.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: ama $ $Date: 2000-10-30 09:57:43 $ + * last change: $Author: ama $ $Date: 2000-11-06 09:11:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -88,35 +88,78 @@ struct SwBracket }; /*-----------------16.10.00 12:45------------------- - * The SwMultiPortion is line portion inside a line portion - * to allow double line portions in a line. + * The SwMultiPortion is line portion inside a line portion, + * it's a group of portions, + * e.g. a double line portion in a line + * or phonetics (ruby) + * or combined characters + * or a rotated portion. * --------------------------------------------------*/ class SwMultiPortion : public SwLinePortion { SwLineLayout aRoot; // One or more lines - SwFldPortion *pFldRest; // A field rest from the previous line - SwBracket* pBracket; // Surrounding brackets - SwTwips nLineDiff; // Difference of the width of the both lines - xub_StrLen nBlank1; // Number of blanks in the first line - xub_StrLen nBlank2; // Number of blanks in the second line - sal_Bool bTabulator; // Multiportion includes tabulator -public: - SwMultiPortion( xub_StrLen nEnd ) : pFldRest( 0 ), pBracket( 0 ), - bTabulator( sal_False ) + SwFldPortion *pFldRest; // Field rest from the previous line + sal_Bool bTabulator :1; // Multiportion includes tabulator + sal_Bool bDouble :1; // Double line + sal_Bool bRuby :1; // Phonetics + sal_Bool bTop :1; // Phonetic position + sal_Bool bFormatted :1; // Already formatted + sal_Bool bFollowFld :1; // Field follow inside +protected: + SwMultiPortion( xub_StrLen nEnd ) : pFldRest( 0 ), bTabulator( sal_False ), + bDouble( sal_False ), bRuby( sal_False ), bFormatted( sal_False ), + bFollowFld( sal_False ) { SetWhichPor( POR_MULTI ); SetLen( nEnd ); } + inline void SetDouble() { bDouble = sal_True; } + inline void SetRuby() { bRuby = sal_True; } + inline void SetTop( sal_Bool bNew ) { bTop = bNew; } + inline void SetTabulator( sal_Bool bNew ) { bTabulator = bNew; } +public: ~SwMultiPortion(); - const SwLineLayout& GetRoot() const { return aRoot; } SwLineLayout& GetRoot() { return aRoot; } SwFldPortion* GetFldRest() { return pFldRest; } void SetFldRest( SwFldPortion* pNew ) { pFldRest = pNew; } - inline sal_Bool HasBrackets() const { return 0 != pBracket; } + inline sal_Bool HasTabulator() const { return bTabulator; } + inline sal_Bool IsFormatted() const { return bFormatted; } + inline void SetFormatted() { bFormatted = sal_True; } + inline sal_Bool IsFollowFld() const { return bFollowFld; } + inline void SetFollowFld() { bFollowFld = sal_True; } + inline sal_Bool IsDouble() const { return bDouble; } + inline sal_Bool IsRuby() const { return bRuby; } + inline sal_Bool OnTop() const { return bTop; } + void ActualizeTabulator(); + + virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual long CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const; + + // Summarize the internal lines to calculate the (external) size + virtual void CalcSize( SwTxtFormatter& rLine ); + + inline sal_Bool ChgSpaceAdd( SwLineLayout* pCurr, short nSpaceAdd ); + inline sal_Bool HasBrackets() const; + OUTPUT_OPERATOR +}; + +class SwDoubleLinePortion : public SwMultiPortion +{ + SwBracket* pBracket; // Surrounding brackets + SwTwips nLineDiff; // Difference of the width of the both lines + xub_StrLen nBlank1; // Number of blanks in the first line + xub_StrLen nBlank2; // Number of blanks in the second line +public: + SwDoubleLinePortion( xub_StrLen nEnd ) : SwMultiPortion( nEnd ), + pBracket( 0 ) { SetDouble(); } + SwDoubleLinePortion( SwDoubleLinePortion& rDouble, xub_StrLen nEnd ); + ~SwDoubleLinePortion(); + + inline SwBracket* GetBrackets() const { return pBracket; } void SetBrackets( sal_Unicode cPre, sal_Unicode cPost ); - inline void SetBrackets( const SwMultiPortion& rMulti ) - { SetBrackets( rMulti.pBracket->cPre, rMulti.pBracket->cPost ); } - void PaintBracket( const SwTxtPaintInfo& rInf, sal_Bool bOpen ) const; + inline void SetBrackets( const SwDoubleLinePortion& rDouble ) + { SetBrackets( rDouble.pBracket->cPre, rDouble.pBracket->cPost ); } + void PaintBracket( SwTxtPaintInfo& rInf, short nSpc, sal_Bool bOpen ) const; void FormatBrackets( SwTxtFormatInfo &rInf, SwTwips& nMaxWidth ); inline KSHORT PreWidth() const { return pBracket->nPreWidth; }; inline KSHORT PostWidth() const { return pBracket->nPostWidth; } @@ -127,7 +170,6 @@ public: sal_Bool ChangeSpaceAdd( SwLineLayout* pCurr, short nSpaceAdd ); static void ResetSpaceAdd( SwLineLayout* pCurr ); inline SwTwips GetLineDiff() const { return nLineDiff; } - inline sal_Bool HasTabulator() const { return bTabulator; } inline xub_StrLen GetSpaceCnt() const { return ( nLineDiff < 0 ) ? nBlank2 : nBlank1; } inline xub_StrLen GetSmallerSpaceCnt() const @@ -135,15 +177,21 @@ public: inline xub_StrLen GetBlank1() const { return nBlank1; } inline xub_StrLen GetBlank2() const { return nBlank2; } - virtual void Paint( const SwTxtPaintInfo &rInf ) const; virtual long CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const; +}; - // Summarize the internal lines to calculate the (external) size - void CalcSize( SwTxtFormatter& rLine ); - - OUTPUT_OPERATOR +class SwRubyPortion : public SwMultiPortion +{ + USHORT nAdjustment; + void _Adjust(); +public: + SwRubyPortion( xub_StrLen nEnd, USHORT nAdj, sal_Bool bTp = sal_True ) : + SwMultiPortion( nEnd ), nAdjustment( nAdj ) { SetRuby(); SetTop(bTp); } + void Adjust() { if( nAdjustment && GetRoot().GetNext() ) _Adjust(); } + inline USHORT GetAdjustment() const { return nAdjustment; } }; + // For cursor travelling in multiportions class SwTxtCursorSave @@ -163,6 +211,14 @@ public: * inline - Implementations *************************************************************************/ +inline sal_Bool SwMultiPortion::ChgSpaceAdd(SwLineLayout* pCurr,short nSpaceAdd) + { return IsDouble() ? ((SwDoubleLinePortion*)this)->ChangeSpaceAdd( pCurr, + nSpaceAdd ) : sal_False; } + +inline sal_Bool SwMultiPortion::HasBrackets() const + { return IsDouble() ? 0 != ((SwDoubleLinePortion*)this)->GetBrackets() + : sal_False; } + CLASSIO( SwMultiPortion ) #endif |