diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/text')
66 files changed, 28964 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/text/guess.hxx b/binfilter/bf_sw/source/core/text/guess.hxx new file mode 100644 index 000000000000..143da7d16dbf --- /dev/null +++ b/binfilter/bf_sw/source/core/text/guess.hxx @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _GUESS_HXX +#define _GUESS_HXX + +#include <tools/solar.h> +#include <tools/string.hxx> +#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> + +#include "txttypes.hxx" +#include "breakit.hxx" +#include "porrst.hxx" // SwHangingPortion +namespace binfilter { + +class SwTxtSizeInfo; +class SwTxtFormatInfo; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::linguistic2; + +/************************************************************************* + * class SwTxtGuess + *************************************************************************/ + +class SwTxtGuess +{ + uno::Reference< XHyphenatedWord > xHyphWord; + SwHangingPortion *pHanging; // for hanging punctuation + xub_StrLen nCutPos; // this character doesn't fit + xub_StrLen nBreakStart; // start index of word containing line break + xub_StrLen nBreakPos; // start index of break position + xub_StrLen nFieldDiff; // absolut positions can be wrong if we + // a field in the text has been expanded + KSHORT nBreakWidth; // width of the broken portion +public: + inline SwTxtGuess(): pHanging( NULL ), nCutPos(0), nBreakStart(0), + nBreakPos(0), nFieldDiff(0), nBreakWidth(0) + { } + ~SwTxtGuess() { delete pHanging; } + + // true, if current portion still fits to current line + sal_Bool Guess( const SwTxtPortion& rPor, SwTxtFormatInfo &rInf, + const KSHORT nHeight ); + sal_Bool AlternativeSpelling( const SwTxtFormatInfo &rInf, const xub_StrLen nPos ); + + inline SwHangingPortion* GetHangingPortion() const { return pHanging; } + inline void ClearHangingPortion() { pHanging = NULL; } + inline KSHORT BreakWidth() const { return nBreakWidth; } + inline xub_StrLen CutPos() const { return nCutPos; } + inline xub_StrLen BreakStart() const { return nBreakStart; } + inline xub_StrLen BreakPos() const {return nBreakPos; } + inline xub_StrLen FieldDiff() const {return nFieldDiff; } + inline uno::Reference< XHyphenatedWord > HyphWord() const + { return xHyphWord; } +}; + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/inftxt.hxx b/binfilter/bf_sw/source/core/text/inftxt.hxx new file mode 100644 index 000000000000..2313e74d1bf6 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/inftxt.hxx @@ -0,0 +1,859 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _INFTXT_HXX +#define _INFTXT_HXX + +#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> +#include <com/sun/star/beans/PropertyValues.hpp> +#include <tools/table.hxx> + +#include "swtypes.hxx" +#include "txttypes.hxx" +#include "swrect.hxx" + +#include "txtfly.hxx" +#include "swfont.hxx" +#include "porlay.hxx" +#include "txtfrm.hxx" +#include "ndtxt.hxx" +#include "txttypes.hxx" + +#include <bf_svx/paravertalignitem.hxx> +class Font; +class OutputDevice; +namespace binfilter { + + +class SvxBrushItem; +class SvxLineSpacingItem; +class SvxTabStop; +class SvxTabStopItem; +class SwAttrSet; +class SwField; +class SwFldPortion; +class SwFlyPortion; +class SwFmtDrop; +class SwFtnPortion; +class SwLineHeightRule; +class SwLineLayout; +class SwLinePortion; +class SwLineSpaceRule; +class SwParaPortion; +class SwTabPortion; +class SwTxtFrm; +class SwTxtSizeInfo; +class SwViewOption; +class ViewShell; +class SwTxtFtn; +class SwAttrIter; +struct SwMultiCreator; + +#ifdef BIDI +class SwMultiPortion; +#endif + +/* Minimum: Prozentwert fuers kernen */ +#define MINKERNPERCENT 5 +#define ARROW_WIDTH 200 +#define DIR_LEFT2RIGHT 0 +#define DIR_BOTTOM2TOP 1 +#define DIR_RIGHT2LEFT 2 +#define DIR_TOP2BOTTOM 3 + +#ifdef DBG_UTIL +#define OPTCALM( rInf ) (rInf).IsOptCalm() +#define OPTLOW( rInf ) (rInf).IsOptLow() +#define OPTDBG( rInf ) (rInf).IsOptDbg() +#else +#define OPTCALM( rInf ) sal_True +#define OPTLOW( rInf ) sal_False +#define OPTDBG( rInf ) sal_False +#endif + +/************************************************************************* + * class SwLineInfo + *************************************************************************/ + +// Beruecksichtigt das Attribut LineSpace bei der Hoehen/Ascentberechnung. + +class SwLineInfo +{ + friend class SwTxtIter; + + const SvxTabStopItem *pRuler; + const SvxLineSpacingItem *pSpace; + USHORT nVertAlign; + KSHORT nDefTabStop; + void CtorInit( const SwAttrSet& rAttrSet ); + inline SwLineInfo() {} +public: + inline SwLineInfo( const SwAttrSet& rAttrSet ) + { CtorInit( rAttrSet ); } + // Liefert den Tabstop, der auf LinePos folgt, oder 0. + const SvxTabStop *GetTabStop( const SwTwips nLinePos, + const SwTwips nLeft, + const SwTwips nRight ) const; + inline const SvxLineSpacingItem *GetLineSpacing() const { return pSpace; } + inline KSHORT GetDefTabStop() const { return nDefTabStop; } + inline void SetDefTabStop( KSHORT nNew ) const + { ( (SwLineInfo*)this )->nDefTabStop = nNew; } + + // vertical alignment + inline USHORT GetVertAlign() const { return nVertAlign; } +#ifdef BIDI + inline sal_Bool HasSpecialAlign( sal_Bool bVert ) const + { return bVert ? + ( SvxParaVertAlignItem::BASELINE != nVertAlign ) : + ( SvxParaVertAlignItem::BASELINE != nVertAlign && + SvxParaVertAlignItem::AUTOMATIC != nVertAlign ); } +#else + inline sal_Bool HasSpecialAlign() const + { return SvxParaVertAlignItem::BASELINE != nVertAlign || + SvxParaVertAlignItem::AUTOMATIC != nVertAlign; } +#endif + +// friend ostream &operator<<( ostream &rOS, const SwLineInfo &rInf ); + friend SvStream &operator<<( SvStream &rOS, const SwLineInfo &rInf ); +}; + +/************************************************************************* + * class SwTxtInfo + *************************************************************************/ + +class SwTxtInfo +{ + // Implementation in txthyph.cxx + friend void SetParaPortion( SwTxtInfo *pInf, SwParaPortion *pRoot ); + SwParaPortion *pPara; + xub_StrLen nTxtStart; // TxtOfst bei Follows + +protected: + inline SwTxtInfo() { } +public: + void CtorInit( SwTxtFrm *pFrm ); + SwTxtInfo( const SwTxtInfo &rInf ); + inline SwTxtInfo( SwTxtFrm *pFrm ) { CtorInit( pFrm ); } + inline SwParaPortion *GetParaPortion() { return pPara; } + inline const SwParaPortion *GetParaPortion() const { return pPara; } + inline xub_StrLen GetTxtStart() const { return nTxtStart; } + + friend SvStream &operator<<( SvStream &rOS, const SwTxtInfo &rInf ); +}; + +/************************************************************************* + * class SwTxtSizeInfo + *************************************************************************/ + +DECLARE_TABLE( SwTxtPortionTable, sal_IntPtr ) + +class SwTxtSizeInfo : public SwTxtInfo +{ +protected: + // during formatting, a small database is built, mapping portion pointers + // to their maximum size (used for kana compression) + SwTxtPortionTable aMaxWidth; + // for each line, an array of compression values is calculated + // this array is passed over to the info structure + SvUShorts* pKanaComp; + + ViewShell *pVsh; + + // pOut is the output device, pRef is the device used for formatting + OutputDevice *pOut; + OutputDevice *pRef; + + SwFont *pFnt; + SwUnderlineFont *pUnderFnt; // Font for underlining + SwTxtFrm *pFrm; + const SwViewOption *pOpt; + const XubString *pTxt; + xub_StrLen nIdx, nLen; + USHORT nKanaIdx; + sal_Bool bOnWin : 1; + sal_Bool bNotEOL : 1; + sal_Bool bURLNotify : 1; + sal_Bool bStopUnderFlow : 1;// Underflow gestoppt z.B. von einer FlyPortion + sal_Bool bArrowDone : 1; // Pfeil nach links bei gescrollten Absaetzen + sal_Bool bFtnInside : 1; // the current line contains a footnote + sal_Bool bMulti : 1; // inside a multiportion + sal_Bool bFirstMulti : 1; // this flag is used for two purposes: + // - the multiportion is the first lineportion + // - indicates, if we are currently in second + // line of multi portion + sal_Bool bRuby : 1; // during the formatting of a phonetic line + sal_Bool bHanging : 1; // formatting of hanging punctuation allowed + sal_Bool bScriptSpace : 1; // space between different scripts (Asian/Latin) + sal_Bool bForbiddenChars : 1; // Forbidden start/endline characters +#ifdef VERTICAL_LAYOUT + sal_Bool bSnapToGrid : 1; // paragraph snaps to grid +#endif + sal_uInt8 nDirection : 2; // writing direction: 0/90/180/270 degree + +protected: + void CtorInit( SwTxtFrm *pFrm, SwFont *pFnt = 0, + const xub_StrLen nIdx = 0, + const xub_StrLen nLen = STRING_LEN ); + SwTxtSizeInfo() {} +public: + SwTxtSizeInfo( const SwTxtSizeInfo &rInf ); + SwTxtSizeInfo( const SwTxtSizeInfo &rInf, const XubString &rTxt, + const xub_StrLen nIdx = 0, + const xub_StrLen nLen = STRING_LEN ); + + inline SwTxtSizeInfo( SwTxtFrm *_pFrm, SwFont *_pFnt = 0, + const xub_StrLen _nIdx = 0, + const xub_StrLen _nLen = STRING_LEN ) + { CtorInit( _pFrm, _pFnt, _nIdx, _nLen ); } + + // GetMultiAttr returns the text attribute of the multiportion, + // if rPos is inside any multi-line part. + // rPos will set to the end of the multi-line part. +#ifdef BIDI + SwMultiCreator* GetMultiCreator( xub_StrLen &rPos, SwMultiPortion* pM ) const; +#else + SwMultiCreator* GetMultiCreator( xub_StrLen &rPos ) const; +#endif + + inline sal_Bool OnWin() const { return bOnWin; } + inline void SetOnWin( const sal_Bool bNew ) { bOnWin = bNew; } + inline sal_Bool NotEOL() const { return bNotEOL; } + inline void SetNotEOL( const sal_Bool bNew ) { bNotEOL = bNew; } + inline sal_Bool URLNotify() const { return bURLNotify; } + inline void SetURLNotify( const sal_Bool bNew ) { bURLNotify = bNew; } + inline sal_Bool StopUnderFlow() const { return bStopUnderFlow; } + inline void SetStopUnderFlow( const sal_Bool bNew ) { bStopUnderFlow = bNew; } + inline sal_Bool IsFtnInside() const { return bFtnInside; } + inline void SetFtnInside( const sal_Bool bNew ) { bFtnInside = bNew; } + inline sal_Bool IsMulti() const { return bMulti; } + 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 sal_Bool IsHanging() const { return bHanging; } + inline void SetHanging( const sal_Bool bNew ) { bHanging = bNew; } + inline sal_Bool HasScriptSpace() const { return bScriptSpace; } + inline void SetScriptSpace( const sal_Bool bNew ) { bScriptSpace = bNew; } + inline sal_Bool HasForbiddenChars() const { return bForbiddenChars; } + inline void SetForbiddenChars( const sal_Bool bN ) { bForbiddenChars = bN; } +#ifdef VERTICAL_LAYOUT + inline sal_Bool SnapToGrid() const { return bSnapToGrid; } + inline void SetSnapToGrid( const sal_Bool bN ) { bSnapToGrid = bN; } +#endif + inline sal_uInt8 GetDirection() const { return nDirection; } + inline void SetDirection( const sal_uInt8 nNew ) { nDirection = nNew; } + inline sal_Bool IsRotated() const { return 0 != ( 1 & nDirection ); } + + inline ViewShell *GetVsh() { return pVsh; } + inline const ViewShell *GetVsh() const { return pVsh; } + + inline OutputDevice *GetOut() { return pOut; } + inline const OutputDevice *GetOut() const { return pOut; } + inline void SetOut( OutputDevice* pNewOut ) { pOut = pNewOut; } + + inline OutputDevice *GetRefDev() { return pRef; } + inline const OutputDevice *GetRefDev() const { return pRef; } + + inline SwFont *GetFont() { return pFnt; } + inline const SwFont *GetFont() const { return pFnt; } + inline void SetFont( SwFont *pNew ) { pFnt = pNew; } + void SelectFont(); + inline void SetUnderFnt( SwUnderlineFont* pNew ) { pUnderFnt = pNew; } + inline SwUnderlineFont* GetUnderFnt() const { return pUnderFnt; } + + inline const SwViewOption &GetOpt() const { return *pOpt; } + inline const XubString &GetTxt() const { return *pTxt; } + inline xub_Unicode GetChar( const xub_StrLen nPos ) const + { return pTxt->GetChar( nPos ); } + + inline KSHORT GetTxtHeight() const; + + // + // GetTxtSize + // + SwPosSize GetTxtSize( OutputDevice *pOut, const SwScriptInfo* pSI, + const XubString& rTxt, const xub_StrLen nIdx, + const xub_StrLen nLen, const USHORT nComp ) const; + SwPosSize GetTxtSize() const; + void GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIdx, + const xub_StrLen nLen, const USHORT nComp, + USHORT& nMinSize, USHORT& nMaxSizeDiff ) const; + inline SwPosSize GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIdx, + const xub_StrLen nLen, const USHORT nComp ) const; + inline SwPosSize GetTxtSize( const XubString &rTxt ) const; + + // + // GetTxtBreak + // + xub_StrLen GetTxtBreak( const long nLineWidth, + const xub_StrLen nMaxLen, + const USHORT nComp ) const; + xub_StrLen GetTxtBreak( const long nLineWidth, + const xub_StrLen nMaxLen, + const USHORT nComp, + xub_StrLen& rExtraCharPos ) const; + + inline KSHORT GetAscent() const; + + inline xub_StrLen GetIdx() const { return nIdx; } + inline void SetIdx( const xub_StrLen nNew ) { nIdx = nNew; } + inline xub_StrLen GetLen() const { return nLen; } + inline void SetLen( const xub_StrLen nNew ) { nLen = nNew; } + inline void SetTxt( const XubString &rNew ){ pTxt = &rNew; } + + friend SvStream &operator<<( SvStream &rOS, const SwTxtSizeInfo &rInf ); + +// 7780: Keine Bullets beim Symbol-Zeichensatz! + inline sal_Bool IsNoSymbol() const + { return RTL_TEXTENCODING_SYMBOL != pFnt->GetCharSet( pFnt->GetActual() ); } + + + // Home is where Your heart is... + inline SwTxtFrm *GetTxtFrm() { return pFrm; } + inline const SwTxtFrm *GetTxtFrm() const { return pFrm; } + + inline sal_Bool HasHint( xub_StrLen nPos ) const + { return _HasHint( pFrm->GetTxtNode(), nPos ); } + static sal_Bool _HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos ); + + inline SwDoc* GetDoc() const { return pFrm->GetNode()->GetDoc(); }; + + // + // If Kana Compression is enabled, a minimum and maximum portion width + // is calculated. We format lines with minimal size and share remaining + // space among compressed kanas. + // During formatting, the maximum values of compressable portions are + // stored in aMaxWidth and discarded after a line has been formatted. + inline void SetMaxWidthDiff( ULONG nKey, USHORT nVal ) + { + aMaxWidth.Insert( nKey, nVal ); + }; + inline USHORT GetMaxWidthDiff( ULONG nKey ) + { + return (USHORT)aMaxWidth.Get( nKey ); + }; + inline void ResetMaxWidthDiff() + { + aMaxWidth.Clear(); + }; + inline sal_Bool CompressLine() + { + return (sal_Bool)aMaxWidth.Count(); + }; + + // + // Feature: Kana Compression + // + inline MSHORT GetKanaIdx() const { return nKanaIdx; } + inline void ResetKanaIdx(){ nKanaIdx = 0; } + inline void SetKanaIdx( MSHORT nNew ) { nKanaIdx = nNew; } + inline void IncKanaIdx() { ++nKanaIdx; } + inline void SetKanaComp( SvUShorts *pNew ){ pKanaComp = pNew; } + inline SvUShorts* GetpKanaComp() const { return pKanaComp; } + inline USHORT GetKanaComp() const + { return ( pKanaComp && nKanaIdx < pKanaComp->Count() ) + ? (*pKanaComp)[nKanaIdx] : 0; } + +#ifdef DBG_UTIL +#endif +}; + +/************************************************************************* + * class SwTxtPaintInfo + *************************************************************************/ + +class SwTxtPaintInfo : public SwTxtSizeInfo +{ + SwWrongList *pWrongList; + SvShorts *pSpaceAdd; + const SvxBrushItem *pBrushItem; // Fuer den Hintergrund + SwRect aItemRect; // ebenfalls fuer den Hintergrund + SwTxtFly aTxtFly; // FlyFrm-Berechnung + Point aPos; // Ausgabeposition + SwRect aPaintRect; // Original Ausgaberechteck (aus Layout-Paint) + + MSHORT nSpaceIdx; + + SwTxtPaintInfo &operator=(const SwTxtPaintInfo&); + +protected: +#ifndef DBG_UTIL + SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0; pBrushItem = 0;} +#else + SwTxtPaintInfo() { pFrm = 0; pWrongList = 0; pSpaceAdd = 0; + pBrushItem = ((SvxBrushItem*)-1);} +#endif +public: + SwTxtPaintInfo( const SwTxtPaintInfo &rInf ); + + void CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint ); + + void SetBack( const SvxBrushItem *pItem, + const SwRect &rRect ) { pBrushItem = pItem; aItemRect = rRect;} + const SvxBrushItem *GetBrushItem() const { return pBrushItem; } + const SwRect &GetBrushRect() const { return aItemRect; } + + inline SwTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint ) + { CtorInit( pFrame, rPaint ); } + + inline SwTwips X() const { return aPos.X(); } + inline void X( const long nNew ) { aPos.X() = nNew; } + inline SwTwips Y() const { return aPos.Y(); } + inline void Y( const SwTwips nNew ) { aPos.Y() = nNew; } + + inline SwTxtFly *GetTxtFly() { return &aTxtFly; } + inline const SwTxtFly *GetTxtFly() const { return &aTxtFly; } + inline void DrawText( const XubString &rText, const SwLinePortion &rPor, + const xub_StrLen nIdx = 0, + const xub_StrLen nLen = STRING_LEN, + const sal_Bool bKern = sal_False) const; + inline void DrawText( const SwLinePortion &rPor, const xub_StrLen nLen, + const sal_Bool bKern = sal_False ) const; + inline void DrawWrongText( const SwLinePortion &rPor, const xub_StrLen nLen, + const sal_Bool bKern = sal_False ) const; +#ifdef VERTICAL_LAYOUT +#endif + + + inline SwTwips GetPaintOfst() const; + inline void SetPaintOfst( const SwTwips nNew ); + inline const Point &GetPos() const { return aPos; } + inline void SetPos( const Point &rNew ) { aPos = rNew; } + + inline const SwRect &GetPaintRect() const { return aPaintRect; } + inline void SetPaintRect( const SwRect &rNew ) { aPaintRect = rNew; } + + friend SvStream &operator<<( SvStream &rOS, const SwTxtPaintInfo &rInf ); + + inline MSHORT GetSpaceIdx() const { return nSpaceIdx; } + inline void ResetSpaceIdx(){nSpaceIdx = 0; } + inline void SetSpaceIdx( MSHORT nNew ) { nSpaceIdx = nNew; } + inline void IncSpaceIdx() { ++nSpaceIdx; } + inline void SetSpaceAdd( SvShorts *pNew ){ pSpaceAdd = pNew; } + inline SvShorts* GetpSpaceAdd() const { return pSpaceAdd; } + inline short GetSpaceAdd() const + { return ( pSpaceAdd && nSpaceIdx < pSpaceAdd->Count() ) + ? (*pSpaceAdd)[nSpaceIdx] : 0; } + + inline void SetWrongList( SwWrongList *pNew ){ pWrongList = pNew; } + inline SwWrongList* GetpWrongList() const { return pWrongList; } + +}; + +/************************************************************************* + * class SwTxtFormatInfo + *************************************************************************/ + +class SwTxtFormatInfo : public SwTxtPaintInfo +{ + // temporary arguments for hyphenation + ::com::sun::star::beans::PropertyValues aHyphVals; + + SwLineLayout *pRoot; // die Root der aktuellen Zeile (pCurr) + SwLinePortion *pLast; // die letzte Portion + SwFlyPortion *pFly; // die nachfolgende FlyPortion + SwFldPortion *pLastFld; // umgebrochenes Feld + SwLinePortion *pUnderFlow; // Unterlaufsituation: letzte Portion + SwLinePortion *pRest; // Rest ist der Beginn der naechsten Zeile + + SwTabPortion *pLastTab; // die _letzte_ TabPortion + + xub_StrLen nSoftHyphPos; // SoftHyphPos fuer Hyphenate + xub_StrLen nHyphStart; // TxtPos, an der die interakt.Tr.z.Z. steht + xub_StrLen nHyphWrdStart; // gefundene Wort-Position + xub_StrLen nHyphWrdLen; // gefundene Wort-Laenge + xub_StrLen nLineStart; // aktueller Zeilenbeginn im rTxt + xub_StrLen nUnderScorePos; // enlarge repaint if underscore has been found + KSHORT nLeft; // linker Rand + KSHORT nRight; // rechter Rand + KSHORT nFirst; // EZE + KSHORT nRealWidth; // "echte" Zeilenbreite + KSHORT nWidth; // "virtuelle" Zeilenbreite + KSHORT nLineHeight; // endgueltige Hoehe nach CalcLine + KSHORT nLineNettoHeight; // line height without spacing + KSHORT nForcedLeftMargin; // Verschiebung des linken Rands wg. Rahmen + + INT16 nMinLeading; // minimum number of chars before hyphenation point + INT16 nMinTrailing; // minimum number of chars after hyphenation point + INT16 nMinWordLength; // minimum length of word to be hyphenated + + sal_Bool bFull : 1; // Zeile ist voll + sal_Bool bFtnDone : 1; // Ftn bereits formatiert + sal_Bool bErgoDone : 1; // ErgoDone bereits formatiert + sal_Bool bNumDone : 1; // bNumDone bereits formatiert + sal_Bool bStop : 1; // Sofort abbrechen, Zeile verwerfen. + sal_Bool bNewLine : 1; // Noch eine weitere Zeile formatieren. + sal_Bool bShift : 1; // Positionsaend.: Repaint bis auf Weiteres + sal_Bool bUnderFlow : 1; // Kontext: UnderFlow() ? + sal_Bool bInterHyph: 1; // interaktive Trennung ? + sal_Bool bAutoHyph : 1; // automatische Trennung ? + sal_Bool bDropInit : 1; // DropWidth einstellen. + sal_Bool bQuick : 1; // FormatQuick() + sal_Bool bNoEndHyph : 1; // Trennung am Zeilenende abgeschaltet wg. MaxHyphens + sal_Bool bNoMidHyph : 1; // Trennung vor Flies abgeschaltet wg. MaxHyphens + sal_Bool bIgnoreFly: 1; // FitToContent ignoriert Flies + sal_Bool bFakeLineStart: 1; // String has been replaced by field portion + // info structure only pretends that we are at + // the beginning of a line + + xub_Unicode cTabDecimal; // das _aktuelle_ Dezimalzeichen + xub_Unicode cHookChar; // fuer Tabs in Feldern etc. + sal_uInt8 nMaxHyph; // max. Zeilenanz. aufeinanderfolg. Trenn. + sal_Bool bTestFormat; // Testformatierung aus WouldFit, keine Benachrichtigungen etc. + + // Hyphenating ... + sal_Bool InitHyph( const sal_Bool bAuto = sal_False ); + sal_Bool _CheckFtnPortion( SwLineLayout* pCurr ); + +public: + void CtorInit( SwTxtFrm *pFrm, const sal_Bool bInterHyph = sal_False, + const sal_Bool bQuick = sal_False, const sal_Bool bTst = sal_False ); + inline SwTxtFormatInfo(SwTxtFrm *pFrame,const sal_Bool _bInterHyph=sal_False, + const sal_Bool _bQuick = sal_False, const sal_Bool bTst = sal_False ) + { CtorInit( pFrame, _bInterHyph, _bQuick, bTst ); } + + // For the formatting inside a double line in a line (multi-line portion) + // we need a modified text-format-info: + + inline KSHORT Width() const { return nWidth; } + inline void Width( const KSHORT nNew ) { nWidth = nNew; } + void Init(); + + // liefert die erste veraenderte Position im Absatz zurueck + inline xub_StrLen GetReformatStart() const; + + // Raender + inline KSHORT Left() const { return nLeft; } + inline void Left( const KSHORT nNew ) { nLeft = nNew; } + inline KSHORT Right() const { return nRight; } + inline void Right( const KSHORT nNew ) { nRight = nNew; } + inline KSHORT First() const { return nFirst; } + inline void First( const KSHORT nNew ) { nFirst = nNew; } + inline KSHORT CurrLeft() const { return (nLineStart ? nLeft : nFirst); } + inline KSHORT RealWidth() const { return nRealWidth; } + inline void RealWidth( const KSHORT nNew ) { nRealWidth = nNew; } + inline KSHORT ForcedLeftMargin() const { return nForcedLeftMargin; } + inline void ForcedLeftMargin( const KSHORT nN ) { nForcedLeftMargin = nN; } + + inline sal_uInt8 &MaxHyph() { return nMaxHyph; } + inline const sal_uInt8 &MaxHyph() const { return nMaxHyph; } + + inline SwLineLayout *GetRoot() { return pRoot; } + inline const SwLineLayout *GetRoot() const { return pRoot; } + + inline void SetRoot( SwLineLayout *pNew ) { pRoot = pNew; } + inline SwLinePortion *GetLast() { return pLast; } + inline void SetLast( SwLinePortion *pNewLast ) { pLast = pNewLast; } + inline sal_Bool IsFull() const { return bFull; } + inline void SetFull( const sal_Bool bNew ) { bFull = bNew; } + inline sal_Bool IsHyphForbud() const + { return pFly ? bNoMidHyph : bNoEndHyph; } + inline void SetHyphForbud( const sal_Bool bNew ) + { if ( pFly ) bNoMidHyph = bNew; else bNoEndHyph = bNew; } + inline void ChkNoHyph( const sal_uInt8 bEnd, const sal_uInt8 bMid ) + { bNoEndHyph = (nMaxHyph && bEnd >= nMaxHyph); + bNoMidHyph = (nMaxHyph && bMid >= nMaxHyph); } + inline sal_Bool IsIgnoreFly() const { return bIgnoreFly; } + inline void SetIgnoreFly( const sal_Bool bNew ) { bIgnoreFly = bNew; } + inline sal_Bool IsFakeLineStart() const { return bFakeLineStart; } + inline void SetFakeLineStart( const sal_Bool bNew ) { bFakeLineStart = bNew; } + inline sal_Bool IsStop() const { return bStop; } + inline void SetStop( const sal_Bool bNew ) { bStop = bNew; } + inline SwLinePortion *GetRest() { return pRest; } + inline void SetRest( SwLinePortion *pNewRest ) { pRest = pNewRest; } + inline sal_Bool IsNewLine() const { return bNewLine; } + inline void SetNewLine( const sal_Bool bNew ) { bNewLine = bNew; } + inline sal_Bool IsShift() const { return bShift; } + inline void SetShift( const sal_Bool bNew ) { bShift = bNew; } + inline sal_Bool IsInterHyph() const { return bInterHyph; } + inline sal_Bool IsAutoHyph() const { return bAutoHyph; } + inline sal_Bool IsUnderFlow() const { return bUnderFlow; } + inline void ClrUnderFlow() { bUnderFlow = sal_False; } + inline sal_Bool IsDropInit() const { return bDropInit; } + inline void SetDropInit( const sal_Bool bNew ) { bDropInit = bNew; } + inline sal_Bool IsQuick() const { return bQuick; } + inline sal_Bool IsTest() const { return bTestFormat; } + + inline xub_StrLen GetLineStart() const { return nLineStart; } + inline void SetLineStart( const xub_StrLen nNew ) { nLineStart = nNew; } + + // these are used during fly calculation + inline KSHORT GetLineHeight() const { return nLineHeight; } + inline void SetLineHeight( const KSHORT nNew ) { nLineHeight = nNew; } + inline KSHORT GetLineNettoHeight() const { return nLineNettoHeight; } + inline void SetLineNettoHeight( const KSHORT nNew ) { nLineNettoHeight = nNew; } + + inline const SwLinePortion *GetUnderFlow() const { return pUnderFlow; } + inline SwLinePortion *GetUnderFlow() { return pUnderFlow; } + inline void SetUnderFlow( SwLinePortion *pNew ) + { pUnderFlow = pNew; bUnderFlow = sal_True; } + inline xub_StrLen GetSoftHyphPos() const { return nSoftHyphPos; } + inline void SetSoftHyphPos( const xub_StrLen nNew ) { nSoftHyphPos = nNew; } + + inline void SetParaFtn(); + + // FlyFrms + inline SwFlyPortion *GetFly() { return pFly; } + inline void SetFly( SwFlyPortion *pNew ) { pFly = pNew; } + + inline const SwAttrSet& GetCharAttr() const; + + // Tabs + inline SwTabPortion *GetLastTab() { return pLastTab; } + inline void SetLastTab( SwTabPortion *pNew ) { pLastTab = pNew; } + inline xub_Unicode GetTabDecimal() const { return cTabDecimal; } + inline void SetTabDecimal( const xub_Unicode cNew ) { cTabDecimal = cNew;} + + // Last* + inline SwFldPortion *GetLastFld() { return pLastFld; } + inline void SetLastFld( SwFldPortion *pNew ) { pLastFld = pNew; } + + inline void ClearHookChar() { cHookChar = 0; } + inline void SetHookChar( const xub_Unicode cNew ) { cHookChar = cNew; } + inline xub_Unicode GetHookChar() const { return cHookChar; } + + // Done-Flags + inline sal_Bool IsFtnDone() const { return bFtnDone; } + inline void SetFtnDone( const sal_Bool bNew ) { bFtnDone = bNew; } + inline sal_Bool IsErgoDone() const { return bErgoDone; } + inline void SetErgoDone( const sal_Bool bNew ) { bErgoDone = bNew; } + inline sal_Bool IsNumDone() const { return bNumDone; } + inline void SetNumDone( const sal_Bool bNew ) { bNumDone = bNew; } + inline sal_Bool IsArrowDone() const { return bArrowDone; } + inline void SetArrowDone( const sal_Bool bNew ) { bArrowDone = bNew; } + + // Fuer SwTxtPortion::Hyphenate + inline sal_Bool IsSoftHyph( const xub_StrLen nPos ) const; + sal_Bool ChgHyph( const sal_Bool bNew ); + + // Soll die Trennhilfe angeschmissen werden? + sal_Bool IsHyphenate() const; + inline void SetHyphStart( const xub_StrLen nNew ) { nHyphStart = nNew; } + inline xub_StrLen GetHyphStart() const { return nHyphStart; } + inline void SetHyphWrdStart( const xub_StrLen nNew ) { nHyphWrdStart = nNew; } + inline xub_StrLen GetHyphWrdStart() const { return nHyphWrdStart; } + inline void SetHyphWrdLen( const xub_StrLen nNew ) { nHyphWrdLen = nNew; } + inline xub_StrLen GetHyphWrdLen() const { return nHyphWrdLen; } + inline xub_StrLen GetUnderScorePos() const { return nUnderScorePos; } + inline void SetUnderScorePos( xub_StrLen nNew ) { nUnderScorePos = nNew; } + + // ruft HyphenateWord() des Hyphenators + const ::com::sun::star::beans::PropertyValues & + GetHyphValues() const; + + sal_Bool CheckFtnPortion( SwLineLayout* pCurr ) + { return IsFtnInside() && _CheckFtnPortion( pCurr ); } + + // Dropcaps vom SwTxtFormatter::CTOR gerufen. + const SwFmtDrop *GetDropFmt() const; + + // setzt die FormatInfo wieder in den Anfangszustand + void Reset( const SwTxtFrm *pFrame); // , const sal_Bool bAll ); + + // Sets the last SwKernPortion as pLast, if it is followed by empty portions + BOOL LastKernPortion(); + + // Sucht ab nIdx bis nEnd nach Tabs, TabDec, TXTATR und BRK. + // Return: gefundene Position, setzt ggf. cHookChar + xub_StrLen ScanPortionEnd( const xub_StrLen nStart, const xub_StrLen nEnd ); + +// friend ostream &operator<<( ostream &rOS, const SwTxtFormatInfo &rInf ); + friend SvStream &operator<<( SvStream &rOS, const SwTxtFormatInfo &rInf ); +}; + +/************************************************************************* + * class SwTxtSlot + *************************************************************************/ + +// Fuer die Textersetzung und Restaurierung der SwTxtSizeInfo. +// Die Art und Weise ist etwas kriminell, rInf ist const und wird +// trotzdem veraendert. Da rInf im DTOR wieder restauriert wird, +// ist dies zulaessig, es handelt sich um ein "logisches const". +// Die beiden Klassen SwTxtSlot und SwTxtSlotLen sind Zwillinge, sie +// unterscheiden sich nur im Ctor in der Zuweisung der Textlaenge +// an pInf. Aenderungen muessen in beiden gepflegt werden! + +class SwTxtSlot +{ + const XubString *pOldTxt; + XubString aTxt; + xub_StrLen nIdx; + xub_StrLen nLen; + sal_Bool bOn; +protected: + SwTxtSizeInfo *pInf; +public: + SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor ); + ~SwTxtSlot(); + inline sal_Bool IsOn() const { return bOn; } +}; + +class SwTxtSlotLen +{ + const XubString *pOldTxt; + XubString aTxt; + xub_StrLen nIdx; + xub_StrLen nLen; + sal_Bool bOn; +protected: + SwTxtSizeInfo *pInf; +public: + // Der Ersetzungstring kommt wahlweise aus der Portion via GetExpText() + // oder aus dem char Pointer pCh, wenn dieser ungleich NULL ist. + SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor, + const sal_Char *pCh = NULL ); + ~SwTxtSlotLen(); + inline sal_Bool IsOn() const { return bOn; } +}; + +/************************************************************************* + * class SwFontSave + *************************************************************************/ + +class SwFontSave +{ + SwTxtSizeInfo *pInf; + SwFont *pFnt; + SwAttrIter *pIter; +public: + SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pFnt, + SwAttrIter* pItr = NULL ); + ~SwFontSave(); +}; + +/************************************************************************* + * class SwDefFontSave + *************************************************************************/ + + +/************************************************************************* + * class SwFtnSave + *************************************************************************/ + +class SwFtnSave +{ + SwTxtSizeInfo *pInf; + SwFont *pFnt; + SwFont *pOld; +public: + SwFtnSave( const SwTxtSizeInfo &rInf, const SwTxtFtn *pTxtFtn ); + ~SwFtnSave(); +}; + +/************************************************************************* + * Inline-Implementierungen SwTxtSizeInfo + *************************************************************************/ + +inline KSHORT SwTxtSizeInfo::GetAscent() const +{ + return ((SwFont*)GetFont())->GetAscent( pVsh, GetOut() ); +} + +inline KSHORT SwTxtSizeInfo::GetTxtHeight() const +{ + return ((SwFont*)GetFont())->GetHeight( pVsh, GetOut() ); +} + +inline SwPosSize SwTxtSizeInfo::GetTxtSize( const XubString &rTxt ) const +{ + return GetTxtSize( pOut, 0, rTxt, 0, rTxt.Len(), 0 ); +} + +inline SwPosSize SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, + const xub_StrLen nNewIdx, + const xub_StrLen nNewLen, + const USHORT nCompress ) const +{ + return GetTxtSize( pOut, pSI, *pTxt, nNewIdx, nNewLen, nCompress ); +} + +/************************************************************************* + * Inline-Implementierungen SwTxtPaintInfo + *************************************************************************/ + +inline SwTwips SwTxtPaintInfo::GetPaintOfst() const +{ + return GetParaPortion()->GetRepaint()->GetOfst(); +} + +inline void SwTxtPaintInfo::SetPaintOfst( const SwTwips nNew ) +{ + GetParaPortion()->GetRepaint()->SetOfst( nNew ); +} + + +inline void SwTxtPaintInfo::DrawText( const XubString&, + const SwLinePortion&, + const xub_StrLen , const xub_StrLen, + const sal_Bool ) const +{ + DBG_BF_ASSERT(0, "STRIP"); +} + +inline void SwTxtPaintInfo::DrawText( const SwLinePortion&, + const xub_StrLen, const sal_Bool ) const +{ + DBG_BF_ASSERT(0, "STRIP"); +} + +inline void SwTxtPaintInfo::DrawWrongText( const SwLinePortion&, + const xub_StrLen, const sal_Bool ) const +{ + DBG_BF_ASSERT(0, "STRIP"); +} + +/************************************************************************* + * Inline-Implementierungen SwTxtFormatInfo + *************************************************************************/ + +inline xub_StrLen SwTxtFormatInfo::GetReformatStart() const +{ + return GetParaPortion()->GetReformat()->Start(); +} + +inline const SwAttrSet& SwTxtFormatInfo::GetCharAttr() const +{ + return GetTxtFrm()->GetTxtNode()->GetSwAttrSet(); +} + +inline void SwTxtFormatInfo::SetParaFtn() +{ + GetTxtFrm()->SetFtn( sal_True ); +} + +inline sal_Bool SwTxtFormatInfo::IsSoftHyph( const xub_StrLen nPos ) const +{ + return CHAR_SOFTHYPHEN == GetTxtFrm()->GetTxtNode()->GetTxt().GetChar(nPos); +} + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/itratr.hxx b/binfilter/bf_sw/source/core/text/itratr.hxx new file mode 100644 index 000000000000..4f58e38cbab7 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/itratr.hxx @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ITRATR_HXX +#define _ITRATR_HXX + + +#include <tools/solar.h> +#include <atrhndl.hxx> + +#include "txttypes.hxx" +#include "swfont.hxx" +#include "porlay.hxx" + +#define _SVSTDARR_XUB_STRLEN +#define _SVSTDARR_USHORTS +#include <bf_svtools/svstdarr.hxx> +class OutputDevice; +namespace binfilter { + + +class SwFont; +class SwpHints; +class SwTxtAttr; +class SwAttrSet; +class SwTxtNode; +class SwRedlineItr; +class ViewShell; + +#ifdef VERTICAL_LAYOUT +class SwTxtFrm; +#endif + +/************************************************************************* + * class SwAttrIter + *************************************************************************/ + +class SwAttrIter +{ + friend class SwFontSave; +protected: + + SwAttrHandler aAttrHandler; + ViewShell *pShell; + SwFont *pFnt; + SwpHints *pHints; + const SwAttrSet* pAttrSet; // das Char-Attribut-Set + SwScriptInfo* pScriptInfo; + +private: + OutputDevice *pLastOut; + MSHORT nChgCnt; + SwRedlineItr *pRedln; + xub_StrLen nStartIndex, nEndIndex, nPos; + BYTE nPropFont; + void SeekFwd( const xub_StrLen nPos ); + inline void SetFnt( SwFont* pNew ) { pFnt = pNew; } + const void* aMagicNo[ SW_SCRIPTS ]; + MSHORT aFntIdx[ SW_SCRIPTS ]; + +protected: + void Chg( SwTxtAttr *pHt ); + void Rst( SwTxtAttr *pHt ); +#ifdef VERTICAL_LAYOUT + void CtorInit( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf, SwTxtFrm* pFrm = 0 ); +#else + void CtorInit( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf ); +#endif + inline SwAttrIter() + : pFnt(0), pLastOut(0), nChgCnt(0), nPropFont(0), pShell(0), pRedln(0){} + +public: + // Konstruktor, Destruktor + inline SwAttrIter( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf ) + : pFnt(0), pLastOut(0), nChgCnt(0), nPropFont(0), pShell(0), pRedln(0) + { CtorInit( rTxtNode, rScrInf ); } + + virtual ~SwAttrIter(); + + inline SwRedlineItr *GetRedln() { return pRedln; } + // Liefert im Parameter die Position des naechsten Wechsels vor oder an + // der uebergebenen Characterposition zurueck. Liefert sal_False, wenn vor + // oder an dieser Position kein Wechsel mehr erfolgt, sal_True sonst. + xub_StrLen GetNextAttr( ) const; + // Macht die an der Characterposition i gueltigen Attribute im + // logischen Font wirksam. + sal_Bool Seek( const xub_StrLen nPos ); + // Bastelt den Font an der gew. Position via Seek und fragt ihn, + // ob er ein Symbolfont ist. + sal_Bool IsSymbol( const xub_StrLen nPos ); + + // Fuehrt ChgPhysFnt aus, wenn Seek() sal_True zurueckliefert. + sal_Bool SeekAndChg( const xub_StrLen nPos, OutputDevice *pOut ); + sal_Bool SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont = sal_False ); + + // Gibt es ueberhaupt Attributwechsel ? + inline sal_Bool HasHints() const { return 0 != pHints; } + + // liefert fuer eine Position das Attribut + SwTxtAttr *GetAttr( const xub_StrLen nPos ) const; + + inline const SwAttrSet* GetAttrSet() const { return pAttrSet; } + + inline const SwpHints *GetHints() const { return pHints; } + + inline SwFont *GetFnt() { return pFnt; } + inline const SwFont *GetFnt() const { return pFnt; } + + inline BYTE GetPropFont() const { return nPropFont; } + inline void SetPropFont( const BYTE nNew ) { nPropFont = nNew; } + + inline SwAttrHandler& GetAttrHandler() { return aAttrHandler; } +}; + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/itrform2.hxx b/binfilter/bf_sw/source/core/text/itrform2.hxx new file mode 100644 index 000000000000..a104222b314e --- /dev/null +++ b/binfilter/bf_sw/source/core/text/itrform2.hxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ITRFORM2_HXX +#define _ITRFORM2_HXX + +#include "itrpaint.hxx" +class SvLongs; +namespace binfilter { + +class SwFlyCntPortion; +class SwInterHyphInfo; +class SwDropPortion; +class SwFmtDrop; +class SwDrawObjs; +class SwTxtAttr; +class SwNumberPortion; +class SwErgoSumPortion; +class SwExpandPortion; +class SwMultiPortion; + + +/************************************************************************* + * class SwTxtFormatter + *************************************************************************/ + +class SwTxtFormatter : public SwTxtPainter +{ + const SwFmtDrop *pDropFmt; + SwMultiPortion* pMulti; // during formatting a multi-portion + sal_uInt8 nCntEndHyph; // zaehlt aufeinanderfolgende Hyphens am Zeilenende + sal_uInt8 nCntMidHyph; // zaehlt aufeinanderfolgende Hyphens vor Flies + xub_StrLen nLeftScanIdx; // for increasing performance during + xub_StrLen nRightScanIdx; // scanning for portion ends + sal_Bool bOnceMore : 1; // noch 'ne Runde? + sal_Bool bFlyInCntBase : 1; // Base-Referenz der zeichengeb. Rahmen setzen + sal_Bool bChanges : 1; // Flag, fuer die Berechnung des Repaint-Rechtecks + sal_Bool bTruncLines : 1; // Flag, Repaint-Rechtecks ggf. erweitern + sal_Bool bUnclipped : 1; // Flag, ob Repaint groesser als feste Zeilenhoehe + SwLinePortion *NewPortion( SwTxtFormatInfo &rInf ); + SwTxtPortion *NewTxtPortion( SwTxtFormatInfo &rInf ); + SwLinePortion *NewExtraPortion( SwTxtFormatInfo &rInf ); + SwTabPortion *NewTabPortion( SwTxtFormatInfo &rInf ) const; + SwNumberPortion *NewNumberPortion( SwTxtFormatInfo &rInf ) const; + SwDropPortion *NewDropPortion( SwTxtFormatInfo &rInf ); + SwNumberPortion *NewFtnNumPortion( SwTxtFormatInfo &rInf ) const; + SwErgoSumPortion *NewErgoSumPortion( SwTxtFormatInfo &rInf ) const; + SwExpandPortion *NewFldPortion( SwTxtFormatInfo &rInf, + const SwTxtAttr *pHt ) const; + SwFtnPortion *NewFtnPortion( SwTxtFormatInfo &rInf, SwTxtAttr *pHt ); + SwFlyCntPortion *NewFlyCntPortion( SwTxtFormatInfo &rInf, + SwTxtAttr *pHt ) const; + SwLinePortion *WhichFirstPortion( SwTxtFormatInfo &rInf ); + SwTxtPortion *WhichTxtPor( SwTxtFormatInfo &rInf ) const; + + // Das Herzstueck der Formatierung + void BuildPortions( SwTxtFormatInfo &rInf ); + + // Berechnung des emulierten rechten Rands + void CalcFlyWidth( SwTxtFormatInfo &rInf ); + + // wird von SwTxtFormatter wegen UpdatePos ueberladen + void CalcAdjustLine( SwLineLayout *pCurr ); + + // consideres line spacing attributes + void CalcRealHeight( sal_Bool bNewLine = sal_False ); + + // uebertraegt die Daten nach rInf + void FeedInf( SwTxtFormatInfo &rInf ) const; + + // behandelt die Unterlaufsituationen + SwLinePortion *UnderFlow( SwTxtFormatInfo &rInf ); + + // errechnet den Ascent und die Hoehe aus der Fontmetric + void CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor ); + + // determines, if a optimized repaint rectange is allowed + sal_Bool AllowRepaintOpt() const; + + // calculates and sets the optimized repaint offset + long CalcOptRepaint( xub_StrLen nOldLineEnd, const SvLongs* pFlyStart ); + + // wird von FormatLine gerufen. + void FormatReset( SwTxtFormatInfo &rInf ); + + // durch das Adjustment aendert sich die Position der Portions + void UpdatePos( SwLineLayout *pCurr, Point aStart, xub_StrLen nStartIdx, + sal_Bool bAllWays = sal_False ) const; + + // Setze alle FlyInCntFrms auf die uebergebene BaseLine + void AlignFlyInCntBase( long nBaseLine ) const; + + // Unterlaufbedingungen bei Flys + sal_Bool ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const; + + // Portion einfuegen. + void InsertPortion( SwTxtFormatInfo &rInf, SwLinePortion *pPor ) const; + + // schaetzt die Hoehe fuer die DropPortion + void GuessDropHeight( const MSHORT nLines ); + +public: + // errechnet die Hoehe fuer die DropPortion + void CalcDropHeight( const MSHORT nLines ); + + // errechnet den Bottom des Absatzes, beruecksichtigt an diesem verankerte + // Objekte mit Umlauf 1. Absatz. + SwTwips CalcBottomLine() const; + + // Beruecksichtigt zeichengebundene Objekte bei der Repaintrechteck- + // berechnung in Zeilen mit fester Zeilenhoehe + void CalcUnclipped( SwTwips& rTop, SwTwips& rBottom ); + + // u.a. fuer DropCaps + sal_Bool CalcOnceMore(); + + void CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf ); + inline SwTxtFormatter( SwTxtFrm *pFrm, SwTxtFormatInfo *pInf ) + { CtorInit( pFrm, pInf ); } + ~SwTxtFormatter(); + + xub_StrLen FormatLine( const xub_StrLen nStart ); + + void RecalcRealHeight(); + + // Wir formatieren eine Zeile fuer die interaktive Trennung + + // Spezialmethode fuer QuoVadis-Texte + // nErgo ist die Seitennummer der ErgoSum-Ftn + // Bei 0 ist es noch unklar. + xub_StrLen FormatQuoVadis( const xub_StrLen nStart ); + + // Die Notbremse: Formatierung abbrechen, Zeile verwerfen. + inline sal_Bool IsStop() const { return GetInfo().IsStop(); } + + // Das Gegenstueck: Formatierung unbedingt fortsetzen. + inline sal_Bool IsNewLine() const { return GetInfo().IsNewLine(); } + + // FormatQuick(); auffrischen von Formatinformationen + inline sal_Bool IsQuick() const { return GetInfo().IsQuick(); } + + // erzeugt ggfs. ein SwLineLayout, dass Ftn/Fly--Oszillation unterbindet. + + // SwTxtIter-Funktionalitaet + void Insert( SwLineLayout *pLine ); + + // die noch verbleibende Hoehe bis zum Seitenrand + + // Wie breit waerest Du ohne rechte Begrenzungen (Flys etc.)? + + SwLinePortion* MakeRestPortion(const SwLineLayout* pLine, xub_StrLen nPos); + + inline const SwFmtDrop *GetDropFmt() const { return pDropFmt; } + inline void ClearDropFmt() { pDropFmt = 0; } + + inline SwMultiPortion *GetMulti() const { return pMulti; } + + inline sal_Bool IsOnceMore() const { return bOnceMore; } + inline void SetOnceMore( sal_Bool bNew ) { bOnceMore = bNew; } + + inline sal_Bool HasChanges() const { return bChanges; } + inline void SetChanges() { bChanges = sal_True; } + + inline sal_Bool HasTruncLines() const { return bTruncLines; } + inline void SetTruncLines( sal_Bool bNew ) { bTruncLines = bNew; } + + inline sal_Bool IsUnclipped() const { return bUnclipped; } + inline void SetUnclipped( sal_Bool bNew ) { bUnclipped = bNew; } + + inline sal_Bool IsFlyInCntBase() const { return bFlyInCntBase; } + inline void SetFlyInCntBase( sal_Bool bNew = sal_True ){ bFlyInCntBase = bNew; } + + inline SwTxtFormatInfo &GetInfo() + { return (SwTxtFormatInfo&)SwTxtIter::GetInfo(); } + inline const SwTxtFormatInfo &GetInfo() const + { return (const SwTxtFormatInfo&)SwTxtIter::GetInfo(); } + + inline void InitCntHyph() { CntHyphens( nCntEndHyph, nCntMidHyph ); } + inline const sal_uInt8 &CntEndHyph() const { return nCntEndHyph; } + inline const sal_uInt8 &CntMidHyph() const { return nCntMidHyph; } + inline sal_uInt8 &CntEndHyph() { return nCntEndHyph; } + inline sal_uInt8 &CntMidHyph() { return nCntMidHyph; } +}; + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/itrpaint.hxx b/binfilter/bf_sw/source/core/text/itrpaint.hxx new file mode 100644 index 000000000000..ba0fecb3f8f6 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/itrpaint.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ITRPAINT_HXX +#define _ITRPAINT_HXX + +#include "itrtxt.hxx" +namespace binfilter { + +class SwSaveClip; // SwTxtPainter +class SwMultiPortion; + +/************************************************************************* + * class SwTxtPainter + *************************************************************************/ + +class SwTxtPainter : public SwTxtCursor +{ + sal_Bool bPaintDrop; + +protected: + void CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf ); + inline SwTxtPainter() { } +public: + inline SwTxtPainter( SwTxtFrm *pFrm, SwTxtPaintInfo *pInf ) + { CtorInit( pFrm, pInf ); } + // if PaintMultiPortion is called recursively, we have to pass the + // surrounding SwBidiPortion + inline void SetPaintDrop( const sal_Bool bNew ) { bPaintDrop = bNew; } + inline int IsPaintDrop() const { return bPaintDrop; } + inline SwTxtPaintInfo &GetInfo() + { return (SwTxtPaintInfo&)SwTxtIter::GetInfo(); } + inline const SwTxtPaintInfo &GetInfo() const + { return (const SwTxtPaintInfo&)SwTxtIter::GetInfo(); } +}; + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/itrtxt.hxx b/binfilter/bf_sw/source/core/text/itrtxt.hxx new file mode 100644 index 000000000000..8d8847dbe6c2 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/itrtxt.hxx @@ -0,0 +1,358 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _ITRTXT_HXX +#define _ITRTXT_HXX + +#include "swtypes.hxx" +#include "itratr.hxx" +#include "inftxt.hxx" +namespace binfilter { + +class SwTxtFrm; +struct SwPosition; +struct SwCrsrMoveState; +class SwMarginPortion; +class SwFlyPortion; + +/************************************************************************* + * class SwTxtIter + *************************************************************************/ + +class SwTxtIter : public SwAttrIter +{ +protected: + SwLineInfo aLineInf; +#ifndef VERTICAL_LAYOUT + Point aTopLeft; // erste Ausgabeposition +#endif + SwTxtFrm *pFrm; + SwTxtInfo *pInf; + SwLineLayout *pCurr; + SwLineLayout *pPrev; +#ifdef VERTICAL_LAYOUT + SwTwips nFrameStart; +#endif + SwTwips nY; + SwTwips nRegStart; // Anfangsposition (Y) des Registers + xub_StrLen nStart; // Start im Textstring, Ende = pCurr->GetLen() + KSHORT nRegDiff; // Zeilenabstand des Registers + MSHORT nLineNr; // Zeilennummer + sal_Bool bPrev : 1; + sal_Bool bRegisterOn : 1; // Registerhaltigkeit + sal_Bool bOneBlock : 1; // Blocksatz: Einzelwoerter austreiben + sal_Bool bLastBlock : 1; // Blocksatz: Auch die letzte Zeile + sal_Bool bLastCenter : 1; // Blocksatz: Letzte Zeile zentrieren + + SwLineLayout *_GetPrev(); + + // Zuruecksetzen in die erste Zeile. + void Init(); + void CtorInit( SwTxtFrm *pFrm, SwTxtInfo *pInf ); + inline SwTxtIter() { } + +public: + inline SwTxtIter( SwTxtFrm *pFrm, SwTxtInfo *pInf ) + { CtorInit( pFrm, pInf ); } + inline const SwLineLayout *GetCurr() const { return pCurr; } // niemals 0! + inline const SwLineLayout *GetNext() const { return pCurr->GetNext(); } + const SwLineLayout *GetPrev(); + inline xub_StrLen GetLength() const { return pCurr->GetLen(); } + inline MSHORT GetLineNr() const { return nLineNr; } + inline xub_StrLen GetStart() const { return nStart; } + inline xub_StrLen GetEnd() const { return GetStart() + GetLength(); } + inline SwTwips Y() const { return nY; } + + inline SwTwips RegStart() const { return nRegStart; } + inline KSHORT RegDiff() const { return nRegDiff; } + inline sal_Bool IsRegisterOn() const { return bRegisterOn; } + + inline SwTxtInfo &GetInfo() { return *pInf; } + inline const SwTxtInfo &GetInfo() const { return *pInf; } + + inline void Top() { Init(); } + void Bottom(); + const SwLineLayout *Next(); + const SwLineLayout *Prev(); + + // Ueberspringt die Dummyzeilen der FlyFrms + const SwLineLayout *NextLine(); + const SwLineLayout *PrevLine(); + const SwLineLayout *GetNextLine() const; + const SwLineLayout *GetPrevLine(); + + void CharToLine( const xub_StrLen ); + const SwLineLayout *TwipsToLine(const SwTwips); + + // schneidet ab pCurr alle ab. + void TruncLines( sal_Bool bNoteFollow = sal_False ); + + inline KSHORT GetLineHeight() const { return pCurr->GetRealHeight(); } + void CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const; + + // 5298, viel Aerger durch die Abfrage auf pCurr == pPara + inline sal_Bool IsFirstTxtLine() const + { return nStart == GetInfo().GetTxtStart() && + !( pCurr->IsDummy() && GetNextLine() ); } + + // Als Ersatz fuer das alte IsFirstLine() + inline sal_Bool IsParaLine() const + { return pCurr == pInf->GetParaPortion(); } + + const SwLineInfo &GetLineInfo() const { return aLineInf; } +#ifdef VERTICAL_LAYOUT + inline SwTwips GetFirstPos() const { return nFrameStart; } +#else + inline const Point &GetFirstPos() const { return aTopLeft; } +#endif + + inline sal_Bool SeekAndChg( SwTxtSizeInfo &rInf ); + inline sal_Bool SeekAndChgBefore( SwTxtSizeInfo &rInf ); + inline sal_Bool SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara=sal_False ); + + inline SwTxtFrm *GetTxtFrm() { return pFrm; } + inline const SwTxtFrm *GetTxtFrm() const { return pFrm; } + + // zaehlt aufeinanderfolgende Trennungen, um MaxHyphens einzuhalten + void CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const; +}; + +/************************************************************************* + * class SwTxtMargin + *************************************************************************/ + +class SwTxtMargin : public SwTxtIter +{ +private: + SwTwips nLeft; + SwTwips nRight; + SwTwips nFirst; + KSHORT nDropLeft; + KSHORT nDropHeight; + KSHORT nDropDescent; + MSHORT nDropLines; + MSHORT nAdjust; + +protected: + // fuer FormatQuoVadis + inline void Right( const SwTwips nNew ) { nRight = nNew; } + // fuer CalcFlyAdjust + inline void SetDropLeft( const KSHORT nNew ) { nDropLeft = nNew; } + + void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ); + inline SwTxtMargin() { } +public: + inline SwTxtMargin( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ) + { CtorInit( pFrm, pInf ); } + inline SwTwips GetLeftMargin() const; + inline SwTwips Left() const; + inline SwTwips Right() const { return nRight; } + inline SwTwips FirstLeft() const { return nFirst; } + inline SwTwips CurrWidth() const { return pCurr->PrtWidth(); } + SwTwips GetLineStart() const; + inline SwTwips GetLineEnd() const { return GetLineStart() + CurrWidth(); } + inline Point GetTopLeft() const { return Point( GetLineStart(), Y() ); } + inline sal_Bool IsOneBlock() const { return bOneBlock; } + inline sal_Bool IsLastBlock() const { return bLastBlock; } + inline sal_Bool IsLastCenter() const { return bLastCenter; } + inline MSHORT GetAdjust() const { return nAdjust; } +#ifndef BIDI + inline void SetAdjust( const MSHORT nNew ) { nAdjust = nNew; } +#endif + inline KSHORT GetLineWidth() const + { return KSHORT( Right() - GetLeftMargin() + 1 ); } + inline SwTwips GetLeftMin() const { return nFirst < nLeft ? nFirst : nLeft; } + inline sal_Bool HasNegFirst() const { return nFirst < nLeft; } + + // DropCaps + inline MSHORT GetDropLines() const { return nDropLines; } + inline void SetDropLines( const MSHORT nNew ) { nDropLines = nNew; } + inline KSHORT GetDropLeft() const { return nDropLeft; } + inline KSHORT GetDropHeight() const { return nDropHeight; } + inline void SetDropHeight( const KSHORT nNew ) { nDropHeight = nNew; } + inline KSHORT GetDropDescent() const { return nDropDescent; } + inline void SetDropDescent( const KSHORT nNew ) { nDropDescent = nNew; } + void DropInit(); + + // liefert TxtPos fuer Start und Ende der aktuellen Zeile ohne whitespaces + // In frminf.cxx implementiert. + + inline SwTxtSizeInfo &GetInfo() + { return (SwTxtSizeInfo&)SwTxtIter::GetInfo(); } + inline const SwTxtSizeInfo &GetInfo() const + { return (const SwTxtSizeInfo&)SwTxtIter::GetInfo(); } + +}; + + +/************************************************************************* + * class SwTxtAdjuster + *************************************************************************/ + +class SwTxtAdjuster : public SwTxtMargin +{ + // Gleicht die Portions aus, wenn Adjustment und FlyFrms vorliegen. + void CalcFlyAdjust( SwLineLayout *pCurr ); + + // ruft SplitGlues und CalcBlockAdjust + void FormatBlock( ); + + // Erstellt bei kurzen Zeilen die Glue-Kette. + SwMarginPortion* CalcRightMargin( SwLineLayout *pCurr, SwTwips nReal = 0 ); + + // Berechnung des Adjustments (FlyPortions) + SwFlyPortion *CalcFlyPortion( const long nRealWidth, + const SwRect &rCurrRect ); + +protected: + inline SwTxtAdjuster() { } + // spannt beim Blocksatz die Glues auf. + void CalcNewBlock( SwLineLayout *pCurr, const SwLinePortion *pStopAt, + SwTwips nReal = 0 ); +public: + inline SwTxtAdjuster( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ) + { SwTxtMargin::CtorInit( pFrm, pInf ); } + + // wird von SwTxtFormatter wegen UpdatePos ueberladen + void CalcAdjLine( SwLineLayout *pCurr ); + + // sorgt fuer das nachtraegliche adjustieren + inline void GetAdjusted() const + { + if( pCurr->IsFormatAdj() ) + ((SwTxtAdjuster*)this)->CalcAdjLine( pCurr ); + } + + // DropCaps-Extrawurst + void CalcDropRepaint(); +}; + +/************************************************************************* + * class SwTxtCursor + *************************************************************************/ + +class SwTxtCursor : public SwTxtAdjuster +{ + // A small helper-class to save SwTxtCursor member, manipulate them + // and to restore them + + // 1170: Mehrdeutigkeiten + static sal_Bool bRightMargin; + void _GetCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* ); +protected: + void CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ); + inline SwTxtCursor() { } +public: + inline SwTxtCursor( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ) + { CtorInit( pFrm, pInf ); } + sal_Bool GetCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0, + const long nMax = 0 ); + sal_Bool GetEndCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0,//STRIP001 sal_Bool GetEndCharRect(SwRect *, const xub_StrLen, SwCrsrMoveState* = 0, + const long nMax = 0 ){DBG_BF_ASSERT(0, "STRIP"); return FALSE;} ;//STRIP001 const long nMax = 0 ); + xub_StrLen GetCrsrOfst( SwPosition *pPos, const Point &rPoint, + const MSHORT nChgNode, const SwCrsrMoveState* = 0 ) const; + // 1170: beruecksichtigt Mehrdeutigkeiten; Implementierung s.u. + const SwLineLayout *CharCrsrToLine( const xub_StrLen nPos ); + + // calculates baseline for portion rPor + // bAutoToCentered indicates, if AUTOMATIC mode means CENTERED or BASELINE +#ifdef VERTICAL_LAYOUT + USHORT AdjustBaseLine( const SwLineLayout& rLine, const SwLinePortion* pPor, + USHORT nPorHeight = 0, USHORT nAscent = 0, + const sal_Bool bAutoToCentered = sal_False ) const; +#else + USHORT AdjustBaseLine( const SwLineLayout& rLine, + const USHORT nPorHeight, + const USHORT nPorAscent, + const sal_Bool bAutoToCentered = sal_False ) const; + + inline USHORT AdjustBaseLine( const SwLineLayout& rLine, + const SwLinePortion& rPor, + const sal_Bool bAutoToCentered = sal_False ) const + { return AdjustBaseLine( rLine, rPor.Height(), + rPor.GetAscent(), bAutoToCentered ); }; +#endif + + static inline void SetRightMargin( const sal_Bool bNew ){ bRightMargin = bNew; } + static inline sal_Bool IsRightMargin() { return bRightMargin; } +}; + +/************************************************************************* + * SwHookOut + * + * Change current output device to printer, this has to be done before + * formatting. + *************************************************************************/ + +class SwHookOut +{ + SwTxtSizeInfo* pInf; + OutputDevice* pOut; + sal_Bool bOnWin; +public: + SwHookOut( SwTxtSizeInfo& rInfo ); + ~SwHookOut(); +}; + +/************************************************************************* + * Inline-Implementierungen + *************************************************************************/ + +inline sal_Bool SwTxtIter::SeekAndChg( SwTxtSizeInfo &rInf ) +{ + return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() ); +} + +inline sal_Bool SwTxtIter::SeekAndChgBefore( SwTxtSizeInfo &rInf ) +{ + if ( rInf.GetIdx() ) + return SwAttrIter::SeekAndChg( rInf.GetIdx()-1, rInf.GetOut() ); + else + return SwAttrIter::SeekAndChg( rInf.GetIdx(), rInf.GetOut() ); +} + +inline sal_Bool SwTxtIter::SeekStartAndChg( SwTxtSizeInfo &rInf, const sal_Bool bPara ) +{ + return SwAttrIter::SeekStartAndChg( rInf.GetOut(), bPara ); +} + +inline SwTwips SwTxtMargin::GetLeftMargin() const +{ + return IsFirstTxtLine() ? nFirst : Left(); +} + +inline SwTwips SwTxtMargin::Left() const +{ + return (nDropLines >= nLineNr && 1 != nLineNr) ? nFirst + nDropLeft : nLeft; +} + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/makefile.mk b/binfilter/bf_sw/source/core/text/makefile.mk new file mode 100644 index 000000000000..f60682ce4bb6 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/makefile.mk @@ -0,0 +1,111 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +EXTERNAL_WARNINGS_NOT_ERRORS := TRUE + +PRJ=..$/..$/..$/.. +BFPRJ=..$/..$/.. + +PRJNAME=binfilter +TARGET=sw_text + +NO_HIDS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/inc$/bf_sw$/swpre.mk +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/inc$/bf_sw$/sw.mk +INC+= -I$(PRJ)$/inc$/bf_sw +.IF "$(GUI)"!="OS2" +INCEXT=s:\solar\inc\hm +.ENDIF + +.IF "$(mydebug)" != "" +CDEFS+=-Dmydebug +.ENDIF + +.IF "$(GUI)$(COM)" == "WINMSC" +LIBFLAGS=/NOI /NOE /PAGE:512 +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/sw_atrstck.obj \ + $(SLO)$/sw_frmcrsr.obj \ + $(SLO)$/sw_frmform.obj \ + $(SLO)$/sw_frmpaint.obj \ + $(SLO)$/sw_guess.obj \ + $(SLO)$/sw_inftxt.obj \ + $(SLO)$/sw_itradj.obj \ + $(SLO)$/sw_itratr.obj \ + $(SLO)$/sw_itrcrsr.obj \ + $(SLO)$/sw_itrform2.obj \ + $(SLO)$/sw_itrpaint.obj \ + $(SLO)$/sw_itrtxt.obj \ + $(SLO)$/sw_porexp.obj \ + $(SLO)$/sw_porfld.obj \ + $(SLO)$/sw_porfly.obj \ + $(SLO)$/sw_porglue.obj \ + $(SLO)$/sw_porlay.obj \ + $(SLO)$/sw_porlin.obj \ + $(SLO)$/sw_pormulti.obj \ + $(SLO)$/sw_porrst.obj \ + $(SLO)$/sw_portox.obj \ + $(SLO)$/sw_portxt.obj \ + $(SLO)$/sw_redlnitr.obj \ + $(SLO)$/sw_txtcache.obj \ + $(SLO)$/sw_txtdrop.obj \ + $(SLO)$/sw_txtfld.obj \ + $(SLO)$/sw_txtfly.obj \ + $(SLO)$/sw_txtfrm.obj \ + $(SLO)$/sw_txtftn.obj \ + $(SLO)$/sw_txthyph.obj \ + $(SLO)$/sw_txtinit.obj \ + $(SLO)$/sw_txttab.obj \ + $(SLO)$/sw_widorp.obj \ + $(SLO)$/sw_blink.obj \ + $(SLO)$/sw_noteurl.obj \ + $(SLO)$/sw_wrong.obj + +.IF "$(dbgutil)" != "" +SLOFILES += \ + $(SLO)$/sw_txtio.obj +.ENDIF + +.IF "$(CPUNAME)" == "SPARC" +.IF "$(OS)" == "NETBSD" +NOOPTFILES = \ + $(SLO)$/sw_txtftn.obj +.ENDIF +.ENDIF + +# --- Tagets ------------------------------------------------------- + +.INCLUDE : target.mk + diff --git a/binfilter/bf_sw/source/core/text/pordrop.hxx b/binfilter/bf_sw/source/core/text/pordrop.hxx new file mode 100644 index 000000000000..3d5c58e412e3 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/pordrop.hxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORDROP_HXX +#define _PORDROP_HXX + +#include "portxt.hxx" +namespace binfilter { + +class SwFont; + +/************************************************************************* + * class SwDropPortionPart + * + * A drop portion can consist of one or more parts in order to allow + * attribute changes inside them. + *************************************************************************/ + +class SwDropPortionPart +{ + SwDropPortionPart* pFollow; + SwFont* pFnt; + xub_StrLen nLen; + USHORT nWidth; + +public: + SwDropPortionPart( SwFont& rFont, const xub_StrLen nL ) + : pFollow( 0 ), pFnt( &rFont ), nLen( nL ), nWidth( 0 ) {}; + ~SwDropPortionPart(); + + inline SwDropPortionPart* GetFollow() const { return pFollow; }; + inline void SetFollow( SwDropPortionPart* pNew ) { pFollow = pNew; }; + inline SwFont& GetFont() const { return *pFnt; } + inline xub_StrLen GetLen() const { return nLen; } + inline USHORT GetWidth() const { return nWidth; } + inline void SetWidth( USHORT nNew ) { nWidth = nNew; } +}; + +/************************************************************************* + * class SwDropPortion + *************************************************************************/ + +class SwDropPortion : public SwTxtPortion +{ + SwDropPortionPart* pPart; // due to script / attribute changes + MSHORT nLines; // Anzahl der Zeilen + KSHORT nDropHeight; // Hoehe + KSHORT nDropDescent; // Abstand zur naechsten Zeile + KSHORT nDistance; // Abstand zum Text + KSHORT nFix; // Fixposition + short nX; // X-PaintOffset + short nY; // Y-Offset + + inline void Fix( const KSHORT nNew ) { nFix = nNew; } +public: + SwDropPortion( const MSHORT nLineCnt, + const KSHORT nDropHeight, + const KSHORT nDropDescent, + const KSHORT nDistance ); + virtual ~SwDropPortion(); + + + inline MSHORT GetLines() const { return nLines; } + inline KSHORT GetDistance() const { return nDistance; } + inline KSHORT GetDropHeight() const { return nDropHeight; } + inline KSHORT GetDropDescent() const { return nDropDescent; } + inline KSHORT GetDropLeft() const { return Width() + nFix; } + + inline SwDropPortionPart* GetPart() const { return pPart; } + inline void SetPart( SwDropPortionPart* pNew ) { pPart = pNew; } + + inline void SetY( short nNew ) { nY = nNew; } + + inline SwFont* GetFnt() { return pPart ? &pPart->GetFont() : NULL; } + + static void DeleteDropCapCache(); + + OUTPUT_OPERATOR +}; + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porexp.hxx b/binfilter/bf_sw/source/core/text/porexp.hxx new file mode 100644 index 000000000000..9db325ab3126 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porexp.hxx @@ -0,0 +1,98 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _POREXP_HXX +#define _POREXP_HXX + +#include "portxt.hxx" +namespace binfilter { + +/************************************************************************* + * class SwExpandPortion + *************************************************************************/ + +class SwExpandPortion : public SwTxtPortion +{ +public: + inline SwExpandPortion() { SetWhichPor( POR_EXP ); } + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const; + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + + +/************************************************************************* + * class SwBlankPortion + *************************************************************************/ + +class SwBlankPortion : public SwExpandPortion +{ + xub_Unicode cChar; + BOOL bMulti; // For multiportion brackets +public: + inline SwBlankPortion( xub_Unicode cCh, BOOL bMult = sal_False ) + : cChar( cCh ), bMulti( bMult ) + { cChar = cCh; SetLen(1); SetWhichPor( POR_BLANK ); } + + BOOL IsMulti() const { return bMulti; } + void SetMulti( BOOL bNew ) { bMulti = bNew; } + + virtual SwLinePortion *Compress(); + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + MSHORT MayUnderFlow( const SwTxtFormatInfo &rInf, xub_StrLen nIdx, + sal_Bool bUnderFlow ) const; + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwPostItsPortion + *************************************************************************/ + +class SwPostItsPortion : public SwExpandPortion +{ +public: + SwPostItsPortion( sal_Bool bScrpt ){DBG_BF_ASSERT(0, "STRIP");}; //STRIP001 //STRIP001 SwPostItsPortion( sal_Bool bScrpt ); + OUTPUT_OPERATOR +}; + + +CLASSIO( SwExpandPortion ) +CLASSIO( SwBlankPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porfld.hxx b/binfilter/bf_sw/source/core/text/porfld.hxx new file mode 100644 index 000000000000..b912a8fea194 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porfld.hxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORFLD_HXX +#define _PORFLD_HXX + +#include "swtypes.hxx" +#include "porexp.hxx" +#include <fmtornt.hxx> +namespace binfilter { + +class SwFont; +class SvxBrushItem; +class SwFmtVertOrient; +class SwFrm; + +/************************************************************************* + * class SwFldPortion + *************************************************************************/ + +class SwFldPortion : public SwExpandPortion +{ + friend class SwTxtFormatter; +protected: + XubString aExpand; // das expandierte Feld + SwFont *pFnt; // Fuer mehrzeilige Felder + xub_StrLen nNextOffset; // Offset des Follows im Originalstring + KSHORT nViewWidth; // Screenbreite fuer leere Felder + sal_Bool bFollow : 1; // 2. oder weiterer Teil eines Feldes + sal_Bool bLeft : 1; // wird von SwNumberPortion benutzt + sal_Bool bHide : 1; // wird von SwNumberPortion benutzt + sal_Bool bCenter : 1; // wird von SwNumberPortion benutzt + sal_Bool bHasFollow : 1; // geht in der naechsten Zeile weiter + sal_Bool bAnimated : 1; // wird von SwGrfNumPortion benutzt + sal_Bool bNoPaint : 1; // wird von SwGrfNumPortion benutzt + sal_Bool bReplace : 1; // wird von SwGrfNumPortion benutzt + + inline void SetFont( SwFont *pNew ) { pFnt = pNew; } + inline const SwFont *GetFont() const { return pFnt; } + BYTE ScriptChange( const SwTxtSizeInfo &rInf, xub_StrLen& rFull ); +public: + SwFldPortion( const SwFldPortion& rFld ); + SwFldPortion( const XubString &rExpand, SwFont *pFnt = 0 ); + ~SwFldPortion(); + + void TakeNextOffset( const SwFldPortion* pFld ); + void CheckScript( const SwTxtSizeInfo &rInf ); + inline sal_Bool HasFont() const { return 0 != pFnt; } + + inline const XubString &GetExp() const { return aExpand; } + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + + // leere Felder sind auch erlaubt + virtual SwLinePortion *Compress(); + + + inline sal_Bool IsFollow() const { return bFollow; } + inline void SetFollow( sal_Bool bNew ) { bFollow = bNew; } + + inline sal_Bool IsLeft() const { return bLeft; } + inline void SetLeft( sal_Bool bNew ) { bLeft = bNew; } + + inline sal_Bool IsHide() const { return bHide; } + inline void SetHide( sal_Bool bNew ) { bHide = bNew; } + + inline sal_Bool IsCenter() const { return bCenter; } + inline void SetCenter( sal_Bool bNew ) { bCenter = bNew; } + + inline sal_Bool HasFollow() const { return bHasFollow; } + inline void SetHasFollow( sal_Bool bNew ) { bHasFollow = bNew; } + + inline xub_StrLen GetNextOffset() const { return nNextOffset; } + inline void SetNextOffset( xub_StrLen nNew ) { nNextOffset = nNew; } + + // Felder-Cloner fuer SplitGlue + virtual SwFldPortion *Clone( const XubString &rExpand ) const; + + // Extra-GetTxtSize wegen pFnt + virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const; + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwHiddenPortion + *************************************************************************/ +// Unterscheidung nur fuer's Painten/verstecken. + +class SwHiddenPortion : public SwFldPortion +{ +public: + inline SwHiddenPortion( const XubString &rExpand, SwFont *pFnt = 0 ) + : SwFldPortion( rExpand, pFnt ) + { SetLen(1); SetWhichPor( POR_HIDDEN ); } + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + + // Felder-Cloner fuer SplitGlue + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwNumberPortion + *************************************************************************/ + +class SwNumberPortion : public SwFldPortion +{ +protected: + KSHORT nFixWidth; // vgl. Glues + KSHORT nMinDist; // minimaler Abstand zum Text +public: + SwNumberPortion( const XubString &rExpand, SwFont *pFnt, + const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst ); + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + + // Felder-Cloner fuer SplitGlue + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwBulletPortion + *************************************************************************/ + +class SwBulletPortion : public SwNumberPortion +{ +public: + SwBulletPortion( const xub_Unicode cCh, SwFont *pFnt, const sal_Bool bLeft, + const sal_Bool bCenter, const KSHORT nMinDst ); + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwBmpBulletPortion + *************************************************************************/ + +class SwGrfNumPortion : public SwNumberPortion +{ +public: +SwGrfNumPortion( SwFrm *pFrm, const SvxBrushItem* pGrfBrush,//STRIP001 SwGrfNumPortion( SwFrm *pFrm, const SvxBrushItem* pGrfBrush, +const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize,//STRIP001 const SwFmtVertOrient* pGrfOrient, const Size& rGrfSize, +const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst ):SwNumberPortion( aEmptyStr, NULL, bLeft, bCenter, nMinDst ){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 const sal_Bool bLeft, const sal_Bool bCenter, const KSHORT nMinDst ); +void SetBase( long nLnAscent, long nLnDescent,//STRIP001 void SetBase( long nLnAscent, long nLnDescent, +long nFlyAscent, long nFlyDescent ){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 long nFlyAscent, long nFlyDescent ); + OUTPUT_OPERATOR +}; + +CLASSIO( SwHiddenPortion ) +CLASSIO( SwNumberPortion ) +CLASSIO( SwBulletPortion ) +CLASSIO( SwGrfNumPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porfly.hxx b/binfilter/bf_sw/source/core/text/porfly.hxx new file mode 100644 index 000000000000..af4900d3da27 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porfly.hxx @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORFLY_HXX +#define _PORFLY_HXX + +#include "porglue.hxx" +namespace binfilter { + +class SwDrawContact; +class SwFrmFmt; +class SwFlyInCntFrm; +class SwTxtFrm; +struct SwCrsrMoveState; + +/************************************************************************* + * class SwFlyPortion + *************************************************************************/ + +class SwFlyPortion : public SwFixPortion +{ + KSHORT nBlankWidth; +public: + inline SwFlyPortion( const SwRect &rFlyRect ) + : SwFixPortion(rFlyRect), nBlankWidth( 0 ) { SetWhichPor( POR_FLY ); } + inline KSHORT GetBlankWidth( ) const { return nBlankWidth; } + inline void SetBlankWidth( const KSHORT nNew ) { nBlankWidth = nNew; } + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwFlyCntPortion + *************************************************************************/ + +#define SETBASE_NOFLAG 0 +#define SETBASE_QUICK 1 +#define SETBASE_ULSPACE 2 +#define SETBASE_INIT 4 +#define SETBASE_ROTATE 8 +#define SETBASE_REVERSE 16 +#ifdef BIDI +#define SETBASE_BIDI 32 +#endif + +class SwFlyCntPortion : public SwLinePortion +{ + void *pContact; // bDraw ? DrawContact : FlyInCntFrm + Point aRef; // Relativ zu diesem Point wird die AbsPos berechnet. + sal_Bool bDraw : 1; // DrawContact? + sal_Bool bMax : 1; // Zeilenausrichtung und Hoehe == Zeilenhoehe + sal_uInt8 nAlign : 3; // Zeilenausrichtung? Nein, oben, mitte, unten + +public: + SwFlyCntPortion( const SwTxtFrm& rFrm, SwFlyInCntFrm *pFly, + const Point &rBase, long nAscent, long nDescent, + long nFlyAsc, long nFlyDesc, sal_uInt8 nFlags ); + SwFlyCntPortion( const SwTxtFrm& rFrm, SwDrawContact *pDrawContact, + const Point &rBase, long nAscent, long nDescent, + long nFlyAsc, long nFlyDesc, sal_uInt8 nFlags ); + inline const Point& GetRefPoint() const { return aRef; } + inline SwFlyInCntFrm *GetFlyFrm() { return (SwFlyInCntFrm*)pContact; } + inline const SwFlyInCntFrm *GetFlyFrm() const + { return (SwFlyInCntFrm*)pContact; } + inline SwDrawContact *GetDrawContact() { return (SwDrawContact*)pContact; } + inline const SwDrawContact* GetDrawContact() const + { return (SwDrawContact*)pContact; } + inline sal_Bool IsDraw() const { return bDraw; } + inline sal_Bool IsMax() const { return bMax; } + inline sal_uInt8 GetAlign() const { return nAlign; } + inline void SetAlign( sal_uInt8 nNew ) { nAlign = nNew; } + inline void SetMax( sal_Bool bNew ) { bMax = bNew; } + void SetBase( const SwTxtFrm& rFrm, const Point &rBase, + long nLnAscent, long nLnDescent, long nFlyAscent, + long nFlyDescent, sal_uInt8 nFlags ); + const SwFrmFmt *GetFrmFmt() const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + OUTPUT_OPERATOR +}; + +CLASSIO( SwFlyPortion ) +CLASSIO( SwFlyCntPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porftn.hxx b/binfilter/bf_sw/source/core/text/porftn.hxx new file mode 100644 index 000000000000..c4867539567c --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porftn.hxx @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORFTN_HXX +#define _PORFTN_HXX + +#include "porfld.hxx" +namespace binfilter { + +class SwTxtFrm; +class SwTxtFtn; + +/************************************************************************* + * class SwFtnPortion + *************************************************************************/ + +class SwFtnPortion : public SwFldPortion +{ + SwTxtFrm *pFrm; // um im Dtor RemoveFtn rufen zu koennen. + SwTxtFtn *pFtn; + KSHORT nOrigHeight; +public: + SwFtnPortion( const XubString &rExpand, SwTxtFrm *pFrm, SwTxtFtn *pFtn, + KSHORT nOrig = KSHRT_MAX ); + inline KSHORT& Orig() { return nOrigHeight; } + + virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + + const SwTxtFtn* GetTxtFtn() const { return pFtn; }; + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwFtnNumPortion + *************************************************************************/ + +class SwFtnNumPortion : public SwNumberPortion +{ +public: + inline SwFtnNumPortion( const XubString &rExpand, SwFont *pFnt ) + : SwNumberPortion( rExpand, pFnt, sal_True, sal_False, 0 ) + { SetWhichPor( POR_FTNNUM ); } + sal_Bool DiffFont( SwFont* pFont ); + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwQuoVadisPortion + *************************************************************************/ + +class SwQuoVadisPortion : public SwFldPortion +{ +public: + SwQuoVadisPortion( const XubString &rExp, const XubString& rStr ): SwFldPortion( rExp ){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 SwQuoVadisPortion( const XubString &rExp, const XubString& rStr ); + + // Felder-Cloner fuer SplitGlue + + // Accessibility: pass information about this portion to the PortionHandler + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwErgoSumPortion + *************************************************************************/ + +class SwErgoSumPortion : public SwFldPortion +{ +public: +SwErgoSumPortion( const XubString &rExp, const XubString& rStr ):SwFldPortion( rExp ){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 SwErgoSumPortion( const XubString &rExp, const XubString& rStr ); + OUTPUT_OPERATOR +}; + +CLASSIO( SwFtnPortion ) +CLASSIO( SwFtnNumPortion ) +CLASSIO( SwQuoVadisPortion ) +CLASSIO( SwErgoSumPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porglue.hxx b/binfilter/bf_sw/source/core/text/porglue.hxx new file mode 100644 index 000000000000..735c74004496 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porglue.hxx @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORGLUE_HXX +#define _PORGLUE_HXX + +#include "porlin.hxx" + +namespace binfilter { + +class SwRect; +class SwLineLayout; +struct SwPosition; + +/************************************************************************* + * class SwGluePortion + *************************************************************************/ + +class SwGluePortion : public SwLinePortion +{ +private: + KSHORT nFixWidth; +public: + SwGluePortion( const KSHORT nInitFixWidth ); + + void Join( SwGluePortion *pVictim ); + + inline short GetPrtGlue() const; + inline KSHORT GetFixWidth() const { return nFixWidth; } + inline void SetFixWidth( const KSHORT nNew ) { nFixWidth = nNew; } + void MoveGlue( SwGluePortion *pTarget, const short nPrtGlue ); + inline void MoveAllGlue( SwGluePortion *pTarget ); + inline void MoveHalfGlue( SwGluePortion *pTarget ); + inline void AdjFixWidth(); + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");};//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwFixPortion + *************************************************************************/ + +class SwFixPortion : public SwGluePortion +{ + KSHORT nFix; // der Width-Offset in der Zeile +public: + SwFixPortion( const SwRect &rFlyRect ); + SwFixPortion( const KSHORT nFixWidth, const KSHORT nFixPos ); + inline void Fix( const KSHORT nNewFix ) { nFix = nNewFix; } + inline KSHORT Fix() const { return nFix; } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwMarginPortion + *************************************************************************/ + +class SwMarginPortion : public SwGluePortion +{ +public: + SwMarginPortion( const KSHORT nFixWidth ); + void AdjustRight( const SwLineLayout* pCurr ); + OUTPUT_OPERATOR +}; + +/************************************************************************* + * inline SwGluePortion::GetPrtGlue() + *************************************************************************/ + +inline short SwGluePortion::GetPrtGlue() const +{ return Width() - nFixWidth; } + +/************************************************************************* + * inline SwGluePortion::AdjFixWidth() + * Die FixWidth darf niemals groesser sein als die Gesamtbreite ! + *************************************************************************/ + +inline void SwGluePortion::AdjFixWidth() +{ + if( nFixWidth > PrtWidth() ) + nFixWidth = PrtWidth(); +} + +/************************************************************************* + * inline SwGluePortion::MoveGlue() + *************************************************************************/ + +inline void SwGluePortion::MoveAllGlue( SwGluePortion *pTarget ) +{ + MoveGlue( pTarget, GetPrtGlue() ); +} + +/************************************************************************* + * inline SwGluePortion::MoveHalfGlue() + *************************************************************************/ + +inline void SwGluePortion::MoveHalfGlue( SwGluePortion *pTarget ) +{ + MoveGlue( pTarget, GetPrtGlue() / 2 ); +} + +CLASSIO( SwGluePortion ) +CLASSIO( SwFixPortion ) +CLASSIO( SwMarginPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porhyph.hxx b/binfilter/bf_sw/source/core/text/porhyph.hxx new file mode 100644 index 000000000000..931f93fbfde0 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porhyph.hxx @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORHYPH_HXX +#define _PORHYPH_HXX + +#include "porexp.hxx" +namespace binfilter { + +/************************************************************************* + * class SwHyphPortion + *************************************************************************/ + +class SwHyphPortion : public SwExpandPortion +{ +public: + inline SwHyphPortion( ) { SetWhichPor( POR_HYPH ); } + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwHyphStrPortion + *************************************************************************/ + +class SwHyphStrPortion : public SwHyphPortion +{ + XubString aExpand; +public: + inline SwHyphStrPortion( const XubString &rStr ); + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwSoftHyphPortion + *************************************************************************/ + +class SwSoftHyphPortion : public SwHyphPortion +{ + sal_Bool bExpand; + KSHORT nViewWidth; + KSHORT nHyphWidth; + +public: + SwSoftHyphPortion(); + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + virtual SwLinePortion *Compress(); + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual void FormatEOL( SwTxtFormatInfo &rInf ); + inline void SetExpand( const sal_Bool bNew ) { bExpand = bNew; } + sal_Bool IsExpand() const { return bExpand; } + + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwSoftHyphStrPortion + *************************************************************************/ + +CLASSIO( SwHyphPortion ) +CLASSIO( SwHyphStrPortion ) +CLASSIO( SwSoftHyphPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porlay.hxx b/binfilter/bf_sw/source/core/text/porlay.hxx new file mode 100644 index 000000000000..67ef2e5b8d50 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porlay.hxx @@ -0,0 +1,373 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORLAY_HXX +#define _PORLAY_HXX + +#include <tools/string.hxx> +#include <tools/fract.hxx> +#include <drawfont.hxx> + +#include "swrect.hxx" // SwRepaint +#include "portxt.hxx" +#include "swfont.hxx" +class SvStream; +namespace binfilter { + +class SwMarginPortion; +class SwDropPortion; + +class SwTxtFormatter; + +/************************************************************************* + * class SwCharRange + *************************************************************************/ + +class SwCharRange +{ + xub_StrLen nStart, nLen; +public: + inline SwCharRange( const xub_StrLen nInitStart = 0, + const xub_StrLen nInitLen = 0): nStart( nInitStart ), nLen(nInitLen) {} + inline xub_StrLen &Start() { return nStart; } + inline const xub_StrLen &Start() const { return nStart; } + inline void LeftMove( xub_StrLen nNew ) + { if ( nNew < nStart ) { nLen += nStart-nNew; nStart = nNew; } } + inline xub_StrLen End() const + { return nStart + nLen; } + inline xub_StrLen &Len() { return nLen; } + inline const xub_StrLen &Len() const { return nLen; } + inline sal_Bool operator<(const SwCharRange &rRange) const + { return nStart < rRange.nStart; } + inline sal_Bool operator>(const SwCharRange &rRange) const + { return nStart + nLen > rRange.nStart + rRange.nLen; } + inline sal_Bool operator!=(const SwCharRange &rRange) const + { return *this < rRange || *this > rRange; } + SwCharRange &operator+=(const SwCharRange &rRange); +}; + +/************************************************************************* + * class SwRepaint + *************************************************************************/ + +// SwRepaint ist ein dokumentglobales SwRect mit einem nOfst der angibt, +// ab wo in der ersten Zeile gepaintet werden soll +// und einem nRightOfst, der den rechten Rand bestimmt +class SwRepaint : public SwRect +{ + SwTwips nOfst; + SwTwips nRightOfst; +public: + SwRepaint() : SwRect(), nOfst( 0 ), nRightOfst( 0 ) {} + SwRepaint( const SwRepaint& rRep ) : SwRect( rRep ), nOfst( rRep.nOfst ), + nRightOfst( rRep.nRightOfst ) {} + + SwTwips GetOfst() const { return nOfst; } + void SetOfst( const SwTwips nNew ) { nOfst = nNew; } + SwTwips GetRightOfst() const { return nRightOfst; } + void SetRightOfst( const SwTwips nNew ) { nRightOfst = nNew; } +}; + +/************************************************************************* + * class SwLineLayout + *************************************************************************/ + +class SwLineLayout : public SwTxtPortion +{ +private: + SwLineLayout *pNext;// Die naechste Zeile. + SvShorts* pSpaceAdd;// Fuer den Blocksatz + SvUShorts* pKanaComp; + KSHORT nRealHeight; // Die aus Zeilenabstand/Register resultierende Hoehe + sal_Bool bFormatAdj : 1; + sal_Bool bDummy : 1; + sal_Bool bFntChg : 1; + sal_Bool bEndHyph : 1; + sal_Bool bMidHyph : 1; + sal_Bool bTab : 1; + sal_Bool bFly : 1; + sal_Bool bRest : 1; + sal_Bool bBlinking : 1; + sal_Bool bClipping : 1; // Clipping erforderlich wg. exakter Zeilenhoehe + sal_Bool bContent : 1; // enthaelt Text, fuer Zeilennumerierung + sal_Bool bRedline : 1; // enthaelt Redlining + sal_Bool bForcedLeftMargin : 1; // vom Fly verschobener linker Einzug + sal_Bool bHanging : 1; // contents a hanging portion in the margin + sal_Bool bUnderscore : 1; + + SwTwips _GetHangingMargin() const; + +public: + // von SwLinePortion + virtual SwLinePortion *Insert( SwLinePortion *pPortion ); + inline SwLinePortion *GetFirstPortion() const; + + // Flags + inline void ResetFlags(); + inline void SetFormatAdj( const sal_Bool bNew ) { bFormatAdj = bNew; } + inline sal_Bool IsFormatAdj() const { return bFormatAdj; } + inline void SetFntChg( const sal_Bool bNew ) { bFntChg = bNew; } + inline sal_Bool IsFntChg() const { return bFntChg; } + inline void SetEndHyph( const sal_Bool bNew ) { bEndHyph = bNew; } + inline sal_Bool IsEndHyph() const { return bEndHyph; } + inline void SetMidHyph( const sal_Bool bNew ) { bMidHyph = bNew; } + inline sal_Bool IsMidHyph() const { return bMidHyph; } + inline void SetTab( const sal_Bool bNew ) { bTab = bNew; } + inline sal_Bool IsTab() const { return bTab; } + inline void SetFly( const sal_Bool bNew ) { bFly = bNew; } + inline sal_Bool IsFly() const { return bFly; } + inline void SetRest( const sal_Bool bNew ) { bRest = bNew; } + inline sal_Bool IsRest() const { return bRest; } + inline void SetBlinking( const sal_Bool bNew = sal_True ) { bBlinking = bNew; } + inline sal_Bool IsBlinking() const { return bBlinking; } + inline void SetCntnt( const sal_Bool bNew = sal_True ) { bContent = bNew; } + inline sal_Bool HasCntnt() const { return bContent; } + inline void SetRedline( const sal_Bool bNew = sal_True ) { bRedline = bNew; } + inline sal_Bool HasRedline() const { return bRedline; } + inline void SetForcedLeftMargin( const sal_Bool bNew = sal_True ) { bForcedLeftMargin = bNew; } + inline sal_Bool HasForcedLeftMargin() const { return bForcedLeftMargin; } + inline void SetHanging( const sal_Bool bNew = sal_True ) { bHanging = bNew; } + inline sal_Bool IsHanging() const { return bHanging; } + inline void SetUnderscore( const sal_Bool bNew = sal_True ) { bUnderscore = bNew; } + inline sal_Bool HasUnderscore() const { return bUnderscore; } + + // Beruecksichtigung von Dummyleerzeilen + // 4147, 8221: + inline void SetDummy( const sal_Bool bNew ) { bDummy = bNew; } + inline sal_Bool IsDummy() const { return bDummy; } + + inline void SetClipping( const sal_Bool bNew ) { bClipping = bNew; } + inline sal_Bool IsClipping() const { return bClipping; } + + inline SwLineLayout(); + virtual ~SwLineLayout(); + + inline SwLineLayout *GetNext() { return pNext; } + inline const SwLineLayout *GetNext() const { return pNext; } + inline void SetNext( SwLineLayout *pNew ) { pNext = pNew; } + + void Init( SwLinePortion *pNextPortion = NULL); + + // Sammelt die Daten fuer die Zeile. + void CalcLine( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf ); + + inline void SetRealHeight( KSHORT nNew ) { nRealHeight = nNew; } + inline KSHORT GetRealHeight() const { return nRealHeight; } + + // Erstellt bei kurzen Zeilen die Glue-Kette. + SwMarginPortion *CalcLeftMargin(); + + inline SwTwips GetHangingMargin() const + { return _GetHangingMargin(); } + + // fuer die Sonderbehandlung bei leeren Zeilen + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + + inline sal_Bool IsNoSpaceAdd() { return pSpaceAdd == NULL; } + inline void InitSpaceAdd() + { if ( !pSpaceAdd ) CreateSpaceAdd(); else (*pSpaceAdd)[0] = 0; } + inline void SetKanaComp( SvUShorts* pNew ){ pKanaComp = pNew; } + inline void FinishSpaceAdd() { delete pSpaceAdd; pSpaceAdd = NULL; } + inline void FinishKanaComp() { delete pKanaComp; pKanaComp = NULL; } + inline SvShorts* GetpSpaceAdd() const { return pSpaceAdd; } + inline SvShorts& GetSpaceAdd() { return *pSpaceAdd; } + inline SvUShorts* GetpKanaComp() const { return pKanaComp; } + inline SvUShorts& GetKanaComp() { return *pKanaComp; } + + void CreateSpaceAdd( const short nInit = 0 ); + +#ifdef DBG_UTIL + void DebugPortions( SvStream &rOs, const XubString &rTxt, + const xub_StrLen nStart ); //$ ostream +#endif + + OUTPUT_OPERATOR + DECL_FIXEDMEMPOOL_NEWDEL(SwLineLayout) +}; + +class SwParaPortion : public SwLineLayout +{ + // neu zu paintender Bereich + SwRepaint aRepaint; + // neu zu formatierender Bereich + SwCharRange aReformat; + SwScriptInfo aScriptInfo; +// Fraction aZoom; + long nDelta; + + // Wenn ein SwTxtFrm gelocked ist, werden keine Veraenderungen an den + // Formatierungsdaten (unter pLine) vorgenommen (vgl. ORPHANS) + sal_Bool bFlys : 1; // Ueberlappen Flys ? + sal_Bool bPrep : 1; // PREP_* + sal_Bool bPrepWidows : 1; // PREP_WIDOWS + sal_Bool bPrepAdjust : 1; // PREP_ADJUST_FRM + sal_Bool bPrepMustFit : 1; // PREP_MUST_FIT + sal_Bool bFollowField : 1; // Es steht noch ein Feldrest fuer den Follow an. + + sal_Bool bFixLineHeight : 1; // Feste Zeilenhoehe + sal_Bool bFtnNum : 1; // contents a footnotenumberportion + sal_Bool bMargin : 1; // contents a hanging punctuation in the margin + + sal_Bool bFlag00 : 1; // + sal_Bool bFlag11 : 1; // + sal_Bool bFlag12 : 1; // + sal_Bool bFlag13 : 1; // + sal_Bool bFlag14 : 1; // + sal_Bool bFlag15 : 1; // + sal_Bool bFlag16 : 1; // + +public: + SwParaPortion(); + + // setzt alle Formatinformationen zurueck (ausser bFlys wg. 9916) + inline void FormatReset(); + + // Setzt die Flags zurueck + inline void ResetPreps(); + + // Get/Set-Methoden + inline SwRepaint *GetRepaint() { return &aRepaint; } + inline const SwRepaint *GetRepaint() const { return &aRepaint; } + inline SwCharRange *GetReformat() { return &aReformat; } + inline const SwCharRange *GetReformat() const { return &aReformat; } + inline long *GetDelta() { return &nDelta; } + inline const long *GetDelta() const { return &nDelta; } + inline SwScriptInfo& GetScriptInfo() { return aScriptInfo; } + inline const SwScriptInfo& GetScriptInfo() const { return aScriptInfo; } + + // fuer SwTxtFrm::Format: liefert die aktuelle Laenge des Absatzes + xub_StrLen GetParLen() const; + + // fuer Prepare() + sal_Bool UpdateQuoVadis( const XubString &rQuo ); + + // Flags + inline void SetFly( const sal_Bool bNew = sal_True ) { bFlys = bNew; } + inline sal_Bool HasFly() const { return bFlys; } + + // Preps + inline void SetPrep( const sal_Bool bNew = sal_True ) { bPrep = bNew; } + inline sal_Bool IsPrep() const { return bPrep; } + inline void SetPrepWidows( const sal_Bool bNew = sal_True ) { bPrepWidows = bNew; } + inline sal_Bool IsPrepWidows() const { return bPrepWidows; } + inline void SetPrepMustFit( const sal_Bool bNew = sal_True ) { bPrepMustFit = bNew; } + inline sal_Bool IsPrepMustFit() const { return bPrepMustFit; } + inline void SetPrepAdjust( const sal_Bool bNew = sal_True ) { bPrepAdjust = bNew; } + inline sal_Bool IsPrepAdjust() const { return bPrepAdjust; } + inline void SetFollowField( const sal_Bool bNew = sal_True ) { bFollowField = bNew; } + inline sal_Bool IsFollowField() const { return bFollowField; } + inline void SetFixLineHeight( const sal_Bool bNew = sal_True ) { bFixLineHeight = bNew; } + inline sal_Bool IsFixLineHeight() const { return bFixLineHeight; } + + inline void SetFtnNum( const sal_Bool bNew = sal_True ) { bFtnNum = bNew; } + inline sal_Bool IsFtnNum() const { return bFtnNum; } + inline void SetMargin( const sal_Bool bNew = sal_True ) { bMargin = bNew; } + inline sal_Bool IsMargin() const { return bMargin; } + inline void SetFlag00( const sal_Bool bNew = sal_True ) { bFlag00 = bNew; } + inline sal_Bool IsFlag00() const { return bFlag00; } + inline void SetFlag11( const sal_Bool bNew = sal_True ) { bFlag11 = bNew; } + inline sal_Bool IsFlag11() const { return bFlag11; } + inline void SetFlag12( const sal_Bool bNew = sal_True ) { bFlag12 = bNew; } + inline sal_Bool IsFlag12() const { return bFlag12; } + inline void SetFlag13( const sal_Bool bNew = sal_True ) { bFlag13 = bNew; } + inline sal_Bool IsFlag13() const { return bFlag13; } + inline void SetFlag14( const sal_Bool bNew = sal_True ) { bFlag14 = bNew; } + inline sal_Bool IsFlag14() const { return bFlag14; } + inline void SetFlag15( const sal_Bool bNew = sal_True ) { bFlag15 = bNew; } + inline sal_Bool IsFlag15() const { return bFlag15; } + inline void SetFlag16( const sal_Bool bNew = sal_True ) { bFlag16 = bNew; } + inline sal_Bool IsFlag16() const { return bFlag16; } + + // schneller, hoeher, weiter: Read/Write-Methoden fuer den SWG-Filter + SvStream &ReadSwg ( SvStream& rStream ); //$ istream + SvStream &WriteSwg( SvStream& rStream ); //$ ostream + + // nErgo in der QuoVadisPortion setzen + + const SwDropPortion *FindDropPortion() const; + + OUTPUT_OPERATOR + DECL_FIXEDMEMPOOL_NEWDEL(SwParaPortion) +}; + +/************************************************************************* + * Inline-Implementierungen + *************************************************************************/ + +inline void SwLineLayout::ResetFlags() +{ + bFormatAdj = bDummy = bFntChg = bTab = bEndHyph = bMidHyph = bFly + = bRest = bBlinking = bClipping = bContent = bRedline + = bForcedLeftMargin = bHanging = sal_False; +} + +inline SwLineLayout::SwLineLayout() + : pNext( 0 ), nRealHeight( 0 ), pSpaceAdd( 0 ), pKanaComp( 0 ), + bUnderscore( sal_False ) +{ + ResetFlags(); + SetWhichPor( POR_LAY ); +} + +inline void SwParaPortion::ResetPreps() +{ + bPrep = bPrepWidows = bPrepAdjust = bPrepMustFit = sal_False; +} + +inline void SwParaPortion::FormatReset() +{ + nDelta = 0; + aReformat = SwCharRange( 0, STRING_LEN ); +// AMA 9916: bFlys muss in SwTxtFrm::_Format() erhalten bleiben, damit +// leere Absaetze, die Rahmen ohne Umfluss ausweichen mussten, sich +// neu formatieren, wenn der Rahmen aus dem Bereich verschwindet. +// bFlys = sal_False; + ResetPreps(); + bFollowField = bFixLineHeight = bMargin = sal_False; +} + +#ifdef UNX +// C30 ist mit dem ternaeren Ausdruck ueberfordert. +inline SwLinePortion *SwLineLayout::GetFirstPortion() const +{ + register SwLinePortion *pTmp = pPortion; + if ( !pPortion ) + pTmp = (SwLinePortion*)this; + return( pTmp ); +} +#else +inline SwLinePortion *SwLineLayout::GetFirstPortion() const +{ return( pPortion ? pPortion : (SwLinePortion*)this ); } +#endif + +CLASSIO( SwLineLayout ) +CLASSIO( SwParaPortion ) + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porlin.hxx b/binfilter/bf_sw/source/core/text/porlin.hxx new file mode 100644 index 000000000000..b448b4c62f1c --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porlin.hxx @@ -0,0 +1,248 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORLIN_HXX +#define _PORLIN_HXX + +#include "possiz.hxx" // SwPosSize +class XubString; +namespace binfilter { + + +class SwTxtSizeInfo; +class SwTxtPaintInfo; +class SwTxtFormatInfo; +class SwPortionHandler; + +// Die Ausgabeoperatoren der Portions sind virtuelle Methoden der Portion. +// Das CLASSIO-Makro implementiert die 'freischwebende' Funktion. +// Auf diese Weise erhaelt man beide Vorteile: virtuelle Ausgabeoperatoren +// und allgemeine Verwendbarkeit. +#ifdef DBG_UTIL +#define OUTPUT_OPERATOR virtual SvStream &operator<<( SvStream & aOs ) const; +#else +#define OUTPUT_OPERATOR +#endif + +// Portiongruppen +#define PORGRP_TXT 0x8000 +#define PORGRP_EXP 0x4000 +#define PORGRP_FLD 0x2000 +#define PORGRP_HYPH 0x1000 +#define PORGRP_NUMBER 0x0800 +#define PORGRP_GLUE 0x0400 +#define PORGRP_FIX 0x0200 +#define PORGRP_TAB 0x0100 +#define PORGRP_NOTRECY 0x0080 +// kleine Spezialgruppen +#define PORGRP_FIXMARG 0x0040 +//#define PORGRP_? 0x0020 +#define PORGRP_TABNOTLFT 0x0010 +#define PORGRP_TOXREF 0x0008 + +/************************************************************************* + * class SwLinePortion + *************************************************************************/ + +class SwLinePortion: public SwPosSize +{ +protected: + // Hier gibt es Bereiche mit unterschiedlichen Attributen. + SwLinePortion *pPortion; + // Anzahl der Zeichen und Spaces auf der Zeile + xub_StrLen nLineLength; + KSHORT nAscent; // Maximaler Ascender + + SwLinePortion(); +private: + MSHORT nWhichPor; // Who's who? + + void _Truncate(); + +public: + inline SwLinePortion(const SwLinePortion &rPortion); + virtual ~SwLinePortion(); + + // Zugriffsmethoden + inline SwLinePortion *GetPortion() const { return( pPortion ); } + inline SwLinePortion &operator=(const SwLinePortion &rPortion); + inline sal_Bool operator==( const SwLinePortion &rPortion ) const; + inline xub_StrLen GetLen() const { return nLineLength; } + inline void SetLen( const xub_StrLen nLen ) { nLineLength = nLen; } + inline void SetPortion( SwLinePortion *pNew ){ pPortion = pNew; } + inline KSHORT &GetAscent() { return nAscent; } + inline KSHORT GetAscent() const { return nAscent; } + inline void SetAscent( const KSHORT nNewAsc ) { nAscent = nNewAsc; } + inline void PrtWidth( KSHORT nNewWidth ) { Width( nNewWidth ); } + inline KSHORT PrtWidth() const { return Width(); } + inline void AddPrtWidth( const KSHORT nNew ) { Width( Width() + nNew ); } + inline void SubPrtWidth( const KSHORT nNew ) { Width( Width() - nNew ); } + + inline const SwPosSize &PrtSize() const { return *this; } + + // Einfuegeoperationen: + virtual SwLinePortion *Insert( SwLinePortion *pPortion ); + virtual SwLinePortion *Append( SwLinePortion *pPortion ); + SwLinePortion *Cut( SwLinePortion *pVictim ); + inline void Truncate(); + + // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind. + virtual SwLinePortion *Compress(); + + inline void SetWhichPor( const MSHORT nNew ) { nWhichPor = nNew; } + inline MSHORT GetWhichPor( ) const { return nWhichPor; } + +// Gruppenabfragen: + inline sal_Bool InTxtGrp( ) const { return nWhichPor & PORGRP_TXT ? sal_True : sal_False; } + inline sal_Bool InGlueGrp( ) const { return nWhichPor & PORGRP_GLUE ? sal_True : sal_False;} + inline sal_Bool InTabGrp( ) const { return nWhichPor & PORGRP_TAB ? sal_True : sal_False; } + inline sal_Bool InHyphGrp( ) const { return nWhichPor & PORGRP_HYPH ? sal_True : sal_False;} + inline sal_Bool InNumberGrp( )const { return nWhichPor & PORGRP_NUMBER ? sal_True : sal_False;} + inline sal_Bool InFixGrp( ) const { return nWhichPor & PORGRP_FIX ? sal_True : sal_False; } + inline sal_Bool InFldGrp( ) const { return nWhichPor & PORGRP_FLD ? sal_True : sal_False; } + inline sal_Bool InToxRefGrp( ) const { return nWhichPor & PORGRP_TOXREF ? sal_True : sal_False; } + inline sal_Bool InToxRefOrFldGrp( ) const { return nWhichPor & + ( PORGRP_FLD | PORGRP_TOXREF ) ? sal_True : sal_False; } + inline sal_Bool InExpGrp( ) const { return nWhichPor & PORGRP_EXP ? sal_True : sal_False; } + inline sal_Bool InTabnLftGrp( ) const + { return nWhichPor & PORGRP_TABNOTLFT ? sal_True : sal_False; } + inline sal_Bool InFixMargGrp( )const + { return nWhichPor & PORGRP_FIXMARG ? sal_True : sal_False; } + inline sal_Bool InSpaceGrp( )const + { return InTxtGrp() || IsMultiPortion(); } +// Individuelle Abfragen: + inline sal_Bool IsGrfNumPortion( )const{ return nWhichPor == POR_GRFNUM; } + inline sal_Bool IsFlyCntPortion( )const{ return nWhichPor == POR_FLYCNT; } + inline sal_Bool IsBlankPortion( ) const{ return nWhichPor == POR_BLANK; } + inline sal_Bool IsBreakPortion( ) const{ return nWhichPor == POR_BRK; } + inline sal_Bool IsErgoSumPortion()const{ return nWhichPor == POR_ERGOSUM;} + inline sal_Bool IsQuoVadisPortion()const{ return nWhichPor==POR_QUOVADIS;} + inline sal_Bool IsTabCntPortion( )const{ return nWhichPor==POR_TABCENTER;} + inline sal_Bool IsTabLeftPortion()const{ return nWhichPor == POR_TABLEFT;} + inline sal_Bool IsFtnNumPortion( )const{ return nWhichPor == POR_FTNNUM; } + inline sal_Bool IsFtnPortion( ) const{ return nWhichPor == POR_FTN; } + inline sal_Bool IsTmpEndPortion( )const{ return nWhichPor == POR_TMPEND; } + inline sal_Bool IsDropPortion( ) const{ return nWhichPor == POR_DROP; } + inline sal_Bool IsLayPortion( ) const{ return nWhichPor == POR_LAY; } + inline sal_Bool IsParaPortion( ) const{ return nWhichPor == POR_PARA; } + inline sal_Bool IsMarginPortion( )const{ return nWhichPor == POR_MARGIN; } + inline sal_Bool IsFlyPortion( ) const{ return nWhichPor == POR_FLY; } + inline sal_Bool IsHolePortion( ) const{ return nWhichPor == POR_HOLE; } + inline sal_Bool IsSoftHyphPortion()const{ return nWhichPor==POR_SOFTHYPH;} + inline sal_Bool IsPostItsPortion()const{ return nWhichPor == POR_POSTITS;} + inline sal_Bool IsCombinedPortion()const{ return nWhichPor==POR_COMBINED;} + inline sal_Bool IsTextPortion( ) const{ return nWhichPor == POR_TXT; } + inline sal_Bool IsURLPortion( ) const{ return nWhichPor == POR_URL; } + inline sal_Bool IsHangingPortion( ) const{ return nWhichPor == POR_HNG; } + inline sal_Bool IsKernPortion( ) const{ return nWhichPor == POR_KERN; } + inline sal_Bool IsArrowPortion( ) const{ return nWhichPor == POR_ARROW; } + inline sal_Bool IsMultiPortion( ) const{ return nWhichPor == POR_MULTI; } + + // Positionierung + SwLinePortion *FindPrevPortion( const SwLinePortion *pRoot ); + SwLinePortion *FindLastPortion(); + + virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const; + void CalcTxtSize( const SwTxtSizeInfo &rInfo ); + + // Ausgabe + virtual void Paint( const SwTxtPaintInfo &rInf ) const = 0; + +#ifdef DBG_UTIL +#endif + + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + // wird fuer die letzte Portion der Zeile extra gerufen + virtual void FormatEOL( SwTxtFormatInfo &rInf ); + void Move( SwTxtPaintInfo &rInf ); + + // Fuer SwTxtSlot + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + + // fuer SwFldPortion, SwSoftHyphPortion + + // for text- and multi-portions + virtual long CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const; + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + + +/************************************************************************* + * inline - Implementations + *************************************************************************/ + +inline SwLinePortion &SwLinePortion::operator=(const SwLinePortion &rPortion) +{ + *(SwPosSize*)this = rPortion; + nLineLength = rPortion.nLineLength; + nAscent = rPortion.nAscent; + nWhichPor = rPortion.nWhichPor; + return *this; +} + +inline sal_Bool SwLinePortion::operator==(const SwLinePortion &rPortion ) const +{ + return( *(SwPosSize*)this == rPortion && + nLineLength == rPortion.GetLen() && + nAscent == rPortion.GetAscent() ); +} + +inline SwLinePortion::SwLinePortion(const SwLinePortion &rPortion) : + SwPosSize( rPortion ), + pPortion( 0 ), + nLineLength( rPortion.nLineLength ), + nAscent( rPortion.nAscent ), + nWhichPor( rPortion.nWhichPor ) +{ +} + +inline void SwLinePortion::Truncate() +{ + if ( pPortion ) + _Truncate(); +} + + +//$ ostream +#ifdef DBGTXT +#define CLASSIO( class ) \ + inline SvStream &operator<<( SvStream &rOs, const class &rClass ) {\ + return rClass.operator<<( rOs );\ + } +#else +#define CLASSIO( class ) +#endif + +CLASSIO( SwLinePortion ) + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/pormulti.hxx b/binfilter/bf_sw/source/core/text/pormulti.hxx new file mode 100644 index 000000000000..0454ca30b940 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/pormulti.hxx @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PORMULTI_HXX +#define _PORMULTI_HXX + +#include "porlay.hxx" +#include "porexp.hxx" +namespace binfilter { + +class SfxPoolItem; +class SwTxtFormatInfo; +class SwFldPortion; +class SwTxtCursor; +class SwLineLayout; +class SwBlankPortion; +class SwTxtPaintInfo; +class SwTxtAttr; + +class SwFont; + +/*-----------------02.02.01 15:01------------------- + * SwMultiCreator is a small structur to create a multiportion. + * It contains the kind of multiportion and a textattribute + * or a poolitem. + * The GetMultiCreator-function fills this structur and + * the Ctor of the SwMultiPortion uses it. + * --------------------------------------------------*/ + +#define SW_MC_DOUBLE 0 +#define SW_MC_RUBY 1 +#define SW_MC_ROTATE 2 +#ifdef BIDI +#define SW_MC_BIDI 3 +#endif + +struct SwMultiCreator +{ + const SwTxtAttr* pAttr; + const SfxPoolItem* pItem; + BYTE nId; +#ifdef BIDI + BYTE nLevel; +#endif +}; + +/*-----------------25.10.00 16:19------------------- + * A two-line-portion (SwMultiPortion) could have surrounding brackets, + * in this case the structur SwBracket will be used. + * --------------------------------------------------*/ + +struct SwBracket +{ + xub_StrLen nStart; // Start of text attribute determins the font + KSHORT nAscent; // Ascent of the brackets + KSHORT nHeight; // Height of them + KSHORT nPreWidth; // Width of the opening bracket + KSHORT nPostWidth; // Width of the closing bracket + sal_Unicode cPre; // Initial character, e.g. '(' + sal_Unicode cPost; // Final character, e.g. ')' + BYTE nPreScript; // Script of the initial character + BYTE nPostScript; // Script of the final character +}; + +/*-----------------16.10.00 12:45------------------- + * 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; // Field rest from the previous line + sal_Bool bTab1 :1; // First line tabulator + sal_Bool bTab2 :1; // Second line includes tabulator + sal_Bool bDouble :1; // Double line + sal_Bool bRuby :1; // Phonetics + #ifdef BIDI + sal_Bool bBidi :1; + #endif + sal_Bool bTop :1; // Phonetic position + sal_Bool bFormatted :1; // Already formatted + sal_Bool bFollowFld :1; // Field follow inside + sal_uInt8 nDirection:2; // Direction (0/90/180/270 degrees) + sal_Bool bFlyInCntnt:1; // Fly as character inside +protected: +SwMultiPortion( xub_StrLen nEnd ) : pFldRest( 0 ), bTab1( sal_False ), + #ifdef BIDI + bTab2( sal_False ), bDouble( sal_False ), bRuby( sal_False ), + bBidi( sal_False ), bFormatted( sal_False ), bFollowFld( sal_False ), + nDirection( 0 ), bFlyInCntnt( sal_False ) + #else + bTab2( sal_False ), bDouble( sal_False ), bRuby( sal_False ), + bFormatted( sal_False ), bFollowFld( sal_False ), nDirection( 0 ), + bFlyInCntnt( sal_False ) + #endif + { SetWhichPor( POR_MULTI ); SetLen( nEnd ); } +public: + const SwLineLayout& GetRoot() const { return aRoot; } + SwLineLayout& GetRoot() { return aRoot; } + inline sal_Bool HasTabulator() const{DBG_BF_ASSERT(0, "STRIP"); return FALSE;} //STRIP001 inline sal_Bool HasTabulator() const { return bTab1 || bTab2; } + inline sal_Bool IsFollowFld() const { return bFollowFld; } + inline sal_Bool HasFlyInCntnt() const { return bFlyInCntnt; } + inline sal_Bool IsDouble() const{DBG_BF_ASSERT(0, "STRIP"); return FALSE;} //STRIP001 inline sal_Bool IsDouble() const { return bDouble; } +#ifdef BIDI + inline sal_Bool IsBidi() const { return bBidi; } +#endif + inline sal_Bool HasRotation() const { return 0 != (1 & nDirection); } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * inline - Implementations + *************************************************************************/ + +#ifndef BIDI +inline sal_Bool SwMultiPortion::ChgSpaceAdd(SwLineLayout* pCurr,short nSpaceAdd) + { return IsDouble() ? ((SwDoubleLinePortion*)this)->ChangeSpaceAdd( pCurr, + nSpaceAdd ) : sal_False; } +#endif + + +CLASSIO( SwMultiPortion ) + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porref.hxx b/binfilter/bf_sw/source/core/text/porref.hxx new file mode 100644 index 000000000000..651af117cab3 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porref.hxx @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORREF_HXX +#define _PORREF_HXX + +#include "portxt.hxx" +namespace binfilter { + +/************************************************************************* + * class SwRefPortion + *************************************************************************/ + +class SwRefPortion : public SwTxtPortion +{ +public: + inline SwRefPortion(){ SetWhichPor( POR_REF ); } +//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwIsoRefPortion + *************************************************************************/ + +class SwIsoRefPortion : public SwRefPortion +{ +//STRIP001 KSHORT nViewWidth; +//STRIP001 +public: + SwIsoRefPortion(){DBG_BF_ASSERT(0, "STRIP");}; //STRIP001 //STRIP001 SwIsoRefPortion(); +//STRIP001 virtual sal_Bool Format( SwTxtFormatInfo &rInf ); +//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; +//STRIP001 virtual SwLinePortion *Compress(); +//STRIP001 virtual KSHORT GetViewWidth( const SwTxtSizeInfo &rInf ) const; + + // Accessibility: pass information about this portion to the PortionHandler +//STRIP001 virtual void HandlePortion( SwPortionHandler& rPH ) const; + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * inline - Implementations + *************************************************************************/ + +CLASSIO( SwRefPortion ) +//STRIP001 CLASSIO( SwIsoRefPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/porrst.hxx b/binfilter/bf_sw/source/core/text/porrst.hxx new file mode 100644 index 000000000000..b4a0290d5a19 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/porrst.hxx @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORRST_HXX +#define _PORRST_HXX + +#include <bf_svtools/svarray.hxx> + +#include "porlay.hxx" +#include "porexp.hxx" +namespace binfilter { + +#ifdef VERTICAL_LAYOUT +#define LINE_BREAK_WIDTH 150 +#define SPECIAL_FONT_HEIGHT 200 +#endif + +class SwTxtFormatInfo; + +/************************************************************************* + * class SwBreakPortion + *************************************************************************/ + +class SwBreakPortion : public SwLinePortion +{ +#ifdef VERTICAL_LAYOUT +#else + void CalcViewWidth( const SwTxtSizeInfo &rInf ); +#endif + +protected: +#ifndef VERTICAL_LAYOUT + KSHORT nViewWidth; +#endif + KSHORT nRestWidth; +public: + SwBreakPortion( const SwLinePortion &rPortion ); + // liefert 0 zurueck, wenn keine Nutzdaten enthalten sind. + virtual SwLinePortion *Compress(); + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + USHORT GetRestWidth() const { return nRestWidth; } + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwKernPortion + *************************************************************************/ + +class SwKernPortion : public SwLinePortion +{ + short nKern; + sal_Bool bBackground; + +#ifdef VERTICAL_LAYOUT + sal_Bool bGridKern; +#endif + +public: + +#ifdef VERTICAL_LAYOUT + // This constructor automatically appends the portion to rPortion + // bBG indicates, that the background of the kerning portion has to + // be painted, e.g., if the portion if positioned between to fields. + // bGridKern indicates, that the kerning portion is used to provide + // additional space in grid mode. + SwKernPortion( SwLinePortion &rPortion, short nKrn, + sal_Bool bBG = sal_False, sal_Bool bGridKern = sal_False ); + + // This constructor only sets the height and ascent to the values + // of rPortion. It is only used for kerning portions for grid mode +#else + SwKernPortion( SwLinePortion &rPortion, short nKrn, + sal_Bool bBG = sal_False ); +#endif + + virtual void FormatEOL( SwTxtFormatInfo &rInf ); + virtual void Paint( const SwTxtPaintInfo &rInf ) const; + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwArrowPortion + *************************************************************************/ + +class SwArrowPortion : public SwLinePortion +{ + Point aPos; + sal_Bool bLeft; +public: + SwArrowPortion( const SwLinePortion &rPortion ); + virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual SwLinePortion *Compress(); +#ifndef VERTICAL_LAYOUT +#endif + inline sal_Bool IsLeft() const { return bLeft; } + inline const Point& GetPos() const { return aPos; } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwHangingPortion + * The characters which are forbidden at the start of a line like the dot and + * other punctuation marks are allowed to display in the margin of the page + * by a user option. + * The SwHangingPortion is the corresponding textportion to do that. + *************************************************************************/ + +class SwHangingPortion : public SwTxtPortion +{ + KSHORT nInnerWidth; +public: + inline SwHangingPortion( SwPosSize aSize ) : nInnerWidth( aSize.Width() ) + { SetWhichPor( POR_HNG ); SetLen( 1 ); Height( aSize.Height() ); } + + inline KSHORT GetInnerWidth() const { return nInnerWidth; } +}; + + +/************************************************************************* + * inline - Implementations + *************************************************************************/ + +CLASSIO( SwBreakPortion ) +CLASSIO( SwEndPortion ) +CLASSIO( SwKernPortion ) +CLASSIO( SwArrowPortion ) + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/portab.hxx b/binfilter/bf_sw/source/core/text/portab.hxx new file mode 100644 index 000000000000..72f9a98a5fec --- /dev/null +++ b/binfilter/bf_sw/source/core/text/portab.hxx @@ -0,0 +1,123 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORTAB_HXX +#define _PORTAB_HXX + +#include "porglue.hxx" +namespace binfilter { + +/************************************************************************* + * class SwTabPortion + *************************************************************************/ + +class SwTabPortion : public SwFixPortion +{ + const KSHORT nTabPos; + const xub_Unicode cFill; + + // Das Format() verzweigt entweder in Pre- oder PostFormat() + sal_Bool PreFormat( SwTxtFormatInfo &rInf ); +public: + SwTabPortion( const KSHORT nTabPos, const xub_Unicode cFill = '\0' ); + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual void FormatEOL( SwTxtFormatInfo &rInf ); + sal_Bool PostFormat( SwTxtFormatInfo &rInf ); + inline sal_Bool IsFilled() const { return 0 != cFill; } + inline KSHORT GetTabPos() const { return nTabPos; } + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwTabLeftPortion + *************************************************************************/ + +class SwTabLeftPortion : public SwTabPortion +{ +public: + inline SwTabLeftPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' ) + : SwTabPortion( nTabPos, cFill ) + { SetWhichPor( POR_TABLEFT ); } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwTabRightPortion + *************************************************************************/ + +class SwTabRightPortion : public SwTabPortion +{ +public: + inline SwTabRightPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' ) + : SwTabPortion( nTabPos, cFill ) + { SetWhichPor( POR_TABRIGHT ); } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwTabCenterPortion + *************************************************************************/ + +class SwTabCenterPortion : public SwTabPortion +{ +public: + inline SwTabCenterPortion( const KSHORT nTabPos, const xub_Unicode cFill='\0' ) + : SwTabPortion( nTabPos, cFill ) + { SetWhichPor( POR_TABCENTER ); } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwTabDecimalPortion + *************************************************************************/ + +class SwTabDecimalPortion : public SwTabPortion +{ + const xub_Unicode cTab; +public: + inline SwTabDecimalPortion( const KSHORT nTabPos, const xub_Unicode cTab, + const xub_Unicode cFill = '\0' ) + : SwTabPortion( nTabPos, cFill ), cTab(cTab) + { SetWhichPor( POR_TABDECIMAL ); } + inline xub_Unicode GetTabDecimal() const { return cTab; } + OUTPUT_OPERATOR +}; + +CLASSIO( SwTabPortion ) +CLASSIO( SwTabLeftPortion ) +CLASSIO( SwTabRightPortion ) +CLASSIO( SwTabCenterPortion ) +CLASSIO( SwTabDecimalPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/portox.hxx b/binfilter/bf_sw/source/core/text/portox.hxx new file mode 100644 index 000000000000..bfcbcbe85f64 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/portox.hxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PORTOX_HXX +#define _PORTOX_HXX + +#include "portxt.hxx" + +namespace binfilter { + +/************************************************************************* + * class SwToxPortion + *************************************************************************/ + +class SwToxPortion : public SwTxtPortion +{ +public: + inline SwToxPortion(){ SetWhichPor( POR_TOX ); } + OUTPUT_OPERATOR +}; + +/************************************************************************* + * class SwIsoToxPortion + *************************************************************************/ + +class SwIsoToxPortion : public SwToxPortion +{ + KSHORT nViewWidth; + +public: + SwIsoToxPortion(); + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual SwLinePortion *Compress(); + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR +}; + +/************************************************************************* + * inline - Implementations + *************************************************************************/ + +CLASSIO( SwToxPortion ) +CLASSIO( SwIsoToxPortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/portxt.hxx b/binfilter/bf_sw/source/core/text/portxt.hxx new file mode 100644 index 000000000000..ea28ec5e0d08 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/portxt.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _PORTXT_HXX +#define _PORTXT_HXX + +#ifdef GCC +#include <sys/types.h> +#else +#include <new.h> //fuer size_t, FIXEDMEM aus tools +#endif +#include <tools/mempool.hxx> + +#include "porlin.hxx" +/*N*/ #include <tools/debug.hxx> //for stripping +namespace binfilter { +class SwTxtGuess; + +/************************************************************************* + * class SwTxtPortion + *************************************************************************/ + +class SwTxtPortion : public SwLinePortion +{ + void BreakCut( SwTxtFormatInfo &rInf, const SwTxtGuess &rGuess ); + void BreakUnderflow( SwTxtFormatInfo &rInf ); + sal_Bool _Format( SwTxtFormatInfo &rInf ); + +public: + inline SwTxtPortion(){ SetWhichPor( POR_TXT ); } + SwTxtPortion( const SwLinePortion &rPortion ); + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");}; //STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + virtual sal_Bool Format( SwTxtFormatInfo &rInf ); + virtual void FormatEOL( SwTxtFormatInfo &rInf ); + virtual SwPosSize GetTxtSize( const SwTxtSizeInfo &rInfo ) const; + virtual sal_Bool GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const; + + // zaehlt die Spaces fuer Blocksatz + xub_StrLen GetSpaceCnt( const SwTxtSizeInfo &rInf, xub_StrLen& rCnt ) const; + + sal_Bool CreateHyphen( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess ); + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR + DECL_FIXEDMEMPOOL_NEWDEL(SwTxtPortion) +}; + +/************************************************************************* + * class SwHolePortion + *************************************************************************/ + +class SwHolePortion : public SwLinePortion +{ + KSHORT nBlankWidth; +public: + SwHolePortion( const SwTxtPortion &rPor ); + inline KSHORT GetBlankWidth( ) const { return nBlankWidth; } + inline void SetBlankWidth( const KSHORT nNew ) { nBlankWidth = nNew; } + virtual SwLinePortion *Compress(); + virtual void Paint( const SwTxtPaintInfo &rInf ) const{DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 virtual void Paint( const SwTxtPaintInfo &rInf ) const; + + // Accessibility: pass information about this portion to the PortionHandler + + OUTPUT_OPERATOR + DECL_FIXEDMEMPOOL_NEWDEL(SwHolePortion) +}; + +CLASSIO( SwTxtPortion ) +CLASSIO( SwHolePortion ) + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/possiz.hxx b/binfilter/bf_sw/source/core/text/possiz.hxx new file mode 100644 index 000000000000..2b03fea578fb --- /dev/null +++ b/binfilter/bf_sw/source/core/text/possiz.hxx @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _POSSIZ_HXX +#define _POSSIZ_HXX + + +#include <tools/gen.hxx> +#include "txttypes.hxx" +namespace binfilter { + +// Im Gegensazt zu den SV-Sizes ist die SwPosSize immer positiv +class SwPosSize +{ + KSHORT nWidth; + KSHORT nHeight; +public: + inline SwPosSize( const KSHORT nWidth = 0, const KSHORT nHeight = 0 ) + : nWidth(nWidth), nHeight(nHeight) { } + inline SwPosSize( const Size &rSize ) + : nWidth(KSHORT(rSize.Width())), nHeight(KSHORT(rSize.Height())){ } + inline KSHORT Height() const { return nHeight; } + inline void Height( const KSHORT nNew ) { nHeight = nNew; } + inline KSHORT Width() const { return nWidth; } + inline void Width( const KSHORT nNew ) { nWidth = nNew; } + + inline Size SvLSize() const { return Size( nWidth, nHeight ); } + inline void SvLSize( const Size &rSize ); + inline void SvXSize( const Size &rSize ); + inline sal_Bool operator==( const SwPosSize &rSize ) const; + inline SwPosSize &operator=( const SwPosSize &rSize ); + inline SwPosSize &operator=( const Size &rSize ); +}; + +inline sal_Bool SwPosSize::operator==(const SwPosSize &rSize ) const +{ + return( Height() == rSize.Height() && + Width() == rSize.Width() ); +} + +inline SwPosSize &SwPosSize::operator=(const SwPosSize &rSize ) +{ + nWidth = rSize.Width(); + nHeight = rSize.Height(); + return *this; +} + +inline void SwPosSize::SvLSize( const Size &rSize ) +{ + nWidth = KSHORT(rSize.Width()); + nHeight = KSHORT(rSize.Height()); +} + +inline void SwPosSize::SvXSize( const Size &rSize ) +{ + nHeight = KSHORT(rSize.Width()); + nWidth = KSHORT(rSize.Height()); +} + +inline SwPosSize &SwPosSize::operator=( const Size &rSize ) +{ + nWidth = KSHORT(rSize.Width()); + nHeight = KSHORT(rSize.Height()); + return *this; +} + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/redlnitr.hxx b/binfilter/bf_sw/source/core/text/redlnitr.hxx new file mode 100644 index 000000000000..e9848c80a816 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/redlnitr.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _REDLNITR_HXX +#define _REDLNITR_HXX + +#include "ndhints.hxx" +#include "redlenum.hxx" // SwRedlineType +#include "swfont.hxx" +#ifndef _SVSTDARR_USHORTS +#define _SVSTDARR_USHORTS +#include <bf_svtools/svstdarr.hxx> +#endif +namespace binfilter { +class SfxItemSet; + +class SwTxtNode; +class SwDoc; + +class SwAttrHandler; + +class SwExtend +{ + SwFont *pFnt; + const SvUShorts ⇒ // XAMA: Array of xub_StrLen + xub_StrLen nStart; + xub_StrLen nPos; + xub_StrLen nEnd; + sal_Bool _Leave( SwFont& rFnt, xub_StrLen nNew ); + sal_Bool Inside() const { return ( nPos >= nStart && nPos < nEnd ); } + void ActualizeFont( SwFont &rFnt, xub_StrLen nAttr ); +public: + SwExtend( const SvUShorts &rA, xub_StrLen nSt ) : rArr( rA ), pFnt(0), + nStart( nSt ), nPos( STRING_LEN ), nEnd( nStart + rA.Count() ) {} + ~SwExtend() { delete pFnt; } + sal_Bool IsOn() const { return pFnt != 0; } + void Reset() { if( pFnt ) { delete pFnt; pFnt = NULL; } nPos = STRING_LEN; } + sal_Bool Leave( SwFont& rFnt, xub_StrLen nNew ) + { if( pFnt ) return _Leave( rFnt, nNew ); return sal_False; } + short Enter( SwFont& rFnt, xub_StrLen nNew ); + xub_StrLen Next( xub_StrLen nNext ); + SwFont* GetFont() { return pFnt; } + void UpdateFont( SwFont &rFnt ) { ActualizeFont( rFnt, rArr[ nPos - nStart ] ); } +}; + +class SwRedlineItr +{ + SwExtend *pExt; + sal_Bool bOn; +public: +SwRedlineItr( const SwTxtNode& rTxtNd, SwFont& rFnt, SwAttrHandler& rAH,//STRIP001 SwRedlineItr( const SwTxtNode& rTxtNd, SwFont& rFnt, SwAttrHandler& rAH, +xub_StrLen nRedlPos, sal_Bool bShw, const SvUShorts *pArr = 0,//STRIP001 xub_StrLen nRedlPos, sal_Bool bShw, const SvUShorts *pArr = 0, +xub_StrLen nStart = STRING_LEN ){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 xub_StrLen nStart = STRING_LEN ); + inline sal_Bool IsOn() const { return bOn || ( pExt && pExt->IsOn() ); } + sal_Bool CheckLine( xub_StrLen nChkStart, xub_StrLen nChkEnd ){DBG_BF_ASSERT(0, "STRIP"); return FALSE;} //STRIP001 sal_Bool CheckLine( xub_StrLen nChkStart, xub_StrLen nChkEnd ); + inline sal_Bool ExtOn() { if( pExt ) return pExt->IsOn(); return sal_False; } +}; + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_atrstck.cxx b/binfilter/bf_sw/source/core/text/sw_atrstck.cxx new file mode 100644 index 000000000000..91eeaec8fbaf --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_atrstck.cxx @@ -0,0 +1,729 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <atrhndl.hxx> +#include <bf_svtools/itemiter.hxx> +#include <bf_svx/cmapitem.hxx> +#include <bf_svx/colritem.hxx> +#include <bf_svx/cntritem.hxx> +#include <bf_svx/crsditem.hxx> +#include <bf_svx/escpitem.hxx> +#include <bf_svx/fontitem.hxx> +#include <bf_svx/fhgtitem.hxx> +#include <bf_svx/kernitem.hxx> +#include <bf_svx/charreliefitem.hxx> +#include <bf_svx/langitem.hxx> +#include <bf_svx/postitem.hxx> +#include <bf_svx/shdditem.hxx> +#include <bf_svx/udlnitem.hxx> +#include <bf_svx/wghtitem.hxx> +#include <bf_svx/wrlmitem.hxx> +#include <bf_svx/akrnitem.hxx> +#include <bf_svx/blnkitem.hxx> +#include <bf_svx/charrotateitem.hxx> +#include <bf_svx/emphitem.hxx> +#include <bf_svx/charscaleitem.hxx> +#include <bf_svx/twolinesitem.hxx> +#include <charfmt.hxx> +#include <fchrfmt.hxx> +#include <bf_svx/brshitem.hxx> +#include <txtinet.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <viewsh.hxx> // ViewShell +#include <viewopt.hxx> // SwViewOptions +namespace binfilter { + +#define STACK_INCREMENT 4 + +/************************************************************************* + * Attribute to Stack Mapping + * + * Attributes applied to a text are pushed on different stacks. For each + * stack, the top most attribute on the stack is valid. Because some + * kinds of attributes have to be pushed to the same stacks we map their + * ids to stack ids + * Attention: The first NUM_DEFAULT_VALUES ( defined in swfntcch.hxx == 34 ) + * are stored in the defaultitem-cache, if you add one, you have to increase + * NUM_DEFAULT_VALUES. + *************************************************************************/ + +const BYTE StackPos[ RES_TXTATR_WITHEND_END - RES_CHRATR_BEGIN + 1 ] = { + 0, // // 0 + 1, // RES_CHRATR_CASEMAP = RES_CHRATR_BEGIN // 1 + 0, // RES_CHRATR_CHARSETCOLOR, // 2 + 2, // RES_CHRATR_COLOR, // 3 + 3, // RES_CHRATR_CONTOUR, // 4 + 4, // RES_CHRATR_CROSSEDOUT, // 5 + 5, // RES_CHRATR_ESCAPEMENT, // 6 + 6, // RES_CHRATR_FONT, // 7 + 7, // RES_CHRATR_FONTSIZE, // 8 + 8, // RES_CHRATR_KERNING, // 9 + 9, // RES_CHRATR_LANGUAGE, // 10 + 10, // RES_CHRATR_POSTURE, // 11 + 0, // RES_CHRATR_PROPORTIONALFONTSIZE, // 12 + 11, // RES_CHRATR_SHADOWED, // 13 + 12, // RES_CHRATR_UNDERLINE, // 14 + 13, // RES_CHRATR_WEIGHT, // 15 + 14, // RES_CHRATR_WORDLINEMODE, // 16 + 15, // RES_CHRATR_AUTOKERN, // 17 + 16, // RES_CHRATR_BLINK, // 18 + 17, // RES_CHRATR_NOHYPHEN, // 19 + 0, // RES_CHRATR_NOLINEBREAK, // 20 + 18, // RES_CHRATR_BACKGROUND, // 21 + 19, // RES_CHRATR_CJK_FONT, // 22 + 20, // RES_CHRATR_CJK_FONTSIZE, // 23 + 21, // RES_CHRATR_CJK_LANGUAGE, // 24 + 22, // RES_CHRATR_CJK_POSTURE, // 25 + 23, // RES_CHRATR_CJK_WEIGHT, // 26 + 24, // RES_CHRATR_CTL_FONT, // 27 + 25, // RES_CHRATR_CTL_FONTSIZE, // 28 + 26, // RES_CHRATR_CTL_LANGUAGE, // 29 + 27, // RES_CHRATR_CTL_POSTURE, // 30 + 28, // RES_CHRATR_CTL_WEIGHT, // 31 + 29, // RES_CHRATR_ROTATE, // 32 + 30, // RES_CHRATR_EMPHASIS_MARK, // 33 + 31, // RES_CHRATR_TWO_LINES, // 34 + 32, // RES_CHRATR_SCALEW, // 35 + 33, // RES_CHRATR_RELIEF, // 36 + 0, // RES_CHRATR_DUMMY1, // 37 + 0, // RES_TXTATR_INETFMT // 38 + 0, // RES_TXTATR_DUMMY4, // 39 + 34, // RES_TXTATR_REFMARK, // 40 + 35, // RES_TXTATR_TOXMARK, // 41 + 0, // RES_TXTATR_CHARFMT, // 42 + 0, // RES_TXTATR_DUMMY5, // 43 + 36, // RES_TXTATR_CJK_RUBY, // 44 + 0, // RES_TXTATR_UNKNOWN_CONTAINER, // 45 + 0, // RES_TXTATR_DUMMY6, // 46 + 0 // RES_TXTATR_DUMMY7, // 47 +}; + +/************************************************************************* + * lcl_GetItem + * extracts pool item of type nWhich from rAttr + *************************************************************************/ + + +/************************************************************************* + * lcl_ChgHyperLinkColor + * returns if the color attribute has to be changed for hyperlinks + *************************************************************************/ + +/*M*/ sal_Bool lcl_ChgHyperLinkColor( const SwTxtAttr& rAttr, +/*M*/ const SfxPoolItem& rItem, +/*M*/ const ViewShell* pShell ) +/*M*/ { +/*M*/ return pShell && pShell->GetWin() && +/*M*/ ! pShell->GetViewOptions()->IsPagePreview() && +/*M*/ RES_TXTATR_INETFMT == rAttr.Which() && +/*M*/ RES_CHRATR_COLOR == rItem.Which() && +/*M*/ ( ((SwTxtINetFmt&)rAttr).IsVisited() && SwViewOption::IsVisitedLinks() || +/*M*/ ! ((SwTxtINetFmt&)rAttr).IsVisited() && SwViewOption::IsLinks() ); +/*M*/ } + + +/************************************************************************* + * SwAttrHandler::SwAttrStack::SwAttrStack() + *************************************************************************/ + +/*N*/ inline SwAttrHandler::SwAttrStack::SwAttrStack() +/*N*/ : nCount( 0 ), nSize( INITIAL_NUM_ATTR ) +/*N*/ { +/*N*/ pArray = pInitialArray; +/*N*/ } + +/************************************************************************* + * SwAttrHandler::SwAttrStack::Insert() + *************************************************************************/ + +/*N*/ void SwAttrHandler::SwAttrStack::Insert( const SwTxtAttr& rAttr, const USHORT nPos ) +/*N*/ { +/*N*/ // do we still have enough space? +/*N*/ if ( nCount >= nSize ) +/*N*/ { +/*?*/ // we are still in our initial array +/*?*/ if ( INITIAL_NUM_ATTR == nSize ) +/*?*/ { +/*?*/ nSize += STACK_INCREMENT; +/*?*/ pArray = new SwTxtAttr*[ nSize ]; +/*?*/ // copy from pInitArray to new Array +/*?*/ memcpy( pArray, pInitialArray, +/*?*/ INITIAL_NUM_ATTR * sizeof(SwTxtAttr*) +/*?*/ ); +/*?*/ } +/*?*/ // we are in new memory +/*?*/ else +/*?*/ { +/*?*/ nSize += STACK_INCREMENT; +/*?*/ SwTxtAttr** pTmpArray = new SwTxtAttr*[ nSize ]; +/*?*/ // copy from pArray to new Array +/*?*/ memcpy( pTmpArray, pArray, nCount * sizeof(SwTxtAttr*) ); +/*?*/ // free old array +/*?*/ delete [] pArray; +/*?*/ pArray = pTmpArray; +/*?*/ } +/*?*/ } +/*N*/ +/*N*/ ASSERT( nPos <= nCount, "wrong position for insert operation"); +/*N*/ +/*N*/ if ( nPos < nCount ) +/*N*/ memmove( pArray + nPos + 1, pArray + nPos, +/*N*/ ( nCount - nPos ) * sizeof(SwTxtAttr*) +/*N*/ ); +/*N*/ pArray[ nPos ] = (SwTxtAttr*)&rAttr; +/*N*/ +/*N*/ nCount++; +/*N*/ } + +/************************************************************************* + * SwAttrHandler::SwAttrStack::Remove() + *************************************************************************/ + +/*N*/ void SwAttrHandler::SwAttrStack::Remove( const SwTxtAttr& rAttr ) +/*N*/ { +/*N*/ USHORT nPos = Pos( rAttr ); +/*N*/ if ( nPos < nCount ) +/*N*/ { +/*N*/ memmove( pArray + nPos, pArray + nPos + 1, +/*N*/ ( nCount - 1 - nPos ) * sizeof(SwTxtAttr*) +/*N*/ ); +/*N*/ nCount--; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwAttrHandler::SwAttrStack::Top() + *************************************************************************/ + +/*N*/ const SwTxtAttr* SwAttrHandler::SwAttrStack::Top() const +/*N*/ { +/*N*/ return nCount ? pArray[ nCount - 1 ] : 0; +/*N*/ } + +/************************************************************************* + * SwAttrHandler::SwAttrStack::Pos() + *************************************************************************/ + +/*N*/ USHORT SwAttrHandler::SwAttrStack::Pos( const SwTxtAttr& rAttr ) const +/*N*/ { +/*N*/ if ( ! nCount ) +/*N*/ // empty stack +/*?*/ return USHRT_MAX; +/*N*/ +/*N*/ for ( USHORT nIdx = nCount; nIdx > 0; ) +/*N*/ { +/*N*/ if ( &rAttr == pArray[ --nIdx ] ) +/*N*/ return nIdx; +/*N*/ } +/*N*/ +/*N*/ // element not found +/*N*/ return USHRT_MAX; +/*N*/ } + +/************************************************************************* + * SwAttrHandler::SwAttrHandler() + *************************************************************************/ + +/*M*/ SwAttrHandler::SwAttrHandler() : pShell( 0 ), pFnt( 0 ), bVertLayout( sal_False ) +/*M*/ +/*N*/ { +/*N*/ memset( pDefaultArray, 0, NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) ); +/*N*/ } + +/*N*/ SwAttrHandler::~SwAttrHandler() +/*N*/ { +/*N*/ delete pFnt; +/*N*/ } + +/************************************************************************* + * SwAttrHandler::Init() + *************************************************************************/ + + +/*M*/ void SwAttrHandler::Init( const SfxPoolItem** pPoolItem, const SwAttrSet* pAS, +/*M*/ const SwDoc& rDoc, const ViewShell* pSh, +/*M*/ SwFont& rFnt, sal_Bool bVL ) +/*M*/ { +/*M*/ // initialize default array +/*M*/ memcpy( pDefaultArray, pPoolItem, +/*M*/ NUM_DEFAULT_VALUES * sizeof(SfxPoolItem*) ); +/*M*/ +/*M*/ pDoc = &rDoc; +/*M*/ pShell = pSh; +/*M*/ +/*M*/ // do we have to apply additional paragraph attributes? +/*M*/ bVertLayout = bVL; +/*M*/ +/*M*/ if ( pAS && pAS->Count() ) +/*M*/ { +/*M*/ SfxItemIter aIter( *pAS ); +/*M*/ register USHORT nWhich; +/*M*/ const SfxPoolItem* pItem = aIter.GetCurItem(); +/*M*/ while( TRUE ) +/*M*/ { +/*M*/ nWhich = pItem->Which(); +/*M*/ if( RES_CHRATR_BEGIN <= nWhich && RES_CHRATR_END > nWhich ) +/*M*/ { +/*M*/ pDefaultArray[ StackPos[ nWhich ] ] = pItem; +/*M*/ FontChg( *pItem, rFnt, sal_True ); +/*M*/ } +/*M*/ +/*M*/ if( aIter.IsAtEnd() ) +/*M*/ break; +/*M*/ +/*M*/ pItem = aIter.NextItem(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // It is possible, that Init is called more than once, e.g., in a +/*M*/ // SwTxtFrm::FormatOnceMore situation. +/*M*/ delete pFnt; +/*M*/ pFnt = new SwFont( rFnt ); +/*M*/ } + +/*N*/ void SwAttrHandler::Reset( ) +/*N*/ { +/*N*/ for ( USHORT i = 0; i < NUM_ATTRIBUTE_STACKS; i++ ) +/*N*/ aAttrStack[ i ].Reset(); +/*N*/ } + +/************************************************************************* + * SwAttrHandler::PushAndChg() + *************************************************************************/ + +/*M*/ void SwAttrHandler::PushAndChg( const SwTxtAttr& rAttr, SwFont& rFnt ) +/*M*/ { +/*M*/ // these special attributes in fact represent a collection of attributes +/*M*/ // they have to be pushed to each stack they belong to +/*M*/ if ( RES_TXTATR_INETFMT == rAttr.Which() || +/*M*/ RES_TXTATR_CHARFMT == rAttr.Which() ) +/*M*/ { +/*M*/ SwCharFmt* pFmt; +/*M*/ if( RES_TXTATR_INETFMT == rAttr.Which() ) +/*M*/ pFmt = ((SwTxtINetFmt&)rAttr).GetCharFmt(); +/*M*/ else +/*M*/ pFmt = rAttr.GetCharFmt().GetCharFmt(); +/*M*/ +/*M*/ if ( !pFmt ) +/*M*/ return; +/*M*/ +/*M*/ for ( USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) +/*M*/ { +/*M*/ const SfxPoolItem* pItem; +/*M*/ BOOL bRet = SFX_ITEM_SET == +/*M*/ pFmt->GetItemState( i, TRUE, &pItem ); +/*M*/ if ( bRet ) +/*M*/ { +/*M*/ // we push rAttr onto the appropriate stack +/*M*/ if ( Push( rAttr, *pItem , rFnt ) ) +/*M*/ { +/*M*/ // we let pItem change rFnt +/*M*/ if ( lcl_ChgHyperLinkColor( rAttr, *pItem, pShell ) ) +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ // for hyperlinks we still have to evaluate +/*M*/ // the appearence settings +/*M*/ } +/*M*/ else +/*M*/ FontChg( *pItem, rFnt, sal_True ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ // this is the usual case, we have a basic attribute, push it onto the +/*M*/ // stack and change the font +/*M*/ else +/*M*/ { +/*M*/ if ( Push( rAttr, rAttr.GetAttr(), rFnt ) ) +/*M*/ // we let pItem change rFnt +/*M*/ FontChg( rAttr.GetAttr(), rFnt, sal_True ); +/*M*/ } +/*M*/ } + +/************************************************************************* + * SwAttrHandler::Push() + *************************************************************************/ + +/*M*/ sal_Bool SwAttrHandler::Push( const SwTxtAttr& rAttr, const SfxPoolItem& rItem, SwFont& rFnt ) +/*M*/ { +/*M*/ ASSERT( rItem.Which() < RES_TXTATR_WITHEND_END || +/*M*/ RES_UNKNOWNATR_CONTAINER == rItem.Which() , +/*M*/ "I do not want this attribute, nWhich >= RES_TXTATR_WITHEND_END" ); +/*M*/ +/*M*/ // robust +/*M*/ if ( RES_TXTATR_WITHEND_END <= rItem.Which() || +/*M*/ RES_UNKNOWNATR_CONTAINER == rItem.Which() ) +/*M*/ return sal_False; +/*M*/ +/*M*/ USHORT nStack = StackPos[ rItem.Which() ]; +/*M*/ +/*M*/ // attributes originating from redlining have highest priority +/*M*/ // second priority are hyperlink attributes, which have a color replacement +/*M*/ const SwTxtAttr* pTopAttr = aAttrStack[ nStack ].Top(); +/*M*/ if ( ! pTopAttr || rAttr.IsPriorityAttr() || +/*M*/ ( ! pTopAttr->IsPriorityAttr() && +/*M*/ ! lcl_ChgHyperLinkColor( *pTopAttr, rItem, pShell ) ) ) +/*M*/ { +/*M*/ aAttrStack[ nStack ].Push( rAttr ); +/*M*/ return sal_True; +/*M*/ } +/*M*/ +/*M*/ USHORT nPos = aAttrStack[ nStack ].Count(); +/*M*/ ASSERT( nPos, "empty stack?" ); +/*M*/ aAttrStack[ nStack ].Insert( rAttr, nPos - 1 ); +/*M*/ return sal_False; +/*M*/ } + +/************************************************************************* + * SwAttrHandler::PopAndChg() + *************************************************************************/ + +/*N*/ void SwAttrHandler::PopAndChg( const SwTxtAttr& rAttr, SwFont& rFnt ) +/*N*/ { +/*N*/ // these special attributes in fact represent a collection of attributes +/*N*/ // they have to be removed from each stack they belong to +/*N*/ if ( RES_TXTATR_INETFMT == rAttr.Which() || +/*N*/ RES_TXTATR_CHARFMT == rAttr.Which() ) +/*N*/ { +/*N*/ SwCharFmt* pFmt; +/*N*/ if( RES_TXTATR_INETFMT == rAttr.Which() ) +/*N*/ pFmt = ((SwTxtINetFmt&)rAttr).GetCharFmt(); +/*N*/ else +/*N*/ pFmt = rAttr.GetCharFmt().GetCharFmt(); +/*N*/ +/*N*/ if ( !pFmt ) +/*N*/ return; +/*N*/ +/*N*/ for ( USHORT i = RES_CHRATR_BEGIN; i < RES_CHRATR_END; i++) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ BOOL bRet = SFX_ITEM_SET == +/*N*/ pFmt->GetItemState( i, TRUE, &pItem ); +/*N*/ if ( bRet ) +/*N*/ { +/*N*/ // we remove rAttr from the appropriate stack +/*N*/ USHORT nStackPos = StackPos[ i ]; +/*N*/ aAttrStack[ nStackPos ].Remove( rAttr ); +/*N*/ // reset font according to attribute on top of stack +/*N*/ // or default value +/*N*/ ActivateTop( rFnt, i ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // this is the usual case, we have a basic attribute, remove it from the +/*N*/ // stack and reset the font +/*N*/ else if ( RES_UNKNOWNATR_CONTAINER != rAttr.Which() ) +/*N*/ { +/*N*/ aAttrStack[ StackPos[ rAttr.Which() ] ].Remove( rAttr ); +/*N*/ // reset font according to attribute on top of stack +/*N*/ // or default value +/*N*/ ActivateTop( rFnt, rAttr.Which() ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwAttrHandler::Pop() + * + * only used during redlining + *************************************************************************/ + + +/************************************************************************* + * SwAttrHandler::ActivateTop() + *************************************************************************/ +/*M*/ void SwAttrHandler::ActivateTop( SwFont& rFnt, const USHORT nAttr ) +/*M*/ { +/*M*/ ASSERT( nAttr < RES_TXTATR_WITHEND_END, +/*M*/ "I cannot activate this attribute, nWhich >= RES_TXTATR_WITHEND_END" ); +/*M*/ +/*M*/ const USHORT nStackPos = StackPos[ nAttr ]; +/*M*/ const SwTxtAttr* pTopAt = aAttrStack[ nStackPos ].Top(); +/*M*/ if ( pTopAt ) +/*M*/ { +/*M*/ // check if top attribute is collection of attributes +/*M*/ if ( RES_TXTATR_INETFMT == pTopAt->Which() || +/*M*/ RES_TXTATR_CHARFMT == pTopAt->Which() ) +/*M*/ { +/*M*/ SwCharFmt* pFmtNext; +/*M*/ if( RES_TXTATR_INETFMT == pTopAt->Which() ) +/*M*/ pFmtNext = ((SwTxtINetFmt*)pTopAt)->GetCharFmt(); +/*M*/ else +/*M*/ pFmtNext = pTopAt->GetCharFmt().GetCharFmt(); +/*M*/ +/*M*/ const SfxPoolItem* pItemNext; +/*M*/ pFmtNext->GetItemState( nAttr, TRUE, &pItemNext ); +/*M*/ +/*M*/ if ( lcl_ChgHyperLinkColor( *pTopAt, *pItemNext, pShell ) ) +/*M*/ { +/*M*/ // for hyperlinks we still have to evaluate +/*M*/ // the appearence settings +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Color aColor; +/*M*/ } +/*M*/ else +/*M*/ FontChg( *pItemNext, rFnt, sal_False ); +/*M*/ } +/*M*/ else +/*M*/ FontChg( pTopAt->GetAttr(), rFnt, sal_False ); +/*M*/ } +/*M*/ +/*M*/ // default value has to be set, we only have default values for char attribs +/*M*/ else if ( nStackPos < NUM_DEFAULT_VALUES ) +/*M*/ FontChg( *pDefaultArray[ nStackPos ], rFnt, sal_False ); +/*M*/ +/*M*/ else if ( RES_TXTATR_REFMARK == nAttr ) +/*M*/ rFnt.GetRef()--; +/*M*/ else if ( RES_TXTATR_TOXMARK == nAttr ) +/*M*/ rFnt.GetTox()--; +/*M*/ else if ( RES_TXTATR_CJK_RUBY == nAttr ) +/*M*/ { +/*M*/ // ruby stack has no more attributes +/*M*/ // check, if an rotation attribute has to be applied +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ]; +/*M*/ } +/*M*/ } + +/************************************************************************* + * Font Changing Function + * + * When popping an attribute from the stack, the top mose remaining + * attribute in the stack becomes valid. The following function change + * a font depending on the stack id. + *************************************************************************/ + +/*M*/ void SwAttrHandler::FontChg(const SfxPoolItem& rItem, SwFont& rFnt, sal_Bool bPush ) +/*M*/ { +/*M*/ switch ( rItem.Which() ) +/*M*/ { +/*M*/ case RES_CHRATR_CASEMAP : +/*M*/ rFnt.SetCaseMap( ((SvxCaseMapItem&)rItem).GetCaseMap() ); +/*M*/ break; +/*M*/ case RES_CHRATR_COLOR : +/*M*/ rFnt.SetColor( ((SvxColorItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_CONTOUR : +/*M*/ rFnt.SetOutline( ((SvxContourItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_CROSSEDOUT : +/*M*/ rFnt.SetStrikeout( ((SvxCrossedOutItem&)rItem).GetStrikeout() ); +/*M*/ break; +/*M*/ case RES_CHRATR_ESCAPEMENT : +/*M*/ rFnt.SetEscapement( ((SvxEscapementItem&)rItem).GetEsc() ); +/*M*/ rFnt.SetProportion( ((SvxEscapementItem&)rItem).GetProp() ); +/*M*/ break; +/*M*/ case RES_CHRATR_FONT : +/*M*/ rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_LATIN ); +/*M*/ rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_LATIN ); +/*M*/ rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_LATIN ); +/*M*/ rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_LATIN ); +/*M*/ rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_LATIN ); +/*M*/ break; +/*M*/ case RES_CHRATR_FONTSIZE : +/*M*/ rFnt.SetSize(Size(0,((SvxFontHeightItem&)rItem).GetHeight() ), SW_LATIN ); +/*M*/ break; +/*M*/ case RES_CHRATR_KERNING : +/*M*/ rFnt.SetFixKerning( ((SvxKerningItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_LANGUAGE : +/*M*/ rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_LATIN ); +/*M*/ break; +/*M*/ case RES_CHRATR_POSTURE : +/*M*/ rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_LATIN ); +/*M*/ break; +/*M*/ case RES_CHRATR_SHADOWED : +/*M*/ rFnt.SetShadow( ((SvxShadowedItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_UNDERLINE : +/*M*/ rFnt.SetUnderline( ((SvxUnderlineItem&)rItem).GetUnderline() ); +/*M*/ rFnt.SetUnderColor( ((SvxUnderlineItem&)rItem).GetColor() ); +/*M*/ break; +/*M*/ case RES_CHRATR_WEIGHT : +/*M*/ rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_LATIN ); +/*M*/ break; +/*M*/ case RES_CHRATR_WORDLINEMODE : +/*M*/ rFnt.SetWordLineMode( ((SvxWordLineModeItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_AUTOKERN : +/*M*/ if( ((SvxAutoKernItem&)rItem).GetValue() ) +/*M*/ rFnt.SetAutoKern( ( !pDoc || !pDoc->IsKernAsianPunctuation() ) ? +/*M*/ KERNING_FONTSPECIFIC : KERNING_ASIAN ); +/*M*/ else +/*M*/ rFnt.SetAutoKern( 0 ); +/*M*/ break; +/*M*/ case RES_CHRATR_BLINK : +/*M*/ rFnt.SetBlink( ((SvxBlinkItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_BACKGROUND : +/*M*/ rFnt.SetBackColor(new Color( ((SvxBrushItem&)rItem).GetColor() ) ); +/*M*/ break; +/*M*/ case RES_CHRATR_CJK_FONT : +/*M*/ rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CJK ); +/*M*/ rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CJK ); +/*M*/ rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CJK ); +/*M*/ rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CJK ); +/*M*/ rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CJK ); +/*M*/ break; +/*M*/ case RES_CHRATR_CJK_FONTSIZE : +/*M*/ rFnt.SetSize(Size( 0, ((SvxFontHeightItem&)rItem).GetHeight()), SW_CJK); +/*M*/ break; +/*M*/ case RES_CHRATR_CJK_LANGUAGE : +/*M*/ rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CJK ); +/*M*/ break; +/*M*/ case RES_CHRATR_CJK_POSTURE : +/*M*/ rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CJK ); +/*M*/ break; +/*M*/ case RES_CHRATR_CJK_WEIGHT : +/*M*/ rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CJK ); +/*M*/ break; +/*M*/ case RES_CHRATR_CTL_FONT : +/*M*/ rFnt.SetName( ((SvxFontItem&)rItem).GetFamilyName(), SW_CTL ); +/*M*/ rFnt.SetStyleName( ((SvxFontItem&)rItem).GetStyleName(), SW_CTL ); +/*M*/ rFnt.SetFamily( ((SvxFontItem&)rItem).GetFamily(), SW_CTL ); +/*M*/ rFnt.SetPitch( ((SvxFontItem&)rItem).GetPitch(), SW_CTL ); +/*M*/ rFnt.SetCharSet( ((SvxFontItem&)rItem).GetCharSet(), SW_CTL ); +/*M*/ break; +/*M*/ case RES_CHRATR_CTL_FONTSIZE : +/*M*/ rFnt.SetSize(Size(0, ((SvxFontHeightItem&)rItem).GetHeight() ), SW_CTL); +/*M*/ break; +/*M*/ case RES_CHRATR_CTL_LANGUAGE : +/*M*/ rFnt.SetLanguage( ((SvxLanguageItem&)rItem).GetLanguage(), SW_CTL ); +/*M*/ break; +/*M*/ case RES_CHRATR_CTL_POSTURE : +/*M*/ rFnt.SetItalic( ((SvxPostureItem&)rItem).GetPosture(), SW_CTL ); +/*M*/ break; +/*M*/ case RES_CHRATR_CTL_WEIGHT : +/*M*/ rFnt.SetWeight( ((SvxWeightItem&)rItem).GetWeight(), SW_CTL ); +/*M*/ break; +/*M*/ case RES_CHRATR_EMPHASIS_MARK : +/*M*/ rFnt.SetEmphasisMark( +/*M*/ ((SvxEmphasisMarkItem&)rItem).GetEmphasisMark() +/*M*/ ); +/*M*/ break; +/*M*/ case RES_CHRATR_SCALEW : +/*M*/ rFnt.SetPropWidth( ((SvxCharScaleWidthItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ case RES_CHRATR_RELIEF : +/*M*/ rFnt.SetRelief( (FontRelief)((SvxCharReliefItem&)rItem).GetValue() ); +/*M*/ break; +/*M*/ +/*M*/ case RES_CHRATR_ROTATE : +/*M*/ { +/*M*/ // rotate attribute is applied, when: +/*M*/ // 1. ruby stack is empty and +/*M*/ // 2. top of two line stack ( or default attribute )is an +/*M*/ // deactivated two line attribute +/*M*/ sal_Bool bRuby = 0 != +/*M*/ aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count(); +/*M*/ +/*M*/ if ( bRuby ) +/*M*/ break; +/*M*/ +/*M*/ USHORT nTwoLineStack = StackPos[ RES_CHRATR_TWO_LINES ]; +/*M*/ sal_Bool bTwoLineAct = sal_False; +/*M*/ const SfxPoolItem* pTwoLineItem = 0; +/*M*/ const SwTxtAttr* pTwoLineAttr = aAttrStack[ nTwoLineStack ].Top(); +/*M*/ +/*M*/ if ( pTwoLineAttr ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pTwoLineItem = lcl_GetItem( *pTwoLineAttr, RES_CHRATR_TWO_LINES ); +/*?*/ bTwoLineAct = ((SvxTwoLinesItem*)pTwoLineItem)->GetValue(); +/*M*/ } +/*M*/ else +/*M*/ bTwoLineAct = +/*M*/ ((SvxTwoLinesItem*)pDefaultArray[ nTwoLineStack ])->GetValue(); +/*M*/ +/*M*/ if ( !bTwoLineAct ) +/*M*/ rFnt.SetVertical( ((SvxCharRotateItem&)rItem).GetValue(), +/*M*/ bVertLayout ); +/*M*/ +/*M*/ break; +/*M*/ } +/*M*/ case RES_CHRATR_TWO_LINES : +/*M*/ { +/*M*/ sal_Bool bRuby = 0 != +/*M*/ aAttrStack[ StackPos[ RES_TXTATR_CJK_RUBY ] ].Count(); +/*M*/ sal_Bool bTwoLineAct = sal_False; +/*M*/ +/*M*/ // two line is activated, if +/*M*/ // 1. no ruby attribute is set and +/*M*/ // 2. attribute is active +/*M*/ bTwoLineAct = ((SvxTwoLinesItem&)rItem).GetValue(); +/*M*/ +/*M*/ if ( !bRuby && bTwoLineAct ) +/*M*/ { +/*M*/ rFnt.SetVertical( 0, bVertLayout ); +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ // a deactivating two line attribute is on top of stack, +/*M*/ // check if rotate attribute has to be enabled +/*M*/ if ( bRuby ) +/*M*/ break; +/*M*/ +/*M*/ USHORT nRotateStack = StackPos[ RES_CHRATR_ROTATE ]; +/*M*/ const SfxPoolItem* pRotateItem = 0; +/*M*/ const SwTxtAttr* pRotateAttr = aAttrStack[ nRotateStack ].Top(); +/*M*/ +/*M*/ if ( pRotateAttr ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pRotateItem = lcl_GetItem( *pRotateAttr, RES_CHRATR_ROTATE ); +/*M*/ } +/*M*/ else +/*M*/ rFnt.SetVertical( +/*M*/ ((SvxCharRotateItem*)pDefaultArray[ nRotateStack ])->GetValue(), +/*M*/ bVertLayout +/*M*/ ); +/*M*/ break; +/*M*/ } +/*M*/ case RES_TXTATR_CJK_RUBY : +/*M*/ rFnt.SetVertical( 0, bVertLayout ); +/*M*/ break; +/*M*/ case RES_TXTATR_REFMARK : +/*M*/ if ( bPush ) +/*M*/ rFnt.GetRef()++; +/*M*/ else +/*M*/ rFnt.GetRef()--; +/*M*/ break; +/*M*/ case RES_TXTATR_TOXMARK : +/*M*/ if ( bPush ) +/*M*/ rFnt.GetTox()++; +/*M*/ else +/*M*/ rFnt.GetTox()--; +/*M*/ break; +/*M*/ } +/*M*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_blink.cxx b/binfilter/bf_sw/source/core/text/sw_blink.cxx new file mode 100644 index 000000000000..ccd868ad8bd0 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_blink.cxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "blink.hxx" +#include "porlay.hxx" // SwLineLayout +namespace binfilter { +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_frmcrsr.cxx b/binfilter/bf_sw/source/core/text/sw_frmcrsr.cxx new file mode 100644 index 000000000000..fc789c0ebbd0 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_frmcrsr.cxx @@ -0,0 +1,634 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <errhdl.hxx> + +#include "pam.hxx" // SwPosition + +#include <horiornt.hxx> + +#include "pagefrm.hxx" + + + + + + +#include <unicode/ubidi.h> + +#include "txtcfg.hxx" +#include "itrtxt.hxx" // SwTxtCursor +#include "crstate.hxx" // SwTxtCursor + +#if OSL_DEBUG_LEVEL > 1 +#endif +namespace binfilter { + +#define MIN_OFFSET_STEP 10 + +/* + * 1170-SurvivalKit: Wie gelangt man hinter das letzte Zeichen der Zeile. + * - RightMargin verzichtet auf den Positionsausgleich mit -1 + * - GetCharRect liefert bei MV_RIGHTMARGIN ein GetEndCharRect + * - GetEndCharRect setzt bRightMargin auf sal_True + * - SwTxtCursor::bRightMargin wird per CharCrsrToLine auf sal_False gesetzt + */ + +/************************************************************************* + * GetAdjFrmAtPos() + *************************************************************************/ + +/*N*/ SwTxtFrm *GetAdjFrmAtPos( SwTxtFrm *pFrm, const SwPosition &rPos, +/*N*/ const sal_Bool bRightMargin, const sal_Bool bNoScroll = TRUE ) +/*N*/ { +/*N*/ // 8810: vgl. 1170, RightMargin in der letzten Masterzeile... +/*N*/ const xub_StrLen nOffset = rPos.nContent.GetIndex(); +/*N*/ SwTxtFrm *pFrmAtPos = pFrm; +/*N*/ if( !bNoScroll || pFrm->GetFollow() ) +/*N*/ { +/*N*/ pFrmAtPos = pFrm->GetFrmAtPos( rPos ); +/*N*/ if( nOffset < pFrmAtPos->GetOfst() && +/*N*/ !pFrmAtPos->IsFollow() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ xub_StrLen nNew = nOffset; +/*N*/ } +/*N*/ } +/*N*/ while( pFrm != pFrmAtPos ) +/*N*/ { +/*?*/ pFrm = pFrmAtPos; +/*?*/ pFrm->GetFormatted(); +/*?*/ pFrmAtPos = (SwTxtFrm*)pFrm->GetFrmAtPos( rPos ); +/*N*/ } +/*N*/ +/*N*/ if( nOffset && bRightMargin ) +/*N*/ { +/*N*/ while( pFrmAtPos && pFrmAtPos->GetOfst() == nOffset && +/*N*/ pFrmAtPos->IsFollow() ) +/*N*/ { +/*?*/ pFrmAtPos->GetFormatted(); +/*?*/ pFrmAtPos = pFrmAtPos->FindMaster(); +/*N*/ } +/*N*/ ASSERT( pFrmAtPos, "+GetCharRect: no frame with my rightmargin" ); +/*N*/ } +/*N*/ return pFrmAtPos ? pFrmAtPos : pFrm; +/*N*/ } + + +/************************************************************************* + * GetFrmAtOfst(), GetFrmAtPos() + *************************************************************************/ + +/*N*/ SwTxtFrm *SwTxtFrm::GetFrmAtOfst( const xub_StrLen nWhere ) +/*N*/ { +/*N*/ SwTxtFrm *pRet = this; +/*N*/ while( pRet->HasFollow() && nWhere >= pRet->GetFollow()->GetOfst() ) +/*?*/ pRet = pRet->GetFollow(); +/*N*/ return pRet; +/*N*/ } + +/*N*/ SwTxtFrm *SwTxtFrm::GetFrmAtPos( const SwPosition &rPos ) +/*N*/ { +/*N*/ SwTxtFrm *pFoll = (SwTxtFrm*)this; +/*N*/ while( pFoll->GetFollow() ) +/*N*/ { +/*N*/ if( rPos.nContent.GetIndex() > pFoll->GetFollow()->GetOfst() ) +/*N*/ pFoll = pFoll->GetFollow(); +/*N*/ else +/*N*/ { +/*N*/ if( rPos.nContent.GetIndex() == pFoll->GetFollow()->GetOfst() +/*N*/ && !SwTxtCursor::IsRightMargin() ) +/*?*/ pFoll = pFoll->GetFollow(); +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ return pFoll; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::GetCharRect() + *************************************************************************/ + +/* + * GetCharRect() findet die Characterzelle des Characters, dass + * durch aPos beschrieben wird. GetCrsrOfst() findet den + * umgekehrten Weg: Von einer Dokumentkoordinate zu einem Pam. + * Beide sind virtuell in der Framebasisklasse und werden deshalb + * immer angezogen. + */ + +/*N*/ sal_Bool SwTxtFrm::GetCharRect( SwRect& rOrig, const SwPosition &rPos, +/*N*/ SwCrsrMoveState *pCMS ) const +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::GetCharRect with swapped frame" ); +/*N*/ +/*N*/ if( IsLocked() || IsHiddenNow() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ //Erstmal den richtigen Frm finden, dabei muss beachtet werden, dass: +/*N*/ //- die gecachten Informationen verworfen sein koennen (GetPara() == 0) +/*N*/ //- das ein Follow gemeint sein kann +/*N*/ //- das die Kette der Follows dynamisch waechst; der in den wir +/*N*/ // schliesslich gelangen muss aber Formatiert sein. +/*N*/ +/*N*/ // opt: reading ahead erspart uns ein GetAdjFrmAtPos +/*N*/ const sal_Bool bRightMargin = pCMS && ( MV_RIGHTMARGIN == pCMS->eState ); +/*N*/ const sal_Bool bNoScroll = pCMS && pCMS->bNoScroll; +/*N*/ SwTxtFrm *pFrm = GetAdjFrmAtPos( (SwTxtFrm*)this, rPos, bRightMargin, +/*N*/ bNoScroll ); +/*N*/ pFrm->GetFormatted(); +/*N*/ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper(); +/*N*/ +/*N*/ SWRECTFN ( pFrm ) +/*N*/ const SwTwips nUpperMaxY = (pTmpFrm->*fnRect->fnGetPrtBottom)(); +/*N*/ const SwTwips nFrmMaxY = (pFrm->*fnRect->fnGetPrtBottom)(); +/*N*/ +/*N*/ // nMaxY is an absolute value +/*N*/ SwTwips nMaxY = bVert ? +/*N*/ Max( nFrmMaxY, nUpperMaxY ) : +/*N*/ Min( nFrmMaxY, nUpperMaxY ); +/*N*/ +/*N*/ sal_Bool bRet = sal_False; +/*N*/ +/*N*/ if ( pFrm->IsEmpty() || ! (pFrm->Prt().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos(); +/*N*/ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode(); +/*N*/ short nFirstOffset; +/*N*/ pTxtNd->GetFirstLineOfsWithNum( nFirstOffset ); +/*N*/ +/*N*/ Point aPnt2; +/*N*/ if ( bVert ) +/*N*/ { +/*?*/ if( nFirstOffset > 0 ) +/*?*/ aPnt1.Y() += nFirstOffset; +/*?*/ +/*?*/ if ( aPnt1.X() < nMaxY ) +/*?*/ aPnt1.X() = nMaxY; +/*?*/ aPnt2.X() = aPnt1.X() + pFrm->Prt().Width(); +/*?*/ aPnt2.Y() = aPnt1.Y(); +/*?*/ if( aPnt2.X() < nMaxY ) +/*?*/ aPnt2.X() = nMaxY; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nFirstOffset > 0 ) +/*N*/ aPnt1.X() += nFirstOffset; +/*N*/ +/*N*/ if( aPnt1.Y() > nMaxY ) +/*N*/ aPnt1.Y() = nMaxY; +/*N*/ aPnt2.X() = aPnt1.X(); +/*N*/ aPnt2.Y() = aPnt1.Y() + pFrm->Prt().Height(); +/*N*/ if( aPnt2.Y() > nMaxY ) +/*N*/ aPnt2.Y() = nMaxY; +/*N*/ } +/*N*/ +/*N*/ rOrig = SwRect( aPnt1, aPnt2 ); +/*N*/ +/*N*/ if ( pCMS ) +/*N*/ { +/*N*/ pCMS->aRealHeight.X() = 0; +/*N*/ pCMS->aRealHeight.Y() = bVert ? -rOrig.Width() : rOrig.Height(); +/*N*/ } +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ if ( pFrm->IsRightToLeft() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchLTRtoRTL( rOrig ); +/*N*/ #endif +/*N*/ +/*N*/ bRet = sal_True; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pFrm->HasPara() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ SwFrmSwapper aSwapper( pFrm, sal_True ); +/*N*/ if ( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nMaxY = pFrm->SwitchVerticalToHorizontal( nMaxY ); +/*N*/ +/*N*/ sal_Bool bGoOn = sal_True; +/*N*/ xub_StrLen nOffset = rPos.nContent.GetIndex(); +/*N*/ xub_StrLen nNextOfst; +/*N*/ +/*N*/ do +/*N*/ { +/*N*/ { +/*N*/ SwTxtSizeInfo aInf( pFrm ); +/*N*/ SwTxtCursor aLine( pFrm, &aInf ); +/*N*/ nNextOfst = aLine.GetEnd(); +/*N*/ // Siehe Kommentar in AdjustFrm +/*N*/ // 1170: das letzte Zeichen der Zeile mitnehmen? +/*N*/ bRet = bRightMargin ? aLine.GetEndCharRect( &rOrig, nOffset, pCMS, nMaxY ) +/*N*/ : aLine.GetCharRect( &rOrig, nOffset, pCMS, nMaxY ); +/*N*/ } +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ if ( pFrm->IsRightToLeft() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchLTRtoRTL( rOrig ); +/*N*/ #endif +/*N*/ if ( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchHorizontalToVertical( rOrig ); +/*N*/ +/*N*/ if( pFrm->IsUndersized() && pCMS && !pFrm->GetNext() && +/*N*/ (rOrig.*fnRect->fnGetBottom)() == nUpperMaxY && +/*N*/ pFrm->GetOfst() < nOffset && +/*N*/ !pFrm->IsFollow() && !bNoScroll && +/*N*/ pFrm->GetTxtNode()->GetTxt().Len() != nNextOfst ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ bGoOn = lcl_ChangeOffset( pFrm, nNextOfst ); +/*N*/ else +/*N*/ bGoOn = sal_False; +/*N*/ } while ( bGoOn ); +/*N*/ +/*N*/ if ( pCMS ) +/*N*/ { +/*N*/ #ifdef BIDI +/*N*/ if ( pFrm->IsRightToLeft() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( pCMS->b2Lines && pCMS->p2Lines) +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if ( bVert ) +/*N*/ { +/*?*/ if ( pCMS->bRealHeight ) +/*?*/ { +/*?*/ pCMS->aRealHeight.Y() = -pCMS->aRealHeight.Y(); +/*?*/ if ( pCMS->aRealHeight.Y() < 0 ) +/*?*/ { +/*?*/ // writing direction is from top to bottom +/*?*/ pCMS->aRealHeight.X() = ( rOrig.Width() - +/*?*/ pCMS->aRealHeight.X() + +/*?*/ pCMS->aRealHeight.Y() ); +/*?*/ } +/*?*/ } +/*?*/ if( pCMS->b2Lines && pCMS->p2Lines) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pFrm->SwitchHorizontalToVertical( pCMS->p2Lines->aLine ); +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ } +/*N*/ } +/*N*/ if( bRet ) +/*N*/ { +/*N*/ SwPageFrm *pPage = pFrm->FindPageFrm(); +/*N*/ ASSERT( pPage, "Text esaped from page?" ); +/*N*/ const SwTwips nOrigTop = (rOrig.*fnRect->fnGetTop)(); +/*N*/ const SwTwips nPageTop = (pPage->Frm().*fnRect->fnGetTop)(); +/*N*/ const SwTwips nPageBott = (pPage->Frm().*fnRect->fnGetBottom)(); +/*N*/ +/*N*/ // Following situation: if the frame is in an invalid sectionframe, +/*N*/ // it's possible that the frame is outside the page. If we restrict +/*N*/ // the cursor position to the page area, we enforce the formatting +/*N*/ // of the page, of the section frame and the frame himself. +/*N*/ if( (*fnRect->fnYDiff)( nPageTop, nOrigTop ) > 0 ) +/*N*/ (rOrig.*fnRect->fnSetTop)( nPageTop ); +/*N*/ +/*N*/ if ( (*fnRect->fnYDiff)( nOrigTop, nPageBott ) > 0 ) +/*?*/ (rOrig.*fnRect->fnSetTop)( nPageBott ); +/*N*/ } +/*N*/ +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::GetAutoPos() + *************************************************************************/ + +/* + * GetAutoPos() findet die Characterzelle des Characters, dass + * durch aPos beschrieben wird und wird von autopositionierten Rahmen genutzt. + */ + +/*N*/ sal_Bool SwTxtFrm::GetAutoPos( SwRect& rOrig, const SwPosition &rPos ) const +/*N*/ { +/*N*/ if( IsHiddenNow() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ xub_StrLen nOffset = rPos.nContent.GetIndex(); +/*N*/ SwTxtFrm *pFrm = ((SwTxtFrm*)this)->GetFrmAtOfst( nOffset ); +/*N*/ +/*N*/ pFrm->GetFormatted(); +/*N*/ const SwFrm* pTmpFrm = (SwFrm*)pFrm->GetUpper(); +/*N*/ +/*N*/ SWRECTFN( pTmpFrm ) +/*N*/ SwTwips nUpperMaxY = (pTmpFrm->*fnRect->fnGetPrtBottom)(); +/*N*/ +/*N*/ // nMaxY is in absolute value +/*N*/ SwTwips nMaxY = bVert ? +/*N*/ Max( (pFrm->*fnRect->fnGetPrtBottom)(), nUpperMaxY ) : +/*N*/ Min( (pFrm->*fnRect->fnGetPrtBottom)(), nUpperMaxY ); +/*N*/ +/*N*/ if ( pFrm->IsEmpty() || ! (pFrm->Prt().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ Point aPnt1 = pFrm->Frm().Pos() + pFrm->Prt().Pos(); +/*N*/ Point aPnt2; +/*N*/ if ( bVert ) +/*N*/ { +/*?*/ if ( aPnt1.X() < nMaxY ) +/*?*/ aPnt1.X() = nMaxY; +/*?*/ aPnt2.X() = aPnt1.X() + pFrm->Prt().Width(); +/*?*/ aPnt2.Y() = aPnt1.Y(); +/*?*/ if( aPnt2.X() < nMaxY ) +/*?*/ aPnt2.X() = nMaxY; +/*?*/ } +/*?*/ else +/*?*/ { +/*N*/ if( aPnt1.Y() > nMaxY ) +/*N*/ aPnt1.Y() = nMaxY; +/*N*/ aPnt2.X() = aPnt1.X(); +/*N*/ aPnt2.Y() = aPnt1.Y() + pFrm->Prt().Height(); +/*N*/ if( aPnt2.Y() > nMaxY ) +/*N*/ aPnt2.Y() = nMaxY; +/*N*/ } +/*N*/ rOrig = SwRect( aPnt1, aPnt2 ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ else +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 + return FALSE; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::_GetCrsrOfst() + *************************************************************************/ + +// Minimaler Abstand von nichtleeren Zeilen etwas weniger als 2 cm +#define FILL_MIN_DIST 1100 + +struct SwFillData +{ + SwRect aFrm; + const SwCrsrMoveState *pCMS; + SwPosition* pPos; + const Point& rPoint; + SwTwips nLineWidth; + sal_Bool bFirstLine : 1; + sal_Bool bInner : 1; + sal_Bool bColumn : 1; + sal_Bool bEmpty : 1; + SwFillData( const SwCrsrMoveState *pC, SwPosition* pP, const SwRect& rR, + const Point& rPt ) : aFrm( rR ), pCMS( pC ), pPos( pP ), rPoint( rPt ), + nLineWidth( 0 ), bFirstLine( sal_True ), bInner( sal_False ), bColumn( sal_False ), + bEmpty( sal_True ){} + SwFillMode Mode() const { return pCMS->pFill->eMode; } + long X() const { return rPoint.X(); } + long Y() const { return rPoint.Y(); } + long Left() const { return aFrm.Left(); } + long Right() const { return aFrm.Right(); } + long Bottom() const { return aFrm.Bottom(); } + SwRect& Frm() { return aFrm; } + SwFillCrsrPos &Fill() const { return *pCMS->pFill; } + void SetTab( MSHORT nNew ) { pCMS->pFill->nTabCnt = nNew; } + void SetSpace( MSHORT nNew ) { pCMS->pFill->nSpaceCnt = nNew; } + void SetOrient( const SwHoriOrient eNew ){ pCMS->pFill->eOrient = eNew; } +}; + +/*N*/ sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint, +/*N*/ const sal_Bool bChgFrm, const SwCrsrMoveState* pCMS ) const +/*N*/ { +/*N*/ // 8804: _GetCrsrOfst wird vom GetCrsrOfst und GetKeyCrsrOfst gerufen. +/*N*/ // In keinem Fall nur ein return sal_False. +/*N*/ +/*N*/ if( IsLocked() || IsHiddenNow() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ ((SwTxtFrm*)this)->GetFormatted(); +/*N*/ +/*N*/ Point aOldPoint( rPoint ); +/*N*/ +/*N*/ if ( IsVertical() ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ if ( IsRightToLeft() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 SwitchRTLtoLTR( (Point&)rPoint ); +/*N*/ #endif +/*N*/ +/*N*/ SwFillData *pFillData = ( pCMS && pCMS->pFill ) ? +/*N*/ new SwFillData( pCMS, pPos, Frm(), rPoint ) : NULL; +/*N*/ +/*N*/ if ( IsEmpty() ) +/*N*/ { +/*N*/ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode(); +/*N*/ pPos->nNode = *pTxtNd; +/*N*/ pPos->nContent.Assign( pTxtNd, 0 ); +/*N*/ if( pCMS && pCMS->bFieldInfo ) +/*N*/ { +/*?*/ SwTwips nDiff = rPoint.X() - Frm().Left() - Prt().Left(); +/*?*/ if( nDiff > 50 || nDiff < 0 ) +/*?*/ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTxtSizeInfo aInf( (SwTxtFrm*)this ); +/*N*/ SwTxtCursor aLine( ((SwTxtFrm*)this), &aInf ); +/*N*/ +/*N*/ // Siehe Kommentar in AdjustFrm() +/*N*/ SwTwips nMaxY = Frm().Top() + Prt().Top() + Prt().Height(); +/*N*/ aLine.TwipsToLine( rPoint.Y() ); +/*N*/ while( aLine.Y() + aLine.GetLineHeight() > nMaxY ) +/*N*/ { +///*?*/ DBG_LOOP; +/*?*/ if( !aLine.Prev() ) +/*?*/ break; +/*N*/ } +/*N*/ +/*N*/ if( aLine.GetDropLines() >= aLine.GetLineNr() && 1 != aLine.GetLineNr() +/*N*/ && rPoint.X() < aLine.FirstLeft() + aLine.GetDropLeft() ) +/*N*/ while( aLine.GetLineNr() > 1 ) +/*N*/ aLine.Prev(); +/*N*/ +/*N*/ xub_StrLen nOffset = aLine.GetCrsrOfst( pPos, rPoint, bChgFrm, pCMS ); +/*N*/ +/*N*/ if( pCMS && pCMS->eState == MV_NONE && aLine.GetEnd() == nOffset ) +/*?*/ ((SwCrsrMoveState*)pCMS)->eState = MV_RIGHTMARGIN; +/*N*/ +/*N*/ // 6776: pPos ist ein reiner IN-Parameter, der nicht ausgewertet werden darf. +/*N*/ // Das pIter->GetCrsrOfst returnt aus einer Verschachtelung mit STRING_LEN. +/*N*/ // Wenn SwTxtIter::GetCrsrOfst von sich aus weitere GetCrsrOfst +/*N*/ // ruft, so aendert sich nNode der Position. In solchen Faellen +/*N*/ // darf pPos nicht berechnet werden. +/*N*/ if( STRING_LEN != nOffset ) +/*N*/ { +/*N*/ #ifdef USED +/*N*/ // 8626: bei Up/Down darf diese Zeile nicht verlassen werden. +/*N*/ if( pCMS && MV_UPDOWN == pCMS->eState ) +/*N*/ { +/*N*/ const xub_StrLen nEnd = aLine.GetEnd(); +/*N*/ if( nOffset >= nEnd && nEnd ) +/*N*/ { +/*N*/ // Man muss hinter das letzte Zeichen kommen duerfen?! +/*N*/ nOffset = nEnd - 1; // UnitUp-Korrektur +/*N*/ } +/*N*/ else +/*N*/ if( nOffset < aLine.GetStart() ) +/*N*/ nOffset = aLine.GetStart(); // UnitDown-Korrektur +/*N*/ } +/*N*/ #endif +/*N*/ SwTxtNode* pTxtNd = ((SwTxtFrm*)this)->GetTxtNode(); +/*N*/ pPos->nNode = *pTxtNd; +/*N*/ pPos->nContent.Assign( pTxtNd, nOffset ); +/*N*/ if( pFillData ) +/*N*/ { +/*N*/ if( pTxtNd->GetTxt().Len() > nOffset || +/*N*/ rPoint.Y() < Frm().Top() ) +/*N*/ pFillData->bInner = sal_True; +/*N*/ pFillData->bFirstLine = aLine.GetLineNr() < 2; +/*N*/ if( pTxtNd->GetTxt().Len() ) +/*N*/ { +/*?*/ pFillData->bEmpty = sal_False; +/*?*/ pFillData->nLineWidth = aLine.GetCurr()->Width(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ sal_Bool bChgFillData = sal_False; +/*N*/ if( pFillData && FindPageFrm()->Frm().IsInside( aOldPoint ) ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ if ( IsVertical() ) +/*N*/ { +/*N*/ if ( bChgFillData ) +/*N*/ SwitchHorizontalToVertical( pFillData->Fill().aCrsr.Pos() ); +/*N*/ ((SwTxtFrm*)this)->SwapWidthAndHeight(); +/*N*/ } +/*N*/ +/*N*/ if ( IsRightToLeft() && bChgFillData ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ (Point&)rPoint = aOldPoint; +/*N*/ delete pFillData; +/*N*/ +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * virtual SwTxtFrm::GetCrsrOfst() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint, +/*N*/ const SwCrsrMoveState* pCMS ) const +/*N*/ { +/*N*/ MSHORT nChgFrm = 2; +/*N*/ if( pCMS ) +/*N*/ { +/*N*/ if( MV_UPDOWN == pCMS->eState ) +/*N*/ nChgFrm = 0; +/*N*/ else if( MV_SETONLYTEXT == pCMS->eState || +/*N*/ MV_TBLSEL == pCMS->eState ) +/*N*/ nChgFrm = 1; +/*N*/ } +/*N*/ return _GetCrsrOfst( pPos, rPoint, nChgFrm != 0, pCMS ); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::LeftMargin() + *************************************************************************/ + +/* + * Layout-orientierte Cursorbewegungen + */ + +/* + * an den Zeilenanfang + */ + + +/************************************************************************* + * SwTxtFrm::RightMargin() + *************************************************************************/ + +/* + * An das Zeilenende:Das ist die Position vor dem letzten + * Character in der Zeile. Ausnahme: In der letzten Zeile soll + * der Cursor auch hinter dem letzten Character stehen koennen, + * um Text anhaengen zu koennen. + * + */ + + +/************************************************************************* + * SwTxtFrm::_UnitUp() + *************************************************************************/ + +//Die beiden folgenden Methoden versuchen zunaechst den Crsr in die +//nachste/folgende Zeile zu setzen. Gibt es im Frame keine vorhergehende/ +//folgende Zeile, so wird der Aufruf an die Basisklasse weitergeleitet. +//Die Horizontale Ausrichtung des Crsr wird hinterher von der CrsrShell +//vorgenommen. + +class SwSetToRightMargin +{ + sal_Bool bRight; +public: + inline SwSetToRightMargin() : bRight( sal_False ) { } + inline ~SwSetToRightMargin() { SwTxtCursor::SetRightMargin( bRight ); } + inline void SetRight( const sal_Bool bNew ) { bRight = bNew; } +}; + + +// +// Used for Bidi. nPos is the logical position in the string, bLeft indicates +// if left arrow or right arrow was pressed. The return values are: +// nPos: the new visual position +// bLeft: whether the break iterator has to add or subtract from the +// current position + + +/************************************************************************* + * SwTxtFrm::_UnitDown() + *************************************************************************/ + + +/************************************************************************* + * virtual SwTxtFrm::UnitUp() + *************************************************************************/ + + +/************************************************************************* + * virtual SwTxtFrm::UnitDown() + *************************************************************************/ + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_frmform.cxx b/binfilter/bf_sw/source/core/text/sw_frmform.cxx new file mode 100644 index 000000000000..481b5aab6c63 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_frmform.cxx @@ -0,0 +1,2088 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_svx/keepitem.hxx> +#include <bf_svx/hyznitem.hxx> + +#include <pagefrm.hxx> // ChangeFtnRef +#include <dflyobj.hxx> // SwVirtFlyDrawObj + +#include <horiornt.hxx> + +#include <ftnfrm.hxx> // SwFtnFrm +#include <paratr.hxx> +#include <viewopt.hxx> // SwViewOptions +#include <viewsh.hxx> // ViewShell +#include <frmatr.hxx> +#include <flyfrms.hxx> +#include <frmsh.hxx> +#include <txtcfg.hxx> +#include <itrform2.hxx> // SwTxtFormatter +#include <widorp.hxx> // Widows and Orphans +#include <txtcache.hxx> +#include <sectfrm.hxx> // SwSectionFrm + +namespace binfilter { + +extern FASTBOOL IsInProgress( const SwFlyFrm *pFly ); + +class FormatLevel +{ + static MSHORT nLevel; +public: + inline FormatLevel() { ++nLevel; } + inline ~FormatLevel() { --nLevel; } + inline MSHORT GetLevel() const { return nLevel; } + static sal_Bool LastLevel() { return 10 < nLevel; } +}; +MSHORT FormatLevel::nLevel = 0; + +/************************************************************************* + * ValidateTxt/Frm() + *************************************************************************/ + +/*N*/ void ValidateTxt( SwFrm *pFrm ) // Freund vom Frame +/*N*/ { +/*N*/ if ( ( ! pFrm->IsVertical() && +/*N*/ pFrm->Frm().Width() == pFrm->GetUpper()->Prt().Width() ) || +/*N*/ pFrm->IsVertical() && +/*N*/ pFrm->Frm().Height() == pFrm->GetUpper()->Prt().Height() ) +/*N*/ pFrm->bValidSize = sal_True; +/* + pFrm->bValidPrtArea = sal_True; + //Die Position validieren um nicht unnoetige (Test-)Moves zu provozieren. + //Dabei darf allerdings nicht eine tatsaechlich falsche Coordinate + //validiert werden. + if ( !pFrm->bValidPos ) + { + //Leider muessen wir dazu die korrekte Position berechnen. + Point aOld( pFrm->Frm().Pos() ); + pFrm->MakePos(); + if ( aOld != pFrm->Pos() ) + { + pFrm->Frm().Pos( aOld ); + pFrm->bValidPos = sal_False; + } + } +*/ +/*N*/ } + +/*N*/ void SwTxtFrm::ValidateFrm() +/*N*/ { +/*N*/ // Umgebung validieren, um Oszillationen zu verhindern. +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*M*/ if ( !IsInFly() && !IsInTab() ) +/*N*/ { //Innerhalb eines Flys nur this validieren, der Rest sollte eigentlich +/*N*/ //nur fuer Fussnoten notwendig sein und die gibt es innerhalb von +/*N*/ //Flys nicht. Fix fuer 5544 +/*N*/ SwSectionFrm* pSct = FindSctFrm(); +/*N*/ if( pSct ) +/*N*/ { +/*?*/ if( !pSct->IsColLocked() ) +/*?*/ pSct->ColLock(); +/*?*/ else +/*?*/ pSct = NULL; +/*N*/ } +/*N*/ +/*N*/ SwFrm *pUp = GetUpper(); +/*N*/ pUp->Calc(); +/*N*/ if( pSct ) +/*?*/ pSct->ColUnlock(); +/*N*/ } +/*N*/ ValidateTxt( this ); +/*N*/ +/*N*/ //MA: mindestens das MustFit-Flag muessen wir retten! +/*N*/ ASSERT( HasPara(), "ResetPreps(), missing ParaPortion." ); +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ const sal_Bool bMustFit = pPara->IsPrepMustFit(); +/*N*/ ResetPreps(); +/*N*/ pPara->SetPrepMustFit( bMustFit ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/************************************************************************* + * ValidateBodyFrm() + *************************************************************************/ + +// nach einem RemoveFtn muss der BodyFrm und alle innenliegenden kalkuliert +// werden, damit die DeadLine richtig sitzt. +// Erst wird nach aussen hin gesucht, beim Rueckweg werden alle kalkuliert. + +/*N*/ void _ValidateBodyFrm( SwFrm *pFrm ) +/*N*/ { +/*N*/ if( pFrm && !pFrm->IsCellFrm() ) +/*N*/ { +/*N*/ if( !pFrm->IsBodyFrm() && pFrm->GetUpper() ) +/*N*/ _ValidateBodyFrm( pFrm->GetUpper() ); +/*N*/ if( !pFrm->IsSctFrm() ) +/*N*/ pFrm->Calc(); +/*N*/ else +/*N*/ { +/*N*/ sal_Bool bOld = ((SwSectionFrm*)pFrm)->IsCntntLocked(); +/*N*/ ((SwSectionFrm*)pFrm)->SetCntntLock( sal_True ); +/*N*/ pFrm->Calc(); +/*N*/ if( !bOld ) +/*N*/ ((SwSectionFrm*)pFrm)->SetCntntLock( sal_False ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void SwTxtFrm::ValidateBodyFrm() +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ //siehe Kommtar in ValidateFrm() +/*M*/ if ( !IsInFly() && !IsInTab() && +/*M*/ !( IsInSct() && FindSctFrm()->Lower()->IsColumnFrm() ) ) +/*N*/ _ValidateBodyFrm( GetUpper() ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FindBodyFrm() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::FindBodyFrm() + *************************************************************************/ + +/*N*/ const SwBodyFrm *SwTxtFrm::FindBodyFrm() const +/*N*/ { +/*N*/ if ( IsInDocBody() ) +/*N*/ { +/*N*/ const SwFrm *pFrm = GetUpper(); +/*N*/ while( pFrm && !pFrm->IsBodyFrm() ) +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ return (const SwBodyFrm*)pFrm; +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcFollow() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::CalcFollow( const xub_StrLen nTxtOfst ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ ASSERT( HasFollow(), "CalcFollow: missing Follow." ); +/*N*/ +/*N*/ SwTxtFrm *pFollow = GetFollow(); +/*N*/ +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ sal_Bool bFollowFld = pPara ? pPara->IsFollowField() : sal_False; +/*N*/ +/*N*/ if( !pFollow->GetOfst() || pFollow->GetOfst() != nTxtOfst || +/*N*/ bFollowFld || pFollow->IsFieldFollow() || +/*N*/ ( pFollow->IsVertical() && !pFollow->Prt().Width() ) || +/*N*/ ( ! pFollow->IsVertical() && !pFollow->Prt().Height() ) ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ const SwFrm *pOldUp = GetUpper(); +/*N*/ #endif +/*N*/ +/*N*/ SWRECTFN ( this ) +/*N*/ SwTwips nOldBottom = (GetUpper()->Frm().*fnRect->fnGetBottom)(); +/*N*/ SwTwips nMyPos = (Frm().*fnRect->fnGetTop)(); +/*N*/ +/*N*/ const SwPageFrm *pPage = 0; +/*N*/ sal_Bool bOldInvaCntnt, +/*N*/ bOldInvaLayout; +/*N*/ if ( !IsInFly() && GetNext() ) +/*N*/ { +/*N*/ pPage = FindPageFrm(); +/*N*/ //Minimieren - sprich ggf. zuruecksetzen - der Invalidierungen s.u. +/*N*/ bOldInvaCntnt = pPage->IsInvalidCntnt(); +/*N*/ bOldInvaLayout = pPage->IsInvalidLayout(); +/*N*/ } +/*N*/ +/*N*/ pFollow->_SetOfst( nTxtOfst ); +/*N*/ pFollow->SetFieldFollow( bFollowFld ); +/*N*/ if( HasFtn() || pFollow->HasFtn() ) +/*N*/ { +/*?*/ ValidateFrm(); +/*?*/ ValidateBodyFrm(); +/*?*/ if( pPara ) +/*?*/ { +/*?*/ *(pPara->GetReformat()) = SwCharRange(); +/*?*/ *(pPara->GetDelta()) = 0; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ //Der Fussnotenbereich darf sich keinesfalls vergrossern. +/*N*/ SwSaveFtnHeight aSave( FindFtnBossFrm( sal_True ), LONG_MAX ); +/*N*/ +/*N*/ pFollow->CalcFtnFlag(); +/*N*/ if ( !pFollow->GetNext() && !pFollow->HasFtn() ) +/*N*/ nOldBottom = bVert ? 0 : LONG_MAX; +/*N*/ +/*N*/ while( sal_True ) +/*N*/ { +/*N*/ if( !FormatLevel::LastLevel() ) +/*N*/ { +/*N*/ // Weenn der Follow in einem spaltigen Bereich oder einem +/*N*/ // spaltigen Rahmen steckt, muss zunaechst dieser kalkuliert +/*N*/ // werden, da das FormatWidthCols() nicht funktioniert, wenn +/*N*/ // es aus dem MakeAll des _gelockten_ Follows heraus gerufen +/*N*/ // wird. +/*N*/ SwSectionFrm* pSct = pFollow->FindSctFrm(); +/*N*/ if( pSct && !pSct->IsAnLower( this ) ) +/*N*/ { +/*?*/ if( pSct->GetFollow() ) +/*?*/ pSct->SimpleFormat(); +/*?*/ else if( ( pSct->IsVertical() && !pSct->Frm().Width() ) || +/*?*/ ( ! pSct->IsVertical() && !pSct->Frm().Height() ) ) +/*?*/ break; +/*N*/ } +/*N*/ // OD 14.03.2003 #i11760# - intrinsic format of follow is controlled. +/*N*/ if ( FollowFormatAllowed() ) +/*N*/ { +/*N*/ // OD 14.03.2003 #i11760# - no nested format of follows, if +/*N*/ // text frame is contained in a column frame. +/*N*/ // Thus, forbid intrinsic format of follow. +/*N*/ { +/*N*/ bool bIsFollowInColumn = false; +/*N*/ SwFrm* pFollowUpper = pFollow->GetUpper(); +/*N*/ while ( pFollowUpper ) +/*N*/ { +/*N*/ if ( pFollowUpper->IsColumnFrm() ) +/*N*/ { +/*N*/ bIsFollowInColumn = true; +/*N*/ break; +/*N*/ } +/*N*/ if ( pFollowUpper->IsPageFrm() || +/*N*/ pFollowUpper->IsFlyFrm() ) +/*N*/ { +/*N*/ break; +/*N*/ } +/*N*/ pFollowUpper = pFollowUpper->GetUpper(); +/*N*/ } +/*N*/ if ( bIsFollowInColumn ) +/*N*/ { +/*N*/ pFollow->ForbidFollowFormat(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFollow->Calc(); +/*N*/ // Der Follow merkt anhand seiner Frm().Height(), dass was schief +/*N*/ // gelaufen ist. +/*N*/ ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: cheesy follow" ); +/*N*/ if( pFollow->GetPrev() ) +/*N*/ { +/*?*/ pFollow->Prepare( PREP_CLEAR ); +/*?*/ pFollow->Calc(); +/*?*/ ASSERT( !pFollow->GetPrev(), "SwTxtFrm::CalcFollow: very cheesy follow" ); +/*N*/ } +/*N*/ +/*N*/ // OD 14.03.2003 #i11760# - reset control flag for follow format. +/*N*/ pFollow->AllowFollowFormat(); +/*N*/ } +/*N*/ +/*N*/ //Sicherstellen, dass der Follow gepaintet wird. +/*N*/ pFollow->SetCompletePaint(); +/*N*/ } +/*N*/ +/*N*/ pPara = GetPara(); +/*N*/ //Solange der Follow wg. Orphans Zeilen angefordert, bekommt er +/*N*/ //diese und wird erneut formatiert, falls moeglich. +/*N*/ if( pPara && pPara->IsPrepWidows() ) +/*N*/ CalcPreps(); +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ if( HasFtn() || pFollow->HasFtn() ) +/*N*/ { +/*?*/ ValidateBodyFrm(); +/*?*/ ValidateFrm(); +/*?*/ if( pPara ) +/*?*/ { +/*?*/ *(pPara->GetReformat()) = SwCharRange(); +/*?*/ *(pPara->GetDelta()) = 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( pPage ) +/*N*/ { +/*N*/ if ( !bOldInvaCntnt ) +/*N*/ pPage->ValidateCntnt(); +/*N*/ if ( !bOldInvaLayout && !IsInSct() ) +/*N*/ pPage->ValidateLayout(); +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ ASSERT( pOldUp == GetUpper(), "SwTxtFrm::CalcFollow: heavy follow" ); +/*N*/ #endif +/*N*/ +/*N*/ const long nRemaining = +/*N*/ - (GetUpper()->Frm().*fnRect->fnBottomDist)( nOldBottom ); +/*N*/ if ( nRemaining > 0 && !GetUpper()->IsSctFrm() && +/*N*/ nRemaining != ( bVert ? +/*N*/ nMyPos - Frm().Right() : +/*N*/ Frm().Top() - nMyPos ) ) +/*N*/ { +/*N*/ UNDO_SWAP( this ) +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::AdjustFrm() + *************************************************************************/ + +/*N*/ void SwTxtFrm::AdjustFrm( const SwTwips nChgHght, sal_Bool bHasToFit ) +/*N*/ { +/*N*/ if( IsUndersized() ) +/*N*/ { +/*N*/ if( GetOfst() && !IsFollow() ) // ein gescrollter Absatz (undersized) +/*N*/ return; +/*N*/ SetUndersized( nChgHght == 0 || bHasToFit ); +/*N*/ } +/*N*/ +/*N*/ // AdjustFrm is called with a swapped frame during +/*N*/ // formatting but the frame is not swapped during FormatEmpty +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ SWRECTFN ( this ) +/*N*/ +/*N*/ // Die Size-Variable des Frames wird durch Grow inkrementiert +/*N*/ // oder durch Shrink dekrementiert. Wenn die Groesse +/*N*/ // unveraendert ist, soll nichts passieren! +/*N*/ if( nChgHght >= 0) +/*N*/ { +/*N*/ SwTwips nChgHeight = nChgHght; +/*N*/ if( nChgHght && !bHasToFit ) +/*N*/ { +/*N*/ if( IsInFtn() && !IsInSct() ) +/*N*/ { +/*N*/ SwTwips nReal = Grow( nChgHght PHEIGHT, sal_True ); +/*N*/ if( nReal < nChgHght ) +/*N*/ { +/*?*/ SwTwips nBot = (*fnRect->fnYInc)( (Frm().*fnRect->fnGetBottom)(), +/*?*/ nChgHght - nReal ); +/*?*/ SwFrm* pCont = FindFtnFrm()->GetUpper(); +/*?*/ +/*?*/ if( (pCont->Frm().*fnRect->fnBottomDist)( nBot ) > 0 ) +/*?*/ { +/*?*/ (Frm().*fnRect->fnAddBottom)( nChgHght ); +/*?*/ if( bVert ) +/*?*/ Prt().SSize().Width() += nChgHght; +/*?*/ else +/*?*/ Prt().SSize().Height() += nChgHght; +/*?*/ UNDO_SWAP( this ) +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ Grow( nChgHght PHEIGHT ); +/*N*/ +/*N*/ if ( IsInFly() ) +/*N*/ { +/*N*/ //MA 06. May. 93: Wenn einer der Upper ein Fly ist, so ist es +/*N*/ //sehr wahrscheinlich, dass dieser Fly durch das Grow seine +/*N*/ //Position veraendert - also muss auch meine Position korrigiert +/*N*/ //werden (sonst ist die Pruefung s.u. nicht aussagekraeftig). +/*N*/ //Die Vorgaenger muessen berechnet werden, damit die Position +/*N*/ //korrekt berechnet werden kann. +/*N*/ if ( GetPrev() ) +/*N*/ { +/*N*/ SwFrm *pPre = GetUpper()->Lower(); +/*N*/ do +/*N*/ { pPre->Calc(); +/*N*/ pPre = pPre->GetNext(); +/*N*/ } while ( pPre && pPre != this ); +/*N*/ } +/*N*/ const Point aOldPos( Frm().Pos() ); +/*N*/ MakePos(); +/*N*/ if ( aOldPos != Frm().Pos() ) +/*N*/ CalcFlys( sal_True ); //#43679# Fly in Fly in ... +/*N*/ } +/*N*/ nChgHeight = 0; +/*N*/ } +/*N*/ // Ein Grow() wird von der Layout-Seite immer akzeptiert, +/*N*/ // also auch, wenn die FixSize des umgebenden Layoutframes +/*N*/ // dies nicht zulassen sollte. Wir ueberpruefen diesen +/*N*/ // Fall und korrigieren die Werte. +/*N*/ // MA 06. May. 93: Der Frm darf allerdings auch im Notfall nicht +/*N*/ // weiter geschrumpft werden als es seine Groesse zulaesst. +/*N*/ SwTwips nRstHeight; +/*N*/ if ( IsVertical() ) +/*N*/ { +/*?*/ ASSERT( ! IsSwapped(),"Swapped frame while calculating nRstHeight" ); +/*?*/ nRstHeight = Frm().Left() + Frm().Width() - +/*?*/ ( GetUpper()->Frm().Left() + GetUpper()->Prt().Left() ); +/*N*/ } +/*N*/ else +/*N*/ nRstHeight = GetUpper()->Frm().Top() +/*N*/ + GetUpper()->Prt().Top() +/*N*/ + GetUpper()->Prt().Height() +/*N*/ - Frm().Top(); +/*N*/ +/*N*/ //In Tabellenzellen kann ich mir evtl. noch ein wenig dazuholen, weil +/*N*/ //durch eine vertikale Ausrichtung auch oben noch Raum sein kann. +/*N*/ if ( IsInTab() ) +/*N*/ { +/*N*/ long nAdd = (*fnRect->fnYDiff)( (GetUpper()->Lower()->Frm().*fnRect->fnGetTop)(), +/*N*/ (GetUpper()->*fnRect->fnGetPrtTop)() ); +/*N*/ ASSERT( nAdd >= 0, "Ey" ); +/*N*/ nRstHeight += nAdd; +/*N*/ } +/*N*/ +/* ------------------------------------ + * #50964#: nRstHeight < 0 bedeutet, dass der TxtFrm komplett ausserhalb seines + * Upper liegt. Dies kann passieren, wenn er innerhalb eines FlyAtCntFrm liegt, der + * durch das Grow() die Seite gewechselt hat. In so einem Fall ist es falsch, der + * folgenden Grow-Versuch durchzufuehren. Im Bugfall fuehrte dies sogar zur + * Endlosschleife. + * -----------------------------------*/ +/*N*/ SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*N*/ SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ if( nRstHeight < nFrmHeight ) +/*N*/ { +/*N*/ //Kann sein, dass ich die richtige Grosse habe, der Upper aber zu +/*N*/ //klein ist und der Upper noch Platz schaffen kann. +/*N*/ if( ( nRstHeight >= 0 || ( IsInFtn() && IsInSct() ) ) && !bHasToFit ) +/*N*/ nRstHeight += GetUpper()->Grow( nFrmHeight - nRstHeight PHEIGHT ); +/*N*/ // In spaltigen Bereichen wollen wir moeglichst nicht zu gross werden, damit +/*N*/ // nicht ueber GetNextSctLeaf weitere Bereiche angelegt werden. Stattdessen +/*N*/ // schrumpfen wir und notieren bUndersized, damit FormatWidthCols die richtige +/*N*/ // Spaltengroesse ermitteln kann. +/*N*/ if ( nRstHeight < nFrmHeight ) +/*N*/ { +/*N*/ if( bHasToFit || !IsMoveable() || +/*N*/ ( IsInSct() && !FindSctFrm()->MoveAllowed(this) ) ) +/*N*/ { +/*N*/ SetUndersized( sal_True ); +/*N*/ Shrink( Min( ( nFrmHeight - nRstHeight), nPrtHeight ) +/*N*/ PHEIGHT ); +/*N*/ } +/*N*/ else +/*N*/ SetUndersized( sal_False ); +/*N*/ } +/*N*/ } +/*N*/ else if( nChgHeight ) +/*N*/ { +/*?*/ if( nRstHeight - nFrmHeight < nChgHeight ) +/*?*/ nChgHeight = nRstHeight - nFrmHeight; +/*?*/ if( nChgHeight ) +/*?*/ Grow( nChgHeight ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ Shrink( -nChgHght PHEIGHT ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/************************************************************************* + * SwTxtFrm::AdjustFollow() + *************************************************************************/ + +/* AdjustFollow erwartet folgende Situation: + * Der SwTxtIter steht am unteren Ende des Masters, der Offset wird + * im Follow eingestellt. + * nOffset haelt den Offset im Textstring, ab dem der Master abschliesst + * und der Follow beginnt. Wenn er 0 ist, wird der FolgeFrame geloescht. + */ + +/*N*/ void SwTxtFrm::_AdjustFollow( SwTxtFormatter &rLine, +/*N*/ const xub_StrLen nOffset, const xub_StrLen nEnd, +/*N*/ const sal_uInt8 nMode ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ // Wir haben den Rest der Textmasse: alle Follows loeschen +/*N*/ // Sonderfall sind DummyPortions() +/*N*/ // - special cases are controlled by parameter <nMode>. +/*N*/ if( HasFollow() && !(nMode & 1) && nOffset == nEnd ) +/*N*/ { +/*N*/ while( GetFollow() ) +/*N*/ { +/*N*/ if( ((SwTxtFrm*)GetFollow())->IsLocked() ) +/*N*/ { +/*?*/ ASSERT( sal_False, "+SwTxtFrm::JoinFrm: Follow ist locked." ); +/*?*/ UNDO_SWAP( this ) +/*?*/ return; +/*N*/ } +/*N*/ JoinFrm(); +/*N*/ } +/*N*/ UNDO_SWAP( this ) +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ // Tanz auf dem Vulkan: Wir formatieren eben schnell noch einmal +/*N*/ // die letzte Zeile fuer das QuoVadis-Geraffel. Selbstverstaendlich +/*N*/ // kann sich dadurch auch der Offset verschieben: +/*N*/ const xub_StrLen nNewOfst = ( IsInFtn() && ( !GetIndNext() || HasFollow() ) ) ? +/*N*/ rLine.FormatQuoVadis(nOffset) : nOffset; +/*N*/ +/*N*/ if( !(nMode & 1) ) +/*N*/ { +/*N*/ // Wir klauen unseren Follows Textmasse, dabei kann es passieren, +/*N*/ // dass wir einige Follows Joinen muessen. +/*N*/ while( GetFollow() && GetFollow()->GetFollow() && +/*N*/ nNewOfst >= GetFollow()->GetFollow()->GetOfst() ) +/*N*/ { +///*?*/ DBG_LOOP; +/*?*/ JoinFrm(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Der Ofst hat sich verschoben. +/*N*/ if( GetFollow() ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ static sal_Bool bTest = sal_False; +/*N*/ if( !bTest || ( nMode & 1 ) ) +/*N*/ #endif +/*N*/ if ( nMode ) +/*N*/ GetFollow()->ManipOfst( 0 ); +/*N*/ +/*N*/ if ( CalcFollow( nNewOfst ) ) // CalcFollow erst zum Schluss, dort erfolgt ein SetOfst +/*N*/ rLine.SetOnceMore( sal_True ); +/*N*/ } +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/************************************************************************* + * SwTxtFrm::JoinFrm() + *************************************************************************/ + +/*N*/ SwCntntFrm *SwTxtFrm::JoinFrm() +/*N*/ { +/*N*/ ASSERT( GetFollow(), "+SwTxtFrm::JoinFrm: no follow" ); +/*N*/ SwTxtFrm *pFoll = GetFollow(); +/*N*/ +/*N*/ SwTxtFrm *pNxt = pFoll->GetFollow(); +/*N*/ +/*N*/ // Alle Fussnoten des zu zerstoerenden Follows werden auf uns +/*N*/ // umgehaengt. +/*N*/ xub_StrLen nStart = pFoll->GetOfst(); +/*N*/ if ( pFoll->HasFtn() ) +/*N*/ { +/*?*/ const SwpHints *pHints = pFoll->GetTxtNode()->GetpSwpHints(); +/*?*/ if( pHints ) +/*?*/ { +/*?*/ SwFtnBossFrm *pFtnBoss = 0; +/*?*/ SwFtnBossFrm *pEndBoss = 0; +/*?*/ for( MSHORT i = 0; i < pHints->Count(); ++i ) +/*?*/ { +/*?*/ const SwTxtAttr *pHt = (*pHints)[i]; +/*?*/ if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nStart ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( pHt->GetFtn().IsEndNote() ) +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ else if ( pFoll->GetValidPrtAreaFlag() || +/*N*/ pFoll->GetValidSizeFlag() ) +/*N*/ { +/*N*/ pFoll->CalcFtnFlag(); +/*N*/ ASSERT( !pFoll->HasFtn(), "Missing FtnFlag." ); +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ pFoll->MoveFlyInCnt( this, nStart, STRING_LEN ); +/*N*/ pFoll->SetFtn( FALSE ); +/*N*/ pFoll->Cut(); +/*N*/ delete pFoll; +/*N*/ pFollow = pNxt; +/*N*/ return pNxt; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::SplitFrm() + *************************************************************************/ + +/*N*/ SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ // Durch das Paste wird ein Modify() an mich verschickt. +/*N*/ // Damit meine Daten nicht verschwinden, locke ich mich. +/*N*/ SwTxtFrmLocker aLock( this ); +/*N*/ SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm()); +/*N*/ pNew->bIsFollow = sal_True; +/*N*/ +/*N*/ pNew->SetFollow( GetFollow() ); +/*N*/ SetFollow( pNew ); +/*N*/ +/*N*/ pNew->Paste( GetUpper(), GetNext() ); +/*N*/ +/*N*/ // Wenn durch unsere Aktionen Fussnoten in pNew landen, +/*N*/ // so muessen sie umgemeldet werden. +/*N*/ if ( HasFtn() ) +/*N*/ { +/*?*/ const SwpHints *pHints = GetTxtNode()->GetpSwpHints(); +/*?*/ if( pHints ) +/*?*/ { +/*?*/ SwFtnBossFrm *pFtnBoss = 0; +/*?*/ SwFtnBossFrm *pEndBoss = 0; +/*?*/ for( MSHORT i = 0; i < pHints->Count(); ++i ) +/*?*/ { +/*?*/ const SwTxtAttr *pHt = (*pHints)[i]; +/*?*/ if( RES_TXTATR_FTN==pHt->Which() && *pHt->GetStart()>=nTxtPos ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( pHt->GetFtn().IsEndNote() ) +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ else +/*N*/ { +/*N*/ CalcFtnFlag( nTxtPos-1 ); +/*N*/ ASSERT( !HasFtn(), "Missing FtnFlag." ); +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ MoveFlyInCnt( pNew, nTxtPos, STRING_LEN ); +/*N*/ +/*N*/ // Kein SetOfst oder CalcFollow, weil gleich ohnehin ein AdjustFollow folgt. +/*N*/ #ifdef USED +/*N*/ CalcFollow( nNewOfst ); +/*N*/ #endif +/*N*/ +/*N*/ pNew->ManipOfst( nTxtPos ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ return pNew; +/*N*/ } + + +/************************************************************************* + * virtual SwTxtFrm::SetOfst() + *************************************************************************/ + +/*N*/ void SwTxtFrm::_SetOfst( const xub_StrLen nNewOfst ) +/*N*/ { +/*N*/ #ifdef DBGTXT +/*N*/ // Es gibt tatsaechlich einen Sonderfall, in dem ein SetOfst(0) +/*N*/ // zulaessig ist: bug 3496 +/*N*/ ASSERT( nNewOfst, "!SwTxtFrm::SetOfst: missing JoinFrm()." ); +/*N*/ #endif +/*N*/ +/*N*/ // Die Invalidierung unseres Follows ist nicht noetig. +/*N*/ // Wir sind ein Follow, werden gleich formatiert und +/*N*/ // rufen von dort aus das SetOfst() ! +/*N*/ nOfst = nNewOfst; +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ if( pPara ) +/*N*/ { +/*N*/ SwCharRange &rReformat = *(pPara->GetReformat()); +/*N*/ rReformat.Start() = 0; +/*N*/ rReformat.Len() = GetTxt().Len(); +/*N*/ *(pPara->GetDelta()) = rReformat.Len(); +/*N*/ } +/*N*/ InvalidateSize(); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcPreps + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::CalcPreps() +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), "SwTxtFrm::CalcPreps with swapped frame" ); +/*N*/ SWRECTFN( this ); +/*N*/ +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ if ( !pPara ) +/*N*/ return sal_False; +/*N*/ sal_Bool bPrep = pPara->IsPrep(); +/*N*/ sal_Bool bPrepWidows = pPara->IsPrepWidows(); +/*N*/ sal_Bool bPrepAdjust = pPara->IsPrepAdjust(); +/*N*/ sal_Bool bPrepMustFit = pPara->IsPrepMustFit(); +/*N*/ ResetPreps(); +/*N*/ +/*N*/ sal_Bool bRet = sal_False; +/*N*/ if( bPrep && !pPara->GetReformat()->Len() ) +/*N*/ { +/*N*/ // PREP_WIDOWS bedeutet, dass im Follow die Orphans-Regel +/*N*/ // zuschlug. +/*N*/ // Es kann in unguenstigen Faellen vorkommen, dass auch ein +/*N*/ // PrepAdjust vorliegt (3680)! +/*N*/ if( bPrepWidows ) +/*N*/ { +/*N*/ if( !GetFollow() ) +/*N*/ { +/*?*/ ASSERT( GetFollow(), "+SwTxtFrm::CalcPreps: no credits" ); +/*?*/ return sal_False; +/*N*/ } +/*N*/ +/*N*/ // Wir muessen uns auf zwei Faelle einstellen: +/*N*/ // Wir konnten dem Follow noch ein paar Zeilen abgeben, +/*N*/ // -> dann muessen wir schrumpfen +/*N*/ // oder wir muessen auf die naechste Seite +/*N*/ // -> dann lassen wir unseren Frame zu gross werden. +/*N*/ +/*N*/ SwTwips nChgHeight = GetParHeight(); +/*N*/ if( nChgHeight >= (Prt().*fnRect->fnGetHeight)() ) +/*N*/ { +/*N*/ if( bPrepMustFit ) +/*N*/ { +/*?*/ GetFollow()->SetJustWidow( sal_True ); +/*?*/ GetFollow()->Prepare( PREP_CLEAR ); +/*N*/ } +/*N*/ else if ( bVert ) +/*N*/ { +/*?*/ Frm().Width( Frm().Width() + Frm().Left() ); +/*?*/ Prt().Width( Prt().Width() + Frm().Left() ); +/*?*/ Frm().Left( 0 ); +/*?*/ SetWidow( sal_True ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwTwips nTmp = LONG_MAX - (Frm().Top()+10000); +/*N*/ SwTwips nDiff = nTmp - Frm().Height(); +/*N*/ Frm().Height( nTmp ); +/*N*/ Prt().Height( Prt().Height() + nDiff ); +/*N*/ SetWidow( sal_True ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ASSERT( nChgHeight < (Prt().*fnRect->fnGetHeight)(), +/*?*/ "+SwTxtFrm::CalcPrep: wanna shrink" ); +/*?*/ +/*?*/ nChgHeight = (Prt().*fnRect->fnGetHeight)() - nChgHeight; +/*?*/ +/*?*/ GetFollow()->SetJustWidow( sal_True ); +/*?*/ GetFollow()->Prepare( PREP_CLEAR ); +/*?*/ Shrink( nChgHeight PHEIGHT ); +/*?*/ SwRect &rRepaint = *(pPara->GetRepaint()); +/*?*/ +/*?*/ if ( bVert ) +/*?*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ SwRect aRepaint( Frm().Pos() + Prt().Pos(), Prt().SSize() ); +/*?*/ } +/*?*/ else +/*?*/ rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() ); +/*?*/ +/*?*/ // 6792: Rrand < LRand und Repaint +/*?*/ if( 0 >= rRepaint.Width() ) +/*?*/ rRepaint.Width(1); +/*N*/ } +/*N*/ bRet = sal_True; +/*N*/ } +/*N*/ +/*N*/ else if ( bPrepAdjust ) +/*N*/ { +/*N*/ if ( HasFtn() ) +/*N*/ { +/*N*/ if( !CalcPrepFtnAdjust() ) +/*N*/ { +/*?*/ if( bPrepMustFit ) +/*?*/ { +/*?*/ SwTxtLineAccess aAccess( this ); +/*?*/ aAccess.GetPara()->SetPrepMustFit( sal_True ); +/*?*/ } +/*?*/ return sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ SwTxtFormatInfo aInf( this ); +/*N*/ SwTxtFormatter aLine( this, &aInf ); +/*N*/ +/*N*/ WidowsAndOrphans aFrmBreak( this ); +/*N*/ // Egal was die Attribute meinen, bei MustFit wird +/*N*/ // der Absatz im Notfall trotzdem gesplittet... +/*N*/ if( bPrepMustFit ) +/*N*/ { +/*?*/ aFrmBreak.SetKeep( sal_False ); +/*?*/ aFrmBreak.ClrOrphLines(); +/*N*/ } +/*N*/ // Bevor wir FormatAdjust aufrufen muessen wir dafuer +/*N*/ // sorgen, dass die Zeilen, die unten raushaengen +/*N*/ // auch tatsaechlich abgeschnitten werden. +/*N*/ sal_Bool bBreak = aFrmBreak.IsBreakNow( aLine ); +/*N*/ bRet = sal_True; +/*N*/ while( !bBreak && aLine.Next() ) +/*N*/ bBreak = aFrmBreak.IsBreakNow( aLine ); +/*N*/ if( bBreak ) +/*N*/ { +/*N*/ // Es gibt Komplikationen: wenn TruncLines gerufen wird, +/*N*/ // veraendern sich ploetzlich die Bedingungen in +/*N*/ // IsInside, so dass IsBreakNow andere Ergebnisse +/*N*/ // liefern kann. Aus diesem Grund wird rFrmBreak bekannt +/*N*/ // gegeben, dass da wo rLine steht, das Ende erreicht +/*N*/ // ist. Mal sehen, ob's klappt ... +/*N*/ aLine.TruncLines(); +/*N*/ aFrmBreak.SetRstHeight( aLine ); +/*N*/ FormatAdjust( aLine, aFrmBreak, aInf.GetTxt().Len(), aInf.IsStop() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !GetFollow() ) +/*N*/ { +/*N*/ FormatAdjust( aLine, aFrmBreak, +/*N*/ aInf.GetTxt().Len(), aInf.IsStop() ); +/*N*/ } +/*N*/ else if ( !aFrmBreak.IsKeepAlways() ) +/*N*/ { +/*N*/ // Siehe Bug: 2320 +/*N*/ // Vor dem Master wird eine Zeile geloescht, der Follow +/*N*/ // koennte eine Zeile abgeben. +/*N*/ const SwCharRange aFollowRg( GetFollow()->GetOfst(), 1 ); +/*N*/ *(pPara->GetReformat()) += aFollowRg; +/*N*/ // Es soll weitergehen! +/*N*/ bRet = sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ // Eine letzte Ueberpruefung, falls das FormatAdjust() nichts +/*N*/ // brachte, muessen wir amputieren. +/*N*/ if( bPrepMustFit ) +/*N*/ { +/*?*/ const SwTwips nMust = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*?*/ const SwTwips nIs = (Frm().*fnRect->fnGetBottom)(); +/*?*/ +/*?*/ if( bVert && nIs < nMust ) +/*?*/ { +/*?*/ Shrink( nMust - nIs ); +/*?*/ if( Prt().Width() < 0 ) +/*?*/ Prt().Width( 0 ); +/*?*/ SetUndersized( sal_True ); +/*?*/ } +/*?*/ else if ( ! bVert && nIs > nMust ) +/*?*/ { +/*?*/ Shrink( nIs - nMust ); +/*?*/ if( Prt().Height() < 0 ) +/*?*/ Prt().Height( 0 ); +/*?*/ SetUndersized( sal_True ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pPara->SetPrepMustFit( bPrepMustFit ); +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FormatAdjust() + *************************************************************************/ + +// Hier werden die Fussnoten und "als Zeichen"-gebundenen Objekte umgehaengt +#define CHG_OFFSET( pFrm, nNew )\ + {\ + if( pFrm->GetOfst() < nNew )\ + pFrm->MoveFlyInCnt( this, 0, nNew );\ + else if( pFrm->GetOfst() > nNew )\ + MoveFlyInCnt( pFrm, nNew, STRING_LEN );\ + } + +/*N*/ void SwTxtFrm::FormatAdjust( SwTxtFormatter &rLine, +/*N*/ WidowsAndOrphans &rFrmBreak, +/*N*/ const xub_StrLen nStrLen, +/*N*/ const sal_Bool bDummy ) +/*N*/ { +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion(); +/*N*/ +/*N*/ xub_StrLen nEnd = rLine.GetStart(); +/*N*/ +/*N*/ // Wir muessen fuer eindeutige Verhaeltnisse sorgen +/*N*/ // rFrmBreak.SetRstHeight( rLine ); +/*N*/ +/*N*/ // rLine.GetStart(): die letzte Zeile von rLine, +/*N*/ // ist bereits die Zeile, die nicht +/*N*/ // mehr passte. Ihr Anfang ist das Ende des Masters. +/*N*/ // @@@if( !GetFollow() && nEnd < nStrLen ) +/*N*/ // (nEnd < nStrLen || rFrmBreak.IsBreakNow(rLine)); +/*N*/ +/*N*/ sal_Bool bHasToFit = pPara->IsPrepMustFit(); +/*N*/ +/*N*/ // Das StopFlag wird durch Fussnoten gesetzt, +/*N*/ // die auf die naechste Seite wollen. +/*N*/ sal_uInt8 nNew = ( !GetFollow() && nEnd < nStrLen && +/*N*/ ( rLine.IsStop() || ( bHasToFit ? +/*N*/ ( rLine.GetLineNr() > 1 && !rFrmBreak.IsInside( rLine ) ) +/*N*/ : rFrmBreak.IsBreakNow( rLine ) ) ) ) ? 1 : 0; +/*N*/ if( nNew ) +/*N*/ SplitFrm( nEnd ); +/*N*/ +/*N*/ const SwFrm *pBodyFrm = (const SwFrm*)(FindBodyFrm()); +/*N*/ +/*N*/ const long nBodyHeight = pBodyFrm ? ( IsVertical() ? +/*N*/ pBodyFrm->Frm().Width() : +/*N*/ pBodyFrm->Frm().Height() ) : 0; +/*N*/ +/*N*/ // Wenn die aktuellen Werte berechnet wurden, anzeigen, dass +/*N*/ // sie jetzt gueltig sind. +/*N*/ *(pPara->GetReformat()) = SwCharRange(); +/*N*/ sal_Bool bDelta = *pPara->GetDelta() != 0; +/*N*/ *(pPara->GetDelta()) = 0; +/*N*/ +/*N*/ if( rLine.IsStop() ) +/*N*/ { +/*?*/ rLine.TruncLines( sal_True ); +/*?*/ nNew = 1; +/*N*/ } +/*N*/ +/*N*/ // FindBreak schneidet die letzte Zeile ab. +/*N*/ if( !rFrmBreak.FindBreak( this, rLine, bHasToFit ) ) +/*N*/ { +/*N*/ // Wenn wir bis zum Ende durchformatiert haben, wird nEnd auf das Ende +/*N*/ // gesetzt. In AdjustFollow wird dadurch ggf. JoinFrm() ausgefuehrt. +/*N*/ // Ansonsten ist nEnd das Ende der letzten Zeile im Master. +/*N*/ xub_StrLen nOld = nEnd; +/*N*/ nEnd = rLine.GetEnd(); +/*N*/ if( GetFollow() ) +/*N*/ { +/*N*/ if( nNew && nOld < nEnd ) +/*N*/ RemoveFtn( nOld, nEnd - nOld ); +/*N*/ CHG_OFFSET( GetFollow(), nEnd ) +/*N*/ if( !bDelta ) +/*N*/ GetFollow()->ManipOfst( nEnd ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { // Wenn wir Zeilen abgeben, darf kein Join auf den Folows gerufen werden, +/*N*/ // im Gegenteil, es muss ggf. sogar ein Follow erzeugt werden. +/*N*/ // Dies muss auch geschehen, wenn die Textmasse komplett im Master +/*N*/ // bleibt, denn es könnte ja ein harter Zeilenumbruch noch eine weitere +/*N*/ // Zeile (ohne Textmassse) notwendig machen! +/*N*/ nEnd = rLine.GetEnd(); +/*N*/ if( GetFollow() ) +/*N*/ { +/*N*/ // OD 21.03.2003 #108121# - Another case for not joining the follow: +/*N*/ // Text frame has no content, but a numbering. Then, do *not* join. +/*N*/ // Example of this case: When an empty, but numbered paragraph +/*N*/ // at the end of page is completely displaced by a fly frame. +/*N*/ // Thus, the text frame introduced a follow by a +/*N*/ // <SwTxtFrm::SplitFrm(..)> - see below. The follow then shows +/*N*/ // the numbering and must stay. +/*N*/ if ( GetFollow()->GetOfst() != nEnd || +/*N*/ GetFollow()->IsFieldFollow() || +/*N*/ ( nStrLen == 0 && +/*N*/ ( GetTxtNode()->GetNum() || GetTxtNode()->GetOutlineNum() ) ) +/*N*/ ) +/*N*/ { +/*N*/ nNew |= 3; +/*N*/ } +/*N*/ CHG_OFFSET( GetFollow(), nEnd ) +/*N*/ GetFollow()->ManipOfst( nEnd ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ // OD 21.03.2003 #108121# - Only split frame, if the frame contains +/*?*/ // content or contains no content, but has a numbering. +/*?*/ if ( nStrLen > 0 || +/*?*/ ( nStrLen == 0 && +/*?*/ ( GetTxtNode()->GetNum() || GetTxtNode()->GetOutlineNum() ) ) +/*?*/ ) +/*?*/ { +/*?*/ SplitFrm( nEnd ); +/*?*/ nNew |= 3; +/*?*/ } +/*N*/ } +/*N*/ // Wenn sich die Resthoehe geaendert hat, z.B. durch RemoveFtn() +/*N*/ // dann muessen wir auffuellen, um Oszillationen zu vermeiden! +/*N*/ if( bDummy && pBodyFrm && +/*N*/ nBodyHeight < ( IsVertical() ? +/*N*/ pBodyFrm->Frm().Width() : +/*N*/ pBodyFrm->Frm().Height() ) ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ rLine.MakeDummyLine(); +/*N*/ } +/*N*/ +/*N*/ // In AdjustFrm() stellen wir uns selbst per Grow/Shrink ein, +/*N*/ // in AdjustFollow() stellen wir unseren FolgeFrame ein. +/*N*/ +/*N*/ const SwTwips nDocPrtTop = Frm().Top() + Prt().Top(); +/*N*/ const SwTwips nOldHeight = Prt().SSize().Height(); +/*N*/ const SwTwips nChg = rLine.CalcBottomLine() - nDocPrtTop - nOldHeight; +/*N*/ +/*N*/ // Vertical Formatting: +/*N*/ // The (rotated) repaint rectangle's x coordinate referes to the frame. +/*N*/ // If the frame grows (or shirks) the repaint rectangle cannot simply +/*N*/ // be rotated back after formatting, because we use the upper left point +/*N*/ // of the frame for rotation. This point changes when growing/shrinking. +/*N*/ if ( IsVertical() && nChg ) +/*N*/ { +/*?*/ SwRect &rRepaint = *(pPara->GetRepaint()); +/*?*/ rRepaint.Left( rRepaint.Left() - nChg ); +/*?*/ rRepaint.Width( rRepaint.Width() - nChg ); +/*N*/ } +/*N*/ +/*N*/ AdjustFrm( nChg, bHasToFit ); + +/* + // FME 16.07.2003 #i16930# - removed this code because it did not + // work correctly. In SwCntntFrm::MakeAll, the frame did not move to the + // next page, instead the print area was recalculated and + // Prepare( PREP_POS_CHGD, (const void*)&bFormatted, FALSE ) invalidated + // the other flags => loop + + // OD 04.04.2003 #108446# - handle special case: + // If text frame contains no content and just has splitted, because of a + // line stop, it has to move forward. To force this forward move without + // unnecessary formatting of its footnotes and its follow, especially in + // columned sections, adjust frame height to zero (0) and do not perform + // the intrinsic format of the follow. + // The formating method <SwCntntFrm::MakeAll()> will initiate the move forward. + sal_Bool bForcedNoIntrinsicFollowCalc = sal_False; + if ( nEnd == 0 && + rLine.IsStop() && HasFollow() && nNew == 1 + ) + { + AdjustFrm( -Frm().SSize().Height(), bHasToFit ); + Prt().Pos().Y() = 0; + Prt().Height( Frm().Height() ); + if ( FollowFormatAllowed() ) + { + bForcedNoIntrinsicFollowCalc = sal_True; + ForbidFollowFormat(); + } + } + else + { + AdjustFrm( nChg, bHasToFit ); + } + */ + +/*N*/ if( HasFollow() || IsInFtn() ) +/*N*/ _AdjustFollow( rLine, nEnd, nStrLen, nNew ); + + // FME 16.07.2003 #i16930# - removed this code because it did not work + // correctly + // OD 04.04.2003 #108446# - allow intrinsic format of follow, if above + // special case has forbit it. +/* if ( bForcedNoIntrinsicFollowCalc ) + { + AllowFollowFormat(); + } + */ + +/*N*/ pPara->SetPrepMustFit( sal_False ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FormatLine() + *************************************************************************/ + +// bPrev zeigt an, ob Reformat.Start() wegen Prev() vorgezogen wurde. +// Man weiss sonst nicht, ob man Repaint weiter einschraenken kann oder nicht. + + +/*N*/ sal_Bool SwTxtFrm::FormatLine( SwTxtFormatter &rLine, const sal_Bool bPrev ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || IsSwapped(), +/*N*/ "SwTxtFrm::FormatLine( rLine, bPrev) with unswapped frame" ); +/*N*/ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion(); +/*N*/ // Nach rLine.FormatLine() haelt nStart den neuen Wert, +/*N*/ // waehrend in pOldStart der alte Offset gepflegt wird. +/*N*/ // Ueber diesen Weg soll das nDelta ersetzt werden. +/*N*/ // *pOldStart += rLine.GetCurr()->GetLen(); +/*N*/ const SwLineLayout *pOldCur = rLine.GetCurr(); +/*N*/ const xub_StrLen nOldLen = pOldCur->GetLen(); +/*N*/ const KSHORT nOldAscent = pOldCur->GetAscent(); +/*N*/ const KSHORT nOldHeight = pOldCur->Height(); +/*N*/ const SwTwips nOldWidth = pOldCur->Width() + pOldCur->GetHangingMargin(); +/*N*/ const sal_Bool bOldHyph = pOldCur->IsEndHyph(); +/*N*/ SwTwips nOldTop = 0; +/*N*/ SwTwips nOldBottom; +/*N*/ if( rLine.GetCurr()->IsClipping() ) +/*N*/ rLine.CalcUnclipped( nOldTop, nOldBottom ); +/*N*/ +/*N*/ const xub_StrLen nNewStart = rLine.FormatLine( rLine.GetStart() ); +/*N*/ +/*N*/ ASSERT( Frm().Pos().Y() + Prt().Pos().Y() == rLine.GetFirstPos(), +/*N*/ "SwTxtFrm::FormatLine: frame leaves orbit." ); +/*N*/ ASSERT( rLine.GetCurr()->Height(), +/*N*/ "SwTxtFrm::FormatLine: line height is zero" ); +/*N*/ +/*N*/ // Das aktuelle Zeilenumbruchobjekt. +/*N*/ const SwLineLayout *pNew = rLine.GetCurr(); +/*N*/ +/*N*/ sal_Bool bUnChg = nOldLen == pNew->GetLen() && +/*N*/ bOldHyph == pNew->IsEndHyph(); +/*N*/ if ( bUnChg && !bPrev ) +/*N*/ { +/*N*/ // 6672: Toleranz von SLOPPY_TWIPS (5 Twips); vgl. 6922 +/*N*/ const long nWidthDiff = nOldWidth > pNew->Width() +/*N*/ ? nOldWidth - pNew->Width() +/*N*/ : pNew->Width() - nOldWidth; +/*N*/ +/*N*/ // we only declare a line as unchanged, if its main values have not +/*N*/ // changed and it is not the last line (!paragraph end symbol!) +/*N*/ bUnChg = nOldHeight == pNew->Height() && +/*N*/ nOldAscent == pNew->GetAscent() && +/*N*/ nWidthDiff <= SLOPPY_TWIPS && +/*N*/ pOldCur->GetNext(); +/*N*/ } +/*N*/ +/*N*/ // rRepaint wird berechnet: +/*N*/ const SwTwips nBottom = rLine.Y() + rLine.GetLineHeight(); +/*N*/ SwRepaint &rRepaint = *(pPara->GetRepaint()); +/*N*/ if( bUnChg && rRepaint.Top() == rLine.Y() +/*N*/ && (bPrev || nNewStart <= pPara->GetReformat()->Start()) +/*N*/ && ( nNewStart < GetTxtNode()->GetTxt().Len() ) ) +/*N*/ { +/*N*/ rRepaint.Top( nBottom ); +/*N*/ rRepaint.Height( 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nOldTop ) +/*N*/ { +/*?*/ if( nOldTop < rRepaint.Top() ) +/*?*/ rRepaint.Top( nOldTop ); +/*?*/ if( !rLine.IsUnclipped() || nOldBottom > rRepaint.Bottom() ) +/*?*/ { +/*?*/ rRepaint.Bottom( nOldBottom - 1 ); +/*?*/ rLine.SetUnclipped( sal_True ); +/*?*/ } +/*N*/ } +/*N*/ if( rLine.GetCurr()->IsClipping() && rLine.IsFlyInCntBase() ) +/*N*/ { +/*?*/ SwTwips nTmpTop, nTmpBottom; +/*?*/ rLine.CalcUnclipped( nTmpTop, nTmpBottom ); +/*?*/ if( nTmpTop < rRepaint.Top() ) +/*?*/ rRepaint.Top( nTmpTop ); +/*?*/ if( !rLine.IsUnclipped() || nTmpBottom > rRepaint.Bottom() ) +/*?*/ { +/*?*/ rRepaint.Bottom( nTmpBottom - 1 ); +/*?*/ rLine.SetUnclipped( sal_True ); +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !rLine.IsUnclipped() || nBottom > rRepaint.Bottom() ) +/*N*/ { +/*N*/ rRepaint.Bottom( nBottom - 1 ); +/*N*/ rLine.SetUnclipped( sal_False ); +/*N*/ } +/*N*/ } +/*N*/ SwTwips nRght = Max( nOldWidth, pNew->Width() + +/*N*/ pNew->GetHangingMargin() ); +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ const SwViewOption *pOpt = pSh ? pSh->GetViewOptions() : 0; +/*N*/ if( pOpt && (pOpt->IsParagraph() || pOpt->IsLineBreak()) ) +/*?*/ nRght += ( Max( nOldAscent, pNew->GetAscent() ) ); +/*N*/ else +/*N*/ nRght += ( Max( nOldAscent, pNew->GetAscent() ) / 4); +/*N*/ nRght += rLine.GetLeftMargin(); +/*N*/ if( rRepaint.GetOfst() || rRepaint.GetRightOfst() < nRght ) +/*N*/ rRepaint.SetRightOfst( nRght ); +/*N*/ +/*N*/ // Finally we enlarge the repaint rectangle if we found an underscore +/*N*/ // within our line. 40 Twips should be enough +/*N*/ const sal_Bool bHasUnderscore = +/*N*/ ( rLine.GetInfo().GetUnderScorePos() < nNewStart ); +/*N*/ if ( bHasUnderscore || rLine.GetCurr()->HasUnderscore() ) +/*N*/ rRepaint.Bottom( rRepaint.Bottom() + 40 ); +/*N*/ +/*N*/ ((SwLineLayout*)rLine.GetCurr())->SetUnderscore( bHasUnderscore ); +/*N*/ } +/*N*/ if( !bUnChg ) +/*N*/ rLine.SetChanges(); +/*N*/ +/*N*/ // Die gute, alte nDelta-Berechnung: +/*N*/ *(pPara->GetDelta()) -= long(pNew->GetLen()) - long(nOldLen); +/*N*/ +/*N*/ // Stop! +/*N*/ if( rLine.IsStop() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // Unbedingt noch eine Zeile +/*N*/ if( rLine.IsNewLine() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // bis zum Ende des Strings ? +/*N*/ if( nNewStart >= GetTxtNode()->GetTxt().Len() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ if( rLine.GetInfo().IsShift() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // Ende des Reformats erreicht ? +/*N*/ const xub_StrLen nEnd = pPara->GetReformat()->Start() + +/*N*/ pPara->GetReformat()->Len(); +/*N*/ +/*N*/ if( nNewStart <= nEnd ) +/*N*/ return sal_True; +/*N*/ +/*N*/ return 0 != *(pPara->GetDelta()); +/*N*/ +/*N*/ // Dieser Bereich ist so sensibel, da behalten wir mal die alte Version: +/*N*/ #ifdef USED +/*N*/ // nDelta abgearbeitet ? +/*N*/ if( 0 == *(pPara->GetDelta()) ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // Wenn die Zeilen ausgeglichen sind, ist alles ok. +/*N*/ if( bUnChg ) +/*N*/ return sal_False; +/*N*/ +/*N*/ return sal_True; +/*N*/ #endif +/*N*/ } + +/************************************************************************* + * SwTxtFrm::_Format() + *************************************************************************/ + +/*N*/ void SwTxtFrm::_Format( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf, +/*N*/ const sal_Bool bAdjust ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || IsSwapped(),"SwTxtFrm::_Format with unswapped frame" ); +/*N*/ +/*N*/ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion(); +/*N*/ rLine.SetUnclipped( sal_False ); +/*N*/ +/*N*/ // Das war dem C30 zu kompliziert: aString( GetTxt() ); +/*N*/ const XubString &rString = GetTxtNode()->GetTxt(); +/*N*/ const xub_StrLen nStrLen = rString.Len(); +/*N*/ +/*N*/ SwCharRange &rReformat = *(pPara->GetReformat()); +/*N*/ SwRepaint &rRepaint = *(pPara->GetRepaint()); +/*N*/ SwRepaint *pFreeze = NULL; +/*N*/ +/*N*/ // Aus Performancegruenden wird in Init() rReformat auf STRING_LEN gesetzt. +/*N*/ // Fuer diesen Fall wird rReformat angepasst. +/*N*/ if( rReformat.Len() > nStrLen ) +/*N*/ rReformat.Len() = nStrLen; +/*N*/ +/*N*/ // Optimiert: +/*N*/ xub_StrLen nEnd = rReformat.Start() + rReformat.Len(); +/*N*/ if( nEnd > nStrLen ) +/*N*/ { +/*?*/ rReformat.Len() = nStrLen - rReformat.Start(); +/*?*/ nEnd = nStrLen; +/*N*/ } +/*N*/ +/*N*/ SwTwips nOldBottom; +/*N*/ if( GetOfst() && !IsFollow() ) +/*N*/ { +/*?*/ rLine.Bottom(); +/*?*/ nOldBottom = rLine.Y(); +/*?*/ rLine.Top(); +/*N*/ } +/*N*/ else +/*N*/ nOldBottom = 0; +/*N*/ rLine.CharToLine( rReformat.Start() ); +/*N*/ +/*N*/ // Worte koennen durch Fortfall oder Einfuegen eines Space +/*N*/ // auf die Zeile vor der editierten hinausgezogen werden, +/*N*/ // deshalb muss diese ebenfalls formatiert werden. +/*N*/ // Optimierung: Wenn rReformat erst hinter dem ersten Wort der +/*N*/ // Zeile beginnt, so kann diese Zeile die vorige nicht mehr beeinflussen. +/*N*/ // AMA: Leider doch, Textgroessenaenderungen + FlyFrames, die Rueckwirkung +/*N*/ // kann im Extremfall mehrere Zeilen (Frames!!!) betreffen! +/*N*/ +/*N*/ sal_Bool bPrev = rLine.GetPrev() && +/*N*/ ( FindBrk( rString, rLine.GetStart(), +/*N*/ rReformat.Start() + 1 ) >= rReformat.Start() || +/*N*/ rLine.GetCurr()->IsRest() ); +/*N*/ if( bPrev ) +/*N*/ { +/*N*/ while( rLine.Prev() ) +/*N*/ if( rLine.GetCurr()->GetLen() && !rLine.GetCurr()->IsRest() ) +/*N*/ { +/*N*/ if( !rLine.GetStart() ) +/*N*/ rLine.Top(); // damit NumDone nicht durcheinander kommt +/*N*/ break; +/*N*/ } +/*N*/ xub_StrLen nNew = rLine.GetStart() + rLine.GetLength(); +/*N*/ if( nNew ) +/*N*/ { +/*N*/ --nNew; +/*N*/ if( CH_BREAK == rString.GetChar( nNew ) ) +/*N*/ { +/*N*/ ++nNew; +/*N*/ rLine.Next(); +/*N*/ bPrev = sal_False; +/*N*/ } +/*N*/ } +/*N*/ rReformat.Len() += rReformat.Start() - nNew; +/*N*/ rReformat.Start() = nNew; +/*N*/ } +/*N*/ +/*N*/ rRepaint.SetOfst( 0 ); +/*N*/ rRepaint.SetRightOfst( 0 ); +/*N*/ rRepaint.Chg( Frm().Pos() + Prt().Pos(), Prt().SSize() ); +/*N*/ if( pPara->IsMargin() ) +/*?*/ rRepaint.Width( rRepaint.Width() + pPara->GetHangingMargin() ); +/*N*/ rRepaint.Top( rLine.Y() ); +/*N*/ // 6792: Rrand < LRand und Repaint +/*N*/ if( 0 >= rRepaint.Width() ) +/*?*/ rRepaint.Width(1); +/*N*/ WidowsAndOrphans aFrmBreak( this, rInf.IsTest() ? 1 : 0 ); +/*N*/ +/*N*/ // rLine steht jetzt auf der ersten Zeile, die formatiert werden +/*N*/ // muss. Das Flag bFirst sorgt dafuer, dass nicht Next() gerufen wird. +/*N*/ // Das ganze sieht verdreht aus, aber es muss sichergestellt werden, +/*N*/ // dass bei IsBreakNow rLine auf der Zeile zum stehen kommt, die +/*N*/ // nicht mehr passt. +/*N*/ sal_Bool bFirst = sal_True; +/*N*/ sal_Bool bFormat = sal_True; +/*N*/ +/*N*/ // 5383: Das CharToLine() kann uns auch in den roten Bereich fuehren. +/*N*/ // In diesem Fall muessen wir zurueckwandern, bis die Zeile, die +/*N*/ // nicht mehr passt in rLine eingestellt ist. Ansonsten geht Textmasse +/*N*/ // verloren, weil der Ofst im Follow falsch eingestellt wird. +/*N*/ +/*N*/ sal_Bool bBreak = ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 ) +/*N*/ && aFrmBreak.IsBreakNow( rLine ); +/*N*/ if( bBreak ) +/*N*/ { +/*?*/ sal_Bool bPrevDone = 0 != rLine.Prev(); +/*?*/ while( bPrevDone && aFrmBreak.IsBreakNow(rLine) ) +/*?*/ bPrevDone = 0 != rLine.Prev(); +/*?*/ if( bPrevDone ) +/*?*/ { +/*?*/ aFrmBreak.SetKeep( sal_False ); +/*?*/ rLine.Next(); +/*?*/ } +/*?*/ rLine.TruncLines(); +/*?*/ +/*?*/ // auf Nummer sicher: +/*?*/ bBreak = aFrmBreak.IsBreakNow(rLine) && +/*?*/ ( !pPara->IsPrepMustFit() || rLine.GetLineNr() > 1 ); +/*N*/ } +/*N*/ +/* Bedeutung der folgenden Flags: + Ist das Watch(End/Mid)Hyph-Flag gesetzt, so muss formatiert werden, wenn + eine Trennung am (Zeilenende/Fly) vorliegt, sofern MaxHyph erreicht ist. + Das Jump(End/Mid)Flag bedeutet, dass die naechste Zeile, bei der keine + Trennung (Zeilenende/Fly) vorliegt, formatiert werden muss, da jetzt + umgebrochen werden koennte, was vorher moeglicherweise durch MaxHyph + verboten war. + Watch(End/Mid)Hyph wird gesetzt, wenn die letzte formatierte Zeile eine + Trennstelle erhalten hat, vorher aber keine hatte, + Jump(End/Mid)Hyph, wenn eine Trennstelle verschwindet. +*/ +/*N*/ sal_Bool bJumpEndHyph = sal_False, +/*N*/ bWatchEndHyph = sal_False, +/*N*/ bJumpMidHyph = sal_False, +/*N*/ bWatchMidHyph = sal_False; +/*N*/ +/*N*/ const SwAttrSet& rAttrSet = GetTxtNode()->GetSwAttrSet(); +/*N*/ sal_Bool bMaxHyph = ( 0 != +/*N*/ ( rInf.MaxHyph() = rAttrSet.GetHyphenZone().GetMaxHyphens() ) ); +/*N*/ if ( bMaxHyph ) +/*N*/ rLine.InitCntHyph(); +/*N*/ +/*N*/ if( IsFollow() && IsFieldFollow() && rLine.GetStart() == GetOfst() ) +/*N*/ { +/*N*/ const SwLineLayout* pLine; +/*N*/ { +/*?*/ SwTxtFrm *pMaster = FindMaster(); +/*?*/ ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" ); +/*?*/ if( !pMaster->HasPara() ) +/*?*/ pMaster->GetFormatted(); +/*?*/ SwTxtSizeInfo aInf( pMaster ); +/*?*/ SwTxtIter aMasterLine( pMaster, &aInf ); +/*?*/ aMasterLine.Bottom(); +/*?*/ pLine = aMasterLine.GetCurr(); +/*?*/ } +/*?*/ SwLinePortion* pRest = +/*?*/ rLine.MakeRestPortion( pLine, GetOfst() ); +/*?*/ if( pRest ) +/*?*/ rInf.SetRest( pRest ); +/*?*/ else +/*?*/ SetFieldFollow( sal_False ); +/*N*/ } +/*N*/ +/* Zum Abbruchkriterium: + * Um zu erkennen, dass eine Zeile nicht mehr auf die Seite passt, + * muss sie formatiert werden. Dieser Ueberhang wird z.B. in AdjustFollow + * wieder entfernt. + * Eine weitere Komplikation: wenn wir der Master sind, so muessen + * wir die Zeilen durchgehen, da es ja sein kann, dass eine Zeile + * vom Follow in den Master rutschen kann. + */ +/*N*/ do +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if( bFirst ) +/*N*/ bFirst = sal_False; +/*N*/ else +/*N*/ { +/*N*/ if ( bMaxHyph ) +/*N*/ { +/*N*/ if ( rLine.GetCurr()->IsEndHyph() ) +/*N*/ rLine.CntEndHyph()++; +/*N*/ else +/*N*/ rLine.CntEndHyph() = 0; +/*N*/ if ( rLine.GetCurr()->IsMidHyph() ) +/*N*/ rLine.CntMidHyph()++; +/*N*/ else +/*N*/ rLine.CntMidHyph() = 0; +/*N*/ } +/*N*/ if( !rLine.Next() ) +/*N*/ { +/*N*/ if( !bFormat ) +/*N*/ rLine.MakeRestPortion( rLine.GetCurr(), rLine.GetEnd() ); +/*N*/ rLine.Insert( new SwLineLayout() ); +/*N*/ rLine.Next(); +/*N*/ bFormat = sal_True; +/*N*/ } +/*N*/ } +/*N*/ if ( !bFormat && bMaxHyph && +/*N*/ (bWatchEndHyph || bJumpEndHyph || bWatchMidHyph || bJumpMidHyph) ) +/*N*/ { +/*N*/ if ( rLine.GetCurr()->IsEndHyph() ) +/*N*/ { +/*N*/ if ( bWatchEndHyph ) +/*?*/ bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bFormat = bJumpEndHyph; +/*N*/ bWatchEndHyph = sal_False; +/*N*/ bJumpEndHyph = sal_False; +/*N*/ } +/*N*/ if ( rLine.GetCurr()->IsMidHyph() ) +/*N*/ { +/*?*/ if ( bWatchMidHyph && !bFormat ) +/*?*/ bFormat = ( rLine.CntEndHyph() == rInf.MaxHyph() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ bFormat = bFormat || bJumpMidHyph; +/*N*/ bWatchMidHyph = sal_False; +/*N*/ bJumpMidHyph = sal_False; +/*N*/ } +/*N*/ } +/*N*/ if( bFormat ) +/*N*/ { +/*N*/ sal_Bool bOldEndHyph = rLine.GetCurr()->IsEndHyph(); +/*N*/ sal_Bool bOldMidHyph = rLine.GetCurr()->IsMidHyph(); +/*N*/ bFormat = FormatLine( rLine, bPrev ); +/*N*/ //9334: Es kann nur ein bPrev geben... (???) +/*N*/ bPrev = sal_False; +/*N*/ if ( bMaxHyph ) +/*N*/ { +/*N*/ if ( rLine.GetCurr()->IsEndHyph() != bOldEndHyph ) +/*N*/ { +/*N*/ bWatchEndHyph = !bOldEndHyph; +/*N*/ bJumpEndHyph = bOldEndHyph; +/*N*/ } +/*N*/ if ( rLine.GetCurr()->IsMidHyph() != bOldMidHyph ) +/*N*/ { +/*?*/ bWatchMidHyph = !bOldMidHyph; +/*?*/ bJumpMidHyph = bOldMidHyph; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( !rInf.IsNewLine() ) +/*N*/ { +/*N*/ if( !bFormat ) +/*N*/ bFormat = 0 != rInf.GetRest(); +/*N*/ if( rInf.IsStop() || rInf.GetIdx() >= nStrLen ) +/*N*/ break; +/*N*/ if( !bFormat && ( !bMaxHyph || ( !bWatchEndHyph && +/*N*/ !bJumpEndHyph && !bWatchMidHyph && !bJumpMidHyph ) ) ) +/*N*/ { +/*N*/ if( GetFollow() ) +/*N*/ { +/*N*/ while( rLine.Next() ) +/*N*/ ; //Nothing +/*N*/ pFreeze = new SwRepaint( rRepaint ); // to minimize painting +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ bBreak = aFrmBreak.IsBreakNow(rLine); +/*N*/ }while( !bBreak ); +/*N*/ +/*N*/ if( pFreeze ) +/*N*/ { +/*N*/ rRepaint = *pFreeze; +/*N*/ delete pFreeze; +/*N*/ } +/*N*/ +/*N*/ if( !rLine.IsStop() ) +/*N*/ { +/*N*/ // Wurde aller Text formatiert und gibt es noch weitere +/*N*/ // Zeilenobjekte, dann sind diese jetzt ueberfluessig, +/*N*/ // weil der Text kuerzer geworden ist. +/*N*/ if( rLine.GetStart() + rLine.GetLength() >= nStrLen && +/*N*/ rLine.GetCurr()->GetNext() ) +/*N*/ { +/*N*/ rLine.TruncLines(); +/*N*/ rLine.SetTruncLines( sal_True ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( !rInf.IsTest() ) +/*N*/ { +/*N*/ // Bei OnceMore lohnt sich kein FormatAdjust +/*N*/ if( bAdjust || !rLine.GetDropFmt() || !rLine.CalcOnceMore() ) +/*N*/ { +/*N*/ FormatAdjust( rLine, aFrmBreak, nStrLen, rInf.IsStop() ); +/*N*/ } +/*N*/ if( rRepaint.HasArea() ) +/*N*/ SetRepaint(); +/*N*/ rLine.SetTruncLines( sal_False ); +/*N*/ if( nOldBottom ) // Bei "gescollten" Absaetzen wird +/*N*/ { // noch ueberprueft, ob durch Schrumpfen +/*?*/ rLine.Bottom(); // das Scrolling ueberfluessig wurde. +/*?*/ SwTwips nNewBottom = rLine.Y(); +/*?*/ if( nNewBottom < nOldBottom ) +/*?*/ _SetOfst( 0 ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::Format() + *************************************************************************/ + +/*N*/ void SwTxtFrm::FormatOnceMore( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || IsSwapped(), +/*N*/ "A frame is not swapped in SwTxtFrm::FormatOnceMore" ); +/*N*/ +/*N*/ SwParaPortion *pPara = rLine.GetInfo().GetParaPortion(); +/*N*/ if( !pPara ) +/*N*/ return; +/*N*/ +/*N*/ // ggf gegen pPara +/*N*/ KSHORT nOld = ((const SwTxtMargin&)rLine).GetDropHeight(); +/*N*/ sal_Bool bShrink = sal_False, +/*N*/ bGrow = sal_False, +/*N*/ bGoOn = rLine.IsOnceMore(); +/*N*/ sal_uInt8 nGo = 0; +/*N*/ while( bGoOn ) +/*N*/ { +/*N*/ #ifdef DBGTXT +/*N*/ aDbstream << "OnceMore!" << endl; +/*N*/ #endif +/*N*/ ++nGo; +/*N*/ rInf.Init(); +/*N*/ rLine.Top(); +/*N*/ if( !rLine.GetDropFmt() ) +/*N*/ rLine.SetOnceMore( sal_False ); +/*N*/ SwCharRange aRange( 0, rInf.GetTxt().Len() ); +/*N*/ *(pPara->GetReformat()) = aRange; +/*N*/ _Format( rLine, rInf ); +/*N*/ +/*N*/ bGoOn = rLine.IsOnceMore(); +/*N*/ if( bGoOn ) +/*N*/ { +/*?*/ const KSHORT nNew = ((const SwTxtMargin&)rLine).GetDropHeight(); +/*?*/ if( nOld == nNew ) +/*?*/ bGoOn = sal_False; +/*?*/ else +/*?*/ { +/*?*/ if( nOld > nNew ) +/*?*/ bShrink = sal_True; +/*?*/ else +/*?*/ bGrow = sal_True; +/*?*/ +/*?*/ if( bShrink == bGrow || 5 < nGo ) +/*?*/ bGoOn = sal_False; +/*?*/ +/*?*/ nOld = nNew; +/*?*/ } +/*?*/ +/*?*/ // 6107: Wenn was schief ging, muss noch einmal formatiert werden. +/*?*/ if( !bGoOn ) +/*?*/ { +/*?*/ rInf.CtorInit( this ); +/*?*/ rLine.CtorInit( this, &rInf ); +/*?*/ rLine.SetDropLines( 1 ); +/*?*/ rLine.CalcDropHeight( 1 ); +/*?*/ SwCharRange aRange( 0, rInf.GetTxt().Len() ); +/*?*/ *(pPara->GetReformat()) = aRange; +/*?*/ _Format( rLine, rInf, sal_True ); +/*?*/ // 8047: Wir painten alles... +/*?*/ SetCompletePaint(); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::_Format() + *************************************************************************/ + + +/*N*/ void SwTxtFrm::_Format( SwParaPortion *pPara ) +/*N*/ { +/*N*/ const xub_StrLen nStrLen = GetTxt().Len(); +/*N*/ +/*N*/ // AMA: Wozu soll das gut sein? Scheint mir zuoft zu einem kompletten +/*N*/ // Formatieren und Repainten zu fuehren??? +/*N*/ // if ( !(*pPara->GetDelta()) ) +/*N*/ // *(pPara->GetDelta()) = nStrLen; +/*N*/ // else +/*N*/ if ( !nStrLen ) +/*N*/ { +/*N*/ // Leere Zeilen werden nicht lange gequaelt: +/*N*/ // pPara wird blank geputzt +/*N*/ // entspricht *pPara = SwParaPortion; +/*N*/ sal_Bool bMustFit = pPara->IsPrepMustFit(); +/*N*/ pPara->Truncate(); +/*N*/ pPara->FormatReset(); +/*N*/ +/*N*/ // delete pSpaceAdd und pKanaComp +/*N*/ pPara->FinishSpaceAdd(); +/*N*/ pPara->FinishKanaComp(); +/*N*/ pPara->ResetFlags(); +/*N*/ pPara->SetPrepMustFit( bMustFit ); +/*N*/ } +/*N*/ +/*N*/ ASSERT( ! IsSwapped(), "A frame is swapped before _Format" ); +/*N*/ +/*N*/ if ( IsVertical() ) +/*?*/ SwapWidthAndHeight(); +/*N*/ +/*N*/ SwTxtFormatInfo aInf( this ); +/*N*/ SwTxtFormatter aLine( this, &aInf ); +/*N*/ +/*N*/ _Format( aLine, aInf ); +/*N*/ +/*N*/ if( aLine.IsOnceMore() ) +/*N*/ FormatOnceMore( aLine, aInf ); +/*N*/ +/*N*/ if ( IsVertical() ) +/*?*/ SwapWidthAndHeight(); +/*N*/ +/*N*/ ASSERT( ! IsSwapped(), "A frame is swapped after _Format" ); +/*N*/ +/*N*/ if( 1 < aLine.GetDropLines() ) +/*N*/ { +/*N*/ if( SVX_ADJUST_LEFT != aLine.GetAdjust() && +/*N*/ SVX_ADJUST_BLOCK != aLine.GetAdjust() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ aLine.CalcDropAdjust(); +/*N*/ } +/*N*/ +/*N*/ if( aLine.IsPaintDrop() ) +/*N*/ { +/*N*/ aLine.CalcDropRepaint(); +/*N*/ aLine.SetPaintDrop( sal_False ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::Format() + *************************************************************************/ + +/* + * Format berechnet die Groesse des Textframes und ruft, wenn + * diese feststeht, Shrink() oder Grow(), um die Framegroesse dem + * evtl. veraenderten Platzbedarf anzupassen. + */ + +/*M*/ void SwTxtFrm::Format( const SwBorderAttrs * ) +/*M*/ { +///*M*/ DBG_LOOP; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ const XubString aXXX = GetTxtNode()->GetTxt(); +/*M*/ const SwTwips nDbgY = Frm().Top(); +/*M*/ const SwPageFrm *pDbgPage = FindPageFrm(); +/*M*/ const MSHORT nDbgPageNr = pDbgPage->GetPhyPageNum(); +/*M*/ // Um zu gucken, ob es einen Ftn-Bereich gibt. +/*M*/ const SwFrm *pDbgFtnCont = (const SwFrm*)(FindPageFrm()->FindFtnCont()); +/*M*/ +/*M*/ #ifdef DBG_UTIL +/*M*/ // nStopAt laesst sich vom CV bearbeiten. +/*M*/ static MSHORT nStopAt = 0; +/*M*/ if( nStopAt == GetFrmId() ) +/*M*/ { +/*M*/ int i = GetFrmId(); +/*M*/ } +/*M*/ #endif +/*M*/ #endif +/*M*/ +/*M*/ #ifdef DEBUG_FTN +/*M*/ //Fussnote darf nicht auf einer Seite vor ihrer Referenz stehen. +/*M*/ if( IsInFtn() ) +/*M*/ { +/*M*/ const SwFtnFrm *pFtn = (SwFtnFrm*)GetUpper(); +/*M*/ const SwPageFrm *pFtnPage = pFtn->GetRef()->FindPageFrm(); +/*M*/ const MSHORT nFtnPageNr = pFtnPage->GetPhyPageNum(); +/*M*/ if( !IsLocked() ) +/*M*/ { +/*M*/ if( nFtnPageNr > nDbgPageNr ) +/*M*/ { +/*M*/ SwTxtFrmLocker aLock(this); +/*M*/ ASSERT( nFtnPageNr <= nDbgPageNr, "!Ftn steht vor der Referenz." ); +/*M*/ MSHORT i = 0; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ #endif +/*M*/ +/*M*/ MSHORT nRepeat = 0; +/*M*/ +/*M*/ SWRECTFN( this ) +/*M*/ +/*M*/ do +/*M*/ { +/*M*/ // Vom Berichtsautopiloten oder ueber die BASIC-Schnittstelle kommen +/*M*/ // gelegentlich TxtFrms mit einer Breite <=0. +/*M*/ if( (Prt().*fnRect->fnGetWidth)() <= 0 ) +/*M*/ { +/*M*/ // Wenn MustFit gesetzt ist, schrumpfen wir ggf. auf die Unterkante +/*M*/ // des Uppers, ansonsten nehmen wir einfach eine Standardgroesse +/*M*/ // von 12 Pt. ein (240 Twip). +/*M*/ SwTxtLineAccess aAccess( this ); +/*M*/ long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*M*/ if( aAccess.GetPara()->IsPrepMustFit() ) +/*M*/ { +/*M*/ const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*M*/ const SwTwips nDiff = - (Frm().*fnRect->fnBottomDist)( nLimit ); +/*M*/ if( nDiff > 0 ) +/*M*/ Shrink( nDiff ); +/*M*/ } +/*M*/ else if( 240 < nFrmHeight ) +/*M*/ Shrink( nFrmHeight - 240 ); +/*M*/ else if( 240 > nFrmHeight ) +/*M*/ Grow( 240 - nFrmHeight ); +/*M*/ nFrmHeight = (Frm().*fnRect->fnGetHeight)(); +/*M*/ +/*M*/ long nTop = (this->*fnRect->fnGetTopMargin)(); +/*M*/ if( nTop > nFrmHeight ) +/*M*/ (this->*fnRect->fnSetYMargins)( nFrmHeight, 0 ); +/*M*/ else if( (Prt().*fnRect->fnGetHeight)() < 0 ) +/*M*/ (Prt().*fnRect->fnSetHeight)( 0 ); +/*M*/ return; +/*M*/ } +/*M*/ +/*M*/ sal_Bool bChkAtCnt = sal_False; +/*M*/ const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len(); +/*M*/ if ( nStrLen || !FormatEmpty() ) +/*M*/ { +/*M*/ +/*M*/ SetEmpty( sal_False ); +/*M*/ // Um nicht durch verschachtelte Formats irritiert zu werden. +/*M*/ FormatLevel aLevel; +/*M*/ if( 12 == aLevel.GetLevel() ) +/*M*/ return; +/*M*/ +/*M*/ // Die Formatinformationen duerfen u.U. nicht veraendert werden. +/*M*/ if( IsLocked() ) +/*M*/ return; +/*M*/ +/*M*/ // Waehrend wir formatieren, wollen wir nicht gestoert werden. +/*M*/ SwTxtFrmLocker aLock(this); +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ //MA 25. Jan. 94 Das Flag stimmt sehr haufig beim Eintritt nicht. Das muss +/*M*/ // bei naechster Gelegenheit geprueft und gefixt werden. +/*M*/ const sal_Bool bOldFtnFlag = HasFtn(); +/*M*/ CalcFtnFlag(); +/*M*/ if ( bOldFtnFlag != HasFtn() ) +/*M*/ {int bla = 5;} +/*M*/ #endif +/*M*/ +/*M*/ // 8708: Vorsicht, das Format() kann auch durch GetFormatted() +/*M*/ // angestossen werden. +/*M*/ if( IsHiddenNow() ) +/*M*/ { +/*M*/ long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); +/*M*/ if( nPrtHeight ) +/*M*/ { +/*M*/ HideHidden(); +/*M*/ Shrink( nPrtHeight ); +/*M*/ } +/*M*/ ChgThisLines(); +/*M*/ return; +/*M*/ } +/*M*/ +/*M*/ SwTxtLineAccess aAccess( this ); +/*M*/ const sal_Bool bNew = !aAccess.SwTxtLineAccess::IsAvailable(); +/*M*/ sal_Bool bSetOfst = sal_False; +/*M*/ +/*M*/ if( CalcPreps() ) +/*M*/ ; // nothing +/*M*/ // Wir returnen, wenn schon formatiert wurde, nicht aber, wenn +/*M*/ // der TxtFrm gerade erzeugt wurde und ueberhaupt keine Format- +/*M*/ // informationen vorliegen. +/*M*/ else if( !bNew && !aAccess.GetPara()->GetReformat()->Len() ) +/*M*/ { +/*M*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() ) +/*M*/ { +/*M*/ aAccess.GetPara()->SetPrepAdjust( sal_True ); +/*M*/ aAccess.GetPara()->SetPrep( sal_True ); +/*M*/ CalcPreps(); +/*M*/ } +/*M*/ SetWidow( sal_False ); +/*M*/ } +/*M*/ else if( ( bSetOfst = ( GetOfst() && GetOfst() > GetTxtNode()->GetTxt().Len() ) ) && +/*M*/ IsFollow() ) +/*M*/ { +/*M*/ SwTxtFrm *pMaster = FindMaster(); +/*M*/ ASSERT( pMaster, "SwTxtFrm::Format: homeless follow" ); +/*M*/ if( pMaster ) +/*M*/ pMaster->Prepare( PREP_FOLLOW_FOLLOWS ); +/*M*/ SwTwips nMaxY = (GetUpper()->*fnRect->fnGetPrtBottom)(); +/*M*/ if( (Frm().*fnRect->fnOverStep)( nMaxY ) ) +/*M*/ (this->*fnRect->fnSetLimit)( nMaxY ); +/*M*/ else if( (Frm().*fnRect->fnBottomDist)( nMaxY ) < 0 ) +/*M*/ (Frm().*fnRect->fnAddBottom)( -(Frm().*fnRect->fnGetHeight)() ); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ // bSetOfst here means that we have the "red arrow situation" +/*M*/ if ( bSetOfst ) +/*M*/ _SetOfst( 0 ); +/*M*/ +/*M*/ const sal_Bool bOrphan = IsWidow(); +/*M*/ const SwFtnBossFrm* pFtnBoss = HasFtn() ? FindFtnBossFrm() : 0; +/*M*/ SwTwips nFtnHeight; +/*M*/ if( pFtnBoss ) +/*M*/ { +/*M*/ const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont(); +/*M*/ nFtnHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0; +/*M*/ } +/*M*/ do +/*M*/ { +/*M*/ _Format( aAccess.GetPara() ); +/*M*/ if( pFtnBoss && nFtnHeight ) +/*M*/ { +/*M*/ const SwFtnContFrm* pCont = pFtnBoss->FindFtnCont(); +/*M*/ SwTwips nNewHeight = pCont ? (pCont->Frm().*fnRect->fnGetHeight)() : 0; +/*M*/ // If we lost some footnotes, we may have more space +/*M*/ // for our main text, so we have to format again ... +/*M*/ if( nNewHeight < nFtnHeight ) +/*M*/ nFtnHeight = nNewHeight; +/*M*/ else +/*M*/ break; +/*M*/ } +/*M*/ else +/*M*/ break; +/*M*/ } while ( pFtnBoss ); +/*M*/ if( bOrphan ) +/*M*/ { +/*M*/ ValidateFrm(); +/*M*/ SetWidow( sal_False ); +/*M*/ } +/*M*/ bChkAtCnt = sal_True; +/*M*/ } +/*M*/ if( IsEmptyMaster() ) +/*M*/ { +/*M*/ SwFrm* pPre = GetPrev(); +/*M*/ if( pPre && pPre->GetAttrSet()->GetKeep().GetValue() ) +/*M*/ pPre->InvalidatePos(); +/*M*/ } +/*M*/ } +/*M*/ MSHORT nMaxRepeat = 2; +/*M*/ if( bChkAtCnt && nRepeat < nMaxRepeat ) +/*M*/ { +/*M*/ sal_Bool bRepeat = sal_False; +/*M*/ MSHORT nRepAdd = 0; +/*M*/ SwDrawObjs *pObjs; +/*M*/ SwTxtFrm *pMaster = IsFollow() ? FindMaster() : this; +/*M*/ if( pMaster && !pMaster->IsFlyLock() ) +/*M*/ { +/*M*/ if ( 0 != (pObjs = pMaster->GetDrawObjs()) ) +/*M*/ { +/*M*/ MSHORT nAutoCnt = 0; +/*M*/ for( MSHORT i = 0; i < pObjs->Count(); ++i ) +/*M*/ { +/*M*/ SdrObject *pO = (*pObjs)[i]; +/*M*/ if ( pO->IsWriterFlyFrame() ) +/*M*/ { +/*M*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*M*/ if( pFly->IsAutoPos() && !::binfilter::IsInProgress( pFly ) ) +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ if( nAutoCnt > 11 ) +/*M*/ nMaxRepeat = nAutoCnt/4; +/*M*/ } +/*M*/ } +/*M*/ if( bRepeat ) +/*M*/ nRepeat += nRepAdd; +/*M*/ else +/*M*/ nRepeat = 0; +/*M*/ } +/*M*/ else +/*M*/ nRepeat = 0; +/*M*/ } while( nRepeat ); +/*M*/ +/*M*/ ChgThisLines(); +/*M*/ +/*N*/ // the PrepMustFit should not survive a Format operation +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ if ( pPara ) +/*N*/ pPara->SetPrepMustFit( sal_False ); +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ // Hier ein Instrumentarium, um ungewoehnlichen Master/Follow-Kombinationen, +/*M*/ // insbesondere bei Fussnoten, auf die Schliche zu kommen +/*M*/ if( IsFollow() || GetFollow() ) +/*M*/ { +/*M*/ SwTxtFrm *pTmpFrm = IsFollow() ? FindMaster() : this; +/*M*/ const SwPageFrm *pTmpPage = pTmpFrm->FindPageFrm(); +/*M*/ MSHORT nPgNr = pTmpPage->GetPhyPageNum(); +/*M*/ MSHORT nLast; +/*M*/ MSHORT nDummy = 0; // nur zum Breakpoint setzen +/*M*/ while( pTmpFrm->GetFollow() ) +/*M*/ { +/*M*/ pTmpFrm = pTmpFrm->GetFollow(); +/*M*/ nLast = nPgNr; +/*M*/ pTmpPage = pTmpFrm->FindPageFrm(); +/*M*/ nPgNr = pTmpPage->GetPhyPageNum(); +/*M*/ if( nLast > nPgNr ) +/*M*/ ++nDummy; // schon fast eine Assertion wert +/*M*/ else if( nLast == nPgNr ) +/*M*/ ++nDummy; // bei Spalten voellig normal, aber sonst!? +/*M*/ else if( nLast < nPgNr - 1 ) +/*M*/ ++nDummy; // kann schon mal temporaer vorkommen +/*M*/ } +/*M*/ } +/*M*/ #endif +/*N*/ +/*N*/ CalcBaseOfstForFly(); +/*M*/ } + +/************************************************************************* + * SwTxtFrm::FormatQuick() + *************************************************************************/ +// 6995: +// return sal_False: Prepare(), HasPara(), InvalidateRanges(), + +/*N*/ sal_Bool SwTxtFrm::FormatQuick() +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::FormatQuick with swapped frame" ); +/*N*/ +///*N*/ DBG_LOOP; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const XubString aXXX = GetTxtNode()->GetTxt(); +/*N*/ const SwTwips nDbgY = Frm().Top(); +/*N*/ #ifdef DBG_UTIL +/*N*/ // nStopAt laesst sich vom CV bearbeiten. +/*N*/ static MSHORT nStopAt = 0; +/*N*/ if( nStopAt == GetFrmId() ) +/*N*/ { +/*?*/ int i = GetFrmId(); +/*N*/ } +/*N*/ #endif +/*N*/ #endif +/*N*/ +/*N*/ if( IsEmpty() && FormatEmpty() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // Wir sind sehr waehlerisch: +/*N*/ if( HasPara() || IsWidow() || IsLocked() +/*N*/ || !GetValidSizeFlag() || +/*N*/ ( ( IsVertical() ? Prt().Width() : Prt().Height() ) && IsHiddenNow() ) ) +/*N*/ return sal_False; +/*N*/ +/*N*/ SwTxtLineAccess aAccess( this ); +/*N*/ SwParaPortion *pPara = aAccess.GetPara(); +/*N*/ if( !pPara ) +/*N*/ return sal_False; +/*N*/ +/*N*/ SwFrmSwapper aSwapper( this, sal_True ); +/*N*/ +/*N*/ SwTxtFrmLocker aLock(this); +/*N*/ SwTxtFormatInfo aInf( this, sal_False, sal_True ); +/*N*/ if( 0 != aInf.MaxHyph() ) // 27483: MaxHyphen beachten! +/*N*/ return sal_False; +/*N*/ +/*N*/ SwTxtFormatter aLine( this, &aInf ); +/*N*/ +/*N*/ // DropCaps sind zu kompliziert... +/*N*/ if( aLine.GetDropFmt() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ xub_StrLen nStart = GetOfst(); +/*N*/ const xub_StrLen nEnd = GetFollow() +/*N*/ ? GetFollow()->GetOfst() : aInf.GetTxt().Len(); +/*N*/ do +/*N*/ { //DBG_LOOP; +/*N*/ nStart = aLine.FormatLine( nStart ); +/*N*/ if( aInf.IsNewLine() || (!aInf.IsStop() && nStart < nEnd) ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ aLine.Insert( new SwLineLayout() ); +/*N*/ } while( aLine.Next() ); +/*N*/ +/*N*/ // Last exit: die Hoehen muessen uebereinstimmen. +/*N*/ Point aTopLeft( Frm().Pos() ); +/*N*/ aTopLeft += Prt().Pos(); +/*N*/ const SwTwips nNewHeight = aLine.Y() + aLine.GetLineHeight(); +/*N*/ const SwTwips nOldHeight = aTopLeft.Y() + Prt().Height(); +/*N*/ if( nNewHeight != nOldHeight && !IsUndersized() ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*?*/ // Achtung: Durch FormatLevel==12 kann diese Situation auftreten, don't panic! +/*?*/ // ASSERT( nNewHeight == nOldHeight, "!FormatQuick: rosebud" ); +/*?*/ #endif +/*?*/ xub_StrLen nStrt = GetOfst(); +/*?*/ _InvalidateRange( SwCharRange( nStrt, nEnd - nStrt) ); +/*?*/ return sal_False; +/*N*/ } +/*N*/ +/*N*/ if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() ) +/*N*/ return sal_False; // kann z.B. durch Orphans auftreten (35083,35081) +/*N*/ +/*N*/ // Geschafft, wir sind durch ... +/*N*/ +/*N*/ // Repaint setzen +/*N*/ pPara->GetRepaint()->Pos( aTopLeft ); +/*N*/ pPara->GetRepaint()->SSize( Prt().SSize() ); +/*N*/ +/*N*/ // Reformat loeschen +/*N*/ *(pPara->GetReformat()) = SwCharRange(); +/*N*/ *(pPara->GetDelta()) = 0; +/*N*/ +/*N*/ return sal_True; +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_frmpaint.cxx b/binfilter/bf_sw/source/core/text/sw_frmpaint.cxx new file mode 100644 index 000000000000..1172d3b9182d --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_frmpaint.cxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + + + +#include <pagedesc.hxx> // SwPageDesc + +#include <itrpaint.hxx> // SwTxtPainter + +#include <horiornt.hxx> + +namespace binfilter { + + +// steht im number.cxx +extern const sal_Char __FAR_DATA sBulletFntName[]; + +extern FASTBOOL bOneBeepOnly; + +sal_Bool bInitFont = sal_True; + +#define REDLINE_DISTANCE 567/4 +#define REDLINE_MINDIST 567/10 + + +/************************************************************************* + * SwExtraPainter::PaintExtra() + **************************************************************************/ + + + + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + +/*N*/ SwRect SwTxtFrm::Paint() +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const SwTwips nDbgY = Frm().Top(); +/*N*/ #endif +/*N*/ +/*N*/ // finger layout +/*N*/ ASSERT( GetValidPosFlag(), "+SwTxtFrm::Paint: no Calc()" ); +/*N*/ +/*N*/ SwRect aRet( Prt() ); +/*N*/ if ( IsEmpty() || !HasPara() ) +/*N*/ aRet += Frm().Pos(); +/*N*/ else +/*N*/ { +/*N*/ // AMA: Wir liefern jetzt mal das richtige Repaintrechteck zurueck, +/*N*/ // d.h. als linken Rand den berechneten PaintOfst! +/*N*/ SwRepaint *pRepaint = GetPara()->GetRepaint(); +/*N*/ long l; +/*N*/ if( pRepaint->GetOfst() ) +/*N*/ pRepaint->Left( pRepaint->GetOfst() ); +/*N*/ +/*N*/ l = pRepaint->GetRightOfst(); +/*N*/ if( l && ( pRepaint->GetOfst() || l > pRepaint->Right() ) ) +/*N*/ pRepaint->Right( l ); +/*N*/ pRepaint->SetOfst( 0 ); +/*N*/ aRet = *pRepaint; +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ if ( IsRightToLeft() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ SwitchLTRtoRTL( aRet ); +/*N*/ #endif +/*N*/ if ( IsVertical() ) +/*N*/ SwitchHorizontalToVertical( aRet ); +/*N*/ } +/*N*/ ResetRepaint(); +/*N*/ +/*N*/ return aRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::Paint() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_guess.cxx b/binfilter/bf_sw/source/core/text/sw_guess.cxx new file mode 100644 index 000000000000..d23547d77649 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_guess.cxx @@ -0,0 +1,578 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <ctype.h> + +#include <tools/shl.hxx> // needed for SW_MOD() macro + +#include <swmodule.hxx> +#include <guess.hxx> +#include <inftxt.hxx> // SwTxtSizeInfo, SwTxtFormatInfo + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <pagefrm.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> + +#include <com/sun/star/i18n/BreakType.hpp> +#include <com/sun/star/i18n/WordType.hpp> +#include <unotools/charclass.hxx> +#include <porfld.hxx> +namespace binfilter { + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::beans; + +using rtl::OUString; + +#ifdef VERTICAL_LAYOUT +#define CH_FULL_BLANK 0x3000 +#endif + +/************************************************************************* + * SwTxtGuess::Guess + * + * provides information for line break calculation + * returns true if no line break has to be performed + * otherwise possible break or hyphenation position is determined + *************************************************************************/ + +/*M*/ sal_Bool SwTxtGuess::Guess( const SwTxtPortion& rPor, SwTxtFormatInfo &rInf, +/*M*/ const KSHORT nPorHeight ) +/*M*/ { +/*M*/ nCutPos = rInf.GetIdx(); +/*M*/ +/*M*/ // Leere Strings sind immer 0 +/*M*/ if( !rInf.GetLen() || !rInf.GetTxt().Len() ) +/*M*/ return sal_False; +/*M*/ +/*M*/ ASSERT( rInf.GetIdx() < rInf.GetTxt().Len(), +/*M*/ "+SwTxtGuess::Guess: invalid SwTxtFormatInfo" ); +/*M*/ +/*M*/ ASSERT( nPorHeight, "+SwTxtGuess::Guess: no height" ); +/*M*/ +/*M*/ USHORT nMinSize; +/*M*/ USHORT nMaxSizeDiff; +/*M*/ +/*M*/ const SwScriptInfo& rSI = +/*M*/ ((SwParaPortion*)rInf.GetParaPortion())->GetScriptInfo(); +/*M*/ +/*M*/ USHORT nMaxComp = ( SW_CJK == rInf.GetFont()->GetActual() ) && +/*M*/ rSI.CountCompChg() && +/*M*/ ! rInf.IsMulti() && +/*M*/ ! rPor.InFldGrp() && +/*M*/ ! rPor.IsDropPortion() ? +/*M*/ 10000 : +/*M*/ 0 ; +/*M*/ +/*M*/ SwTwips nLineWidth = rInf.Width() - rInf.X(); +/*M*/ const xub_StrLen nMaxLen = Min( xub_StrLen(rInf.GetTxt().Len() - rInf.GetIdx()), +/*M*/ rInf.GetLen() ); +/*M*/ // special case: char width > line width +/*M*/ if( !nMaxLen || !nLineWidth ) +/*M*/ return sal_False; +/*M*/ +/*M*/ KSHORT nItalic = 0; +/*M*/ if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() ) +/*M*/ { +/*M*/ sal_Bool bAddItalic = sal_True; +/*M*/ +/*M*/ // do not add extra italic value if we have an active character grid +/*M*/ if ( rInf.SnapToGrid() ) +/*M*/ { +/*M*/ GETGRID( rInf.GetTxtFrm()->FindPageFrm() ) +/*M*/ bAddItalic = ! pGrid || GRID_LINES_CHARS != pGrid->GetGridType(); +/*M*/ } +/*M*/ +/*M*/ #ifdef MAC +/*M*/ nItalic = bAddItalic ? nPorHeight / 4 : 0; +/*M*/ #else +/*M*/ nItalic = bAddItalic ? nPorHeight / 12 : 0; +/*M*/ #endif +/*M*/ if( nItalic >= nLineWidth ) +/*M*/ { +/*M*/ nBreakWidth = nItalic; +/*M*/ nCutPos = rInf.GetIdx(); +/*M*/ return sal_False; +/*M*/ } +/*M*/ else +/*M*/ nLineWidth -= nItalic; +/*M*/ } +/*M*/ +/*M*/ // first check if everything fits to line +/*M*/ if ( long ( nLineWidth ) * 2 > long ( nMaxLen ) * nPorHeight ) +/*M*/ { +/*M*/ // call GetTxtSize with maximum compression (for kanas) +/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nMaxLen, +/*M*/ nMaxComp, nMinSize, nMaxSizeDiff ); +/*M*/ +/*M*/ nBreakWidth = nMinSize; +/*M*/ +/*M*/ if ( nBreakWidth <= nLineWidth ) +/*M*/ { +/*M*/ // portion fits to line +/*M*/ nCutPos = rInf.GetIdx() + nMaxLen - 1; +/*M*/ if( nItalic && ( nCutPos + 1 ) >= rInf.GetTxt().Len() ) +/*M*/ nBreakWidth += nItalic; +/*M*/ +/*M*/ // save maximum width for later use +/*M*/ if ( nMaxSizeDiff ) +/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff ); +/*M*/ +/*M*/ return sal_True; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ sal_Bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud(); +/*M*/ xub_StrLen nHyphPos = 0; +/*M*/ +/*M*/ // nCutPos is the first character not fitting to the current line +/*M*/ // nHyphPos is the first character not fitting to the current line, +/*M*/ // considering an additional "-" for hyphenation +/*M*/ if( bHyph ) +/*M*/ { +/*M*/ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos ); +/*M*/ +/*M*/ if ( !nHyphPos && rInf.GetIdx() ) +/*M*/ nHyphPos = rInf.GetIdx() - 1; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp ); +/*M*/ +/*M*/ #ifdef DBG_UTIL +/*M*/ if ( STRING_LEN != nCutPos ) +/*M*/ { +/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nCutPos - rInf.GetIdx(), +/*M*/ nMaxComp, nMinSize, nMaxSizeDiff ); +/*M*/ ASSERT( nMinSize <= nLineWidth, "What a Guess!!!" ); +/*M*/ } +/*M*/ #endif +/*M*/ } +/*M*/ +/*M*/ if( nCutPos > rInf.GetIdx() + nMaxLen ) +/*M*/ { +/*M*/ // second check if everything fits to line +/*M*/ nCutPos = nBreakPos = rInf.GetIdx() + nMaxLen - 1; +/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nMaxLen, nMaxComp, +/*M*/ nMinSize, nMaxSizeDiff ); +/*M*/ +/*M*/ nBreakWidth = nMinSize; +/*M*/ +/*M*/ // Der folgende Vergleich sollte eigenlich immer sal_True ergeben, sonst +/*M*/ // hat es wohl bei GetTxtBreak einen Pixel-Rundungsfehler gegeben... +/*M*/ if ( nBreakWidth <= nLineWidth ) +/*M*/ { +/*M*/ if( nItalic && ( nBreakPos + 1 ) >= rInf.GetTxt().Len() ) +/*M*/ nBreakWidth += nItalic; +/*M*/ +/*M*/ // save maximum width for later use +/*M*/ if ( nMaxSizeDiff ) +/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff ); +/*M*/ +/*M*/ return sal_True; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // we have to trigger an underflow for a footnote portion +/*M*/ // which does not fit to the current line +/*M*/ if ( rPor.IsFtnPortion() ) +/*M*/ { +/*M*/ nBreakPos = rInf.GetIdx(); +/*M*/ nCutPos = rInf.GetLen(); +/*M*/ return sal_False; +/*M*/ } +/*M*/ +/*M*/ xub_StrLen nPorLen = 0; +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ // do not call the break iterator nCutPos is a blank +/*M*/ xub_Unicode cCutChar = rInf.GetTxt().GetChar( nCutPos ); +/*M*/ if( CH_BLANK == cCutChar || CH_FULL_BLANK == cCutChar ) +/*M*/ #else +/*M*/ if( CH_BLANK == rInf.GetTxt().GetChar( nCutPos ) ) +/*M*/ #endif +/*M*/ { +/*M*/ nBreakPos = nCutPos; +/*M*/ xub_StrLen nX = nBreakPos; +/*M*/ +/*M*/ // we step back until a non blank character has been found +/*M*/ // or there is only one more character left +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ while( nX && nBreakPos > rInf.GetLineStart() + 1 && +/*M*/ ( CH_BLANK == ( cCutChar = rInf.GetChar( --nX ) ) || +/*M*/ CH_FULL_BLANK == cCutChar ) ) +/*M*/ --nBreakPos; +/*M*/ #else +/*M*/ while( nX && nBreakPos > rInf.GetLineStart() + 1 && +/*M*/ CH_BLANK == rInf.GetChar( --nX ) ) +/*M*/ --nBreakPos; +/*M*/ #endif +/*M*/ +/*M*/ if( nBreakPos > rInf.GetIdx() ) +/*M*/ nPorLen = nBreakPos - rInf.GetIdx(); +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ while( ++nCutPos < rInf.GetTxt().Len() && +/*M*/ ( CH_BLANK == ( cCutChar = rInf.GetChar( nCutPos ) ) || +/*M*/ CH_FULL_BLANK == cCutChar ) ) +/*M*/ ; // nothing +/*M*/ #else +/*M*/ while( ++nCutPos < rInf.GetTxt().Len() && +/*M*/ CH_BLANK == rInf.GetChar( nCutPos ) ) +/*M*/ ; // nothing +/*M*/ #endif +/*M*/ +/*M*/ nBreakStart = nCutPos; +/*M*/ } +/*M*/ else if( pBreakIt->xBreak.is() ) +/*M*/ { +/*M*/ // New: We should have a look into the last portion, if it was a +/*M*/ // field portion. For this, we expand the text of the field portion +/*M*/ // into our string. If the line break position is inside of before +/*M*/ // the field portion, we trigger an underflow. +/*M*/ +/*M*/ xub_StrLen nOldIdx = rInf.GetIdx(); +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ xub_Unicode cFldChr = 0; +/*M*/ #else +/*M*/ sal_Char cFldChr = 0; +/*M*/ #endif +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ XubString aDebugString; +/*M*/ #endif +/*M*/ +/*M*/ // be careful: a field portion can be both: 0x01 (common field) +/*M*/ // or 0x02 (the follow of a footnode) +/*M*/ if ( rInf.GetLast() && rInf.GetLast()->InFldGrp() && +/*M*/ ! rInf.GetLast()->IsFtnPortion() && +/*M*/ rInf.GetIdx() > rInf.GetLineStart() && +/*M*/ CH_TXTATR_BREAKWORD == +/*M*/ ( cFldChr = rInf.GetTxt().GetChar( rInf.GetIdx() - 1 ) ) ) +/*M*/ { +/*M*/ SwFldPortion* pFld = (SwFldPortion*)rInf.GetLast(); +/*M*/ XubString aTxt; +/*M*/ pFld->GetExpTxt( rInf, aTxt ); +/*M*/ +/*M*/ if ( aTxt.Len() ) +/*M*/ { +/*M*/ nFieldDiff = aTxt.Len() - 1; +/*M*/ nCutPos += nFieldDiff; +/*M*/ nHyphPos += nFieldDiff; +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ aDebugString = rInf.GetTxt(); +/*M*/ #endif +/*M*/ +/*M*/ XubString& rOldTxt = (XubString&)rInf.GetTxt(); +/*M*/ rOldTxt.Erase( rInf.GetIdx() - 1, 1 ); +/*M*/ rOldTxt.Insert( aTxt, rInf.GetIdx() - 1 ); +/*M*/ rInf.SetIdx( rInf.GetIdx() + nFieldDiff ); +/*M*/ } +/*M*/ else +/*M*/ cFldChr = 0; +/*M*/ } +/*M*/ +/*M*/ LineBreakHyphenationOptions aHyphOpt; +/*M*/ Reference< XHyphenator > xHyph; +/*M*/ if( bHyph ) +/*M*/ { +/*M*/ xHyph = ::binfilter::GetHyphenator(); +/*M*/ aHyphOpt = LineBreakHyphenationOptions( xHyph, +/*M*/ rInf.GetHyphValues(), nHyphPos ); +/*M*/ } +/*M*/ +/*N*/ // Get Language for break iterator. +/*N*/ // We have to switch the current language if we have a script +/*N*/ // change at nCutPos. Otherwise LATIN punctuation would never +/*N*/ // be allowed to be hanging punctuation. +/*N*/ // NEVER call GetLang if the string has been modified!!! +/*N*/ LanguageType aLang = rInf.GetFont()->GetLanguage(); +/*N*/ +/*N*/ // If we are inside a field portion, we use a temporar string which +/*N*/ // differs from the string at the textnode. Therefore we are not allowed +/*N*/ // to call the GetLang function. +/*N*/ if ( nCutPos && ! rPor.InFldGrp() ) +/*N*/ { +/*N*/ const CharClass& rCC = GetAppCharClass(); +/*N*/ +/*N*/ // step back until a non-punctuation character is reached +/*N*/ xub_StrLen nLangIndex = nCutPos; +/*N*/ +/*N*/ // If a field has been expanded right in front of us we do not +/*N*/ // step further than the beginning of the expanded field +/*N*/ // (which is the position of the field placeholder in our +/*N*/ // original string). +/*N*/ const xub_StrLen nDoNotStepOver = CH_TXTATR_BREAKWORD == cFldChr ? +/*N*/ rInf.GetIdx() - nFieldDiff - 1: +/*N*/ 0; +/*N*/ +/*N*/ while ( nLangIndex > nDoNotStepOver && +/*N*/ ! rCC.isLetterNumeric( rInf.GetTxt(), nLangIndex ) ) +/*N*/ --nLangIndex; +/*N*/ +/*N*/ // last "real" character is not inside our current portion +/*N*/ // we have to check the script type of the last "real" character +/*N*/ if ( nLangIndex < rInf.GetIdx() ) +/*N*/ { +/*N*/ USHORT nScript = pBreakIt->GetRealScriptOfText( rInf.GetTxt(), +/*N*/ nLangIndex ); +/*N*/ ASSERT( nScript, "Script is not between 1 and 4" ); +/*N*/ +/*N*/ // compare current script with script from last "real" character +/*N*/ if ( nScript - 1 != rInf.GetFont()->GetActual() ) +/*N*/ aLang = rInf.GetTxtFrm()->GetTxtNode()->GetLang( +/*N*/ CH_TXTATR_BREAKWORD == cFldChr ? +/*N*/ nDoNotStepOver : +/*N*/ nLangIndex, 0, nScript ); +/*N*/ } +/*N*/ } +/*N*/ +/*M*/ const ForbiddenCharacters aForbidden( +/*M*/ *rInf.GetTxtFrm()->GetNode()->GetDoc()-> +/*M*/ GetForbiddenCharacters( aLang, TRUE )); +/*M*/ +/*M*/ const sal_Bool bAllowHanging = rInf.IsHanging() && ! rInf.IsMulti() && +/*M*/ ! rPor.InFldGrp(); +/*M*/ +/*M*/ LineBreakUserOptions aUserOpt( +/*M*/ aForbidden.beginLine, aForbidden.endLine, +/*M*/ rInf.HasForbiddenChars(), bAllowHanging, sal_False ); +/*M*/ +/*M*/ // !!! We must have a local copy of the locale, because inside +/*M*/ // getLineBreak the LinguEventListener can trigger a new formatting, +/*M*/ // which can corrupt the locale pointer inside pBreakIt. +/*M*/ const ::com::sun::star::lang::Locale aLocale = pBreakIt->GetLocale( aLang ); +/*M*/ +/*M*/ // determines first possible line break from nRightPos to +/*M*/ // start index of current line +/*M*/ LineBreakResults aResult = pBreakIt->xBreak->getLineBreak( +/*M*/ rInf.GetTxt(), nCutPos, aLocale, +/*M*/ rInf.GetLineStart(), aHyphOpt, aUserOpt ); +/*M*/ +/*M*/ nBreakPos = (xub_StrLen)aResult.breakIndex; +/*M*/ +/*M*/ // if we are formatting multi portions we want to allow line breaks +/*M*/ // at the border between single line and multi line portion +/*M*/ // we have to be carefull with footnote portions, they always come in +/*M*/ // with an index 0 +/*M*/ if ( nBreakPos < rInf.GetLineStart() && rInf.IsFirstMulti() && +/*M*/ ! rInf.IsFtnInside() ) +/*M*/ nBreakPos = rInf.GetLineStart(); +/*M*/ +/*M*/ nBreakStart = nBreakPos; +/*M*/ +/*M*/ bHyph = BreakType::HYPHENATION == aResult.breakType; +/*M*/ +/*M*/ if ( bHyph && nBreakPos != STRING_LEN) +/*M*/ { +/*M*/ // found hyphenation position within line +/*M*/ // nBreakPos is set to the hyphenation position +/*M*/ xHyphWord = aResult.rHyphenatedWord; +/*M*/ nBreakPos += xHyphWord->getHyphenationPos() + 1; +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ // e.g., Schif-fahrt, referes to our string +/*M*/ const String aWord = xHyphWord->getWord(); +/*M*/ // e.g., Schiff-fahrt, referes to the word after hyphenation +/*M*/ const String aHyphenatedWord = xHyphWord->getHyphenatedWord(); +/*M*/ // e.g., Schif-fahrt: 5, referes to our string +/*M*/ const USHORT nHyphenationPos = xHyphWord->getHyphenationPos(); +/*M*/ // e.g., Schiff-fahrt: 6, referes to the word after hyphenation +/*M*/ const USHORT nHyphenPos = xHyphWord->getHyphenPos(); +/*M*/ #endif +/*M*/ +/*M*/ // if not in interactive mode, we have to break behind a soft hyphen +/*M*/ if ( ! rInf.IsInterHyph() && rInf.GetIdx() ) +/*M*/ { +/*M*/ const long nSoftHyphPos = +/*M*/ xHyphWord->getWord().indexOf( CHAR_SOFTHYPHEN ); +/*M*/ +/*M*/ if ( nSoftHyphPos >= 0 && +/*M*/ nBreakStart + nSoftHyphPos <= nBreakPos && +/*M*/ nBreakPos > rInf.GetLineStart() ) +/*M*/ nBreakPos = rInf.GetIdx() - 1; +/*M*/ } +/*M*/ +/*M*/ if( nBreakPos >= rInf.GetIdx() ) +/*M*/ { +/*M*/ nPorLen = nBreakPos - rInf.GetIdx(); +/*M*/ if( '-' == rInf.GetTxt().GetChar( nBreakPos - 1 ) ) +/*M*/ xHyphWord = NULL; +/*M*/ } +/*M*/ } +/*M*/ else if ( !bHyph && nBreakPos >= rInf.GetLineStart() ) +/*M*/ { +/*M*/ ASSERT( nBreakPos != STRING_LEN, "we should have found a break pos" ); +/*M*/ +/*M*/ // found break position within line +/*M*/ xHyphWord = NULL; +/*M*/ +/*M*/ // check, if break position is soft hyphen and an underflow +/*M*/ // has to be triggered +/*M*/ if( nBreakPos > rInf.GetLineStart() && rInf.GetIdx() && +/*M*/ CHAR_SOFTHYPHEN == rInf.GetTxt().GetChar( nBreakPos - 1 ) ) +/*M*/ nBreakPos = rInf.GetIdx() - 1; +/*M*/ +/*M*/ // Delete any blanks at the end of a line, but be careful: +/*M*/ // If a field has been expanded, we do not want to delete any +/*M*/ // blanks inside the field portion. This would cause an unwanted +/*M*/ // underflow +/*M*/ xub_StrLen nX = nBreakPos; +/*M*/ #ifdef VERTICAL_LAYOUT +/*M*/ while( nX > rInf.GetLineStart() && +/*M*/ ( CH_TXTATR_BREAKWORD != cFldChr || nX > rInf.GetIdx() ) && +/*M*/ ( CH_BLANK == rInf.GetChar( --nX ) || +/*M*/ CH_FULL_BLANK == rInf.GetChar( nX ) ) ) +/*M*/ nBreakPos = nX; +/*M*/ #else +/*M*/ while( nX > rInf.GetLineStart() && +/*M*/ ( CH_TXTATR_BREAKWORD != cFldChr || nX > rInf.GetIdx() ) && +/*M*/ CH_BLANK == rInf.GetChar(--nX) ) +/*M*/ nBreakPos = nX; +/*M*/ #endif +/*M*/ if( nBreakPos > rInf.GetIdx() ) +/*M*/ nPorLen = nBreakPos - rInf.GetIdx(); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ // no line break found, setting nBreakPos to STRING_LEN +/*M*/ // causes a break cut +/*M*/ nBreakPos = STRING_LEN; +/*M*/ ASSERT( nCutPos >= rInf.GetIdx(), "Deep cut" ); +/*M*/ nPorLen = nCutPos - rInf.GetIdx(); +/*M*/ } +/*M*/ +/*M*/ if( nBreakPos > nCutPos && nBreakPos != STRING_LEN ) +/*M*/ { +/*M*/ const xub_StrLen nHangingLen = nBreakPos - nCutPos; +/*M*/ SwPosSize aTmpSize = rInf.GetTxtSize( &rSI, nCutPos, +/*M*/ nHangingLen, 0 ); +/*M*/ ASSERT( !pHanging, "A hanging portion is hanging around" ); +/*M*/ pHanging = new SwHangingPortion( aTmpSize ); +/*M*/ pHanging->SetLen( nHangingLen ); +/*M*/ nPorLen = nCutPos - rInf.GetIdx(); +/*M*/ } +/*M*/ +/*M*/ // If we expanded a field, we must repair the original string. +/*M*/ // In case we do not trigger an underflow, we correct the nBreakPos +/*M*/ // value, but we cannot correct the nBreakStart value: +/*M*/ // If we have found a hyphenation position, nBreakStart can lie before +/*M*/ // the field. +/*M*/ if ( CH_TXTATR_BREAKWORD == cFldChr ) +/*M*/ { +/*M*/ if ( nBreakPos < rInf.GetIdx() ) +/*M*/ nBreakPos = nOldIdx - 1; +/*M*/ else if ( STRING_LEN != nBreakPos ) +/*M*/ { +/*M*/ ASSERT( nBreakPos >= nFieldDiff, "I've got field trouble!" ); +/*M*/ nBreakPos -= nFieldDiff; +/*M*/ } +/*M*/ +/*M*/ ASSERT( nCutPos >= rInf.GetIdx() && nCutPos >= nFieldDiff, +/*M*/ "I've got field trouble, part2!" ); +/*M*/ nCutPos -= nFieldDiff; +/*M*/ +/*M*/ XubString& rOldTxt = (XubString&)rInf.GetTxt(); +/*M*/ rOldTxt.Erase( nOldIdx - 1, nFieldDiff + 1 ); +/*M*/ rOldTxt.Insert( cFldChr, nOldIdx - 1 ); +/*M*/ rInf.SetIdx( nOldIdx ); +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ ASSERT( aDebugString == rInf.GetTxt(), +/*M*/ "Somebody, somebody, somebody put something in my string" ); +/*M*/ #endif +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if( nPorLen ) +/*M*/ { +/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nPorLen, +/*M*/ nMaxComp, nMinSize, nMaxSizeDiff ); +/*M*/ +/*M*/ // save maximum width for later use +/*M*/ if ( nMaxSizeDiff ) +/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff ); +/*M*/ +/*M*/ nBreakWidth = nItalic + nMinSize; +/*M*/ } +/*M*/ else +/*M*/ nBreakWidth = 0; +/*M*/ +/*M*/ if( pHanging ) +/*M*/ nBreakPos = nCutPos; +/*M*/ +/*M*/ return sal_False; +/*M*/ } + +/************************************************************************* + * SwTxtGuess::AlternativeSpelling + *************************************************************************/ + +// returns true if word at position nPos has a diffenrent spelling +// if hyphenated at this position (old german spelling) + +/*N*/ sal_Bool SwTxtGuess::AlternativeSpelling( const SwTxtFormatInfo &rInf, +/*N*/ const xub_StrLen nPos ) +/*N*/ { +/*N*/ // get word boundaries +/*N*/ xub_StrLen nWordLen; +/*N*/ +/*N*/ Boundary aBound = +/*N*/ pBreakIt->xBreak->getWordBoundary( rInf.GetTxt(), nPos, +/*N*/ pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ), +/*N*/ WordType::DICTIONARY_WORD, sal_True ); +/*N*/ nBreakStart = (xub_StrLen)aBound.startPos; +/*N*/ nWordLen = aBound.endPos - nBreakStart; +/*N*/ +/*N*/ // if everything else fails, we want to cut at nPos +/*N*/ nCutPos = nPos; +/*N*/ +/*N*/ XubString aTxt( rInf.GetTxt().Copy( nBreakStart, nWordLen ) ); +/*N*/ +/*N*/ // check, if word has alternative spelling +/*N*/ Reference< XHyphenator > xHyph( ::binfilter::GetHyphenator() ); +/*N*/ ASSERT( xHyph.is(), "Hyphenator is missing"); +/*N*/ //! subtract 1 since the UNO-interface is 0 based +/*N*/ xHyphWord = xHyph->queryAlternativeSpelling( OUString(aTxt), +/*N*/ pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ), +/*N*/ nPos - nBreakStart, rInf.GetHyphValues() ); +/*N*/ return xHyphWord.is() && xHyphWord->isAlternativeSpelling(); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_inftxt.cxx b/binfilter/bf_sw/source/core/text/sw_inftxt.cxx new file mode 100644 index 000000000000..a721a47c7da5 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_inftxt.cxx @@ -0,0 +1,1029 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <com/sun/star/uno/Sequence.h> + +#include <bf_svtools/linguprops.hxx> + +#include <hintids.hxx> + +#include <bf_svtools/ctloptions.hxx> +#include <bf_sfx2/printer.hxx> +#include <bf_svx/hyznitem.hxx> +#include <bf_svx/hngpnctitem.hxx> +#include <bf_svx/scriptspaceitem.hxx> +#include <bf_svx/pgrditem.hxx> +#include <breakit.hxx> +#include <bf_svx/forbiddenruleitem.hxx> +#include <swmodule.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <tools/shl.hxx> +#include <viewsh.hxx> // ViewShell + +#include <horiornt.hxx> + +#include <doc.hxx> // SwDoc +#include <paratr.hxx> // SwFmtDrop +#include <inftxt.hxx> // SwTxtInfo +#include <noteurl.hxx> // SwNoteURL +#include <porftn.hxx> // SwFtnPortion +#include <frmsh.hxx> +#include <itratr.hxx> +namespace binfilter { + +using namespace ::com::sun::star; +using namespace ::com::sun::star::linguistic2; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; + +#define C2U(cChar) ::rtl::OUString::createFromAscii(cChar) +#define CHAR_UNDERSCORE ((sal_Unicode)0x005F) +#define CHAR_LEFT_ARROW ((sal_Unicode)0x25C0) +#define CHAR_RIGHT_ARROW ((sal_Unicode)0x25B6) +#define CHAR_TAB ((sal_Unicode)0x2192) +#define CHAR_TAB_RTL ((sal_Unicode)0x2190) +#define CHAR_LINEBREAK ((sal_Unicode)0x21B5) +#define CHAR_LINEBREAK_RTL ((sal_Unicode)0x21B3) + +#ifdef BIDI +#define DRAW_SPECIAL_OPTIONS_CENTER 1 +#define DRAW_SPECIAL_OPTIONS_ROTATE 2 +#endif + +// steht im number.cxx +extern const sal_Char __FAR_DATA sBulletFntName[]; + +// OD 24.01.2003 #106593# - no longer needed, included in <frmtool.hxx> +//extern void MA_FASTCALL SwAlignRect( SwRect &rRect, ViewShell *pSh ); + +#ifdef DBG_UTIL +// Test2: WYSIWYG++ +// Test4: WYSIWYG debug +static sal_Bool bDbgLow = sal_False; +#endif + +#ifdef DBG_UTIL + + +#endif + +/************************************************************************* + * SwLineInfo::SwLineInfo() + *************************************************************************/ + +/*N*/ void SwLineInfo::CtorInit( const SwAttrSet& rAttrSet ) +/*N*/ { +/*N*/ pRuler = &rAttrSet.GetTabStops(); +/*N*/ pSpace = &rAttrSet.GetLineSpacing(); +/*N*/ nVertAlign = rAttrSet.GetParaVertAlign().GetValue(); +/*N*/ nDefTabStop = MSHRT_MAX; +/*N*/ } + +/************************************************************************* + * SwTxtInfo::CtorInit() + *************************************************************************/ + +/*N*/ void SwTxtInfo::CtorInit( SwTxtFrm *pFrm ) +/*N*/ { +/*N*/ pPara = pFrm->GetPara(); +/*N*/ nTxtStart = pFrm->GetOfst(); +/*N*/ if( !pPara ) +/*N*/ { +/*?*/ ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" ); +/*?*/ pFrm->Format(); +/*?*/ pPara = pFrm->GetPara(); +/*N*/ } +/*N*/ } + +/*N*/ SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf ) +/*N*/ : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ), +/*N*/ nTxtStart( rInf.GetTxtStart() ) +/*N*/ { } + + +#ifdef DBG_UTIL +/************************************************************************* + * ChkOutDev() + *************************************************************************/ + +/*N*/ void ChkOutDev( const SwTxtSizeInfo &rInf ) +/*N*/ { +/*N*/ if ( !rInf.GetVsh() ) +/*N*/ return; +/*N*/ +/*N*/ const OutputDevice *pOut = rInf.GetOut(); +/*N*/ const OutputDevice *pWin = rInf.GetVsh()->GetWin(); +/*N*/ const OutputDevice *pRef = rInf.GetRefDev(); +/*N*/ ASSERT( pOut && pRef, "ChkOutDev: invalid output devices" ) +/*N*/ } +/*N*/ #endif // PRODUCT + + +/*N*/ inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf ) +/*N*/ { +/*N*/ const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen(); +/*N*/ return Min( rInf.GetTxt().Len(), nInfLen ); +/*N*/ } + + +/*N*/ SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew ) +/*N*/ : SwTxtInfo( rNew ), +/*N*/ pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()), +/*N*/ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()), +/*N*/ pOut(((SwTxtSizeInfo&)rNew).GetOut()), +/*N*/ pRef(((SwTxtSizeInfo&)rNew).GetRefDev()), +/*N*/ pFnt(((SwTxtSizeInfo&)rNew).GetFont()), +/*N*/ pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()), +/*N*/ pFrm(rNew.pFrm), +/*N*/ pOpt(&rNew.GetOpt()), +/*N*/ pTxt(&rNew.GetTxt()), +/*N*/ nIdx(rNew.GetIdx()), +/*N*/ nLen(rNew.GetLen()), +/*N*/ nKanaIdx( rNew.GetKanaIdx() ), +/*N*/ bOnWin( rNew.OnWin() ), +/*N*/ bNotEOL( rNew.NotEOL() ), +/*N*/ bURLNotify( rNew.URLNotify() ), +/*N*/ bStopUnderFlow( rNew.StopUnderFlow() ), +/*N*/ bFtnInside( rNew.IsFtnInside() ), +/*N*/ bMulti( rNew.IsMulti() ), +/*N*/ bFirstMulti( rNew.IsFirstMulti() ), +/*N*/ bRuby( rNew.IsRuby() ), +/*N*/ bHanging( rNew.IsHanging() ), +/*N*/ bScriptSpace( rNew.HasScriptSpace() ), +/*N*/ bForbiddenChars( rNew.HasForbiddenChars() ), +/*N*/ bSnapToGrid( rNew.SnapToGrid() ), +/*N*/ nDirection( rNew.GetDirection() ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ ChkOutDev( *this ); +/*N*/ #endif +/*N*/ } + +/*N*/ void SwTxtSizeInfo::CtorInit( SwTxtFrm *pFrame, SwFont *pNewFnt, +/*N*/ const xub_StrLen nNewIdx, const xub_StrLen nNewLen ) +/*N*/ { +/*N*/ pKanaComp = NULL; +/*N*/ nKanaIdx = 0; +/*N*/ pFrm = pFrame; +/*N*/ SwTxtInfo::CtorInit( pFrm ); +/*N*/ const SwTxtNode *pNd = pFrm->GetTxtNode(); +/*N*/ pVsh = pFrm->GetShell(); +/*N*/ +/*N*/ // Get the output and reference device +/*N*/ if ( pVsh ) +/*N*/ { +/*N*/ pOut = pVsh->GetOut(); +/*N*/ pRef = &pVsh->GetRefDev(); +/*N*/ bOnWin = pVsh->GetWin() || OUTDEV_WINDOW == pOut->GetOutDevType(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein. +/*N*/ if ( pNd->GetDoc()->IsBrowseMode() ) //?!?!?!? +/*N*/ //in Ermangelung eines Besseren kann hier ja wohl nur noch das +/*N*/ //AppWin genommen werden? +/*N*/ pOut = GetpApp()->GetDefaultDevice(); +/*N*/ else +/*N*/ pOut = pNd->GetDoc()->GetPrt(); //Muss es geben (oder sal_True uebergeben?) +/*N*/ pRef = pOut; +/*N*/ } +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ ChkOutDev( *this ); +/*N*/ #endif +/*N*/ +/*N*/ // Set default layout mode ( LTR or RTL ). +/*N*/ if ( pFrm->IsRightToLeft() ) +/*N*/ { +/*N*/ pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL ); +/*N*/ pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL ); +/*N*/ nDirection = DIR_RIGHT2LEFT; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG ); +/*N*/ pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG ); +/*N*/ nDirection = DIR_LEFT2RIGHT; +/*N*/ } +/*N*/ +/*N*/ LanguageType eLang; +/*N*/ const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions(); +/*N*/ if ( SvtCTLOptions::NUMERALS_HINDI == rCTLOptions.GetCTLTextNumerals() ) +/*N*/ eLang = LANGUAGE_ARABIC_SAUDI_ARABIA; +/*N*/ else if ( SvtCTLOptions::NUMERALS_ARABIC == rCTLOptions.GetCTLTextNumerals() ) +/*N*/ eLang = LANGUAGE_ENGLISH; +/*N*/ else +/*N*/ eLang = (LanguageType)::binfilter::GetAppLanguage(); +/*N*/ +/*N*/ pOut->SetDigitLanguage( eLang ); +/*N*/ pRef->SetDigitLanguage( eLang ); +/*N*/ +/*N*/ // +/*N*/ // The Options +/*N*/ // +/*N*/ pOpt = pVsh ? +/*N*/ pVsh->GetViewOptions() : +/*N*/ SW_MOD()->GetViewOption(pNd->GetDoc()->IsHTMLMode()); //Options vom Module wg. StarONE +/*N*/ +/*N*/ // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet +/*N*/ // TODO: Aufdröseln +/*N*/ bURLNotify = pNoteURL && !bOnWin; +/*N*/ // bURLNotify = pNoteURL && !bOnWin +/*N*/ // && (pOut && OUTDEV_PRINTER != pOut->GetOutDevType()); +/*N*/ +/*N*/ SetSnapToGrid( pNd->GetSwAttrSet().GetParaGrid().GetValue() && +/*N*/ pFrm->IsInDocBody() ); +/*N*/ +/*N*/ pFnt = pNewFnt; +/*N*/ pUnderFnt = 0; +/*N*/ pTxt = &pNd->GetTxt(); +/*N*/ +/*N*/ nIdx = nNewIdx; +/*N*/ nLen = nNewLen; +/*N*/ bNotEOL = sal_False; +/*N*/ bStopUnderFlow = bFtnInside = sal_False; +/*N*/ bMulti = bFirstMulti = bRuby = bHanging = bScriptSpace = +/*N*/ bForbiddenChars = sal_False; +/*N*/ #ifndef BIDI +/*N*/ nDirection = DIR_LEFT2RIGHT; +/*N*/ #endif +/*N*/ +/*N*/ SetLen( GetMinLen( *this ) ); +/*N*/ } + +/*N*/ SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt, +/*N*/ const xub_StrLen nIdx, const xub_StrLen nLen ) +/*N*/ : SwTxtInfo( rNew ), +/*N*/ pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()), +/*N*/ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()), +/*N*/ pOut(((SwTxtSizeInfo&)rNew).GetOut()), +/*N*/ pRef(((SwTxtSizeInfo&)rNew).GetRefDev()), +/*N*/ pFnt(((SwTxtSizeInfo&)rNew).GetFont()), +/*N*/ pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()), +/*N*/ pFrm( rNew.pFrm ), +/*N*/ pOpt(&rNew.GetOpt()), +/*N*/ pTxt(&rTxt), +/*N*/ nIdx(nIdx), +/*N*/ nLen(nLen), +/*N*/ nKanaIdx( rNew.GetKanaIdx() ), +/*N*/ bOnWin( rNew.OnWin() ), +/*N*/ bNotEOL( rNew.NotEOL() ), +/*N*/ bURLNotify( rNew.URLNotify() ), +/*N*/ bStopUnderFlow( rNew.StopUnderFlow() ), +/*N*/ bFtnInside( rNew.IsFtnInside() ), +/*N*/ bMulti( rNew.IsMulti() ), +/*N*/ bFirstMulti( rNew.IsFirstMulti() ), +/*N*/ bRuby( rNew.IsRuby() ), +/*N*/ bHanging( rNew.IsHanging() ), +/*N*/ bScriptSpace( rNew.HasScriptSpace() ), +/*N*/ bForbiddenChars( rNew.HasForbiddenChars() ), +/*N*/ bSnapToGrid( rNew.SnapToGrid() ), +/*N*/ nDirection( rNew.GetDirection() ) +/*N*/ { +/*N*/ #ifdef DBG_UTIL +/*N*/ ChkOutDev( *this ); +/*N*/ #endif +/*N*/ SetLen( GetMinLen( *this ) ); +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::SelectFont() + *************************************************************************/ + +/*N*/ void SwTxtSizeInfo::SelectFont() +/*N*/ { +/*N*/ // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet +/*N*/ // der FontMetricCache durcheinander. In diesem Fall steht pLastMet +/*N*/ // auf dem alten Wert. +/*N*/ // Falsch: GetOut()->SetFont( GetFont()->GetFnt() ); +/*N*/ GetFont()->Invalidate(); +/*N*/ GetFont()->ChgPhysFnt( pVsh, GetOut() ); +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::NoteAnimation() + *************************************************************************/ + + +/************************************************************************* + * SwTxtSizeInfo::GetTxtSize() + *************************************************************************/ + +/*N*/ SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev, +/*N*/ const SwScriptInfo* pSI, +/*N*/ const XubString& rTxt, +/*N*/ const xub_StrLen nIdx, +/*N*/ const xub_StrLen nLen, +/*N*/ const USHORT nComp ) const +/*N*/ { +/*N*/ SwDrawTextInfo aDrawInf( pVsh, *pOutDev, pSI, rTxt, nIdx, nLen ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetFont( pFnt ); +/*N*/ aDrawInf.SetSnapToGrid( SnapToGrid() ); +/*N*/ aDrawInf.SetKanaComp( nComp ); +/*N*/ SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf ); +/*N*/ return aSize; +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::GetTxtSize() + *************************************************************************/ + +/*N*/ SwPosSize SwTxtSizeInfo::GetTxtSize() const +/*N*/ { +/*N*/ const SwScriptInfo& rSI = +/*N*/ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); +/*N*/ +/*N*/ // in some cases, compression is not allowed or surpressed for +/*N*/ // performance reasons +/*N*/ USHORT nComp =( SW_CJK == GetFont()->GetActual() && +/*N*/ rSI.CountCompChg() && +/*N*/ ! IsMulti() ) ? +/*N*/ GetKanaComp() : +/*N*/ 0 ; +/*N*/ +/*N*/ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rSI, *pTxt, nIdx, nLen ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetFont( pFnt ); +/*N*/ aDrawInf.SetSnapToGrid( SnapToGrid() ); +/*N*/ aDrawInf.SetKanaComp( nComp ); +/*N*/ return pFnt->_GetTxtSize( aDrawInf ); +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::GetTxtSize() + *************************************************************************/ + +/*N*/ void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIdx, +/*N*/ const xub_StrLen nLen, const USHORT nComp, +/*N*/ USHORT& nMinSize, USHORT& nMaxSizeDiff ) const +/*N*/ { +/*N*/ SwDrawTextInfo aDrawInf( pVsh, *pOut, pSI, *pTxt, nIdx, nLen ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetFont( pFnt ); +/*N*/ aDrawInf.SetSnapToGrid( SnapToGrid() ); +/*N*/ aDrawInf.SetKanaComp( nComp ); +/*N*/ SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf ); +/*N*/ nMaxSizeDiff = (USHORT)aDrawInf.GetKanaDiff(); +/*N*/ nMinSize = aSize.Width(); +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::GetTxtBreak() + *************************************************************************/ + + +/************************************************************************* + * SwTxtSizeInfo::GetTxtBreak() + *************************************************************************/ + +/*N*/ xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth, +/*N*/ const xub_StrLen nMaxLen, +/*N*/ const USHORT nComp ) const +/*N*/ { +/*N*/ const SwScriptInfo& rScriptInfo = +/*N*/ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); +/*N*/ +/*N*/ ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" ) +/*N*/ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo, +/*N*/ *pTxt, GetIdx(), nMaxLen ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetFont( pFnt ); +/*N*/ aDrawInf.SetSnapToGrid( SnapToGrid() ); +/*N*/ aDrawInf.SetKanaComp( nComp ); +/*N*/ aDrawInf.SetHyphPos( 0 ); +/*N*/ +/*N*/ return pFnt->GetTxtBreak( aDrawInf, nLineWidth ); +/*N*/ } + +/************************************************************************* + * SwTxtSizeInfo::GetTxtBreak() + *************************************************************************/ + +/*N*/ xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth, +/*N*/ const xub_StrLen nMaxLen, +/*N*/ const USHORT nComp, +/*N*/ xub_StrLen& rExtraCharPos ) const +/*N*/ { +/*N*/ const SwScriptInfo& rScriptInfo = +/*N*/ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo(); +/*N*/ +/*N*/ ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" ) +/*N*/ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo, +/*N*/ *pTxt, GetIdx(), nMaxLen ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetFont( pFnt ); +/*N*/ aDrawInf.SetSnapToGrid( SnapToGrid() ); +/*N*/ aDrawInf.SetKanaComp( nComp ); +/*N*/ aDrawInf.SetHyphPos( &rExtraCharPos ); +/*N*/ +/*N*/ return pFnt->GetTxtBreak( aDrawInf, nLineWidth ); +/*N*/ } + +/************************************************************************* + * SwTxtPaintInfo::CtorInit() + *************************************************************************/ + +/*N*/ void SwTxtPaintInfo::CtorInit( SwTxtFrm *pFrame, const SwRect &rPaint ) +/*N*/ { +/*N*/ SwTxtSizeInfo::CtorInit( pFrame ); +/*N*/ aTxtFly.CtorInit( pFrame ), +/*N*/ aPaintRect = rPaint; +/*N*/ nSpaceIdx = 0; +/*N*/ pSpaceAdd = NULL; +/*N*/ pWrongList = NULL; +/*N*/ #ifndef DBG_UTIL +/*N*/ pBrushItem = 0; +/*N*/ #else +/*N*/ pBrushItem = ((SvxBrushItem*)-1); +/*N*/ #endif +/*N*/ } + + +/*N*/ SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf ) +/*N*/ : SwTxtSizeInfo( rInf ), +/*N*/ aTxtFly( *rInf.GetTxtFly() ), +/*N*/ aPos( rInf.GetPos() ), +/*N*/ aPaintRect( rInf.GetPaintRect() ), +/*N*/ nSpaceIdx( rInf.GetSpaceIdx() ), +/*N*/ pSpaceAdd( rInf.GetpSpaceAdd() ), +/*N*/ pWrongList( rInf.GetpWrongList() ), +/*N*/ pBrushItem( rInf.GetBrushItem() ) +/*N*/ { } + +extern Color aGlobalRetoucheColor; + +/************************************************************************* + * lcl_IsDarkBackground + * + * Returns if the current background color is dark. + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::_DrawText() + *************************************************************************/ + + +/************************************************************************* + * lcl_CalcRect() + *************************************************************************/ + + +/************************************************************************* + * lcl_DrawSpecial + * + * Draws a special portion, e.g., line break portion, tab portion. + * rPor - The portion + * rRect - The rectangle surrounding the character + * pCol - Specify a color for the character + * bCenter - Draw the character centered, otherwise left aligned + * bRotate - Rotate the character if character rotation is set + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::DrawRect() + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::DrawTab() + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::DrawLineBreak() + *************************************************************************/ + + + +/************************************************************************* + * SwTxtPaintInfo::DrawRedArrow() + *************************************************************************/ + + + +/************************************************************************* + * SwTxtPaintInfo::DrawPostIts() + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::DrawBackGround() + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::DrawViewOpt() + *************************************************************************/ + + +/************************************************************************* + * SwTxtPaintInfo::_NotifyURL() + *************************************************************************/ + + +/************************************************************************* + * lcl_InitHyphValues() + *************************************************************************/ + +/*N*/ static void lcl_InitHyphValues( PropertyValues &rVals, +/*N*/ INT16 nMinLeading, INT16 nMinTrailing ) +/*N*/ { +/*N*/ INT32 nLen = rVals.getLength(); +/*N*/ +/*N*/ if (0 == nLen) // yet to be initialized? +/*N*/ { +/*N*/ rVals.realloc( 2 ); +/*N*/ PropertyValue *pVal = rVals.getArray(); +/*N*/ +/*N*/ pVal[0].Name = C2U( UPN_HYPH_MIN_LEADING ); +/*N*/ pVal[0].Handle = UPH_HYPH_MIN_LEADING; +/*N*/ pVal[0].Value <<= nMinLeading; +/*N*/ +/*N*/ pVal[1].Name = C2U( UPN_HYPH_MIN_TRAILING ); +/*N*/ pVal[1].Handle = UPH_HYPH_MIN_TRAILING; +/*N*/ pVal[1].Value <<= nMinTrailing; +/*N*/ } +/*N*/ else if (2 == nLen) // already initialized once? +/*N*/ { +/*?*/ PropertyValue *pVal = rVals.getArray(); +/*?*/ pVal[0].Value <<= nMinLeading; +/*?*/ pVal[1].Value <<= nMinTrailing; +/*?*/ } +/*?*/ else +/*?*/ DBG_ERROR( "unxpected size of sequence" ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::GetHyphValues() + *************************************************************************/ +/*N*/ +/*N*/ const PropertyValues & SwTxtFormatInfo::GetHyphValues() const +/*N*/ { +/*N*/ DBG_ASSERT( 2 == aHyphVals.getLength(), +/*N*/ "hyphenation values not yet initialized" ); +/*N*/ return aHyphVals; +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::InitHyph() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyph ) +/*N*/ { +/*N*/ const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet(); +/*N*/ SetHanging( rAttrSet.GetHangingPunctuation().GetValue() ); +/*N*/ SetScriptSpace( rAttrSet.GetScriptSpace().GetValue() ); +/*N*/ SetForbiddenChars( rAttrSet.GetForbiddenRule().GetValue() ); +/*N*/ const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone(); +/*N*/ MaxHyph() = rAttr.GetMaxHyphens(); +/*N*/ sal_Bool bAuto = bAutoHyph || rAttr.IsHyphen(); +/*N*/ if( bAuto || bInterHyph ) +/*N*/ { +/*N*/ nHyphStart = nHyphWrdStart = STRING_LEN; +/*N*/ nHyphWrdLen = 0; +/*N*/ +/*N*/ INT16 nMinLeading = Max(rAttr.GetMinLead(), sal_uInt8(2)); +/*N*/ INT16 nMinTrailing = rAttr.GetMinTrail(); +/*N*/ lcl_InitHyphValues( aHyphVals, nMinLeading, nMinTrailing); +/*N*/ } +/*N*/ return bAuto; +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::CtorInit() + *************************************************************************/ + +/*N*/ void SwTxtFormatInfo::CtorInit( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph, +/*N*/ const sal_Bool bNewQuick, const sal_Bool bTst ) +/*N*/ { +/*N*/ SwTxtPaintInfo::CtorInit( pNewFrm, SwRect() ); +/*N*/ +/*N*/ bQuick = bNewQuick; +/*N*/ bInterHyph = bNewInterHyph; +/*N*/ +/*N*/ //! needs to be done in this order +/*N*/ nMinLeading = 2; +/*N*/ nMinTrailing = 2; +/*N*/ nMinWordLength = 0; +/*N*/ bAutoHyph = InitHyph(); +/*N*/ +/*N*/ bIgnoreFly = sal_False; +/*N*/ bFakeLineStart = sal_False; +/*N*/ bShift = sal_False; +/*N*/ bDropInit = sal_False; +/*N*/ bTestFormat = bTst; +/*N*/ nLeft = 0; +/*N*/ nRight = 0; +/*N*/ nFirst = 0; +/*N*/ nRealWidth = 0; +/*N*/ nForcedLeftMargin = 0; +/*N*/ pRest = 0; +/*N*/ nLineHeight = 0; +/*N*/ nLineNettoHeight = 0; +/*N*/ SetLineStart(0); +/*N*/ Init(); +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::IsHyphenate() + *************************************************************************/ +// Trennen oder nicht trennen, das ist hier die Frage: +// - in keinem Fall trennen, wenn der Hyphenator ERROR zurueckliefert, +// oder wenn als Sprache NOLANGUAGE eingestellt ist. +// - ansonsten immer trennen, wenn interaktive Trennung vorliegt +// - wenn keine interakt. Trennung, dann nur trennen, wenn im ParaFmt +// automatische Trennung eingestellt ist. + +/*N*/ sal_Bool SwTxtFormatInfo::IsHyphenate() const +/*N*/ { +/*N*/ if( !bInterHyph && !bAutoHyph ) +/*N*/ return sal_False; +/*N*/ +/*N*/ LanguageType eTmp = GetFont()->GetLanguage(); +/*N*/ if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp ) +/*N*/ return sal_False; +/*N*/ +/*N*/ uno::Reference< XHyphenator > xHyph = ::binfilter::GetHyphenator(); +/*N*/ if (bInterHyph && xHyph.is()) +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SvxSpellWrapper::CheckHyphLang( xHyph, eTmp ); +/*N*/ +/*N*/ if( !xHyph.is() || !xHyph->hasLocale( pBreakIt->GetLocale(eTmp) ) ) +/*N*/ return sal_False; +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::GetDropFmt() + *************************************************************************/ + +// Dropcaps vom SwTxtFormatter::CTOR gerufen. +/*N*/ const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const +/*N*/ { +/*N*/ const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop(); +/*N*/ if( 1 >= pDrop->GetLines() || +/*N*/ ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) ) +/*N*/ pDrop = 0; +/*N*/ return pDrop; +/*N*/ } + +/************************************************************************* + * SwTxtFormatInfo::Init() + *************************************************************************/ + +/*N*/ void SwTxtFormatInfo::Init() +/*N*/ { +/*N*/ // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth +/*N*/ X(0); +/*N*/ bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph = +/*N*/ bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False; +/*N*/ +/*N*/ // generally we do not allow number portions in follows, except... +/*N*/ if ( GetTxtFrm()->IsFollow() ) +/*N*/ { +/*N*/ const SwTxtFrm* pMaster = GetTxtFrm()->FindMaster(); +/*N*/ const SwLinePortion* pPara = pMaster->GetPara(); +/*N*/ +/*N*/ // there is a master for this follow and the master does not have +/*N*/ // any contents (especially it does not have a number portion) +/*N*/ bNumDone = ! pPara || +/*N*/ ! ((SwParaPortion*)pPara)->GetFirstPortion()->IsFlyPortion(); +/*N*/ } +/*N*/ +/*N*/ pRoot = 0; +/*N*/ pLast = 0; +/*N*/ pFly = 0; +/*N*/ pLastFld = 0; +/*N*/ pLastTab = 0; +/*N*/ pUnderFlow = 0; +/*N*/ cTabDecimal = 0; +/*N*/ nWidth = nRealWidth; +/*N*/ nForcedLeftMargin = 0; +/*N*/ nSoftHyphPos = 0; +/*N*/ nUnderScorePos = STRING_LEN; +/*N*/ cHookChar = 0; +/*N*/ SetIdx(0); +/*N*/ SetLen( GetTxt().Len() ); +/*N*/ SetPaintOfst(0); +/*N*/ } + +/*-----------------16.10.00 11:39------------------- + * There are a few differences between a copy constructor + * and the following constructor for multi-line formatting. + * The root is the first line inside the multi-portion, + * the line start is the actual position in the text, + * the line width is the rest width from the surrounding line + * and the bMulti and bFirstMulti-flag has to be set correctly. + * --------------------------------------------------*/ + + +/************************************************************************* + * SwTxtFormatInfo::_CheckFtnPortion() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr ) +/*N*/ { +/*N*/ KSHORT nHeight = pCurr->GetRealHeight(); +/*N*/ SwLinePortion *pPor = pCurr->GetPortion(); +/*N*/ sal_Bool bRet = sal_False; +/*N*/ while( pPor ) +/*N*/ { +/*N*/ if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() ) +/*N*/ { +/*?*/ bRet = sal_True; +/*?*/ SetLineHeight( nHeight ); +/*?*/ SetLineNettoHeight( pCurr->Height() ); +/*?*/ break; +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + + + +/************************************************************************* + * SwTxtFormatInfo::ScanPortionEnd() + *************************************************************************/ +/*N*/ xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart, +/*N*/ const xub_StrLen nEnd ) +/*N*/ { +/*N*/ cHookChar = 0; +/*N*/ const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0; +/*N*/ xub_StrLen i = nStart; +/*N*/ +/*N*/ // Removed for i7288. bSkip used to be passed from SwFldPortion::Format +/*N*/ // as IsFollow(). Therefore more than one special character was not +/*N*/ // handled correctly at the beginning of follow fields. +/*N*/ // if ( bSkip && i < nEnd ) +/*N*/ // ++i; +/*N*/ +/*N*/ for( ; i < nEnd; ++i ) +/*N*/ { +/*N*/ const xub_Unicode cPos = GetChar( i ); +/*N*/ switch( cPos ) +/*N*/ { +/*N*/ case CH_TXTATR_BREAKWORD: +/*N*/ case CH_TXTATR_INWORD: +/*N*/ if( !HasHint( i )) +/*N*/ break; +/*N*/ // no break; +/*N*/ +/*N*/ case CHAR_SOFTHYPHEN: +/*N*/ case CHAR_HARDHYPHEN: +/*N*/ case CHAR_HARDBLANK: +/*N*/ case CH_TAB: +/*N*/ case CH_BREAK: +/*N*/ cHookChar = cPos; +/*N*/ return i; +/*N*/ +/*N*/ case CHAR_UNDERSCORE: +/*N*/ if ( STRING_LEN == nUnderScorePos ) +/*N*/ nUnderScorePos = i; +/*N*/ break; +/*N*/ +/*N*/ default: +/*N*/ if( cTabDec == cPos ) +/*N*/ { +/*N*/ ASSERT( cPos, "Unexspected end of string" ); +/*N*/ if( cPos ) // robust +/*N*/ { +/*N*/ cHookChar = cPos; +/*N*/ return i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return i; +/*N*/ } + +/*N*/ BOOL SwTxtFormatInfo::LastKernPortion() +/*N*/ { +/*N*/ if( GetLast() ) +/*N*/ { +/*N*/ if( GetLast()->IsKernPortion() ) +/*N*/ return TRUE; +/*N*/ if( GetLast()->Width() || ( GetLast()->GetLen() && +/*N*/ !GetLast()->IsHolePortion() ) ) +/*N*/ return FALSE; +/*N*/ } +/*N*/ SwLinePortion* pPor = GetRoot(); +/*N*/ SwLinePortion *pKern = NULL; +/*N*/ while( pPor ) +/*N*/ { +/*N*/ if( pPor->IsKernPortion() ) +/*N*/ pKern = pPor; +/*N*/ else if( pPor->Width() || ( pPor->GetLen() && !pPor->IsHolePortion() ) ) +/*N*/ pKern = NULL; +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ if( pKern ) +/*N*/ { +/*?*/ SetLast( pKern ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/************************************************************************* + * class SwTxtSlot + *************************************************************************/ + +/*N*/ SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor ) +/*N*/ { +/*N*/ bOn = pPor->GetExpTxt( *pNew, aTxt ); +/*N*/ +/*N*/ // Der Text wird ausgetauscht... +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf = (SwTxtSizeInfo*)pNew; +/*N*/ nIdx = pInf->GetIdx(); +/*N*/ nLen = pInf->GetLen(); +/*N*/ pInf->SetLen( pPor->GetLen() ); +/*N*/ pOldTxt = &(pInf->GetTxt()); +/*N*/ pInf->SetTxt( aTxt ); +/*N*/ pInf->SetIdx( 0 ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtSlot::~SwTxtSlot() + *************************************************************************/ + +/*N*/ SwTxtSlot::~SwTxtSlot() +/*N*/ { +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf->SetTxt( *pOldTxt ); +/*N*/ pInf->SetIdx( nIdx ); +/*N*/ pInf->SetLen( nLen ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * class SwTxtSlotLen + *************************************************************************/ + +/*N*/ SwTxtSlotLen::SwTxtSlotLen( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor, +/*N*/ const sal_Char *pCh ) +/*N*/ { +/*N*/ if( pCh ) +/*N*/ { +/*?*/ aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 ); +/*?*/ bOn = sal_True; +/*N*/ } +/*N*/ else +/*N*/ bOn = pPor->GetExpTxt( *pNew, aTxt ); +/*N*/ +/*N*/ // Der Text wird ausgetauscht... +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf = (SwTxtSizeInfo*)pNew; +/*N*/ nIdx = pInf->GetIdx(); +/*N*/ nLen = pInf->GetLen(); +/*N*/ pOldTxt = &(pInf->GetTxt()); +/*N*/ pInf->SetTxt( aTxt ); +/*N*/ pInf->SetIdx( 0 ); +/*N*/ pInf->SetLen( pInf->GetTxt().Len() ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtSlotLen::~SwTxtSlotLen() + *************************************************************************/ + +/*N*/ SwTxtSlotLen::~SwTxtSlotLen() +/*N*/ { +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf->SetTxt( *pOldTxt ); +/*N*/ pInf->SetIdx( nIdx ); +/*N*/ pInf->SetLen( nLen ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwFontSave::SwFontSave() + *************************************************************************/ + +/*N*/ SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNew, +/*N*/ SwAttrIter* pItr ) +/*N*/ : pFnt( pNew ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 ) +/*N*/ { +/*N*/ if( pFnt ) +/*N*/ { +/*N*/ pInf = &((SwTxtSizeInfo&)rInf); +/*N*/ // In these cases we temporarily switch to the new font: +/*N*/ // 1. the fonts have a different magic number +/*N*/ // 2. they have different script types +/*N*/ // 3. their background colors differ (this is not covered by 1.) +/*N*/ if( pFnt->DifferentMagic( pNew, pFnt->GetActual() ) || +/*N*/ pNew->GetActual() != pFnt->GetActual() || +/*N*/ ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) || +/*N*/ ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) || +/*N*/ ( pNew->GetBackColor() && pFnt->GetBackColor() && +/*N*/ ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) ) +/*N*/ { +/*N*/ pNew->SetTransparent( sal_True ); +/*N*/ pNew->SetAlign( ALIGN_BASELINE ); +/*N*/ pInf->SetFont( pNew ); +/*N*/ } +/*N*/ else +/*N*/ pFnt = 0; +/*N*/ pNew->Invalidate(); +/*N*/ pNew->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() ); +/*N*/ if( pItr && pItr->GetFnt() == pFnt ) +/*N*/ { +/*?*/ pIter = pItr; +/*?*/ pIter->SetFnt( pNew ); +/*N*/ } +/*N*/ else +/*N*/ pIter = NULL; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwFontSave::~SwFontSave() + *************************************************************************/ + +/*N*/ SwFontSave::~SwFontSave() +/*N*/ { +/*N*/ if( pFnt ) +/*N*/ { +/*N*/ // SwFont zurueckstellen +/*N*/ pFnt->Invalidate(); +/*N*/ pInf->SetFont( pFnt ); +/*N*/ if( pIter ) +/*N*/ { +/*?*/ pIter->SetFnt( pFnt ); +/*?*/ pIter->nPos = STRING_LEN; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwDefFontSave::SwDefFontSave() + *************************************************************************/ + + +/************************************************************************* + * SwDefFontSave::~SwDefFontSave() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFormatInfo::ChgHyph() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew ) +/*N*/ { +/*N*/ const sal_Bool bOld = bAutoHyph; +/*N*/ if( bAutoHyph != bNew ) +/*N*/ { +/*N*/ bAutoHyph = bNew; +/*N*/ InitHyph( bNew ); +/*N*/ // 5744: Sprache am Hyphenator einstellen. +/*N*/ if( pFnt ) +/*N*/ pFnt->ChgPhysFnt( pVsh, pOut ); +/*N*/ } +/*N*/ return bOld; +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itradj.cxx b/binfilter/bf_sw/source/core/text/sw_itradj.cxx new file mode 100644 index 000000000000..894c13aa94c7 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itradj.cxx @@ -0,0 +1,493 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#if OSL_DEBUG_LEVEL > 1 +# include "ndtxt.hxx" // pSwpHints, Ausgabeoperator +#endif + +#include "itrtxt.hxx" +#include "porfly.hxx" // CalcFlyAdjust() +#include "pormulti.hxx" + + +#include <horiornt.hxx> + +#include <doc.hxx> +namespace binfilter { + +#define MIN_TAB_WIDTH 60 + +/************************************************************************* + * SwTxtAdjuster::FormatBlock() + *************************************************************************/ + +/*N*/ void SwTxtAdjuster::FormatBlock( ) +/*N*/ { +/*N*/ // In der letzten Zeile gibt's keinen Blocksatz. +/*N*/ // Und bei Tabulatoren aus Tradition auch nicht. +/*N*/ // 7701: wenn Flys im Spiel sind, geht's weiter +/*N*/ +/*N*/ const SwLinePortion *pFly = 0; +/*N*/ +/*N*/ sal_Bool bSkip = !IsLastBlock() && +/*N*/ nStart + pCurr->GetLen() >= GetInfo().GetTxt().Len(); +/*N*/ +/*N*/ // ????: mehrzeilige Felder sind fies: wir muessen kontrollieren, +/*N*/ // ob es noch andere Textportions im Absatz gibt. +/*N*/ if( bSkip ) +/*N*/ { +/*N*/ const SwLineLayout *pLay = pCurr->GetNext(); +/*N*/ while( pLay && !pLay->GetLen() ) +/*N*/ { +/*?*/ const SwLinePortion *pPor = pCurr->GetFirstPortion(); +/*?*/ while( pPor && bSkip ) +/*?*/ { +/*?*/ if( pPor->InTxtGrp() ) +/*?*/ bSkip = sal_False; +/*?*/ pPor = pPor->GetPortion(); +/*?*/ } +/*?*/ pLay = bSkip ? pLay->GetNext() : 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bSkip ) +/*N*/ { +/*N*/ if( !GetInfo().GetParaPortion()->HasFly() ) +/*N*/ { +/*?*/ if( IsLastCenter() ) +/*?*/ CalcFlyAdjust( pCurr ); +/*?*/ pCurr->FinishSpaceAdd(); +/*?*/ return; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwLinePortion *pTmpFly = NULL; +/*N*/ +/*N*/ // 7701: beim letzten Fly soll Schluss sein +/*N*/ const SwLinePortion *pPos = pCurr->GetFirstPortion(); +/*N*/ while( pPos ) +/*N*/ { +/*N*/ // Ich suche jetzt den letzten Fly, hinter dem noch Text ist: +/*N*/ if( pPos->IsFlyPortion() ) +/*N*/ pTmpFly = pPos; // Ein Fly wurde gefunden +/*N*/ else if ( pTmpFly && pPos->InTxtGrp() ) +/*N*/ { +/*N*/ pFly = pTmpFly; // Ein Fly mit nachfolgendem Text! +/*N*/ pTmpFly = NULL; +/*N*/ } +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ // 8494: Wenn keiner gefunden wurde, ist sofort Schluss! +/*N*/ if( !pFly ) +/*N*/ { +/*N*/ if( IsLastCenter() ) +/*?*/ CalcFlyAdjust( pCurr ); +/*N*/ pCurr->FinishSpaceAdd(); +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ const int nOldIdx = GetInfo().GetIdx(); +/*N*/ GetInfo().SetIdx( nStart ); +/*N*/ CalcNewBlock( pCurr, pFly ); +/*N*/ GetInfo().SetIdx( nOldIdx ); +/*N*/ GetInfo().GetParaPortion()->GetRepaint()->SetOfst(0); +/*N*/ } + +/************************************************************************* + * SwTxtAdjuster::CalcNewBlock() + * + * CalcNewBlock() darf erst nach CalcLine() gerufen werden ! + * Aufgespannt wird immer zwischen zwei RandPortions oder FixPortions + * (Tabs und Flys). Dabei werden die Glues gezaehlt und ExpandBlock gerufen. + *************************************************************************/ + +/*N*/ void SwTxtAdjuster::CalcNewBlock( SwLineLayout *pCurr, +/*N*/ const SwLinePortion *pStopAt, SwTwips nReal ) +/*N*/ { +/*N*/ ASSERT( GetInfo().IsMulti() || SVX_ADJUST_BLOCK == GetAdjust(), +/*N*/ "CalcNewBlock: Why?" ); +/*N*/ ASSERT( pCurr->Height(), "SwTxtAdjuster::CalcBlockAdjust: missing CalcLine()" ); +/*N*/ +/*N*/ pCurr->InitSpaceAdd(); +/*N*/ MSHORT nNull = 0; +/*N*/ xub_StrLen nGluePortion = 0; +/*N*/ xub_StrLen nCharCnt = 0; +/*N*/ MSHORT nSpaceIdx = 0; +/*N*/ +/*N*/ // Nicht vergessen: +/*N*/ // CalcRightMargin() setzt pCurr->Width() auf die Zeilenbreite ! +/*N*/ CalcRightMargin( pCurr, nReal ); +/*N*/ +/*N*/ SwLinePortion *pPos = pCurr->GetPortion(); +/*N*/ +/*N*/ while( pPos ) +/*N*/ { +/*N*/ if ( pPos->IsBreakPortion() && !IsLastBlock() ) +/*N*/ { +/*?*/ pCurr->FinishSpaceAdd(); +/*?*/ break; +/*N*/ } +/*N*/ if ( pPos->InTxtGrp() ) +/*N*/ nGluePortion += ((SwTxtPortion*)pPos)->GetSpaceCnt( GetInfo(), nCharCnt ); +/*N*/ else if( pPos->IsMultiPortion() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ { +/*N*/ +/*N*/ if( pPos->InGlueGrp() ) +/*N*/ { +/*N*/ if( pPos->InFixMargGrp() ) +/*N*/ { +/*N*/ if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() ) +/*N*/ pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx ); +/*N*/ if( nGluePortion ) +/*N*/ { +/*N*/ ( pCurr->GetSpaceAdd() )[nSpaceIdx] = +/*N*/ ( (SwGluePortion*)pPos )->GetPrtGlue() / nGluePortion; +/*N*/ pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() ); +/*N*/ } +/*N*/ else if ( IsOneBlock() && nCharCnt > 1 ) +/*N*/ { +/*?*/ ( pCurr->GetSpaceAdd() )[nSpaceIdx] = +/*?*/ - ( (SwGluePortion*)pPos )->GetPrtGlue() / (nCharCnt-1); +/*?*/ pPos->Width( ( (SwGluePortion*)pPos )->GetFixWidth() ); +/*N*/ } +/*N*/ nSpaceIdx++; +/*N*/ nGluePortion = 0; +/*N*/ nCharCnt = 0; +/*N*/ } +/*N*/ else +/*N*/ ++nGluePortion; +/*N*/ } +/*N*/ GetInfo().SetIdx( GetInfo().GetIdx() + pPos->GetLen() ); +/*N*/ if ( pPos == pStopAt ) +/*N*/ { +/*?*/ if ( nSpaceIdx == pCurr->GetSpaceAdd().Count() ) +/*?*/ pCurr->GetSpaceAdd().Insert( nNull, nSpaceIdx ); +/*?*/ else +/*?*/ pCurr->GetSpaceAdd()[nSpaceIdx] = 0; +/*?*/ break; +/*N*/ } +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtAdjuster::CalcKanaAdj() + *************************************************************************/ + + +/************************************************************************* + * SwTxtAdjuster::CalcRightMargin() + *************************************************************************/ + +/*N*/ SwMarginPortion *SwTxtAdjuster::CalcRightMargin( SwLineLayout *pCurr, +/*N*/ SwTwips nReal ) +/*N*/ { +/*N*/ long nRealWidth; +/*N*/ const USHORT nRealHeight = GetLineHeight(); +/*N*/ const USHORT nLineHeight = pCurr->Height(); +/*N*/ +/*N*/ KSHORT nPrtWidth = pCurr->PrtWidth(); +/*N*/ SwLinePortion *pLast = pCurr->FindLastPortion(); +/*N*/ +/*N*/ if( GetInfo().IsMulti() ) +/*N*/ nRealWidth = nReal; +/*N*/ else +/*N*/ { +/*N*/ nRealWidth = GetLineWidth(); +/*N*/ // Fuer jeden FlyFrm, der in den rechten Rand hineinragt, +/*N*/ // wird eine FlyPortion angelegt. +/*N*/ const long nLeftMar = GetLeftMargin(); +/*N*/ SwRect aCurrRect( nLeftMar + nPrtWidth, Y() + nRealHeight - nLineHeight, +/*N*/ nRealWidth - nPrtWidth, nLineHeight ); +/*N*/ +/*N*/ SwFlyPortion *pFly = CalcFlyPortion( nRealWidth, aCurrRect ); +/*N*/ while( pFly && long( nPrtWidth )< nRealWidth ) +/*N*/ { +/*N*/ pLast->Append( pFly ); +/*N*/ pLast = pFly; +/*N*/ if( pFly->Fix() > nPrtWidth ) +/*?*/ pFly->Width( ( pFly->Fix() - nPrtWidth) + pFly->Width() + 1); +/*N*/ nPrtWidth += pFly->Width() + 1; +/*N*/ aCurrRect.Left( nLeftMar + nPrtWidth ); +/*N*/ pFly = CalcFlyPortion( nRealWidth, aCurrRect ); +/*N*/ } +/*N*/ if( pFly ) +/*?*/ delete pFly; +/*N*/ } +/*N*/ +/*N*/ SwMarginPortion *pRight = new SwMarginPortion( 0 ); +/*N*/ pLast->Append( pRight ); +/*N*/ +/*N*/ if( long( nPrtWidth )< nRealWidth ) +/*N*/ pRight->PrtWidth( KSHORT( nRealWidth - nPrtWidth ) ); +/*N*/ +/*N*/ // pCurr->Width() wird auf die reale Groesse gesetzt, +/*N*/ // da jetzt die MarginPortions eingehaengt sind. +/*N*/ // Dieser Trick hat wundersame Auswirkungen. +/*N*/ // Wenn pCurr->Width() == nRealWidth ist, dann wird das gesamte +/*N*/ // Adjustment implizit ausgecontert. GetLeftMarginAdjust() und +/*N*/ // IsBlocksatz() sind der Meinung, sie haetten eine mit Zeichen +/*N*/ // gefuellte Zeile. +/*N*/ +/*N*/ pCurr->PrtWidth( KSHORT( nRealWidth ) ); +/*N*/ return pRight; +/*N*/ } + +/************************************************************************* + * SwTxtAdjuster::CalcFlyAdjust() + *************************************************************************/ + +/*N*/ void SwTxtAdjuster::CalcFlyAdjust( SwLineLayout *pCurr ) +/*N*/ { +/*N*/ // 1) Es wird ein linker Rand eingefuegt: +/*N*/ SwMarginPortion *pLeft = pCurr->CalcLeftMargin(); +/*N*/ SwGluePortion *pGlue = pLeft; // die letzte GluePortion +/*N*/ +/*N*/ +/*N*/ // 2) Es wird ein rechter Rand angehaengt: +/*N*/ // CalcRightMargin berechnet auch eventuelle Ueberlappungen mit +/*N*/ // FlyFrms. +/*N*/ CalcRightMargin( pCurr ); +/*N*/ +/*N*/ SwLinePortion *pPos = pLeft->GetPortion(); +/*N*/ xub_StrLen nLen = 0; +/*N*/ +/*N*/ // Wenn wir nur eine Zeile vorliegen haben und die Textportion zusammen +/*N*/ // haengend ist und wenn zentriert wird, dann ... +/*N*/ +/*N*/ sal_Bool bComplete = 0 == nStart; +/*N*/ const sal_Bool bTabCompat = GetTxtFrm()->GetNode()->GetDoc()->IsTabCompat(); +/*N*/ sal_Bool bMultiTab = sal_False; +/*N*/ +/*N*/ while( pPos ) +/*N*/ { +/*N*/ if ( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasTabulator() ) +/*N*/ bMultiTab = sal_True; +/*N*/ else if( pPos->InFixMargGrp() && +/*N*/ ( bTabCompat ? ! pPos->InTabGrp() : ! bMultiTab ) ) +/*N*/ { +/*N*/ // in tab compat mode we do not want to change tab portions +/*N*/ // in non tab compat mode we do not want to change margins if we +/*N*/ // found a multi portion with tabs +/*N*/ if( SVX_ADJUST_RIGHT == GetAdjust() ) +/*N*/ ((SwGluePortion*)pPos)->MoveAllGlue( pGlue ); +/*N*/ else +/*N*/ { +/*N*/ // Eine schlaue Idee von MA: +/*N*/ // Fuer die erste Textportion wird rechtsbuendig eingestellt, +/*N*/ // fuer die letzte linksbuendig. +/*N*/ +/*N*/ // Die erste Textportion kriegt den ganzen Glue +/*N*/ // Aber nur, wenn wir mehr als eine Zeile besitzen. +/*N*/ if( bComplete && GetInfo().GetTxt().Len() == nLen ) +/*N*/ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue ); +/*N*/ else +/*N*/ { +/*N*/ if ( ! bTabCompat ) +/*N*/ { +/*N*/ if( pLeft == pGlue ) +/*N*/ { +/*N*/ // Wenn es nur einen linken und rechten Rand gibt, +/*N*/ // dann teilen sich die Raender den Glue. +/*N*/ if( nLen + pPos->GetLen() >= pCurr->GetLen() ) +/*N*/ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue ); +/*N*/ else +/*?*/ ((SwGluePortion*)pPos)->MoveAllGlue( pGlue ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Die letzte Textportion behaelt sein Glue +/*N*/ if( !pPos->IsMarginPortion() ) +/*?*/ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue ); +/*N*/ } +/*N*/ } +/*N*/ else +/*?*/ ((SwGluePortion*)pPos)->MoveHalfGlue( pGlue ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pGlue = (SwFlyPortion*)pPos; +/*N*/ bComplete = sal_False; +/*N*/ } +/*N*/ nLen += pPos->GetLen(); +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ +/*N*/ if( ! bTabCompat && ! bMultiTab && SVX_ADJUST_RIGHT == GetAdjust() ) +/*N*/ // portions are moved to the right if possible +/*N*/ pLeft->AdjustRight( pCurr ); +/*N*/ } + +/************************************************************************* + * SwTxtAdjuster::CalcAdjLine() + *************************************************************************/ + +/*N*/ void SwTxtAdjuster::CalcAdjLine( SwLineLayout *pCurr ) +/*N*/ { +/*N*/ ASSERT( pCurr->IsFormatAdj(), "CalcAdjLine: Why?" ); +/*N*/ +/*N*/ pCurr->SetFormatAdj(sal_False); +/*N*/ +/*N*/ SwParaPortion* pPara = GetInfo().GetParaPortion(); +/*N*/ +/*N*/ switch( GetAdjust() ) +/*N*/ { +/*N*/ case SVX_ADJUST_RIGHT: +/*N*/ case SVX_ADJUST_CENTER: +/*N*/ { +/*N*/ CalcFlyAdjust( pCurr ); +/*N*/ pPara->GetRepaint()->SetOfst( 0 ); +/*N*/ break; +/*N*/ } +/*N*/ case SVX_ADJUST_BLOCK: +/*N*/ { +/*N*/ // 8311: In Zeilen mit LineBreaks gibt es keinen Blocksatz! +/*N*/ if( pCurr->GetLen() && +/*N*/ CH_BREAK == GetInfo().GetChar( nStart + pCurr->GetLen() - 1 ) && +/*N*/ !IsLastBlock() ) +/*N*/ { +/*N*/ if( IsLastCenter() ) +/*N*/ { +/*?*/ CalcFlyAdjust( pCurr ); +/*?*/ pPara->GetRepaint()->SetOfst( 0 ); +/*?*/ break; +/*N*/ } +/*N*/ return; +/*N*/ } +/*N*/ FormatBlock(); +/*N*/ break; +/*N*/ } +/*N*/ default : return; +/*N*/ } +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 + /* + if( OPTDBG( *pInf ) ) + { + pCurr->DebugPortions( aDbstream, pInf->GetTxt(), nStart ); + if( GetHints() ) + { + const SwpHints &rHt = *GetHints(); + aDbstream << rHt; + SwAttrIter::Dump( aDbstream ); + } + } + */ +/*N*/ #endif +/*N*/ } + +/************************************************************************* + * SwTxtAdjuster::CalcFlyPortion() + * + * Die Berechnung hat es in sich: nCurrWidth geibt die Breite _vor_ dem + * aufaddieren des Wortes das noch auf die Zeile passt! Aus diesem Grund + * stimmt die Breite der FlyPortion auch, wenn die Blockierungssituation + * bFirstWord && !WORDFITS eintritt. + *************************************************************************/ + +/*N*/ SwFlyPortion *SwTxtAdjuster::CalcFlyPortion( const long nRealWidth, +/*N*/ const SwRect &rCurrRect ) +/*N*/ { +/*N*/ SwTxtFly aTxtFly( GetTxtFrm() ); +/*N*/ +/*N*/ const KSHORT nCurrWidth = pCurr->PrtWidth(); +/*N*/ SwFlyPortion *pFlyPortion = 0; +/*N*/ +/*N*/ SwRect aLineVert( rCurrRect ); +/*N*/ if ( GetTxtFrm()->IsRightToLeft() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 GetTxtFrm()->SwitchLTRtoRTL( aLineVert ); +/*N*/ if ( GetTxtFrm()->IsVertical() ) +/*?*/ GetTxtFrm()->SwitchHorizontalToVertical( aLineVert ); +/*N*/ +/*N*/ // aFlyRect ist dokumentglobal ! +/*N*/ SwRect aFlyRect( aTxtFly.GetFrm( aLineVert ) ); +/*N*/ +/*N*/ if ( GetTxtFrm()->IsRightToLeft() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 GetTxtFrm()->SwitchRTLtoLTR( aFlyRect ); +/*N*/ if ( GetTxtFrm()->IsVertical() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 GetTxtFrm()->SwitchVerticalToHorizontal( aFlyRect ); +/*N*/ +/*N*/ // Wenn ein Frame ueberlappt, wird eine Portion eroeffnet. +/*N*/ if( aFlyRect.HasArea() ) +/*N*/ { +/*N*/ // aLocal ist framelokal +/*?*/ SwRect aLocal( aFlyRect ); +/*?*/ aLocal.Pos( aLocal.Left() - GetLeftMargin(), aLocal.Top() ); +/*?*/ if( nCurrWidth > aLocal.Left() ) +/*?*/ aLocal.Left( nCurrWidth ); +/*?*/ +/*?*/ // Wenn das Rechteck breiter als die Zeile ist, stutzen +/*?*/ // wir es ebenfalls zurecht. +/*?*/ KSHORT nLocalWidth = KSHORT( aLocal.Left() + aLocal.Width() ); +/*?*/ if( nRealWidth < long( nLocalWidth ) ) +/*?*/ aLocal.Width( nRealWidth - aLocal.Left() ); +/*?*/ GetInfo().GetParaPortion()->SetFly( sal_True ); +/*?*/ pFlyPortion = new SwFlyPortion( aLocal ); +/*?*/ pFlyPortion->Height( KSHORT( rCurrRect.Height() ) ); +/*?*/ // Die Width koennte kleiner sein als die FixWidth, daher: +/*?*/ pFlyPortion->AdjFixWidth(); +/*N*/ } +/*N*/ return pFlyPortion; +/*N*/ } + +/************************************************************************* + * SwTxtPainter::_CalcDropAdjust() + *************************************************************************/ + +// 6721: Drops und Adjustment +// CalcDropAdjust wird ggf. am Ende von Format() gerufen. + + +/************************************************************************* + * SwTxtAdjuster::CalcDropRepaint() + *************************************************************************/ + +/*N*/ void SwTxtAdjuster::CalcDropRepaint() +/*N*/ { +/*N*/ Top(); +/*N*/ SwRepaint &rRepaint = *GetInfo().GetParaPortion()->GetRepaint(); +/*N*/ if( rRepaint.Top() > Y() ) +/*?*/ rRepaint.Top( Y() ); +/*N*/ for( MSHORT i = 1; i < GetDropLines(); ++i ) +/*N*/ NextLine(); +/*N*/ const SwTwips nBottom = Y() + GetLineHeight() - 1; +/*N*/ if( rRepaint.Bottom() < nBottom ) +/*?*/ rRepaint.Bottom( nBottom ); +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itratr.cxx b/binfilter/bf_sw/source/core/text/sw_itratr.cxx new file mode 100644 index 000000000000..dfda582f82ba --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itratr.cxx @@ -0,0 +1,359 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <horiornt.hxx> + +#include <rootfrm.hxx> +#include <redlnitr.hxx> +#include <itrtxt.hxx> +#include <com/sun/star/i18n/ScriptType.hdl> +namespace binfilter { + +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star; + +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +/************************************************************************* + * SwAttrIter::Chg() + *************************************************************************/ + +/*N*/ void SwAttrIter::Chg( SwTxtAttr *pHt ) +/*N*/ { +/*N*/ ASSERT( pHt && pFnt, "No attribute of font available for change"); +/*N*/ if( pRedln && pRedln->IsOn() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True ); +/*N*/ else +/*N*/ aAttrHandler.PushAndChg( *pHt, *pFnt ); +/*N*/ nChgCnt++; +/*N*/ } + +/************************************************************************* + * SwAttrIter::Rst() + *************************************************************************/ + +/*N*/ void SwAttrIter::Rst( SwTxtAttr *pHt ) +/*N*/ { +/*N*/ ASSERT( pHt && pFnt, "No attribute of font available for reset"); +/*N*/ // get top from stack after removing pHt +/*N*/ if( pRedln && pRedln->IsOn() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False ); +/*N*/ else +/*N*/ aAttrHandler.PopAndChg( *pHt, *pFnt ); +/*N*/ nChgCnt--; +/*N*/ } + +/************************************************************************* + * virtual SwAttrIter::~SwAttrIter() + *************************************************************************/ + +/*N*/ SwAttrIter::~SwAttrIter() +/*N*/ { +/*N*/ delete pRedln; +/*N*/ delete pFnt; +/*N*/ } + +/************************************************************************* + * SwAttrIter::GetAttr() + * + * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf + * der Position nPos liegt und kein EndIndex besitzt. + * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen + * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten" + * Attribute sind z.B. Felder (die expandierten Text bereit halten) und + * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen + * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs + * an der Startposition ein Sonderzeichen in den String einfuegt. + * Der Formatierer stoesst auf das Sonderzeichen und holt sich per + * GetAttr() das entartete Attribut. + *************************************************************************/ + +/*N*/ SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPos ) const +/*N*/ { +/*N*/ if( pHints ) +/*N*/ { +/*N*/ for( MSHORT i = 0; i < pHints->Count(); ++i ) +/*N*/ { +/*N*/ SwTxtAttr *pPos = pHints->GetHt(i); +/*N*/ xub_StrLen nStart = *pPos->GetStart(); +/*N*/ if( nPos < nStart ) +/*N*/ return 0; +/*N*/ if( nPos == nStart && !pPos->GetEnd() ) +/*N*/ return pPos; +/*N*/ } +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwAttrIter::SeekAndChg() + *************************************************************************/ + +/*N*/ sal_Bool SwAttrIter::SeekAndChg( const xub_StrLen nNewPos, OutputDevice *pOut ) +/*N*/ { +/*N*/ sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos ); +/*N*/ if ( pLastOut != pOut ) +/*N*/ { +/*N*/ pLastOut = pOut; +/*N*/ pFnt->SetFntChg( sal_True ); +/*N*/ bChg = sal_True; +/*N*/ } +/*N*/ if( bChg ) +/*N*/ { +/*N*/ // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo +/*N*/ // des gewuenschten Fonts ... +/*N*/ if ( !nChgCnt && !nPropFont ) +/*N*/ pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ], +/*N*/ aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() ); +/*N*/ pFnt->ChgPhysFnt( pShell, pOut ); +/*N*/ } +/*N*/ return bChg; +/*N*/ } + + +/************************************************************************* + * SwAttrIter::SeekStartAndChg() + *************************************************************************/ + +/*N*/ sal_Bool SwAttrIter::SeekStartAndChg( OutputDevice *pOut, const sal_Bool bParaFont ) +/*N*/ { +/*N*/ if ( pRedln && pRedln->ExtOn() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRedln->LeaveExtend( *pFnt, 0 ); +/*N*/ +/*N*/ // reset font to its original state +/*N*/ aAttrHandler.Reset(); +/*N*/ aAttrHandler.ResetFont( *pFnt ); +/*N*/ +/*N*/ nStartIndex = nEndIndex = nPos = nChgCnt = 0; +/*N*/ if( nPropFont ) +/*?*/ pFnt->SetProportion( nPropFont ); +/*N*/ if( pRedln ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pRedln->Clear( pFnt ); +/*N*/ } +/*N*/ +/*N*/ if ( pHints && !bParaFont ) +/*N*/ { +/*N*/ SwTxtAttr *pTxtAttr; +/*N*/ // Solange wir noch nicht am Ende des StartArrays angekommen sind && +/*N*/ // das TextAttribut an Position 0 beginnt ... +/*?*/ while ( ( nStartIndex < pHints->GetStartCount() ) && +/*?*/ !(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) ) +/*?*/ { +/*?*/ // oeffne die TextAttribute +/*?*/ Chg( pTxtAttr ); +/*?*/ nStartIndex++; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ register sal_Bool bChg = pFnt->IsFntChg(); +/*N*/ if ( pLastOut != pOut ) +/*N*/ { +/*N*/ pLastOut = pOut; +/*N*/ pFnt->SetFntChg( sal_True ); +/*N*/ bChg = sal_True; +/*N*/ } +/*N*/ if( bChg ) +/*N*/ { +/*N*/ // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo +/*N*/ // des gewuenschten Fonts ... +/*N*/ if ( !nChgCnt && !nPropFont ) +/*N*/ pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ], +/*N*/ aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() ); +/*N*/ pFnt->ChgPhysFnt( pShell, pOut ); +/*N*/ } +/*N*/ return bChg; +/*N*/ } + +/************************************************************************* + * SwAttrIter::SeekFwd() + *************************************************************************/ + +// AMA: Neuer AttrIter Nov 94 + +/*N*/ void SwAttrIter::SeekFwd( const xub_StrLen nNewPos ) +/*N*/ { +/*N*/ SwTxtAttr *pTxtAttr; +/*N*/ +/*N*/ if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden... +/*N*/ { +/*N*/ // Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden. +/*N*/ +/*N*/ // Solange wir noch nicht am Ende des EndArrays angekommen sind && +/*N*/ // das TextAttribut vor oder an der neuen Position endet ... +/*N*/ while ( ( nEndIndex < pHints->GetEndCount() ) && +/*N*/ (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos)) +/*N*/ { +/*N*/ // schliesse die TextAttribute, deren StartPos vor +/*N*/ // oder an der alten nPos lag, die z.Z. geoeffnet sind. +/*N*/ if (*pTxtAttr->GetStart() <= nPos) Rst( pTxtAttr ); +/*N*/ nEndIndex++; +/*N*/ } +/*N*/ } +/*N*/ else // ueberlies die nicht geoeffneten Enden +/*N*/ { +/*N*/ while ( ( nEndIndex < pHints->GetEndCount() ) && +/*N*/ (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos)) +/*N*/ { +/*N*/ nEndIndex++; +/*N*/ } +/*N*/ } +/*N*/ // Solange wir noch nicht am Ende des StartArrays angekommen sind && +/*N*/ // das TextAttribut vor oder an der neuen Position beginnt ... +/*N*/ while ( ( nStartIndex < pHints->GetStartCount() ) && +/*N*/ (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos)) +/*N*/ { +/*N*/ // oeffne die TextAttribute, deren Ende hinter der neuen Position liegt +/*N*/ if ( *pTxtAttr->GetAnyEnd() > nNewPos ) Chg( pTxtAttr ); +/*N*/ nStartIndex++; +/*N*/ } +/*N*/ +/*N*/ } + +/************************************************************************* + * SwAttrIter::Seek() + *************************************************************************/ + +/*N*/ sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos ) +/*N*/ { +/*N*/ if ( pRedln && pRedln->ExtOn() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRedln->LeaveExtend( *pFnt, nNewPos ); +/*N*/ +/*N*/ if( pHints ) +/*N*/ { +/*N*/ if( !nNewPos || nNewPos < nPos ) +/*N*/ { +/*N*/ if( pRedln ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRedln->Clear( NULL ); +/*N*/ +/*N*/ // reset font to its original state +/*N*/ aAttrHandler.Reset(); +/*N*/ aAttrHandler.ResetFont( *pFnt ); +/*N*/ +/*N*/ if( nPropFont ) +/*?*/ pFnt->SetProportion( nPropFont ); +/*N*/ nStartIndex = nEndIndex = nPos = 0; +/*N*/ nChgCnt = 0; +/*N*/ +/*N*/ // Achtung! +/*N*/ // resetting the font here makes it necessary to apply any +/*N*/ // changes for extended input directly to the font +/*N*/ if ( pRedln && pRedln->ExtOn() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ pRedln->UpdateExtFont( *pFnt ); +/*N*/ } +/*N*/ } +/*N*/ SeekFwd( nNewPos ); +/*N*/ } +/*N*/ +/*N*/ pFnt->SetActual( WhichFont( nNewPos, 0, pScriptInfo ) ); +/*N*/ +/*N*/ if( pRedln ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nChgCnt += pRedln->Seek( *pFnt, nNewPos, nPos ); +/*N*/ nPos = nNewPos; +/*N*/ +/*N*/ if( nPropFont ) +/*?*/ pFnt->SetProportion( nPropFont ); +/*N*/ +/*N*/ return pFnt->IsFntChg(); +/*N*/ } + +/************************************************************************* + * SwAttrIter::GetNextAttr() + *************************************************************************/ + +/*N*/ xub_StrLen SwAttrIter::GetNextAttr( ) const +/*N*/ { +/*N*/ xub_StrLen nNext = STRING_LEN; +/*N*/ if( pHints ) +/*N*/ { +/*N*/ if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts? +/*N*/ nNext = (*pHints->GetStart(nStartIndex)->GetStart()); +/*N*/ if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden? +/*N*/ { +/*N*/ xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd()); +/*N*/ if ( nNextEnd<nNext ) nNext = nNextEnd; // Wer ist naeher? +/*N*/ } +/*N*/ } +/*N*/ if( pRedln ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ return pRedln->GetNextRedln( nNext ); +/*N*/ return nNext; +/*N*/ } + +#if OSL_DEBUG_LEVEL > 1 +/************************************************************************* + * SwAttrIter::Dump() + *************************************************************************/ + + +#endif + +class SwMinMaxArgs +{ +public: + OutputDevice *pOut; + ULONG &rMin; + ULONG &rMax; + ULONG &rAbsMin; + long nRowWidth; + long nWordWidth; + long nWordAdd; + xub_StrLen nNoLineBreak; + SwMinMaxArgs( OutputDevice *pOutI, ULONG& rMinI, ULONG &rMaxI, ULONG &rAbsI ) + : pOut( pOutI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI ) + { nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = STRING_LEN; } + void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; } + void NewWord() { nWordAdd = nWordWidth = 0; } +}; + + + +class SwMinMaxNodeArgs +{ +public: + ULONG nMaxWidth; // Summe aller Rahmenbreite + long nMinWidth; // Breitester Rahmen + long nLeftRest; // noch nicht von Rahmen ueberdeckter Platz im l. Rand + long nRightRest; // noch nicht von Rahmen ueberdeckter Platz im r. Rand + long nLeftDiff; // Min/Max-Differenz des Rahmens im linken Rand + long nRightDiff; // Min/Max-Differenz des Rahmens im rechten Rand + ULONG nIndx; // Indexnummer des Nodes + void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; } +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itrcrsr.cxx b/binfilter/bf_sw/source/core/text/sw_itrcrsr.cxx new file mode 100644 index 000000000000..3656ed5b662b --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itrcrsr.cxx @@ -0,0 +1,1124 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "errhdl.hxx" +#include "paratr.hxx" + +#include <horiornt.hxx> + + +#include <bf_svx/adjitem.hxx> +#include <bf_svx/lspcitem.hxx> +#include <bf_svx/lrspitem.hxx> + +#include <frmatr.hxx> + +#ifdef VERTICAL_LAYOUT +#include <pagedesc.hxx> // SwPageDesc +#endif + +#include "txtcfg.hxx" +#include "itrtxt.hxx" + +#include "porfld.hxx" // SwFldPortion::IsFollow() +#include "porfly.hxx" // GetFlyCrsrOfst() +#include "pordrop.hxx" +#include "crstate.hxx" // SwCrsrMoveState +#include <pormulti.hxx> // SwMultiPortion +namespace binfilter { + +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +// Nicht reentrant !!! +// wird in GetCharRect gesetzt und im UnitUp/Down ausgewertet. +sal_Bool SwTxtCursor::bRightMargin = sal_False; + + +/************************************************************************* + * lcl_GetPositionInsideField + * + * After calculating the position of a character during GetCharRect + * this function allows to find the coordinates of a position (defined + * in pCMS->pSpecialPos) inside a special portion (e.g., a field) + *************************************************************************/ + +/************************************************************************* + * SwTxtMargin::CtorInit() + *************************************************************************/ +/*M*/ void SwTxtMargin::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pNewInf ) +/*M*/ { +/*M*/ SwTxtIter::CtorInit( pFrm, pNewInf ); +/*M*/ +/*M*/ pInf = pNewInf; +/*M*/ GetInfo().SetFont( GetFnt() ); +/*M*/ SwTxtNode *pNode = pFrm->GetTxtNode(); +/*M*/ +/*M*/ const SvxLRSpaceItem &rSpace = +/*M*/ pFrm->GetTxtNode()->GetSwAttrSet().GetLRSpace(); +/*M*/ +/*M*/ #ifdef BIDI +/*M*/ // +/*M*/ // Carefully adjust the text formatting ranges. +/*M*/ // +/*M*/ const int nLMWithNum = pNode->GetLeftMarginWithNum( sal_True ); +/*M*/ if ( pFrm->IsRightToLeft() ) +/*M*/ nLeft = pFrm->Frm().Left() + pFrm->Prt().Left() + nLMWithNum - +/*M*/ ( rSpace.GetTxtFirstLineOfst() < 0 ? +/*M*/ rSpace.GetTxtFirstLineOfst() : +/*M*/ 0 ); +/*M*/ else +/*M*/ nLeft = Max( long( rSpace.GetTxtLeft() + nLMWithNum), pFrm->Prt().Left() ) + +/*M*/ pFrm->Frm().Left(); +/*M*/ #else +/*M*/ nLeft = Max( long( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum(sal_True) ), +/*M*/ pFrm->Prt().Left() ) + +/*M*/ pFrm->Frm().Left(); +/*M*/ #endif +/*M*/ +/*M*/ nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width(); +/*M*/ +/*M*/ if( nLeft >= nRight ) +/*M*/ nLeft = pFrm->Prt().Left() + pFrm->Frm().Left(); +/*M*/ if( nLeft >= nRight ) // z.B. bei grossen Absatzeinzuegen in schmalen Tabellenspalten +/*M*/ nRight = nLeft + 1; // einen goennen wir uns immer +/*M*/ if( pFrm->IsFollow() && pFrm->GetOfst() ) +/*M*/ nFirst = nLeft; +/*M*/ else +/*M*/ { +/*M*/ short nFLOfst; +/*M*/ long nFirstLineOfs; +/*M*/ if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) && +/*M*/ rSpace.IsAutoFirst() ) +/*M*/ { +/*M*/ nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height(); +/*M*/ const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing(); +/*M*/ if( pSpace ) +/*M*/ { +/*M*/ switch( pSpace->GetLineSpaceRule() ) +/*M*/ { +/*M*/ case SVX_LINE_SPACE_AUTO: +/*M*/ break; +/*M*/ case SVX_LINE_SPACE_MIN: +/*M*/ { +/*M*/ if( nFirstLineOfs < KSHORT( pSpace->GetLineHeight() ) ) +/*M*/ nFirstLineOfs = pSpace->GetLineHeight(); +/*M*/ break; +/*M*/ } +/*M*/ case SVX_LINE_SPACE_FIX: +/*M*/ nFirstLineOfs = pSpace->GetLineHeight(); +/*M*/ break; +/*M*/ default: ASSERT( sal_False, ": unknown LineSpaceRule" ); +/*M*/ } +/*M*/ switch( pSpace->GetInterLineSpaceRule() ) +/*M*/ { +/*M*/ case SVX_INTER_LINE_SPACE_OFF: +/*M*/ break; +/*M*/ case SVX_INTER_LINE_SPACE_PROP: +/*M*/ { +/*M*/ long nTmp = pSpace->GetPropLineSpace(); +/*M*/ // 50% ist das Minimum, bei 0% schalten wir auf +/*M*/ // den Defaultwert 100% um ... +/*M*/ if( nTmp < 50 ) +/*M*/ nTmp = nTmp ? 50 : 100; +/*M*/ +/*M*/ nTmp *= nFirstLineOfs; +/*M*/ nTmp /= 100; +/*M*/ if( !nTmp ) +/*M*/ ++nTmp; +/*M*/ nFirstLineOfs = (KSHORT)nTmp; +/*M*/ break; +/*M*/ } +/*M*/ case SVX_INTER_LINE_SPACE_FIX: +/*M*/ { +/*M*/ nFirstLineOfs += pSpace->GetInterLineSpace(); +/*M*/ break; +/*M*/ } +/*M*/ default: ASSERT( sal_False, ": unknown InterLineSpaceRule" ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ nFirstLineOfs = nFLOfst; +/*M*/ +/*M*/ #ifdef BIDI +/*M*/ if ( pFrm->IsRightToLeft() ) +/*M*/ nFirst = nLeft + nFirstLineOfs; +/*M*/ else +/*M*/ nFirst = Max( rSpace.GetTxtLeft() + nLMWithNum + nFirstLineOfs, +/*M*/ pFrm->Prt().Left() ) + pFrm->Frm().Left(); +/*M*/ #else +/*M*/ nFirst = Max( rSpace.GetTxtLeft() + pNode->GetLeftMarginWithNum( sal_True ) +/*M*/ + nFirstLineOfs, pFrm->Prt().Left() ) + pFrm->Frm().Left(); +/*M*/ #endif +/*M*/ +/*M*/ if( nFirst >= nRight ) +/*M*/ nFirst = nRight - 1; +/*M*/ } +/*M*/ const SvxAdjustItem& rAdjust = pFrm->GetTxtNode()->GetSwAttrSet().GetAdjust(); +/*M*/ nAdjust = rAdjust.GetAdjust(); +/*M*/ +/*M*/ #ifdef BIDI +/*M*/ // left is left and right is right +/*M*/ if ( pFrm->IsRightToLeft() ) +/*M*/ { +/*M*/ if ( SVX_ADJUST_LEFT == nAdjust ) +/*M*/ nAdjust = SVX_ADJUST_RIGHT; +/*M*/ else if ( SVX_ADJUST_RIGHT == nAdjust ) +/*M*/ nAdjust = SVX_ADJUST_LEFT; +/*M*/ } +/*M*/ #endif +/*M*/ +/*M*/ bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK; +/*M*/ bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK; +/*M*/ bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER; +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ static sal_Bool bOne = sal_False; +/*M*/ static sal_Bool bLast = sal_False; +/*M*/ static sal_Bool bCenter = sal_False; +/*M*/ bOneBlock |= bOne; +/*M*/ bLastBlock |= bLast; +/*M*/ bLastCenter |= bCenter; +/*M*/ #endif +/*M*/ DropInit(); +/*M*/ } + +/************************************************************************* + * SwTxtMargin::DropInit() + *************************************************************************/ +/*N*/ void SwTxtMargin::DropInit() +/*N*/ { +/*N*/ nDropLeft = nDropLines = nDropHeight = nDropDescent = 0; +/*N*/ const SwParaPortion *pPara = GetInfo().GetParaPortion(); +/*N*/ if( pPara ) +/*N*/ { +/*N*/ const SwDropPortion *pPorDrop = pPara->FindDropPortion(); +/*N*/ if ( pPorDrop ) +/*N*/ { +/*N*/ nDropLeft = pPorDrop->GetDropLeft(); +/*N*/ nDropLines = pPorDrop->GetLines(); +/*N*/ nDropHeight = pPorDrop->GetDropHeight(); +/*N*/ nDropDescent = pPorDrop->GetDropDescent(); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtMargin::GetLineStart() + *************************************************************************/ + +// Unter Beruecksichtigung des Erstzeileneinzuges und der angebenen Breite. +/*N*/ SwTwips SwTxtMargin::GetLineStart() const +/*N*/ { +/*N*/ SwTwips nRet = GetLeftMargin(); +/*N*/ if( GetAdjust() != SVX_ADJUST_LEFT && +/*N*/ !pCurr->GetFirstPortion()->IsMarginPortion() ) +/*N*/ { +/*N*/ // Wenn die erste Portion ein Margin ist, dann wird das +/*N*/ // Adjustment durch die Portions ausgedrueckt. +/*N*/ if( GetAdjust() == SVX_ADJUST_RIGHT ) +/*N*/ nRet = Right() - CurrWidth(); +/*N*/ else if( GetAdjust() == SVX_ADJUST_CENTER ) +/*N*/ nRet += (GetLineWidth() - CurrWidth()) / 2; +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtCursor::CtorInit() + *************************************************************************/ +/*N*/ void SwTxtCursor::CtorInit( SwTxtFrm *pFrm, SwTxtSizeInfo *pInf ) +/*N*/ { +/*N*/ SwTxtMargin::CtorInit( pFrm, pInf ); +/*N*/ // 6096: Vorsicht, die Iteratoren sind abgeleitet! +/*N*/ // GetInfo().SetOut( GetInfo().GetWin() ); +/*N*/ } + +/************************************************************************* + * SwTxtCursor::GetEndCharRect() + *************************************************************************/ + +// 1170: Antikbug: Shift-Ende vergisst das letzte Zeichen ... + + +/************************************************************************* + * void SwTxtCursor::_GetCharRect(..) + * internal function, called by SwTxtCursor::GetCharRect() to calculate + * the relative character position in the current line. + * pOrig referes to x and y coordinates, width and height of the cursor + * pCMS is used for restricting the cursor, if there are different font + * heights in one line ( first value = offset to y of pOrig, second + * value = real height of (shortened) cursor + *************************************************************************/ + +/*N*/ void SwTxtCursor::_GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, +/*N*/ SwCrsrMoveState* pCMS ) +/*N*/ { +/*N*/ const XubString &rText = GetInfo().GetTxt(); +/*N*/ SwTxtSizeInfo aInf( GetInfo(), rText, nStart ); +/*N*/ if( GetPropFont() ) +/*?*/ aInf.GetFont()->SetProportion( GetPropFont() ); +/*N*/ KSHORT nTmpAscent, nTmpHeight; // Zeilenhoehe +/*N*/ CalcAscentAndHeight( nTmpAscent, nTmpHeight ); +/*N*/ const Size aCharSize( 1, nTmpHeight ); +/*N*/ const Point aCharPos; +/*N*/ pOrig->Pos( aCharPos ); +/*N*/ pOrig->SSize( aCharSize ); +/*N*/ +/*N*/ // If we are looking for a position inside a field which covers +/*N*/ // more than one line we may not skip any "empty portions" at the +/*N*/ // beginning of a line +/*N*/ const sal_Bool bInsideFirstField = pCMS && pCMS->pSpecialPos && +/*N*/ ( pCMS->pSpecialPos->nLineOfst || +/*N*/ SP_EXTEND_RANGE_BEFORE == +/*N*/ pCMS->pSpecialPos->nExtendRange ); +/*N*/ +/*N*/ sal_Bool bWidth = pCMS && pCMS->bRealWidth; +/*N*/ if( !pCurr->GetLen() && !pCurr->Width() ) +/*N*/ { +/*N*/ if ( pCMS && pCMS->bRealHeight ) +/*N*/ { +/*N*/ pCMS->aRealHeight.X() = 0; +/*N*/ pCMS->aRealHeight.Y() = nTmpHeight; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ KSHORT nPorHeight = nTmpHeight; +/*N*/ KSHORT nPorAscent = nTmpAscent; +/*N*/ SwTwips nX = 0; +/*N*/ SwTwips nFirst = 0; +/*N*/ SwLinePortion *pPor = pCurr->GetFirstPortion(); +/*N*/ SvShorts* pSpaceAdd = pCurr->GetpSpaceAdd(); +/*N*/ SvUShorts* pKanaComp = pCurr->GetpKanaComp(); +/*N*/ MSHORT nSpaceIdx = 0; +/*N*/ MSHORT nKanaIdx = 0; +/*N*/ short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0; +/*N*/ +/*N*/ sal_Bool bNoTxt = sal_True; +/*N*/ +/*N*/ // Zuerst werden alle Portions ohne Len am Zeilenanfang uebersprungen. +/*N*/ // Ausnahme bilden die fiesen Spezialportions aus WhichFirstPortion: +/*N*/ // Num, ErgoSum, FtnNum, FeldReste +/*N*/ // 8477: aber auch die einzige Textportion einer leeren Zeile mit +/*N*/ // Right/Center-Adjustment! Also nicht nur pPor->GetExpandPortion() ... +/*N*/ +/*N*/ while( pPor && !pPor->GetLen() && ! bInsideFirstField ) +/*N*/ { +/*N*/ nX += pPor->Width(); +/*N*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nX += pPor->CalcSpacing( nSpaceAdd, aInf ); +/*N*/ if( bNoTxt ) +/*N*/ nFirst = nX; +/*N*/ // 8670: EndPortions zaehlen hier einmal als TxtPortions. +/*N*/ if( pPor->InTxtGrp() || pPor->IsBreakPortion() ) +/*N*/ { +/*N*/ bNoTxt = sal_False; +/*N*/ nFirst = nX; +/*N*/ } +/*N*/ if( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() ) +/*N*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->Count() ) +/*?*/ ++nKanaIdx; +/*N*/ } +/*N*/ if( pPor->InFixMargGrp() ) +/*N*/ { +/*N*/ if( pPor->IsMarginPortion() ) +/*N*/ bNoTxt = sal_False; +/*N*/ else +/*N*/ { +/*N*/ // fix margin portion => next SpaceAdd, KanaComp value +/*N*/ if( pSpaceAdd ) +/*N*/ { +/*N*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*N*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*N*/ else +/*N*/ nSpaceAdd = 0; +/*N*/ } +/*N*/ +/*N*/ if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->Count() ) +/*N*/ ++nKanaIdx; +/*N*/ } +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ +/*N*/ if( !pPor ) +/*N*/ { +/*N*/ // Es sind nur Spezialportions unterwegs. +/*N*/ nX = nFirst; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() && +/*N*/ (!pPor->InFldGrp() || pPor->GetAscent() ) ) +/*N*/ { +/*N*/ nPorHeight = pPor->Height(); +/*N*/ nPorAscent = pPor->GetAscent(); +/*N*/ } +/*N*/ #ifdef BIDI +/*N*/ while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst || +/*N*/ ( bWidth && ( pPor->IsKernPortion() || pPor->IsMultiPortion() ) ) ) ) +/*N*/ #else +/*N*/ while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst || +/*N*/ ( bWidth && pPor->IsMultiPortion() ) ) ) +/*N*/ #endif +/*N*/ { +/*N*/ if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() && +/*N*/ (!pPor->InFldGrp() || pPor->GetAscent() ) ) +/*N*/ { +/*N*/ nPorHeight = pPor->Height(); +/*N*/ nPorAscent = pPor->GetAscent(); +/*N*/ } +/*N*/ +/*N*/ // If we are behind the portion, we add the portion width to +/*N*/ // nX. Special case: nOfst = aInf.GetIdx() + pPor->GetLen(). +/*N*/ // For common portions (including BidiPortions) we want to add +/*N*/ // the portion width to nX. For MultiPortions, nExtra = 0, +/*N*/ // therefore we go to the 'else' branch and start a recursion. +/*N*/ const BYTE nExtra = pPor->IsMultiPortion() && +/*N*/ ! ((SwMultiPortion*)pPor)->IsBidi() && +/*N*/ ! bWidth ? 0 : 1; +/*N*/ if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra ) +/*N*/ { +/*N*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ nX += pPor->PrtWidth() + +/*N*/ else +/*N*/ { +/*N*/ if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) +/*N*/ { +/*N*/ // update to current SpaceAdd, KanaComp values +/*N*/ if ( pSpaceAdd ) +/*N*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*N*/ +/*N*/ if ( pKanaComp && +/*N*/ ( nKanaIdx + 1 ) < pKanaComp->Count() +/*N*/ ) +/*N*/ ++nKanaIdx; +/*N*/ } +/*N*/ if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() && +/*N*/ !pPor->GetPortion()->IsMarginPortion() ) ) +/*N*/ nX += pPor->PrtWidth(); +/*N*/ } +/*N*/ if( pPor->IsMultiPortion() ) +/*N*/ { +/*N*/ if ( ((SwMultiPortion*)pPor)->HasTabulator() ) +/*N*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->Count() ) +/*?*/ ++nKanaIdx; +/*N*/ } +/*N*/ +/*N*/ } +/*N*/ +/*N*/ aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() ); +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pPor->IsMultiPortion() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ #ifdef VERTICAL_LAYOUT +/*N*/ } +/*N*/ if ( pPor->PrtWidth() ) +/*N*/ { +/*N*/ xub_StrLen nOldLen = pPor->GetLen(); +/*N*/ pPor->SetLen( nOfst - aInf.GetIdx() ); +/*N*/ aInf.SetLen( pPor->GetLen() ); +/*N*/ if( nX || !pPor->InNumberGrp() ) +/*N*/ { +/*N*/ SeekAndChg( aInf ); +/*N*/ const sal_Bool bOldOnWin = aInf.OnWin(); +/*N*/ aInf.SetOnWin( sal_False ); // keine BULLETs! +/*N*/ SwTwips nTmp = nX; +/*N*/ aInf.SetKanaComp( pKanaComp ); +/*N*/ aInf.SetKanaIdx( nKanaIdx ); +/*N*/ nX += pPor->GetTxtSize( aInf ).Width(); +/*N*/ aInf.SetOnWin( bOldOnWin ); +/*N*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*N*/ nX += pPor->CalcSpacing( nSpaceAdd, aInf ); +/*N*/ if( bWidth ) +/*N*/ { +/*?*/ pPor->SetLen( pPor->GetLen() + 1 ); +/*?*/ aInf.SetLen( pPor->GetLen() ); +/*?*/ aInf.SetOnWin( sal_False ); // keine BULLETs! +/*?*/ nTmp += pPor->GetTxtSize( aInf ).Width(); +/*?*/ aInf.SetOnWin( bOldOnWin ); +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ nTmp += pPor->CalcSpacing(nSpaceAdd, aInf); +/*?*/ pOrig->Width( nTmp - nX ); +/*N*/ } +/*N*/ } +/*N*/ pPor->SetLen( nOldLen ); +/*N*/ } +/*N*/ bWidth = sal_False; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( pPor ) +/*N*/ { +/*N*/ ASSERT( !pPor->InNumberGrp() || bInsideFirstField, "Number surprise" ); +/*N*/ sal_Bool bEmptyFld = sal_False; +/*N*/ if( pPor->InFldGrp() && pPor->GetLen() ) +/*N*/ { +/*N*/ SwFldPortion *pTmp = (SwFldPortion*)pPor; +/*N*/ while( pTmp->HasFollow() && !pTmp->GetExp().Len() ) +/*N*/ { +/*?*/ KSHORT nAddX = pTmp->Width(); +/*?*/ SwLinePortion *pNext = pTmp->GetPortion(); +/*?*/ while( pNext && !pNext->InFldGrp() ) +/*?*/ { +/*?*/ ASSERT( !pNext->GetLen(), "Where's my field follow?" ); +/*?*/ nAddX += pNext->Width(); +/*?*/ pNext = pNext->GetPortion(); +/*?*/ } +/*?*/ if( !pNext ) +/*?*/ break; +/*?*/ pTmp = (SwFldPortion*)pNext; +/*?*/ nPorHeight = pTmp->Height(); +/*?*/ nPorAscent = pTmp->GetAscent(); +/*?*/ nX += nAddX; +/*?*/ bEmptyFld = sal_True; +/*N*/ } +/*N*/ } +/*N*/ // 8513: Felder im Blocksatz, ueberspringen +/*N*/ while( pPor && !pPor->GetLen() && ! bInsideFirstField && +/*N*/ ( pPor->IsFlyPortion() || pPor->IsKernPortion() || +/*N*/ pPor->IsBlankPortion() || pPor->InTabGrp() || +/*N*/ ( !bEmptyFld && pPor->InFldGrp() ) ) ) +/*N*/ { +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ nX += pPor->PrtWidth() + +/*?*/ pPor->CalcSpacing( nSpaceAdd, aInf ); +/*?*/ else +/*?*/ { +/*?*/ if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) +/*?*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->Count() ) +/*?*/ ++nKanaIdx; +/*?*/ } +/*?*/ if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() && +/*?*/ !pPor->GetPortion()->IsMarginPortion() ) ) +/*?*/ nX += pPor->PrtWidth(); +/*?*/ } +/*?*/ if( pPor->IsMultiPortion() && +/*?*/ ((SwMultiPortion*)pPor)->HasTabulator() ) +/*?*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->Count() ) +/*?*/ ++nKanaIdx; +/*?*/ } +/*?*/ if( !pPor->IsFlyPortion() ) +/*?*/ { +/*?*/ nPorHeight = pPor->Height(); +/*?*/ nPorAscent = pPor->GetAscent(); +/*?*/ } +/*?*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ +/*N*/ if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() && +/*N*/ pPor->GetPortion() && pPor->GetPortion()->InFixGrp() ) +/*N*/ { +/*N*/ // Alle Sonderportions muessen uebersprungen werden +/*N*/ // Beispiel: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right() +/*N*/ // Ohne den Ausgleich landen wir vor '-' mit dem +/*N*/ // Ausgleich vor 's'. +/*N*/ while( pPor && !pPor->GetLen() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ nX += pPor->Width(); +/*N*/ if( !pPor->IsMarginPortion() ) +/*N*/ { +/*N*/ nPorHeight = pPor->Height(); +/*N*/ nPorAscent = pPor->GetAscent(); +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ } +/*N*/ if( pPor && pCMS ) +/*N*/ { +/*N*/ if( pCMS->bFieldInfo && pPor->InFldGrp() && pPor->Width() ) +/*N*/ pOrig->Width( pPor->Width() ); +/*N*/ if( pPor->IsDropPortion() ) +/*N*/ { +/*?*/ nPorAscent = ((SwDropPortion*)pPor)->GetDropHeight(); +/*?*/ // The drop height is only calculated, if we have more than +/*?*/ // one line. Otherwise it is 0. +/*?*/ if ( ! nPorAscent) +/*?*/ nPorAscent = pPor->Height(); +/*?*/ nPorHeight = nPorAscent; +/*?*/ pOrig->Height( nPorHeight + +/*?*/ ((SwDropPortion*)pPor)->GetDropDescent() ); +/*?*/ if( nTmpHeight < pOrig->Height() ) +/*?*/ { +/*?*/ nTmpAscent = nPorAscent; +/*?*/ nTmpHeight = USHORT( pOrig->Height() ); +/*?*/ } +/*N*/ } +/*N*/ if( bWidth && pPor->PrtWidth() && pPor->GetLen() && +/*N*/ aInf.GetIdx() == nOfst ) +/*N*/ { +/*?*/ if( !pPor->IsFlyPortion() && pPor->Height() && +/*?*/ pPor->GetAscent() ) +/*?*/ { +/*?*/ nPorHeight = pPor->Height(); +/*?*/ nPorAscent = pPor->GetAscent(); +/*?*/ } +/*?*/ SwTwips nTmp; +/*?*/ if( 2 > pPor->GetLen() ) +/*?*/ { +/*?*/ nTmp = pPor->Width(); +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ nTmp += pPor->CalcSpacing( nSpaceAdd, aInf ); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ const sal_Bool bOldOnWin = aInf.OnWin(); +/*?*/ xub_StrLen nOldLen = pPor->GetLen(); +/*?*/ pPor->SetLen( 1 ); +/*?*/ aInf.SetLen( pPor->GetLen() ); +/*?*/ SeekAndChg( aInf ); +/*?*/ aInf.SetOnWin( sal_False ); // keine BULLETs! +/*?*/ aInf.SetKanaComp( pKanaComp ); +/*?*/ aInf.SetKanaIdx( nKanaIdx ); +/*?*/ nTmp = pPor->GetTxtSize( aInf ).Width(); +/*?*/ aInf.SetOnWin( bOldOnWin ); +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ nTmp += pPor->CalcSpacing( nSpaceAdd, aInf ); +/*?*/ pPor->SetLen( nOldLen ); +/*?*/ } +/*?*/ pOrig->Width( nTmp ); +/*N*/ } +/*N*/ +/*N*/ // travel inside field portion? +/*N*/ if ( pCMS->pSpecialPos ) +/*N*/ { +/*N*/ // apply attributes to font + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ Seek( nOfst ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pOrig->Pos().X() += nX; +/*N*/ +/*N*/ if ( pCMS && pCMS->bRealHeight ) +/*N*/ { +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ nTmpAscent = AdjustBaseLine( *pCurr, 0, nPorHeight, nPorAscent ); +/*N*/ #else +/*N*/ nTmpAscent = AdjustBaseLine( *pCurr, nPorHeight, nPorAscent ); +/*N*/ #endif +/*N*/ if ( nTmpAscent > nPorAscent ) +/*N*/ pCMS->aRealHeight.X() = nTmpAscent - nPorAscent; +/*N*/ else +/*N*/ pCMS->aRealHeight.X() = 0; +/*N*/ ASSERT( nPorHeight, "GetCharRect: Missing Portion-Height" ); +/*N*/ if ( nTmpHeight > nPorHeight ) +/*N*/ pCMS->aRealHeight.Y() = nPorHeight; +/*N*/ else +/*N*/ pCMS->aRealHeight.Y() = nTmpHeight; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtCursor::GetCharRect() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtCursor::GetCharRect( SwRect* pOrig, const xub_StrLen nOfst, +/*N*/ SwCrsrMoveState* pCMS, const long nMax ) +/*N*/ { +/*N*/ CharCrsrToLine(nOfst); +/*N*/ +/*N*/ // Indicates that a position inside a special portion (field, number portion) +/*N*/ // is requested. +/*N*/ const sal_Bool bSpecialPos = pCMS && pCMS->pSpecialPos; +/*N*/ xub_StrLen nFindOfst = nOfst; +/*N*/ +/*N*/ if ( bSpecialPos ) +/*N*/ { +/*?*/ xub_StrLen nLineOfst = pCMS->pSpecialPos->nLineOfst; +/*?*/ BYTE nExtendRange = pCMS->pSpecialPos->nExtendRange; +/*?*/ +/*?*/ ASSERT( ! nLineOfst || SP_EXTEND_RANGE_BEFORE != nExtendRange, +/*?*/ "LineOffset AND Number Portion?" ) +/*?*/ +/*?*/ // portions which are behind the string +/*?*/ if ( SP_EXTEND_RANGE_BEHIND == nExtendRange ) +/*?*/ ++nFindOfst; +/*?*/ +/*?*/ // skip lines for fields which cover more than one line +/*?*/ for ( USHORT i = 0; i < pCMS->pSpecialPos->nLineOfst; i++ ) +/*?*/ Next(); +/*N*/ } +/*N*/ +/*N*/ // Adjustierung ggf. nachholen +/*N*/ GetAdjusted(); +/*N*/ +/*N*/ const Point aCharPos( GetTopLeft() ); +/*N*/ sal_Bool bRet = sal_True; +/*N*/ +/*N*/ _GetCharRect( pOrig, nFindOfst, pCMS ); +/*N*/ +/*N*/ const SwTwips nRight = Right() - 12; +/*N*/ +/*N*/ pOrig->Pos().X() += aCharPos.X(); +/*N*/ pOrig->Pos().Y() += aCharPos.Y(); +/*N*/ +/*N*/ if( pCMS && pCMS->b2Lines && pCMS->p2Lines ) +/*N*/ { +/*?*/ pCMS->p2Lines->aLine.Pos().X() += aCharPos.X(); +/*?*/ pCMS->p2Lines->aLine.Pos().Y() += aCharPos.Y(); +/*?*/ pCMS->p2Lines->aPortion.Pos().X() += aCharPos.X(); +/*?*/ pCMS->p2Lines->aPortion.Pos().Y() += aCharPos.Y(); +/*N*/ } +/*N*/ +/*N*/ if( pOrig->Left() > nRight ) +/*?*/ pOrig->Pos().X() = nRight; +/*N*/ +/*N*/ if( nMax ) +/*N*/ { +/*N*/ +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ if( pOrig->Top() + pOrig->Height() > nMax ) +/*N*/ { +/*N*/ if( pOrig->Top() > nMax ) +/*N*/ pOrig->Top( nMax ); +/*N*/ pOrig->Height( nMax - pOrig->Top() ); +/*N*/ #else +/*N*/ if( pOrig->Bottom() > nMax ) +/*N*/ { +/*N*/ if( pOrig->Top() > nMax ) +/*N*/ pOrig->Top( nMax ); +/*N*/ pOrig->Bottom( nMax ); +/*N*/ #endif +/*N*/ } +/*N*/ if ( pCMS && pCMS->bRealHeight && pCMS->aRealHeight.Y() >= 0 ) +/*N*/ { +/*N*/ long nTmp = pCMS->aRealHeight.X() + pOrig->Top(); +/*N*/ if( nTmp >= nMax ) +/*N*/ { +/*?*/ pCMS->aRealHeight.X() = nMax - pOrig->Top(); +/*?*/ pCMS->aRealHeight.Y() = 0; +/*N*/ } +/*N*/ else if( nTmp + pCMS->aRealHeight.Y() > nMax ) +/*?*/ pCMS->aRealHeight.Y() = nMax - nTmp; +/*N*/ } +/*N*/ } +/*N*/ long nOut = pOrig->Right() - GetTxtFrm()->Frm().Right(); +/*N*/ if( nOut > 0 ) +/*N*/ { +/*N*/ if( GetTxtFrm()->Frm().Width() < GetTxtFrm()->Prt().Left() +/*N*/ + GetTxtFrm()->Prt().Width() ) +/*?*/ nOut += GetTxtFrm()->Frm().Width() - GetTxtFrm()->Prt().Left() +/*?*/ - GetTxtFrm()->Prt().Width(); +/*N*/ if( nOut > 0 ) +/*?*/ pOrig->Pos().X() -= nOut + 10; +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtCursor::GetCrsrOfst() + * + * Return: Offset im String + *************************************************************************/ +/*N*/ xub_StrLen SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint, +/*N*/ const MSHORT nChgNode, const SwCrsrMoveState* pCMS ) const +/*N*/ { +/*N*/ // Adjustierung ggf. nachholen +/*N*/ GetAdjusted(); +/*N*/ +/*N*/ const XubString &rText = GetInfo().GetTxt(); +/*N*/ xub_StrLen nOffset = 0; +/*N*/ +/*N*/ // x ist der horizontale Offset innerhalb der Zeile. +/*N*/ SwTwips x = rPoint.X(); +/*N*/ CONST SwTwips nLeftMargin = GetLineStart(); +/*N*/ SwTwips nRightMargin = GetLineEnd(); +/*N*/ if( nRightMargin == nLeftMargin ) +/*N*/ nRightMargin += 30; +/*N*/ +/*N*/ const sal_Bool bLeftOver = x < nLeftMargin; +/*N*/ if( bLeftOver ) +/*N*/ x = nLeftMargin; +/*N*/ const sal_Bool bRightOver = x > nRightMargin; +/*N*/ if( bRightOver ) +/*N*/ x = nRightMargin; +/*N*/ +/*N*/ sal_Bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE ); +/*N*/ +/*N*/ // Bis hierher in Dokumentkoordinaten. +/*N*/ x -= nLeftMargin; +/*N*/ +/*N*/ KSHORT nX = KSHORT( x ); +/*N*/ +/*N*/ // Wenn es in der Zeile Attributwechsel gibt, den Abschnitt +/*N*/ // suchen, in dem nX liegt. +/*N*/ SwLinePortion *pPor = pCurr->GetFirstPortion(); +/*N*/ xub_StrLen nCurrStart = nStart; +/*N*/ sal_Bool bLastPortion; +/*N*/ sal_Bool bHolePortion = sal_False; +/*N*/ sal_Bool bLastHyph = sal_False; +/*N*/ +/*N*/ SvShorts *pSpaceAdd = pCurr->GetpSpaceAdd(); +/*N*/ SvUShorts *pKanaComp = pCurr->GetpKanaComp(); +/*N*/ xub_StrLen nOldIdx = GetInfo().GetIdx(); +/*N*/ MSHORT nSpaceIdx = 0; +/*N*/ MSHORT nKanaIdx = 0; +/*N*/ short nSpaceAdd = pSpaceAdd ? (*pSpaceAdd)[0] : 0; +/*N*/ short nKanaComp = pKanaComp ? (*pKanaComp)[0] : 0; +/*N*/ +/*N*/ // nWidth ist die Breite der Zeile, oder die Breite des +/*N*/ // Abschnitts mit dem Fontwechsel, in dem nX liegt. +/*N*/ +/*N*/ KSHORT nWidth = pPor->Width(); +/*N*/ if ( pSpaceAdd || pKanaComp ) +/*N*/ { +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ { +/*?*/ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart ); +/*?*/ nWidth += USHORT( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) ); +/*?*/ } +/*?*/ if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) || +/*?*/ ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() ) +/*?*/ ) +/*?*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if( pKanaComp ) +/*?*/ { +/*?*/ if ( nKanaIdx + 1 < pKanaComp->Count() ) +/*?*/ nKanaComp = (*pKanaComp)[++nKanaIdx]; +/*?*/ else +/*?*/ nKanaComp = 0; +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ KSHORT nWidth30; +/*N*/ if ( pPor->IsPostItsPortion() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2; +/*N*/ else +/*N*/ nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ? +/*N*/ 30 : +/*N*/ nWidth; +/*N*/ +/*N*/ while(!(bLastPortion = (0 == pPor->GetPortion())) && nWidth30 < nX && +/*N*/ !pPor->IsBreakPortion() ) +/*N*/ { +/*?*/ nX -= nWidth; +/*?*/ nCurrStart += pPor->GetLen(); +/*?*/ bHolePortion = pPor->IsHolePortion(); +/*?*/ pPor = pPor->GetPortion(); +/*?*/ nWidth = pPor->Width(); +/*?*/ if ( pSpaceAdd || pKanaComp ) +/*?*/ { +/*?*/ if ( pPor->InSpaceGrp() && nSpaceAdd ) +/*?*/ { +/*?*/ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart ); +/*?*/ nWidth += USHORT( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) ); +/*?*/ } +/*?*/ +/*?*/ if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) || +/*?*/ ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() ) +/*?*/ ) +/*?*/ { +/*?*/ if ( pSpaceAdd ) +/*?*/ { +/*?*/ if ( ++nSpaceIdx < pSpaceAdd->Count() ) +/*?*/ nSpaceAdd = (*pSpaceAdd)[nSpaceIdx]; +/*?*/ else +/*?*/ nSpaceAdd = 0; +/*?*/ } +/*?*/ +/*?*/ if ( pKanaComp ) +/*?*/ { +/*?*/ if( nKanaIdx + 1 < pKanaComp->Count() ) +/*?*/ nKanaComp = (*pKanaComp)[++nKanaIdx]; +/*?*/ else +/*?*/ nKanaComp = 0; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ if ( pPor->IsPostItsPortion() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2; +/*?*/ else +/*?*/ nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ? +/*?*/ 30 : +/*?*/ nWidth; +/*?*/ if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() ) +/*?*/ bLastHyph = pPor->InHyphGrp(); +/*N*/ } +/*N*/ +/*N*/ if( nX==nWidth ) +/*N*/ { +/*N*/ SwLinePortion *pNextPor = pPor->GetPortion(); +/*N*/ while( pNextPor && pNextPor->InFldGrp() && !pNextPor->Width() ) +/*N*/ { +/*?*/ nCurrStart += pPor->GetLen(); +/*?*/ pPor = pNextPor; +/*?*/ if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() ) +/*?*/ bLastHyph = pPor->InHyphGrp(); +/*?*/ pNextPor = pPor->GetPortion(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ ((SwTxtSizeInfo&)GetInfo()).SetIdx( nOldIdx ); +/*N*/ +/*N*/ xub_StrLen nLength = pPor->GetLen(); +/*N*/ +/*N*/ sal_Bool bFieldInfo = pCMS && pCMS->bFieldInfo; +/*N*/ +/*N*/ if( bFieldInfo && ( nWidth30 < nX || bRightOver || bLeftOver || +/*N*/ ( pPor->InNumberGrp() && !pPor->IsFtnNumPortion() ) || +/*N*/ ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) ) +/*?*/ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True; +/*N*/ +/*N*/ // 7684: Wir sind genau auf der HyphPortion angelangt und muessen dafuer +/*N*/ // sorgen, dass wir in dem String landen. +/*N*/ // 7993: Wenn die Laenge 0 ist muessen wir raus... +/*N*/ if( !nLength ) +/*N*/ { +/*N*/ if( pCMS ) +/*N*/ { +/*N*/ if( pPor->IsFlyPortion() && bFieldInfo ) +/*?*/ ((SwCrsrMoveState*)pCMS)->bPosCorr = sal_True; +/*N*/ +/*N*/ if( pPor->IsFtnNumPortion() && !bRightOver && nX ) +/*?*/ ((SwCrsrMoveState*)pCMS)->bFtnNoInfo = sal_True; +/*N*/ } +/*N*/ if( !nCurrStart ) +/*N*/ return 0; +/*N*/ +/*N*/ // 7849, 7816: auf pPor->GetHyphPortion kann nicht verzichtet werden! +/*N*/ if( bHolePortion || ( !bRightAllowed && bLastHyph ) || +/*N*/ ( pPor->IsMarginPortion() && !pPor->GetPortion() && +/*N*/ // 46598: In der letzten Zeile eines zentrierten Absatzes wollen +/*N*/ // wir auch mal hinter dem letzten Zeichen landen. +/*?*/ nCurrStart < rText.Len() ) ) +/*?*/ --nCurrStart; +/*N*/ else if( pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow() +/*N*/ && nWidth > nX ) +/*N*/ { +/*?*/ if( bFieldInfo ) +/*?*/ --nCurrStart; +/*?*/ else +/*?*/ { +/*?*/ KSHORT nHeight = pPor->Height(); +/*?*/ if ( !nHeight || nHeight > nWidth ) +/*?*/ nHeight = nWidth; +/*?*/ if( nChgNode && nWidth - nHeight/2 > nX ) +/*?*/ --nCurrStart; +/*?*/ } +/*N*/ } +/*N*/ return nCurrStart; +/*N*/ } +/*N*/ if ( 1 == nLength ) +/*N*/ { +/*?*/ if ( nWidth ) +/*?*/ { +/*?*/ // Sonst kommen wir nicht mehr in zeichengeb. Rahmen hinein... +/*?*/ if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) ) +/*?*/ { +/*?*/ if ( pPor->InFldGrp() || +/*?*/ ( pPor->IsMultiPortion() && +/*?*/ ((SwMultiPortion*)pPor)->IsBidi() ) ) +/*?*/ { +/*?*/ KSHORT nHeight = 0; +/*?*/ if( !bFieldInfo ) +/*?*/ { +/*?*/ nHeight = pPor->Height(); +/*?*/ if ( !nHeight || nHeight > nWidth ) +/*?*/ nHeight = nWidth; +/*?*/ } +/*?*/ if( nWidth - nHeight/2 <= nX && +/*?*/ ( ! pPor->InFldGrp() || +/*?*/ !((SwFldPortion*)pPor)->HasFollow() ) ) +/*?*/ ++nCurrStart; +/*?*/ } +/*?*/ else if ( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() && +/*?*/ !pPor->GetPortion()->IsMarginPortion() && +/*?*/ !pPor->GetPortion()->IsHolePortion() ) ) +/*?*/ && ( nWidth/2 < nX ) && +/*?*/ ( !bFieldInfo || +/*?*/ ( pPor->GetPortion() && +/*?*/ pPor->GetPortion()->IsPostItsPortion() ) ) +/*?*/ && ( bRightAllowed || !bLastHyph )) +/*?*/ ++nCurrStart; +/*?*/ return nCurrStart; +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() || +/*?*/ pPor->InToxRefGrp() ) +/*?*/ return nCurrStart; +/*?*/ if ( pPor->InFldGrp() ) +/*?*/ { +/*?*/ if( bRightOver && !((SwFldPortion*)pPor)->HasFollow() ) +/*?*/ ++nCurrStart; +/*?*/ return nCurrStart; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() ) ) +/*N*/ --nLength; +/*N*/ +/*N*/ if( nWidth > nX || +/*N*/ ( nWidth == nX && pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsDouble() ) ) +/*N*/ { +/*N*/ if( pPor->IsMultiPortion() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ // In a multi-portion we use GetCrsrOfst()-function recursively +/*N*/ } +/*N*/ if( pPor->InTxtGrp() ) +/*N*/ { +/*N*/ BYTE nOldProp; +/*N*/ if( GetPropFont() ) +/*N*/ { +/*?*/ ((SwFont*)GetFnt())->SetProportion( GetPropFont() ); +/*?*/ nOldProp = GetFnt()->GetPropr(); +/*N*/ } +/*N*/ else +/*N*/ nOldProp = 0; +/*N*/ { +/*N*/ SwTxtSizeInfo aSizeInf( GetInfo(), rText, nCurrStart ); +/*N*/ ((SwTxtCursor*)this)->SeekAndChg( aSizeInf ); +/*N*/ SwTxtSlot aDiffTxt( &aSizeInf, ((SwTxtPortion*)pPor) ); +/*N*/ SwFontSave aSave( aSizeInf, pPor->IsDropPortion() ? +/*N*/ ((SwDropPortion*)pPor)->GetFnt() : NULL ); +/*N*/ +/*N*/ SwParaPortion* pPara = (SwParaPortion*)GetInfo().GetParaPortion(); +/*N*/ ASSERT( pPara, "No paragraph!" ); +/*N*/ +/*N*/ SwDrawTextInfo aDrawInf( aSizeInf.GetVsh(), +/*N*/ *aSizeInf.GetOut(), +/*N*/ &pPara->GetScriptInfo(), +/*N*/ aSizeInf.GetTxt(), +/*N*/ aSizeInf.GetIdx(), +/*N*/ pPor->GetLen() ); +/*N*/ aDrawInf.SetOfst( nX ); +/*N*/ aDrawInf.SetSpace( nSpaceAdd ); +/*N*/ aDrawInf.SetFont( aSizeInf.GetFont() ); +/*N*/ aDrawInf.SetFrm( pFrm ); +/*N*/ aDrawInf.SetSnapToGrid( aSizeInf.SnapToGrid() ); +/*N*/ aDrawInf.SetPosMatchesBounds( pCMS && pCMS->bPosMatchesBounds ); +/*N*/ +/*N*/ if ( SW_CJK == aSizeInf.GetFont()->GetActual() && +/*N*/ pPara->GetScriptInfo().CountCompChg() && +/*N*/ ! pPor->InFldGrp() ) +/*?*/ aDrawInf.SetKanaComp( nKanaComp ); +/*N*/ +/*N*/ nLength = aSizeInf.GetFont()->_GetCrsrOfst( aDrawInf ); +/*N*/ +/*N*/ if ( pCMS ) +/*N*/ ((SwCrsrMoveState*)pCMS)->nCursorBidiLevel = +/*N*/ aDrawInf.GetCursorBidiLevel(); +/*N*/ +/*N*/ if( bFieldInfo && nLength == pPor->GetLen() && +/*N*/ ( ! pPor->GetPortion() || +/*N*/ ! pPor->GetPortion()->IsPostItsPortion() ) ) +/*N*/ --nLength; +/*N*/ } +/*N*/ if( nOldProp ) +/*?*/ ((SwFont*)GetFnt())->SetProportion( nOldProp ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nChgNode && pPos && pPor->IsFlyCntPortion() +/*N*/ && !( (SwFlyCntPortion*)pPor )->IsDraw() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ { +/*N*/ } +/*N*/ } +/*N*/ nOffset = nCurrStart + nLength; +/*N*/ +/*N*/ // 7684: Wir sind vor der HyphPortion angelangt und muessen dafuer +/*N*/ // sorgen, dass wir in dem String landen. +/*N*/ // Bei Zeilenenden vor FlyFrms muessen ebenso behandelt werden. +/*N*/ +/*N*/ if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() && +/*N*/ !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() ) +/*N*/ --nOffset; +/*N*/ +/*N*/ return nOffset; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itrform2.cxx b/binfilter/bf_sw/source/core/text/sw_itrform2.cxx new file mode 100644 index 000000000000..2a974ccbcf2a --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itrform2.cxx @@ -0,0 +1,1871 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "hintids.hxx" + +#include <com/sun/star/i18n/ScriptType.hdl> + +#include <bf_svx/lspcitem.hxx> + +#include <txtftn.hxx> +#include <fmtftn.hxx> +#include <ftninfo.hxx> +#include <charfmt.hxx> +#include <bf_svx/charrotateitem.hxx> +#include <paratr.hxx> // SwFmtDrop +#include <hintids.hxx> // CH_TXTATR +#include <txtcfg.hxx> +#include <itrform2.hxx> +#include <portab.hxx> // pLastTab-> +#include <porfly.hxx> // CalcFlyWidth +#include <portox.hxx> // WhichTxtPortion +#include <porref.hxx> // WhichTxtPortion + +#include <horiornt.hxx> + +#include <porftn.hxx> // SwFtnPortion +#include <porhyph.hxx> +#include <guess.hxx> +#include <ftnfrm.hxx> // WhichFirstPortion() -> mal Verlagern. + +#include <pagefrm.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> + +#include <doc.hxx> // SwDoc +#include <pormulti.hxx> // SwMultiPortion +#define _SVSTDARR_LONGS +#include <bf_svtools/svstdarr.hxx> +#include <unotools/charclass.hxx> + +#if OSL_DEBUG_LEVEL > 1 +#endif +namespace binfilter { + +using namespace ::com::sun::star::i18n; +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +extern sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt ); + +#define MAX_TXTPORLEN 300 + +/*N*/ inline void ClearFly( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( rInf.GetFly() ) +/*N*/ { +/*N*/ delete rInf.GetFly(); +/*N*/ rInf.SetFly(0); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CtorInit() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::CtorInit( SwTxtFrm *pFrm, SwTxtFormatInfo *pNewInf ) +/*N*/ { +/*N*/ SwTxtPainter::CtorInit( pFrm, pNewInf ); +/*N*/ pInf = pNewInf; +/*N*/ pDropFmt = GetInfo().GetDropFmt(); +/*N*/ pMulti = NULL; +/*N*/ +/*N*/ bOnceMore = sal_False; +/*N*/ bChanges = sal_False; +/*N*/ bTruncLines = sal_False; +/*N*/ nCntEndHyph = 0; +/*N*/ nCntMidHyph = 0; +/*N*/ nLeftScanIdx = STRING_LEN; +/*N*/ nRightScanIdx = 0; +/*N*/ +/*N*/ if( nStart > GetInfo().GetTxt().Len() ) +/*N*/ { +/*?*/ ASSERT( !this, "+SwTxtFormatter::CTOR: bad offset" ); +/*?*/ nStart = GetInfo().GetTxt().Len(); +/*N*/ } +/*N*/ +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::DTOR + *************************************************************************/ + +/*N*/ SwTxtFormatter::~SwTxtFormatter() +/*N*/ { +/*N*/ // Auesserst unwahrscheinlich aber denkbar. +/*N*/ // z.B.: Feld spaltet sich auf, Widows schlagen zu +/*N*/ if( GetInfo().GetRest() ) +/*N*/ { +/*?*/ delete GetInfo().GetRest(); +/*?*/ GetInfo().SetRest(0); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::Insert() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::Insert( SwLineLayout *pLay ) +/*N*/ { +/*N*/ // Einfuegen heute mal ausnahmsweise hinter dem aktuellen Element. +/*N*/ if ( pCurr ) +/*N*/ { +/*N*/ pLay->SetNext( pCurr->GetNext() ); +/*N*/ pCurr->SetNext( pLay ); +/*N*/ } +/*N*/ else +/*N*/ pCurr = pLay; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::GetFrmRstHeight() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFormatter::UnderFlow() + *************************************************************************/ + +/*N*/ SwLinePortion *SwTxtFormatter::UnderFlow( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ // Werte sichern und rInf initialisieren. +/*N*/ SwLinePortion *pUnderFlow = rInf.GetUnderFlow(); +/*N*/ if( !pUnderFlow ) +/*N*/ return 0; +/*N*/ +/*N*/ // Wir formatieren rueckwaerts, d.h. dass Attributwechsel in der +/*N*/ // naechsten Zeile durchaus noch einmal drankommen koennen. +/*N*/ // Zu beobachten in 8081.sdw, wenn man in der ersten Zeile Text eingibt. +/*N*/ +/*N*/ const xub_StrLen nSoftHyphPos = rInf.GetSoftHyphPos(); +/*N*/ const xub_StrLen nUnderScorePos = rInf.GetUnderScorePos(); +/*N*/ +/*N*/ // 8358, 8359: Flys sichern und auf 0 setzen, sonst GPF +/*N*/ // 3983: Nicht ClearFly(rInf) ! +/*N*/ SwFlyPortion *pFly = rInf.GetFly(); +/*N*/ rInf.SetFly( 0 ); +/*N*/ +/*N*/ FeedInf( rInf ); +/*N*/ rInf.SetLast( pCurr ); +/*N*/ // pUnderFlow braucht nicht deletet werden, weil es im folgenden +/*N*/ // Truncate() untergehen wird. +/*N*/ rInf.SetUnderFlow(0); +/*N*/ rInf.SetSoftHyphPos( nSoftHyphPos ); +/*N*/ rInf.SetUnderScorePos( nUnderScorePos ); +/*N*/ rInf.SetPaintOfst( GetLeftMargin() ); +/*N*/ +/*N*/ // Wir suchen die Portion mit der Unterlaufposition +/*N*/ SwLinePortion *pPor = pCurr->GetFirstPortion(); +/*N*/ if( pPor != pUnderFlow ) +/*N*/ { +/*N*/ // pPrev wird die letzte Portion vor pUnderFlow, +/*N*/ // die noch eine echte Breite hat. +/*N*/ // Ausnahme: SoftHyphPortions duerfen dabei natuerlich +/*N*/ // nicht vergessen werden, obwohl sie keine Breite haben. +/*N*/ SwLinePortion *pPrev = pPor; +/*N*/ while( pPor && pPor != pUnderFlow ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if( !pPor->IsKernPortion() && +/*N*/ ( pPor->Width() || pPor->IsSoftHyphPortion() ) ) +/*N*/ { +/*N*/ while( pPrev != pPor ) +/*N*/ { +/*N*/ pPrev->Move( rInf ); +/*N*/ rInf.SetLast( pPrev ); +/*N*/ pPrev = pPrev->GetPortion(); +/*N*/ ASSERT( pPrev, "UnderFlow: Loosing control!" ); +/*N*/ }; +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ pPor = pPrev; +/*N*/ if( pPor && // Flies + Initialen werden nicht beim UnderFlow mitgenommen +/*N*/ ( pPor->IsFlyPortion() || pPor->IsDropPortion() || +/*N*/ pPor->IsFlyCntPortion() ) ) +/*N*/ { +/*N*/ pPor->Move( rInf ); +/*N*/ rInf.SetLast( pPor ); +/*N*/ rInf.SetStopUnderFlow( sal_True ); +/*N*/ pPor = pUnderFlow; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Was? Die Unterlaufsituation ist nicht in der Portion-Kette ? +/*N*/ ASSERT( pPor, "SwTxtFormatter::UnderFlow: overflow but underflow" ); +/*N*/ +/*N*/ if( rInf.IsFtnInside() && pPor && !rInf.IsQuick() ) +/*N*/ { +/*?*/ SwLinePortion *pTmp = pPor->GetPortion(); +/*?*/ while( pTmp ) +/*?*/ { +/*?*/ if( pTmp->IsFtnPortion() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ((SwFtnPortion*)pTmp)->ClearFtn(); +/*?*/ pTmp = pTmp->GetPortion(); +/*?*/ } +/*N*/ } +/*N*/ + /*-----------------14.12.94 09:45------------------- + * 9849: Schnellschuss + * --------------------------------------------------*/ +/*N*/ if ( pPor==rInf.GetLast() ) +/*N*/ { +/*N*/ // Hier landen wir, wenn die UnderFlow-ausloesende Portion sich +/*N*/ // ueber die ganze Zeile erstreckt, z. B. wenn ein Wort ueber +/*N*/ // mehrere Zeilen geht und in der zweiten Zeile in einen Fly +/*N*/ // hineinlaeuft! +/*?*/ rInf.SetFly( pFly ); // wg. 28300 +/*?*/ pPor->Truncate(); +/*?*/ return pPor; // Reicht das? +/*N*/ } + /*--------------------------------------------------- + * Ende des Schnellschusses wg. 9849 + * --------------------------------------------------*/ +/*N*/ +/*N*/ // 4656: X + Width == 0 bei SoftHyph > Zeile ?! +/*N*/ if( !pPor || !(rInf.X() + pPor->Width()) ) +/*N*/ { +/*?*/ delete pFly; +/*?*/ return 0; +/*N*/ } +/*N*/ +/*N*/ // Vorbereitungen auf's Format() +/*N*/ // Wir muessen die Kette hinter pLast abknipsen, weil +/*N*/ // nach dem Format() ein Insert erfolgt. +/*N*/ SeekAndChg( rInf ); +/*N*/ +/*N*/ // line width is adjusted, so that pPor does not fit to current +/*N*/ // line anymore +/*N*/ rInf.Width( (USHORT)(rInf.X() + (pPor->Width() ? pPor->Width() - 1 : 0)) ); +/*N*/ rInf.SetLen( pPor->GetLen() ); +/*N*/ rInf.SetFull( sal_False ); +/*N*/ if( pFly ) +/*N*/ { +/*N*/ // Aus folgendem Grund muss die FlyPortion neu berechnet werden: +/*N*/ // Wenn durch einen grossen Font in der Mitte der Zeile die Grundlinie +/*N*/ // abgesenkt wird und dadurch eine Ueberlappung mit eine Fly entsteht, +/*N*/ // so hat die FlyPortion eine falsche Groesse/Fixsize. +/*N*/ rInf.SetFly( pFly ); +/*N*/ CalcFlyWidth( rInf ); +/*N*/ } +/*N*/ rInf.GetLast()->SetPortion(0); +/*N*/ +/*N*/ // Eine Ausnahme bildet das SwLineLayout, dass sich beim +/*N*/ // ersten Portionwechsel aufspaltet. Hier nun der umgekehrte Weg: +/*N*/ if( rInf.GetLast() == pCurr ) +/*N*/ { +/*N*/ if( pPor->InTxtGrp() && !pPor->InExpGrp() ) +/*N*/ { +/*N*/ MSHORT nOldWhich = pCurr->GetWhichPor(); +/*N*/ *(SwLinePortion*)pCurr = *pPor; +/*N*/ pCurr->SetPortion( pPor->GetPortion() ); +/*N*/ pCurr->SetWhichPor( nOldWhich ); +/*N*/ pPor->SetPortion( 0 ); +/*N*/ delete pPor; +/*N*/ pPor = pCurr; +/*N*/ } +/*N*/ } +/*N*/ pPor->Truncate(); +/*N*/ delete rInf.GetRest(); +/*N*/ rInf.SetRest(0); +/*N*/ return pPor; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::InsertPortion() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::InsertPortion( SwTxtFormatInfo &rInf, +/*N*/ SwLinePortion *pPor ) const +/*N*/ { +/*N*/ // Die neue Portion wird eingefuegt, +/*N*/ // bei dem LineLayout ist allerdings alles anders... +/*N*/ if( pPor == pCurr ) +/*N*/ { +/*N*/ if( pCurr->GetPortion() ) +/*N*/ pPor = pCurr->GetPortion(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwLinePortion *pLast = rInf.GetLast(); +/*N*/ if( pLast->GetPortion() ) +/*N*/ { +/*?*/ while( pLast->GetPortion() ) +/*?*/ pLast = pLast->GetPortion(); +/*?*/ rInf.SetLast( pLast ); +/*N*/ } +/*N*/ pLast->Insert( pPor ); +/*N*/ +/*N*/ // Maxima anpassen: +/*N*/ if( pCurr->Height() < pPor->Height() ) +/*N*/ pCurr->Height( pPor->Height() ); +/*N*/ if( pCurr->GetAscent() < pPor->GetAscent() ) +/*N*/ pCurr->SetAscent( pPor->GetAscent() ); +/*N*/ } +/*N*/ +/*N*/ // manchmal werden ganze Ketten erzeugt (z.B. durch Hyphenate) +/*N*/ rInf.SetLast( pPor ); +/*N*/ while( pPor ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ pPor->Move( rInf ); +/*N*/ rInf.SetLast( pPor ); +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::BuildPortion() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::BuildPortions( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ ASSERT( rInf.GetTxt().Len() < STRING_LEN, +/*N*/ "SwTxtFormatter::BuildPortions: bad text length in info" ); +/*N*/ +/*N*/ rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() ); +/*N*/ +/*N*/ // Erst NewTxtPortion() entscheidet, ob pCurr in pPor landet. +/*N*/ // Wir muessen in jedem Fall dafuer sorgen, dass der Font eingestellt +/*N*/ // wird. In CalcAscent geschieht dies automatisch. +/*N*/ rInf.SetLast( pCurr ); +/*N*/ rInf.ForcedLeftMargin( 0 ); +/*N*/ +/*N*/ ASSERT( pCurr->FindLastPortion() == pCurr, "pLast supposed to equal pCurr" ); +/*N*/ +/*N*/ if( !pCurr->GetAscent() && !pCurr->Height() ) +/*N*/ CalcAscent( rInf, pCurr ); +/*N*/ +/*N*/ SeekAndChg( rInf ); +/*N*/ +/*N*/ // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt. +/*N*/ ASSERT( !rInf.X() || pMulti, "SwTxtFormatter::BuildPortion X=0?" ); +/*N*/ CalcFlyWidth( rInf ); +/*N*/ SwFlyPortion *pFly = rInf.GetFly(); +/*N*/ if( pFly ) +/*N*/ { +/*N*/ if ( 0 < pFly->Fix() ) +/*N*/ ClearFly( rInf ); +/*N*/ else +/*N*/ rInf.SetFull(sal_True); +/*N*/ } +/*N*/ +/*N*/ SwLinePortion *pPor = NewPortion( rInf ); +/*N*/ + // Asian grid stuff +/*N*/ GETGRID( pFrm->FindPageFrm() ) +/*N*/ const sal_Bool bHasGrid = pGrid && rInf.SnapToGrid() && +/*N*/ GRID_LINES_CHARS == pGrid->GetGridType(); +/*N*/ +/*N*/ const USHORT nGridWidth = bHasGrid ? +/*N*/ pGrid->GetBaseHeight() : 0; +/*N*/ +/*N*/ // used for grid mode only: +/*N*/ // the pointer is stored, because after formatting of non-asian text, +/*N*/ // the width of the kerning portion has to be adjusted +/*N*/ SwKernPortion* pGridKernPortion = 0; +/*N*/ +/*N*/ sal_Bool bFull; +/*N*/ SwTwips nUnderLineStart = 0; +/*N*/ rInf.Y( Y() ); +/*N*/ +/*N*/ while( pPor && !rInf.IsStop() ) +/*N*/ { +/*N*/ ASSERT( rInf.GetLen() < STRING_LEN && +/*N*/ rInf.GetIdx() <= rInf.GetTxt().Len(), +/*N*/ "SwTxtFormatter::BuildPortions: bad length in info" ); +///*N*/ DBG_LOOP; +/*N*/ +/*N*/ // We have to check the script for fields in order to set the +/*N*/ // correct nActual value for the font. +/*N*/ if( pPor->InFldGrp() && ! pPor->IsFtnPortion() ) +/*N*/ ((SwFldPortion*)pPor)->CheckScript( rInf ); +/*N*/ +/*N*/ if( ! bHasGrid && rInf.HasScriptSpace() && +/*N*/ rInf.GetLast() && rInf.GetLast()->InTxtGrp() && +/*N*/ rInf.GetLast()->Width() && !rInf.GetLast()->InNumberGrp() ) +/*N*/ { +/*N*/ BYTE nNxtActual = rInf.GetFont()->GetActual(); +/*N*/ BYTE nLstActual = nNxtActual; +/*N*/ USHORT nLstHeight = (USHORT)rInf.GetFont()->GetHeight(); +/*N*/ sal_Bool bAllowBefore = sal_False; +/*N*/ sal_Bool bAllowBehind = sal_False; +/*N*/ const CharClass& rCC = GetAppCharClass(); +/*N*/ +/*N*/ // are there any punctuation characters on both sides +/*N*/ // of the kerning portion? +/*N*/ if ( pPor->InFldGrp() ) +/*N*/ { +/*N*/ XubString aAltTxt; +/*N*/ if ( ((SwFldPortion*)pPor)->GetExpTxt( rInf, aAltTxt ) && +/*N*/ aAltTxt.Len() ) +/*N*/ { +/*N*/ bAllowBehind = rCC.isLetterNumeric( aAltTxt, 0 ); +/*N*/ +/*N*/ const SwFont* pTmpFnt = ((SwFldPortion*)pPor)->GetFont(); +/*N*/ if ( pTmpFnt ) +/*N*/ nNxtActual = pTmpFnt->GetActual(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ bAllowBehind = rCC.isLetterNumeric( rInf.GetTxt(), rInf.GetIdx() ); +/*N*/ +/*N*/ const SwLinePortion* pLast = rInf.GetLast(); +/*N*/ if ( bAllowBehind && pLast ) +/*N*/ { +/*N*/ if ( pLast->InFldGrp() ) +/*N*/ { +/*N*/ XubString aAltTxt; +/*N*/ if ( ((SwFldPortion*)pLast)->GetExpTxt( rInf, aAltTxt ) && +/*N*/ aAltTxt.Len() ) +/*N*/ { +/*N*/ bAllowBefore = rCC.isLetterNumeric( aAltTxt, aAltTxt.Len() - 1 ); +/*N*/ +/*N*/ const SwFont* pTmpFnt = ((SwFldPortion*)pLast)->GetFont(); +/*N*/ if ( pTmpFnt ) +/*N*/ { +/*?*/ nLstActual = pTmpFnt->GetActual(); +/*?*/ nLstHeight = (USHORT)pTmpFnt->GetHeight(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( rInf.GetIdx() ) +/*N*/ { +/*N*/ bAllowBefore = rCC.isLetterNumeric( rInf.GetTxt(), rInf.GetIdx() - 1 ); +/*N*/ // Note: ScriptType returns values in [1,4] +/*N*/ if ( bAllowBefore ) +/*N*/ nLstActual = pScriptInfo->ScriptType( rInf.GetIdx() - 1 ) - 1; +/*N*/ } +/*N*/ +/*N*/ nLstHeight /= 5; +/*N*/ // does the kerning portion still fit into the line? +/*N*/ if( bAllowBefore && ( nLstActual != nNxtActual ) && +/*N*/ nLstHeight && rInf.X() + nLstHeight <= rInf.Width() ) +/*N*/ { +/*?*/ SwKernPortion* pKrn = +/*?*/ new SwKernPortion( *rInf.GetLast(), nLstHeight, +/*?*/ pLast->InFldGrp() && pPor->InFldGrp() ); +/*?*/ rInf.GetLast()->SetPortion( NULL ); +/*?*/ InsertPortion( rInf, pKrn ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if ( bHasGrid && ! pGridKernPortion && ! pMulti ) +/*N*/ { +/*?*/ // insert a grid kerning portion +/*?*/ if ( ! pGridKernPortion ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pGridKernPortion = pPor->IsKernPortion() ? +/*?*/ +/*?*/ // if we have a new GridKernPortion, we initially calculate +/*?*/ // its size so that its ends on the grid +/*?*/ const SwPageFrm* pPageFrm = pFrm->FindPageFrm(); +/*?*/ const SwLayoutFrm* pBody = pPageFrm->FindBodyCont(); +/*?*/ SWRECTFN( pPageFrm ) +/*?*/ +/*?*/ const long nGridOrigin = pBody ? +/*?*/ (pBody->*fnRect->fnGetPrtLeft)() : +/*?*/ (pPageFrm->*fnRect->fnGetPrtLeft)(); +/*?*/ +/*?*/ SwTwips nStartX = rInf.X() + GetLeftMargin(); +/*?*/ if ( bVert ) +/*?*/ { + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ Point aPoint( nStartX, 0 ); +/*?*/ } +/*?*/ +/*?*/ const SwTwips nOfst = nStartX - nGridOrigin; +/*?*/ if ( nOfst ) +/*?*/ { +/*?*/ const ULONG i = ( nOfst > 0 ) ? +/*?*/ ( ( nOfst - 1 ) / nGridWidth + 1 ) : +/*?*/ 0; +/*?*/ const SwTwips nKernWidth = i * nGridWidth - nOfst; +/*?*/ const SwTwips nRestWidth = rInf.Width() - rInf.X(); +/*?*/ +/*?*/ if ( nKernWidth <= nRestWidth ) +/*?*/ pGridKernPortion->Width( (USHORT)nKernWidth ); +/*?*/ } +/*?*/ +/*?*/ if ( pGridKernPortion != pPor ) +/*?*/ InsertPortion( rInf, pGridKernPortion ); +/*N*/ } +/*N*/ +/*N*/ // the multi-portion has it's own format function +/*N*/ if( pPor->IsMultiPortion() && ( !pMulti || pMulti->IsBidi() ) ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ bFull = BuildMultiPortion( rInf, *((SwMultiPortion*)pPor) ); +/*N*/ else +/*N*/ bFull = pPor->Format( rInf ); +/*N*/ +/*N*/ if( rInf.IsRuby() && !rInf.GetRest() ) +/*N*/ bFull = sal_True; +/*N*/ +/*N*/ // if we are underlined, we store the beginning of this underlined +/*N*/ // segment for repaint optimization +/*N*/ if ( UNDERLINE_NONE != pFnt->GetUnderline() && ! nUnderLineStart ) +/*N*/ nUnderLineStart = GetLeftMargin() + rInf.X(); +/*N*/ +/*N*/ if ( pPor->IsFlyPortion() ) +/*N*/ pCurr->SetFly( sal_True ); +/*N*/ // some special cases, where we have to take care for the repaint +/*N*/ // offset: +/*N*/ // 1. Underlined portions due to special underline feature +/*N*/ // 2. Right Tab +/*N*/ // 3. BidiPortions +/*N*/ // 4. other Multiportions +/*N*/ // 5. DropCaps +/*N*/ // 6. Grid Mode +/*N*/ else if ( ( ! rInf.GetPaintOfst() || nUnderLineStart < rInf.GetPaintOfst() ) && +/*N*/ // 1. Underlined portions +/*N*/ nUnderLineStart && +/*N*/ // reformat is at end of an underlined portion and next portion +/*N*/ // is not underlined +/*N*/ ( ( rInf.GetReformatStart() == rInf.GetIdx() && +/*N*/ UNDERLINE_NONE == pFnt->GetUnderline() +/*N*/ ) || +/*N*/ // reformat is inside portion and portion is underlined +/*N*/ ( rInf.GetReformatStart() >= rInf.GetIdx() && +/*N*/ rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() && +/*N*/ UNDERLINE_NONE != pFnt->GetUnderline() ) ) ) +/*N*/ rInf.SetPaintOfst( nUnderLineStart ); +/*N*/ else if ( ! rInf.GetPaintOfst() && +/*N*/ // 2. Right Tab +/*N*/ ( ( pPor->InTabGrp() && !pPor->IsTabLeftPortion() ) || +/*N*/ // 3. BidiPortions +/*N*/ ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsBidi() ) || +/*N*/ // 4. Multi Portion and 5. Drop Caps +/*N*/ ( ( pPor->IsDropPortion() || pPor->IsMultiPortion() ) && +/*N*/ rInf.GetReformatStart() >= rInf.GetIdx() && +/*N*/ rInf.GetReformatStart() <= rInf.GetIdx() + pPor->GetLen() ) +/*N*/ // 6. Grid Mode +/*N*/ || ( bHasGrid && SW_CJK != pFnt->GetActual() ) +/*N*/ ) +/*N*/ ) +/*N*/ // we store the beginning of the critical portion as our +/*N*/ // paint offset +/*N*/ rInf.SetPaintOfst( GetLeftMargin() + rInf.X() ); +/*N*/ +/*N*/ // under one of these conditions we are allowed to delete the +/*N*/ // start of the underline portion +/*N*/ if ( IsUnderlineBreak( *pPor, *pFnt ) ) +/*N*/ nUnderLineStart = 0; +/*N*/ +/*N*/ if( pPor->IsFlyCntPortion() || ( pPor->IsMultiPortion() && +/*N*/ ((SwMultiPortion*)pPor)->HasFlyInCntnt() ) ) +/*N*/ SetFlyInCntBase(); +/*N*/ // 5964: bUnderFlow muss zurueckgesetzt werden, sonst wird beim +/*N*/ // naechsten Softhyphen wieder umgebrochen! +/*N*/ if ( !bFull ) +/*N*/ { +/*N*/ rInf.ClrUnderFlow(); +/*N*/ if( ! bHasGrid && rInf.HasScriptSpace() && pPor->InTxtGrp() && +/*N*/ pPor->GetLen() && !pPor->InFldGrp() ) +/*N*/ { +/*N*/ // The distance between two different scripts is set +/*N*/ // to 20% of the fontheight. +/*N*/ xub_StrLen nTmp = rInf.GetIdx() + pPor->GetLen(); +/*N*/ if( nTmp == pScriptInfo->NextScriptChg( nTmp - 1 ) && +/*N*/ nTmp != rInf.GetTxt().Len() ) +/*N*/ { +/*N*/ USHORT nDist = (USHORT)(rInf.GetFont()->GetHeight()/5); +/*N*/ +/*N*/ if( nDist ) +/*N*/ { +/*N*/ // we do not want a kerning portion if any end +/*N*/ // would be a punctuation character +/*N*/ const CharClass& rCC = GetAppCharClass(); +/*N*/ if ( rCC.isLetterNumeric( rInf.GetTxt(), nTmp - 1 ) && +/*N*/ rCC.isLetterNumeric( rInf.GetTxt(), nTmp ) ) +/*N*/ { +/*N*/ // does the kerning portion still fit into the line? +/*?*/ if ( rInf.X() + pPor->Width() + nDist <= rInf.Width() ) +/*?*/ new SwKernPortion( *pPor, nDist ); +/*?*/ else +/*?*/ bFull = sal_True; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bHasGrid && pPor != pGridKernPortion && ! pMulti ) +/*N*/ { +/*?*/ xub_StrLen nTmp = rInf.GetIdx() + pPor->GetLen(); +/*?*/ const SwTwips nRestWidth = rInf.Width() - rInf.X() - pPor->Width(); +/*?*/ +/*?*/ const BYTE nCurrScript = pFnt->GetActual(); // pScriptInfo->ScriptType( rInf.GetIdx() ); +/*?*/ const BYTE nNextScript = nTmp >= rInf.GetTxt().Len() ? +/*?*/ SW_CJK : +/*?*/ WhichFont( nTmp, 0, pScriptInfo ); +/*?*/ +/*?*/ // snap non-asian text to grid if next portion is ASIAN or +/*?*/ // there are no more portions in this line +/*?*/ // be careful when handling an underflow event: the gridkernportion +/*?*/ // could have been deleted +/*?*/ if ( nRestWidth > 0 && SW_CJK != nCurrScript && +/*?*/ ! rInf.IsUnderFlow() && ( bFull || SW_CJK == nNextScript ) ) +/*?*/ { +/*?*/ ASSERT( pGridKernPortion, "No GridKernPortion available" ) +/*?*/ +/*?*/ // calculate size +/*?*/ SwLinePortion* pTmpPor = pGridKernPortion->GetPortion(); +/*?*/ USHORT nSumWidth = pPor->Width(); +/*?*/ while ( pTmpPor ) +/*?*/ { +/*?*/ nSumWidth += pTmpPor->Width(); +/*?*/ pTmpPor = pTmpPor->GetPortion(); +/*?*/ } +/*?*/ +/*?*/ const USHORT i = nSumWidth ? +/*?*/ ( nSumWidth - 1 ) / nGridWidth + 1 : +/*?*/ 0; +/*?*/ const SwTwips nTmpWidth = i * nGridWidth; +/*?*/ const SwTwips nKernWidth = Min( (SwTwips)(nTmpWidth - nSumWidth), +/*?*/ nRestWidth ); +/*?*/ const USHORT nKernWidth_1 = (USHORT)(nKernWidth / 2); +/*?*/ +/*?*/ ASSERT( nKernWidth <= nRestWidth, +/*?*/ "Not enough space left for adjusting non-asian text in grid mode" ) +/*?*/ +/*?*/ pGridKernPortion->Width( pGridKernPortion->Width() + nKernWidth_1 ); +/*?*/ rInf.X( rInf.X() + nKernWidth_1 ); +/*?*/ +/*?*/ if ( ! bFull ) +/*?*/ new SwKernPortion( *pPor, (short)(nKernWidth - nKernWidth_1), +/*?*/ sal_False, sal_True ); +/*?*/ +/*?*/ pGridKernPortion = 0; +/*?*/ } +/*?*/ else if ( pPor->IsMultiPortion() || pPor->InFixMargGrp() || +/*?*/ pPor->IsFlyCntPortion() || pPor->InNumberGrp() || +/*?*/ pPor->InFldGrp() || nCurrScript != nNextScript ) +/*?*/ // next portion should snap to grid +/*?*/ pGridKernPortion = 0; +/*N*/ } +/*N*/ +/*N*/ rInf.SetFull( bFull ); +/*N*/ +/*N*/ // Restportions von mehrzeiligen Feldern haben bisher noch +/*N*/ // nicht den richtigen Ascent. +/*N*/ if ( !pPor->GetLen() && !pPor->IsFlyPortion() +/*N*/ && !pPor->IsGrfNumPortion() && ! pPor->InNumberGrp() +/*N*/ && !pPor->IsMultiPortion() ) +/*N*/ CalcAscent( rInf, pPor ); +/*N*/ +/*N*/ InsertPortion( rInf, pPor ); +/*N*/ pPor = NewPortion( rInf ); +/*N*/ } +/*N*/ +/*N*/ if( !rInf.IsStop() ) +/*N*/ { +/*N*/ // der letzte rechte, zentrierte, dezimale Tab +/*N*/ SwTabPortion *pLastTab = rInf.GetLastTab(); +/*N*/ if( pLastTab ) +/*N*/ pLastTab->FormatEOL( rInf ); +/*N*/ else if( rInf.GetLast() && rInf.LastKernPortion() ) +/*N*/ rInf.GetLast()->FormatEOL( rInf ); +/*N*/ } +/*N*/ if( pCurr->GetPortion() && pCurr->GetPortion()->InNumberGrp() +/*N*/ && ((SwNumberPortion*)pCurr->GetPortion())->IsHide() ) +/*?*/ rInf.SetNumDone( sal_False ); +/*N*/ +/*N*/ // 3260, 3860: Fly auf jeden Fall loeschen! +/*N*/ ClearFly( rInf ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcAdjustLine() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::CalcAdjustLine( SwLineLayout *pCurr ) +/*N*/ { +/*N*/ if( SVX_ADJUST_LEFT != GetAdjust() && !pMulti) +/*N*/ { +/*N*/ pCurr->SetFormatAdj(sal_True); +/*N*/ if( IsFlyInCntBase() ) +/*N*/ { +/*N*/ CalcAdjLine( pCurr ); +/*N*/ // 23348: z.B. bei zentrierten Flys muessen wir den RefPoint +/*N*/ // auf jeden Fall umsetzen, deshalb bAllWays = sal_True +/*N*/ UpdatePos( pCurr, GetTopLeft(), GetStart(), sal_True ); +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcAscent() + *************************************************************************/ + +/*M*/ void SwTxtFormatter::CalcAscent( SwTxtFormatInfo &rInf, SwLinePortion *pPor ) +/*M*/ { +/*M*/ if ( pPor->InFldGrp() && ((SwFldPortion*)pPor)->GetFont() ) +/*M*/ { +/*M*/ // Numerierungen + InterNetFlds koennen einen eigenen Font beinhalten, +/*M*/ // dann ist ihre Groesse unabhaengig von harten Attributierungen. +/*M*/ SwFont* pFldFnt = ((SwFldPortion*)pPor)->pFnt; +/*M*/ SwFontSave aSave( rInf, pFldFnt ); +/*M*/ ((SwFldPortion*)pPor)->Height( pFldFnt->GetHeight( rInf.GetVsh(), rInf.GetOut() ) ); +/*M*/ ((SwFldPortion*)pPor)->SetAscent( pFldFnt->GetAscent( rInf.GetVsh(), rInf.GetOut() ) ); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ const SwLinePortion *pLast = rInf.GetLast(); +/*M*/ sal_Bool bChg; +/*M*/ +/*M*/ // Fallunterscheidung: in leeren Zeilen werden die Attribute +/*M*/ // per SeekStart angeschaltet. +/*M*/ const sal_Bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx(); +/*M*/ if ( pPor->IsQuoVadisPortion() ) +/*M*/ bChg = SeekStartAndChg( rInf, sal_True ); +/*M*/ else +/*M*/ { +/*M*/ if( bFirstPor ) +/*M*/ { +/*M*/ if( rInf.GetTxt().Len() ) +/*M*/ { +/*M*/ if ( pPor->GetLen() || !rInf.GetIdx() +/*M*/ || ( pCurr != pLast && !pLast->IsFlyPortion() ) +/*M*/ || !pCurr->IsRest() ) // statt !rInf.GetRest() +/*M*/ bChg = SeekAndChg( rInf ); +/*M*/ else +/*M*/ bChg = SeekAndChgBefore( rInf ); +/*M*/ } +/*M*/ else if ( pMulti ) +/*M*/ // do not open attributes starting at 0 in empty multi +/*M*/ // portions (rotated numbering followed by a footnote +/*M*/ // can cause trouble, because the footnote attribute +/*M*/ // starts at 0, but if we open it, the attribute handler +/*M*/ // cannot handle it. +/*M*/ bChg = sal_False; +/*M*/ else +/*M*/ bChg = SeekStartAndChg( rInf ); +/*M*/ } +/*M*/ else +/*M*/ bChg = SeekAndChg( rInf ); +/*M*/ } +/*M*/ if( bChg || bFirstPor || !pPor->GetAscent() +/*M*/ || !rInf.GetLast()->InTxtGrp() ) +/*M*/ { +/*M*/ pPor->SetAscent( rInf.GetAscent() ); +/*M*/ pPor->Height( rInf.GetTxtHeight() ); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ pPor->Height( pLast->Height() ); +/*M*/ pPor->SetAscent( pLast->GetAscent() ); +/*M*/ } +/*M*/ } +/*M*/ } + +/************************************************************************* + * SwTxtFormatter::WhichTxtPor() + *************************************************************************/ + +/*N*/ SwTxtPortion *SwTxtFormatter::WhichTxtPor( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ SwTxtPortion *pPor = 0; +/*N*/ if( GetFnt()->IsTox() ) +/*N*/ pPor = new SwToxPortion; +/*N*/ else +/*N*/ { +/*N*/ if( GetFnt()->IsRef() ) +/*N*/ pPor = new SwRefPortion; +/*N*/ else +/*N*/ { +/*N*/ // Erst zum Schluss ! +/*N*/ // Wenn pCurr keine Breite hat, kann sie trotzdem schon Inhalt haben, +/*N*/ // z.B. bei nicht darstellbaren Zeichen. +/*N*/ if( !rInf.X() && !pCurr->GetPortion() && !pCurr->GetLen() && +/*N*/ !GetFnt()->IsURL() ) +/*N*/ pPor = pCurr; +/*N*/ else +/*N*/ { +/*N*/ pPor = new SwTxtPortion; +/*N*/ if( GetFnt()->IsURL() ) +/*?*/ pPor->SetWhichPor( POR_URL ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pPor; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewTxtPortion() + *************************************************************************/ +// Die Laenge wird ermittelt, folgende Portion-Grenzen sind definiert: +// 1) Tabs +// 2) Linebreaks +// 3) CH_TXTATR_BREAKWORD / CH_TXTATR_INWORD +// 4) naechster Attributwechsel + +/*N*/ SwTxtPortion *SwTxtFormatter::NewTxtPortion( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ // Wenn wir am Zeilenbeginn stehen, nehmen wir pCurr +/*N*/ // Wenn pCurr nicht von SwTxtPortion abgeleitet ist, +/*N*/ // muessen wir duplizieren ... +/*N*/ Seek( rInf.GetIdx() ); +/*N*/ SwTxtPortion *pPor = WhichTxtPor( rInf ); +/*N*/ +/*N*/ // maximal bis zum naechsten Attributwchsel. +/*N*/ xub_StrLen nNextAttr = GetNextAttr(); +/*N*/ xub_StrLen nNextChg = Min( nNextAttr, rInf.GetTxt().Len() ); +/*N*/ +/*N*/ nNextAttr = pScriptInfo->NextScriptChg( rInf.GetIdx() ); +/*N*/ +/*N*/ xub_StrLen nNextDir = pScriptInfo->NextDirChg( rInf.GetIdx() ); +/*N*/ nNextAttr = Min( nNextAttr, nNextDir ); +/*N*/ +/*N*/ if( nNextChg > nNextAttr ) +/*N*/ nNextChg = nNextAttr; +/*N*/ +/*N*/ // 7515, 7516, 3470, 6441 : Turbo-Boost +/*N*/ // Es wird unterstellt, dass die Buchstaben eines Fonts nicht +/*N*/ // groesser als doppelt so breit wie hoch sind. +/*N*/ // 7659: Ganz verrueckt: man muss sich auf den Ascent beziehen. +/*N*/ // Falle: GetSize() enthaelt die Wunschhoehe, die reale Hoehe +/*N*/ // ergibt sich erst im CalcAscent! +/*N*/ // 7697: Das Verhaeltnis ist noch krasser: ein Blank im Times +/*N*/ // New Roman besitzt einen Ascent von 182, eine Hoehe von 200 +/*N*/ // und eine Breite von 53! Daraus folgt, dass eine Zeile mit +/*N*/ // vielen Blanks falsch eingeschaetzt wird. Wir erhoehen von +/*N*/ // Faktor 2 auf 8 (wg. negativen Kernings). +/*N*/ +/*N*/ pPor->SetLen(1); +/*N*/ CalcAscent( rInf, pPor ); +/*N*/ +/*N*/ const SwFont* pFnt = rInf.GetFont(); +/*N*/ KSHORT nExpect = Min( KSHORT( ((Font *)pFnt)->GetSize().Height() ), +/*N*/ KSHORT( pPor->GetAscent() ) ) / 8; +/*N*/ if ( !nExpect ) +/*N*/ nExpect = 1; +/*N*/ nExpect = (USHORT)(rInf.GetIdx() + ((rInf.Width() - rInf.X()) / nExpect)); +/*N*/ if( nExpect > rInf.GetIdx() && nNextChg > nExpect ) +/*N*/ nNextChg = Min( nExpect, rInf.GetTxt().Len() ); +/*N*/ +/*N*/ // we keep an invariant during method calls: +/*N*/ // there are no portion ending characters like hard spaces +/*N*/ // or tabs in [ nLeftScanIdx, nRightScanIdx ] +/*N*/ if ( nLeftScanIdx <= rInf.GetIdx() && rInf.GetIdx() <= nRightScanIdx ) +/*N*/ { +/*N*/ if ( nNextChg > nRightScanIdx ) +/*N*/ nNextChg = nRightScanIdx = +/*N*/ rInf.ScanPortionEnd( nRightScanIdx, nNextChg ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nLeftScanIdx = rInf.GetIdx(); +/*N*/ nNextChg = nRightScanIdx = +/*N*/ rInf.ScanPortionEnd( rInf.GetIdx(), nNextChg ); +/*N*/ } +/*N*/ +/*N*/ pPor->SetLen( nNextChg - rInf.GetIdx() ); +/*N*/ rInf.SetLen( pPor->GetLen() ); +/*N*/ return pPor; +/*N*/ } + + +/************************************************************************* + * SwTxtFormatter::WhichFirstPortion() + *************************************************************************/ + +/*M*/ SwLinePortion *SwTxtFormatter::WhichFirstPortion(SwTxtFormatInfo &rInf) +/*M*/ { +/*M*/ SwLinePortion *pPor = 0; +/*M*/ +/*M*/ if( rInf.GetRest() ) +/*M*/ { +/*M*/ // 5010: Tabs und Felder +/*M*/ if( '\0' != rInf.GetHookChar() ) +/*M*/ return 0; +/*M*/ +/*M*/ pPor = rInf.GetRest(); +/*M*/ if( pPor->IsErgoSumPortion() ) +/*M*/ rInf.SetErgoDone(sal_True); +/*M*/ else +/*M*/ if( pPor->IsFtnNumPortion() ) +/*M*/ rInf.SetFtnDone(sal_True); +/*M*/ else +/*M*/ if( pPor->InNumberGrp() ) +/*M*/ rInf.SetNumDone(sal_True); +/*M*/ if( pPor ) +/*M*/ { +/*M*/ rInf.SetRest(0); +/*M*/ pCurr->SetRest( sal_True ); +/*M*/ return pPor; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // ???? und ????: im Follow duerfen wir schon stehen, +/*M*/ // entscheidend ist, ob pFrm->GetOfst() == 0 ist! +/*M*/ if( rInf.GetIdx() ) +/*M*/ { +/*M*/ // Nun koennen auch FtnPortions und ErgoSumPortions +/*M*/ // verlaengert werden. +/*M*/ +/*M*/ // 1) Die ErgoSumTexte +/*M*/ if( !rInf.IsErgoDone() ) +/*M*/ { +/*M*/ if( pFrm->IsInFtn() && !pFrm->GetIndPrev() ) +/*M*/ pPor = (SwLinePortion*)NewErgoSumPortion( rInf ); +/*M*/ rInf.SetErgoDone( sal_True ); +/*M*/ } +/*M*/ if( !pPor && !rInf.IsArrowDone() ) +/*M*/ { +/*M*/ if( pFrm->GetOfst() && !pFrm->IsFollow() && +/*M*/ rInf.GetIdx() == pFrm->GetOfst() ) +/*M*/ pPor = new SwArrowPortion( *pCurr ); +/*M*/ rInf.SetArrowDone( sal_True ); +/*M*/ } +/*M*/ +/*M*/ if ( ! pPor && ! pCurr->GetPortion() ) +/*M*/ { +/*M*/ GETGRID( GetTxtFrm()->FindPageFrm() ) +/*M*/ if ( pGrid ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 pPor = new SwKernPortion( *pCurr ); +/*M*/ } +/*M*/ +/*M*/ // 2) Die Zeilenreste (mehrzeilige Felder) +/*M*/ if( !pPor ) +/*M*/ { +/*M*/ pPor = rInf.GetRest(); +/*M*/ // 6922: Nur bei pPor natuerlich. +/*M*/ if( pPor ) +/*M*/ { +/*M*/ pCurr->SetRest( sal_True ); +/*M*/ rInf.SetRest(0); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ // 1) Die Fussnotenzahlen +/*M*/ if( !rInf.IsFtnDone() ) +/*M*/ { +/*M*/ ASSERT( ( ! rInf.IsMulti() && ! pMulti ) || pMulti->HasRotation(), +/*M*/ "Rotated number portion trouble" ) +/*M*/ +/*M*/ sal_Bool bFtnNum = pFrm->IsFtnNumFrm(); +/*M*/ rInf.GetParaPortion()->SetFtnNum( bFtnNum ); +/*M*/ if( bFtnNum ) +/*M*/ pPor = (SwLinePortion*)NewFtnNumPortion( rInf ); +/*M*/ rInf.SetFtnDone( sal_True ); +/*M*/ } +/*M*/ +/*M*/ // 2) Die ErgoSumTexte gibt es natuerlich auch im TextMaster, +/*M*/ // entscheidend ist, ob der SwFtnFrm ein Follow ist. +/*M*/ if( !rInf.IsErgoDone() && !pPor && ! rInf.IsMulti() ) +/*M*/ { +/*M*/ if( pFrm->IsInFtn() && !pFrm->GetIndPrev() ) +/*M*/ pPor = (SwLinePortion*)NewErgoSumPortion( rInf ); +/*M*/ rInf.SetErgoDone( sal_True ); +/*M*/ } +/*M*/ +/*M*/ // 3) Die Numerierungen +/*M*/ if( !rInf.IsNumDone() && !pPor ) +/*M*/ { +/*M*/ ASSERT( ( ! rInf.IsMulti() && ! pMulti ) || pMulti->HasRotation(), +/*M*/ "Rotated number portion trouble" ) +/*M*/ +/*M*/ // Wenn wir im Follow stehen, dann natuerlich nicht. +/*M*/ if( GetTxtFrm()->GetTxtNode()->GetNum() || +/*M*/ GetTxtFrm()->GetTxtNode()->GetOutlineNum() ) +/*M*/ pPor = (SwLinePortion*)NewNumberPortion( rInf ); +/*M*/ rInf.SetNumDone( sal_True ); +/*M*/ } +/*M*/ // 4) Die DropCaps +/*M*/ if( !pPor && GetDropFmt() && ! rInf.IsMulti() ) +/*M*/ pPor = (SwLinePortion*)NewDropPortion( rInf ); +/*M*/ +/*M*/ if ( ! pPor && ! pCurr->GetPortion() ) +/*M*/ { +/*M*/ GETGRID( GetTxtFrm()->FindPageFrm() ) +/*M*/ if ( pGrid ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 pPor = new SwKernPortion( *pCurr ); +/*M*/ } +/*M*/ } +/*M*/ return pPor; +/*M*/ } + +/*N*/ sal_Bool lcl_OldFieldRest( const SwLineLayout* pCurr ) +/*N*/ { +/*N*/ if( !pCurr->GetNext() ) +/*N*/ return sal_False; +/*N*/ const SwLinePortion *pPor = pCurr->GetNext()->GetPortion(); +/*N*/ sal_Bool bRet = sal_False; +/*N*/ while( pPor && !bRet ) +/*N*/ { +/*N*/ bRet = (pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()) || +/*N*/ (pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsFollowFld()); +/*N*/ if( !pPor->GetLen() ) +/*N*/ break; +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewPortion() + *************************************************************************/ + +/* NewPortion stellt rInf.nLen ein. + * Eine SwTxtPortion wird begrenzt durch ein tab, break, txtatr, + * attrwechsel. + * Drei Faelle koennen eintreten: + * 1) Die Zeile ist voll und der Umbruch wurde nicht emuliert + * -> return 0; + * 2) Die Zeile ist voll und es wurde ein Umbruch emuliert + * -> Breite neu einstellen und return new FlyPortion + * 3) Es muss eine neue Portion gebaut werden. + * -> CalcFlyWidth emuliert ggf. die Breite und return Portion + */ + +/*M*/ SwLinePortion *SwTxtFormatter::NewPortion( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ // Underflow hat Vorrang +/*M*/ rInf.SetStopUnderFlow( sal_False ); +/*M*/ if( rInf.GetUnderFlow() ) +/*M*/ { +/*M*/ ASSERT( rInf.IsFull(), "SwTxtFormatter::NewPortion: underflow but not full" ); +/*M*/ return UnderFlow( rInf ); +/*M*/ } +/*M*/ +/*M*/ // Wenn die Zeile voll ist, koennten noch Flys oder +/*M*/ // UnderFlow-LinePortions warten ... +/*M*/ if( rInf.IsFull() ) +/*M*/ { +/*M*/ // ????: LineBreaks und Flys (bug05.sdw) +/*M*/ // 8450: IsDummy() +/*M*/ if( rInf.IsNewLine() && (!rInf.GetFly() || !pCurr->IsDummy()) ) +/*M*/ return 0; +/*M*/ +/*M*/ // Wenn der Text an den Fly gestossen ist, oder wenn +/*M*/ // der Fly als erstes drankommt, weil er ueber dem linken +/*M*/ // Rand haengt, wird GetFly() returnt. +/*M*/ // Wenn IsFull() und kein GetFly() vorhanden ist, gibt's +/*M*/ // naturgemaesz eine 0. +/*M*/ if( rInf.GetFly() ) +/*M*/ { +/*M*/ if( rInf.GetLast()->IsBreakPortion() ) +/*M*/ { +/*M*/ delete rInf.GetFly(); +/*M*/ rInf.SetFly( 0 ); +/*M*/ } +/*M*/ +/*M*/ return rInf.GetFly(); +/*M*/ } +/*M*/ // Ein fieser Sonderfall: ein Rahmen ohne Umlauf kreuzt den +/*M*/ // Ftn-Bereich. Wir muessen die Ftn-Portion als Zeilenrest +/*M*/ // bekanntgeben, damit SwTxtFrm::Format nicht abbricht +/*M*/ // (die Textmasse wurde ja durchformatiert). +/*M*/ if( rInf.GetRest() ) +/*M*/ rInf.SetNewLine( sal_True ); +/*M*/ else +/*M*/ { +/*M*/ // Wenn die naechste Zeile mit einem Rest eines Feldes beginnt, +/*M*/ // jetzt aber kein Rest mehr anliegt, +/*M*/ // muss sie auf jeden Fall neu formatiert werden! +/*M*/ if( lcl_OldFieldRest( GetCurr() ) ) +/*M*/ rInf.SetNewLine( sal_True ); +/*M*/ else +/*M*/ { +/*M*/ SwLinePortion *pFirst = WhichFirstPortion( rInf ); +/*M*/ if( pFirst ) +/*M*/ { +/*M*/ rInf.SetNewLine( sal_True ); +/*M*/ if( pFirst->InNumberGrp() ) +/*M*/ rInf.SetNumDone( sal_False) ; +/*M*/ delete pFirst; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ return 0; +/*M*/ } +/*M*/ +/*M*/ SwLinePortion *pPor = WhichFirstPortion( rInf ); +/*M*/ +/*M*/ if( !pPor ) +/*M*/ { +/*M*/ if( !pMulti || pMulti->IsBidi() ) +/*M*/ { // We open a multiportion part, if we enter a multi-line part +/*M*/ // of the paragraph. +/*M*/ xub_StrLen nEnd = rInf.GetIdx(); +/*M*/ SwMultiCreator* pCreate = rInf.GetMultiCreator( nEnd, pMulti ); +/*M*/ if( pCreate ) +/*M*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*M*/ } +/*M*/ } +/*M*/ // 5010: Tabs und Felder +/*M*/ xub_Unicode cChar = rInf.GetHookChar(); +/*M*/ +/*M*/ if( cChar ) +/*M*/ { + /* Wir holen uns nocheinmal cChar, um sicherzustellen, dass das + * Tab jetzt wirklich ansteht und nicht auf die naechste Zeile + * gewandert ist ( so geschehen hinter Rahmen ). + * Wenn allerdings eine FldPortion im Rest wartet, muessen wir + * das cChar natuerlich aus dem Feldinhalt holen, z.B. bei + * DezimalTabs und Feldern (22615) + */ +/*M*/ if( !rInf.GetRest() || !rInf.GetRest()->InFldGrp() ) +/*M*/ cChar = rInf.GetChar( rInf.GetIdx() ); +/*M*/ rInf.SetHookChar(0); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ if( rInf.GetIdx() >= rInf.GetTxt().Len() ) +/*M*/ { +/*M*/ rInf.SetFull(sal_True); +/*M*/ CalcFlyWidth( rInf ); +/*M*/ return pPor; +/*M*/ } +/*M*/ cChar = rInf.GetChar( rInf.GetIdx() ); +/*M*/ } +/*M*/ +/*M*/ switch( cChar ) +/*M*/ { +/*M*/ case CH_TAB : pPor = NewTabPortion( rInf ); break; +/*M*/ case CH_BREAK : pPor = new SwBreakPortion( *rInf.GetLast() ); break; +/*M*/ +/*M*/ case CHAR_SOFTHYPHEN: // soft hyphen +/*M*/ pPor = new SwSoftHyphPortion; break; +/*M*/ +/*M*/ case CHAR_HARDBLANK: // no-break space +/*M*/ pPor = new SwBlankPortion( ' ' ); break; +/*M*/ case CHAR_HARDHYPHEN: // non-breaking hyphen +/*M*/ pPor = new SwBlankPortion( '-' ); break; +/*M*/ +/*M*/ case CH_TXTATR_BREAKWORD: +/*M*/ case CH_TXTATR_INWORD: +/*M*/ if( rInf.HasHint( rInf.GetIdx() ) ) +/*M*/ { +/*M*/ pPor = NewExtraPortion( rInf ); +/*M*/ break; +/*M*/ } +/*M*/ // No break +/*M*/ default : +/*M*/ { +/*M*/ if( rInf.GetLastTab() && cChar == rInf.GetTabDecimal() ) +/*M*/ rInf.SetFull( rInf.GetLastTab()->Format( rInf ) ); +/*M*/ +/*M*/ if( rInf.GetRest() ) +/*M*/ { +/*M*/ if( rInf.IsFull() ) +/*M*/ { +/*M*/ rInf.SetNewLine(sal_True); +/*M*/ return 0; +/*M*/ } +/*M*/ pPor = rInf.GetRest(); +/*M*/ rInf.SetRest(0); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ if( rInf.IsFull() ) +/*M*/ return 0; +/*M*/ pPor = NewTxtPortion( rInf ); +/*M*/ } +/*M*/ break; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // Wenn eine Portion erzeugt wird, obwohl eine RestPortion ansteht, +/*M*/ // dann haben wir es mit einem Feld zu tun, das sich aufgesplittet +/*M*/ // hat, weil z.B. ein Tab enthalten ist. +/*M*/ if( pPor && rInf.GetRest() ) +/*M*/ pPor->SetLen( 0 ); +/*M*/ +/*M*/ // robust: +/*M*/ if( !pPor || rInf.IsStop() ) +/*M*/ { +/*M*/ delete pPor; +/*M*/ return 0; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // Special portions containing numbers (footnote anchor, footnote number, +/*M*/ // numbering) can be contained in a rotated portion, if the user +/*M*/ // choose a rotated character attribute. +/*M*/ if ( pPor && ! pMulti ) +/*M*/ { +/*M*/ if ( pPor->IsFtnPortion() ) +/*M*/ { +/*M*/ const SwTxtFtn* pTxtFtn = ((SwFtnPortion*)pPor)->GetTxtFtn(); +/*M*/ +/*M*/ if ( pTxtFtn ) +/*M*/ { +/*M*/ SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn(); +/*M*/ const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc(); +/*M*/ const SwEndNoteInfo* pInfo; +/*M*/ if( rFtn.IsEndNote() ) +/*M*/ pInfo = &pDoc->GetEndNoteInfo(); +/*M*/ else +/*M*/ pInfo = &pDoc->GetFtnInfo(); +/*M*/ const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet(); +/*M*/ +/*M*/ const SfxPoolItem* pItem; +/*M*/ USHORT nDir = 0; +/*M*/ if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ROTATE, +/*M*/ sal_True, &pItem )) +/*M*/ nDir = ((SvxCharRotateItem*)pItem)->GetValue(); +/*M*/ +/*M*/ if ( 0 != nDir ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 delete pPor; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ else if ( pPor->InNumberGrp() ) +/*M*/ { +/*M*/ const SwFont* pNumFnt = ((SwFldPortion*)pPor)->GetFont(); +/*M*/ +/*M*/ if ( pNumFnt ) +/*M*/ { +/*N*/ USHORT nDir = pNumFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() ); +/*M*/ if ( 0 != nDir ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 delete pPor; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // Der Font wird im Outputdevice eingestellt, +/*M*/ // der Ascent und die Hoehe werden berechnet. +/*M*/ if( !pPor->GetAscent() && !pPor->Height() ) +/*M*/ CalcAscent( rInf, pPor ); +/*M*/ rInf.SetLen( pPor->GetLen() ); +/*M*/ +/*M*/ // In CalcFlyWidth wird Width() verkuerzt, wenn eine FlyPortion vorliegt. +/*M*/ CalcFlyWidth( rInf ); +/*M*/ +/*M*/ // Man darf nicht vergessen, dass pCurr als GetLast() vernuenftige +/*M*/ // Werte bereithalten muss: +/*M*/ if( !pCurr->Height() ) +/*M*/ { +/*M*/ ASSERT( pCurr->Height(), "SwTxtFormatter::NewPortion: limbo dance" ); +/*M*/ pCurr->Height( pPor->Height() ); +/*M*/ pCurr->SetAscent( pPor->GetAscent() ); +/*M*/ } +/*M*/ +/*M*/ ASSERT( !pPor || pPor->Height(), +/*M*/ "SwTxtFormatter::NewPortion: something went wrong"); +/*M*/ if( pPor->IsPostItsPortion() && rInf.X() >= rInf.Width() && rInf.GetFly() ) +/*M*/ { +/*M*/ delete pPor; +/*M*/ pPor = rInf.GetFly(); +/*M*/ } +/*M*/ return pPor; +/*M*/ } + +/************************************************************************* + * SwTxtFormatter::FormatLine() + *************************************************************************/ + +/*M*/ xub_StrLen SwTxtFormatter::FormatLine( const xub_StrLen nStart ) +/*M*/ { +/*M*/ ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(), +/*M*/ "SwTxtFormatter::FormatLine( nStart ) with unswapped frame" ); +/*N*/ +/*N*/ // For the formatting routines, we set pOut to the reference device. +/*N*/ SwHookOut aHook( GetInfo() ); +/*M*/ if( GetInfo().GetLen() < GetInfo().GetTxt().Len() ) +/*M*/ GetInfo().SetLen( GetInfo().GetTxt().Len() ); +/*M*/ +/*M*/ sal_Bool bBuild = sal_True; +/*M*/ SetFlyInCntBase( sal_False ); +/*M*/ GetInfo().SetLineHeight( 0 ); +/*M*/ GetInfo().SetLineNettoHeight( 0 ); +/*M*/ +/*M*/ // Recycling muss bei geaenderter Zeilenhoehe unterdrueckt werden +/*M*/ // und auch bei geaendertem Ascent (Absenken der Grundlinie). +/*M*/ const KSHORT nOldHeight = pCurr->Height(); +/*M*/ const KSHORT nOldAscent = pCurr->GetAscent(); +/*M*/ +/*M*/ pCurr->SetEndHyph( sal_False ); +/*M*/ pCurr->SetMidHyph( sal_False ); +/*M*/ +/*M*/ // fly positioning can make it necessary format a line several times +/*M*/ // for this, we have to keep a copy of our rest portion +/*M*/ SwLinePortion* pFld = GetInfo().GetRest(); +/*M*/ SwFldPortion* pSaveFld = 0; +/*M*/ +/*M*/ if ( pFld && pFld->InFldGrp() && ! pFld->IsFtnPortion() ) +/*M*/ pSaveFld = new SwFldPortion( *((SwFldPortion*)pFld) ); +/*M*/ +/*M*/ // for an optimal repaint rectangle, we want to compare fly portions +/*M*/ // before and after the BuildPortions call +/*M*/ const sal_Bool bOptimizeRepaint = AllowRepaintOpt(); +/*M*/ const xub_StrLen nOldLineEnd = nStart + pCurr->GetLen(); +/*M*/ SvLongs* pFlyStart = 0; +/*M*/ +/*M*/ // these are the conditions for a fly position comparison +/*M*/ if ( bOptimizeRepaint && pCurr->IsFly() ) +/*M*/ { +/*M*/ pFlyStart = new SvLongs; +/*M*/ SwLinePortion* pPor = pCurr->GetFirstPortion(); +/*M*/ long nPOfst = 0; +/*M*/ USHORT nCnt = 0; +/*M*/ +/*M*/ while ( pPor ) +/*M*/ { +/*M*/ if ( pPor->IsFlyPortion() ) +/*M*/ // insert start value of fly portion +/*M*/ pFlyStart->Insert( nPOfst, nCnt++ ); +/*M*/ +/*M*/ nPOfst += pPor->Width(); +/*M*/ pPor = pPor->GetPortion(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // Hier folgt bald die Unterlaufpruefung. +/*M*/ while( bBuild ) +/*M*/ { +/*M*/ GetInfo().SetFtnInside( sal_False ); +/*M*/ +/*M*/ // These values must not be reset by FormatReset(); +/*M*/ sal_Bool bOldNumDone = GetInfo().IsNumDone(); +/*M*/ sal_Bool bOldArrowDone = GetInfo().IsArrowDone(); +/*M*/ sal_Bool bOldErgoDone = GetInfo().IsErgoDone(); +/*M*/ +/*M*/ // besides other things, this sets the repaint offset to 0 +/*M*/ FormatReset( GetInfo() ); +/*M*/ +/*M*/ GetInfo().SetNumDone( bOldNumDone ); +/*M*/ GetInfo().SetArrowDone( bOldArrowDone ); +/*M*/ GetInfo().SetErgoDone( bOldErgoDone ); +/*M*/ +/*M*/ // build new portions for this line +/*M*/ BuildPortions( GetInfo() ); +/*M*/ +/*M*/ if( GetInfo().IsStop() ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pCurr->SetLen( 0 ); +/*M*/ } +/*M*/ else if( GetInfo().IsDropInit() ) +/*M*/ { +/*M*/ DropInit(); +/*M*/ GetInfo().SetDropInit( sal_False ); +/*M*/ } +/*M*/ +/*M*/ pCurr->CalcLine( *this, GetInfo() ); +/*M*/ CalcRealHeight( GetInfo().IsNewLine() ); +/*M*/ +/*M*/ if ( IsFlyInCntBase() && !IsQuick() ) +/*M*/ { +/*M*/ KSHORT nTmpAscent, nTmpHeight; +/*M*/ CalcAscentAndHeight( nTmpAscent, nTmpHeight ); +/*M*/ AlignFlyInCntBase( Y() + long( nTmpAscent ) ); +/*M*/ pCurr->CalcLine( *this, GetInfo() ); +/*M*/ CalcRealHeight(); +/*M*/ } +/*M*/ +/*M*/ // bBuild entscheidet, ob noch eine Ehrenrunde gedreht wird +/*M*/ if ( pCurr->GetRealHeight() <= GetInfo().GetLineHeight() ) +/*M*/ { +/*M*/ pCurr->SetRealHeight( GetInfo().GetLineHeight() ); +/*M*/ bBuild = sal_False; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ bBuild = ( GetInfo().GetTxtFly()->IsOn() && ChkFlyUnderflow( GetInfo() ) +/*M*/ || GetInfo().CheckFtnPortion( pCurr ) ); +/*M*/ if( bBuild ) +/*M*/ { +/*M*/ GetInfo().SetNumDone( bOldNumDone ); +/*M*/ GetInfo().ResetMaxWidthDiff(); +/*M*/ +/*M*/ // delete old rest +/*M*/ if ( GetInfo().GetRest() ) +/*M*/ { +/*M*/ delete GetInfo().GetRest(); +/*M*/ GetInfo().SetRest( 0 ); +/*M*/ } +/*M*/ +/*M*/ // set original rest portion +/*M*/ if ( pSaveFld ) +/*M*/ GetInfo().SetRest( new SwFldPortion( *pSaveFld ) ); +/*M*/ +/*M*/ pCurr->SetLen( 0 ); +/*M*/ pCurr->Width(0); +/*M*/ pCurr->Truncate(); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // calculate optimal repaint rectangle +/*M*/ if ( bOptimizeRepaint ) +/*M*/ { +/*M*/ GetInfo().SetPaintOfst( CalcOptRepaint( nOldLineEnd, pFlyStart ) ); +/*M*/ if ( pFlyStart ) +/*M*/ delete pFlyStart; +/*M*/ } +/*M*/ else +/*M*/ // Special case: We do not allow an optimitation of the repaint +/*M*/ // area, but during formatting the repaint offset is set to indicate +/*M*/ // a maximum value for the offset. This value has to be reset: +/*M*/ GetInfo().SetPaintOfst( 0 ); +/*M*/ +/*M*/ // This corrects the start of the reformat range if something has +/*M*/ // moved to the next line. Otherwise IsFirstReformat in AllowRepaintOpt +/*M*/ // will give us a wrong result if we have to reformat another line +/*M*/ GetInfo().GetParaPortion()->GetReformat()->LeftMove( GetInfo().GetIdx() ); +/*M*/ +/*M*/ // delete master copy of rest portion +/*M*/ if ( pSaveFld ) +/*M*/ delete pSaveFld; +/*M*/ +/*M*/ xub_StrLen nNewStart = nStart + pCurr->GetLen(); +/*M*/ +/*M*/ // adjust text if kana compression is enabled +/*M*/ const SwScriptInfo& rSI = GetInfo().GetParaPortion()->GetScriptInfo(); +/*M*/ +/*M*/ if ( GetInfo().CompressLine() ) +/*M*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 USHORT nRepaintOfst = CalcKanaAdj( pCurr ); +/*M*/ } +/*M*/ +/*M*/ CalcAdjustLine( pCurr ); +/*M*/ +/*M*/ if( nOldHeight != pCurr->Height() || nOldAscent != pCurr->GetAscent() ) +/*M*/ { +/*M*/ SetFlyInCntBase(); +/*M*/ GetInfo().SetPaintOfst( 0 ); //geaenderte Zeilenhoehe => kein Recycling +/*M*/ // alle weiteren Zeilen muessen gepaintet und, wenn Flys im Spiel sind +/*M*/ // auch formatiert werden. +/*M*/ GetInfo().SetShift( sal_True ); +/*M*/ } +/*M*/ +/*M*/ if ( IsFlyInCntBase() && !IsQuick() ) +/*M*/ UpdatePos( pCurr, GetTopLeft(), GetStart() ); +/*M*/ +/*M*/ return nNewStart; +/*M*/ } + +/************************************************************************* + * SwTxtFormatter::RecalcRealHeight() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::RecalcRealHeight() +/*N*/ { +/*N*/ sal_Bool bMore = sal_True; +/*N*/ while(bMore) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ CalcRealHeight(); +/*N*/ bMore = Next() != 0; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcRealHeight() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::CalcRealHeight( sal_Bool bNewLine ) +/*N*/ { +/*N*/ KSHORT nLineHeight = pCurr->Height(); +/*N*/ pCurr->SetClipping( sal_False ); +/*N*/ +/*N*/ GETGRID( pFrm->FindPageFrm() ) +/*N*/ if ( pGrid && GetInfo().SnapToGrid() ) +/*N*/ { +/*?*/ const USHORT nGridWidth = pGrid->GetBaseHeight(); +/*?*/ const USHORT nRubyHeight = pGrid->GetRubyHeight(); +/*?*/ const sal_Bool bRubyTop = ! pGrid->GetRubyTextBelow(); +/*?*/ +/*?*/ USHORT nLineHeight = nGridWidth + nRubyHeight; +/*?*/ USHORT nLineDist = nLineHeight; +/*?*/ +/*?*/ while ( pCurr->Height() > nLineHeight ) +/*?*/ nLineHeight += nLineDist; +/*?*/ +/*?*/ KSHORT nAsc = pCurr->GetAscent() + +/*?*/ ( bRubyTop ? +/*?*/ ( nLineHeight - pCurr->Height() + nRubyHeight ) / 2 : +/*?*/ ( nLineHeight - pCurr->Height() - nRubyHeight ) / 2 ); +/*?*/ +/*?*/ pCurr->Height( nLineHeight ); +/*?*/ pCurr->SetAscent( nAsc ); +/*?*/ pInf->GetParaPortion()->SetFixLineHeight(); +/*?*/ +/*?*/ // we ignore any line spacing options except from ... +/*?*/ const SvxLineSpacingItem* pSpace = aLineInf.GetLineSpacing(); +/*?*/ if ( ! IsParaLine() && pSpace && +/*?*/ SVX_INTER_LINE_SPACE_PROP == pSpace->GetInterLineSpaceRule() ) +/*?*/ { +/*?*/ ULONG nTmp = pSpace->GetPropLineSpace(); +/*?*/ +/*?*/ if( nTmp < 100 ) +/*?*/ nTmp = 100; +/*?*/ +/*?*/ nTmp *= nLineHeight; +/*?*/ nLineHeight = (USHORT)(nTmp / 100); +/*?*/ } +/*?*/ +/*?*/ pCurr->SetRealHeight( nLineHeight ); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ // Das Dummyflag besitzen Zeilen, die nur Flyportions enthalten, diese +/*N*/ // sollten kein Register etc. beachten. Dummerweise hat kann es eine leere +/*N*/ // Zeile am Absatzende geben (bei leeren Abs„tzen oder nach einem +/*N*/ // Shift-Return), die das Register durchaus beachten soll. +/*N*/ if( !pCurr->IsDummy() || ( !pCurr->GetNext() && +/*N*/ GetStart() >= GetTxtFrm()->GetTxt().Len() && !bNewLine ) ) +/*N*/ { +/*N*/ const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing(); +/*N*/ if( pSpace ) +/*N*/ { +/*N*/ switch( pSpace->GetLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_LINE_SPACE_AUTO: +/*N*/ break; +/*N*/ case SVX_LINE_SPACE_MIN: +/*N*/ { +/*N*/ if( nLineHeight < KSHORT( pSpace->GetLineHeight() ) ) +/*N*/ nLineHeight = pSpace->GetLineHeight(); +/*N*/ break; +/*N*/ } +/*N*/ case SVX_LINE_SPACE_FIX: +/*N*/ { +/*?*/ nLineHeight = pSpace->GetLineHeight(); +/*?*/ KSHORT nAsc = ( 4 * nLineHeight ) / 5; // 80% +/*?*/ if( nAsc < pCurr->GetAscent() || +/*?*/ nLineHeight - nAsc < pCurr->Height() - pCurr->GetAscent() ) +/*?*/ pCurr->SetClipping( sal_True ); +/*?*/ pCurr->Height( nLineHeight ); +/*?*/ pCurr->SetAscent( nAsc ); +/*?*/ pInf->GetParaPortion()->SetFixLineHeight(); +/*?*/ } +/*?*/ break; +/*?*/ default: ASSERT( sal_False, ": unknown LineSpaceRule" ); +/*N*/ } +/*N*/ if( !IsParaLine() ) +/*N*/ switch( pSpace->GetInterLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_INTER_LINE_SPACE_OFF: +/*N*/ break; +/*N*/ case SVX_INTER_LINE_SPACE_PROP: +/*N*/ { +/*N*/ long nTmp = pSpace->GetPropLineSpace(); +/*N*/ // 50% ist das Minimum, bei 0% schalten wir auf +/*N*/ // den Defaultwert 100% um ... +/*N*/ if( nTmp < 50 ) +/*N*/ nTmp = nTmp ? 50 : 100; +/*N*/ +/*N*/ nTmp *= nLineHeight; +/*N*/ nTmp /= 100; +/*N*/ if( !nTmp ) +/*N*/ ++nTmp; +/*N*/ nLineHeight = (KSHORT)nTmp; +/*N*/ break; +/*N*/ } +/*N*/ case SVX_INTER_LINE_SPACE_FIX: +/*N*/ { +/*?*/ nLineHeight += pSpace->GetInterLineSpace(); +/*?*/ break; +/*N*/ } +/*N*/ default: ASSERT( sal_False, ": unknown InterLineSpaceRule" ); +/*N*/ } +/*N*/ } +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ KSHORT nDummy = nLineHeight + 1; +/*N*/ #endif +/*N*/ +/*N*/ if( IsRegisterOn() ) +/*N*/ { +/*N*/ SwTwips nTmpY = Y() + pCurr->GetAscent() + nLineHeight - pCurr->Height(); +/*N*/ SWRECTFN( pFrm ) +/*N*/ if ( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nTmpY = pFrm->SwitchHorizontalToVertical( nTmpY ); +/*N*/ nTmpY = (*fnRect->fnYDiff)( nTmpY, RegStart() ); +/*N*/ KSHORT nDiff = KSHORT( nTmpY % RegDiff() ); +/*N*/ if( nDiff ) +/*N*/ nLineHeight += RegDiff() - nDiff; +/*N*/ } +/*N*/ } +/*N*/ pCurr->SetRealHeight( nLineHeight ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::FeedInf() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::FeedInf( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ // 3260, 3860: Fly auf jeden Fall loeschen! +/*N*/ ClearFly( rInf ); +/*N*/ rInf.Init(); +/*N*/ +/*N*/ rInf.ChkNoHyph( CntEndHyph(), CntMidHyph() ); +/*N*/ rInf.SetRoot( pCurr ); +/*N*/ rInf.SetLineStart( nStart ); +/*N*/ rInf.SetIdx( nStart ); +/*N*/ rInf.Left( KSHORT(Left()) ); +/*N*/ rInf.Right( KSHORT(Right()) ); +/*N*/ rInf.First( short(FirstLeft()) ); +/*N*/ rInf.RealWidth( KSHORT(rInf.Right()) - KSHORT(GetLeftMargin()) ); +/*N*/ rInf.Width( rInf.RealWidth() ); +/*N*/ if( ((SwTxtFormatter*)this)->GetRedln() ) +/*N*/ { + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ((SwTxtFormatter*)this)->GetRedln()->Clear( ((SwTxtFormatter*)this)->GetFnt() ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::FormatReset() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::FormatReset( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ pCurr->Truncate(); +/*N*/ pCurr->Init(); +/*N*/ +/*N*/ // delete pSpaceAdd und pKanaComp +/*N*/ pCurr->FinishSpaceAdd(); +/*N*/ pCurr->FinishKanaComp(); +/*N*/ pCurr->ResetFlags(); +/*N*/ FeedInf( rInf ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcOnceMore() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFormatter::CalcOnceMore() +/*N*/ { +/*N*/ if( pDropFmt ) +/*N*/ { +/*N*/ const KSHORT nOldDrop = GetDropHeight(); +/*N*/ CalcDropHeight( pDropFmt->GetLines() ); +/*N*/ bOnceMore = nOldDrop != GetDropHeight(); +/*N*/ } +/*N*/ else +/*N*/ bOnceMore = sal_False; +/*N*/ return bOnceMore; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcBottomLine() + *************************************************************************/ + +/*N*/ SwTwips SwTxtFormatter::CalcBottomLine() const +/*N*/ { +/*N*/ SwTwips nRet = Y() + GetLineHeight(); +/*N*/ SwTwips nMin = GetInfo().GetTxtFly()->GetMinBottom(); +/*N*/ if( nMin && ++nMin > nRet ) +/*N*/ { +/*N*/ SwTwips nDist = pFrm->Frm().Height() - pFrm->Prt().Height() +/*N*/ - pFrm->Prt().Top(); +/*N*/ if( nRet + nDist < nMin ) +/*N*/ { +/*N*/ sal_Bool bRepaint = HasTruncLines() && +/*N*/ GetInfo().GetParaPortion()->GetRepaint()->Bottom() == nRet-1; +/*N*/ nRet = nMin - nDist; +/*N*/ if( bRepaint ) +/*N*/ { +/*?*/ ((SwRepaint*)GetInfo().GetParaPortion() +/*?*/ ->GetRepaint())->Bottom( nRet-1 ); +/*?*/ ((SwTxtFormatInfo&)GetInfo()).SetPaintOfst( 0 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::_CalcFitToContent() + * + * FME: This routine does a limited text formatting under the assumption, + * that the line length is USHORT twips. I'm not sure why we do not do + * a full text formatting using "FormatLine" or "BuildPortion" here, + * similar to SwTxtFormatter::Hyphenate(). If we compare this function + * to BuildPortions(), it looks like they used to be very similar + * (back in 1995), but BuildPortions() changed and _CalcFitToContent() + * did not. So _CalcFitToContent() does not give you exact results, + * although the results should be good enought for most situations. + *************************************************************************/ + + +/************************************************************************* + * SwTxtFormatter::AllowRepaintOpt() + * + * determines if the calculation of a repaint offset is allowed + * otherwise each line is painted from 0 (this is a copy of the beginning + * of the former SwTxtFormatter::Recycle() function + *************************************************************************/ +/*N*/ sal_Bool SwTxtFormatter::AllowRepaintOpt() const +/*N*/ { +/*N*/ // reformat position in front of current line? Only in this case +/*N*/ // we want to set the repaint offset +/*N*/ sal_Bool bOptimizeRepaint = nStart < GetInfo().GetReformatStart() && +/*N*/ pCurr->GetLen(); +/*N*/ +/*N*/ // a special case is the last line of a block adjusted paragraph: +/*N*/ if ( bOptimizeRepaint ) +/*N*/ { +/*N*/ switch( GetAdjust() ) +/*N*/ { +/*N*/ case SVX_ADJUST_BLOCK: +/*N*/ { +/*N*/ if( IsLastBlock() || IsLastCenter() ) +/*?*/ bOptimizeRepaint = sal_False; +/*N*/ else +/*N*/ { +/*N*/ // ????: Blank in der letzten Masterzeile (blocksat.sdw) +/*N*/ bOptimizeRepaint = 0 == pCurr->GetNext() && !pFrm->GetFollow(); +/*N*/ if ( bOptimizeRepaint ) +/*N*/ { +/*N*/ SwLinePortion *pPos = pCurr->GetFirstPortion(); +/*N*/ while ( pPos && !pPos->IsFlyPortion() ) +/*N*/ pPos = pPos->GetPortion(); +/*N*/ bOptimizeRepaint = !pPos; +/*N*/ } +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case SVX_ADJUST_CENTER: +/*N*/ case SVX_ADJUST_RIGHT: +/*N*/ bOptimizeRepaint = sal_False; +/*N*/ break; +/*N*/ default: ; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Schon wieder ein Sonderfall: unsichtbare SoftHyphs +/*N*/ const xub_StrLen nReformat = GetInfo().GetReformatStart(); +/*N*/ if( bOptimizeRepaint && STRING_LEN != nReformat ) +/*N*/ { +/*N*/ const xub_Unicode cCh = GetInfo().GetTxt().GetChar( nReformat ); +/*N*/ bOptimizeRepaint = ( CH_TXTATR_BREAKWORD != cCh && CH_TXTATR_INWORD != cCh ) +/*N*/ || ! GetInfo().HasHint( nReformat ); +/*N*/ } +/*N*/ +/*N*/ return bOptimizeRepaint; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcOptRepaint() + * + * calculates an optimal repaint offset for the current line + *************************************************************************/ +/*N*/ long SwTxtFormatter::CalcOptRepaint( xub_StrLen nOldLineEnd, +/*N*/ const SvLongs* pFlyStart ) +/*N*/ { +/*N*/ if ( GetInfo().GetIdx() < GetInfo().GetReformatStart() ) +/*N*/ // the reformat position is behind our new line, that means +/*N*/ // something of our text has moved to the next line +/*N*/ return 0; +/*N*/ +/*N*/ xub_StrLen nReformat = Min( GetInfo().GetReformatStart(), nOldLineEnd ); +/*N*/ +/*N*/ // in case we do not have any fly in our line, our repaint position +/*N*/ // is the changed position - 1 +/*N*/ if ( ! pFlyStart && ! pCurr->IsFly() ) +/*N*/ { +/*N*/ // this is the maximum repaint offset determined during formatting +/*N*/ // for example: the beginning of the first right tab stop +/*N*/ // if this value is 0, this means that we do not have an upper +/*N*/ // limit for the repaint offset +/*N*/ const long nFormatRepaint = GetInfo().GetPaintOfst(); +/*N*/ +/*N*/ if ( nReformat < GetInfo().GetLineStart() + 3 ) +/*N*/ return 0; +/*N*/ +/*N*/ // step back for smoother repaint +/*N*/ --nReformat; +/*N*/ +/*N*/ // step back two more characters for complex scripts +/*N*/ const SwScriptInfo& rSI = GetInfo().GetParaPortion()->GetScriptInfo(); +/*N*/ if ( ScriptType::COMPLEX == rSI.ScriptType( nReformat ) ) +/*N*/ nReformat -= 2; +/*N*/ +/*N*/ // Weird situation: Our line used to end with a hole portion +/*N*/ // and we delete some characters at the end of our line. We have +/*N*/ // to take care for repainting the blanks which are not anymore +/*N*/ // covered by the hole portion +/*N*/ while ( nReformat > GetInfo().GetLineStart() && +/*N*/ CH_BLANK == GetInfo().GetChar( nReformat ) ) +/*N*/ --nReformat; +/*N*/ +/*N*/ ASSERT( nReformat < GetInfo().GetIdx(), "Reformat too small for me!" ); +/*N*/ SwRect aRect; +/*N*/ +/*N*/ // Note: GetChareRect is not const. It definitely changes the +/*N*/ // bMulti flag. We have to save and resore the old value. +/*N*/ sal_Bool bOldMulti = GetInfo().IsMulti(); +/*N*/ GetCharRect( &aRect, nReformat ); +/*N*/ GetInfo().SetMulti( bOldMulti ); +/*N*/ +/*N*/ return nFormatRepaint ? Min( aRect.Left(), nFormatRepaint ) : +/*N*/ aRect.Left(); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ // nReformat may be wrong, if something around flys has changed: +/*?*/ // we compare the former and the new fly positions in this line +/*?*/ // if anything has changed, we carefully have to adjust the right +/*?*/ // repaint position +/*?*/ long nPOfst = 0; +/*?*/ USHORT nCnt = 0; +/*?*/ USHORT nX = 0; +/*?*/ USHORT nIdx = GetInfo().GetLineStart(); +/*?*/ SwLinePortion* pPor = pCurr->GetFirstPortion(); +/*?*/ +/*?*/ while ( pPor ) +/*?*/ { +/*?*/ if ( pPor->IsFlyPortion() ) +/*?*/ { +/*?*/ // compare start of fly with former start of fly +/*?*/ if ( pFlyStart && +/*?*/ nCnt < pFlyStart->Count() && +/*?*/ nX == (*pFlyStart)[ nCnt ] && +/*?*/ nIdx < nReformat +/*?*/ ) +/*?*/ // found fix position, nothing has changed left from nX +/*?*/ nPOfst = nX + pPor->Width(); +/*?*/ else +/*?*/ break; +/*?*/ +/*?*/ nCnt++; +/*?*/ } +/*?*/ nX += pPor->Width(); +/*?*/ nIdx += pPor->GetLen(); +/*?*/ pPor = pPor->GetPortion(); +/*?*/ } +/*?*/ +/*?*/ return nPOfst + GetLeftMargin(); +/*N*/ } +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itrpaint.cxx b/binfilter/bf_sw/source/core/text/sw_itrpaint.cxx new file mode 100644 index 000000000000..fb54f6ba5705 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itrpaint.cxx @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <horiornt.hxx> + +#include "txtatr.hxx" // SwINetFmt + + +#include <pagedesc.hxx> // SwPageDesc + +#include "itrpaint.hxx" +#include "pormulti.hxx" +namespace binfilter { + +/************************************************************************* + * IsUnderlineBreak + * + * Returns, if we have an underline breaking situation + * Adding some more conditions here means you also have to change them + * in SwTxtPainter::CheckSpecialUnderline + *************************************************************************/ +/*N*/ sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt ) +/*N*/ { +/*N*/ return UNDERLINE_NONE == rFnt.GetUnderline() || +/*N*/ rPor.IsFlyPortion() || rPor.IsFlyCntPortion() || +/*N*/ rPor.IsBreakPortion() || rPor.IsMarginPortion() || +/*N*/ rPor.IsHolePortion() || +/*N*/ ( rPor.IsMultiPortion() && ! ((SwMultiPortion&)rPor).IsBidi() ) || +/*N*/ rFnt.GetEscapement() < 0 || rFnt.IsWordLineMode() || +/*N*/ SVX_CASEMAP_KAPITAELCHEN == rFnt.GetCaseMap(); +/*N*/ } + +/************************************************************************* + * SwTxtPainter::CtorInit() + *************************************************************************/ +/*N*/ void SwTxtPainter::CtorInit( SwTxtFrm *pFrm, SwTxtPaintInfo *pNewInf ) +/*N*/ { +/*N*/ SwTxtCursor::CtorInit( pFrm, pNewInf ); +/*N*/ pInf = pNewInf; +/*N*/ SwFont *pFnt = GetFnt(); +/*N*/ GetInfo().SetFont( pFnt ); +/*N*/ #ifdef DBG_UTIL +/*N*/ if( ALIGN_BASELINE != pFnt->GetAlign() ) +/*N*/ { +/*?*/ ASSERT( ALIGN_BASELINE == pFnt->GetAlign(), +/*?*/ "+SwTxtPainter::CTOR: font alignment revolution" ); +/*?*/ pFnt->SetAlign( ALIGN_BASELINE ); +/*N*/ } +/*N*/ #endif +/*N*/ bPaintDrop = sal_False; +/*N*/ } + + +/************************************************************************* + * SwTxtPainter::CalcPaintOfst() + *************************************************************************/ + +/************************************************************************* + * SwTxtPainter::DrawTextLine() + * + * Es gibt zwei Moeglichkeiten bei transparenten Font auszugeben: + * 1) DrawRect auf die ganze Zeile und die DrawText hinterher + * (objektiv schnell, subjektiv langsam). + * 2) Fuer jede Portion ein DrawRect mit anschliessendem DrawText + * ausgefuehrt (objektiv langsam, subjektiv schnell). + * Da der User in der Regel subjektiv urteilt, wird die 2. Methode + * als Default eingestellt. + *************************************************************************/ + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_itrtxt.cxx b/binfilter/bf_sw/source/core/text/sw_itrtxt.cxx new file mode 100644 index 000000000000..e3599f007226 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_itrtxt.cxx @@ -0,0 +1,514 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <errhdl.hxx> + + +#include <horiornt.hxx> + +#include "paratr.hxx" +#include "errhdl.hxx" + + +#ifdef VERTICAL_LAYOUT +#include <pagefrm.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> +#endif + +#include "txtcfg.hxx" +#include "itrtxt.hxx" +namespace binfilter { + +#if OSL_DEBUG_LEVEL > 1 +# include "txtfrm.hxx" // GetFrmID, +#endif + +/************************************************************************* + * SwTxtIter::CtorInit() + *************************************************************************/ + +/*N*/ void SwTxtIter::CtorInit( SwTxtFrm *pNewFrm, SwTxtInfo *pNewInf ) +/*N*/ { +/*N*/ #ifdef DBGTXT +/*N*/ // nStopAt laesst sich vom CV bearbeiten. +/*N*/ static MSHORT nStopAt = 0; +/*N*/ if( nStopAt == pNewFrm->GetFrmId() ) +/*N*/ { +/*N*/ int i = pNewFrm->GetFrmId(); +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ SwTxtNode *pNode = pNewFrm->GetTxtNode(); +/*N*/ +/*N*/ ASSERT( pNewFrm->GetPara(), "No paragraph" ); +/*N*/ +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ SwAttrIter::CtorInit( *pNode, pNewFrm->GetPara()->GetScriptInfo(), pNewFrm ); +/*N*/ #else +/*N*/ SwAttrIter::CtorInit( *pNode, pNewFrm->GetPara()->GetScriptInfo() ); +/*N*/ #endif +/*N*/ +/*N*/ pFrm = pNewFrm; +/*N*/ pInf = pNewInf; +/*N*/ aLineInf.CtorInit( pNode->GetSwAttrSet() ); +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ nFrameStart = pFrm->Frm().Pos().Y() + pFrm->Prt().Pos().Y(); +/*N*/ #else +/*N*/ aTopLeft = pFrm->Frm().Pos() + pFrm->Prt().Pos(); +/*N*/ #endif +/*N*/ SwTxtIter::Init(); +/*N*/ if( pNode->GetSwAttrSet().GetRegister().GetValue() ) +/*N*/ bRegisterOn = pFrm->FillRegister( nRegStart, nRegDiff ); +/*N*/ else +/*N*/ bRegisterOn = sal_False; +/*N*/ } + +/************************************************************************* + * SwTxtIter::Init() + *************************************************************************/ + +/*N*/ void SwTxtIter::Init() +/*N*/ { +/*N*/ pCurr = pInf->GetParaPortion(); +/*N*/ nStart = pInf->GetTxtStart(); +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ nY = nFrameStart; +/*N*/ #else +/*N*/ nY = aTopLeft.Y(); +/*N*/ #endif +/*N*/ bPrev = sal_True; +/*N*/ pPrev = 0; +/*N*/ nLineNr = 1; +/*N*/ } + +/************************************************************************* + * SwTxtIter::_GetHeightAndAscent() + *************************************************************************/ + +/*N*/ void SwTxtIter::CalcAscentAndHeight( KSHORT &rAscent, KSHORT &rHeight ) const +/*N*/ { +/*N*/ rHeight = GetLineHeight(); +/*N*/ rAscent = pCurr->GetAscent() + rHeight - pCurr->Height(); +/*N*/ } + +/************************************************************************* + * SwTxtIter::_GetPrev() + *************************************************************************/ + +/*N*/ SwLineLayout *SwTxtIter::_GetPrev() +/*N*/ { +/*N*/ pPrev = 0; +/*N*/ bPrev = sal_True; +/*N*/ SwLineLayout *pLay = pInf->GetParaPortion(); +/*N*/ if( pCurr == pLay ) +/*N*/ return 0; +/*N*/ while( pLay->GetNext() != pCurr ) +/*N*/ pLay = pLay->GetNext(); +/*N*/ return pPrev = pLay; +/*N*/ } + +/************************************************************************* + * SwTxtIter::GetPrev() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::GetPrev() +/*N*/ { +/*N*/ if(! bPrev) +/*?*/ _GetPrev(); +/*N*/ return pPrev; +/*N*/ } + +/************************************************************************* + * SwTxtIter::Prev() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::Prev() +/*N*/ { +/*N*/ if( !bPrev ) +/*N*/ _GetPrev(); +/*N*/ if( pPrev ) +/*N*/ { +/*N*/ bPrev = sal_False; +/*N*/ pCurr = pPrev; +/*N*/ nStart -= pCurr->GetLen(); +/*N*/ nY -= GetLineHeight(); +/*N*/ if( !pCurr->IsDummy() && !(--nLineNr) ) +/*N*/ ++nLineNr; +/*N*/ return pCurr; +/*N*/ } +/*N*/ else +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwTxtIter::Next() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::Next() +/*N*/ { +/*N*/ if(pCurr->GetNext()) +/*N*/ { +/*N*/ pPrev = pCurr; +/*N*/ bPrev = sal_True; +/*N*/ nStart += pCurr->GetLen(); +/*N*/ nY += GetLineHeight(); +/*N*/ if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) ) +/*N*/ ++nLineNr; +/*N*/ return pCurr = pCurr->GetNext(); +/*N*/ } +/*N*/ else +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwTxtIter::NextLine() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::NextLine() +/*N*/ { +/*N*/ const SwLineLayout *pNext = Next(); +/*N*/ while( pNext && pNext->IsDummy() && pNext->GetNext() ) +/*N*/ { +///*?*/ DBG_LOOP; +/*?*/ pNext = Next(); +/*N*/ } +/*N*/ return pNext; +/*N*/ } + +/************************************************************************* + * SwTxtIter::GetNextLine() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::GetNextLine() const +/*N*/ { +/*N*/ const SwLineLayout *pNext = pCurr->GetNext(); +/*N*/ while( pNext && pNext->IsDummy() && pNext->GetNext() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ pNext = pNext->GetNext(); +/*N*/ } +/*N*/ return (SwLineLayout*)pNext; +/*N*/ } + +/************************************************************************* + * SwTxtIter::GetPrevLine() + *************************************************************************/ + + +/************************************************************************* + * SwTxtIter::PrevLine() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::PrevLine() +/*N*/ { +/*N*/ const SwLineLayout *pPrev = Prev(); +/*N*/ if( !pPrev ) +/*N*/ return 0; +/*N*/ +/*N*/ const SwLineLayout *pLast = pPrev; +/*N*/ while( pPrev && pPrev->IsDummy() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ pLast = pPrev; +/*N*/ pPrev = Prev(); +/*N*/ } +/*N*/ return (SwLineLayout*)(pPrev ? pPrev : pLast); +/*N*/ } + +/************************************************************************* + * SwTxtIter::Bottom() + *************************************************************************/ + +/*N*/ void SwTxtIter::Bottom() +/*N*/ { +/*N*/ while( Next() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtIter::CharToLine() + *************************************************************************/ +/*N*/ +/*N*/ void SwTxtIter::CharToLine(const xub_StrLen nChar) +/*N*/ { +/*N*/ while( nStart + pCurr->GetLen() <= nChar && Next() ) +/*N*/ ; +/*N*/ while( nStart > nChar && Prev() ) +/*N*/ ; +/*N*/ } + +/************************************************************************* + * SwTxtIter::CharCrsrToLine() + *************************************************************************/ + +// 1170: beruecksichtigt Mehrdeutigkeiten: +/*N*/ const SwLineLayout *SwTxtCursor::CharCrsrToLine( const xub_StrLen nPos ) +/*N*/ { +/*N*/ CharToLine( nPos ); +/*N*/ if( nPos != nStart ) +/*N*/ bRightMargin = sal_False; +/*N*/ sal_Bool bPrev = bRightMargin && pCurr->GetLen() && GetPrev() && +/*N*/ GetPrev()->GetLen(); +/*N*/ if( bPrev && nPos && CH_BREAK == GetInfo().GetChar( nPos-1 ) ) +/*N*/ bPrev = sal_False; +/*N*/ return bPrev ? PrevLine() : pCurr; +/*N*/ } + +/************************************************************************* + * SwTxtCrsr::AdjustBaseLine() + *************************************************************************/ + +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ USHORT SwTxtCursor::AdjustBaseLine( const SwLineLayout& rLine, +/*N*/ const SwLinePortion* pPor, +/*N*/ USHORT nPorHeight, USHORT nPorAscent, +/*N*/ const sal_Bool bAutoToCentered ) const +/*N*/ { +/*N*/ if ( pPor ) +/*N*/ { +/*?*/ nPorHeight = pPor->Height(); +/*?*/ nPorAscent = pPor->GetAscent(); +/*N*/ } +/*N*/ +/*N*/ USHORT nOfst = rLine.GetRealHeight() - rLine.Height(); +/*N*/ +/*N*/ GETGRID( pFrm->FindPageFrm() ) +/*N*/ const sal_Bool bHasGrid = pGrid && GetInfo().SnapToGrid(); +/*N*/ +/*N*/ if ( bHasGrid ) +/*N*/ { +/*?*/ const USHORT nGridWidth = pGrid->GetBaseHeight(); +/*?*/ const USHORT nRubyHeight = pGrid->GetRubyHeight(); +/*?*/ const sal_Bool bRubyTop = ! pGrid->GetRubyTextBelow(); +/*?*/ +/*?*/ if ( GetInfo().IsMulti() ) +/*?*/ // we are inside the GetCharRect recursion for multi portions +/*?*/ // we center the portion in its surrounding line +/*?*/ nOfst = ( pCurr->Height() - nPorHeight ) / 2 + nPorAscent; +/*?*/ else + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ { +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ switch ( GetLineInfo().GetVertAlign() ) { +/*?*/ case SvxParaVertAlignItem::TOP : +/*?*/ nOfst += nPorAscent; +/*?*/ break; +/*?*/ case SvxParaVertAlignItem::CENTER : +/*?*/ ASSERT( rLine.Height() >= nPorHeight, "Portion height > Line height"); +/*?*/ nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent; +/*?*/ break; +/*?*/ case SvxParaVertAlignItem::BOTTOM : +/*?*/ nOfst += rLine.Height() - nPorHeight + nPorAscent; +/*?*/ break; +/*N*/ case SvxParaVertAlignItem::AUTOMATIC : +/*N*/ if ( bAutoToCentered || GetInfo().GetTxtFrm()->IsVertical() ) +/*N*/ { +/*?*/ nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent; +/*?*/ break; +/*N*/ } +/*N*/ case SvxParaVertAlignItem::BASELINE : +/*N*/ // base line +/*N*/ nOfst += rLine.GetAscent(); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return nOfst; +/*N*/ } +/*N*/ #else +/*N*/ USHORT SwTxtCursor::AdjustBaseLine( const SwLineLayout& rLine, +/*N*/ const USHORT nPorHeight, +/*N*/ const USHORT nPorAscent, +/*N*/ const sal_Bool bAutoToCentered ) const +/*N*/ { +/*N*/ USHORT nOfst = rLine.GetRealHeight() - rLine.Height(); +/*N*/ +/*N*/ switch ( GetLineInfo().GetVertAlign() ) { +/*N*/ case SvxParaVertAlignItem::TOP : +/*N*/ nOfst += nPorAscent; +/*N*/ break; +/*N*/ case SvxParaVertAlignItem::CENTER : +/*N*/ ASSERT( rLine.Height() >= nPorHeight, "Portion height > Line height"); +/*N*/ nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent; +/*N*/ break; +/*N*/ case SvxParaVertAlignItem::BOTTOM : +/*N*/ nOfst += rLine.Height() - nPorHeight + nPorAscent; +/*N*/ break; +/*N*/ case SvxParaVertAlignItem::AUTOMATIC : +/*N*/ if ( bAutoToCentered ) +/*N*/ { +/*N*/ nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent; +/*N*/ break; +/*N*/ } +/*N*/ case SvxParaVertAlignItem::BASELINE : +/*N*/ // base line +/*N*/ nOfst += rLine.GetAscent(); +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ return nOfst; +/*N*/ } +/*N*/ #endif + +/************************************************************************* + * SwTxtIter::TwipsToLine() + *************************************************************************/ + +/*N*/ const SwLineLayout *SwTxtIter::TwipsToLine( const SwTwips y) +/*N*/ { +/*N*/ while( nY + GetLineHeight() <= y && Next() ) +/*N*/ ; +/*N*/ while( nY > y && Prev() ) +/*N*/ ; +/*N*/ return pCurr; +/*N*/ } + +/************************************************************************* + * SwTxtIter::TruncLines() + *************************************************************************/ + +/*N*/ void SwTxtIter::TruncLines( sal_Bool bNoteFollow ) +/*N*/ { +/*N*/ SwLineLayout *pDel = pCurr->GetNext(); +/*N*/ const xub_StrLen nEnd = nStart + pCurr->GetLen(); +/*N*/ +/*N*/ if( pDel ) +/*N*/ { +/*N*/ pCurr->SetNext( 0 ); +/*N*/ if( GetHints() && bNoteFollow ) +/*N*/ { +/*N*/ GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() ); +/*N*/ +/*N*/ // bug 88534: wrong positioning of flys +/*N*/ SwTxtFrm* pFollow = GetTxtFrm()->GetFollow(); +/*N*/ if ( pFollow && ! pFollow->IsLocked() && +/*N*/ nEnd == pFollow->GetOfst() ) +/*N*/ { +/*N*/ xub_StrLen nRangeEnd = nEnd; +/*N*/ SwLineLayout* pLine = pDel; +/*N*/ +/*N*/ // determine range to be searched for flys anchored as characters +/*N*/ while ( pLine ) +/*N*/ { +/*N*/ nRangeEnd += pLine->GetLen(); +/*N*/ pLine = pLine->GetNext(); +/*N*/ } +/*N*/ +/*N*/ SwpHints* pHints = GetTxtFrm()->GetTxtNode()->GetpSwpHints(); +/*N*/ +/*N*/ // examine hints in range nEnd - (nEnd + nRangeChar) +/*N*/ for( USHORT i = 0; i < pHints->Count(); i++ ) +/*N*/ { +/*N*/ const SwTxtAttr* pHt = pHints->GetHt( i ); +/*N*/ if( RES_TXTATR_FLYCNT == pHt->Which() ) +/*N*/ { +/*N*/ // check, if hint is in our range +/*?*/ const USHORT nPos = *pHt->GetStart(); +/*?*/ if ( nEnd <= nPos && nPos < nRangeEnd ) +/*?*/ pFollow->_InvalidateRange( +/*?*/ SwCharRange( nPos, nPos ), 0 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ delete pDel; +/*N*/ } +/*N*/ if( pCurr->IsDummy() && +/*N*/ !pCurr->GetLen() && +/*N*/ nStart < GetTxtFrm()->GetTxt().Len() ) +/*N*/ pCurr->SetRealHeight( 1 ); +/*N*/ if( GetHints() ) +/*N*/ pFrm->RemoveFtn( nEnd ); +/*N*/ } + +/************************************************************************* + * SwTxtIter::CntHyphens() + *************************************************************************/ + +/*N*/ void SwTxtIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const +/*N*/ { +/*N*/ nEndCnt = 0; +/*N*/ nMidCnt = 0; +/*N*/ if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() ) +/*N*/ return; +/*N*/ SwLineLayout *pLay = pInf->GetParaPortion(); +/*N*/ if( pCurr == pLay ) +/*N*/ return; +/*N*/ while( pLay != pCurr ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if ( pLay->IsEndHyph() ) +/*N*/ nEndCnt++; +/*N*/ else +/*N*/ nEndCnt = 0; +/*N*/ if ( pLay->IsMidHyph() ) +/*N*/ nMidCnt++; +/*N*/ else +/*N*/ nMidCnt = 0; +/*N*/ pLay = pLay->GetNext(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwHookOut + * + * Change current output device to formatting device, this has to be done before + * formatting. + *************************************************************************/ + +/*N*/ SwHookOut::SwHookOut( SwTxtSizeInfo& rInfo ) : +/*N*/ pInf( &rInfo ), +/*N*/ pOut( rInfo.GetOut() ), +/*N*/ bOnWin( rInfo.OnWin() ) +/*N*/ { +/*N*/ ASSERT( rInfo.GetRefDev(), "No reference device for text formatting" ) +/*N*/ +/*N*/ // set new values +/*N*/ rInfo.SetOut( rInfo.GetRefDev() ); +/*N*/ rInfo.SetOnWin( sal_False ); +/*N*/ } + +/*N*/ SwHookOut::~SwHookOut() +/*N*/ { +/*N*/ pInf->SetOut( pOut ); +/*N*/ pInf->SetOnWin( bOnWin ); +/*N*/ } + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_noteurl.cxx b/binfilter/bf_sw/source/core/text/sw_noteurl.cxx new file mode 100644 index 000000000000..372a27a0b6b8 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_noteurl.cxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +/*N*/ #ifdef _MSC_VER +/*N*/ #pragma hdrstop +/*N*/ #endif +/*N*/ +/*N*/ #include "swtypes.hxx" +/*N*/ +/*N*/ #ifndef _SV_OUTDEV_HXX //autogen +/*N*/ #include <vcl/outdev.hxx> +/*N*/ #endif +/*N*/ #ifndef _GOODIES_IMAPRECT_HXX +/*N*/ #include <bf_svtools/imaprect.hxx> +/*N*/ #endif +/*N*/ #ifndef _IMAP_HXX //autogen +/*N*/ #include <bf_svtools/imap.hxx> +/*N*/ #endif +/*N*/ +/*N*/ #include "txttypes.hxx" +/*N*/ #include "noteurl.hxx" +/*N*/ namespace binfilter { +/*N*/ // globale Variable, wird in noteurl.Hxx bekanntgegeben +/*N*/ SwNoteURL *pNoteURL = NULL; + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porexp.cxx b/binfilter/bf_sw/source/core/text/sw_porexp.cxx new file mode 100644 index 000000000000..816255a7f33a --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porexp.cxx @@ -0,0 +1,215 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <inftxt.hxx> +#include <porexp.hxx> +namespace binfilter { + +/************************************************************************* + * class SwExpandPortion + *************************************************************************/ + + +/************************************************************************* + * virtual SwExpandPortion::GetExpTxt() + *************************************************************************/ + + +/************************************************************************* + * virtual SwExpandPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * virtual SwExpandPortion::GetTxtSize() + *************************************************************************/ + +/*N*/ SwPosSize SwExpandPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const +/*N*/ { +/*N*/ SwTxtSlot aDiffTxt( &rInf, this ); +/*N*/ return rInf.GetTxtSize(); +/*N*/ } + +/************************************************************************* + * virtual SwExpandPortion::Format() + *************************************************************************/ + +// 5010: Exp und Tabs + +/*N*/ sal_Bool SwExpandPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ SwTxtSlotLen aDiffTxt( &rInf, this ); +/*N*/ const xub_StrLen nFullLen = rInf.GetLen(); +/*N*/ +/*N*/ // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der +/*N*/ // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs) +/*N*/ // sal_False returnen wegen SetFull ... +/*N*/ if( !nFullLen ) +/*N*/ { +/*N*/ // nicht Init(), weil wir Hoehe und Ascent brauchen +/*?*/ Width(0); +/*?*/ return sal_False; +/*N*/ } +/*N*/ return SwTxtPortion::Format( rInf ); +/*N*/ } + +/************************************************************************* + * virtual SwExpandPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * class SwBlankPortion + *************************************************************************/ + +/*N*/ 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... + +/*N*/ MSHORT SwBlankPortion::MayUnderFlow( const SwTxtFormatInfo &rInf, +/*N*/ xub_StrLen nIdx, sal_Bool bUnderFlow ) const +/*N*/ { +/*N*/ if( rInf.StopUnderFlow() ) +/*N*/ return 0; +/*N*/ const SwLinePortion *pPos = rInf.GetRoot(); +/*N*/ if( pPos->GetPortion() ) +/*N*/ pPos = pPos->GetPortion(); +/*N*/ while( pPos && pPos->IsBlankPortion() ) +/*?*/ pPos = pPos->GetPortion(); +/*N*/ if( !pPos || !rInf.GetIdx() || ( !pPos->GetLen() && pPos == rInf.GetRoot() ) ) +/*N*/ return 0; // Nur noch BlankPortions unterwegs +/*N*/ // Wenn vor uns ein Blank ist, brauchen wir kein Underflow ausloesen, +/*N*/ // wenn hinter uns ein Blank ist, brauchen wir kein Underflow weiterreichen +/*N*/ if( bUnderFlow && CH_BLANK == rInf.GetTxt().GetChar( nIdx + 1) ) +/*N*/ return 0; +/*N*/ if( nIdx && !((SwTxtFormatInfo&)rInf).GetFly() ) +/*N*/ { +/*N*/ while( pPos && !pPos->IsFlyPortion() ) +/*N*/ pPos = pPos->GetPortion(); +/*N*/ if( !pPos ) +/*N*/ { +/*N*/ //Hier wird ueberprueft, ob es in dieser Zeile noch sinnvolle Umbrueche +/*N*/ //gibt, Blanks oder Felder etc., wenn nicht, kein Underflow. +/*N*/ //Wenn Flys im Spiel sind, lassen wir das Underflow trotzdem zu. +/*N*/ xub_StrLen nBlank = nIdx; +/*N*/ while( --nBlank > rInf.GetLineStart() ) +/*N*/ { +/*N*/ const xub_Unicode cCh = rInf.GetChar( nBlank ); +/*N*/ if( CH_BLANK == cCh || +/*N*/ (( CH_TXTATR_BREAKWORD == cCh || CH_TXTATR_INWORD == cCh ) +/*N*/ && rInf.HasHint( nBlank ) ) ) +/*N*/ break; +/*N*/ } +/*N*/ if( nBlank <= rInf.GetLineStart() ) +/*N*/ return 0; +/*N*/ } +/*N*/ } +/*N*/ xub_Unicode cCh; +/*N*/ if( nIdx < 2 || CH_BLANK == (cCh = rInf.GetChar( nIdx - 1 )) ) +/*N*/ return 1; +/*N*/ if( CH_BREAK == cCh ) +/*N*/ return 0; +/*N*/ return 2; +/*N*/ } + +/************************************************************************* + * virtual SwBlankPortion::FormatEOL() + *************************************************************************/ +// Format end of Line + + +/************************************************************************* + * virtual SwBlankPortion::Format() + *************************************************************************/ + +// 7771: UnderFlows weiterreichen und selbst ausloesen! +/*N*/ sal_Bool SwBlankPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ const sal_Bool bFull = rInf.IsUnderFlow() || SwExpandPortion::Format( rInf ); +/*N*/ if( bFull && MayUnderFlow( rInf, rInf.GetIdx(), rInf.IsUnderFlow() ) ) +/*N*/ { +/*N*/ Truncate(); +/*N*/ rInf.SetUnderFlow( this ); +/*N*/ if( rInf.GetLast()->IsKernPortion() ) +/*?*/ rInf.SetUnderFlow( rInf.GetLast() ); +/*N*/ } +/*N*/ return bFull; +/*N*/ } + +/************************************************************************* + * virtual SwBlankPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * virtual SwBlankPortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwBlankPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ rTxt = cChar; +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * virtual SwBlankPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * class SwPostItsPortion + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwPostItsPortion::Format() + *************************************************************************/ + + +/************************************************************************* + * virtual SwPostItsPortion::GetExpTxt() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porfld.cxx b/binfilter/bf_sw/source/core/text/sw_porfld.cxx new file mode 100644 index 000000000000..fef4bfe1a341 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porfld.cxx @@ -0,0 +1,526 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <com/sun/star/i18n/ScriptType.hdl> + + +#include <viewopt.hxx> // SwViewOptions + +#include <horiornt.hxx> + +#include <inftxt.hxx> +#include <breakit.hxx> +#include <porftn.hxx> // SwFtnPortion +namespace binfilter { + +using namespace ::com::sun::star; + +/************************************************************************* + * class SwFldPortion + *************************************************************************/ + +/*N*/ SwLinePortion *SwFldPortion::Compress() +/*N*/ { return (GetLen() || aExpand.Len() || SwLinePortion::Compress()) ? this : 0; } + +/*N*/ SwFldPortion *SwFldPortion::Clone( const XubString &rExpand ) const +/*N*/ { +/*N*/ SwFont *pNewFnt; +/*N*/ if( 0 != ( pNewFnt = pFnt ) ) +/*?*/ pNewFnt = new SwFont( *pFnt ); +/*N*/ SwFldPortion* pClone = new SwFldPortion( rExpand, pNewFnt ); +/*N*/ pClone->SetNextOffset( nNextOffset ); +/*N*/ return pClone; +/*N*/ } + +/*N*/ void SwFldPortion::TakeNextOffset( const SwFldPortion* pFld ) +/*N*/ { +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //STRIP001 ASSERT( pFld, "TakeNextOffset: Missing Source" ); +/*N*/ } + +/*N*/ SwFldPortion::SwFldPortion( const XubString &rExpand, SwFont *pFnt ) +/*N*/ : aExpand(rExpand), pFnt(pFnt), nViewWidth(0), nNextOffset(0), +/*N*/ bFollow( sal_False ), bHasFollow( sal_False ) +/*N*/ { +/*N*/ SetWhichPor( POR_FLD ); +/*N*/ } + +/*N*/ SwFldPortion::SwFldPortion( const SwFldPortion& rFld ) +/*N*/ : aExpand( rFld.GetExp() ), +/*N*/ bCenter( rFld.IsCenter() ), +/*N*/ bFollow( rFld.IsFollow() ), +/*N*/ bHasFollow( rFld.HasFollow() ), +/*N*/ bHide( rFld.IsHide() ), +/*N*/ bLeft( rFld.IsLeft() ), +/*N*/ nNextOffset( rFld.GetNextOffset() ) +/*N*/ { +/*N*/ if ( rFld.HasFont() ) +/*N*/ pFnt = new SwFont( *rFld.GetFont() ); +/*N*/ else +/*N*/ pFnt = 0; +/*N*/ +/*N*/ SetWhichPor( POR_FLD ); +/*N*/ } + +/*N*/ SwFldPortion::~SwFldPortion() +/*N*/ { +/*N*/ delete pFnt; +/*N*/ } + +/************************************************************************* + * virtual SwFldPortion::GetViewWidth() + *************************************************************************/ + + +/************************************************************************* + * virtual SwFldPortion::Format() + *************************************************************************/ + +// 8653: in keinem Fall nur SetLen(0); + +/************************************************************************* + * Hilfsklasse SwFldSlot + **************************************************************************/ + +class SwFldSlot +{ + const XubString *pOldTxt; + XubString aTxt; + xub_StrLen nIdx; + xub_StrLen nLen; + sal_Bool bOn; + SwTxtFormatInfo *pInf; +public: + SwFldSlot( const SwTxtFormatInfo* pNew, const SwFldPortion *pPor ); + ~SwFldSlot(); +}; + +/*N*/ SwFldSlot::SwFldSlot( const SwTxtFormatInfo* pNew, const SwFldPortion *pPor ) +/*N*/ { +/*N*/ bOn = pPor->GetExpTxt( *pNew, aTxt ); +/*N*/ +/*N*/ // Der Text wird ausgetauscht... +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf = (SwTxtFormatInfo*)pNew; +/*N*/ nIdx = pInf->GetIdx(); +/*N*/ nLen = pInf->GetLen(); +/*N*/ pOldTxt = &(pInf->GetTxt()); +/*N*/ pInf->SetLen( aTxt.Len() ); +/*N*/ if( pPor->IsFollow() ) +/*N*/ { +/*N*/ pInf->SetFakeLineStart( nIdx > pInf->GetLineStart() ); +/*N*/ pInf->SetIdx( 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ XubString aTmp( aTxt ); +/*N*/ aTxt = *pOldTxt; +/*N*/ aTxt.Erase( nIdx, 1 ); +/*N*/ aTxt.Insert( aTmp, nIdx ); +/*N*/ } +/*N*/ pInf->SetTxt( aTxt ); +/*N*/ } +/*N*/ } + +/*N*/ SwFldSlot::~SwFldSlot() +/*N*/ { +/*N*/ if( bOn ) +/*N*/ { +/*N*/ pInf->SetTxt( *pOldTxt ); +/*N*/ pInf->SetIdx( nIdx ); +/*N*/ pInf->SetLen( nLen ); +/*N*/ pInf->SetFakeLineStart( sal_False ); +/*N*/ } +/*N*/ } + +/*N*/ BYTE SwFldPortion::ScriptChange( const SwTxtSizeInfo &rInf, xub_StrLen& rFull ) +/*N*/ { +/*N*/ BYTE nRet = 0; +/*N*/ const String& rTxt = rInf.GetTxt(); +/*N*/ rFull += rInf.GetIdx(); +/*N*/ if( rFull > rTxt.Len() ) +/*?*/ rFull = rTxt.Len(); +/*N*/ if( rFull && pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ BYTE nActual = pFnt ? pFnt->GetActual() : rInf.GetFont()->GetActual(); +/*N*/ xub_StrLen nChg = rInf.GetIdx(); +/*N*/ USHORT nScript; +/*N*/ { +/*N*/ nScript = i18n::ScriptType::LATIN; +/*N*/ if( nActual ) +/*N*/ nScript = nActual == SW_CJK ? i18n::ScriptType::ASIAN +/*N*/ : i18n::ScriptType::COMPLEX; +/*N*/ nChg = (xub_StrLen)pBreakIt->xBreak->endOfScript(rTxt,nChg,nScript); +/*N*/ } +/*N*/ if( rFull > nChg ) +/*N*/ { +/*?*/ nRet = nActual; +/*?*/ nScript = pBreakIt->xBreak->getScriptType( rTxt, nChg ); +/*?*/ if( i18n::ScriptType::ASIAN == nScript ) +/*?*/ nRet += SW_CJK; +/*?*/ else if( i18n::ScriptType::COMPLEX == nScript ) +/*?*/ nRet += SW_CTL; +/*?*/ rFull = nChg; +/*N*/ } +/*N*/ } +/*N*/ rFull -= rInf.GetIdx(); +/*N*/ return nRet; +/*N*/ } + +/*N*/ void SwFldPortion::CheckScript( const SwTxtSizeInfo &rInf ) +/*N*/ { +/*N*/ String aTxt; +/*N*/ if( GetExpTxt( rInf, aTxt ) && aTxt.Len() && pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ BYTE nActual = pFnt ? pFnt->GetActual() : rInf.GetFont()->GetActual(); +/*N*/ USHORT nScript; +/*N*/ { +/*N*/ nScript = pBreakIt->xBreak->getScriptType( aTxt, 0 ); +/*N*/ xub_StrLen nChg = 0; +/*N*/ USHORT nCnt = 0; +/*N*/ if( i18n::ScriptType::WEAK == nScript ) +/*N*/ { +/*N*/ nChg =(xub_StrLen)pBreakIt->xBreak->endOfScript(aTxt,0,nScript); +/*N*/ if( nChg < aTxt.Len() ) +/*?*/ nScript = pBreakIt->xBreak->getScriptType( aTxt, nChg ); +/*N*/ } +/*N*/ } +/*N*/ BYTE nTmp; +/*N*/ switch ( nScript ) { +/*N*/ case i18n::ScriptType::LATIN : nTmp = SW_LATIN; break; +/*N*/ case i18n::ScriptType::ASIAN : nTmp = SW_CJK; break; +/*N*/ case i18n::ScriptType::COMPLEX : nTmp = SW_CTL; break; +/*N*/ default: nTmp = nActual; +/*N*/ } +/*N*/ if( nTmp != nActual ) +/*N*/ { +/*?*/ if( !pFnt ) +/*?*/ pFnt = new SwFont( *rInf.GetFont() ); +/*?*/ pFnt->SetActual( nTmp ); +/*N*/ } +/*N*/ } +/*N*/ } + +/*M*/ sal_Bool SwFldPortion::Format( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ // Scope wegen aDiffTxt::DTOR! +/*M*/ xub_StrLen nRest; +/*M*/ sal_Bool bFull; +/*M*/ sal_Bool bEOL = sal_False; +/*M*/ long nTxtRest = rInf.GetTxt().Len() - rInf.GetIdx(); +/*M*/ { +/*M*/ SwFldSlot aDiffTxt( &rInf, this ); +/*N*/ SwLayoutModeModifier aLayoutModeModifier( *rInf.GetOut() ); +/*N*/ aLayoutModeModifier.SetAuto(); +/*N*/ +/*M*/ const xub_StrLen nOldFullLen = rInf.GetLen(); +/*M*/ const MSHORT nFollow = IsFollow() ? 0 : 1; +/*M*/ xub_StrLen nFullLen; +/*M*/ // In Numerierungen kennen wir keine Platzhalter, sondern +/*M*/ // nur "normale" Zeichen. +/*M*/ if( InNumberGrp() ) +/*M*/ nFullLen = nOldFullLen; +/*M*/ else +/*M*/ { +/*M*/ nFullLen = rInf.ScanPortionEnd( rInf.GetIdx(), +/*N*/ rInf.GetIdx() + nOldFullLen ) - rInf.GetIdx(); +/*M*/ if( nFullLen && CH_BREAK == aExpand.GetChar( nFullLen - 1 ) ) +/*M*/ --nFullLen; +/*M*/ +/*M*/ if ( STRING_LEN != rInf.GetUnderScorePos() && +/*M*/ rInf.GetUnderScorePos() > rInf.GetIdx() ) +/*M*/ rInf.SetUnderScorePos( rInf.GetIdx() ); +/*M*/ } +/*M*/ BYTE nScriptChg = ScriptChange( rInf, nFullLen ); +/*M*/ rInf.SetLen( nFullLen ); +/*M*/ if( pFnt ) +/*M*/ pFnt->GoMagic( rInf.GetVsh(), pFnt->GetActual() ); +/*M*/ +/*M*/ SwFontSave aSave( rInf, pFnt ); +/*M*/ +/*M*/ // 8674: Laenge muss 0 sein, bei bFull nach Format ist die Laenge +/*M*/ // gesetzt und wird in nRest uebertragen. Ansonsten bleibt die +/*M*/ // Laenge erhalten und wuerde auch in nRest einfliessen! +/*M*/ SetLen(0); +/*M*/ +/*M*/ // So komisch es aussieht, die Abfrage auf GetLen() muss wegen der +/*M*/ // ExpandPortions _hinter_ aDiffTxt (vgl. SoftHyphs) +/*M*/ // sal_False returnen wegen SetFull ... +/*M*/ if( !nFullLen ) +/*M*/ { +/*M*/ // nicht Init(), weil wir Hoehe und Ascent brauchen +/*M*/ Width(0); +/*M*/ bFull = rInf.Width() <= rInf.GetPos().X(); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ xub_StrLen nOldLineStart = rInf.GetLineStart(); +/*M*/ if( IsFollow() ) +/*M*/ rInf.SetLineStart( 0 ); +/*M*/ rInf.SetNotEOL( nFullLen == nOldFullLen && nTxtRest > nFollow ); +/*M*/ +/*M*/ // the height depending on the fields font is set, +/*M*/ // this is required for SwTxtGuess::Guess +/*M*/ Height( rInf.GetTxtHeight() ); +/*M*/ // If a kerning portion is inserted after our field portion, +/*M*/ // the ascent and height must be known +/*M*/ SetAscent( rInf.GetAscent() ); +/*M*/ bFull = SwTxtPortion::Format( rInf ); +/*M*/ rInf.SetNotEOL( sal_False ); +/*M*/ rInf.SetLineStart( nOldLineStart ); +/*M*/ } +/*M*/ xub_StrLen nTmpLen = GetLen(); +/*M*/ bEOL = !nTmpLen && nFollow && bFull; +/*M*/ nRest = nOldFullLen - nTmpLen; +/*M*/ +/*M*/ // Das Zeichen wird in der ersten Portion gehalten. +/*M*/ // Unbedingt nach Format! +/*M*/ SetLen( nFollow ); +/*M*/ +/*M*/ if( nRest ) +/*M*/ { +/*M*/ // aExpand ist noch nicht gekuerzt worden, der neue Ofst +/*M*/ // ergibt sich durch nRest. +/*M*/ xub_StrLen nNextOfst = aExpand.Len() - nRest; +/*M*/ +/*M*/ if ( IsQuoVadisPortion() ) +/*?*/ { DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 nNextOfst += ((SwQuoVadisPortion*)this)->GetContTxt().Len(); +/*M*/ +/*M*/ XubString aNew( aExpand, nNextOfst, STRING_LEN ); +/*M*/ aExpand.Erase( nNextOfst, STRING_LEN ); +/*M*/ +/*M*/ // Trailingspace et al. ! +/*M*/ switch( aNew.GetChar( 0 )) +/*M*/ { +/*M*/ case CH_BREAK : bFull = sal_True; +/*M*/ // kein break; +/*M*/ case ' ' : +/*M*/ case CH_TAB : +/*M*/ case CHAR_HARDHYPHEN: // non-breaking hyphen +/*N*/ case CHAR_SOFTHYPHEN: +/*N*/ case CHAR_HARDBLANK: +/*M*/ { +/*M*/ aNew.Erase( 0, 1 ); +/*M*/ ++nNextOfst; +/*M*/ break; +/*M*/ } +/*M*/ default: ; +/*M*/ } +/*M*/ +/*M*/ if( aNew.Len() || IsQuoVadisPortion() ) +/*M*/ { +/*M*/ // sal_True, weil es ein FollowFeld ist +/*M*/ // SwFont *pFont = new SwFont( rInf.GetFont()->GetFnt() ); +/*M*/ SwFldPortion *pFld = Clone( aNew ); +/*M*/ if( !pFld->GetFont() ) +/*M*/ { +/*M*/ SwFont *pNewFnt = new SwFont( *rInf.GetFont() ); +/*M*/ pFld->SetFont( pNewFnt ); +/*M*/ } +/*M*/ pFld->SetFollow( sal_True ); +/*M*/ SetHasFollow( sal_True ); +/*M*/ // In nNextOffset steht bei einem neuangelegten Feld zunaechst +/*M*/ // der Offset, an dem es selbst im Originalstring beginnt. +/*M*/ // Wenn beim Formatieren ein FollowFeld angelegt wird, wird +/*M*/ // der Offset dieses FollowFelds in nNextOffset festgehalten. +/*M*/ nNextOffset += nNextOfst; +/*M*/ pFld->SetNextOffset( nNextOffset ); +/*M*/ rInf.SetRest( pFld ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if( bEOL && rInf.GetLast() && !rInf.GetUnderFlow() ) +/*M*/ rInf.GetLast()->FormatEOL( rInf ); +/*M*/ return bFull; +/*M*/ } + +/************************************************************************* + * virtual SwFldPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * virtual SwFldPortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwFldPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ rTxt = aExpand; +/*N*/ if( !rTxt.Len() && rInf.OnWin() && +/*N*/ !rInf.GetOpt().IsPagePreview() && !rInf.GetOpt().IsReadonly() && +/*N*/ SwViewOption::IsFieldShadings() && +/*N*/ !HasFollow() ) +/*N*/ rTxt = ' '; +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * virtual SwFldPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * virtual SwFldPortion::GetTxtSize() + *************************************************************************/ + +/*N*/ SwPosSize SwFldPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const +/*N*/ { +/*N*/ SwFontSave aSave( rInf, pFnt ); +/*N*/ SwPosSize aSize( SwExpandPortion::GetTxtSize( rInf ) ); +/*N*/ return aSize; +/*N*/ } + +/************************************************************************* + * class SwHiddenPortion + *************************************************************************/ + +/************************************************************************* + * virtual SwHiddenPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * virtual SwHiddenPortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwHiddenPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ // Nicht auf IsHidden() abfragen ! +/*N*/ return SwFldPortion::GetExpTxt( rInf, rTxt ); +/*N*/ } + +/************************************************************************* + * class SwNumberPortion + *************************************************************************/ + +/*N*/ SwNumberPortion::SwNumberPortion( const XubString &rExpand, SwFont *pFnt, +/*N*/ const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst ) +/*N*/ : SwFldPortion( rExpand, pFnt ), nFixWidth(0), nMinDist( nMinDst ) +/*N*/ { +/*N*/ SetWhichPor( POR_NUMBER ); +/*N*/ SetLeft( bLft ); +/*N*/ SetHide( sal_False ); +/*N*/ SetCenter( bCntr ); +/*N*/ } + + + +/************************************************************************* + * virtual SwNumberPortion::Format() + *************************************************************************/ + +// 5010: Wir sind in der Lage, mehrzeilige NumFelder anzulegen! +// 3689: Fies ist, wenn man in der Dialogbox soviel Davor-Text +// eingibt, bis die Zeile ueberlaeuft. +// Man muss die Fly-Ausweichmanoever beachten! + +/*M*/ sal_Bool SwNumberPortion::Format( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ SetHide( sal_False ); +/*M*/ const sal_Bool bFull = SwFldPortion::Format( rInf ); +/*M*/ SetLen( 0 ); +/*M*/ // a numbering portion can be contained in a rotated portion!!! +/*M*/ nFixWidth = rInf.IsMulti() ? Height() : Width(); +/*M*/ rInf.SetNumDone( !rInf.GetRest() ); +/*M*/ if( rInf.IsNumDone() ) +/*M*/ { +/*M*/ // SetAscent( rInf.GetAscent() ); +/*M*/ ASSERT( Height() && nAscent, "NumberPortions without Height | Ascent" ) +/*M*/ +/*M*/ long nDiff = rInf.Left() - rInf.First() + rInf.ForcedLeftMargin(); +/*M*/ // Ein Vorschlag von Juergen und Volkmar: +/*M*/ // Der Textteil hinter der Numerierung sollte immer +/*M*/ // mindestens beim linken Rand beginnen. +/*M*/ if( nDiff < 0 ) +/*M*/ nDiff = 0; +/*M*/ else if ( nDiff > rInf.X() ) +/*M*/ nDiff -= rInf.X(); +/*M*/ if( nDiff < nFixWidth + nMinDist ) +/*M*/ nDiff = nFixWidth + nMinDist; +/*M*/ // 2739: Numerierung weicht Fly aus, kein nDiff in der zweiten Runde +/*M*/ // fieser Sonderfall: FlyFrm liegt in dem Bereich, +/*M*/ // den wir uns gerade unter den Nagel reissen wollen. +/*M*/ // Die NumberPortion wird als verborgen markiert. +/*M*/ if( nDiff > rInf.Width() ) +/*M*/ { +/*M*/ nDiff = rInf.Width(); +/*M*/ SetHide( sal_True ); +/*M*/ } +/*M*/ +/*M*/ // A numbering portion can be inside a SwRotatedPortion. Then the +/*M*/ // Height has to be changed +/*M*/ if ( rInf.IsMulti() ) +/*M*/ { +/*M*/ if ( Height() < nDiff ) +/*M*/ Height( KSHORT( nDiff ) ); +/*M*/ } +/*M*/ else if( Width() < nDiff ) +/*M*/ Width( KSHORT(nDiff) ); +/*M*/ } +/*M*/ return bFull; +/*M*/ } + +/* Ein FormatEOL deutet daraufhin, dass der folgende Text + * nicht mit auf die Zeile passte. Damit die Numerierung mitwandert, + * wird diese NumberPortion verborgen. + */ + + // This caused trouble with flys anchored as characters. + // If one of these is numbered but does not fit to the line, + // it calls this function, causing a loop because both the number + // portion and the fly portion go to the next line +// SetHide( sal_True ); + +/************************************************************************* + * virtual SwNumberPortion::Paint() + *************************************************************************/ + + + +/************************************************************************* + * class SwBulletPortion + *************************************************************************/ + +/*N*/ SwBulletPortion::SwBulletPortion( const xub_Unicode cBullet, SwFont *pFont, +/*N*/ const sal_Bool bLft, const sal_Bool bCntr, const KSHORT nMinDst ) +/*N*/ : SwNumberPortion( XubString( cBullet ), pFont, bLft, bCntr, nMinDst ) +/*N*/ { +/*N*/ SetWhichPor( POR_BULLET ); +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porfly.cxx b/binfilter/bf_sw/source/core/text/sw_porfly.cxx new file mode 100644 index 000000000000..3b08c4fb4c93 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porfly.cxx @@ -0,0 +1,639 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "dcontact.hxx" // SwDrawContact +#include "dflyobj.hxx" // SwVirtFlyDrawObj +#include <errhdl.hxx> + +#include "pam.hxx" // SwPosition + +#include <horiornt.hxx> + +#include "frmfmt.hxx" // SwFrmFmt + +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/ulspitem.hxx> +#include <fmtanchr.hxx> +#include <fmtflcnt.hxx> +#include <fmtornt.hxx> +#include <frmatr.hxx> +#include "flyfrms.hxx" +#include "txatbase.hxx" // SwTxtAttr +#include "porfly.hxx" +#include "inftxt.hxx" // SwTxtPaintInfo +namespace binfilter { + +/************************************************************************* + * class SwFlyPortion + * + * Wir erwarten ein framelokales SwRect ! + *************************************************************************/ + + +/************************************************************************* + * virtual SwFlyPortion::Format() + *************************************************************************/ +/*N*/ sal_Bool SwFlyPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ ASSERT( Fix() >= rInf.X(), "SwFlyPortion::Format: rush hour" ); +/*N*/ // 8537: Tabs muessen expandiert werden. +/*N*/ if( rInf.GetLastTab() ) +/*?*/ ((SwLinePortion*)rInf.GetLastTab())->FormatEOL( rInf ); +/*N*/ +/*N*/ // Der Glue wird aufgespannt. +/*N*/ rInf.GetLast()->FormatEOL( rInf ); +/*N*/ #ifdef USED +/*N*/ long nFirstDiff; +/*N*/ +/*N*/ if( !Fix() ) +/*N*/ { +/*N*/ nFirstDiff = rInf.Left() - long( rInf.First() ); +/*N*/ if( rInf.GetLineStart() ) +/*N*/ { +/*N*/ if( nFirstDiff < 0 ) +/*N*/ nFirstDiff = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nFirstDiff > 0 ) +/*N*/ nFirstDiff = 0; +/*N*/ else +/*N*/ nFirstDiff = -nFirstDiff; +/*N*/ } +/*N*/ nFirstDiff += rInf.GetTxtFrm()->Prt().Left(); +/*N*/ } +/*N*/ else +/*N*/ nFirstDiff = 0; +/*N*/ PrtWidth( (Fix() - rInf.X()) + PrtWidth() + nFirstDiff ); +/*N*/ #else +/*N*/ PrtWidth( (Fix() - rInf.X()) + PrtWidth() ); +/*N*/ #endif +/*N*/ if( !Width() ) +/*N*/ { +/*N*/ ASSERT( Width(), "+SwFlyPortion::Format: a fly is a fly is a fly" ); +/*N*/ Width(1); +/*N*/ } +/*N*/ +/*N*/ // Restaurierung +/*N*/ rInf.SetFly( 0 ); +/*N*/ rInf.Width( rInf.RealWidth() ); +/*N*/ rInf.GetParaPortion()->SetFly( sal_True ); +/*N*/ +/*N*/ // trailing blank: +/*N*/ if( rInf.GetIdx() < rInf.GetTxt().Len() && 1 < rInf.GetIdx() +/*N*/ && !rInf.GetRest() +/*N*/ && ' ' == rInf.GetChar( rInf.GetIdx() ) +/*N*/ && ' ' != rInf.GetChar( rInf.GetIdx() - 1 ) +/*N*/ && ( !rInf.GetLast() || !rInf.GetLast()->IsBreakPortion() ) ) +/*N*/ { +/*N*/ SetBlankWidth( rInf.GetTxtSize( ' ' ).Width() ); +/*N*/ SetLen( 1 ); +/*N*/ } +/*N*/ +/*N*/ const KSHORT nNewWidth = rInf.X() + PrtWidth(); +/*N*/ if( rInf.Width() <= nNewWidth ) +/*N*/ { +/*N*/ Truncate(); +/*N*/ if( nNewWidth > rInf.Width() ) +/*N*/ { +/*N*/ PrtWidth( nNewWidth - rInf.Width() ); +/*N*/ SetFixWidth( PrtWidth() ); +/*N*/ } +/*N*/ return sal_True; +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * virtual SwFlyCntPortion::Format() + *************************************************************************/ +/*M*/ sal_Bool SwFlyCntPortion::Format( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ sal_Bool bFull = rInf.Width() < rInf.X() + PrtWidth(); +/*M*/ +/*M*/ if( bFull ) +/*M*/ { +/*M*/ // 3924: wenn die Zeile voll ist und der zeichengebundene Frame am +/*M*/ // Anfang der Zeile steht. +/*M*/ // 5157: nicht wenn einem Fly ausgewichen werden kann! +/*M*/ // "Begin of line" criteria ( ! rInf.X() ) has to be extended. +/*M*/ // KerningPortions at beginning of line, e.g., for grid layout +/*M*/ // must be considered. +/*M*/ const SwLinePortion* pLastPor = rInf.GetLast(); +/*M*/ const USHORT nLeft = ( pLastPor && +/*M*/ ( pLastPor->IsKernPortion() || +/*M*/ pLastPor->IsErgoSumPortion() ) ) ? +/*M*/ pLastPor->Width() : +/*M*/ 0; +/*M*/ +/*M*/ if( nLeft == rInf.X() && ! rInf.GetFly() ) +/*M*/ { +/*M*/ Width( rInf.Width() ); +/*M*/ bFull = sal_False; // Damit Notizen noch in dieser Zeile landen +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ if( !rInf.GetFly() ) +/*M*/ rInf.SetNewLine( sal_True ); +/*M*/ Width(0); +/*M*/ SetAscent(0); +/*M*/ SetLen(0); +/*M*/ if( rInf.GetLast() ) +/*M*/ rInf.GetLast()->FormatEOL( rInf ); +/*M*/ +/*M*/ return bFull; +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ rInf.GetParaPortion()->SetFly( sal_True ); +/*M*/ return bFull; +/*M*/ } + +/************************************************************************* + * SwTxtFrm::MoveFlyInCnt() haengt jetzt die zeichengebundenen Objekte + * innerhalb des angegebenen Bereichs um, damit koennen diese vom Master + * zum Follow oder umgekehrt wandern. + *************************************************************************/ +/*N*/ void SwTxtFrm::MoveFlyInCnt( SwTxtFrm *pNew, xub_StrLen nStart, xub_StrLen nEnd ) +/*N*/ { +/*N*/ SwDrawObjs *pObjs; +/*N*/ if ( 0 != (pObjs = GetDrawObjs()) ) +/*N*/ { +/*N*/ for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*pObjs)[MSHORT(i)]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( pFly->IsFlyInCntFrm() ) +/*N*/ { +/*?*/ const SwFmtAnchor &rAnch = pFly->GetFmt()->GetAnchor(); +/*?*/ const SwPosition *pPos = rAnch.GetCntntAnchor(); +/*?*/ xub_StrLen nIdx = pPos->nContent.GetIndex(); +/*?*/ if ( nIdx >= nStart && nEnd > nIdx ) +/*?*/ { +/*?*/ RemoveFly( pFly ); +/*?*/ pNew->AppendFly( pFly ); +/*?*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pO); +/*N*/ const SwFmtAnchor &rAnch = pContact->GetFmt()->GetAnchor(); +/*N*/ if ( FLY_IN_CNTNT == rAnch.GetAnchorId() ) +/*N*/ { +/*?*/ const SwPosition *pPos = rAnch.GetCntntAnchor(); +/*?*/ xub_StrLen nIdx = pPos->nContent.GetIndex(); +/*?*/ if ( nIdx >= nStart && nEnd > nIdx ) +/*?*/ { +/*?*/ RemoveDrawObj( pContact ); +/*?*/ pNew->AppendDrawObj( pContact ); +/*?*/ --i; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcFlyPos() + *************************************************************************/ +/*N*/ xub_StrLen SwTxtFrm::CalcFlyPos( SwFrmFmt* pSearch ) +/*N*/ { +/*N*/ SwpHints* pHints = GetTxtNode()->GetpSwpHints(); +/*N*/ ASSERT( pHints, "CalcFlyPos: Why me?" ); +/*N*/ if( !pHints ) +/*N*/ return STRING_LEN; +/*N*/ SwTxtAttr* pFound = NULL; +/*N*/ for( MSHORT i = 0; i < pHints->Count(); i++) +/*N*/ { +/*N*/ SwTxtAttr *pHt = pHints->GetHt( i ); +/*N*/ if( RES_TXTATR_FLYCNT == pHt->Which() ) +/*N*/ { +/*N*/ SwFrmFmt* pFrmFmt = pHt->GetFlyCnt().GetFrmFmt(); +/*N*/ if( pFrmFmt == pSearch ) +/*N*/ pFound = pHt; +/*N*/ } +/*N*/ } +/*N*/ ASSERT( pHints, "CalcFlyPos: Not Found!" ); +/*N*/ if( !pFound ) +/*N*/ return STRING_LEN; +/*N*/ return *pFound->GetStart(); +/*N*/ } + +/************************************************************************* + * virtual SwFlyCntPortion::Paint() + *************************************************************************/ + +/************************************************************************* + * SwFlyCntPortion::SwFlyCntPortion() + * + * Es werden die Masze vom pFly->OutRect() eingestellt. + * Es erfolgt ein SetBase() ! + *************************************************************************/ +/*N*/ SwFlyCntPortion::SwFlyCntPortion( const SwTxtFrm& rFrm, +/*N*/ SwFlyInCntFrm *pFly, const Point &rBase, +/*N*/ long nLnAscent, long nLnDescent, +/*N*/ long nFlyAsc, long nFlyDesc, sal_uInt8 nFlags ) : +/*N*/ pContact( pFly ), +/*N*/ bDraw( sal_False ), +/*N*/ bMax( sal_False ), +/*N*/ nAlign( 0 ) +/*N*/ { +/*N*/ ASSERT( pFly, "SwFlyCntPortion::SwFlyCntPortion: no SwFlyInCntFrm!" ); +/*N*/ nLineLength = 1; +/*N*/ nFlags |= SETBASE_ULSPACE | SETBASE_INIT; +/*N*/ SetBase( rFrm, rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags ); +/*N*/ SetWhichPor( POR_FLYCNT ); +/*N*/ } + +/*N*/ SwFlyCntPortion::SwFlyCntPortion( const SwTxtFrm& rFrm, +/*N*/ SwDrawContact *pDrawContact, const Point &rBase, +/*N*/ long nLnAscent, long nLnDescent, long nFlyAsc, +/*N*/ long nFlyDesc, sal_uInt8 nFlags ) : +/*N*/ pContact( pDrawContact ), +/*N*/ bDraw( sal_True ), +/*N*/ bMax( sal_False ), +/*N*/ nAlign( 0 ) +/*N*/ { +/*N*/ ASSERT( pDrawContact, "SwFlyCntPortion::SwFlyCntPortion: no SwDrawContact!" ); +/*N*/ if( !pDrawContact->GetAnchor() ) +/*N*/ { +/*N*/ if( nFlags & SETBASE_QUICK ) +/*N*/ { +/*N*/ Point aAnchorPos = pDrawContact->GetMaster()->GetAnchorPos(); +/*N*/ pDrawContact->ConnectToLayout(); +/*N*/ pDrawContact->GetMaster()->SetAnchorPos( aAnchorPos ); +/*N*/ } +/*N*/ else +/*N*/ pDrawContact->ConnectToLayout(); +/*N*/ } +/*N*/ nLineLength = 1; +/*N*/ nFlags |= SETBASE_ULSPACE | SETBASE_INIT; +/*N*/ +/*N*/ SetBase( rFrm, rBase, nLnAscent, nLnDescent, nFlyAsc, nFlyDesc, nFlags ); +/*N*/ +/*N*/ SetWhichPor( POR_FLYCNT ); +/*N*/ } + +/*N*/ const SwFrmFmt *SwFlyCntPortion::GetFrmFmt() const +/*N*/ { +/*N*/ if( bDraw ) +/*N*/ return GetDrawContact()->GetFmt(); +/*N*/ else +/*N*/ return GetFlyFrm()->GetFmt(); +/*N*/ } + +/************************************************************************* + * SwFlyCntPortion::SetBase() + * + * Nach dem Setzen des RefPoints muss der Ascent neu berechnet werden, + * da er von der RelPos abhaengt. + * pFly->GetRelPos().Y() bezeichnet die relative Position zur Baseline. + * Bei 0 liegt der obere Rand des FlyCnt auf der Baseline der Zeile. + *************************************************************************/ + +/*N*/ void SwFlyCntPortion::SetBase( const SwTxtFrm& rFrm, const Point &rBase, +/*N*/ long nLnAscent, long nLnDescent, long nFlyAsc, +/*N*/ long nFlyDesc, sal_uInt8 nFlags ) +/*N*/ { +/*N*/ // Note: rBase is an absolute value +/*N*/ SWAP_IF_SWAPPED( (&rFrm ) ) +/*N*/ SWRECTFN( (&rFrm ) ) +/*N*/ Point aBase( rBase ); +/*N*/ const SwFrmFmt* pFmt = GetFrmFmt(); +/*N*/ const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); +/*N*/ const SwVertOrient eOri = rVert.GetVertOrient(); +/*N*/ const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace(); +/*N*/ const SvxULSpaceItem &rULSpace = pFmt->GetULSpace(); +/*N*/ +/*N*/ //Die vertikale Position wird berechnet, die relative horizontale +/*N*/ //Position ist stets 0. +/*N*/ +/*N*/ SdrObject *pSdrObj; +/*N*/ SwRect aBoundRect; +/*N*/ long nOldWidth; +/*N*/ if( bDraw ) +/*N*/ { +/*N*/ // OD 20.06.2003 #108784# - determine drawing object ('master' or 'virtual') +/*N*/ // by frame. +/*N*/ pSdrObj = GetDrawContact()->GetDrawObjectByAnchorFrm( rFrm ); +/*N*/ if ( !pSdrObj ) +/*N*/ { +/*N*/ ASSERT( false, "SwFlyCntPortion::SetBase(..) - No drawing object found by <GetDrawContact()->GetDrawObjectByAnchorFrm( rFrm )>" ); +/*N*/ pSdrObj = GetDrawContact()->GetMaster(); +/*N*/ } +/*N*/ aBoundRect = pSdrObj->GetBoundRect(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aBoundRect = GetFlyFrm()->Frm(); +/*N*/ nOldWidth = aBoundRect.Width(); +/*N*/ } +/*N*/ +/*N*/ nOldWidth = (aBoundRect.*fnRect->fnGetWidth)(); +/*N*/ +/*N*/ long nLRSpaceLeft, nLRSpaceRight, nULSpaceUpper, nULSpaceLower; +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ { +/*N*/ // Seems to be easier to do it all the horizontal way +/*N*/ // So, from now on think horizontal. +/*N*/ rFrm.SwitchVerticalToHorizontal( aBoundRect ); +/*N*/ rFrm.SwitchVerticalToHorizontal( aBase ); +/*N*/ +/*N*/ // convert the spacing values +/*N*/ nLRSpaceLeft = rULSpace.GetUpper(); +/*N*/ nLRSpaceRight = rULSpace.GetLower(); +/*N*/ nULSpaceUpper = rLRSpace.GetRight(); +/*N*/ nULSpaceLower = rLRSpace.GetLeft(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if ( rFrm.IsRightToLeft() ) +/*N*/ { +/*N*/ nLRSpaceLeft = rLRSpace.GetRight(); +/*N*/ nLRSpaceRight = rLRSpace.GetLeft(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nLRSpaceLeft = rLRSpace.GetLeft(); +/*N*/ nLRSpaceRight = rLRSpace.GetRight(); +/*N*/ } +/*N*/ +/*N*/ nULSpaceUpper = rULSpace.GetUpper(); +/*N*/ nULSpaceLower = rULSpace.GetLower(); +/*N*/ } +/*N*/ +/*N*/ if( nFlags & SETBASE_ULSPACE ) +/*N*/ aBase.X() += nLRSpaceLeft; +/*N*/ aBase.Y() += nULSpaceUpper; +/*N*/ +/*N*/ if( bDraw ) +/*N*/ { +/*N*/ SwRect aSnapRect = pSdrObj->GetSnapRect(); +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ rFrm.SwitchVerticalToHorizontal( aSnapRect ); +/*N*/ +/*N*/ if( nFlags & SETBASE_ULSPACE ) +/*N*/ aBase.X() += aSnapRect.Left() - aBoundRect.Left(); +/*N*/ aBase.Y() += aSnapRect.Top() - aBoundRect.Top(); +/*N*/ } +/*N*/ +/*N*/ aBoundRect.Left( aBoundRect.Left() - nLRSpaceLeft ); +/*N*/ aBoundRect.Width( aBoundRect.Width() + nLRSpaceRight ); +/*N*/ aBoundRect.Top( aBoundRect.Top() - nULSpaceUpper ); +/*N*/ aBoundRect.Height( aBoundRect.Height() + nULSpaceLower ); +/*N*/ +/*N*/ SwTwips nBoundHeight = ( nFlags & SETBASE_ROTATE ) ? +/*N*/ aBoundRect.Width() : aBoundRect.Height(); +/*N*/ SwTwips nRelPos = 0; +/*N*/ if ( eOri == VERT_NONE ) +/*N*/ nRelPos = rVert.GetPos(); +/*N*/ else +/*N*/ { +/*N*/ nRelPos = 0; +/*N*/ if ( eOri == VERT_CENTER ) +/*N*/ nRelPos -= nBoundHeight / 2; +/*N*/ else if ( eOri == VERT_TOP ) +/*N*/ nRelPos -= nBoundHeight; +/*N*/ else if ( eOri == VERT_BOTTOM ) +/*N*/ ; +/*N*/ else if ( eOri == VERT_CHAR_CENTER ) +/*N*/ nRelPos -= ( nBoundHeight + nLnAscent - nLnDescent ) / 2; +/*N*/ else if ( eOri == VERT_CHAR_TOP ) +/*N*/ nRelPos -= nLnAscent; +/*N*/ else if ( eOri == VERT_CHAR_BOTTOM ) +/*N*/ nRelPos += nLnDescent - nBoundHeight; +/*N*/ else +/*N*/ { +/*N*/ if( nBoundHeight >= nFlyAsc + nFlyDesc ) +/*N*/ { +/*N*/ // wenn ich genauso gross bin wie die Zeile, brauche ich mich +/*N*/ // nicht an der Zeile nicht weiter ausrichten, ich lasse +/*N*/ // dann auch den max. Ascent der Zeile zunaechst unveraendert +/*N*/ nRelPos -= nFlyAsc; +/*N*/ if ( eOri == VERT_LINE_CENTER ) +/*N*/ SetAlign( 2 ); +/*N*/ else if ( eOri == VERT_LINE_TOP ) +/*N*/ SetAlign( 1 ); +/*N*/ else if ( eOri == VERT_LINE_BOTTOM ) +/*N*/ SetAlign( 3 ); +/*N*/ } +/*N*/ else if ( eOri == VERT_LINE_CENTER ) +/*N*/ { +/*N*/ nRelPos -= ( nBoundHeight +nFlyAsc -nFlyDesc ) / 2; +/*N*/ SetAlign( 2 ); +/*N*/ } +/*N*/ else if ( eOri == VERT_LINE_TOP ) +/*N*/ { +/*N*/ nRelPos -= nFlyAsc; +/*N*/ SetAlign( 1 ); +/*N*/ } +/*N*/ else if ( eOri == VERT_LINE_BOTTOM ) +/*N*/ { +/*N*/ nRelPos += nFlyDesc - nBoundHeight; +/*N*/ SetAlign( 3 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nFlags & SETBASE_INIT && nRelPos < 0 && nFlyAsc < -nRelPos ) +/*N*/ { +/*N*/ if( nFlags & SETBASE_ROTATE ) +/*N*/ aBase.X() -= nFlyAsc + nRelPos; +/*N*/ else +/*N*/ aBase.Y() -= nFlyAsc + nRelPos; +/*N*/ } +/*N*/ +/*N*/ if( nFlags & SETBASE_BIDI ) +/*N*/ aBase.X() -= aBoundRect.Width(); +/*N*/ +/*N*/ Point aRelPos; +/*N*/ if( nFlags & SETBASE_ROTATE ) +/*N*/ { +/*N*/ if( nFlags & SETBASE_REVERSE ) +/*N*/ aRelPos.X() = -nRelPos - aBoundRect.Width(); +/*N*/ else +/*N*/ { +/*N*/ aRelPos.X() = nRelPos; +/*N*/ aRelPos.Y() = -aBoundRect.Height(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ aRelPos.Y() = nRelPos; +/*N*/ if( bDraw ) +/*N*/ { +/*N*/ if( !( nFlags & SETBASE_QUICK ) ) +/*N*/ { +/*N*/ if( rVert.GetPos() != nRelPos && eOri != VERT_NONE ) +/*N*/ { +/*N*/ // Das aRelPos wird gepflegt, weil sonst SwDrawContact::_Changed +/*N*/ // auf die Idee kommen koennte, auf VERT_NONE umzuschalten. +/*N*/ SwFmtVertOrient aVert( rVert ); +/*N*/ aVert.SetPos( nRelPos ); +/*N*/ ((SwFrmFmt*)pFmt)->LockModify(); +/*N*/ ((SwFrmFmt*)pFmt)->SetAttr( aVert ); +/*N*/ ((SwFrmFmt*)pFmt)->UnlockModify(); +/*N*/ } +/*N*/ Point aAnchorBase( aBase ); +/*N*/ if ( rFrm.IsRightToLeft() ) +/*N*/ { +/*N*/ rFrm.SwitchLTRtoRTL( aAnchorBase ); +/*N*/ aAnchorBase.X() -= nOldWidth; +/*N*/ } +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ rFrm.SwitchHorizontalToVertical( aAnchorBase ); +/*N*/ +/*N*/ // OD 20.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ if ( pSdrObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pSdrObj); +/*N*/ +/*N*/ pDrawVirtObj->NbcSetAnchorPos( aAnchorBase ); +/*N*/ pDrawVirtObj->AdjustRelativePosToReference(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // There used to be a ImpSetAnchorPos here. Very dangerous +/*N*/ // for group object. +/*N*/ pSdrObj->NbcSetAnchorPos( aAnchorBase ); +/*N*/ // OD 20.06.2003 #108784# - correct movement of 'virtual' drawing +/*N*/ // objects caused by the <SetAnchorPos(..)> of the 'master' drawing object. +/*N*/ GetDrawContact()->CorrectRelativePosOfVirtObjs(); +/*N*/ } +/*N*/ +/*N*/ SwRect aSnapRect = pSdrObj->GetSnapRect(); +/*N*/ +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ rFrm.SwitchVerticalToHorizontal( aSnapRect ); +/*N*/ +/*N*/ Point aDiff; +/*N*/ if ( rFrm.IsRightToLeft() ) +/*N*/ aDiff = aRelPos + aAnchorBase - aSnapRect.TopLeft(); +/*N*/ else +/*N*/ aDiff = aRelPos + aBase - aSnapRect.TopLeft(); +/*N*/ +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ aDiff = Point( -aDiff.Y(), aDiff.X() ); +/*N*/ +/*N*/ // OD 20.06.2003 #108784# - consider 'virtual' drawing objects +/*N*/ if ( !pSdrObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ // #80046# here a Move() is necessary, a NbcMove() is NOT ENOUGH(!) +/*N*/ pSdrObj->Move( Size( aDiff.X(), aDiff.Y() ) ); +/*N*/ // OD 23.06.2003 #108784# - correct movement of 'virtual' drawing +/*N*/ // objects caused by the <Move(..)> of the 'master' drawing object +/*N*/ GetDrawContact()->MoveOffsetOfVirtObjs( Size( -aDiff.X(), -aDiff.Y() ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ rFrm.SwitchHorizontalToVertical( aBase ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Point aRelAttr; +/*N*/ if ( rFrm.IsRightToLeft() ) +/*N*/ { +/*N*/ rFrm.SwitchLTRtoRTL( aBase ); +/*N*/ aBase.X() -= nOldWidth; +/*N*/ } +/*N*/ if ( rFrm.IsVertical() ) +/*N*/ { +/*N*/ rFrm.SwitchHorizontalToVertical( aBase ); +/*N*/ aRelAttr = Point( -nRelPos, 0 ); +/*N*/ aRelPos = Point( -aRelPos.Y(), aRelPos.X() ); +/*N*/ } +/*N*/ else +/*N*/ aRelAttr = Point( 0, nRelPos ); +/*N*/ +/*N*/ if ( !(nFlags & SETBASE_QUICK) && (aBase != GetFlyFrm()->GetRefPoint() || +/*N*/ aRelAttr != GetFlyFrm()->GetCurRelPos()) ) +/*N*/ { +/*N*/ GetFlyFrm()->SetRefPoint( aBase, aRelAttr, aRelPos ); +/*N*/ if( nOldWidth != (GetFlyFrm()->Frm().*fnRect->fnGetWidth)() ) +/*N*/ { +/*N*/ aBoundRect = GetFlyFrm()->Frm(); +/*N*/ aBoundRect.Left( aBoundRect.Left() - rLRSpace.GetLeft() ); +/*N*/ aBoundRect.Width( aBoundRect.Width() + rLRSpace.GetRight() ); +/*N*/ aBoundRect.Top( aBoundRect.Top() - rULSpace.GetUpper() ); +/*N*/ aBoundRect.Height( aBoundRect.Height() + rULSpace.GetLower() ); +/*N*/ } +/*N*/ } +/*N*/ ASSERT( (GetFlyFrm()->Frm().*fnRect->fnGetHeight)(), +/*N*/ "SwFlyCntPortion::SetBase: flyfrm has an invalid height" ); +/*N*/ } +/*N*/ aRef = aBase; +/*N*/ if( nFlags & SETBASE_ROTATE ) +/*N*/ SvXSize( aBoundRect.SSize() ); +/*N*/ else +/*N*/ SvLSize( aBoundRect.SSize() ); +/*N*/ if( Height() ) +/*N*/ { +/*N*/ if ( nRelPos < 0 ) +/*N*/ { +/*N*/ nAscent = Abs( int( nRelPos ) ); +/*N*/ if( nAscent > Height() ) +/*N*/ Height( nAscent ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nAscent = 0; +/*N*/ Height( Height() + int( nRelPos ) ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Height( 1 ); +/*N*/ nAscent = 0; +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( ( &rFrm ) ) +/*N*/ } + +/************************************************************************* + * virtual SwFlyCntPortion::GetFlyCrsrOfst() + *************************************************************************/ + + +/************************************************************************* + * virtual SwFlyCntPortion::GetCrsrOfst() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porglue.cxx b/binfilter/bf_sw/source/core/text/sw_porglue.cxx new file mode 100644 index 000000000000..c041e8ff6548 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porglue.cxx @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "paratr.hxx" // pTabStop, ADJ* + + +#include "txtcfg.hxx" +#include "porlay.hxx" // SwParaPortion, SetFull +#include "porfly.hxx" // SwParaPortion, SetFull +namespace binfilter { + +/************************************************************************* + * class SwGluePortion + *************************************************************************/ + +/*N*/ SwGluePortion::SwGluePortion( const KSHORT nInitFixWidth ) +/*N*/ : nFixWidth( nInitFixWidth ) +/*N*/ { +/*N*/ PrtWidth( nFixWidth ); +/*N*/ SetWhichPor( POR_GLUE ); +/*N*/ } + +/************************************************************************* + * virtual SwGluePortion::GetCrsrOfst() + *************************************************************************/ + + +/************************************************************************* + * virtual SwGluePortion::GetTxtSize() + *************************************************************************/ + + +/************************************************************************* + * virtual SwGluePortion::GetExpTxt() + *************************************************************************/ + + +/************************************************************************* + * virtual SwGluePortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * SwGluePortion::MoveGlue() + *************************************************************************/ + +/*N*/ void SwGluePortion::MoveGlue( SwGluePortion *pTarget, const short nPrtGlue ) +/*N*/ { +/*N*/ short nPrt = Min( nPrtGlue, GetPrtGlue() ); +/*N*/ if( 0 < nPrt ) +/*N*/ { +/*N*/ pTarget->AddPrtWidth( nPrt ); +/*N*/ SubPrtWidth( nPrt ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * void SwGluePortion::Join() + *************************************************************************/ + +/*N*/ void SwGluePortion::Join( SwGluePortion *pVictim ) +/*N*/ { +/*N*/ // Die GluePortion wird ausgesogen und weggespuelt ... +/*N*/ AddPrtWidth( pVictim->PrtWidth() ); +/*N*/ SetLen( pVictim->GetLen() + GetLen() ); +/*N*/ if( Height() < pVictim->Height() ) +/*N*/ Height( pVictim->Height() ); +/*N*/ +/*N*/ AdjFixWidth(); +/*N*/ Cut( pVictim ); +/*N*/ delete pVictim; +/*N*/ } + +/************************************************************************* + * class SwFixPortion + *************************************************************************/ + +// Wir erwarten ein framelokales SwRect ! +/*N*/ SwFixPortion::SwFixPortion( const SwRect &rRect ) +/*N*/ :SwGluePortion( KSHORT(rRect.Width()) ), nFix( KSHORT(rRect.Left()) ) +/*N*/ { +/*N*/ Height( KSHORT(rRect.Height()) ); +/*N*/ SetWhichPor( POR_FIX ); +/*N*/ } +/*N*/ +/*N*/ SwFixPortion::SwFixPortion(const KSHORT nFixWidth, const KSHORT nFixPos) +/*N*/ : SwGluePortion(nFixWidth), nFix(nFixPos) +/*N*/ { +/*N*/ SetWhichPor( POR_FIX ); +/*N*/ } + +/************************************************************************* + * class SwMarginPortion + *************************************************************************/ + +/*N*/ SwMarginPortion::SwMarginPortion( const KSHORT nFixWidth ) +/*N*/ :SwGluePortion( nFixWidth ) +/*N*/ { +/*N*/ SetWhichPor( POR_MARGIN ); +/*N*/ } + +/************************************************************************* + * SwMarginPortion::AdjustRight() + * + * In der umschliessenden Schleife werden alle Portions durchsucht, + * dabei werden erst die am Ende liegenden GluePortions verarbeitet. + * Das Ende wird nach jeder Schleife nach vorne verlegt, bis keine + * GluePortions mehr vorhanden sind. + * Es werden immer GluePortion-Paare betrachtet (pLeft und pRight), + * wobei Textportions zwischen pLeft und pRight hinter pRight verschoben + * werden, wenn pRight genuegend Glue besitzt. Bei jeder Verschiebung + * wandert ein Teil des Glues von pRight nach pLeft. + * Im naechsten Schleifendurchlauf ist pLeft das pRight und das Spiel + * beginnt von vorne. + *************************************************************************/ + +/*N*/ void SwMarginPortion::AdjustRight( const SwLineLayout *pCurr ) +/*N*/ { +/*N*/ SwGluePortion *pRight = 0; +/*N*/ BOOL bNoMove = 0 != pCurr->GetpKanaComp(); +/*N*/ while( pRight != this ) +/*N*/ { +/*N*/ +/*N*/ // 1) Wir suchen den linken Glue +/*N*/ SwLinePortion *pPos = (SwLinePortion*)this; +/*N*/ SwGluePortion *pLeft = 0; +/*N*/ while( pPos ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if( pPos->InFixMargGrp() ) +/*N*/ pLeft = (SwGluePortion*)pPos; +/*N*/ pPos = pPos->GetPortion(); +/*N*/ if( pPos == pRight) +/*N*/ pPos = 0; +/*N*/ } +/*N*/ +/*N*/ // Zwei nebeneinander liegende FlyPortions verschmelzen +/*N*/ if( pRight && pLeft->GetPortion() == pRight ) +/*N*/ { +/*?*/ pRight->MoveAllGlue( pLeft ); +/*?*/ pRight = 0; +/*N*/ } +/*N*/ KSHORT nRightGlue = pRight && 0 < pRight->GetPrtGlue() +/*N*/ ? KSHORT(pRight->GetPrtGlue()) : 0; +/*N*/ // 2) linken und rechten Glue ausgleichen +/*N*/ // Bei Tabs haengen wir nix um ... +/*N*/ if( pLeft && nRightGlue && !pRight->InTabGrp() ) +/*N*/ { +/*?*/ // pPrev ist die Portion, die unmittelbar vor pRight liegt. +/*?*/ SwLinePortion *pPrev = pRight->FindPrevPortion( pLeft ); +/*?*/ +/*?*/ if ( pRight->IsFlyPortion() && pRight->GetLen() ) +/*?*/ { +/*?*/ SwFlyPortion *pFly = (SwFlyPortion *)pRight; +/*?*/ if ( pFly->GetBlankWidth() < nRightGlue ) +/*?*/ { +/*?*/ // Hier entsteht eine neue TxtPortion, die dass zuvor +/*?*/ // vom Fly verschluckte Blank reaktiviert. +/*?*/ nRightGlue -= pFly->GetBlankWidth(); +/*?*/ pFly->SubPrtWidth( pFly->GetBlankWidth() ); +/*?*/ pFly->SetLen( 0 ); +/*?*/ SwTxtPortion *pNewPor = new SwTxtPortion; +/*?*/ pNewPor->SetLen( 1 ); +/*?*/ pNewPor->Height( pFly->Height() ); +/*?*/ pNewPor->Width( pFly->GetBlankWidth() ); +/*?*/ pFly->Insert( pNewPor ); +/*?*/ } +/*?*/ else +/*?*/ pPrev = pLeft; +/*?*/ } +/*?*/ while( pPrev != pLeft ) +/*?*/ { +///*?*/ DBG_LOOP; +/*?*/ +/*?*/ if( bNoMove || pPrev->PrtWidth() >= nRightGlue || +/*?*/ pPrev->InHyphGrp() || pPrev->IsKernPortion() ) +/*?*/ { +/*?*/ // Die Portion, die vor pRight liegt kann nicht +/*?*/ // verschoben werden, weil kein Glue mehr vorhanden ist. +/*?*/ // Wir fuehren die Abbruchbedingung herbei: +/*?*/ pPrev = pLeft; +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ nRightGlue -= pPrev->PrtWidth(); +/*?*/ // pPrev wird hinter pRight verschoben. +/*?*/ // Dazu wird der Gluewert zwischen pRight und pLeft +/*?*/ // ausgeglichen. +/*?*/ pRight->MoveGlue( pLeft, short( pPrev->PrtWidth() ) ); +/*?*/ // Jetzt wird die Verkettung gerichtet. +/*?*/ SwLinePortion *pPrevPrev = pPrev->FindPrevPortion( pLeft ); +/*?*/ pPrevPrev->SetPortion( pRight ); +/*?*/ pPrev->SetPortion( pRight->GetPortion() ); +/*?*/ pRight->SetPortion( pPrev ); +/*?*/ if ( pPrev->GetPortion() && pPrev->InTxtGrp() +/*?*/ && pPrev->GetPortion()->IsHolePortion() ) +/*?*/ { +/*?*/ SwHolePortion *pHolePor = +/*?*/ (SwHolePortion*)pPrev->GetPortion(); +/*?*/ if ( !pHolePor->GetPortion() || +/*?*/ !pHolePor->GetPortion()->InFixMargGrp() ) +/*?*/ { +/*?*/ pPrev->AddPrtWidth( pHolePor->GetBlankWidth() ); +/*?*/ pPrev->SetLen( pPrev->GetLen() + 1 ); +/*?*/ pPrev->SetPortion( pHolePor->GetPortion() ); +/*?*/ delete pHolePor; +/*?*/ } +/*?*/ } +/*?*/ pPrev = pPrevPrev; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ // Wenn es keinen linken Glue mehr gibt, wird die Abbruchbedingung +/*N*/ // herbeigefuehrt. +/*N*/ pRight = pLeft ? pLeft : (SwGluePortion*)this; +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porlay.cxx b/binfilter/bf_sw/source/core/text/sw_porlay.cxx new file mode 100644 index 000000000000..5306c31e55d3 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porlay.cxx @@ -0,0 +1,1186 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "txtcfg.hxx" +#include "itrform2.hxx" +#include "redlnitr.hxx" // SwRedlineItr +#include "porfly.hxx" // SwFlyCntPortion +#include <porrst.hxx> // SwHangingPortion +#include <pormulti.hxx> // SwMultiPortion +#include <breakit.hxx> +#include <com/sun/star/i18n/ScriptType.hdl> +#include <com/sun/star/i18n/WordType.hdl> + +#include <horiornt.hxx> + +#include <doc.hxx> +#ifdef BIDI +#include <paratr.hxx> +#include <bf_svx/adjitem.hxx> +#endif +#include <bf_svx/scripttypeitem.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::i18n::ScriptType; + +#ifdef BIDI +#include <unicode/ubidi.h> +namespace binfilter { + +/************************************************************************* + * lcl_IsLigature + * + * Checks if cCh + cNectCh builds a ligature (used for Kashidas) + *************************************************************************/ + + +/************************************************************************* + * lcl_ConnectToPrev + * + * Checks if cCh is connectable to cPrevCh (used for Kashidas) + *************************************************************************/ + + +#endif + + +/************************************************************************* + * SwLineLayout::~SwLineLayout() + * + * class SwLineLayout: Das Layout einer einzelnen Zeile. Dazu + * gehoeren vor allen Dingen die Dimension, die Anzahl der + * Character und der Wortzwischenraeume in der Zeile. + * Zeilenobjekte werden in einem eigenen Pool verwaltet, um zu + * erreichen, dass sie im Speicher moeglichst beeinander liegen + * (d.h. zusammen gepaged werden und den Speicher nicht + * fragmentieren). + *************************************************************************/ + +/*N*/ SwLineLayout::~SwLineLayout() +/*N*/ { +/*N*/ Truncate(); +/*N*/ if( GetNext() ) +/*N*/ delete GetNext(); +/*N*/ delete pSpaceAdd; +/*N*/ if ( pKanaComp ) +/*?*/ delete pKanaComp; +/*N*/ } + +/************************************************************************* + * virtual SwLineLayout::Insert() + *************************************************************************/ + +SwLinePortion *SwLineLayout::Insert( SwLinePortion *pIns ) +/*N*/ { +/*N*/ // Erster Attributwechsel, Masse und Laengen +/*N*/ // aus *pCurr in die erste Textportion kopieren. +/*N*/ if( !pPortion ) +/*N*/ { +/*N*/ if( GetLen() ) +/*N*/ { +/*N*/ pPortion = new SwTxtPortion( *(SwLinePortion*)this ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetPortion( pIns ); +/*N*/ return pIns; +/*N*/ } +/*N*/ } +/*N*/ // mit Skope aufrufen, sonst Rekursion ! +/*N*/ return pPortion->SwLinePortion::Insert( pIns ); +/*N*/ } + +/************************************************************************* + * virtual SwLineLayout::Append() + *************************************************************************/ + + +/************************************************************************* + * virtual SwLineLayout::Format() + *************************************************************************/ + +// fuer die Sonderbehandlung bei leeren Zeilen + +/*N*/ sal_Bool SwLineLayout::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( GetLen() ) +/*N*/ return SwTxtPortion::Format( rInf ); +/*N*/ else +/*N*/ { +/*?*/ Height( rInf.GetTxtHeight() ); +/*?*/ return sal_True; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwLineLayout::CalcLeftMargin() + * + * Wir sammeln alle FlyPortions am Anfang der Zeile zu einer MarginPortion. + *************************************************************************/ + +/*N*/ SwMarginPortion *SwLineLayout::CalcLeftMargin() +/*N*/ { +/*N*/ SwMarginPortion *pLeft = (GetPortion() && GetPortion()->IsMarginPortion()) ? +/*N*/ (SwMarginPortion *)GetPortion() : 0; +/*N*/ if( !GetPortion() ) +/*N*/ SetPortion( new SwTxtPortion( *(SwLinePortion*)this ) ); +/*N*/ if( !pLeft ) +/*N*/ { +/*N*/ pLeft = new SwMarginPortion( 0 ); +/*N*/ pLeft->SetPortion( GetPortion() ); +/*N*/ SetPortion( pLeft ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ pLeft->Height( 0 ); +/*?*/ pLeft->Width( 0 ); +/*?*/ pLeft->SetLen( 0 ); +/*?*/ pLeft->SetAscent( 0 ); +/*?*/ pLeft->SetPortion( NULL ); +/*?*/ pLeft->SetFixWidth(0); +/*N*/ } +/*N*/ +/*N*/ SwLinePortion *pPos = pLeft->GetPortion(); +/*N*/ while( pPos ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if( pPos->IsFlyPortion() ) +/*N*/ { +/*N*/ // Die FlyPortion wird ausgesogen ... +/*N*/ pLeft->Join( (SwGluePortion*)pPos ); +/*N*/ pPos = pLeft->GetPortion(); +/*N*/ if( GetpKanaComp() ) +/*N*/ GetKanaComp().Remove( 0, 1 ); +/*N*/ } +/*N*/ else +/*N*/ pPos = 0; +/*N*/ } +/*N*/ return pLeft; +/*N*/ } + +/************************************************************************* + * SwLineLayout::CreateSpaceAdd() + *************************************************************************/ + +/*N*/ void SwLineLayout::CreateSpaceAdd( const short nInit ) +/*N*/ { +/*N*/ pSpaceAdd = new SvShorts; +/*N*/ pSpaceAdd->Insert( nInit, 0 ); +/*N*/ } + +/************************************************************************* + * SwLineLayout::CalcLine() + * + * Aus FormatLine() ausgelagert. + *************************************************************************/ + +/*N*/ void SwLineLayout::CalcLine( SwTxtFormatter &rLine, SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ const KSHORT nLineWidth = rInf.RealWidth(); +/*N*/ +/*N*/ KSHORT nFlyAscent; +/*N*/ KSHORT nFlyHeight; +/*N*/ KSHORT nFlyDescent; +/*N*/ sal_Bool bOnlyPostIts = sal_True; +/*N*/ SetHanging( sal_False ); +/*N*/ +/*N*/ sal_Bool bTmpDummy = ( 0 == GetLen() ); +/*N*/ SwFlyCntPortion* pFlyCnt = 0; +/*N*/ if( bTmpDummy ) +/*N*/ { +/*N*/ nFlyAscent = 0; +/*N*/ nFlyHeight = 0; +/*N*/ nFlyDescent = 0; +/*N*/ } +/*N*/ +/*N*/ if( pPortion ) +/*N*/ { +/*N*/ SetCntnt( sal_False ); +/*N*/ if( pPortion->IsBreakPortion() ) +/*N*/ { +/*N*/ SetLen( pPortion->GetLen() ); +/*N*/ if( GetLen() ) +/*N*/ bTmpDummy = sal_False; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Init( GetPortion() ); +/*N*/ SwLinePortion *pPos = pPortion; +/*N*/ SwLinePortion *pLast = this; +/*N*/ KSHORT nMaxDescent = 0; +/*N*/ +/*N*/ // Eine Gruppe ist ein Abschnitt in der Portion-Kette von +/*N*/ // pCurr oder einer Fix-Portion bis zum Ende bzw. zur naechsten +/*N*/ // Fix-Portion. +/*N*/ while( pPos ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ ASSERT( POR_LIN != pPos->GetWhichPor(), +/*N*/ "SwLineLayout::CalcLine: don't use SwLinePortions !" ); +/*N*/ // Null-Portions werden eliminiert. Sie koennen entstehen, +/*N*/ // wenn zwei FlyFrms ueberlappen. +/*N*/ if( !pPos->Compress() ) +/*N*/ { +/*N*/ // 8110: Hoehe und Ascent nur uebernehmen, wenn sonst in der +/*N*/ // Zeile nichts mehr los ist. +/*N*/ if( !pPos->GetPortion() ) +/*N*/ { +/*N*/ if( !Height() ) +/*N*/ Height( pPos->Height() ); +/*N*/ if( !GetAscent() ) +/*N*/ SetAscent( pPos->GetAscent() ); +/*N*/ } +/*N*/ delete pLast->Cut( pPos ); +/*N*/ pPos = pLast->GetPortion(); +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ // Es gab Attributwechsel: Laengen und Masse aufaddieren; +/*N*/ // bzw.Maxima bilden. +/*N*/ +/*N*/ nLineLength += pPos->GetLen(); +/*N*/ +/*N*/ KSHORT nPosHeight = pPos->Height(); +/*N*/ KSHORT nPosAscent = pPos->GetAscent(); +/*N*/ AddPrtWidth( pPos->Width() ); +/*N*/ +/*N*/ ASSERT( nPosHeight >= nPosAscent, +/*N*/ "SwLineLayout::CalcLine: bad ascent or height" ); +/*N*/ if( pPos->IsHangingPortion() ) +/*N*/ { +/*?*/ SetHanging( sal_True ); +/*?*/ rInf.GetParaPortion()->SetMargin( sal_True ); +/*N*/ } +/*N*/ +/*N*/ // Damit ein Paragraphende-Zeichen nicht durch ein Descent zu einer +/*N*/ // geaenderten Zeilenhoehe und zum Umformatieren fuehrt. +/*N*/ if ( !pPos->IsBreakPortion() || !Height() ) +/*N*/ { +/*N*/ bOnlyPostIts &= pPos->IsPostItsPortion(); +/*N*/ if( bTmpDummy && !nLineLength ) +/*N*/ { +/*N*/ if( pPos->IsFlyPortion() ) +/*N*/ { +/*N*/ if( nFlyHeight < nPosHeight ) +/*N*/ nFlyHeight = nPosHeight; +/*N*/ if( nFlyAscent < nPosAscent ) +/*N*/ nFlyAscent = nPosAscent; +/*N*/ if( nFlyDescent < nPosHeight - nPosAscent ) +/*N*/ nFlyDescent = nPosHeight - nPosAscent; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pPos->InNumberGrp() ) +/*N*/ { +/*N*/ KSHORT nTmp = rInf.GetFont()->GetAscent( +/*N*/ rInf.GetVsh(), rInf.GetOut() ); +/*N*/ if( nTmp > nPosAscent ) +/*N*/ { +/*N*/ nPosHeight += nTmp - nPosAscent; +/*N*/ nPosAscent = nTmp; +/*N*/ } +/*N*/ nTmp = rInf.GetFont()->GetHeight( rInf.GetVsh(), +/*N*/ rInf.GetOut() ); +/*N*/ if( nTmp > nPosHeight ) +/*N*/ nPosHeight = nTmp; +/*N*/ } +/*N*/ Height( nPosHeight ); +/*N*/ nAscent = nPosAscent; +/*N*/ nMaxDescent = nPosHeight - nPosAscent; +/*N*/ } +/*N*/ } +/*N*/ else if( !pPos->IsFlyPortion() ) +/*N*/ { +/*N*/ if( Height() < nPosHeight ) +/*N*/ Height( nPosHeight ); +/*N*/ if( pPos->IsFlyCntPortion() || ( pPos->IsMultiPortion() +/*N*/ && ((SwMultiPortion*)pPos)->HasFlyInCntnt() ) ) +/*N*/ rLine.SetFlyInCntBase(); +/*N*/ if( pPos->IsFlyCntPortion() && +/*N*/ ((SwFlyCntPortion*)pPos)->GetAlign() ) +/*N*/ { +/*N*/ ((SwFlyCntPortion*)pPos)->SetMax( sal_False ); +/*N*/ if( !pFlyCnt || pPos->Height() > pFlyCnt->Height() ) +/*N*/ pFlyCnt = (SwFlyCntPortion*)pPos; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( nAscent < nPosAscent ) +/*N*/ nAscent = nPosAscent; +/*N*/ if( nMaxDescent < nPosHeight - nPosAscent ) +/*N*/ nMaxDescent = nPosHeight - nPosAscent; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( pPos->GetLen() ) +/*N*/ bTmpDummy = sal_False; +/*N*/ if( !HasCntnt() && !pPos->InNumberGrp() ) +/*N*/ { +/*N*/ if ( pPos->InExpGrp() ) +/*N*/ { +/*N*/ XubString aTxt; +/*N*/ if( pPos->GetExpTxt( rInf, aTxt ) && aTxt.Len() ) +/*N*/ SetCntnt( sal_True ); +/*N*/ } +/*N*/ else if( ( pPos->InTxtGrp() || pPos->IsMultiPortion() ) && +/*N*/ pPos->GetLen() ) +/*N*/ SetCntnt( sal_True ); +/*N*/ } +/*N*/ bTmpDummy = bTmpDummy && !HasCntnt() && +/*N*/ ( !pPos->Width() || pPos->IsFlyPortion() ); +/*N*/ +/*N*/ pLast = pPos; +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ if( pFlyCnt ) +/*N*/ { +/*N*/ if( pFlyCnt->Height() == Height() ) +/*N*/ { +/*N*/ pFlyCnt->SetMax( sal_True ); +/*N*/ if( Height() > nMaxDescent + nAscent ) +/*N*/ { +/*N*/ if( 3 == pFlyCnt->GetAlign() ) // Bottom +/*?*/ nAscent = Height() - nMaxDescent; +/*N*/ else if( 2 == pFlyCnt->GetAlign() ) // Center +/*N*/ nAscent = ( Height() + nAscent - nMaxDescent ) / 2; +/*N*/ } +/*N*/ pFlyCnt->SetAscent( nAscent ); +/*N*/ } +/*N*/ } +/*N*/ if( bTmpDummy && nFlyHeight ) +/*N*/ { +/*N*/ nAscent = nFlyAscent; +/*N*/ if( nFlyDescent > nFlyHeight - nFlyAscent ) +/*?*/ Height( nFlyHeight + nFlyDescent ); +/*N*/ else +/*N*/ Height( nFlyHeight ); +/*N*/ } +/*N*/ else if( nMaxDescent > Height() - nAscent ) +/*N*/ Height( nMaxDescent + nAscent ); +/*N*/ if( bOnlyPostIts ) +/*N*/ { +/*?*/ Height( rInf.GetFont()->GetHeight( rInf.GetVsh(), rInf.GetOut() ) ); +/*?*/ nAscent = rInf.GetFont()->GetAscent( rInf.GetVsh(), rInf.GetOut() ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ SetCntnt( !bTmpDummy ); +/*N*/ // Robust: +/*N*/ if( nLineWidth < Width() ) +/*N*/ Width( nLineWidth ); +/*N*/ ASSERT( nLineWidth >= Width(), "SwLineLayout::CalcLine: line is bursting" ); +/*N*/ SetDummy( bTmpDummy ); +/*N*/ SetRedline( rLine.GetRedln() && +/*N*/ rLine.GetRedln()->CheckLine( rLine.GetStart(), rLine.GetEnd() ) ); +/*N*/ } + +/************************************************************************* + * class SwCharRange + *************************************************************************/ + +/*N*/ SwCharRange &SwCharRange::operator+=(const SwCharRange &rRange) +/*N*/ { +/*N*/ if(0 != rRange.nLen ) { +/*N*/ if(0 == nLen) { +/*N*/ nStart = rRange.nStart; +/*N*/ nLen = rRange.nLen ; +/*N*/ } +/*N*/ else { +/*N*/ if(rRange.nStart + rRange.nLen > nStart + nLen) { +/*N*/ nLen = rRange.nStart + rRange.nLen - nStart; +/*N*/ } +/*N*/ if(rRange.nStart < nStart) { +/*N*/ nLen += nStart - rRange.nStart; +/*N*/ nStart = rRange.nStart; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return *this; +/*N*/ } + +/************************************************************************* + * WhichFont() + * + * Converts i18n Script Type (LATIN, ASIAN, COMPLEX, WEAK) to + * Sw Script Types (SW_LATIN, SW_CJK, SW_CTL), used to identify the font + *************************************************************************/ + +/*N*/ BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, const SwScriptInfo* pSI ) +/*N*/ { +/*N*/ ASSERT( pTxt || pSI,"How should I determine the script type?" ); +/*N*/ USHORT nScript; +/*N*/ +/*N*/ // First we try to use our SwScriptInfo +/*N*/ if ( pSI ) +/*N*/ nScript = pSI->ScriptType( nIdx ); +/*N*/ else +/*N*/ // Ok, we have to ask the break iterator +/*N*/ nScript = pBreakIt->GetRealScriptOfText( *pTxt, nIdx ); +/*N*/ +/*N*/ switch ( nScript ) { +/*N*/ case i18n::ScriptType::LATIN : return SW_LATIN; +/*?*/ case i18n::ScriptType::ASIAN : return SW_CJK; +/*?*/ case i18n::ScriptType::COMPLEX : return SW_CTL; +/*?*/ } +/*?*/ +/*?*/ ASSERT( sal_False, "Somebody tells lies about the script type!" ); +/*?*/ return SW_LATIN; +/*N*/ } + + +/************************************************************************* + * SwScriptInfo::InitScriptInfo() + * + * searches for script changes in rTxt and stores them + *************************************************************************/ + +/*N*/ void SwScriptInfo::InitScriptInfo( const SwTxtNode& rNode, sal_Bool bRTL ) +/*N*/ { +/*N*/ if( !pBreakIt->xBreak.is() ) +/*N*/ return; +/*N*/ +/*N*/ xub_StrLen nChg = nInvalidityPos; +/*N*/ +/*N*/ // STRING_LEN means the data structure is up to date +/*N*/ nInvalidityPos = STRING_LEN; +/*N*/ +/*N*/ // this is the default direction +/*N*/ nDefaultDir = bRTL ? UBIDI_RTL : UBIDI_LTR; +/*N*/ +/*N*/ // counter for script info arrays +/*N*/ USHORT nCnt = 0; +/*N*/ // counter for compression information arrays +/*N*/ USHORT nCntComp = 0; +/*N*/ #ifdef BIDI +/*N*/ // counter for kashida array +/*N*/ USHORT nCntKash = 0; +/*N*/ #endif +/*N*/ BYTE nScript; +/*N*/ +/*N*/ const String& rTxt = rNode.GetTxt(); +/*N*/ +/*N*/ // compression type +/*N*/ const SwCharCompressType aCompEnum = rNode.GetDoc()->GetCharCompressType(); +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ // justification type +/*N*/ const sal_Bool bAdjustBlock = SVX_ADJUST_BLOCK == +/*N*/ rNode.GetSwAttrSet().GetAdjust().GetAdjust(); +/*N*/ #endif +/*N*/ +/*N*/ +/*N*/ // +/*N*/ // FIND INVALID RANGES IN SCRIPT INFO ARRAYS: +/*N*/ // +/*N*/ +/*N*/ if( nChg ) +/*N*/ { +/*N*/ // if change position = 0 we do not use any data from the arrays +/*N*/ // because by deleting all characters of the first group at the beginning +/*N*/ // of a paragraph nScript is set to a wrong value +/*N*/ ASSERT( CountScriptChg(), "Where're my changes of script?" ); +/*N*/ while( nCnt < CountScriptChg() ) +/*N*/ { +/*N*/ if ( nChg <= GetScriptChg( nCnt ) ) +/*N*/ { +/*N*/ nScript = GetScriptType( nCnt ); +/*N*/ break; +/*N*/ } +/*N*/ else +/*N*/ nCnt++; +/*N*/ } +/*N*/ if( CHARCOMPRESS_NONE != aCompEnum ) +/*N*/ { +/*N*/ while( nCntComp < CountCompChg() ) +/*N*/ { +/*N*/ if ( nChg <= GetCompStart( nCntComp ) ) +/*N*/ break; +/*N*/ else +/*N*/ nCntComp++; +/*N*/ } +/*N*/ } +/*N*/ #ifdef BIDI +/*N*/ if ( bAdjustBlock ) +/*N*/ { +/*N*/ while( nCntKash < CountKashida() ) +/*N*/ { +/*N*/ if ( nChg <= GetKashida( nCntKash ) ) +/*N*/ break; +/*N*/ else +/*N*/ nCntKash++; +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ else +/*N*/ nScript = (BYTE)pBreakIt->xBreak->getScriptType( rTxt, 0 ); +/*N*/ +/*N*/ +/*N*/ // +/*N*/ // ADJUST nChg VALUE: +/*N*/ // +/*N*/ +/*N*/ // by stepping back one position we know that we are inside a group +/*N*/ // declared as an nScript group +/*N*/ if ( nChg ) +/*N*/ --nChg; +/*N*/ +/*N*/ const xub_StrLen nGrpStart = nCnt ? GetScriptChg( nCnt - 1 ) : 0; +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ // we go back in our group until we reach the first character of +/*N*/ // type nScript +/*N*/ while ( nChg > nGrpStart && +/*N*/ nScript != pBreakIt->xBreak->getScriptType( rTxt, nChg ) ) +/*N*/ --nChg; +/*N*/ #else +/*N*/ // we go back in our group until we reach a non-weak character +/*N*/ while ( nChg > nGrpStart && +/*N*/ WEAK == pBreakIt->xBreak->getScriptType( rTxt, nChg ) ) +/*N*/ --nChg; +/*N*/ #endif +/*N*/ +/*N*/ +/*N*/ // +/*N*/ // INVALID DATA FROM THE SCRIPT INFO ARRAYS HAS TO BE DELETED: +/*N*/ // +/*N*/ +/*N*/ // remove invalid entries from script information arrays +/*N*/ const USHORT nScriptRemove = aScriptChg.Count() - nCnt; +/*N*/ aScriptChg.Remove( nCnt, nScriptRemove ); +/*N*/ aScriptType.Remove( nCnt, nScriptRemove ); +/*N*/ +/*N*/ // get the start of the last compression group +/*N*/ USHORT nLastCompression = nChg; +/*N*/ if( nCntComp ) +/*N*/ { +/*N*/ --nCntComp; +/*N*/ nLastCompression = GetCompStart( nCntComp ); +/*N*/ if( nChg >= nLastCompression + GetCompLen( nCntComp ) ) +/*N*/ { +/*N*/ nLastCompression = nChg; +/*N*/ ++nCntComp; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // remove invalid entries from compression information arrays +/*N*/ const USHORT nCompRemove = aCompChg.Count() - nCntComp; +/*N*/ aCompChg.Remove( nCntComp, nCompRemove ); +/*N*/ aCompLen.Remove( nCntComp, nCompRemove ); +/*N*/ aCompType.Remove( nCntComp, nCompRemove ); +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ // get the start of the last kashida group +/*N*/ USHORT nLastKashida = nChg; +/*N*/ if( nCntKash && i18n::ScriptType::COMPLEX == nScript ) +/*N*/ { +/*N*/ --nCntKash; +/*N*/ nLastKashida = GetKashida( nCntKash ); +/*N*/ } +/*N*/ +/*N*/ // remove invalid entries from kashida array +/*N*/ aKashida.Remove( nCntKash, aKashida.Count() - nCntKash ); +/*N*/ #endif +/*N*/ +/*N*/ +/*N*/ // +/*N*/ // TAKE CARE OF WEAK CHARACTERS: WE MUST FIND AN APPROPRIATE +/*N*/ // SCRIPT FOR WEAK CHARACTERS AT THE BEGINNING OF A PARAGRAPH +/*N*/ // +/*N*/ +/*N*/ if( WEAK == pBreakIt->xBreak->getScriptType( rTxt, nChg ) ) +/*N*/ { +/*N*/ // If the beginning of the current group is weak, this means that +/*N*/ // all of the characters in this grounp are weak. We have to assign +/*N*/ // the scripts to these characters depending on the fonts which are +/*N*/ // set for these characters to display them. +/*N*/ xub_StrLen nEnd = +/*N*/ (xub_StrLen)pBreakIt->xBreak->endOfScript( rTxt, nChg, WEAK ); +/*N*/ +/*N*/ if( nEnd > rTxt.Len() ) +/*N*/ nEnd = rTxt.Len(); +/*N*/ +/*N*/ nScript = (BYTE)GetI18NScriptTypeOfLanguage( (USHORT)GetAppLanguage() ); +/*N*/ +/*N*/ ASSERT( i18n::ScriptType::LATIN == nScript || +/*N*/ i18n::ScriptType::ASIAN == nScript || +/*N*/ i18n::ScriptType::COMPLEX == nScript, "Wrong default language" ); +/*N*/ +/*N*/ nChg = nEnd; +/*N*/ aScriptChg.Insert( nEnd, nCnt ); +/*N*/ aScriptType.Insert( nScript, nCnt++ ); +/*N*/ +/*N*/ // Get next script type or set to weak in order to exit +/*N*/ nScript = ( nEnd < rTxt.Len() ) ? +/*N*/ (BYTE)pBreakIt->xBreak->getScriptType( rTxt, nEnd ) : +/*N*/ (BYTE)WEAK; +/*N*/ } +/*N*/ +/*N*/ // +/*N*/ // UPDATE THE SCRIPT INFO ARRAYS: +/*N*/ // +/*N*/ +/*N*/ // if there are only weak characters in paragraph we are finished +/*N*/ if ( WEAK == nScript ) +/*N*/ return; +/*N*/ +/*N*/ ASSERT( WEAK != (BYTE)pBreakIt->xBreak->getScriptType( rTxt, nChg ), +/*N*/ "Oh my god, it's weak again" ); +/*N*/ +/*N*/ do +/*N*/ { +/*N*/ ASSERT( i18n::ScriptType::WEAK != nScript, +/*N*/ "Inserting WEAK into SwScriptInfo structure" ); +/*N*/ ASSERT( STRING_LEN != nChg, "65K? Strange length of script section" ); +/*N*/ +/*N*/ nChg = (xub_StrLen)pBreakIt->xBreak->endOfScript( rTxt, nChg, nScript ); +/*N*/ +/*N*/ if ( nChg > rTxt.Len() ) +/*N*/ nChg = rTxt.Len(); +/*N*/ +/*N*/ aScriptChg.Insert( nChg, nCnt ); +/*N*/ aScriptType.Insert( nScript, nCnt++ ); +/*N*/ +/*N*/ // if current script is asian, we search for compressable characters +/*N*/ // in this range +/*N*/ if ( CHARCOMPRESS_NONE != aCompEnum && +/*N*/ i18n::ScriptType::ASIAN == nScript ) +/*N*/ { +/*?*/ BYTE ePrevState = NONE; +/*?*/ BYTE eState; +/*?*/ USHORT nPrevChg = nLastCompression; +/*?*/ +/*?*/ while ( nLastCompression < nChg ) +/*?*/ { +/*?*/ xub_Unicode cChar = rTxt.GetChar( nLastCompression ); +/*?*/ +/*?*/ // examine current character +/*?*/ switch ( cChar ) +/*?*/ { +/*?*/ // Left punctuation found +/*?*/ case 0x3008: case 0x300A: case 0x300C: case 0x300E: +/*?*/ case 0x3010: case 0x3014: case 0x3016: case 0x3018: +/*?*/ case 0x301A: case 0x301D: +/*?*/ eState = SPECIAL_LEFT; +/*?*/ break; +/*?*/ // Right punctuation found +/*?*/ case 0x3001: case 0x3002: case 0x3009: case 0x300B: +/*?*/ case 0x300D: case 0x300F: case 0x3011: case 0x3015: +/*?*/ case 0x3017: case 0x3019: case 0x301B: case 0x301E: +/*?*/ case 0x301F: +/*?*/ eState = SPECIAL_RIGHT; +/*?*/ break; +/*?*/ default: +/*?*/ eState = ( 0x3040 <= cChar && 0x3100 > cChar ) ? +/*?*/ KANA : +/*?*/ NONE; +/*?*/ } +/*?*/ +/*?*/ // insert range of compressable characters +/*?*/ if( ePrevState != eState ) +/*?*/ { +/*?*/ if ( ePrevState != NONE ) +/*?*/ { +/*?*/ // insert start and type +/*?*/ if ( CHARCOMPRESS_PUNCTUATION_KANA == aCompEnum || +/*?*/ ePrevState != KANA ) +/*?*/ { +/*?*/ aCompChg.Insert( nPrevChg, nCntComp ); +/*?*/ BYTE nTmpType = ePrevState; +/*?*/ aCompType.Insert( nTmpType, nCntComp ); +/*?*/ aCompLen.Insert( nLastCompression - nPrevChg, nCntComp++ ); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ ePrevState = eState; +/*?*/ nPrevChg = nLastCompression; +/*?*/ } +/*?*/ +/*?*/ nLastCompression++; +/*?*/ } +/*?*/ +/*?*/ // we still have to examine last entry +/*?*/ if ( ePrevState != NONE ) +/*?*/ { +/*?*/ // insert start and type +/*?*/ if ( CHARCOMPRESS_PUNCTUATION_KANA == aCompEnum || +/*?*/ ePrevState != KANA ) +/*?*/ { +/*?*/ aCompChg.Insert( nPrevChg, nCntComp ); +/*?*/ BYTE nTmpType = ePrevState; +/*?*/ aCompType.Insert( nTmpType, nCntComp ); +/*?*/ aCompLen.Insert( nLastCompression - nPrevChg, nCntComp++ ); +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ #ifdef BIDI +/*N*/ // we search for connecting opportunities (kashida) +/*N*/ else if ( bAdjustBlock && i18n::ScriptType::COMPLEX == nScript ) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if ( nChg >= rTxt.Len() ) +/*N*/ break; +/*N*/ +/*N*/ nScript = (BYTE)pBreakIt->xBreak->getScriptType( rTxt, nChg ); +/*N*/ nLastCompression = nChg; +/*N*/ #ifdef BIDI +/*N*/ nLastKashida = nChg; +/*N*/ #endif +/*N*/ +/*N*/ } while ( TRUE ); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ // check kashida data +/*N*/ long nTmpKashidaPos = -1; +/*N*/ sal_Bool bWrongKash = sal_False; +/*N*/ for ( USHORT i = 0; i < aKashida.Count(); ++i ) +/*N*/ { +/*N*/ long nCurrKashidaPos = GetKashida( i ); +/*N*/ if ( nCurrKashidaPos <= nTmpKashidaPos ) +/*N*/ { +/*N*/ bWrongKash = sal_True; +/*N*/ break; +/*N*/ } +/*N*/ nTmpKashidaPos = nCurrKashidaPos; +/*N*/ } +/*N*/ ASSERT( ! bWrongKash, "Kashida array contains wrong data" ) +/*N*/ #endif +/*N*/ +/*N*/ // remove invalid entries from direction information arrays +/*N*/ const USHORT nDirRemove = aDirChg.Count(); +/*N*/ aDirChg.Remove( 0, nDirRemove ); +/*N*/ aDirType.Remove( 0, nDirRemove ); +/*N*/ +/*N*/ // Perform Unicode Bidi Algorithm for text direction information +/*N*/ nCnt = 0; +/*N*/ sal_Bool bLatin = sal_False; +/*N*/ sal_Bool bAsian = sal_False; +/*N*/ sal_Bool bComplex = sal_False; +/*N*/ +/*N*/ while( nCnt < CountScriptChg() ) +/*N*/ { +/*N*/ nScript = GetScriptType( nCnt++ ); +/*N*/ switch ( nScript ) +/*N*/ { +/*N*/ case i18n::ScriptType::LATIN: +/*N*/ bLatin = sal_True; +/*N*/ break; +/*N*/ case i18n::ScriptType::ASIAN: +/*N*/ bAsian = sal_True; +/*N*/ break; +/*N*/ case i18n::ScriptType::COMPLEX: +/*N*/ bComplex = sal_True; +/*N*/ break; +/*N*/ default: +/*N*/ ASSERT( ! rTxt.Len(), "Wrong script found" ) +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // do not call the unicode bidi algorithm if not required +/*N*/ if ( UBIDI_LTR != nDefaultDir || bComplex ) +/*N*/ UpdateBidiInfo( rTxt ); +/*N*/ } + +/*N*/ void SwScriptInfo::UpdateBidiInfo( const String& rTxt ) +/*N*/ { +/*N*/ // remove invalid entries from direction information arrays +/*N*/ const USHORT nDirRemove = aDirChg.Count(); +/*N*/ aDirChg.Remove( 0, nDirRemove ); +/*N*/ aDirType.Remove( 0, nDirRemove ); +/*N*/ +/*N*/ // +/*N*/ // Bidi functions from icu 2.0 +/*N*/ // +/*N*/ UErrorCode nError = U_ZERO_ERROR; +/*N*/ UBiDi* pBidi = ubidi_openSized( rTxt.Len(), 0, &nError ); +/*N*/ nError = U_ZERO_ERROR; +/*N*/ +/*N*/ ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(rTxt.GetBuffer()), rTxt.Len(), // UChar != sal_Unicode in MinGW +/*N*/ nDefaultDir, NULL, &nError ); +/*N*/ nError = U_ZERO_ERROR; +/*N*/ long nCount = ubidi_countRuns( pBidi, &nError ); +/*N*/ int32_t nStart = 0; +/*N*/ int32_t nEnd; +/*N*/ UBiDiLevel nCurrDir; +/*N*/ // counter for direction information arrays +/*N*/ USHORT nCntDir = 0; +/*N*/ +/*N*/ for ( USHORT nIdx = 0; nIdx < nCount; ++nIdx ) +/*N*/ { +/*N*/ ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir ); +/*N*/ aDirChg.Insert( (USHORT)nEnd, nCntDir ); +/*N*/ aDirType.Insert( (BYTE)nCurrDir, nCntDir++ ); +/*N*/ nStart = nEnd; +/*N*/ } +/*N*/ +/*N*/ ubidi_close( pBidi ); +/*N*/ } + + +/************************************************************************* + * SwScriptInfo::NextScriptChg(..) + * returns the position of the next character which belongs to another script + * than the character of the actual (input) position. + * If there's no script change until the end of the paragraph, it will return + * STRING_LEN. + * Scripts are Asian (Chinese, Japanese, Korean), + * Latin ( English etc.) + * and Complex ( Hebrew, Arabian ) + *************************************************************************/ + +/*N*/ xub_StrLen SwScriptInfo::NextScriptChg( const xub_StrLen nPos ) const +/*N*/ { +/*N*/ USHORT nEnd = CountScriptChg(); +/*N*/ for( USHORT nX = 0; nX < nEnd; ++nX ) +/*N*/ { +/*N*/ if( nPos < GetScriptChg( nX ) ) +/*N*/ return GetScriptChg( nX ); +/*N*/ } +/*N*/ +/*N*/ return STRING_LEN; +/*N*/ } + +/************************************************************************* + * SwScriptInfo::ScriptType(..) + * returns the script of the character at the input position + *************************************************************************/ + +/*N*/ BYTE SwScriptInfo::ScriptType( const xub_StrLen nPos ) const +/*N*/ { +/*N*/ USHORT nEnd = CountScriptChg(); +/*N*/ for( USHORT nX = 0; nX < nEnd; ++nX ) +/*N*/ { +/*N*/ if( nPos < GetScriptChg( nX ) ) +/*N*/ return GetScriptType( nX ); +/*N*/ } +/*N*/ +/*N*/ // the default is the application language script +/*N*/ return (BYTE)GetI18NScriptTypeOfLanguage( (USHORT)GetAppLanguage() ); +/*N*/ } + +#ifdef BIDI + +/*N*/ xub_StrLen SwScriptInfo::NextDirChg( const xub_StrLen nPos, +/*N*/ const BYTE* pLevel ) const +/*N*/ { +/*N*/ BYTE nCurrDir = pLevel ? *pLevel : 62; +/*N*/ USHORT nEnd = CountDirChg(); +/*N*/ for( USHORT nX = 0; nX < nEnd; ++nX ) +/*N*/ { +/*N*/ if( nPos < GetDirChg( nX ) && +/*N*/ ( nX + 1 == nEnd || GetDirType( nX + 1 ) <= nCurrDir ) ) +/*?*/ return GetDirChg( nX ); +/*N*/ } +/*N*/ +/*N*/ return STRING_LEN; +/*N*/ } + +/*N*/ BYTE SwScriptInfo::DirType( const xub_StrLen nPos ) const +/*N*/ { +/*N*/ USHORT nEnd = CountDirChg(); +/*N*/ for( USHORT nX = 0; nX < nEnd; ++nX ) +/*N*/ { +/*?*/ if( nPos < GetDirChg( nX ) ) +/*?*/ return GetDirType( nX ); +/*N*/ } +/*N*/ +/*N*/ return 0; +/*N*/ } + +#endif + +/************************************************************************* + * SwScriptInfo::CompType(..) + * returns the type of the compressed character + *************************************************************************/ + + +/************************************************************************* + * SwScriptInfo::HasKana() + * returns, if there are compressable kanas or specials + * betwenn nStart and nEnd + *************************************************************************/ + +/*N*/ USHORT SwScriptInfo::HasKana( xub_StrLen nStart, const xub_StrLen nLen ) const +/*N*/ { +/*N*/ USHORT nCnt = CountCompChg(); +/*N*/ xub_StrLen nEnd = nStart + nLen; +/*N*/ +/*N*/ for( USHORT nX = 0; nX < nCnt; ++nX ) +/*N*/ { +/*N*/ xub_StrLen nKanaStart = GetCompStart( nX ); +/*N*/ xub_StrLen nKanaEnd = nKanaStart + GetCompLen( nX ); +/*N*/ +/*N*/ if ( nKanaStart >= nEnd ) +/*N*/ return USHRT_MAX; +/*N*/ +/*N*/ if ( nStart < nKanaEnd ) +/*N*/ return nX; +/*N*/ } +/*N*/ +/*N*/ return USHRT_MAX; +/*N*/ } + +/************************************************************************* + * SwScriptInfo::Compress() + *************************************************************************/ + +/*N*/ long SwScriptInfo::Compress( sal_Int32* pKernArray, xub_StrLen nIdx, xub_StrLen nLen, +/*N*/ const USHORT nCompress, const USHORT nFontHeight, +/*N*/ Point* pPoint ) const +/*N*/ { +/*N*/ ASSERT( nCompress, "Compression without compression?!" ); +/*N*/ ASSERT( nLen, "Compression without text?!" ); +/*N*/ USHORT nCompCount = CountCompChg(); +/*N*/ +/*N*/ // In asian typography, there are full width and half width characters. +/*N*/ // Full width punctuation characters can be compressed by 50 % +/*N*/ // to determine this, we compare the font width with 75 % of its height +/*N*/ USHORT nMinWidth = ( 3 * nFontHeight ) / 4; +/*N*/ +/*N*/ USHORT nCompIdx = HasKana( nIdx, nLen ); +/*N*/ +/*N*/ if ( USHRT_MAX == nCompIdx ) +/*N*/ return 0; +/*N*/ +/*N*/ xub_StrLen nChg = GetCompStart( nCompIdx ); +/*N*/ xub_StrLen nCompLen = GetCompLen( nCompIdx ); +/*N*/ USHORT nI = 0; +/*N*/ nLen += nIdx; +/*N*/ +/*N*/ if( nChg > nIdx ) +/*N*/ { +/*N*/ nI = nChg - nIdx; +/*N*/ nIdx = nChg; +/*N*/ } +/*N*/ else if( nIdx < nChg + nCompLen ) +/*N*/ nCompLen -= nIdx - nChg; +/*N*/ +/*N*/ if( nIdx > nLen || nCompIdx >= nCompCount ) +/*N*/ return 0; +/*N*/ +/*N*/ long nSub = 0; +/*N*/ long nLast = nI ? pKernArray[ nI - 1 ] : 0; +/*N*/ do +/*N*/ { +/*N*/ USHORT nType = GetCompType( nCompIdx ); +/*N*/ ASSERT( nType == CompType( nIdx ), "Gimme the right type!" ); +/*N*/ nCompLen += nIdx; +/*N*/ if( nCompLen > nLen ) +/*N*/ nCompLen = nLen; +/*N*/ +/*N*/ // are we allowed to compress the character? +/*N*/ if ( pKernArray[ nI ] - nLast < nMinWidth ) +/*N*/ { +/*N*/ nIdx++; nI++; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ while( nIdx < nCompLen ) +/*N*/ { +/*N*/ ASSERT( SwScriptInfo::NONE != nType, "None compression?!" ); +/*N*/ +/*N*/ // nLast is width of current character +/*N*/ nLast -= pKernArray[ nI ]; +/*N*/ +/*N*/ nLast *= nCompress; +/*N*/ long nMove = 0; +/*N*/ if( SwScriptInfo::KANA != nType ) +/*N*/ { +/*N*/ nLast /= 20000; +/*N*/ if( pPoint && SwScriptInfo::SPECIAL_LEFT == nType ) +/*N*/ { +/*N*/ if( nI ) +/*N*/ nMove = nLast; +/*N*/ else +/*N*/ { +/*N*/ pPoint->X() += nLast; +/*N*/ nLast = 0; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ nLast /= 100000; +/*N*/ nSub -= nLast; +/*N*/ nLast = pKernArray[ nI ]; +/*N*/ if( nMove ) +/*N*/ pKernArray[ nI - 1 ] += nMove; +/*N*/ pKernArray[ nI++ ] -= nSub; +/*N*/ ++nIdx; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nIdx < nLen ) +/*N*/ { +/*N*/ xub_StrLen nChg; +/*N*/ if( ++nCompIdx < nCompCount ) +/*N*/ { +/*N*/ nChg = GetCompStart( nCompIdx ); +/*N*/ if( nChg > nLen ) +/*N*/ nChg = nLen; +/*N*/ nCompLen = GetCompLen( nCompIdx ); +/*N*/ } +/*N*/ else +/*N*/ nChg = nLen; +/*N*/ while( nIdx < nChg ) +/*N*/ { +/*N*/ nLast = pKernArray[ nI ]; +/*N*/ pKernArray[ nI++ ] -= nSub; +/*N*/ ++nIdx; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ break; +/*N*/ } while( nIdx < nLen ); +/*N*/ return nSub; +/*N*/ } + +/************************************************************************* + * class SwParaPortion + *************************************************************************/ + +/*N*/ SwParaPortion::SwParaPortion() +/*N*/ { +/*N*/ FormatReset(); +/*N*/ bFlys = bFtnNum = bMargin = sal_False; +/*N*/ SetWhichPor( POR_PARA ); +/*N*/ } + +/************************************************************************* + * SwParaPortion::GetParLen() + *************************************************************************/ + +/*N*/ xub_StrLen SwParaPortion::GetParLen() const +/*N*/ { +/*N*/ xub_StrLen nLen = 0; +/*N*/ const SwLineLayout *pLay = this; +/*N*/ while( pLay ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ nLen += pLay->GetLen(); +/*N*/ pLay = pLay->GetNext(); +/*N*/ } +/*N*/ return nLen; +/*N*/ } + +/************************************************************************* + * SwParaPortion::FindDropPortion() + *************************************************************************/ + +/*N*/ const SwDropPortion *SwParaPortion::FindDropPortion() const +/*N*/ { +/*N*/ const SwLineLayout *pLay = this; +/*N*/ while( pLay && pLay->IsDummy() ) +/*N*/ pLay = pLay->GetNext(); +/*N*/ while( pLay ) +/*N*/ { +/*N*/ const SwLinePortion *pPos = pLay->GetPortion(); +/*N*/ while ( pPos && !pPos->GetLen() ) +/*N*/ pPos = pPos->GetPortion(); +/*N*/ if( pPos && pPos->IsDropPortion() ) +/*N*/ return (SwDropPortion *)pPos; +/*N*/ pLay = pLay->GetLen() ? NULL : pLay->GetNext(); +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/************************************************************************* + * SwLineLayout::Init() + *************************************************************************/ + +/*N*/ void SwLineLayout::Init( SwLinePortion* pNextPortion ) +/*N*/ { +/*N*/ Height( 0 ); +/*N*/ Width( 0 ); +/*N*/ SetLen( 0 ); +/*N*/ SetAscent( 0 ); +/*N*/ SetRealHeight( 0 ); +/*N*/ SetPortion( pNextPortion ); +/*N*/ } + +/*-----------------16.11.00 11:04------------------- + * HangingMargin() + * looks for hanging punctuation portions in the paragraph + * and return the maximum right offset of them. + * If no such portion is found, the Margin/Hanging-flags will be atualized. + * --------------------------------------------------*/ + +/*N*/ SwTwips SwLineLayout::_GetHangingMargin() const +/*N*/ { +/*N*/ SwLinePortion* pPor = GetPortion(); +/*N*/ BOOL bFound = sal_False; +/*N*/ SwTwips nDiff = 0; +/*N*/ while( pPor) +/*N*/ { +/*N*/ if( pPor->IsHangingPortion() ) +/*N*/ { +/*?*/ nDiff = ((SwHangingPortion*)pPor)->GetInnerWidth() - pPor->Width(); +/*?*/ if( nDiff ) +/*?*/ bFound = sal_True; +/*N*/ } +/*N*/ // the last post its portion +/*N*/ else if ( pPor->IsPostItsPortion() && ! pPor->GetPortion() ) +/*N*/ nDiff = nAscent; +/*N*/ +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ if( !bFound ) // actualize the hanging-flag +/*N*/ ((SwLineLayout*)this)->SetHanging( sal_False ); +/*N*/ return nDiff; +/*N*/ } + +/*N*/ SwTwips SwTxtFrm::HangingMargin() const +/*N*/ { +/*N*/ ASSERT( HasPara(), "Don't call me without a paraportion" ); +/*N*/ if( !GetPara()->IsMargin() ) +/*N*/ return 0; +/*?*/ const SwLineLayout* pLine = GetPara(); +/*?*/ SwTwips nRet = 0; +/*?*/ do +/*?*/ { +/*?*/ SwTwips nDiff = pLine->GetHangingMargin(); +/*?*/ if( nDiff > nRet ) +/*?*/ nRet = nDiff; +/*?*/ pLine = pLine->GetNext(); +/*?*/ } while ( pLine ); +/*?*/ if( !nRet ) // actualize the margin-flag +/*?*/ ((SwParaPortion*)GetPara())->SetMargin( sal_False ); +/*?*/ return nRet; +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porlin.cxx b/binfilter/bf_sw/source/core/text/sw_porlin.cxx new file mode 100644 index 000000000000..13c6b8344f8e --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porlin.cxx @@ -0,0 +1,349 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#ifdef BIDI +#endif + + +#include "txtcfg.hxx" +#include "pormulti.hxx" +#include "inftxt.hxx" +namespace binfilter { + +#ifdef DBG_UTIL + +/*N*/ sal_Bool ChkChain( SwLinePortion *pStart ) +/*N*/ { +/*N*/ SwLinePortion *pPor = pStart->GetPortion(); +/*N*/ MSHORT nCount = 0; +/*N*/ while( pPor ) +/*N*/ { +/*N*/ ++nCount; +/*N*/ ASSERT( nCount < 200 && pPor != pStart, +/*N*/ "ChkChain(): lost in chains" ); +/*N*/ if( nCount >= 200 || pPor == pStart ) +/*N*/ { +/*N*/ // der Lebensretter +/*?*/ pPor = pStart->GetPortion(); +/*?*/ pStart->SetPortion(0); +/*?*/ pPor->Truncate(); +/*?*/ pStart->SetPortion( pPor ); +/*?*/ return sal_False; +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ return sal_True; +/*N*/ } +#endif + +#if OSL_DEBUG_LEVEL > 1 +const sal_Char *GetPortionName( const MSHORT nType ); +#endif + +/*N*/ SwLinePortion::~SwLinePortion() +/*N*/ { +/*N*/ } + +/*N*/ SwLinePortion *SwLinePortion::Compress() +/*N*/ { +/*N*/ return GetLen() || Width() ? this : 0; +/*N*/ } + + +/************************************************************************* + * SwLinePortion::SwLinePortion( ) + *************************************************************************/ + +/*N*/ SwLinePortion::SwLinePortion( ) : +/*N*/ nLineLength( 0 ), +/*N*/ nAscent( 0 ), +/*N*/ pPortion( NULL ) +/*N*/ { +/*N*/ } + +/************************************************************************* + * SwLinePortion::PrePaint() + *************************************************************************/ + + +/************************************************************************* + * SwLinePortion::CalcTxtSize() + *************************************************************************/ + +/*N*/ void SwLinePortion::CalcTxtSize( const SwTxtSizeInfo &rInf ) +/*N*/ { +/*N*/ if( GetLen() == rInf.GetLen() ) +/*N*/ *((SwPosSize*)this) = GetTxtSize( rInf ); +/*N*/ else +/*N*/ { +/*?*/ SwTxtSizeInfo aInf( rInf ); +/*?*/ aInf.SetLen( GetLen() ); +/*?*/ *((SwPosSize*)this) = GetTxtSize( aInf ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwLinePortion::Truncate() + * + * Es werden alle nachfolgenden Portions geloescht. + *************************************************************************/ + +/*N*/ void SwLinePortion::_Truncate() +/*N*/ { +/*N*/ SwLinePortion *pPos = pPortion; +/*N*/ do +/*N*/ { ASSERT( pPos != this, "SwLinePortion::Truncate: loop" ); +/*N*/ SwLinePortion *pLast = pPos; +/*N*/ pPos = pPos->GetPortion(); +/*N*/ pLast->SetPortion( 0 ); +/*N*/ delete pLast; +/*N*/ +/*N*/ } while( pPos ); +/*N*/ +/*N*/ pPortion = 0; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::Insert() + * + * Es wird immer hinter uns eingefuegt. + *************************************************************************/ + +/*N*/ SwLinePortion *SwLinePortion::Insert( SwLinePortion *pIns ) +/*N*/ { +/*N*/ pIns->FindLastPortion()->SetPortion( pPortion ); +/*N*/ SetPortion( pIns ); +/*N*/ #ifdef DBG_UTIL +/*N*/ ChkChain( this ); +/*N*/ #endif +/*N*/ return pIns; +/*N*/ } + +/************************************************************************* + * SwLinePortion::FindLastPortion() + *************************************************************************/ + +/*N*/ SwLinePortion *SwLinePortion::FindLastPortion() +/*N*/ { +/*N*/ register SwLinePortion *pPos = this; +/*N*/ // An das Ende wandern und pLinPortion an den letzten haengen ... +/*N*/ while( pPos->GetPortion() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ return pPos; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::Append() + *************************************************************************/ + +/*N*/ SwLinePortion *SwLinePortion::Append( SwLinePortion *pIns ) +/*N*/ { +/*N*/ SwLinePortion *pPos = FindLastPortion(); +/*N*/ pPos->SetPortion( pIns ); +/*N*/ pIns->SetPortion( 0 ); +/*N*/ #ifdef DBG_UTIL +/*N*/ ChkChain( this ); +/*N*/ #endif +/*N*/ return pIns; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::Cut() + *************************************************************************/ + +/*N*/ SwLinePortion *SwLinePortion::Cut( SwLinePortion *pVictim ) +/*N*/ { +/*N*/ SwLinePortion *pPrev = pVictim->FindPrevPortion( this ); +/*N*/ ASSERT( pPrev, "SwLinePortion::Cut(): can't cut" ); +/*N*/ pPrev->SetPortion( pVictim->GetPortion() ); +/*N*/ pVictim->SetPortion(0); +/*N*/ return pVictim; +/*N*/ } + +/************************************************************************* + * SwLinePortion::FindPrevPortion() + *************************************************************************/ + +/*N*/ SwLinePortion *SwLinePortion::FindPrevPortion( const SwLinePortion *pRoot ) +/*N*/ { +/*N*/ ASSERT( pRoot != this, "SwLinePortion::FindPrevPortion(): invalid root" ); +/*N*/ SwLinePortion *pPos = (SwLinePortion*)pRoot; +/*N*/ while( pPos->GetPortion() && pPos->GetPortion() != this ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ ASSERT( pPos->GetPortion(), +/*N*/ "SwLinePortion::FindPrevPortion: blowing in the wind"); +/*N*/ return pPos; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::GetCrsrOfst() + *************************************************************************/ + + +/************************************************************************* + * virtual SwLinePortion::GetTxtSize() + *************************************************************************/ +/*N*/ +/*N*/ SwPosSize SwLinePortion::GetTxtSize( const SwTxtSizeInfo & ) const +/*N*/ { +/*N*/ ASSERT( !this, "SwLinePortion::GetTxtSize: don't ask me about sizes, " +/*N*/ "I'm only a stupid SwLinePortion" ); +/*N*/ return SwPosSize(); +/*N*/ } + +#ifdef DBG_UTIL + +/************************************************************************* + * virtual SwLinePortion::Check() + *************************************************************************/ + +#endif + +/************************************************************************* + * virtual SwLinePortion::Format() + *************************************************************************/ + +/*N*/ sal_Bool SwLinePortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( rInf.X() > rInf.Width() ) +/*N*/ { +/*?*/ Truncate(); +/*?*/ rInf.SetUnderFlow( this ); +/*?*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ register const SwLinePortion *pLast = rInf.GetLast(); +/*N*/ Height( pLast->Height() ); +/*N*/ SetAscent( pLast->GetAscent() ); +/*N*/ const KSHORT nNewWidth = rInf.X() + PrtWidth(); +/*N*/ // Nur Portions mit echter Breite koennen ein sal_True zurueckliefern +/*N*/ // Notizen beispielsweise setzen niemals bFull==sal_True +/*N*/ if( rInf.Width() <= nNewWidth && PrtWidth() && ! IsKernPortion() ) +/*N*/ { +/*?*/ Truncate(); +/*?*/ if( nNewWidth > rInf.Width() ) +/*?*/ PrtWidth( nNewWidth - rInf.Width() ); +/*?*/ rInf.GetLast()->FormatEOL( rInf ); +/*?*/ return sal_True; +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::FormatEOL() + *************************************************************************/ + +// Format end of line + +/*N*/ void SwLinePortion::FormatEOL( SwTxtFormatInfo &rInf ) +/*N*/ { } + +/************************************************************************* + * SwLinePortion::Move() + *************************************************************************/ + +/*N*/ void SwLinePortion::Move( SwTxtPaintInfo &rInf ) +/*N*/ { +/*N*/ BOOL bB2T = rInf.GetDirection() == DIR_BOTTOM2TOP; +/*N*/ #ifdef BIDI +/*N*/ const BOOL bFrmDir = rInf.GetTxtFrm()->IsRightToLeft(); +/*N*/ BOOL bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == rInf.GetDirection() ) || +/*N*/ ( bFrmDir && DIR_LEFT2RIGHT == rInf.GetDirection() ); +/*N*/ #endif +/*N*/ +/*N*/ if ( InSpaceGrp() && rInf.GetSpaceAdd() ) +/*N*/ { +/*?*/ SwTwips nTmp = PrtWidth() + CalcSpacing( rInf.GetSpaceAdd(), rInf ); +/*?*/ if( rInf.IsRotated() ) +/*?*/ rInf.Y( rInf.Y() + ( bB2T ? -nTmp : nTmp ) ); +/*?*/ #ifdef BIDI +/*?*/ else if ( bCounterDir ) +/*?*/ rInf.X( rInf.X() - nTmp ); +/*?*/ #endif +/*?*/ else +/*?*/ rInf.X( rInf.X() + nTmp ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( InFixMargGrp() && !IsMarginPortion() ) +/*N*/ { +/*N*/ rInf.IncSpaceIdx(); +/*N*/ rInf.IncKanaIdx(); +/*N*/ } +/*N*/ if( rInf.IsRotated() ) +/*?*/ rInf.Y( rInf.Y() + ( bB2T ? -PrtWidth() : PrtWidth() ) ); +/*N*/ #ifdef BIDI +/*N*/ else if ( bCounterDir ) +/*?*/ rInf.X( rInf.X() - PrtWidth() ); +/*N*/ #endif +/*N*/ else +/*N*/ rInf.X( rInf.X() + PrtWidth() ); +/*N*/ } +/*N*/ if( IsMultiPortion() && ((SwMultiPortion*)this)->HasTabulator() ) +/*?*/ rInf.IncSpaceIdx(); +/*N*/ +/*N*/ rInf.SetIdx( rInf.GetIdx() + GetLen() ); +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::CalcSpacing() + *************************************************************************/ + +/*N*/ long SwLinePortion::CalcSpacing( short nSpaceAdd, const SwTxtSizeInfo &rInf ) const +/*N*/ { +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwLinePortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * virtual SwLinePortion::HandlePortion() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_pormulti.cxx b/binfilter/bf_sw/source/core/text/sw_pormulti.cxx new file mode 100644 index 000000000000..913aee8e9b45 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_pormulti.cxx @@ -0,0 +1,840 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <com/sun/star/i18n/ScriptType.hdl> +#include <bf_svx/twolinesitem.hxx> +#include <bf_svx/charrotateitem.hxx> + +#ifdef BIDI +#endif + +#include <charfmt.hxx> +#include <txtinet.hxx> +#include <fchrfmt.hxx> +#include <pormulti.hxx> // SwMultiPortion +#include <itrform2.hxx> // SwTxtFormatter + +#include <horiornt.hxx> + +#include <porfld.hxx> // SwFldPortion +namespace binfilter { + +using namespace ::com::sun::star; +extern sal_Bool IsUnderlineBreak( const SwLinePortion& rPor, const SwFont& rFnt ); +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +/*-----------------10.10.00 15:23------------------- + * class SwMultiPortion + * + * A SwMultiPortion is not a simple portion, + * it's a container, which contains almost a SwLineLayoutPortion. + * This SwLineLayout could be followed by other textportions via pPortion + * and by another SwLineLayout via pNext to realize a doubleline portion. + * --------------------------------------------------*/ + + + +/*-----------------13.10.00 16:21------------------- + * Summarize the internal lines to calculate the (external) size. + * The internal line has to calculate first. + * --------------------------------------------------*/ + + + +#ifdef BIDI +#endif + +/************************************************************************* + * virtual SwMultiPortion::HandlePortion() + *************************************************************************/ + + +/*-----------------01.11.00 14:21------------------- + * SwMultiPortion::ActualizeTabulator() + * sets the tabulator-flag, if there's any tabulator-portion inside. + * --------------------------------------------------*/ + + +/*-----------------16.02.01 12:07------------------- + * SwRotatedPortion::SwRotatedPortion(..) + * --------------------------------------------------*/ + + + +/*-----------------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. + * --------------------------------------------------*/ + + +/*-----------------01.11.00 14:22------------------- + * SwDoubleLinePortion::SwDoubleLinePortion(..) + * This constructor uses the textattribut to get the right brackets. + * The textattribut could be a 2-line-attribute or a character- or + * internetstyle, which contains the 2-line-attribute. + * --------------------------------------------------*/ + + + +/*-----------------25.10.00 09:51------------------- + * SwMultiPortion::PaintBracket paints the wished bracket, + * if the multiportion has surrounding brackets. + * The X-position of the SwTxtPaintInfo will be modified: + * the open bracket sets position behind itself, + * the close bracket in front of itself. + * --------------------------------------------------*/ + + +/*-----------------25.10.00 16:26------------------- + * SwDoubleLinePortion::SetBrackets creates the bracket-structur + * and fills it, if not both characters are 0x00. + * --------------------------------------------------*/ + + +/*-----------------25.10.00 16:29------------------- + * 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. + * --------------------------------------------------*/ + + +/*-----------------26.10.00 10:36------------------- + * 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. + * --------------------------------------------------*/ + + + +/*-----------------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. + * --------------------------------------------------*/ + +/*-----------------01.11.00 14:29------------------- + * SwDoubleLinePortion::ResetSpaceAdd(..) + * cancels the manipulation from SwDoubleLinePortion::ChangeSpaceAdd(..) + * --------------------------------------------------*/ + + +#ifdef BIDI +/*-----------------13.11.00 14:50------------------- + * SwRubyPortion::SwRubyPortion(..) + * constructs a ruby portion, i.e. an additional text is displayed + * beside the main text, e.g. phonetic characters. + * --------------------------------------------------*/ + + +#endif + +/*-----------------13.11.00 14:50------------------- + * SwRubyPortion::SwRubyPortion(..) + * constructs a ruby portion, i.e. an additional text is displayed + * beside the main text, e.g. phonetic characters. + * --------------------------------------------------*/ + + +/*-----------------13.11.00 14:56------------------- + * SwRubyPortion::_Adjust(..) + * In ruby portion there are different alignments for + * the ruby text and the main text. + * Left, right, centered and two possibilities of block adjustment + * The block adjustment is realized by spacing between the characteres, + * either with a half space or no space in front of the first letter and + * a half space at the end of the last letter. + * Notice: the smaller line will be manipulated, normally it's the ruby line, + * but it could be the main text, too. + * If there is a tabulator in smaller line, no adjustment is possible. + * --------------------------------------------------*/ + + +/*-----------------08.11.00 14:14------------------- + * CalcRubyOffset() + * has to change the nRubyOffset, if there's a fieldportion + * in the phonetic line. + * The nRubyOffset is the position in the rubystring, where the + * next SwRubyPortion has start the displaying of the phonetics. + * --------------------------------------------------*/ + + +/*-----------------13.10.00 16:22------------------- + * SwTxtSizeInfo::GetMultiCreator(..) + * If we (e.g. the position rPos) are inside a two-line-attribute or + * a ruby-attribute, the attribute will be returned in a SwMultiCreator-struct, + * otherwise the function returns zero. + * The rPos parameter is set to the end of the multiportion, + * normally this is the end of the attribute, + * but sometimes it is the start of another attribute, which finished or + * interrupts the first attribute. + * E.g. a ruby portion interrupts a 2-line-attribute, a 2-line-attribute + * with different brackets interrupts another 2-line-attribute. + * --------------------------------------------------*/ + +/*-----------------13.11.00 15:38------------------- + * lcl_Has2Lines(..) + * is a little help function for GetMultiCreator(..) + * It extracts the 2-line-format from a 2-line-attribute or a character style. + * The rValue is set to TRUE, if the 2-line-attribute's value is set and + * no 2-line-format reference is passed. If there is a 2-line-format reference, + * then the rValue is set only, if the 2-line-attribute's value is set _and_ + * the 2-line-formats has the same brackets. + * --------------------------------------------------*/ + +/*N*/ sal_Bool lcl_Has2Lines( const SwTxtAttr& rAttr, const SvxTwoLinesItem* &rpRef, +/*N*/ sal_Bool &rValue ) +/*N*/ { +/*N*/ if( RES_CHRATR_TWO_LINES == rAttr.Which() ) +/*N*/ { +/*?*/ rValue = rAttr.Get2Lines().GetValue(); +/*?*/ if( !rpRef ) +/*?*/ rpRef = &rAttr.Get2Lines(); +/*?*/ else if( rAttr.Get2Lines().GetEndBracket() != rpRef->GetEndBracket() || +/*?*/ rAttr.Get2Lines().GetStartBracket() != rpRef->GetStartBracket() ) +/*?*/ rValue = sal_False; +/*?*/ return sal_True; +/*N*/ } +/*N*/ SwCharFmt* pFmt = NULL; +/*N*/ if( RES_TXTATR_INETFMT == rAttr.Which() ) +/*N*/ pFmt = ((SwTxtINetFmt&)rAttr).GetCharFmt(); +/*N*/ else if( RES_TXTATR_CHARFMT == rAttr.Which() ) +/*N*/ pFmt = rAttr.GetCharFmt().GetCharFmt(); +/*N*/ if ( pFmt ) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pFmt->GetAttrSet(). +/*N*/ GetItemState( RES_CHRATR_TWO_LINES, TRUE, &pItem ) ) +/*N*/ { +/*?*/ rValue = ((SvxTwoLinesItem*)pItem)->GetValue(); +/*?*/ if( !rpRef ) +/*?*/ rpRef = (SvxTwoLinesItem*)pItem; +/*?*/ else if( ((SvxTwoLinesItem*)pItem)->GetEndBracket() != +/*?*/ rpRef->GetEndBracket() || +/*?*/ ((SvxTwoLinesItem*)pItem)->GetStartBracket() != +/*?*/ rpRef->GetStartBracket() ) +/*?*/ rValue = sal_False; +/*?*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/*-----------------16.02.01 16:39------------------- + * lcl_HasRotation(..) + * is a little help function for GetMultiCreator(..) + * It extracts the charrotation from a charrotate-attribute or a character style. + * The rValue is set to TRUE, if the charrotate-attribute's value is set and + * no charrotate-format reference is passed. + * If there is a charrotate-format reference, then the rValue is set only, + * if the charrotate-attribute's value is set _and_ identical + * to the charrotate-format's value. + * --------------------------------------------------*/ + +/*N*/ sal_Bool lcl_HasRotation( const SwTxtAttr& rAttr, +/*N*/ const SvxCharRotateItem* &rpRef, sal_Bool &rValue ) +/*N*/ { +/*N*/ if( RES_CHRATR_ROTATE == rAttr.Which() ) +/*N*/ { +/*?*/ rValue = 0 != rAttr.GetCharRotate().GetValue(); +/*?*/ if( !rpRef ) +/*?*/ rpRef = &rAttr.GetCharRotate(); +/*?*/ else if( rAttr.GetCharRotate().GetValue() != rpRef->GetValue() ) +/*?*/ rValue = sal_False; +/*?*/ return sal_True; +/*N*/ } +/*N*/ SwCharFmt* pFmt = NULL; +/*N*/ if( RES_TXTATR_INETFMT == rAttr.Which() ) +/*N*/ pFmt = ((SwTxtINetFmt&)rAttr).GetCharFmt(); +/*N*/ else if( RES_TXTATR_CHARFMT == rAttr.Which() ) +/*N*/ pFmt = rAttr.GetCharFmt().GetCharFmt(); +/*N*/ if ( pFmt ) +/*N*/ { +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pFmt->GetAttrSet(). +/*N*/ GetItemState( RES_CHRATR_ROTATE, TRUE, &pItem ) ) +/*N*/ { +/*?*/ rValue = 0 != ((SvxCharRotateItem*)pItem)->GetValue(); +/*?*/ if( !rpRef ) +/*?*/ rpRef = (SvxCharRotateItem*)pItem; +/*?*/ else if( ((SvxCharRotateItem*)pItem)->GetValue() != +/*?*/ rpRef->GetValue() ) +/*?*/ rValue = sal_False; +/*?*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/*N*/ #ifdef BIDI +/*N*/ SwMultiCreator* SwTxtSizeInfo::GetMultiCreator( xub_StrLen &rPos, +/*N*/ SwMultiPortion* pMulti ) const +/*N*/ #else +/*N*/ SwMultiCreator* SwTxtSizeInfo::GetMultiCreator( xub_StrLen &rPos ) const +/*N*/ #endif +/*N*/ { +/*N*/ #ifdef BIDI +/*N*/ SwScriptInfo& rSI = ((SwParaPortion*)GetParaPortion())->GetScriptInfo(); +/*N*/ +/*N*/ // get the last embedding level +/*N*/ BYTE nCurrLevel; +/*N*/ if ( pMulti ) +/*N*/ { + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ASSERT( pMulti->IsBidi(), "Nested MultiPortion is not BidiPortion" ) +/*N*/ } +/*N*/ else +/*N*/ // no nested bidi portion required +/*N*/ nCurrLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0; +/*N*/ +/*N*/ // check if there is a field at rPos: +/*N*/ BYTE nNextLevel = nCurrLevel; +/*N*/ sal_Bool bFldBidi = sal_False; +/*N*/ +/*N*/ if ( CH_TXTATR_BREAKWORD == GetChar( rPos ) ) +/*N*/ { + bFldBidi = sal_True; +/* + // examining the script of the field text should be sufficient + // for 99% of all cases + XubString aTxt = GetTxtFrm()->GetTxtNode()->GetExpandTxt( rPos, 1 ); + + if ( pBreakIt->xBreak.is() && aTxt.Len() ) + { + sal_Bool bFldDir = ( ::com::sun::star::i18n::ScriptType::COMPLEX == + pBreakIt->GetRealScriptOfText( aTxt, 0 ) ); + sal_Bool bCurrDir = ( 0 != ( nCurrLevel % 2 ) ); + if ( bFldDir != bCurrDir ) + { + nNextLevel = nCurrLevel + 1; + bFldBidi = sal_True; + } + }*/ +/*N*/ } +/*N*/ else +/*N*/ nNextLevel = rSI.DirType( rPos ); +/*N*/ +/*N*/ if ( GetTxt().Len() != rPos && nNextLevel > nCurrLevel ) +/*N*/ { +/*?*/ rPos = bFldBidi ? rPos + 1 : rSI.NextDirChg( rPos, &nCurrLevel ); +/*?*/ if ( STRING_LEN == rPos ) +/*?*/ return NULL; +/*?*/ SwMultiCreator *pRet = new SwMultiCreator; +/*?*/ pRet->pItem = NULL; +/*?*/ pRet->pAttr = NULL; +/*?*/ pRet->nId = SW_MC_BIDI; +/*?*/ pRet->nLevel = nCurrLevel + 1; +/*?*/ return pRet; +/*N*/ } +/*N*/ +/*N*/ // a bidi portion can only contain other bidi portions +/*N*/ if ( pMulti ) +/*N*/ return NULL; +/*N*/ #endif +/*N*/ +/*N*/ const SvxCharRotateItem* pRotate = NULL; +/*N*/ const SfxPoolItem* pRotItem; +/*N*/ if( SFX_ITEM_SET == pFrm->GetTxtNode()->GetSwAttrSet(). +/*N*/ GetItemState( RES_CHRATR_ROTATE, TRUE, &pRotItem ) && +/*N*/ ((SvxCharRotateItem*)pRotItem)->GetValue() ) +/*?*/ pRotate = (SvxCharRotateItem*)pRotItem; +/*N*/ else +/*N*/ pRotItem = NULL; +/*N*/ const SvxTwoLinesItem* p2Lines = NULL; +/*N*/ const SfxPoolItem* pItem; +/*N*/ if( SFX_ITEM_SET == pFrm->GetTxtNode()->GetSwAttrSet(). +/*N*/ GetItemState( RES_CHRATR_TWO_LINES, TRUE, &pItem ) && +/*N*/ ((SvxTwoLinesItem*)pItem)->GetValue() ) +/*N*/ p2Lines = (SvxTwoLinesItem*)pItem; +/*N*/ else +/*N*/ pItem = NULL; +/*N*/ +/*N*/ const SwpHints *pHints = pFrm->GetTxtNode()->GetpSwpHints(); +/*N*/ if( !pHints && !p2Lines && !pRotate ) +/*N*/ return NULL; +/*N*/ const SwTxtAttr *pRuby = NULL; +/*N*/ sal_Bool bTwo = sal_False; +/*N*/ sal_Bool bRot = sal_False; +/*N*/ USHORT n2Lines = USHRT_MAX; +/*N*/ USHORT nRotate = USHRT_MAX; +/*N*/ USHORT nCount = pHints ? pHints->Count() : 0; +/*N*/ USHORT i; +/*N*/ for( i = 0; i < nCount; ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pTmp = (*pHints)[i]; +/*N*/ xub_StrLen nStart = *pTmp->GetStart(); +/*N*/ if( rPos < nStart ) +/*N*/ break; +/*N*/ if( *pTmp->GetAnyEnd() > rPos ) +/*N*/ { +/*N*/ if( RES_TXTATR_CJK_RUBY == pTmp->Which() ) +/*N*/ pRuby = pTmp; +/*N*/ else +/*N*/ { +/*N*/ const SvxCharRotateItem* pRoTmp = NULL; +/*N*/ if( lcl_HasRotation( *pTmp, pRoTmp, bRot ) ) +/*N*/ { +/*N*/ nRotate = bRot ? i : nCount; +/*N*/ pRotate = pRoTmp; +/*N*/ } +/*N*/ const SvxTwoLinesItem* p2Tmp = NULL; +/*N*/ if( lcl_Has2Lines( *pTmp, p2Tmp, bTwo ) ) +/*N*/ { +/*N*/ n2Lines = bTwo ? i : nCount; +/*N*/ p2Lines = p2Tmp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( pRuby ) +/*N*/ { // The winner is ... a ruby attribute and so +/*N*/ // the end of the multiportion is the end of the ruby attribute. +/*?*/ rPos = *pRuby->GetEnd(); +/*?*/ SwMultiCreator *pRet = new SwMultiCreator; +/*?*/ pRet->pItem = NULL; +/*?*/ pRet->pAttr = pRuby; +/*?*/ pRet->nId = SW_MC_RUBY; +/*?*/ #ifdef BIDI +/*?*/ pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0; +/*?*/ #endif +/*?*/ return pRet; +/*N*/ } +/*N*/ if( n2Lines < nCount || ( pItem && pItem == p2Lines && +/*N*/ rPos < GetTxt().Len() ) ) +/*N*/ { // The winner is a 2-line-attribute, +/*?*/ // the end of the multiportion depends on the following attributes... +/*?*/ SwMultiCreator *pRet = new SwMultiCreator; +/*?*/ +/*?*/ // We note the endpositions of the 2-line attributes in aEnd as stack +/*?*/ SvXub_StrLens aEnd; +/*?*/ +/*?*/ // The bOn flag signs the state of the last 2-line attribute in the +/*?*/ // aEnd-stack, it is compatible with the winner-attribute or +/*?*/ // it interrupts the other attribute. +/*?*/ sal_Bool bOn = sal_True; +/*?*/ +/*?*/ if( n2Lines < nCount ) +/*?*/ { +/*?*/ pRet->pItem = NULL; +/*?*/ pRet->pAttr = (*pHints)[n2Lines]; +/*?*/ aEnd.Insert( *pRet->pAttr->GetEnd(), 0 ); +/*?*/ if( pItem ) +/*?*/ { +/*?*/ aEnd[ 0 ] = GetTxt().Len(); +/*?*/ bOn = ((SvxTwoLinesItem*)pItem)->GetEndBracket() == +/*?*/ p2Lines->GetEndBracket() && +/*?*/ ((SvxTwoLinesItem*)pItem)->GetStartBracket() == +/*?*/ p2Lines->GetStartBracket(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pRet->pItem = pItem; +/*?*/ pRet->pAttr = NULL; +/*?*/ aEnd.Insert( GetTxt().Len(), 0 ); +/*?*/ } +/*?*/ pRet->nId = SW_MC_DOUBLE; +/*?*/ #ifdef BIDI +/*?*/ pRet->nLevel = GetTxtFrm()->IsRightToLeft() ? 1 : 0; +/*?*/ #endif +/*?*/ +/*?*/ // n2Lines is the index of the last 2-line-attribute, which contains +/*?*/ // the actual position. +/*?*/ i = 0; +/*?*/ // At this moment we know that at position rPos the "winner"-attribute +/*?*/ // causes a 2-line-portion. The end of the attribute is the end of the +/*?*/ // portion, if there's no interrupting attribute. +/*?*/ // There are two kinds of interruptors: +/*?*/ // - ruby attributes stops the 2-line-attribute, the end of the +/*?*/ // multiline is the start of the ruby attribute +/*?*/ // - 2-line-attributes with value "Off" or with different brackets, +/*?*/ // these attributes may interrupt the winner, but they could be +/*?*/ // neutralized by another 2-line-attribute starting at the same +/*?*/ // position with the same brackets as the winner-attribute. +/*?*/ +/*?*/ // In the following loop rPos is the critical position and it will be +/*?*/ // evaluated, if at rPos starts a interrupting or a maintaining +/*?*/ // continuity attribute. +/*?*/ while( i < nCount ) +/*?*/ { +/*?*/ const SwTxtAttr *pTmp = (*pHints)[i++]; +/*?*/ if( *pTmp->GetAnyEnd() <= rPos ) +/*?*/ continue; +/*?*/ if( rPos < *pTmp->GetStart() ) +/*?*/ { +/*?*/ // If bOn is FALSE and the next attribute starts later than rPos +/*?*/ // the winner attribute is interrupted at rPos. +/*?*/ // If the start of the next atribute is behind the end of +/*?*/ // the last attribute on the aEnd-stack, this is the endposition +/*?*/ // on the stack is the end of the 2-line portion. +/*?*/ if( !bOn || aEnd[ aEnd.Count()-1 ] < *pTmp->GetStart() ) +/*?*/ break; +/*?*/ // At this moment, bOn is TRUE and the next attribute starts +/*?*/ // behind rPos, so we could move rPos to the next startpoint +/*?*/ rPos = *pTmp->GetStart(); +/*?*/ // We clean up the aEnd-stack, endpositions equal to rPos are +/*?*/ // superfluous. +/*?*/ while( aEnd.Count() && aEnd[ aEnd.Count()-1 ] <= rPos ) +/*?*/ { +/*?*/ bOn = !bOn; +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ } +/*?*/ // If the endstack is empty, we simulate an attribute with +/*?*/ // state TRUE and endposition rPos +/*?*/ if( !aEnd.Count() ) +/*?*/ { +/*?*/ aEnd.Insert( rPos, 0 ); +/*?*/ bOn = sal_True; +/*?*/ } +/*?*/ } +/*?*/ // A ruby attribute stops the 2-line immediately +/*?*/ if( RES_TXTATR_CJK_RUBY == pTmp->Which() ) +/*?*/ return pRet; +/*?*/ if( lcl_Has2Lines( *pTmp, p2Lines, bTwo ) ) +/*?*/ { // We have an interesting attribute.. +/*?*/ if( bTwo == bOn ) +/*?*/ { // .. with the same state, so the last attribute could +/*?*/ // be continued. +/*?*/ if( aEnd[ aEnd.Count()-1 ] < *pTmp->GetEnd() ) +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ else +/*?*/ { // .. with a different state. +/*?*/ bOn = bTwo; +/*?*/ // If this is smaller than the last on the stack, we put +/*?*/ // it on the stack. If it has the same endposition, the last +/*?*/ // could be removed. +/*?*/ if( aEnd[ aEnd.Count()-1 ] > *pTmp->GetEnd() ) +/*?*/ aEnd.Insert( *pTmp->GetEnd(), aEnd.Count() ); +/*?*/ else if( aEnd.Count() > 1 ) +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ else +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ if( bOn && aEnd.Count() ) +/*?*/ rPos = aEnd[ aEnd.Count()-1 ]; +/*?*/ return pRet; +/*N*/ } +/*N*/ if( nRotate < nCount || ( pRotItem && pRotItem == pRotate && +/*N*/ rPos < GetTxt().Len() ) ) +/*N*/ { // The winner is a rotate-attribute, +/*?*/ // the end of the multiportion depends on the following attributes... +/*?*/ SwMultiCreator *pRet = new SwMultiCreator; +/*?*/ pRet->nId = SW_MC_ROTATE; +/*?*/ +/*?*/ // We note the endpositions of the 2-line attributes in aEnd as stack +/*?*/ SvXub_StrLens aEnd; +/*?*/ +/*?*/ // The bOn flag signs the state of the last 2-line attribute in the +/*?*/ // aEnd-stack, which could interrupts the winning rotation attribute. +/*?*/ sal_Bool bOn = pItem ? sal_True : sal_False; +/*?*/ aEnd.Insert( GetTxt().Len(), 0 ); +/*?*/ // n2Lines is the index of the last 2-line-attribute, which contains +/*?*/ // the actual position. +/*?*/ i = 0; +/*?*/ xub_StrLen n2Start = rPos; +/*?*/ while( i < nCount ) +/*?*/ { +/*?*/ const SwTxtAttr *pTmp = (*pHints)[i++]; +/*?*/ if( *pTmp->GetAnyEnd() <= n2Start ) +/*?*/ continue; +/*?*/ if( n2Start < *pTmp->GetStart() ) +/*?*/ { +/*?*/ if( bOn || aEnd[ aEnd.Count()-1 ] < *pTmp->GetStart() ) +/*?*/ break; +/*?*/ n2Start = *pTmp->GetStart(); +/*?*/ while( aEnd.Count() && aEnd[ aEnd.Count()-1 ] <= n2Start ) +/*?*/ { +/*?*/ bOn = !bOn; +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ } +/*?*/ if( !aEnd.Count() ) +/*?*/ { +/*?*/ aEnd.Insert( n2Start, 0 ); +/*?*/ bOn = sal_False; +/*?*/ } +/*?*/ } +/*?*/ // A ruby attribute stops immediately +/*?*/ if( RES_TXTATR_CJK_RUBY == pTmp->Which() ) +/*?*/ { +/*?*/ bOn = sal_True; +/*?*/ break; +/*?*/ } +/*?*/ p2Lines = NULL; +/*?*/ if( lcl_Has2Lines( *pTmp, p2Lines, bTwo ) ) +/*?*/ { +/*?*/ if( bTwo == bOn ) +/*?*/ { +/*?*/ if( aEnd[ aEnd.Count()-1 ] < *pTmp->GetEnd() ) +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ bOn = bTwo; +/*?*/ if( aEnd[ aEnd.Count()-1 ] > *pTmp->GetEnd() ) +/*?*/ aEnd.Insert( *pTmp->GetEnd(), aEnd.Count() ); +/*?*/ else if( aEnd.Count() > 1 ) +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ else +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ if( !bOn && aEnd.Count() ) +/*?*/ n2Start = aEnd[ aEnd.Count()-1 ]; +/*?*/ +/*?*/ if( aEnd.Count() ) +/*?*/ aEnd.Remove( 0, aEnd.Count() ); +/*?*/ +/*?*/ bOn = sal_True; +/*?*/ if( nRotate < nCount ) +/*?*/ { +/*?*/ pRet->pItem = NULL; +/*?*/ pRet->pAttr = (*pHints)[nRotate]; +/*?*/ aEnd.Insert( *pRet->pAttr->GetEnd(), 0 ); +/*?*/ if( pRotItem ) +/*?*/ { +/*?*/ aEnd[ 0 ] = GetTxt().Len(); +/*?*/ bOn = ((SvxCharRotateItem*)pRotItem)->GetValue() == +/*?*/ pRotate->GetValue(); +/*?*/ } +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ pRet->pItem = pRotItem; +/*?*/ pRet->pAttr = NULL; +/*?*/ aEnd.Insert( GetTxt().Len(), 0 ); +/*?*/ } +/*?*/ i = 0; +/*?*/ while( i < nCount ) +/*?*/ { +/*?*/ const SwTxtAttr *pTmp = (*pHints)[i++]; +/*?*/ if( *pTmp->GetAnyEnd() <= rPos ) +/*?*/ continue; +/*?*/ if( rPos < *pTmp->GetStart() ) +/*?*/ { +/*?*/ if( !bOn || aEnd[ aEnd.Count()-1 ] < *pTmp->GetStart() ) +/*?*/ break; +/*?*/ rPos = *pTmp->GetStart(); +/*?*/ while( aEnd.Count() && aEnd[ aEnd.Count()-1 ] <= rPos ) +/*?*/ { +/*?*/ bOn = !bOn; +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ } +/*?*/ if( !aEnd.Count() ) +/*?*/ { +/*?*/ aEnd.Insert( rPos, 0 ); +/*?*/ bOn = sal_True; +/*?*/ } +/*?*/ } +/*?*/ if( RES_TXTATR_CJK_RUBY == pTmp->Which() ) +/*?*/ { +/*?*/ bOn = sal_False; +/*?*/ break; +/*?*/ } +/*?*/ if( lcl_HasRotation( *pTmp, pRotate, bTwo ) ) +/*?*/ { +/*?*/ if( bTwo == bOn ) +/*?*/ { +/*?*/ if( aEnd[ aEnd.Count()-1 ] < *pTmp->GetEnd() ) +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ bOn = bTwo; +/*?*/ if( aEnd[ aEnd.Count()-1 ] > *pTmp->GetEnd() ) +/*?*/ aEnd.Insert( *pTmp->GetEnd(), aEnd.Count() ); +/*?*/ else if( aEnd.Count() > 1 ) +/*?*/ aEnd.Remove( aEnd.Count()-1, 1 ); +/*?*/ else +/*?*/ aEnd[ aEnd.Count()-1 ] = *pTmp->GetEnd(); +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ if( bOn && aEnd.Count() ) +/*?*/ rPos = aEnd[ aEnd.Count()-1 ]; +/*?*/ if( rPos > n2Start ) +/*?*/ rPos = n2Start; +/*?*/ return pRet; +/*N*/ } +/*N*/ return NULL; +/*N*/ } + +/*-----------------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. + * --------------------------------------------------*/ + + + + + +/*-----------------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, + * internal it is like a SwTxtFrm::Paint with multiple DrawTextLines + * --------------------------------------------------*/ + + + +/*---------------------------------------------------- + * lcl_TruncateMultiPortion + * If a multi portion completely has to go to the + * next line, this function is called to trunctate + * the rest of the remaining multi portion + * --------------------------------------------------*/ + + +/*----------------------------------------------------------------------------- + * SwTxtFormatter::BuildMultiPortion + * manages the formatting of a SwMultiPortion. External, for the calling + * function, it seems to be a normal Format-function, internal it is like a + * SwTxtFrm::_Format with multiple BuildPortions + *---------------------------------------------------------------------------*/ + + +/*-----------------08.11.00 09:29------------------- + * SwTxtFormatter::MakeRestPortion(..) + * When a fieldportion at the end of line breaks and needs a following + * fieldportion in the next line, then the "restportion" of the formatinfo + * has to be set. Normally this happens during the formatting of the first + * part of the fieldportion. + * But sometimes the formatting starts at the line with the following part, + * exspecally when the following part is on the next page. + * In this case the MakeRestPortion-function has to create the following part. + * The first parameter is the line that contains possibly a first part + * of a field. When the function finds such field part, it creates the right + * restportion. This may be a multiportion, e.g. if the field is surrounded by + * a doubleline- or ruby-portion. + * The second parameter is the start index of the line. + * --------------------------------------------------*/ + +/*N*/ SwLinePortion* SwTxtFormatter::MakeRestPortion( const SwLineLayout* pLine, +/*N*/ xub_StrLen nPos ) +/*N*/ { +/*N*/ if( !nPos ) +/*N*/ return NULL; +/*N*/ xub_StrLen nMultiPos = nPos - pLine->GetLen(); +/*N*/ const SwMultiPortion *pTmpMulti = NULL; +/*N*/ const SwMultiPortion *pMulti = NULL; +/*N*/ const SwLinePortion* pPor = pLine->GetFirstPortion(); +/*N*/ SwFldPortion *pFld = NULL; +/*N*/ while( pPor ) +/*N*/ { +/*N*/ if( pPor->GetLen() ) +/*N*/ { +/*N*/ if( !pMulti ) +/*N*/ { +/*N*/ nMultiPos += pPor->GetLen(); +/*N*/ pTmpMulti = NULL; +/*N*/ } +/*N*/ } +/*N*/ if( pPor->InFldGrp() ) +/*N*/ { +/*?*/ if( !pMulti ) +/*?*/ pTmpMulti = NULL; +/*?*/ pFld = (SwFldPortion*)pPor; +/*N*/ } +/*N*/ else if( pPor->IsMultiPortion() ) +/*N*/ { +/*?*/ #ifdef BIDI +/*?*/ ASSERT( !pMulti || pMulti->IsBidi(), +/*?*/ "Nested multiportions are forbidden." ); +/*?*/ #else +/*?*/ ASSERT( !pMulti, "Nested multiportions are forbidden." ); +/*?*/ #endif +/*?*/ +/*?*/ pFld = NULL; +/*?*/ pTmpMulti = (SwMultiPortion*)pPor; +/*N*/ } +/*N*/ pPor = pPor->GetPortion(); +/*N*/ // If the last portion is a multi-portion, we enter it +/*N*/ // and look for a field portion inside. +/*N*/ // If we are already in a multiportion, we could change to the +/*N*/ // next line +/*N*/ if( !pPor && pTmpMulti ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ { +/*N*/ } +/*N*/ if( pFld && !pFld->HasFollow() ) +/*N*/ pFld = NULL; +/*N*/ +/*N*/ SwLinePortion *pRest = NULL; +/*N*/ if( pFld ) +/*N*/ { +/*?*/ const SwTxtAttr *pHint = GetAttr( nPos - 1 ); +/*?*/ if( pHint && pHint->Which() == RES_TXTATR_FIELD ) +/*?*/ { +/*?*/ pRest = NewFldPortion( GetInfo(), pHint ); +/*?*/ if( pRest->InFldGrp() ) +/*?*/ ((SwFldPortion*)pRest)->TakeNextOffset( pFld ); +/*?*/ else +/*?*/ { +/*?*/ delete pRest; +/*?*/ pRest = NULL; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ if( !pMulti ) +/*N*/ return pRest; +/*N*/ {DBG_BF_ASSERT(0, "STRIP");} +/*?*/ return pRest; +/*N*/ } + + + +/*-----------------23.10.00 10:47------------------- + * SwTxtCursorSave notes the start and current line of a SwTxtCursor, + * sets them to the values for GetCrsrOfst inside a multiportion + * and restores them in the destructor. + * --------------------------------------------------*/ + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_porrst.cxx b/binfilter/bf_sw/source/core/text/sw_porrst.cxx new file mode 100644 index 000000000000..842723d28ddc --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_porrst.cxx @@ -0,0 +1,381 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_svx/lspcitem.hxx> +#include <bf_svx/adjitem.hxx> +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/pgrditem.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> +#include <viewsh.hxx> // ViewShell +#include <viewopt.hxx> +#include <pagefrm.hxx> // SwPageFrm +#include <paratr.hxx> +#include <porrst.hxx> +#include <inftxt.hxx> +#include <tgrditem.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <frmsh.hxx> +#include <frmatr.hxx> +#include <atrhndl.hxx> +namespace binfilter { + +/************************************************************************* + * class SwBreakPortion + *************************************************************************/ +/*N*/ SwBreakPortion::SwBreakPortion( const SwLinePortion &rPortion ) +/*N*/ : SwLinePortion( rPortion ), nRestWidth( 0 ) +/*N*/ { +/*N*/ nLineLength = 1; +/*N*/ SetWhichPor( POR_BRK ); +/*N*/ } + + +/*N*/ SwLinePortion *SwBreakPortion::Compress() +/*N*/ { return (GetPortion() && GetPortion()->InTxtGrp() ? 0 : this); } + + +/************************************************************************* + * SwBreakPortion::CalcViewWidth() + *************************************************************************/ + + +/************************************************************************* + * virtual SwBreakPortion::Format() + *************************************************************************/ + +/*N*/ sal_Bool SwBreakPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ nRestWidth = (USHORT)(rInf.Width() - rInf.X()); +/*N*/ register const SwLinePortion *pRoot = rInf.GetRoot(); +/*N*/ Width( 0 ); +/*N*/ Height( pRoot->Height() ); +/*N*/ SetAscent( pRoot->GetAscent() ); +/*N*/ if ( rInf.GetIdx()+1 == rInf.GetTxt().Len() ) +/*N*/ rInf.SetNewLine( sal_True ); +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * virtual SwBreakPortion::HandlePortion() + *************************************************************************/ + + + +/*N*/ SwKernPortion::SwKernPortion( SwLinePortion &rPortion, short nKrn, +/*N*/ sal_Bool bBG, sal_Bool bGK ) : +/*N*/ nKern( nKrn ), bBackground( bBG ), bGridKern( bGK ) +/*N*/ { +/*N*/ Height( rPortion.Height() ); +/*N*/ SetAscent( rPortion.GetAscent() ); +/*N*/ nLineLength = 0; +/*N*/ SetWhichPor( POR_KERN ); +/*N*/ if( nKern > 0 ) +/*N*/ Width( nKern ); +/*N*/ rPortion.Insert( this ); +/*N*/ } + + +/*N*/ void SwKernPortion::Paint( const SwTxtPaintInfo &rInf ) const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //STRIP001 if( Width() ) +/*N*/ } + +/*N*/ void SwKernPortion::FormatEOL( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if ( bGridKern ) +/*N*/ return; +/*N*/ +/*N*/ if( rInf.GetLast() == this ) +/*N*/ rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) ); +/*N*/ if( nKern < 0 ) +/*N*/ Width( -nKern ); +/*N*/ else +/*N*/ Width( 0 ); +/*N*/ rInf.GetLast()->FormatEOL( rInf ); +/*N*/ } + +/*N*/ SwArrowPortion::SwArrowPortion( const SwLinePortion &rPortion ) : +/*N*/ bLeft( sal_True ) +/*N*/ { +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 Height( rPortion.Height() ); +/*N*/ } + +/*N*/ void SwArrowPortion::Paint( const SwTxtPaintInfo &rInf ) const +/*N*/ { +/*N*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ((SwArrowPortion*)this)->aPos = rInf.GetPos(); +/*N*/ } + +/*N*/ SwLinePortion *SwArrowPortion::Compress() { return this; } + +/*N*/ SwTwips SwTxtFrm::EmptyHeight() const +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::EmptyHeight with swapped frame" ); +/*N*/ +/*N*/ SwFont *pFnt; +/*N*/ const SwTxtNode& rTxtNode = *GetTxtNode(); +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ if ( rTxtNode.HasSwAttrSet() ) +/*N*/ { +/*N*/ const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() ); +/*N*/ pFnt = new SwFont( pAttrSet, GetTxtNode()->GetDoc() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh); +/*N*/ pFnt = new SwFont( *aFontAccess.Get()->GetFont() ); +/*N*/ pFnt->ChkMagic( pSh, pFnt->GetActual() ); +/*N*/ } +/*N*/ +/*N*/ if ( IsVertical() ) +/*?*/ pFnt->SetVertical( 2700 ); +/*N*/ +/*N*/ OutputDevice *pOut = pSh ? pSh->GetOut() : 0; +/*N*/ if ( !pOut || !rTxtNode.GetDoc()->IsBrowseMode() || +/*N*/ ( pSh->GetViewOptions()->IsPrtFormat() ) ) +/*N*/ { +/*N*/ pOut = &rTxtNode.GetDoc()->GetRefDev(); +/*N*/ } +/*N*/ +/*N*/ const SwDoc* pDoc = rTxtNode.GetDoc(); + /*N*/ if( ::binfilter::IsShowChanges( pDoc->GetRedlineMode() ) ) +/*N*/ { +/*N*/ MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode ); +/*N*/ if( MSHRT_MAX != nRedlPos ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ SwAttrHandler aAttrHandler; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ SwTwips nRet; +/*N*/ if( !pOut ) +/*?*/ nRet = IsVertical() ? +/*?*/ Prt().SSize().Width() + 1 : +/*?*/ Prt().SSize().Height() + 1; +/*N*/ else +/*N*/ { +/*N*/ pFnt->SetFntChg( sal_True ); +/*N*/ pFnt->ChgPhysFnt( pSh, pOut ); +/*N*/ nRet = pFnt->GetHeight( pSh, pOut ); +/*N*/ } +/*N*/ delete pFnt; +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FormatEmpty() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::FormatEmpty() +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::FormatEmpty with swapped frame" ); +/*N*/ +/*N*/ if ( HasFollow() || GetTxtNode()->GetpSwpHints() || +/*N*/ 0 != GetTxtNode()->GetNumRule() || +/*N*/ 0 != GetTxtNode()->GetOutlineNum() || +/*N*/ IsInFtn() || ( HasPara() && GetPara()->IsPrepMustFit() ) ) +/*N*/ return sal_False; +/*N*/ const SwAttrSet& aSet = GetTxtNode()->GetSwAttrSet(); +/*N*/ #ifdef BIDI +/*N*/ const USHORT nAdjust = aSet.GetAdjust().GetAdjust(); +/*N*/ if( ( ( ! IsRightToLeft() && ( SVX_ADJUST_LEFT != nAdjust ) ) || +/*N*/ ( IsRightToLeft() && ( SVX_ADJUST_RIGHT != nAdjust ) ) ) || +/*N*/ aSet.GetRegister().GetValue() ) +/*N*/ #else +/*N*/ if( SVX_ADJUST_LEFT != aSet.GetAdjust().GetAdjust() +/*N*/ || aSet.GetRegister().GetValue() ) +/*N*/ #endif +/*N*/ return sal_False; +/*N*/ const SvxLineSpacingItem &rSpacing = aSet.GetLineSpacing(); +/*N*/ if( SVX_LINE_SPACE_MIN == rSpacing.GetLineSpaceRule() || +/*N*/ SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() || +/*N*/ aSet.GetLRSpace().IsAutoFirst() ) +/*N*/ return sal_False; +/*N*/ else +/*N*/ { +/*N*/ SwTxtFly aTxtFly( this ); +/*N*/ SwRect aRect; +/*N*/ sal_Bool bFirstFlyCheck = 0 != Prt().Height(); +/*N*/ if ( bFirstFlyCheck && +/*N*/ aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) ) +/*N*/ return sal_False; +/*N*/ else +/*N*/ { +/*N*/ SwTwips nHeight = EmptyHeight(); +/*N*/ +/*N*/ if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() && +/*N*/ IsInDocBody() ) +/*N*/ { +/*N*/ GETGRID( FindPageFrm() ) +/*N*/ if ( pGrid ) +/*?*/ nHeight = pGrid->GetBaseHeight() + pGrid->GetRubyHeight(); +/*N*/ } +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ const SwTwips nChg = nHeight - (Prt().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ if( !nChg ) +/*N*/ SetUndersized( sal_False ); +/*N*/ AdjustFrm( nChg ); +/*N*/ +/*N*/ if( HasBlinkPor() ) +/*N*/ { +/*?*/ ClearPara(); +/*?*/ ResetBlinkPor(); +/*N*/ } +/*N*/ SetCacheIdx( MSHRT_MAX ); +/*N*/ if( !IsEmpty() ) +/*N*/ { +/*N*/ SetEmpty( sal_True ); +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ if( !bFirstFlyCheck && +/*N*/ aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) ) +/*N*/ return sal_False; +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ sal_Bool SwTxtFrm::FillRegister( SwTwips& rRegStart, KSHORT& rRegDiff ) +/*N*/ { +/*N*/ const SwFrm *pFrm = this; +/*N*/ rRegDiff = 0; +/*N*/ while( !( ( FRM_BODY | FRM_FLY ) +/*N*/ & pFrm->GetType() ) && pFrm->GetUpper() ) +/*N*/ pFrm = pFrm->GetUpper(); +/*N*/ if( ( FRM_BODY| FRM_FLY ) & pFrm->GetType() ) +/*N*/ { +/*N*/ SWRECTFN( pFrm ) +/*N*/ rRegStart = (pFrm->*fnRect->fnGetPrtTop)(); +/*N*/ pFrm = pFrm->FindPageFrm(); +/*N*/ if( pFrm->IsPageFrm() ) +/*N*/ { +/*N*/ SwPageDesc* pDesc = ((SwPageFrm*)pFrm)->FindPageDesc(); +/*N*/ if( pDesc ) +/*N*/ { +/*N*/ rRegDiff = pDesc->GetRegHeight(); +/*N*/ if( !rRegDiff ) +/*N*/ { +/*N*/ const SwTxtFmtColl *pFmt = pDesc->GetRegisterFmtColl(); +/*N*/ if( pFmt ) +/*N*/ { +/*N*/ const SvxLineSpacingItem &rSpace = pFmt->GetLineSpacing(); +/*N*/ if( SVX_LINE_SPACE_FIX == rSpace.GetLineSpaceRule() ) +/*N*/ { +/*?*/ rRegDiff = rSpace.GetLineHeight(); +/*?*/ pDesc->SetRegHeight( rRegDiff ); +/*?*/ pDesc->SetRegAscent( ( 4 * rRegDiff ) / 5 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ ViewShell *pSh = GetShell(); +/*N*/ SwFontAccess aFontAccess( pFmt, pSh ); +/*N*/ SwFont aFnt( *aFontAccess.Get()->GetFont() ); +/*N*/ OutputDevice *pOut = 0; +/*N*/ if( !GetTxtNode()->GetDoc()->IsBrowseMode() || +/*N*/ (pSh && pSh->GetViewOptions()->IsPrtFormat()) ) +/*N*/ pOut = &GetTxtNode()->GetDoc()->GetRefDev(); +/*N*/ if( pSh && !pOut ) +/*?*/ pOut = pSh->GetWin(); +/*N*/ if( !pOut ) +/*?*/ pOut = GetpApp()->GetDefaultDevice(); +/*N*/ MapMode aOldMap( pOut->GetMapMode() ); +/*N*/ pOut->SetMapMode( MapMode( MAP_TWIP ) ); +/*N*/ aFnt.ChgFnt( pSh, pOut ); +/*N*/ rRegDiff = aFnt.GetHeight( pSh, pOut ); +/*N*/ KSHORT nNettoHeight = rRegDiff; +/*N*/ switch( rSpace.GetLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_LINE_SPACE_AUTO: +/*N*/ break; +/*N*/ case SVX_LINE_SPACE_MIN: +/*N*/ { +/*N*/ if( rRegDiff < KSHORT( rSpace.GetLineHeight() ) ) +/*N*/ rRegDiff = rSpace.GetLineHeight(); +/*N*/ break; +/*N*/ } +/*N*/ default: ASSERT( +/*N*/ sal_False, ": unknown LineSpaceRule" ); +/*N*/ } +/*N*/ switch( rSpace.GetInterLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_INTER_LINE_SPACE_OFF: +/*N*/ break; +/*?*/ case SVX_INTER_LINE_SPACE_PROP: +/*?*/ { +/*?*/ long nTmp = rSpace.GetPropLineSpace(); +/*?*/ if( nTmp < 50 ) +/*?*/ nTmp = nTmp ? 50 : 100; +/*?*/ nTmp *= rRegDiff; +/*?*/ nTmp /= 100; +/*?*/ if( !nTmp ) +/*?*/ ++nTmp; +/*?*/ rRegDiff = (KSHORT)nTmp; +/*?*/ nNettoHeight = rRegDiff; +/*?*/ break; +/*?*/ } +/*?*/ case SVX_INTER_LINE_SPACE_FIX: +/*?*/ { +/*?*/ rRegDiff += rSpace.GetInterLineSpace(); +/*?*/ nNettoHeight = rRegDiff; +/*?*/ break; +/*?*/ } +/*?*/ default: ASSERT( sal_False, ": unknown InterLineSpaceRule" ); +/*N*/ } +/*N*/ pDesc->SetRegHeight( rRegDiff ); +/*N*/ pDesc->SetRegAscent( rRegDiff - nNettoHeight + +/*N*/ aFnt.GetAscent( pSh, pOut ) ); +/*N*/ pOut->SetMapMode( aOldMap ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ const long nTmpDiff = pDesc->GetRegAscent() - rRegDiff; +/*N*/ if ( bVert ) +/*?*/ rRegStart -= nTmpDiff; +/*N*/ else +/*N*/ rRegStart += nTmpDiff; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return ( 0 != rRegDiff ); +/*N*/ } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_portox.cxx b/binfilter/bf_sw/source/core/text/sw_portox.cxx new file mode 100644 index 000000000000..bbee93f6a2c3 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_portox.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "portox.hxx" +namespace binfilter { + +/************************************************************************* + * virtual SwToxPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * class SwIsoToxPortion + *************************************************************************/ + +/*N*/ SwLinePortion *SwIsoToxPortion::Compress() { return this; } +/*N*/ +/*N*/ SwIsoToxPortion::SwIsoToxPortion() : nViewWidth(0) +/*N*/ { +/*N*/ SetLen(1); +/*N*/ SetWhichPor( POR_ISOTOX ); +/*N*/ } + +/************************************************************************* + * virtual SwIsoToxPortion::GetViewWidth() + *************************************************************************/ + + +/************************************************************************* + * virtual SwIsoToxPortion::Format() + *************************************************************************/ + +/*N*/ sal_Bool SwIsoToxPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ const sal_Bool bFull = SwLinePortion::Format( rInf ); +/*N*/ return bFull; +/*N*/ } + +/************************************************************************* + * virtual SwIsoToxPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * virtual SwIsoToxPortion::HandlePortion() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_portxt.cxx b/binfilter/bf_sw/source/core/text/sw_portxt.cxx new file mode 100644 index 000000000000..61ad29f01086 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_portxt.cxx @@ -0,0 +1,633 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <ctype.h> + +#include <com/sun/star/i18n/ScriptType.hdl> +#include <inftxt.hxx> +#include <guess.hxx> // SwTxtGuess, Zeilenumbruch + +#include <horiornt.hxx> + +#include <porfld.hxx> // SwFldPortion +namespace binfilter { + +#if OSL_DEBUG_LEVEL > 1 +const sal_Char *GetLangName( const MSHORT nLang ); +#endif + +using namespace ::com::sun::star::i18n::ScriptType; + +/************************************************************************* + * lcl_AddSpace + * Returns for how many characters an extra space has to be added + * (for justified alignment). + *************************************************************************/ + +/*N*/ USHORT lcl_AddSpace( const SwTxtSizeInfo &rInf, const XubString* pStr, +/*N*/ const SwLinePortion& rPor ) +/*N*/ { +/*N*/ xub_StrLen nPos, nEnd; +/*N*/ const SwScriptInfo* pSI = 0; +/*N*/ +/*N*/ if ( pStr ) +/*N*/ { +/*N*/ // passing a string means we are inside a field +/*?*/ nPos = 0; +/*?*/ nEnd = pStr->Len(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nPos = rInf.GetIdx(); +/*N*/ nEnd = rInf.GetIdx() + rPor.GetLen(); +/*N*/ pStr = &rInf.GetTxt(); +/*N*/ pSI = &((SwParaPortion*)rInf.GetParaPortion())->GetScriptInfo(); +/*N*/ } +/*N*/ +/*N*/ USHORT nCnt = 0; +/*N*/ BYTE nScript = 0; +/*N*/ +/*N*/ // If portion consists of Asian characters and language is not +/*N*/ // Korean, we add extra space to each character. +/*N*/ // first we get the script type +/*N*/ if ( pSI ) +/*N*/ nScript = pSI->ScriptType( nPos ); +/*N*/ else if ( pBreakIt->xBreak.is() ) +/*?*/ nScript = (BYTE)pBreakIt->xBreak->getScriptType( *pStr, nPos ); +/*N*/ +/*N*/ // Note: rInf.GetIdx() can differ from nPos, +/*N*/ // e.g., when rPor is a field portion. nPos referes to the string passed +/*N*/ // to the function, rInf.GetIdx() referes to the original string. +/*N*/ +/*N*/ // We try to find out which justification mode is required. This is done by +/*N*/ // evaluating the script type and the language attribute set for this portion +/*N*/ +/*N*/ // Asian Justification: Each character get some extra space +/*N*/ if ( nEnd > nPos && ASIAN == nScript ) +/*N*/ { +/*N*/ LanguageType aLang = +/*N*/ rInf.GetTxtFrm()->GetTxtNode()->GetLang( rInf.GetIdx(), 1, nScript ); +/*N*/ +/*N*/ if ( LANGUAGE_KOREAN != aLang && LANGUAGE_KOREAN_JOHAB != aLang ) +/*N*/ { +/*N*/ const SwLinePortion* pPor = rPor.GetPortion(); +/*N*/ if ( pPor && pPor->IsKernPortion() ) +/*N*/ pPor = pPor->GetPortion(); +/*N*/ +/*N*/ nCnt += nEnd - nPos; +/*N*/ +/*N*/ if ( !pPor || pPor->IsHolePortion() || pPor->InFixMargGrp() || +/*N*/ pPor->IsBreakPortion() ) +/*N*/ --nCnt; +/*N*/ +/*N*/ return nCnt; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Thai Justification: Each character cell gets some extra space +/*N*/ if ( nEnd > nPos && COMPLEX == nScript ) +/*N*/ { +/*N*/ LanguageType aLang = +/*N*/ rInf.GetTxtFrm()->GetTxtNode()->GetLang( rInf.GetIdx(), 1, nScript ); +/*N*/ +/*N*/ if ( LANGUAGE_THAI == aLang ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ nCnt = SwScriptInfo::ThaiJustify( *pStr, 0, 0, nPos, nEnd - nPos ); +/*?*/ return nCnt; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ #ifdef BIDI +/*N*/ // Kashida Justification: Insert Kashidas +/*N*/ if ( nEnd > nPos && pSI && COMPLEX == nScript ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ LanguageType aLang = +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ // Here starts the good old "Look for blanks and add space to them" part. +/*N*/ // Note: We do not want to add space to an isolated latin blank in front +/*N*/ // of some complex characters in RTL environment +/*N*/ const sal_Bool bDoNotAddSpace = +/*N*/ LATIN == nScript && ( nEnd == nPos + 1 ) && pSI && +/*N*/ ( ::com::sun::star::i18n::ScriptType::COMPLEX == +/*N*/ pSI->ScriptType( nPos + 1 ) ) && +/*N*/ rInf.GetTxtFrm() && rInf.GetTxtFrm()->IsRightToLeft(); +/*N*/ +/*N*/ if ( bDoNotAddSpace ) +/*N*/ return nCnt; +/*N*/ +/*N*/ for ( ; nPos < nEnd; ++nPos ) +/*N*/ { +/*N*/ if( CH_BLANK == pStr->GetChar( nPos ) ) +/*N*/ ++nCnt; +/*N*/ } +/*N*/ +/*N*/ // We still have to examine the next character: +/*N*/ // If the next character is ASIAN and not KOREAN we have +/*N*/ // to add an extra space +/*N*/ // nPos referes to the original string, even if a field string has +/*N*/ // been passed to this function +/*N*/ nPos = rInf.GetIdx() + rPor.GetLen(); +/*N*/ if ( nPos < rInf.GetTxt().Len() ) +/*N*/ { +/*N*/ BYTE nNextScript = 0; +/*N*/ const SwLinePortion* pPor = rPor.GetPortion(); +/*N*/ if ( pPor && pPor->IsKernPortion() ) +/*?*/ pPor = pPor->GetPortion(); +/*N*/ +/*N*/ if ( ! pBreakIt->xBreak.is() || ! pPor || pPor->InFixMargGrp() ) +/*N*/ return nCnt; +/*N*/ +/*N*/ // next character is inside a field? +/*N*/ if ( CH_TXTATR_BREAKWORD == rInf.GetChar( nPos ) && pPor->InExpGrp() ) +/*N*/ { +/*?*/ sal_Bool bOldOnWin = rInf.OnWin(); +/*?*/ ((SwTxtSizeInfo &)rInf).SetOnWin( sal_False ); +/*?*/ +/*?*/ XubString aStr( aEmptyStr ); +/*?*/ pPor->GetExpTxt( rInf, aStr ); +/*?*/ ((SwTxtSizeInfo &)rInf).SetOnWin( bOldOnWin ); +/*?*/ +/*?*/ nNextScript = (BYTE)pBreakIt->xBreak->getScriptType( aStr, 0 ); +/*N*/ } +/*N*/ else +/*N*/ nNextScript = (BYTE)pBreakIt->xBreak->getScriptType( rInf.GetTxt(), nPos ); +/*N*/ +/*N*/ if( ASIAN == nNextScript ) +/*N*/ { +/*?*/ LanguageType aLang = +/*?*/ rInf.GetTxtFrm()->GetTxtNode()->GetLang( nPos, 1, nNextScript ); +/*?*/ +/*?*/ if ( LANGUAGE_KOREAN != aLang && LANGUAGE_KOREAN_JOHAB != aLang ) +/*?*/ ++nCnt; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return nCnt; +/*N*/ } + +/************************************************************************* + * class SwTxtPortion + *************************************************************************/ + +/*N*/ SwTxtPortion::SwTxtPortion( const SwLinePortion &rPortion ) +/*N*/ : SwLinePortion( rPortion ) +/*N*/ { +/*N*/ SetWhichPor( POR_TXT ); +/*N*/ } + +/************************************************************************* + * SwTxtPortion::BreakCut() + *************************************************************************/ + +/*N*/ void SwTxtPortion::BreakCut( SwTxtFormatInfo &rInf, const SwTxtGuess &rGuess ) +/*N*/ { +/*N*/ // Das Wort/Zeichen ist groesser als die Zeile +/*N*/ // Sonderfall Nr.1: Das Wort ist groesser als die Zeile +/*N*/ // Wir kappen... +/*N*/ const KSHORT nLineWidth = (KSHORT)(rInf.Width() - rInf.X()); +/*N*/ xub_StrLen nLen = rGuess.CutPos() - rInf.GetIdx(); +/*N*/ if( nLen ) +/*N*/ { +/*N*/ // special case: guess does not always provide the correct +/*N*/ // width, only in common cases. +/*N*/ if ( !rGuess.BreakWidth() ) +/*N*/ { +/*N*/ rInf.SetLen( nLen ); +/*N*/ SetLen( nLen ); +/*N*/ CalcTxtSize( rInf ); +/*N*/ +/*N*/ // changing these values requires also changing them in +/*N*/ // guess.cxx +/*N*/ KSHORT nItalic = 0; +/*N*/ if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() ) +/*N*/ { +/*N*/ #ifdef MAC +/*N*/ nItalic = Height() / 4; +/*N*/ #else +/*N*/ nItalic = Height() / 12; +/*N*/ #endif +/*N*/ } +/*N*/ Width( Width() + nItalic ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Width( rGuess.BreakWidth() ); +/*N*/ SetLen( nLen ); +/*N*/ } +/*N*/ } +/*N*/ // special case: first character does not fit to line +/*N*/ else if ( rGuess.CutPos() == rInf.GetLineStart() ) +/*N*/ { +/*N*/ SetLen( 1 ); +/*N*/ Width( nLineWidth ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SetLen( 0 ); +/*N*/ Width( 0 ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtPortion::BreakUnderflow() + *************************************************************************/ + +/*N*/ void SwTxtPortion::BreakUnderflow( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ Truncate(); +/*N*/ Height( 0 ); +/*N*/ Width( 0 ); +/*N*/ SetLen( 0 ); +/*N*/ SetAscent( 0 ); +/*N*/ rInf.SetUnderFlow( this ); +/*N*/ } + + /************************************************************************* + * SwTxtPortion::_Format() + *************************************************************************/ + +/*N*/ sal_Bool lcl_HasContent( const SwFldPortion& rFld, SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ String aTxt; +/*N*/ return rFld.GetExpTxt( rInf, aTxt ) && aTxt.Len(); +/*N*/ } + +/*M*/ sal_Bool SwTxtPortion::_Format( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ // 5744: wenn nur der Trennstrich nicht mehr passt, +/*M*/ // muss trotzdem das Wort umgebrochen werden, ansonsten return sal_True! +/*M*/ if( rInf.IsUnderFlow() && rInf.GetSoftHyphPos() ) +/*M*/ { +/*M*/ // soft hyphen portion has triggered an underflow event because +/*M*/ // of an alternative spelling position +/*M*/ sal_Bool bFull = sal_False; +/*M*/ const sal_Bool bHyph = rInf.ChgHyph( sal_True ); +/*M*/ if( rInf.IsHyphenate() ) +/*M*/ { +/*M*/ SwTxtGuess aGuess; +/*M*/ // check for alternative spelling left from the soft hyphen +/*M*/ // this should usually be true but +/*M*/ aGuess.AlternativeSpelling( rInf, rInf.GetSoftHyphPos() - 1 ); +/*M*/ bFull = CreateHyphen( rInf, aGuess ); +/*M*/ ASSERT( bFull, "Problem with hyphenation!!!" ); +/*M*/ } +/*M*/ rInf.ChgHyph( bHyph ); +/*M*/ rInf.SetSoftHyphPos( 0 ); +/*M*/ return bFull; +/*M*/ } +/*M*/ +/*M*/ SwTxtGuess aGuess; +/*M*/ const sal_Bool bFull = !aGuess.Guess( *this, rInf, Height() ); +/*M*/ +/*M*/ // these are the possible cases: +/*M*/ // A Portion fits to current line +/*M*/ // B Portion does not fit to current line but a possible line break +/*M*/ // within the portion has been found by the break iterator, 2 subcases +/*M*/ // B1 break is hyphen +/*M*/ // B2 break is word end +/*M*/ // C Portion does not fit to current line and no possible line break +/*M*/ // has been found by break iterator, 2 subcases: +/*M*/ // C1 break iterator found a possible line break in portion before us +/*M*/ // ==> this break is used (underflow) +/*M*/ // C2 break iterator does not found a possible line break at all: +/*M*/ // ==> line break +/*M*/ +/*M*/ // case A: line not yet full +/*M*/ if ( !bFull ) +/*M*/ { +/*M*/ Width( aGuess.BreakWidth() ); +/*M*/ // Vorsicht ! +/*M*/ if( !InExpGrp() || InFldGrp() ) +/*M*/ SetLen( rInf.GetLen() ); +/*M*/ +/*M*/ short nKern = rInf.GetFont()->CheckKerning(); +/*M*/ if( nKern > 0 && rInf.Width() < rInf.X() + Width() + nKern ) +/*M*/ { +/*N*/ nKern = rInf.Width() - rInf.X() - Width() - 1; +/*M*/ if( nKern < 0 ) +/*M*/ nKern = 0; +/*M*/ } +/*M*/ if( nKern ) +/*M*/ new SwKernPortion( *this, nKern ); +/*M*/ } +/*M*/ // special case: hanging portion +/*M*/ else if( bFull && aGuess.GetHangingPortion() ) +/*M*/ { +/*M*/ Width( aGuess.BreakWidth() ); +/*M*/ SetLen( aGuess.BreakPos() - rInf.GetIdx() ); +/*M*/ Insert( aGuess.GetHangingPortion() ); +/*M*/ aGuess.GetHangingPortion()->SetAscent( GetAscent() ); +/*M*/ aGuess.ClearHangingPortion(); +/*M*/ } +/*M*/ // breakPos >= index +/*M*/ else if ( aGuess.BreakPos() >= rInf.GetIdx() && aGuess.BreakPos() != STRING_LEN ) +/*M*/ { +/*M*/ // case B1 +/*N*/ if( aGuess.HyphWord().is() && aGuess.BreakPos() > rInf.GetLineStart() +/*N*/ && ( aGuess.BreakPos() > rInf.GetIdx() || +/*M*/ ( rInf.GetLast() && ! rInf.GetLast()->IsFlyPortion() ) ) ) +/*M*/ { +/*M*/ CreateHyphen( rInf, aGuess ); +/*M*/ if ( rInf.GetFly() ) +/*M*/ rInf.GetRoot()->SetMidHyph( sal_True ); +/*M*/ else +/*M*/ rInf.GetRoot()->SetEndHyph( sal_True ); +/*M*/ } +/*M*/ // case C1 +/*M*/ else if ( IsFtnPortion() && rInf.IsFakeLineStart() ) +/*M*/ BreakUnderflow( rInf ); +/*M*/ // case B2 +/*M*/ else if( rInf.GetIdx() > rInf.GetLineStart() || +/*M*/ aGuess.BreakPos() > rInf.GetIdx() || +/*M*/ // this is weird: during formatting the follow of a field +/*M*/ // the values rInf.GetIdx and rInf.GetLineStart are replaced +/*M*/ // IsFakeLineStart indicates GetIdx > GetLineStart +/*M*/ rInf.IsFakeLineStart() || +/*M*/ rInf.GetFly() || +/*M*/ rInf.IsFirstMulti() || +/*M*/ ( rInf.GetLast() && +/*M*/ ( rInf.GetLast()->IsFlyPortion() || +/*M*/ ( rInf.GetLast()->InFldGrp() && +/*M*/ ! rInf.GetLast()->InNumberGrp() && +/*M*/ ! rInf.GetLast()->IsErgoSumPortion() && +/*M*/ lcl_HasContent(*((SwFldPortion*)rInf.GetLast()),rInf ) ) ) ) ) +/*M*/ { +/*M*/ if ( rInf.X() + aGuess.BreakWidth() <= rInf.Width() ) +/*M*/ Width( aGuess.BreakWidth() ); +/*M*/ else +/*M*/ // this actually should not happen +/*M*/ Width( KSHORT(rInf.Width() - rInf.X()) ); +/*M*/ +/*M*/ SetLen( aGuess.BreakPos() - rInf.GetIdx() ); +/*M*/ +/*M*/ ASSERT( aGuess.BreakStart() >= aGuess.FieldDiff(), +/*M*/ "Trouble with expanded field portions during line break" ); +/*M*/ const xub_StrLen nRealStart = aGuess.BreakStart() - aGuess.FieldDiff(); +/*N*/ if( aGuess.BreakPos() < nRealStart && !InExpGrp() ) +/*M*/ { +/*M*/ SwHolePortion *pNew = new SwHolePortion( *this ); +/*M*/ pNew->SetLen( nRealStart - aGuess.BreakPos() ); +/*M*/ Insert( pNew ); +/*M*/ } +/*M*/ } +/*M*/ else // case C2, last exit +/*M*/ BreakCut( rInf, aGuess ); +/*M*/ } +/*M*/ // breakPos < index or no breakpos at all +/*M*/ else +/*M*/ { +/*M*/ sal_Bool bFirstPor = rInf.GetLineStart() == rInf.GetIdx(); +/*M*/ if( aGuess.BreakPos() != STRING_LEN && +/*M*/ aGuess.BreakPos() != rInf.GetLineStart() && +/*M*/ ( !bFirstPor || rInf.GetFly() || rInf.GetLast()->IsFlyPortion() || +/*M*/ rInf.IsFirstMulti() ) && +/*M*/ ( !rInf.GetLast()->IsBlankPortion() || ((SwBlankPortion*) +/*M*/ rInf.GetLast())->MayUnderFlow( rInf, rInf.GetIdx()-1, sal_True ))) +/*M*/ { // case C1 (former BreakUnderflow()) +/*M*/ BreakUnderflow( rInf ); +/*M*/ } +/*M*/ else +/*M*/ // case C2, last exit +/*M*/ BreakCut( rInf, aGuess ); +/*M*/ } +/*M*/ +/*M*/ return bFull; +/*M*/ } + +/************************************************************************* + * virtual SwTxtPortion::Format() + *************************************************************************/ + + + +/*N*/ sal_Bool SwTxtPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const XubString aDbgTxt( rInf.GetTxt().Copy( rInf.GetIdx(), rInf.GetLen() ) ); +/*N*/ #endif +/*N*/ +/*N*/ if( rInf.X() > rInf.Width() || (!GetLen() && !InExpGrp()) ) +/*N*/ { +/*N*/ Height( 0 ); +/*N*/ Width( 0 ); +/*N*/ SetLen( 0 ); +/*N*/ SetAscent( 0 ); +/*N*/ SetPortion( NULL ); // ???? +/*N*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ ASSERT( rInf.RealWidth() || (rInf.X() == rInf.Width()), +/*N*/ "SwTxtPortion::Format: missing real width" ); +/*N*/ ASSERT( Height(), "SwTxtPortion::Format: missing height" ); +/*N*/ +/*N*/ return _Format( rInf ); +/*N*/ } + +/************************************************************************* + * virtual SwTxtPortion::FormatEOL() + *************************************************************************/ + +// Format end of line +// 5083: Es kann schon manchmal unguenstige Faelle geben... +// "vom {Nikolaus}", Nikolaus bricht um "vom " wird im Blocksatz +// zu "vom" und " ", wobei der Glue expandiert wird, statt in die +// MarginPortion aufzugehen. +// rInf.nIdx steht auf dem naechsten Wort, nIdx-1 ist der letzte +// Buchstabe der Portion. + + + +/*N*/ void SwTxtPortion::FormatEOL( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ #ifndef USED +/*N*/ if( ( !GetPortion() || ( GetPortion()->IsKernPortion() && +/*N*/ !GetPortion()->GetPortion() ) ) && GetLen() && +/*N*/ rInf.GetIdx() < rInf.GetTxt().Len() && +/*N*/ 1 < rInf.GetIdx() && ' ' == rInf.GetChar( rInf.GetIdx() - 1 ) +/*N*/ #else +/*N*/ if( !GetPortion() && 1 < GetLen() && +/*N*/ rInf.GetIdx() < rInf.GetTxt().Len() && +/*N*/ 1 < rInf.GetIdx() && ' ' == rInf.GetTxt()[xub_StrLen(rInf.GetIdx()-1)] +/*N*/ && !rInf.GetFly() +/*N*/ #endif +/*N*/ +/*N*/ && !rInf.GetLast()->IsHolePortion() ) +/*N*/ { +/*N*/ // calculate number of blanks +/*?*/ xub_StrLen nX = rInf.GetIdx() - 1; +/*?*/ USHORT nHoleLen = 1; +/*?*/ while( nX && nHoleLen < GetLen() && CH_BLANK == rInf.GetChar( --nX ) ) +/*?*/ nHoleLen++; +/*?*/ +/*?*/ // Erst uns einstellen und dann Inserten, weil wir ja auch ein +/*?*/ // SwLineLayout sein koennten. +/*?*/ KSHORT nBlankSize; +/*?*/ if( nHoleLen == GetLen() ) +/*?*/ nBlankSize = Width(); +/*?*/ else +/*?*/ nBlankSize = nHoleLen * rInf.GetTxtSize( ' ' ).Width(); +/*?*/ Width( Width() - nBlankSize ); +/*?*/ rInf.X( rInf.X() - nBlankSize ); +/*?*/ SetLen( GetLen() - nHoleLen ); +/*?*/ SwLinePortion *pHole = new SwHolePortion( *this ); +/*?*/ ( (SwHolePortion *)pHole )->SetBlankWidth( nBlankSize ); +/*?*/ ( (SwHolePortion *)pHole )->SetLen( nHoleLen ); +/*?*/ Insert( pHole ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * virtual SwTxtPortion::GetCrsrOfst() + *************************************************************************/ + + + + +/************************************************************************* + * SwTxtPortion::GetCrsrOfst() + *************************************************************************/ + + +/************************************************************************* + * virtual SwTxtPortion::GetTxtSize() + *************************************************************************/ +// Das GetTxtSize() geht davon aus, dass die eigene Laenge korrekt ist + +/*N*/ SwPosSize SwTxtPortion::GetTxtSize( const SwTxtSizeInfo &rInf ) const +/*N*/ { +/*N*/ return rInf.GetTxtSize(); +/*N*/ } + +/************************************************************************* + * virtual SwTxtPortion::Paint() + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwTxtPortion::GetExpTxt() + *************************************************************************/ + + + +/*N*/ sal_Bool SwTxtPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * xub_StrLen SwTxtPortion::GetSpaceCnt() + * long SwTxtPortion::CalcSpacing() + * sind fuer den Blocksatz zustaendig und ermitteln die Anzahl der Blanks + * und den daraus resultierenden zusaetzlichen Zwischenraum + *************************************************************************/ + +/*N*/ xub_StrLen SwTxtPortion::GetSpaceCnt( const SwTxtSizeInfo &rInf, +/*N*/ xub_StrLen& rCharCnt ) const +/*N*/ { +/*N*/ xub_StrLen nCnt = 0; +/*N*/ xub_StrLen nPos = 0; +/*N*/ if ( InExpGrp() ) +/*N*/ { +/*?*/ if( !IsBlankPortion() && !InNumberGrp() && !IsCombinedPortion() ) +/*?*/ { +/*?*/ // Bei OnWin() wird anstatt eines Leerstrings gern mal ein Blank +/*?*/ // zurueckgeliefert, das koennen wir hier aber gar nicht gebrauchen +/*?*/ sal_Bool bOldOnWin = rInf.OnWin(); +/*?*/ ((SwTxtSizeInfo &)rInf).SetOnWin( sal_False ); +/*?*/ +/*?*/ XubString aStr( aEmptyStr ); +/*?*/ GetExpTxt( rInf, aStr ); +/*?*/ ((SwTxtSizeInfo &)rInf).SetOnWin( bOldOnWin ); +/*?*/ +/*?*/ nCnt += lcl_AddSpace( rInf, &aStr, *this ); +/*?*/ nPos = aStr.Len(); +/*?*/ } +/*N*/ } +/*N*/ else if( !IsDropPortion() ) +/*N*/ { +/*N*/ nCnt += lcl_AddSpace( rInf, 0, *this ); +/*N*/ nPos = GetLen(); +/*N*/ } +/*N*/ rCharCnt += nPos; +/*N*/ return nCnt; +/*N*/ } + + +/************************************************************************* + * virtual SwTxtPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * class SwHolePortion + *************************************************************************/ + + + +/*N*/ SwHolePortion::SwHolePortion( const SwTxtPortion &rPor ) +/*N*/ : nBlankWidth( 0 ) +/*N*/ { +/*N*/ SetLen( 1 ); +/*N*/ Height( rPor.Height() ); +/*N*/ SetAscent( rPor.GetAscent() ); +/*N*/ SetWhichPor( POR_HOLE ); +/*N*/ } + +/*N*/ SwLinePortion *SwHolePortion::Compress() { return this; } + +/************************************************************************* + * virtual SwHolePortion::Paint() + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwHolePortion::Format() + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwHolePortion::HandlePortion() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_redlnitr.cxx b/binfilter/bf_sw/source/core/text/sw_redlnitr.cxx new file mode 100644 index 000000000000..ab555414dcb0 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_redlnitr.cxx @@ -0,0 +1,207 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <com/sun/star/i18n/ScriptType.hdl> + + +#include <errhdl.hxx> + +#include <itratr.hxx> // SwAttrIter +#include <ndtxt.hxx> // SwTxtNode + +#include <horiornt.hxx> + +#include <doc.hxx> // SwDoc +#include <frmsh.hxx> +#include <breakit.hxx> + +////////////////////////// + + + +#include <txtfrm.hxx> // SwTxtFrm +#include <redlnitr.hxx> +#include <extinput.hxx> + +namespace binfilter { + +using namespace ::com::sun::star; + +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +/************************************************************************* + * SwAttrIter::CtorInit() + *************************************************************************/ +/*N*/ void SwAttrIter::CtorInit( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf, SwTxtFrm* pFrm ) +/*N*/ { +/*N*/ // Beim HTML-Import kann es vorkommen, dass kein Layout existiert. +/*N*/ SwRootFrm *pRootFrm = rTxtNode.GetDoc()->GetRootFrm(); +/*N*/ pShell = pRootFrm ? pRootFrm->GetShell() : 0; +/*N*/ +/*N*/ pScriptInfo = &rScrInf; +/*N*/ pAttrSet = &rTxtNode.GetSwAttrSet(); +/*N*/ pHints = rTxtNode.GetpSwpHints(); +/*N*/ +/*N*/ SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pShell ); +/*N*/ +/*N*/ delete pFnt; +/*N*/ pFnt = new SwFont( *aFontAccess.Get()->GetFont() ); +/*N*/ +/*N*/ // set font to vertical if frame layout is vertical +/*N*/ sal_Bool bVertLayout = sal_False; +/*N*/ sal_Bool bRTL = sal_False; +/*N*/ if ( pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsVertical() ) +/*N*/ { +/*N*/ bVertLayout = sal_True; +/*N*/ pFnt->SetVertical( pFnt->GetOrientation(), sal_True ); +/*N*/ } +/*N*/ bRTL = pFrm->IsRightToLeft(); +/*N*/ } +/*N*/ +/*N*/ // Initialize the default attribute of the attribute handler +/*N*/ // based on the attribute array cached together with the font. +/*N*/ // If any further attributes for the paragraph are given in pAttrSet +/*N*/ // consider them during construction of the default array, and apply +/*N*/ // them to the font +/*N*/ aAttrHandler.Init( aFontAccess.Get()->GetDefault(), +/*N*/ rTxtNode.HasSwAttrSet() ? pAttrSet : 0, +/*N*/ *rTxtNode.GetDoc(), pShell, *pFnt, bVertLayout ); +/*N*/ +/*N*/ aMagicNo[SW_LATIN] = aMagicNo[SW_CJK] = aMagicNo[SW_CTL] = NULL; +/*N*/ +/*N*/ // determine script changes if not already done for current paragraph +/*N*/ ASSERT( pScriptInfo, "No script info available"); +/*N*/ if ( pScriptInfo->GetInvalidity() != STRING_LEN ) +/*N*/ pScriptInfo->InitScriptInfo( rTxtNode, bRTL ); +/*N*/ +/*N*/ if ( pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ pFnt->SetActual( WhichFont( 0, 0, pScriptInfo ) ); +/*N*/ +/*N*/ xub_StrLen nChg = 0; +/*N*/ USHORT nCnt = 0; +/*N*/ +/*N*/ do +/*N*/ { +/*N*/ nChg = pScriptInfo->GetScriptChg( nCnt ); +/*N*/ USHORT nScript = pScriptInfo->GetScriptType( nCnt++ ); +/*N*/ BYTE nTmp = 4; +/*N*/ switch ( nScript ) { +/*N*/ case i18n::ScriptType::ASIAN : +/*N*/ if( !aMagicNo[SW_CJK] ) nTmp = SW_CJK; break; +/*N*/ case i18n::ScriptType::COMPLEX : +/*N*/ if( !aMagicNo[SW_CTL] ) nTmp = SW_CTL; break; +/*N*/ default: +/*N*/ if( !aMagicNo[SW_LATIN ] ) nTmp = SW_LATIN; +/*N*/ } +/*N*/ if( nTmp < 4 ) +/*N*/ { +/*N*/ pFnt->ChkMagic( pShell, nTmp ); +/*N*/ pFnt->GetMagic( aMagicNo[ nTmp ], aFntIdx[ nTmp ], nTmp ); +/*N*/ } +/*N*/ } while( nChg < rTxtNode.GetTxt().Len() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFnt->ChkMagic( pShell, SW_LATIN ); +/*N*/ pFnt->GetMagic( aMagicNo[ SW_LATIN ], aFntIdx[ SW_LATIN ], SW_LATIN ); +/*N*/ } +/*N*/ +/*N*/ nStartIndex = nEndIndex = nPos = nChgCnt = 0; +/*N*/ nPropFont = 0; +/*N*/ SwDoc* pDoc = rTxtNode.GetDoc(); +/*N*/ +/*N*/ const SwExtTextInput* pExtInp = pDoc->GetExtTextInput( rTxtNode ); +/*N*/ sal_Bool bShow = ::binfilter::IsShowChanges( pDoc->GetRedlineMode() ); +/*N*/ if( pExtInp || bShow ) +/*N*/ { +/*N*/ MSHORT nRedlPos = pDoc->GetRedlinePos( rTxtNode ); +/*N*/ if( pExtInp || MSHRT_MAX != nRedlPos ) +/*N*/ { +/*N*/ const SvUShorts* pArr = 0; +/*N*/ xub_StrLen nInputStt = 0; +/*N*/ if( pExtInp ) +/*N*/ { +/*N*/ pArr = &pExtInp->GetAttrs(); +/*N*/ nInputStt = pExtInp->Start()->nContent.GetIndex(); +/*N*/ Seek( 0 ); +/*N*/ } +/*N*/ +/*N*/ pRedln = new SwRedlineItr( rTxtNode, *pFnt, aAttrHandler, nRedlPos, +/*N*/ bShow, pArr, nInputStt ); +/*N*/ +/*N*/ if( pRedln->IsOn() ) +/*N*/ ++nChgCnt; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwRedlineItr - Der Redline-Iterator + * + * Folgende Informationen/Zustaende gibt es im RedlineIterator: + * + * nFirst ist der erste Index der RedlineTbl, der mit dem Absatz ueberlappt. + * + * nAct ist der zur Zeit aktive ( wenn bOn gesetzt ist ) oder der naechste + * in Frage kommende Index. + * nStart und nEnd geben die Grenzen des Objekts innerhalb des Absatzes an. + * + * Wenn bOn gesetzt ist, ist der Font entsprechend manipuliert worden. + * + * Wenn nAct auf MSHRT_MAX gesetzt wurde ( durch Reset() ), so ist zur Zeit + * kein Redline aktiv, nStart und nEnd sind invalid. + *************************************************************************/ + + + +// Der Return-Wert von SwRedlineItr::Seek gibt an, ob der aktuelle Font +// veraendert wurde durch Verlassen (-1) oder Betreten eines Bereichs (+1) + + + + + + + + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtcache.cxx b/binfilter/bf_sw/source/core/text/sw_txtcache.cxx new file mode 100644 index 000000000000..67822796b6a3 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtcache.cxx @@ -0,0 +1,244 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "txtcache.hxx" +#include "txtfrm.hxx" +#include "porlay.hxx" +namespace binfilter { + +/************************************************************************* +|* +|* SwTxtLine::SwTxtLine(), ~SwTxtLine() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 16. Mar. 94 +|* +|*************************************************************************/ + +/*N*/ SwTxtLine::SwTxtLine( SwTxtFrm *pFrm, SwParaPortion *pNew ) : +/*N*/ SwCacheObj( (void*)pFrm ), +/*N*/ pLine( pNew ) +/*N*/ { +/*N*/ } +/*N*/ +/*N*/ SwTxtLine::~SwTxtLine() +/*N*/ { +/*N*/ delete pLine; +/*N*/ } + +/************************************************************************* +|* +|* SwTxtLineAccess::NewObj() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 16. Mar. 94 +|* +|*************************************************************************/ + +/*N*/ SwCacheObj *SwTxtLineAccess::NewObj() +/*N*/ { +/*N*/ return new SwTxtLine( (SwTxtFrm*)pOwner ); +/*N*/ } + +/************************************************************************* +|* +|* SwTxtLineAccess::GetPara() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 16. Mar. 94 +|* +|*************************************************************************/ + +/*N*/ SwParaPortion *SwTxtLineAccess::GetPara() +/*N*/ { +/*N*/ SwTxtLine *pRet; +/*N*/ if ( pObj ) +/*N*/ pRet = (SwTxtLine*)pObj; +/*N*/ else +/*N*/ { +/*N*/ pRet = (SwTxtLine*)Get(); +/*N*/ ((SwTxtFrm*)pOwner)->SetCacheIdx( pRet->GetCachePos() ); +/*N*/ } +/*N*/ if ( !pRet->GetPara() ) +/*N*/ pRet->SetPara( new SwParaPortion ); +/*N*/ return pRet->GetPara(); +/*N*/ } + + +/************************************************************************* +|* +|* SwTxtLineAccess::SwTxtLineAccess() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 16. Mar. 94 +|* +|*************************************************************************/ + +/*N*/ SwTxtLineAccess::SwTxtLineAccess( const SwTxtFrm *pOwner ) : +/*N*/ SwCacheAccess( *SwTxtFrm::GetTxtCache(), pOwner, pOwner->GetCacheIdx() ) +/*N*/ { +/*N*/ } + +/************************************************************************* +|* +|* SwTxtLineAccess::IsAvailable +|* +|* Ersterstellung MA 23. Mar. 94 +|* Letzte Aenderung MA 23. Mar. 94 +|* +|*************************************************************************/ + +/*N*/ sal_Bool SwTxtLineAccess::IsAvailable() const +/*N*/ { +/*N*/ if ( pObj ) +/*N*/ return ((SwTxtLine*)pObj)->GetPara() != 0; +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* +|* +|* SwTxtFrm::HasPara() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 22. Aug. 94 +|* +|*************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::_HasPara() const +/*N*/ { +/*N*/ SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()-> +/*N*/ Get( this, GetCacheIdx(), sal_False ); +/*N*/ if ( pTxtLine ) +/*N*/ { +/*N*/ if ( pTxtLine->GetPara() ) +/*N*/ return sal_True; +/*N*/ } +/*N*/ else +/*N*/ ((SwTxtFrm*)this)->nCacheIdx = MSHRT_MAX; +/*N*/ +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* +|* +|* SwTxtFrm::GetPara() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 22. Aug. 94 +|* +|*************************************************************************/ + +/*N*/ SwParaPortion *SwTxtFrm::GetPara() +/*N*/ { +/*N*/ if ( GetCacheIdx() != MSHRT_MAX ) +/*N*/ { SwTxtLine *pLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()-> +/*N*/ Get( this, GetCacheIdx(), sal_False ); +/*N*/ if ( pLine ) +/*N*/ return pLine->GetPara(); +/*N*/ else +/*N*/ nCacheIdx = MSHRT_MAX; +/*N*/ } +/*N*/ return 0; +/*N*/ } + + +/************************************************************************* +|* +|* SwTxtFrm::ClearPara() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 22. Aug. 94 +|* +|*************************************************************************/ + +/*N*/ void SwTxtFrm::ClearPara() +/*N*/ { +/*N*/ ASSERT( !IsLocked(), "+SwTxtFrm::ClearPara: this is locked." ); +/*N*/ if ( !IsLocked() && GetCacheIdx() != MSHRT_MAX ) +/*N*/ { +/*N*/ SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()-> +/*N*/ Get( this, GetCacheIdx(), sal_False ); +/*N*/ if ( pTxtLine ) +/*N*/ { +/*N*/ delete pTxtLine->GetPara(); +/*N*/ pTxtLine->SetPara( 0 ); +/*N*/ } +/*N*/ else +/*N*/ nCacheIdx = MSHRT_MAX; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +|* SwTxtFrm::SetPara() +|* +|* Ersterstellung MA 16. Mar. 94 +|* Letzte Aenderung MA 22. Aug. 94 +|* +|*************************************************************************/ + +/*N*/ void SwTxtFrm::SetPara( SwParaPortion *pNew, sal_Bool bDelete ) +/*N*/ { +/*N*/ if ( GetCacheIdx() != MSHRT_MAX ) +/*N*/ { +/*N*/ //Nur die Information Auswechseln, das CacheObj bleibt stehen. +/*N*/ SwTxtLine *pTxtLine = (SwTxtLine*)SwTxtFrm::GetTxtCache()-> +/*N*/ Get( this, GetCacheIdx(), sal_False ); +/*N*/ if ( pTxtLine ) +/*N*/ { +/*N*/ if( bDelete ) +/*N*/ delete pTxtLine->GetPara(); +/*N*/ pTxtLine->SetPara( pNew ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ASSERT( !pNew, "+SetPara: Losing SwParaPortion" ); +/*?*/ nCacheIdx = MSHRT_MAX; +/*N*/ } +/*N*/ } +/*N*/ else if ( pNew ) +/*N*/ { //Einen neuen einfuegen. +/*N*/ SwTxtLine *pTxtLine = new SwTxtLine( this, pNew ); +/*N*/ if ( SwTxtFrm::GetTxtCache()->Insert( pTxtLine ) ) +/*N*/ nCacheIdx = pTxtLine->GetCachePos(); +/*N*/ else +/*N*/ { +/*?*/ ASSERT( sal_False, "+SetPara: InsertCache failed." ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtdrop.cxx b/binfilter/bf_sw/source/core/text/sw_txtdrop.cxx new file mode 100644 index 000000000000..d3c8bc39a784 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtdrop.cxx @@ -0,0 +1,346 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <vcl/metric.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> + +#include <paratr.hxx> +#include <charfmt.hxx> +#include <viewsh.hxx> // ViewShell +#include <pordrop.hxx> +#include <itrform2.hxx> +#include <breakit.hxx> +#include <com/sun/star/i18n/ScriptType.hdl> +#include <com/sun/star/i18n/WordType.hpp> +#include <bf_svx/langitem.hxx> +#include <charatr.hxx> +namespace binfilter { + +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star; + +/************************************************************************* + * SwDropPortionPart DTor + *************************************************************************/ + +/*N*/ SwDropPortionPart::~SwDropPortionPart() +/*N*/ { +/*N*/ if ( pFollow ) +/*N*/ delete pFollow; +/*N*/ delete pFnt; +/*N*/ } + +/************************************************************************* + * SwDropPortion CTor, DTor + *************************************************************************/ + +/*N*/ SwDropPortion::SwDropPortion( const MSHORT nLineCnt, +/*N*/ const KSHORT nDropHeight, +/*N*/ const KSHORT nDropDescent, +/*N*/ const KSHORT nDistance ) +/*N*/ : pPart( 0 ), +/*N*/ nLines( nLineCnt ), +/*N*/ nDropHeight(nDropHeight), +/*N*/ nDropDescent(nDropDescent), +/*N*/ nDistance(nDistance), +/*N*/ nX(0), +/*N*/ nFix(0) +/*N*/ { +/*N*/ SetWhichPor( POR_DROP ); +/*N*/ } + +/*N*/ SwDropPortion::~SwDropPortion() +/*N*/ { +/*N*/ delete pPart; +/*N*/ } + +/*N*/ sal_Bool SwTxtSizeInfo::_HasHint( const SwTxtNode* pTxtNode, xub_StrLen nPos ) +/*N*/ { +/*N*/ const SwpHints *pHints = pTxtNode->GetpSwpHints(); +/*N*/ if( !pHints ) +/*N*/ return sal_False; +/*N*/ for( MSHORT i = 0; i < pHints->Count(); ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pPos = (*pHints)[i]; +/*N*/ xub_StrLen nStart = *pPos->GetStart(); +/*N*/ if( nPos < nStart ) +/*N*/ return sal_False; +/*N*/ if( nPos == nStart && !pPos->GetEnd() ) +/*N*/ return sal_True; +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * SwTxtNode::GetDropLen() + * + * nWishLen = 0 indicates that we want a whole word + *************************************************************************/ + +/*N*/ MSHORT SwTxtNode::GetDropLen( MSHORT nWishLen ) const +/*N*/ { +/*N*/ xub_StrLen nEnd = GetTxt().Len(); +/*N*/ if( nWishLen && nWishLen < nEnd ) +/*N*/ nEnd = nWishLen; +/*N*/ +/*N*/ if ( ! nWishLen && pBreakIt->xBreak.is() ) +/*N*/ { +/*N*/ // find first word +/*?*/ const SwAttrSet& rAttrSet = GetSwAttrSet(); +/*?*/ const USHORT nTxtScript = pBreakIt->GetRealScriptOfText( GetTxt(), 0 ); +/*?*/ +/*?*/ LanguageType eLanguage; +/*?*/ +/*?*/ switch ( nTxtScript ) +/*?*/ { +/*?*/ case i18n::ScriptType::ASIAN : +/*?*/ eLanguage = rAttrSet.GetCJKLanguage().GetLanguage(); +/*?*/ break; +/*?*/ case i18n::ScriptType::COMPLEX : +/*?*/ eLanguage = rAttrSet.GetCTLLanguage().GetLanguage(); +/*?*/ break; +/*?*/ default : +/*?*/ eLanguage = rAttrSet.GetLanguage().GetLanguage(); +/*?*/ break; +/*?*/ } +/*?*/ +/*?*/ Boundary aBound = +/*?*/ pBreakIt->xBreak->getWordBoundary( GetTxt(), 0, +/*?*/ pBreakIt->GetLocale( eLanguage ), WordType::DICTIONARY_WORD, sal_True ); +/*?*/ +/*?*/ nEnd = (xub_StrLen)aBound.endPos; +/*N*/ } +/*N*/ +/*N*/ xub_StrLen i = 0; +/*N*/ for( ; i < nEnd; ++i ) +/*N*/ { +/*N*/ xub_Unicode cChar = GetTxt().GetChar( i ); +/*N*/ if( CH_TAB == cChar || CH_BREAK == cChar || +/*N*/ (( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar ) +/*N*/ && SwTxtSizeInfo::_HasHint( this, i ) ) ) +/*N*/ break; +/*N*/ } +/*N*/ return i; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcDropHeight() + *************************************************************************/ + +/*N*/ void SwTxtFormatter::CalcDropHeight( const MSHORT nLines ) +/*N*/ { +/*N*/ const SwLinePortion *const pOldCurr = GetCurr(); +/*N*/ KSHORT nDropHght = 0; +/*N*/ KSHORT nAscent = 0; +/*N*/ KSHORT nHeight = 0; +/*N*/ KSHORT nDropLns = 0; +/*N*/ sal_Bool bRegisterOld = IsRegisterOn(); +/*N*/ bRegisterOn = sal_False; +/*N*/ +/*N*/ Top(); +/*N*/ +/*N*/ while( GetCurr()->IsDummy() ) +/*N*/ { +/*N*/ if ( !Next() ) +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ // Wenn wir nur eine Zeile haben returnen wir 0 +/*N*/ if( GetNext() || GetDropLines() == 1 ) +/*N*/ { +/*N*/ for( ; nDropLns < nLines; nDropLns++ ) +/*N*/ { +/*N*/ if ( GetCurr()->IsDummy() ) +/*N*/ break; +/*N*/ else +/*N*/ { +/*N*/ CalcAscentAndHeight( nAscent, nHeight ); +/*N*/ nDropHght += nHeight; +/*N*/ bRegisterOn = bRegisterOld; +/*N*/ } +/*N*/ if ( !Next() ) +/*N*/ { +/*N*/ nDropLns++; // Fix: 11356 +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // In der letzten Zeile plumpsen wir auf den Zeilenascent! +/*N*/ nDropHght -= nHeight; +/*N*/ nDropHght += nAscent; +/*N*/ Top(); +/*N*/ } +/*N*/ bRegisterOn = bRegisterOld; +/*N*/ SetDropDescent( nHeight - nAscent ); +/*N*/ SetDropHeight( nDropHght ); +/*N*/ SetDropLines( nDropLns ); +/*N*/ // Alte Stelle wiederfinden! +/*N*/ while( pOldCurr != GetCurr() ) +/*N*/ { +/*N*/ if( !Next() ) +/*N*/ { +/*N*/ ASSERT( !this, "SwTxtFormatter::_CalcDropHeight: left Toulouse" ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::GuessDropHeight() + * + * Wir schaetzen mal, dass die Fonthoehe sich nicht aendert und dass + * erst mindestens soviele Zeilen gibt, wie die DropCap-Einstellung angibt. + * + *************************************************************************/ + + + +/*N*/ void SwTxtFormatter::GuessDropHeight( const MSHORT nLines ) +/*N*/ { +/*N*/ ASSERT( nLines, "GuessDropHeight: Give me more Lines!" ); +/*N*/ KSHORT nAscent = 0; +/*N*/ KSHORT nHeight = 0; +/*N*/ SetDropLines( nLines ); +/*N*/ if ( GetDropLines() > 1 ) +/*N*/ { +/*N*/ CalcRealHeight(); +/*N*/ CalcAscentAndHeight( nAscent, nHeight ); +/*N*/ } +/*N*/ SetDropDescent( nHeight - nAscent ); +/*N*/ SetDropHeight( nHeight * nLines - GetDropDescent() ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewDropPortion + *************************************************************************/ + +/*N*/ SwDropPortion *SwTxtFormatter::NewDropPortion( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( !pDropFmt ) +/*N*/ return 0; +/*N*/ +/*N*/ xub_StrLen nPorLen = pDropFmt->GetWholeWord() ? 0 : pDropFmt->GetChars(); +/*N*/ nPorLen = pFrm->GetTxtNode()->GetDropLen( nPorLen ); +/*N*/ if( !nPorLen ) +/*N*/ { +/*?*/ ((SwTxtFormatter*)this)->ClearDropFmt(); +/*?*/ return 0; +/*N*/ } +/*N*/ +/*N*/ SwDropPortion *pDropPor = 0; +/*N*/ +/*N*/ // erste oder zweite Runde? +/*N*/ if ( !( GetDropHeight() || IsOnceMore() ) ) +/*N*/ { +/*N*/ if ( GetNext() ) +/*?*/ CalcDropHeight( pDropFmt->GetLines() ); +/*N*/ else +/*N*/ GuessDropHeight( pDropFmt->GetLines() ); +/*N*/ } +/*N*/ +/*N*/ // the DropPortion +/*N*/ if( GetDropHeight() ) +/*?*/ pDropPor = new SwDropPortion( GetDropLines(), GetDropHeight(), +/*N*/ GetDropDescent(), pDropFmt->GetDistance() ); +/*N*/ else +/*N*/ pDropPor = new SwDropPortion( 0,0,0,pDropFmt->GetDistance() ); +/*N*/ +/*N*/ pDropPor->SetLen( nPorLen ); +/*N*/ +/*N*/ // If it was not possible to create a proper drop cap portion +/*N*/ // due to avoiding endless loops. We return a drop cap portion +/*N*/ // with an empty SwDropCapPart. For these portions the current +/*N*/ // font is used. +/*N*/ if ( GetDropLines() < 2 ) +/*N*/ { +/*?*/ ((SwTxtFormatter*)this)->SetPaintDrop( sal_True ); +/*?*/ return pDropPor; +/*N*/ } +/*N*/ +/*N*/ // build DropPortionParts: +/*N*/ ASSERT( ! rInf.GetIdx(), "Drop Portion not at 0 position!" ); +/*N*/ xub_StrLen nIdx = rInf.GetIdx(); +/*N*/ xub_StrLen nNextChg = 0; +/*N*/ const SwCharFmt* pFmt = pDropFmt->GetCharFmt(); +/*N*/ SwDropPortionPart* pCurrPart = 0; +/*N*/ +/*N*/ while ( nNextChg < nPorLen ) +/*N*/ { +/*N*/ // check for attribute changes and if the portion has to split: +/*N*/ Seek( nNextChg ); +/*N*/ +/*N*/ // the font is deleted in the destructor of the drop portion part +/*N*/ SwFont* pTmpFnt = new SwFont( *rInf.GetFont() ); +/*N*/ if ( pFmt ) +/*N*/ { +/*N*/ const SwAttrSet& rSet = pFmt->GetAttrSet(); +/*N*/ pTmpFnt->SetDiffFnt( &rSet, rInf.GetDoc() ); +/*N*/ } +/*N*/ +/*N*/ // we do not allow a vertical font for the drop portion +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ pTmpFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() ); +/*N*/ #else +/*N*/ pTmpFnt->SetVertical( 0 ); +/*N*/ #endif +/*N*/ +/*N*/ // find next attribute change / script change +/*N*/ const xub_StrLen nIdx = nNextChg; +/*N*/ xub_StrLen nNextAttr = Min( GetNextAttr(), rInf.GetTxt().Len() ); +/*N*/ nNextChg = pScriptInfo->NextScriptChg( nIdx ); +/*N*/ if( nNextChg > nNextAttr ) +/*N*/ nNextChg = nNextAttr; +/*N*/ if ( nNextChg > nPorLen ) +/*N*/ nNextChg = nPorLen; +/*N*/ +/*N*/ SwDropPortionPart* pPart = +/*N*/ new SwDropPortionPart( *pTmpFnt, nNextChg - nIdx ); +/*N*/ +/*N*/ if ( ! pCurrPart ) +/*N*/ pDropPor->SetPart( pPart ); +/*N*/ else +/*?*/ pCurrPart->SetFollow( pPart ); +/*N*/ +/*N*/ pCurrPart = pPart; +/*N*/ } +/*N*/ +/*N*/ ((SwTxtFormatter*)this)->SetPaintDrop( sal_True ); +/*N*/ return pDropPor; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtfld.cxx b/binfilter/bf_sw/source/core/text/sw_txtfld.cxx new file mode 100644 index 000000000000..4c832973e1e0 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtfld.cxx @@ -0,0 +1,440 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <fmtfld.hxx> +#include <txtfld.hxx> +#include <charfmt.hxx> + +#include "viewsh.hxx" // NewFldPortion, GetDoc() + +#include <horiornt.hxx> + +#include "doc.hxx" // NewFldPortion, GetSysFldType() +#include "rootfrm.hxx" // Info ueber virt. PageNumber +#include "pagefrm.hxx" // NewFldPortion, GetVirtPageNum() +#include "ndtxt.hxx" // NewNumberPortion, pHints->GetNum() +#include "viewopt.hxx" // SwViewOptions +#include "flyfrm.hxx" //IsInBody() +#include "viewimp.hxx" + +#include "txtcfg.hxx" + + +#include "porftn.hxx" // NewExtraPortion +#include "portox.hxx" // NewExtraPortion +#include "porhyph.hxx" // NewExtraPortion +#include "porfly.hxx" // NewExtraPortion +#include "itrform2.hxx" // SwTxtFormatter + +#include "chpfld.hxx" +#include "dbfld.hxx" +#include "expfld.hxx" +#include "docufld.hxx" +#include "pagedesc.hxx" // NewFldPortion, GetNum() +namespace binfilter { + + +/************************************************************************* + * SwTxtFormatter::NewFldPortion() + *************************************************************************/ + + +/*N*/ sal_Bool lcl_IsInBody( SwFrm *pFrm ) +/*N*/ { +/*N*/ if ( pFrm->IsInDocBody() ) +/*N*/ return sal_True; +/*N*/ else +/*N*/ { +/*N*/ SwFrm *pTmp = pFrm; +/*N*/ SwFlyFrm *pFly; +/*N*/ while ( 0 != (pFly = pTmp->FindFlyFrm()) ) +/*N*/ pTmp = pFly->GetAnchor(); +/*N*/ return pTmp->IsInDocBody(); +/*N*/ } +/*N*/ } + + +/*N*/ SwExpandPortion *SwTxtFormatter::NewFldPortion( SwTxtFormatInfo &rInf, +/*N*/ const SwTxtAttr *pHint ) const +/*N*/ { +/*N*/ SwExpandPortion *pRet = NULL; +/*N*/ SwFrm *pFrame = (SwFrm*)pFrm; +/*N*/ SwField *pFld = (SwField*)pHint->GetFld().GetFld(); +/*N*/ const sal_Bool bName = rInf.GetOpt().IsFldName(); +/*N*/ +/*N*/ SwCharFmt* pChFmt = 0; +/*N*/ sal_Bool bNewFlyPor = sal_False, +/*N*/ bINet = sal_False; +/*N*/ +/*N*/ // Sprache setzen +/*N*/ ((SwTxtFormatter*)this)->SeekAndChg( rInf ); +/*N*/ pFld->SetLanguage( GetFnt()->GetLanguage() ); +/*N*/ +/*N*/ ViewShell *pSh = rInf.GetVsh(); +/*N*/ +/*N*/ switch( pFld->GetTyp()->Which() ) +/*N*/ { +/*N*/ case RES_SCRIPTFLD: +/*N*/ case RES_POSTITFLD: + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRet = new SwPostItsPortion( RES_SCRIPTFLD == pFld->GetTyp()->Which() ); +/*?*/ break; +/*?*/ +/*?*/ case RES_COMBINED_CHARS: +/*?*/ { +/*?*/ String sStr( pFld->GetCntnt( bName )); +/*?*/ if( bName ) +/*?*/ pRet = new SwFldPortion( sStr ); +/*?*/ else + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRet = new SwCombinedPortion( sStr ); +/*?*/ } +/*?*/ break; +/*N*/ +/*N*/ case RES_HIDDENTXTFLD: +/*N*/ pRet = new SwHiddenPortion(pFld->GetCntnt( bName )); +/*N*/ break; +/*N*/ +/*N*/ case RES_CHAPTERFLD: +/*N*/ if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ { +/*N*/ ((SwChapterField*)pFld)->ChangeExpansion( pFrame, +/*N*/ &((SwTxtFld*)pHint)->GetTxtNode() ); +/*N*/ } +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*N*/ break; +/*N*/ +/*N*/ case RES_DOCSTATFLD: +/*N*/ if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ ((SwDocStatField*)pFld)->ChangeExpansion( pFrame ); +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*N*/ break; +/*N*/ +/*N*/ case RES_PAGENUMBERFLD: +/*N*/ { +/*N*/ if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ { +/*N*/ SwDoc* pDoc = pSh->GetDoc(); +/*N*/ SwPageNumberFieldType *pPageNr = (SwPageNumberFieldType *) +/*N*/ pFld->GetTyp(); +/*N*/ //??? pDoc->GetSysFldType( RES_PAGENUMBERFLD ); +/*N*/ +/*N*/ // SwPageFrm *pPage = pFrm->FindPageFrm(); +/*N*/ // sal_Bool bVirt = pPage && pPage->GetNext(); +/*N*/ sal_Bool bVirt = pSh->GetLayout()->IsVirtPageNum(); +/*N*/ +/*N*/ MSHORT nVirtNum = pFrame->GetVirtPageNum(), +/*N*/ nNumPages = pDoc->GetRootFrm()->GetPageNum(); +/*N*/ sal_Int16 nNumFmt = -1; +/*N*/ if(SVX_NUM_PAGEDESC == pFld->GetFormat()) +/*N*/ nNumFmt = pFrame->FindPageFrm()->GetPageDesc()->GetNumType().GetNumberingType(); +/*N*/ +/*N*/ pPageNr->ChangeExpansion( pDoc, nVirtNum, nNumPages, +/*N*/ bVirt, nNumFmt > -1 ? &nNumFmt : 0); +/*N*/ } +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*N*/ break; +/*N*/ } +/*N*/ case RES_GETEXPFLD: +/*N*/ { +/*N*/ if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() ) +/*N*/ { +/*N*/ SwGetExpField* pExpFld = (SwGetExpField*)pFld; + /*N*/ if( !::binfilter::lcl_IsInBody( pFrame ) ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pExpFld->ChgBodyTxtFlag( sal_False ); +/*N*/ } +/*N*/ else if( !pExpFld->IsInBodyTxt() ) +/*N*/ { +/*N*/ // war vorher anders, also erst expandieren, dann umsetzen!! +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 pExpFld->ChangeExpansion( *pFrame, *((SwTxtFld*)pHint) ); +/*N*/ } +/*N*/ } +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*N*/ break; +/*N*/ } +/*N*/ case RES_DBFLD: +/*N*/ { +/*N*/ if( !bName ) +/*N*/ { +/*N*/ SwDBField* pDBFld = (SwDBField*)pFld; +/*N*/ pDBFld->ChgBodyTxtFlag( ::binfilter::lcl_IsInBody( pFrame ) ); + /* Solange das ChangeExpansion auskommentiert ist. + * Aktualisieren in Kopf/Fuszeilen geht aktuell nicht. + if( !::binfilter::lcl_IsInBody( pFrame ) ) + { + pDBFld->ChgBodyTxtFlag( sal_False ); + pDBFld->ChangeExpansion( pFrame, (SwTxtFld*)pHint ); + } + else if( !pDBFld->IsInBodyTxt() ) + { + // war vorher anders, also erst expandieren, dann umsetzen!! + pDBFld->ChangeExpansion( pFrame, (SwTxtFld*)pHint ); + pDBFld->ChgBodyTxtFlag( sal_True ); + } + */ +/*N*/ } +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*N*/ break; +/*N*/ } +/*?*/ case RES_REFPAGEGETFLD: +/*?*/ if( !bName && pSh && !pSh->Imp()->IsUpdateExpFlds() ) + /*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 ((SwRefPageGetField*)pFld)->ChangeExpansion( pFrame, (SwTxtFld*)pHint ); +/*?*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ) ); +/*?*/ break; +/*N*/ +/*N*/ case RES_JUMPEDITFLD: +/*N*/ if( !bName ) +/*N*/ pChFmt = ((SwJumpEditField*)pFld)->GetCharFmt(); +/*N*/ bNewFlyPor = sal_True; +/*N*/ break; +/*N*/ +/*N*/ default: +/*N*/ { +/*N*/ pRet = new SwFldPortion(pFld->GetCntnt( bName ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bNewFlyPor ) +/*N*/ { +/*N*/ SwFont *pTmpFnt = 0; +/*N*/ if( !bName ) +/*N*/ { +/*N*/ pTmpFnt = new SwFont( *pFnt ); +/*N*/ if( bINet ) +/*N*/ { +/*?*/ SwAttrPool* pPool = pChFmt->GetAttrSet().GetPool(); +/*?*/ SfxItemSet aSet( *pPool, RES_CHRATR_BEGIN, RES_CHRATR_END ); +/*?*/ SfxItemSet aTmpSet( aSet ); +/*?*/ pFrm->GetTxtNode()->GetAttr(aSet,rInf.GetIdx(),rInf.GetIdx()+1); +/*?*/ aTmpSet.Set( pChFmt->GetAttrSet() ); +/*?*/ aTmpSet.Differentiate( aSet ); +/*?*/ if( aTmpSet.Count() ) +/*?*/ pTmpFnt->SetDiffFnt( &aTmpSet, rInf.GetDoc() ); +/*N*/ } +/*N*/ else +/*N*/ pTmpFnt->SetDiffFnt( &pChFmt->GetAttrSet(), rInf.GetDoc() ); +/*N*/ } +/*N*/ pRet = new SwFldPortion( pFld->GetCntnt( bName ), pTmpFnt ); +/*N*/ } +/*N*/ +/*N*/ return pRet; +/*N*/ } + + +/************************************************************************* + * SwTxtFormatter::NewExtraPortion() + *************************************************************************/ + + +/*N*/ SwLinePortion *SwTxtFormatter::NewExtraPortion( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ SwTxtAttr *pHint = GetAttr( rInf.GetIdx() ); +/*N*/ SwLinePortion *pRet = 0; +/*N*/ if( !pHint ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ // aDbstream << "NewExtraPortion: hint not found?" << endl; +/*N*/ #endif +/*?*/ pRet = new SwTxtPortion; +/*?*/ pRet->SetLen( 1 ); +/*?*/ rInf.SetLen( 1 ); +/*?*/ return pRet; +/*N*/ } +/*N*/ +/*N*/ switch( pHint->Which() ) +/*N*/ { +/*N*/ case RES_TXTATR_FLYCNT : +/*N*/ { +/*N*/ pRet = NewFlyCntPortion( rInf, pHint ); +/*N*/ break; +/*N*/ } +/*N*/ case RES_TXTATR_FTN : +/*N*/ { +/*N*/ pRet = NewFtnPortion( rInf, pHint ); +/*N*/ break; +/*N*/ } +/*?*/ case RES_TXTATR_SOFTHYPH : +/*?*/ { +/*?*/ pRet = new SwSoftHyphPortion; +/*?*/ break; +/*?*/ } +/*?*/ case RES_TXTATR_HARDBLANK : +/*?*/ { + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pRet = new SwBlankPortion( ((SwTxtHardBlank*)pHint)->GetChar() ); +/*?*/ } +/*N*/ case RES_TXTATR_FIELD : +/*N*/ { +/*N*/ pRet = NewFldPortion( rInf, pHint ); +/*N*/ break; +/*N*/ } +/*?*/ case RES_TXTATR_REFMARK : + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ { +/*N*/ case RES_TXTATR_TOXMARK : +/*N*/ { +/*N*/ pRet = new SwIsoToxPortion; +/*N*/ break; +/*N*/ } +/*N*/ default: ; +/*N*/ } +/*N*/ if( !pRet ) +/*N*/ { +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ // aDbstream << "NewExtraPortion: unknown hint" << endl; +/*N*/ #endif +/*?*/ const XubString aNothing; +/*?*/ pRet = new SwFldPortion( aNothing ); +/*?*/ rInf.SetLen( 1 ); +/*N*/ } +/*N*/ return pRet; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewNumberPortion() + *************************************************************************/ + + +/*N*/ SwNumberPortion *SwTxtFormatter::NewNumberPortion( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ if( rInf.IsNumDone() || rInf.GetTxtStart() != nStart +/*N*/ || rInf.GetTxtStart() != rInf.GetIdx() ) +/*N*/ return 0; +/*N*/ +/*N*/ SwNumberPortion *pRet = 0; +/*N*/ const SwTxtNode* pTxtNd = GetTxtFrm()->GetTxtNode(); +/*N*/ const SwNumRule* pNumRule = pTxtNd->GetNumRule(); +/*N*/ const SwNodeNum* pNum = pTxtNd->GetNum(); +/*N*/ +/*N*/ if( !pNumRule ) // oder sollte OutlineNum an sein? +/*N*/ { +/*N*/ pNum = pTxtNd->GetOutlineNum(); +/*N*/ if( pNum ) +/*N*/ pNumRule = pTxtNd->GetDoc()->GetOutlineNumRule(); +/*N*/ } +/*N*/ // hat ein "gueltige" Nummer ? +/*N*/ if( pNumRule && pNum && MAXLEVEL > pNum->GetLevel() ) +/*N*/ { +/*N*/ CONST SwNumFmt &rNumFmt = pNumRule->Get( pNum->GetLevel() ); +/*N*/ const sal_Bool bLeft = SVX_ADJUST_LEFT == rNumFmt.GetNumAdjust(); +/*N*/ const sal_Bool bCenter = SVX_ADJUST_CENTER == rNumFmt.GetNumAdjust(); +/*N*/ const KSHORT nMinDist = rNumFmt.GetCharTextDistance(); +/*N*/ +/*N*/ if( SVX_NUM_BITMAP == rNumFmt.GetNumberingType() ) +/*N*/ { +/*?*/ pRet = new SwGrfNumPortion( (SwFrm*)GetTxtFrm(),rNumFmt.GetBrush(), +/*?*/ rNumFmt.GetGraphicOrientation(), rNumFmt.GetGraphicSize(), +/*?*/ bLeft, bCenter, nMinDist ); +/*?*/ long nTmpA = rInf.GetLast()->GetAscent(); +/*?*/ long nTmpD = rInf.GetLast()->Height() - nTmpA; +/*?*/ if( !rInf.IsTest() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ ((SwGrfNumPortion*)pRet)->SetBase( nTmpA, nTmpD, nTmpA, nTmpD ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Der SwFont wird dynamisch angelegt und im CTOR uebergeben, +/*N*/ // weil das CharFmt nur einen SV-Font zurueckliefert. +/*N*/ // Im Dtor vom SwNumberPortion wird der SwFont deletet. +/*N*/ SwFont *pNumFnt = 0; +/*N*/ const SwAttrSet* pFmt = rNumFmt.GetCharFmt() ? +/*N*/ &rNumFmt.GetCharFmt()->GetAttrSet() : NULL; +/*N*/ if( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() ) +/*N*/ { +/*N*/ const Font *pFmtFnt = rNumFmt.GetBulletFont(); +/*N*/ pNumFnt = new SwFont( &rInf.GetCharAttr(), rInf.GetDoc() ); +/*N*/ if( pFmt ) +/*N*/ pNumFnt->SetDiffFnt( pFmt, rInf.GetDoc() ); +/*N*/ if ( pFmtFnt ) +/*N*/ { +/*N*/ const BYTE nAct = pNumFnt->GetActual(); +/*N*/ pNumFnt->SetFamily( pFmtFnt->GetFamily(), nAct ); +/*N*/ pNumFnt->SetName( pFmtFnt->GetName(), nAct ); +/*N*/ pNumFnt->SetStyleName( pFmtFnt->GetStyleName(), nAct ); +/*N*/ pNumFnt->SetCharSet( pFmtFnt->GetCharSet(), nAct ); +/*N*/ pNumFnt->SetPitch( pFmtFnt->GetPitch(), nAct ); +/*N*/ } +/*N*/ // we do not allow a vertical font +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ pNumFnt->SetVertical( pNumFnt->GetOrientation(), +/*N*/ pFrm->IsVertical() ); +/*N*/ #else +/*N*/ pNumFnt->SetVertical( 0 ); +/*N*/ #endif +/*N*/ +/*N*/ pRet = new SwBulletPortion( rNumFmt.GetBulletChar(), pNumFnt, bLeft, +/*N*/ bCenter, nMinDist ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ XubString aTxt( pNumRule->MakeNumString( *pNum ) ); +/*N*/ +/*N*/ // 7974: Nicht nur eine Optimierung... +/*N*/ // Eine Numberportion ohne Text wird die Breite von 0 +/*N*/ // erhalten. Die nachfolgende Textportion wird im BreakLine +/*N*/ // in das BreakCut laufen, obwohl rInf.GetLast()->GetFlyPortion() +/*N*/ // vorliegt! +/*N*/ if( aTxt.Len() ) +/*N*/ { +/*N*/ pNumFnt = new SwFont( &rInf.GetCharAttr(), rInf.GetDoc() ); +/*N*/ if( pFmt ) +/*N*/ pNumFnt->SetDiffFnt( pFmt, rInf.GetDoc() ); +/*N*/ // Die SSize muss erhalten bleiben +/*N*/ // pNumFnt->ChangeSize( rInf.GetFont()->GetSize() ); +/*N*/ +/*N*/ // we do not allow a vertical font +/*N*/ #ifdef VERTICAL_LAYOUT +/*N*/ pNumFnt->SetVertical( pNumFnt->GetOrientation(), pFrm->IsVertical() ); +/*N*/ #else +/*N*/ pNumFnt->SetVertical( 0 ); +/*N*/ #endif +/*N*/ +/*N*/ pRet = new SwNumberPortion( aTxt, pNumFnt, bLeft, bCenter, +/*N*/ nMinDist ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return pRet; +/*N*/ } +/* -----------------26.06.2003 13:54----------------- + + --------------------------------------------------*/ +void SwTxtFld::NotifyContentChange(SwFmtFld& rFmtFld) +{ + //if not in undo section notify the change + if(pMyTxtNd && pMyTxtNd->GetNodes().IsDocNodes()) + pMyTxtNd->Modify(0, &rFmtFld); +} + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtfly.cxx b/binfilter/bf_sw/source/core/text/sw_txtfly.cxx new file mode 100644 index 000000000000..22814df6e7eb --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtfly.cxx @@ -0,0 +1,1900 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "viewsh.hxx" +#include "rootfrm.hxx" +#include "pam.hxx" // SwPosition +#include "dcontact.hxx" // SwContact +#include "dflyobj.hxx" // SdrObject +#include "frmtool.hxx" // ::DrawGraphic +#include <pormulti.hxx> // SwMultiPortion + +#ifdef VERT_DISTANCE +#include <math.h> +#endif + + +#include <bf_svx/obj3d.hxx> + +#include <bf_svx/txtrange.hxx> + +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/ulspitem.hxx> +#include <txtflcnt.hxx> +#include <fmtsrnd.hxx> +#include <fmtanchr.hxx> +#include <fmtflcnt.hxx> + + + + +#include <pagefrm.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> + +// #102344# +#include <bf_svx/svdoedge.hxx> + +#include "itrform2.hxx" // SwTxtFormatter +#include "porfly.hxx" // NewFlyCntPortion +#include "porfld.hxx" // SwGrfNumPortion + + +#include "flyfrms.hxx" +#include "fmtcnct.hxx" // SwFmtChain + +#ifdef DBG_UTIL +#include "viewopt.hxx" // SwViewOptions, nur zum Testen (Test2) +#endif +namespace binfilter { + +/***************************************************************************** + * Beschreibung: + * Die Klasse SwTxtFly soll die Universalschnittstelle zwischen der + * Formatierung/Textausgabe und den u.U. ueberlappenden freifliegenden + * Frames sein. + * Waehrend der Formatierung erkundigt sich der Formatierer beim SwTxtFly, + * ob ein bestimmter Bereich durch die Attribute eines ueberlappenden + * Frames vorliegt. Solche Bereiche werden in Form von Dummy-Portions + * abgebildet. + * Die gesamte Textausgabe und Retusche wird ebenfalls an ein SwTxtFly + * weitergeleitet. Dieser entscheidet, ob Textteile geclippt werden muessen + * und zerteilt z.B. die Bereiche bei einem DrawRect. + * Zu beachten ist, dass alle freifliegenden Frames in einem nach TopLeft + * sortiertem PtrArray an der Seite zu finden sind. Intern wird immer nur + * in dokumentglobalen Werten gerechnet. Die IN- und OUT-Parameter sind + * jedoch in den meisten Faellen an die Beduerfnisse des LineIters + * zugeschnitten, d.h. sie werden in frame- oder windowlokalen Koordinaten + * konvertiert. + * Wenn mehrere Frames mit Umlaufattributen in einer Zeile liegen, + * ergeben sich unterschiedliche Auswirkungen fuer den Textfluss: + * + * L/R P L R K + * P -P-P- -P-L -P R- -P K + * L -L P- -L L -L R- -L K + * R R-P- R-L R R- R K + * K K P- K L K R- K K + * + * (P=parallel, L=links, R=rechts, K=kein Umlauf) + * + * Das Verhalten so beschreiben: + * Jeder Rahmen kann Text verdraengen, wobei der Einfluss allerdings nur + * bis zum naechsten Rahmen reicht. + *****************************************************************************/ + +/***************************************************************************** + * + * lcl_TheAnchor liefert den SwFrm, an dem das Objekt verankert ist. + * + *****************************************************************************/ + +// OD 03.07.2003 #108784# - change return type from <pointer> to <reference> +/*N*/ const SwFrm& lcl_TheAnchor( const SdrObject* pObj ) +/*N*/ { +/*N*/ // OD 03.07.2003 #108784# - adjustments for support of drawing objects in +/*N*/ // header/footer. +/*N*/ const SwFrm* pRet = 0L; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ pRet = static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm()->GetAnchor(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwDrawContact* pDrawContact = +/*N*/ static_cast<SwDrawContact*>(GetUserCall( pObj )); +/*N*/ if ( pObj->ISA(SwDrawVirtObj) ) +/*N*/ { +/*N*/ const SwDrawVirtObj* pDrawVirtObj = static_cast<const SwDrawVirtObj*>(pObj); +/*N*/ pRet = pDrawVirtObj->GetAnchorFrm(); +/*N*/ +/*N*/ // error handling, if no anchor frame is found. +/*N*/ if ( !pRet ) +/*N*/ { +/*N*/ // assert, if no anchor frame found at 'virtual' drawing object +/*N*/ // and return anchor frame of 'master' drawing object. +/*N*/ ASSERT( false, "<lcl_TheAnchor(..)> - virtual drawing object with no anchor frame!" ); +/*N*/ pRet = pDrawContact->GetAnchor(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pRet = pDrawContact->GetAnchor(); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ ASSERT( pRet, "<lcl_TheAnchor(..)> - no anchor frame found!" ); +/*N*/ +/*N*/ return *pRet; +/*N*/ } + +/***************************************************************************** + * lcl_MaxAscDescent liefert die max. Ascents und Descents in der Zeile ohne + * FlyPortions (abs. und seitengeb. Objekte), einmal mit und einmal ohne + * Beruecksichtigung der zeichengeb. Objekte. + * Diese Werte sind fuer das SetBase der zeichengebundenen Objekte wichtig, + * wenn diese an den Zeichen oder an der Zeile ausgerichtet werden sollen. + *****************************************************************************/ + +/*N*/ void lcl_MaxAscDescent( SwLinePortion* pPos, long &rAscent, long &rDescent, +/*N*/ long &rFlyAscent, long &rFlyDescent, SwLinePortion* pNot = NULL ) +/*N*/ { +/*N*/ rAscent = 0; +/*N*/ rDescent = 0; +/*N*/ rFlyAscent = 0; +/*N*/ rFlyDescent = 0; +/*N*/ +/*N*/ if( !pPos->GetLen() && ( pPos->IsParaPortion() || pPos->IsLayPortion() ) ) +/*N*/ pPos = pPos->GetPortion(); +/*N*/ +/*N*/ while ( pPos ) +/*N*/ { +/*N*/ if( !pPos->IsBreakPortion() && !pPos->IsFlyPortion() ) +/*N*/ { +/*N*/ sal_Bool bFlyCmp = pPos->IsFlyCntPortion() ? +/*N*/ ((SwFlyCntPortion*)pPos)->IsMax() : pPos != pNot; +/*N*/ if( bFlyCmp ) +/*N*/ { +/*N*/ rFlyAscent = Max( rFlyAscent, (long)pPos->GetAscent() ); +/*N*/ rFlyDescent = Max( rFlyDescent, +/*N*/ (long)( pPos->Height() - pPos->GetAscent() ) ); +/*N*/ } +/*N*/ if( !pPos->IsFlyCntPortion() && !pPos->IsGrfNumPortion() ) +/*N*/ { +/*N*/ rAscent = Max( rAscent, (long)pPos->GetAscent() ); +/*N*/ rDescent = Max( rDescent, +/*N*/ (long)( pPos->Height() - pPos->GetAscent() ) ); +/*N*/ } +/*N*/ } +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ } + +/*N*/ void SwTxtFormatter::CalcUnclipped( SwTwips& rTop, SwTwips& rBottom ) +/*N*/ { +/*N*/ ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(), +/*N*/ "SwTxtFormatter::CalcUnclipped with unswapped frame" ) +/*N*/ +/*N*/ long nFlyAsc, nFlyDesc; +/*N*/ lcl_MaxAscDescent( pCurr, rTop, rBottom, nFlyAsc, nFlyDesc ); +/*N*/ rTop = Y() + GetCurr()->GetAscent(); +/*N*/ rBottom = rTop + nFlyDesc; +/*N*/ rTop -= nFlyAsc; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::UpdatePos() aktualisiert die Referenzpunkte der zeichengeb. + * Objekte, z. B. nach Adjustierung ( rechtsbuendig, Blocksatz etc. ) + * ( hauptsaechlich Korrrektur der X-Position ) + *************************************************************************/ + +/*N*/ void SwTxtFormatter::UpdatePos( SwLineLayout *pCurr, Point aStart, +/*N*/ xub_StrLen nStartIdx, sal_Bool bAllWays ) const +/*N*/ { +/*N*/ ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(), +/*N*/ "SwTxtFormatter::UpdatePos with unswapped frame" ) +/*N*/ +/*N*/ if( GetInfo().IsTest() ) +/*N*/ return; +/*N*/ SwLinePortion *pFirst = pCurr->GetFirstPortion(); +/*N*/ SwLinePortion *pPos = pFirst; +/*N*/ SwTxtPaintInfo aTmpInf( GetInfo() ); +/*N*/ aTmpInf.SetSpaceAdd( pCurr->GetpSpaceAdd() ); +/*N*/ aTmpInf.ResetSpaceIdx(); +/*N*/ aTmpInf.SetKanaComp( pCurr->GetpKanaComp() ); +/*N*/ aTmpInf.ResetKanaIdx(); +/*N*/ +/*N*/ // Die Groesse des Frames +/*N*/ aTmpInf.SetIdx( nStartIdx ); +/*N*/ aTmpInf.SetPos( aStart ); +/*N*/ +/*N*/ long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc; +/*N*/ lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc ); +/*N*/ KSHORT nTmpHeight = pCurr->GetRealHeight(); +/*N*/ KSHORT nAscent = pCurr->GetAscent() + nTmpHeight - pCurr->Height(); +/*N*/ sal_uInt8 nFlags = SETBASE_ULSPACE; +/*N*/ if( GetMulti() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ { +/*N*/ else +/*N*/ aTmpInf.Y( aTmpInf.Y() + nAscent ); +/*N*/ +/*N*/ while( pPos ) +/*N*/ { +/*N*/ // bislang ist mir nur ein Fall bekannt, wo die Positionsaenderung +/*N*/ // (verursacht durch das Adjustment) fuer eine Portion wichtig +/*N*/ // sein koennte: Bei FlyCntPortions muss ein SetRefPoint erfolgen. +/*N*/ if( ( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() ) +/*N*/ && ( bAllWays || !IsQuick() ) ) +/*N*/ { +/*N*/ lcl_MaxAscDescent( pFirst, nTmpAscent, nTmpDescent, +/*N*/ nFlyAsc, nFlyDesc, pPos ); +/*N*/ if( pPos->IsGrfNumPortion() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( !nFlyAsc && !nFlyDesc ) +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ Point aBase( aTmpInf.GetPos() ); +/*N*/ if ( GetInfo().GetTxtFrm()->IsVertical() ) +/*N*/ GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aBase ); +/*N*/ +/*N*/ ((SwFlyCntPortion*)pPos)->SetBase( *aTmpInf.GetTxtFrm(), +/*N*/ aBase, nTmpAscent, nTmpDescent, nFlyAsc, +/*N*/ nFlyDesc, nFlags ); +/*N*/ } +/*N*/ } +/*N*/ if( pPos->IsMultiPortion() && ((SwMultiPortion*)pPos)->HasFlyInCntnt() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*N*/ { +/*N*/ pPos->Move( aTmpInf ); +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::AlignFlyInCntBase() + * richtet die zeichengeb. Objekte in Y-Richtung ggf. neu aus. + *************************************************************************/ + +/*N*/ void SwTxtFormatter::AlignFlyInCntBase( long nBaseLine ) const +/*N*/ { +/*N*/ ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(), +/*N*/ "SwTxtFormatter::AlignFlyInCntBase with unswapped frame" ) +/*N*/ +/*N*/ if( GetInfo().IsTest() ) +/*N*/ return; +/*N*/ SwLinePortion *pFirst = pCurr->GetFirstPortion(); +/*N*/ SwLinePortion *pPos = pFirst; +/*N*/ sal_uInt8 nFlags = SETBASE_NOFLAG; +/*N*/ if( GetMulti() && GetMulti()->HasRotation() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ nFlags |= SETBASE_ROTATE; +/*N*/ } +/*N*/ +/*N*/ long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc; +/*N*/ +/*N*/ while( pPos ) +/*N*/ { +/*N*/ if( pPos->IsFlyCntPortion() || pPos->IsGrfNumPortion() ) +/*N*/ { +/*N*/ lcl_MaxAscDescent( pFirst, nTmpAscent, nTmpDescent, +/*N*/ nFlyAsc, nFlyDesc, pPos ); +/*N*/ if( pPos->IsGrfNumPortion() ) +/*N*/ ((SwGrfNumPortion*)pPos)->SetBase( nTmpAscent, nTmpDescent, +/*N*/ nFlyAsc, nFlyDesc ); +/*N*/ else +/*N*/ { +/*N*/ Point aBase; +/*N*/ if ( GetInfo().GetTxtFrm()->IsVertical() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ nBaseLine = GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( nBaseLine ); +/*N*/ } +/*N*/ else +/*N*/ aBase = Point( ((SwFlyCntPortion*)pPos)->GetRefPoint().X(), nBaseLine ); +/*N*/ +/*N*/ ((SwFlyCntPortion*)pPos)->SetBase( *GetInfo().GetTxtFrm(), aBase, nTmpAscent, nTmpDescent, +/*N*/ nFlyAsc, nFlyDesc, nFlags ); +/*N*/ } +/*N*/ } +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFly::ChkFlyUnderflow() + * This is called after the real height of the line has been calculated + * Therefore it is possible, that more flys from below intersect with the + * line, or that flys from above do not intersect with the line anymore + * We check this and return true if so, meaning that the line has to be + * formatted again + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFormatter::ChkFlyUnderflow( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ ASSERT( rInf.GetTxtFly()->IsOn(), "SwTxtFormatter::ChkFlyUnderflow: why?" ); +/*N*/ if( GetCurr() ) +/*N*/ { +/*N*/ // Erst pruefen wir, ob ueberhaupt ein Fly mit der Zeile ueberlappt. +/*N*/ // = GetLineHeight() +/*N*/ const long nHeight = GetCurr()->GetRealHeight(); +/*N*/ SwRect aLine( GetLeftMargin(), Y(), rInf.RealWidth(), nHeight ); +/*N*/ +/*N*/ SwRect aLineVert( aLine ); +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwitchHorizontalToVertical( aLineVert ); +/*N*/ SwRect aInter( rInf.GetTxtFly()->GetFrm( aLineVert ) ); +/*N*/ if ( pFrm->IsVertical() ) + //STRIP001 /*?*/ pFrm->SwitchVerticalToHorizontal( aInter ); +/*N*/ +/*N*/ if( !aInter.HasArea() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // Nun ueberpruefen wir jede Portion, die sich haette senken koennen, +/*N*/ // ob sie mit dem Fly ueberlappt. +/*N*/ const SwLinePortion *pPos = GetCurr()->GetFirstPortion(); +/*N*/ aLine.Pos().Y() = Y() + GetCurr()->GetRealHeight() - GetCurr()->Height(); +/*N*/ aLine.Height( GetCurr()->Height() ); +/*N*/ +/*N*/ while( pPos ) +/*N*/ { +/*N*/ aLine.Width( pPos->Width() ); +/*N*/ +/*N*/ aLineVert = aLine; +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwitchHorizontalToVertical( aLineVert ); +/*N*/ aInter = rInf.GetTxtFly()->GetFrm( aLineVert ); +/*N*/ if ( pFrm->IsVertical() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchVerticalToHorizontal( aInter ); +/*N*/ +/*N*/ // new flys from below? +/*N*/ if( !pPos->IsFlyPortion() ) +/*N*/ { +/*N*/ if( aInter.IsOver( aLine ) ) +/*N*/ { +/*N*/ aInter._Intersection( aLine ); +/*N*/ if( aInter.HasArea() ) +/*N*/ { +/*N*/ // to be evaluated during reformat of this line: +/*N*/ // RealHeight including spacing +/*N*/ rInf.SetLineHeight( KSHORT(nHeight) ); +/*N*/ // Height without extra spacing +/*N*/ rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // the fly portion is not anylonger intersected by a fly +/*N*/ if ( ! aInter.IsOver( aLine ) ) +/*N*/ { +/*?*/ rInf.SetLineHeight( KSHORT(nHeight) ); +/*?*/ rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) ); +/*?*/ return sal_True; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aInter._Intersection( aLine ); +/*N*/ +/*N*/ // no area means a fly has become invalid because of +/*N*/ // lowering the line => reformat the line +/*N*/ // we also have to reformat the line, if the fly size +/*N*/ // differs from the intersection intervals size +/*N*/ if( ! aInter.HasArea() || +/*N*/ ((SwFlyPortion*)pPos)->GetFixWidth() != aInter.Width() ) +/*N*/ { +/*N*/ rInf.SetLineHeight( KSHORT(nHeight) ); +/*N*/ rInf.SetLineNettoHeight( KSHORT( pCurr->Height() ) ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ aLine.Left( aLine.Left() + pPos->Width() ); +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::CalcFlyWidth() + * ermittelt das naechste Objekt, das in die restliche Zeile ragt und + * konstruiert die zugehoerige FlyPortion. + * Dazu wird SwTxtFly.GetFrm(..) benutzt. + *************************************************************************/ + +// Durch Flys kann sich der rechte Rand verkuerzen. + +/*N*/ void SwTxtFormatter::CalcFlyWidth( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( GetMulti() || rInf.GetFly() ) +/*N*/ return; +/*N*/ +/*N*/ SwTxtFly *pTxtFly = rInf.GetTxtFly(); +/*N*/ if( !pTxtFly->IsOn() || rInf.IsIgnoreFly() ) +/*N*/ return; +/*N*/ +/*N*/ register const SwLinePortion *pLast = rInf.GetLast(); +/*N*/ +/*N*/ long nAscent; +/*N*/ long nTop = Y(); +/*N*/ long nHeight; +/*N*/ +/*N*/ if( rInf.GetLineHeight() ) +/*N*/ { +/*N*/ // real line height has already been calculated, we only have to +/*N*/ // search for intersections in the lower part of the strip +/*N*/ nAscent = pCurr->GetAscent(); +/*N*/ nHeight = rInf.GetLineNettoHeight(); +/*N*/ nTop += rInf.GetLineHeight() - nHeight; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nAscent = pLast->GetAscent(); +/*N*/ nHeight = pLast->Height(); +/*N*/ +/*N*/ // we make a first guess for the lines real height +/*N*/ if ( ! pCurr->GetRealHeight() ) +/*N*/ CalcRealHeight(); +/*N*/ +/*N*/ if ( pCurr->GetRealHeight() > nHeight ) +/*N*/ nTop += pCurr->GetRealHeight() - nHeight; +/*N*/ else +/*N*/ // important for fixed space between lines +/*N*/ nHeight = pCurr->GetRealHeight(); +/*N*/ } +/*N*/ +/*N*/ const long nLeftMar = GetLeftMargin(); +/*N*/ const long nLeftMin = (rInf.X() || GetDropLeft()) ? nLeftMar : GetLeftMin(); +/*N*/ +/*N*/ SwRect aLine( rInf.X() + nLeftMin, nTop, rInf.RealWidth() - rInf.X() +/*N*/ + nLeftMar - nLeftMin , nHeight ); +/*N*/ +/*N*/ SwRect aLineVert( aLine ); +/*N*/ if ( pFrm->IsRightToLeft() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchLTRtoRTL( aLineVert ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*N*/ pFrm->SwitchHorizontalToVertical( aLineVert ); +/*N*/ SwRect aInter( pTxtFly->GetFrm( aLineVert ) ); +/*N*/ +/*N*/ if ( pFrm->IsRightToLeft() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchRTLtoLTR( aInter ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ pFrm->SwitchVerticalToHorizontal( aInter ); +/*N*/ +/*N*/ if( aInter.IsOver( aLine ) ) +/*N*/ { +/*N*/ aLine.Left( rInf.X() + nLeftMar ); +/*N*/ sal_Bool bForced = sal_False; +/*N*/ if( aInter.Left() <= nLeftMin ) +/*N*/ { +/*N*/ SwTwips nFrmLeft = GetTxtFrm()->Frm().Left(); +/*N*/ if( GetTxtFrm()->Prt().Left() < 0 ) +/*?*/ nFrmLeft += GetTxtFrm()->Prt().Left(); +/*N*/ if( aInter.Left() < nFrmLeft ) +/*N*/ aInter.Left( nFrmLeft ); +/*N*/ aInter.Width( aInter.Width() + nLeftMar - nFrmLeft ); +/*N*/ // Bei negativem Erstzeileneinzug setzen wir das Flag, +/*N*/ // um anzuzeigen, dass der Einzug/Rand verschoben wurde +/*N*/ // Dies muss beim DefaultTab an der Nullposition beruecksichtigt +/*N*/ // werden. +/*N*/ if( IsFirstTxtLine() && HasNegFirst() ) +/*N*/ bForced = sal_True; +/*N*/ } +/*N*/ aInter.Intersection( aLine ); +/*N*/ if( !aInter.HasArea() ) +/*N*/ return; +/*N*/ +/*N*/ const sal_Bool bFullLine = aLine.Left() == aInter.Left() && +/*N*/ aLine.Right() == aInter.Right(); +/*N*/ +/*N*/ // Obwohl kein Text mehr da ist, muss eine weitere Zeile +/*N*/ // formatiert werden, weil auch leere Zeilen einem Fly +/*N*/ // ohne Umlauf ausweichen muessen. +/*N*/ if( bFullLine && rInf.GetIdx() == rInf.GetTxt().Len() ) +/*N*/ { +/*N*/ rInf.SetNewLine( sal_True ); +/*N*/ // 8221: Dummies erkennt man an Ascent == Height +/*N*/ pCurr->SetDummy(sal_True); +/*N*/ } +/*N*/ +/*N*/ // aInter wird framelokal +/*N*/ aInter.Pos().X() -= nLeftMar; +/*N*/ SwFlyPortion *pFly = new SwFlyPortion( aInter ); +/*N*/ if( bForced ) +/*N*/ { +/*N*/ pCurr->SetForcedLeftMargin( sal_True ); +/*N*/ rInf.ForcedLeftMargin( (USHORT)aInter.Width() ); +/*N*/ } +/*N*/ +/*N*/ if( bFullLine ) +/*N*/ { +/*N*/ // 8110: wir muessen um Einheiten von Zeilenhoehen anwachsen, +/*N*/ // um nebeneinanderliegende Flys mit unterschiedlichen +/*N*/ // Umlaufattributen angemessen zu umfliessen. +/*N*/ // Die letzte ausweichende Zeile, sollte in der Hoehe angepasst +/*N*/ // sein, damit nicht der Eindruck von "Rahmenabstaenden" aufkommt. +/*N*/ // 8221: Wichtig ist, dass Ascent == Height ist, weil die FlyPortionWerte +/*N*/ // im CalcLine in pCurr uebertragen werden und IsDummy() darauf +/*N*/ // angewiesen ist. +/*N*/ // Es gibt meines Wissens nur zwei Stellen, in denen DummyLines +/*N*/ // entstehen koennen: hier und in MakeFlyDummies. +/*N*/ // Ausgewertet wird IsDummy() in IsFirstTxtLine() und +/*N*/ // beim Zeilenwandern und im Zusammenhang mit DropCaps. +/*N*/ pFly->Height( KSHORT(aInter.Height()) ); +/*N*/ +/*N*/ // In nNextTop steckt jetzt die Unterkante des Rahmens, dem wir +/*N*/ // ausweichen oder die Oberkante des naechsten Rahmens, den wir +/*N*/ // beachten muessen. Wir koennen also jetzt getrost bis zu diesem +/*N*/ // Wert anwachsen, so sparen wir einige Leerzeilen. +/*N*/ SWRECTFN( pFrm ) +/*N*/ long nNextTop = pTxtFly->GetNextTop(); +/*N*/ if ( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nNextTop = pFrm->SwitchVerticalToHorizontal( nNextTop ); +/*N*/ if( nNextTop > aInter.Bottom() ) +/*N*/ { +/*N*/ SwTwips nH = nNextTop - aInter.Top(); +/*N*/ if( nH < KSHRT_MAX ) +/*N*/ pFly->Height( KSHORT( nH ) ); +/*N*/ } +/*N*/ if( nAscent < pFly->Height() ) +/*N*/ pFly->SetAscent( KSHORT(nAscent) ); +/*N*/ else +/*N*/ pFly->SetAscent( pFly->Height() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( rInf.GetIdx() == rInf.GetTxt().Len() ) +/*N*/ { +/*N*/ // Nicht nHeight nehmen, sonst haben wir einen Riesendescent +/*N*/ pFly->Height( pLast->Height() ); +/*N*/ pFly->SetAscent( pLast->GetAscent() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pFly->Height( KSHORT(aInter.Height()) ); +/*N*/ if( nAscent < pFly->Height() ) +/*N*/ pFly->SetAscent( KSHORT(nAscent) ); +/*N*/ else +/*N*/ pFly->SetAscent( pFly->Height() ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ rInf.SetFly( pFly ); +/*N*/ +/*N*/ if( pFly->Fix() < rInf.Width() ) +/*N*/ rInf.Width( pFly->Fix() ); +/*N*/ +/*N*/ GETGRID( pFrm->FindPageFrm() ) +/*N*/ if ( pGrid ) +/*N*/ { +/*?*/ const SwPageFrm* pPageFrm = pFrm->FindPageFrm(); +/*?*/ const SwLayoutFrm* pBody = pPageFrm->FindBodyCont(); +/*?*/ +/*?*/ SWRECTFN( pPageFrm ) +/*?*/ +/*?*/ const long nGridOrigin = pBody ? +/*?*/ (pBody->*fnRect->fnGetPrtLeft)() : +/*?*/ (pPageFrm->*fnRect->fnGetPrtLeft)(); +/*?*/ +/*?*/ const USHORT nGridWidth = pGrid->GetBaseHeight(); +/*?*/ +/*?*/ SwTwips nStartX = GetLeftMargin(); +/*?*/ if ( bVert ) +/*?*/ { +/*?*/ Point aPoint( nStartX, 0 ); +/*?*/ pFrm->SwitchHorizontalToVertical( aPoint ); +/*?*/ nStartX = aPoint.Y(); +/*?*/ } +/*?*/ +/*?*/ const SwTwips nOfst = nStartX - nGridOrigin; +/*?*/ const SwTwips nTmpWidth = rInf.Width() + nOfst; +/*?*/ +/*?*/ const ULONG i = nTmpWidth / nGridWidth + 1; +/*?*/ +/*?*/ const long nNewWidth = ( i - 1 ) * nGridWidth - nOfst; +/*?*/ if ( nNewWidth > 0 ) +/*?*/ rInf.Width( (USHORT)nNewWidth ); +/*?*/ else +/*?*/ rInf.Width( 0 ); +/*N*/ } +/*N*/ } +/*N*/ } + +/***************************************************************************** + * SwTxtFormatter::NewFlyCntPortion + * legt eine neue Portion fuer ein zeichengebundenes Objekt an. + *****************************************************************************/ + +/*N*/ SwFlyCntPortion *SwTxtFormatter::NewFlyCntPortion( SwTxtFormatInfo &rInf, +/*N*/ SwTxtAttr *pHint ) const +/*N*/ { +/*N*/ SwFlyCntPortion *pRet = 0; +/*N*/ const SwFrm *pFrame = (SwFrm*)pFrm; +/*N*/ +/*N*/ SwFlyInCntFrm *pFly; +/*N*/ SwFrmFmt* pFrmFmt = ((SwTxtFlyCnt*)pHint)->GetFlyCnt().GetFrmFmt(); +/*N*/ if( RES_FLYFRMFMT == pFrmFmt->Which() ) +/*N*/ pFly = ((SwTxtFlyCnt*)pHint)->GetFlyFrm(pFrame); +/*N*/ else +/*N*/ pFly = NULL; +/*N*/ // aBase bezeichnet die dokumentglobale Position, +/*N*/ // ab der die neue Extraportion plaziert wird. +/*N*/ // aBase.X() = Offset in der Zeile, +/*N*/ // hinter der aktuellen Portion +/*N*/ // aBase.Y() = LineIter.Y() + Ascent der aktuellen Portion +/*N*/ +/*N*/ SwLinePortion *pPos = pCurr->GetFirstPortion(); +/*N*/ +/*N*/ long nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc; +/*N*/ lcl_MaxAscDescent( pPos, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc ); +/*N*/ +/*N*/ // Wenn der Ascent des Rahmens groesser als der Ascent der akt. Portion +/*N*/ // ist, wird dieser bei der Base-Berechnung verwendet, sonst wuerde +/*N*/ // der Rahmen zunaechst zu weit nach oben gesetzt, um dann doch wieder +/*N*/ // nach unten zu rutschen und dabei ein Repaint in einem Bereich ausloesen, +/*N*/ // indem er niemals wirklich war. +/*N*/ KSHORT nAscent; +/*N*/ if ( IsQuick() || !pFly || !pFly->GetValidPosFlag() || +/*N*/ ( GetInfo().GetTxtFrm()->IsVertical() ? +/*N*/ ( ! pFly->GetRefPoint().X() || +/*N*/ ( nAscent = Abs( int( pFly->GetRelPos().X() ) ) ) ) : +/*N*/ ( ! pFly->GetRefPoint().Y() || +/*N*/ ( nAscent = Abs( int( pFly->GetRelPos().Y() ) ) ) ) ) ) +/*N*/ nAscent = rInf.GetLast()->GetAscent(); +/*N*/ else if( nAscent > nFlyAsc ) +/*N*/ nFlyAsc = nAscent; +/*N*/ +/*N*/ Point aBase( GetLeftMargin() + rInf.X(), Y() + nAscent ); +/*N*/ sal_uInt8 nMode = IsQuick() ? SETBASE_QUICK : 0; +/*N*/ if( GetMulti() && GetMulti()->HasRotation() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ nMode |= SETBASE_ROTATE; +/*N*/ } +/*N*/ +/*N*/ Point aTmpBase( aBase ); +/*N*/ if ( GetInfo().GetTxtFrm()->IsVertical() ) +/*?*/ GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase ); +/*N*/ +/*N*/ if( pFly ) +/*N*/ { +/*N*/ pRet = new SwFlyCntPortion( *GetInfo().GetTxtFrm(), pFly, aTmpBase, +/*N*/ nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode ); +/*N*/ // Wir muessen sicherstellen, dass unser Font wieder im OutputDevice +/*N*/ // steht. Es koennte sein, dass der FlyInCnt frisch eingefuegt wurde, +/*N*/ // dann hat GetFlyFrm dazu gefuehrt, dass er neu angelegt wird. +/*N*/ // Dessen Frames werden sofort formatiert, die verstellen den Font +/*N*/ // und schon haben wir den Salat (3322). +/*N*/ rInf.SelectFont(); +/*N*/ if( pRet->GetAscent() > nAscent ) +/*N*/ { +/*N*/ aBase.Y() = Y() + pRet->GetAscent(); +/*N*/ nMode |= SETBASE_ULSPACE; +/*N*/ if( !rInf.IsTest() ) +/*N*/ aTmpBase = aBase; +/*N*/ if ( GetInfo().GetTxtFrm()->IsVertical() ) +/*?*/ GetInfo().GetTxtFrm()->SwitchHorizontalToVertical( aTmpBase ); +/*N*/ +/*N*/ pRet->SetBase( *rInf.GetTxtFrm(), aTmpBase, nTmpAscent, +/*N*/ nTmpDescent, nFlyAsc, nFlyDesc, nMode ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ pRet = new SwFlyCntPortion( *rInf.GetTxtFrm(), (SwDrawContact*)pFrmFmt->FindContactObj(), +/*N*/ aTmpBase, nTmpAscent, nTmpDescent, nFlyAsc, nFlyDesc, nMode ); +/*N*/ } +/*N*/ return pRet; +/*N*/ } + + + +/************************************************************************* + * SwTxtFly::SwTxtFly() + *************************************************************************/ + +/*N*/ SwTxtFly::SwTxtFly( const SwTxtFly& rTxtFly ) +/*N*/ { +/*N*/ pPage = rTxtFly.pPage; +/*N*/ pCurrFly = rTxtFly.pCurrFly; +/*N*/ pCurrFrm = rTxtFly.pCurrFrm; +/*N*/ pMaster = rTxtFly.pMaster; +/*N*/ if( rTxtFly.pFlyList ) +/*N*/ { +/*N*/ pFlyList = new SwFlyList( (BYTE)rTxtFly.pFlyList->Count(), 10 ); +/*N*/ pFlyList->Insert( rTxtFly.pFlyList, 0 ); +/*N*/ } +/*N*/ else +/*N*/ pFlyList = NULL; +/*N*/ +/*N*/ bOn = rTxtFly.bOn; +/*N*/ bLeftSide = rTxtFly.bLeftSide; +/*N*/ bTopRule = rTxtFly.bTopRule; +/*N*/ } + +/*N*/ void SwTxtFly::CtorInit( const SwTxtFrm *pFrm ) +/*N*/ { +/*N*/ mbIgnoreCurrentFrame = sal_False; +/*N*/ mbIgnoreContour = sal_False; +/*N*/ pPage = pFrm->FindPageFrm(); +/*N*/ const SwFlyFrm* pTmp = pFrm->FindFlyFrm(); +/*N*/ pCurrFly = pTmp ? pTmp->GetVirtDrawObj() : NULL; +/*N*/ pCurrFrm = pFrm; +/*N*/ pMaster = pCurrFrm->IsFollow() ? NULL : pCurrFrm; +/*N*/ pFlyList = NULL; +/*N*/ // Wenn wir nicht von einem Frame ueberlappt werden, oder wenn +/*N*/ // es gar keine FlyCollection gibt, dann schaltet wir uns fuer immer ab. +/*N*/ // Aber es koennte sein, dass waehrend der Formatierung eine Zeile +/*N*/ // hinzukommt, die in einen Frame hineinragt. Deswegen keine Optimierung +/*N*/ // per bOn = pSortedFlys && IsAnyFrm(); +/*N*/ bOn = pPage->GetSortedObjs() != 0; +/*N*/ bTopRule = sal_True; +/*N*/ bLeftSide = sal_False; +/*N*/ nMinBottom = 0; +/*N*/ nIndex = ULONG_MAX; +/*N*/ } + +/************************************************************************* + * SwTxtFly::_GetFrm() + * + * IN: dokumentglobal (rRect) + * OUT: framelokal (return-Wert) + * Diese Methode wird waehrend der Formatierung vom LineIter gerufen. + * 1. um die naechste FlyPortion vorzubereiten + * 2. um nach Aenderung der Zeilenhoehe neue Ueberlappungen festzustellen + *************************************************************************/ + +/*N*/ SwRect SwTxtFly::_GetFrm( const SwRect &rRect, sal_Bool bTop ) const +/*N*/ { +/*N*/ SwRect aRet; +/*N*/ if( ForEach( rRect, &aRet, sal_True ) ) +/*N*/ { +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ if( bTop ) +/*N*/ (aRet.*fnRect->fnSetTop)( (rRect.*fnRect->fnGetTop)() ); +/*N*/ +/*N*/ // 8110: Bottom nicht immer anpassen. +/*N*/ const SwTwips nRetBottom = (aRet.*fnRect->fnGetBottom)(); +/*N*/ const SwTwips nRectBottom = (rRect.*fnRect->fnGetBottom)(); +/*N*/ if ( (*fnRect->fnYDiff)( nRetBottom, nRectBottom ) > 0 || +/*N*/ (aRet.*fnRect->fnGetHeight)() < 0 ) +/*N*/ (aRet.*fnRect->fnSetBottom)( nRectBottom ); +/*N*/ } +/*N*/ return aRet; +/*N*/ } + +/************************************************************************* + * SwTxtFly::IsAnyFrm() + * + * IN: dokumentglobal + * fuer die Printarea des aktuellen Frame + * + * dient zum Abschalten des SwTxtFly, wenn keine Objekte ueberlappen (Relax) + * + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFly::IsAnyFrm() const +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( pCurrFrm ) +/*N*/ +/*N*/ ASSERT( bOn, "IsAnyFrm: Why?" ); +/*N*/ SwRect aRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(), +/*N*/ pCurrFrm->Prt().SSize() ); +/*N*/ +/*N*/ const sal_Bool bRet = ForEach( aRect, NULL, sal_False ); +/*N*/ UNDO_SWAP( pCurrFrm ) +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtFly::IsAnyObj() + * + * IN: dokumentglobal + * OUT: sal_True Wenn ein Rahmen oder DrawObj beruecksichtigt werden muss + * Nur wenn IsAnyObj sal_False liefert, koennen Optimierungen benutzt werden + * wie Paint/FormatEmpty fuer leere Absaetze + * und auch das virtuelle Outputdevice. + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFly::IsAnyObj( const SwRect &rRect ) const +/*N*/ { +/*N*/ ASSERT ( bOn, "SwTxtFly::IsAnyObj: Who's knocking?" ); +/*N*/ +/*N*/ SwRect aRect( rRect ); +/*N*/ if ( aRect.IsEmpty() ) +/*N*/ aRect = SwRect( pCurrFrm->Frm().Pos() + pCurrFrm->Prt().Pos(), +/*N*/ pCurrFrm->Prt().SSize() ); +/*N*/ +/*N*/ const SwSortDrawObjs *pSorted = pPage->GetSortedObjs(); +/*N*/ if( pSorted ) // Eigentlich ist durch bOn sichergestellt, dass es an der +/*N*/ // Seite Objekte gibt, aber wer weiss, wer inzwischen etwas geloescht hat. +/*N*/ { +/*N*/ for ( MSHORT i = 0; i < pSorted->Count(); ++i ) +/*N*/ { +/*N*/ const SdrObject *pObj = (*pSorted)[i]; +/*N*/ +/*N*/ const SwRect aBound( GetBoundRect( pObj ) ); +/*N*/ +/*N*/ // Optimierung +/*N*/ if( pObj->GetBoundRect().Left() > aRect.Right() ) +/*N*/ continue; +/*N*/ +/*N*/ if( pCurrFly != pObj && aBound.IsOver( aRect ) ) +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +/*N*/ const SwCntntFrm* SwTxtFly::_GetMaster() +/*N*/ { +/*N*/ pMaster = pCurrFrm; +/*N*/ while( pMaster->IsFollow() ) +/*N*/ pMaster = (SwCntntFrm*)pMaster->FindMaster(); +/*N*/ return pMaster; +/*N*/ } + +/************************************************************************* + * SwTxtFly::DrawTextOpaque() + * + * IN: dokumentglobal + * DrawTextOpaque() wird von DrawText() gerufen. + * Die Clipregions werden so gesetzt, dass nur die Teile ausgegeben werden, + * die nicht in den Bereichen von FlyFrms liegen, die undurchsichtig und + * ueber dem aktuellen Frame liegen. + * Die On-Optimierung uebernimmt DrawText()! + *************************************************************************/ + +#define UINT32_MAX 0xFFFFFFFF + + +/************************************************************************* + * SwTxtFly::DrawFlyRect() + * + * IN: windowlokal + * Zwei Feinheiten gilt es zu beachten: + * 1) DrawRect() oberhalb des ClipRects sind erlaubt ! + * 2) FlyToRect() liefert groessere Werte als die Framedaten ! + *************************************************************************/ + + +/************************************************************************* + * SwTxtFly::GetTop() + * + * GetTop() ueberprueft, ob pNew ueber pCurrFly liegt (Z-Order). + * Es gilt, dass die unten liegenden die obenliegenden beachten nicht + * umgekehrt ! + * Returnwert: pNew, wenn pNew ueber pCurrFly liegt, ansonsten 0. + * wird nur von InitFlyList benutzt, um die in Frage kommenden Objekte + * einzusammeln. + *************************************************************************/ + +/*M*/ sal_Bool SwTxtFly::GetTop( const SdrObject *pNew, const sal_Bool bInFtn, +/*M*/ const sal_Bool bInFooterOrHeader ) +/*M*/ { +/*M*/ if( pNew != pCurrFly ) +/*M*/ { +/*N*/ // #102344# Ignore connectors which have one or more connections +/*N*/ if(pNew && pNew->ISA(SdrEdgeObj)) +/*N*/ { +/*N*/ if(((SdrEdgeObj*)pNew)->GetConnectedNode(TRUE) +/*N*/ || ((SdrEdgeObj*)pNew)->GetConnectedNode(FALSE)) +/*N*/ { +/*N*/ return sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*M*/ if( ( bInFtn || bInFooterOrHeader ) && bTopRule ) +/*M*/ { +/*M*/ SwFrmFmt *pFmt = ((SwContact*)GetUserCall(pNew))->GetFmt(); +/*M*/ const SwFmtAnchor& rNewA = pFmt->GetAnchor(); +/*M*/ +/*M*/ if ( FLY_PAGE == rNewA.GetAnchorId() ) +/*M*/ { +/*M*/ if ( bInFtn ) +/*M*/ return sal_False; +/*M*/ +/*M*/ if ( bInFooterOrHeader ) +/*M*/ { +/*M*/ SwFmtVertOrient aVert( pFmt->GetVertOrient() ); +/*M*/ BOOL bVertPrt = aVert.GetRelationOrient() == PRTAREA || +/*M*/ aVert.GetRelationOrient() == REL_PG_PRTAREA; +/*M*/ if( bVertPrt ) +/*M*/ return sal_False; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ sal_Bool bEvade = !pCurrFly //Selbst nicht im Fly -> allen ausweichen. +/*M*/ //Den Lowern ist auszuweichen. +/*M*/ || Is_Lower_Of(((SwVirtFlyDrawObj*)pCurrFly)->GetFlyFrm(), pNew); +/*M*/ if ( !bEvade ) +/*M*/ { +/*M*/ if ( !bTopRule ) +/*M*/ bEvade = sal_True; // nur an der Paint-Ordnung interessiert +/*M*/ else +/*M*/ { +/*M*/ // innerhalb von verketteten Flys wird nur Lowern ausgewichen +/*M*/ const SwFmtChain &rChain = ((SwContact*)GetUserCall(pCurrFly))->GetFmt()->GetChain(); +/*M*/ if ( !rChain.GetPrev() && !rChain.GetNext() ) +/*M*/ { +/*M*/ // Ausweichregel fuer Text: +/*M*/ const SwFmtAnchor& rNewA = +/*M*/ ((SwContact*)GetUserCall(pNew))->GetFmt()->GetAnchor(); +/*M*/ const SwFmtAnchor& rCurrA = +/*M*/ ((SwContact*)GetUserCall(pCurrFly))->GetFmt()->GetAnchor(); +/*M*/ if( FLY_IN_CNTNT == rCurrA.GetAnchorId() ) +/*M*/ return sal_False; // Zeichengebundene weichen nur Lowern aus. +/*M*/ if( FLY_PAGE == rNewA.GetAnchorId() ) +/*M*/ { //Chg: Seitengebundenen wird nur noch von anderen +/*M*/ // seitengebundenen ausgewichen! +/*M*/ if( FLY_PAGE == rCurrA.GetAnchorId() ) +/*M*/ bEvade = sal_True; +/*M*/ else +/*M*/ return sal_False; +/*M*/ } +/*M*/ else if( FLY_PAGE == rCurrA.GetAnchorId() ) +/*M*/ return sal_False; // Seitengebundene weichen nur seitengeb. aus +/*M*/ else if( FLY_AT_FLY == rNewA.GetAnchorId() ) +/*M*/ bEvade = sal_True; // Nicht seitengeb. weichen Rahmengeb. aus +/*M*/ else if( FLY_AT_FLY == rCurrA.GetAnchorId() ) +/*M*/ return sal_False; // Rahmengebundene weichen abs.geb. nicht aus +/*M*/ else if( bInFooterOrHeader ) +/*M*/ return sal_False; // In header or footer no wrapping +/*M*/ // if both bounded at paragraph +/*M*/ else // Zwei Flies mit (auto-)absatzgebunder Verankerung ... +/*M*/ // ... entscheiden nach der Reihenfolge ihrer Anker im Dok. +/*M*/ bEvade = rNewA.GetCntntAnchor()->nNode.GetIndex() <= +/*M*/ rCurrA.GetCntntAnchor()->nNode.GetIndex(); +/*M*/ } +/*M*/ } +/*M*/ // aber: es wird niemals einem hierarchisch untergeordnetem +/*M*/ // ausgewichen und ausserdem braucht nur bei Ueberlappung +/*M*/ // ausgewichen werden. +/*M*/ bEvade &= ( pCurrFly->GetOrdNum() < pNew->GetOrdNum() ); +/*M*/ if( bEvade ) +/*M*/ { +/*M*/ SwRect aTmp( GetBoundRect( pNew ) ); +/*M*/ if( !aTmp.IsOver( pCurrFly->GetBoundRect() ) ) +/*M*/ bEvade = sal_False; +/*M*/ } +/*M*/ } +/*M*/ if ( bEvade ) +/*M*/ { +/*M*/ const SwFmtAnchor& rNewA = +/*M*/ ((SwContact*)GetUserCall(pNew))->GetFmt()->GetAnchor(); +/*M*/ ASSERT( FLY_IN_CNTNT != rNewA.GetAnchorId(), "Don't call GetTop with a FlyInCntFrm" ); +/*M*/ if( FLY_PAGE == rNewA.GetAnchorId() ) +/*M*/ return sal_True; // Seitengebundenen wird immer ausgewichen. +/*M*/ +/*M*/ // Wenn absatzgebundene Flys in einem FlyCnt gefangen sind, so +/*M*/ // endet deren Einflussbereich an den Grenzen des FlyCnt! +/*M*/ // Wenn wir aber gerade den Text des FlyCnt formatieren, dann +/*M*/ // muss er natuerlich dem absatzgebundenen Frm ausweichen! +/*M*/ // pCurrFrm ist der Anker von pNew? +/*N*/ const SwFrm* pTmp = &lcl_TheAnchor( pNew ); +/*M*/ if( pTmp == pCurrFrm ) +/*M*/ return sal_True; +/*M*/ if( pTmp->IsTxtFrm() && ( pTmp->IsInFly() || pTmp->IsInFtn() ) ) +/*M*/ { +/*M*/ Point aPos; +/*M*/ if( pNew->IsWriterFlyFrame() ) +/*M*/ aPos = ( (SwVirtFlyDrawObj*)pNew )->GetFlyFrm()->Frm().Pos(); +/*M*/ else +/*M*/ aPos = pNew->GetBoundRect().TopLeft(); +/*M*/ pTmp = GetVirtualUpper( pTmp, aPos ); +/*M*/ } +/*M*/ if( pCurrFrm->GetNext() != pTmp && +/*M*/ IsFrmInSameKontext( pTmp, pCurrFrm ) ) +/*M*/ { +/*M*/ if( FLY_AT_FLY == rNewA.GetAnchorId() ) // LAYER_IMPL +/*M*/ return sal_True; // Rahmengebundenen ausweichen. +/*M*/ // Den Index des anderen erhalten wir immer ueber das Ankerattr. +/*M*/ ULONG nTmpIndex = rNewA.GetCntntAnchor()->nNode.GetIndex(); +/*M*/ // Jetzt wird noch ueberprueft, ob der aktuelle Absatz vor dem +/*M*/ // Anker des verdraengenden Objekts im Text steht, dann wird +/*M*/ // nicht ausgewichen. +/*M*/ // Der Index wird moeglichst ueber einen SwFmtAnchor ermittelt, +/*M*/ // da sonst recht teuer. +/*M*/ if( ULONG_MAX == nIndex ) +/*M*/ nIndex = pCurrFrm->GetNode()->GetIndex(); +/*M*/ +/*M*/ if( nIndex >= nTmpIndex ) +/*M*/ return sal_True; +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ return 0; +/*M*/ } + +/************************************************************************* + * SwTxtFly::InitFlyList() + * + * fuellt die FlyList mit den Objekten, denen ggf. ausgwichen werden muss + * + *************************************************************************/ + +/*N*/ SwFlyList *SwTxtFly::InitFlyList() +/*N*/ { +/*N*/ ASSERT( pCurrFrm, "InitFlyList: No Frame, no FlyList" ); +/*N*/ ASSERT( !pFlyList, "InitFlyList: FlyList already initialized" ); +/*N*/ +/*N*/ SWAP_IF_SWAPPED( pCurrFrm ) +/*N*/ +/*N*/ const SwSortDrawObjs *pSorted = pPage->GetSortedObjs(); +/*N*/ const MSHORT nCount = pSorted ? pSorted->Count() : 0; +/*N*/ bOn = sal_False; +/*N*/ if( nCount ) +/*N*/ { +/*N*/ pFlyList = new SwFlyList( 10, 10 ); +/*N*/ +/*N*/ SwRect aRect( pCurrFrm->Prt() ); +/*N*/ aRect += pCurrFrm->Frm().Pos(); +/*N*/ // Wir machen uns etwas kleiner als wir sind, +/*N*/ // damit Ein-Twip-Ueberlappungen ignoriert werden. (#49532) +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ const long nRight = (aRect.*fnRect->fnGetRight)() - 1; +/*N*/ const long nLeft = (aRect.*fnRect->fnGetLeft)() + 1; +/*N*/ const sal_Bool bFooter = pCurrFrm->IsInFtn(); +/*N*/ const sal_Bool bR2L = pCurrFrm->IsRightToLeft(); +/*N*/ +/*N*/ for( MSHORT i = 0; i < nCount; i++ ) +/*N*/ { +/*N*/ SdrObject *pO = (*pSorted)[ i ]; +/*N*/ const SwRect aBound( GetBoundRect( pO ) ); +/*N*/ +/*N*/ if( nRight < (aBound.*fnRect->fnGetLeft)() || +/*N*/ (*fnRect->fnYDiff)( (aRect.*fnRect->fnGetTop)(), +/*N*/ (aBound.*fnRect->fnGetBottom)() ) > 0 || +/*N*/ nLeft > (aBound.*fnRect->fnGetRight)() ) +/*N*/ continue; +/*N*/ +/*N*/ if( GetTop( pO, pCurrFrm->IsInFtn(), +/*N*/ 0 != pCurrFrm->FindFooterOrHeader() ) ) +/*N*/ { +/*N*/ // OD 11.03.2003 #107862# - adjust insert position: +/*N*/ // overlapping objects should be sorted from left to right and +/*N*/ // inside left to right sorting from top to bottom. +/*N*/ // If objects on the same position are found, they are sorted +/*N*/ // on its width. +/*N*/ sal_uInt16 nPos = pFlyList->Count(); +/*N*/ while ( nPos ) +/*N*/ { +/*N*/ SdrObject* pTmpObj = (*pFlyList)[ --nPos ]; +/*N*/ const SwRect aBoundRectOfTmpObj( GetBoundRect( pTmpObj ) ); +/*N*/ if ( ( bR2L && +/*N*/ ( (aBoundRectOfTmpObj.*fnRect->fnGetRight)() == +/*N*/ (aBound.*fnRect->fnGetRight)() ) ) || +/*N*/ ( !bR2L && +/*N*/ ( (aBoundRectOfTmpObj.*fnRect->fnGetLeft)() == +/*N*/ (aBound.*fnRect->fnGetLeft)() ) ) ) +/*N*/ { +/*N*/ SwTwips nTopDiff = +/*N*/ (*fnRect->fnYDiff)( (aBound.*fnRect->fnGetTop)(), +/*N*/ (aBoundRectOfTmpObj.*fnRect->fnGetTop)() ); +/*N*/ if ( nTopDiff == 0 && +/*N*/ ( ( bR2L && +/*N*/ ( (aBound.*fnRect->fnGetLeft)() > +/*N*/ (aBoundRectOfTmpObj.*fnRect->fnGetLeft)() ) ) || +/*N*/ ( !bR2L && +/*N*/ ( (aBound.*fnRect->fnGetRight)() < +/*N*/ (aBoundRectOfTmpObj.*fnRect->fnGetRight)() ) ) ) ) +/*N*/ { +/*N*/ ++nPos; +/*N*/ break; +/*N*/ } +/*N*/ else if ( nTopDiff > 0 ) +/*N*/ { +/*N*/ ++nPos; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ else if ( ( bR2L && +/*N*/ ( (aBoundRectOfTmpObj.*fnRect->fnGetRight)() > +/*N*/ (aBound.*fnRect->fnGetRight)() ) ) || +/*N*/ ( !bR2L && +/*N*/ ( (aBoundRectOfTmpObj.*fnRect->fnGetLeft)() < +/*N*/ (aBound.*fnRect->fnGetLeft)() ) ) ) +/*N*/ { +/*N*/ ++nPos; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ pFlyList->C40_INSERT( SdrObject, pO, nPos ); +/*N*/ +/*N*/ SwContact *pContact = (SwContact*)GetUserCall(pO); +/*N*/ const SwFmtSurround &rFlyFmt = pContact->GetFmt()->GetSurround(); +/*N*/ if( rFlyFmt.IsAnchorOnly() && &lcl_TheAnchor( pO ) == GetMaster() ) +/*N*/ { +/*N*/ const SwFmtVertOrient &rTmpFmt = pContact->GetFmt()->GetVertOrient(); +/*N*/ if( VERT_BOTTOM != rTmpFmt.GetVertOrient() ) +/*N*/ nMinBottom = ( bVert && nMinBottom ) ? +/*N*/ Min( nMinBottom, aBound.Left() ) : +/*N*/ Max( nMinBottom, (aBound.*fnRect->fnGetBottom)() ); +/*N*/ } +/*N*/ +/*N*/ bOn = sal_True; +/*N*/ } +/*N*/ } +/*N*/ if( nMinBottom ) +/*N*/ { +/*N*/ SwTwips nMax = (pCurrFrm->GetUpper()->*fnRect->fnGetPrtBottom)(); +/*N*/ if( (*fnRect->fnYDiff)( nMinBottom, nMax ) > 0 ) +/*N*/ nMinBottom = nMax; +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ pFlyList = new SwFlyList( 0, 10 ); +/*N*/ +/*N*/ UNDO_SWAP( pCurrFrm ) +/*N*/ +/*N*/ return pFlyList; +/*N*/ } + +/*N*/ SwTwips SwTxtFly::CalcMinBottom() const +/*N*/ { +/*N*/ SwTwips nRet = 0; +/*N*/ const SwDrawObjs *pDrawObj = GetMaster()->GetDrawObjs(); +/*N*/ const MSHORT nCount = pDrawObj ? pDrawObj->Count() : 0; +/*N*/ if( nCount ) +/*N*/ { +/*N*/ SwTwips nEndOfFrm = pCurrFrm->Frm().Bottom(); +/*N*/ for( MSHORT i = 0; i < nCount; i++ ) +/*N*/ { +/*N*/ SdrObject *pO = (*pDrawObj)[ i ]; +/*N*/ SwContact *pContact = (SwContact*)GetUserCall(pO); +/*N*/ const SwFmtSurround &rFlyFmt = pContact->GetFmt()->GetSurround(); +/*N*/ if( rFlyFmt.IsAnchorOnly() ) +/*N*/ { +/*?*/ const SwFmtVertOrient &rTmpFmt = pContact->GetFmt()->GetVertOrient(); +/*?*/ if( VERT_BOTTOM != rTmpFmt.GetVertOrient() ) +/*?*/ { +/*?*/ const SwRect aBound( GetBoundRect( pO ) ); +/*?*/ if( aBound.Top() < nEndOfFrm ) +/*?*/ nRet = Max( nRet, aBound.Bottom() ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ SwTwips nMax = pCurrFrm->GetUpper()->Frm().Top() + +/*N*/ pCurrFrm->GetUpper()->Prt().Bottom(); +/*N*/ if( nRet > nMax ) +/*N*/ nRet = nMax; +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * Hier erfolgt die Berechnung der Kontur ... + * CalcBoundRect(..) und andere + *************************************************************************/ + +/************************************************************************* + * class SwContourCache + *************************************************************************/ + +/*N*/ SwContourCache::SwContourCache() : +/*N*/ nObjCnt( 0 ), nPntCnt( 0 ) +/*N*/ { +/*N*/ memset( (SdrObject**)pSdrObj, 0, sizeof(pSdrObj) ); +/*N*/ memset( pTextRanger, 0, sizeof(pTextRanger) ); +/*N*/ } +/*N*/ +/*N*/ SwContourCache::~SwContourCache() +/*N*/ { +/*N*/ for( MSHORT i = 0; i < nObjCnt; delete pTextRanger[ i++ ] ) +/*N*/ ; +/*N*/ } + +/*?*/ void SwContourCache::ClrObject( MSHORT nPos ) +/*?*/ { +/*?*/ ASSERT( pTextRanger[ nPos ], "ClrObject: Allready cleared. Good Bye!" ); +/*?*/ nPntCnt -= pTextRanger[ nPos ]->GetPointCount(); +/*?*/ delete pTextRanger[ nPos ]; +/*?*/ --nObjCnt; +/*?*/ memmove( (SdrObject**)pSdrObj + nPos, pSdrObj + nPos + 1, +/*?*/ ( nObjCnt - nPos ) * sizeof( SdrObject* ) ); +/*?*/ memmove( pTextRanger + nPos, pTextRanger + nPos + 1, +/*?*/ ( nObjCnt - nPos ) * sizeof( TextRanger* ) ); +/*?*/ } + +/*N*/ void ClrContourCache( const SdrObject *pObj ) +/*N*/ { +/*N*/ if( pContourCache && pObj ) +/*N*/ for( MSHORT i = 0; i < pContourCache->GetCount(); ++i ) +/*N*/ if( pObj == pContourCache->GetObject( i ) ) +/*N*/ { +/*?*/ pContourCache->ClrObject( i ); +/*?*/ break; +/*N*/ } +/*N*/ } + +/*N*/ void ClrContourCache() +/*N*/ { +/*N*/ if( pContourCache ) +/*N*/ { +/*N*/ for( MSHORT i = 0; i < pContourCache->GetCount(); +/*N*/ delete pContourCache->pTextRanger[ i++ ] ) +/*N*/ ; +/*N*/ pContourCache->nObjCnt = 0; +/*N*/ pContourCache->nPntCnt = 0; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwContourCache::CalcBoundRect + * berechnet das Rechteck, welches vom Objekt in der angegebenen Zeile + * ueberdeckt wird. + * Bei _nicht_ konturumflossenen Objekten ist dies einfach die Ueber- + * lappung von BoundRect (inkl. Abstand!) und Zeile, + * bei Konturumfluss wird das Polypolygon des Objekts abgeklappert + *************************************************************************/ + +/*N*/ const SwRect SwContourCache::CalcBoundRect( const SdrObject* pObj, +/*N*/ const SwRect &rLine, const SwTxtFrm* pFrm, const long nXPos, +/*N*/ const sal_Bool bRight ) +/*N*/ { +/*N*/ SWRECTFN( pFrm ) +/*N*/ +/*N*/ SwRect aRet; +/*N*/ const SwFmt *pFmt = +/*N*/ ((SwContact*)GetUserCall(pObj))->GetFmt(); +/*N*/ if( pFmt->GetSurround().IsContour() && +/*N*/ ( !pObj->IsWriterFlyFrame() || +/*N*/ ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Lower() && +/*N*/ ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->Lower()->IsNoTxtFrm() ) ) +/*N*/ { +/*N*/ aRet = GetBoundRect( pObj ); +/*N*/ if( aRet.IsOver( rLine ) ) +/*N*/ { +/*N*/ if( !pContourCache ) +/*N*/ pContourCache = new SwContourCache; +/*N*/ +/*N*/ aRet = pContourCache->ContourRect( +/*N*/ pFmt, pObj, pFrm, rLine, nXPos, bRight ); +/*N*/ } +/*N*/ else +/*N*/ aRet.Width( 0 ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aRet = GetBoundRect( pObj ); +/*N*/ } +/*N*/ +/*N*/ return aRet; +/*N*/ } + +/*N*/ const SwRect SwContourCache::ContourRect( const SwFmt* pFmt, +/*N*/ const SdrObject* pObj, const SwTxtFrm* pFrm, const SwRect &rLine, +/*N*/ const long nXPos, const sal_Bool bRight ) +/*N*/ { +/*N*/ SwRect aRet; +/*N*/ MSHORT nPos = 0; // Suche im Cache ... +/*N*/ while( nPos < GetCount() && pObj != pSdrObj[ nPos ] ) +/*N*/ ++nPos; +/*N*/ if( GetCount() == nPos ) // nicht gefunden +/*N*/ { +/*N*/ if( nObjCnt == POLY_CNT ) +/*N*/ { +/*?*/ nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount(); +/*?*/ delete pTextRanger[ nObjCnt ]; +/*N*/ } +/*N*/ XPolyPolygon aXPoly; +/*N*/ XPolyPolygon *pXPoly = NULL; +/*N*/ if ( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ // Vorsicht #37347: Das GetContour() fuehrt zum Laden der Grafik, +/*N*/ // diese aendert dadurch ggf. ihre Groesse, ruft deshalb ein +/*N*/ // ClrObject() auf. +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 PolyPolygon aPoly; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !pObj->ISA( E3dObject ) ) +/*N*/ pObj->TakeXorPoly( aXPoly, sal_True ); +/*N*/ pXPoly = new XPolyPolygon(); +/*N*/ pObj->TakeContour( *pXPoly ); +/*N*/ } +/*N*/ const SvxLRSpaceItem &rLRSpace = pFmt->GetLRSpace(); +/*N*/ const SvxULSpaceItem &rULSpace = pFmt->GetULSpace(); +/*N*/ memmove( pTextRanger + 1, pTextRanger, nObjCnt * sizeof( TextRanger* ) ); +/*N*/ memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nObjCnt++ * sizeof( SdrObject* ) ); +/*N*/ pSdrObj[ 0 ] = pObj; // Wg. #37347 darf das Object erst nach dem +/*N*/ // GetContour() eingetragen werden. +/*N*/ pTextRanger[ 0 ] = new TextRanger( aXPoly, pXPoly, 20, +/*N*/ (USHORT)rLRSpace.GetLeft(), (USHORT)rLRSpace.GetRight(), +/*N*/ pFmt->GetSurround().IsOutside(), sal_False, pFrm->IsVertical() ); +/*N*/ pTextRanger[ 0 ]->SetUpper( rULSpace.GetUpper() ); +/*N*/ pTextRanger[ 0 ]->SetLower( rULSpace.GetLower() ); +/*N*/ +/*N*/ delete pXPoly; +/*N*/ // UPPER_LOWER_TEST +/*N*/ #ifdef DBG_UTIL +/*N*/ if( pFmt->GetDoc()->GetRootFrm()->GetCurrShell() ) +/*N*/ { +/*N*/ sal_Bool bT2 = pFmt->GetDoc()->GetRootFrm()->GetCurrShell()->GetViewOptions()->IsTest2(); +/*N*/ sal_Bool bT6 = pFmt->GetDoc()->GetRootFrm()->GetCurrShell()->GetViewOptions()->IsTest6(); +/*N*/ if( bT2 || bT6 ) +/*N*/ { +/*?*/ if( bT2 ) +/*?*/ pTextRanger[ 0 ]->SetFlag7( sal_True ); +/*?*/ else +/*?*/ pTextRanger[ 0 ]->SetFlag6( sal_True ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ nPntCnt += pTextRanger[ 0 ]->GetPointCount(); +/*N*/ while( nPntCnt > POLY_MAX && nObjCnt > POLY_MIN ) +/*N*/ { +/*?*/ nPntCnt -= pTextRanger[ --nObjCnt ]->GetPointCount(); +/*?*/ delete pTextRanger[ nObjCnt ]; +/*N*/ } +/*N*/ } +/*N*/ else if( nPos ) +/*N*/ { +/*N*/ const SdrObject* pTmpObj = pSdrObj[ nPos ]; +/*N*/ TextRanger* pTmpRanger = pTextRanger[ nPos ]; +/*N*/ memmove( (SdrObject**)pSdrObj + 1, pSdrObj, nPos * sizeof( SdrObject* ) ); +/*N*/ memmove( pTextRanger + 1, pTextRanger, nPos * sizeof( TextRanger* ) ); +/*N*/ pSdrObj[ 0 ] = pTmpObj; +/*N*/ pTextRanger[ 0 ] = pTmpRanger; +/*N*/ } +/*N*/ SWRECTFN( pFrm ) +/*N*/ long nTmpTop = (rLine.*fnRect->fnGetTop)(); +/*N*/ // fnGetBottom is top + height +/*N*/ long nTmpBottom = (rLine.*fnRect->fnGetBottom)(); +/*N*/ +/*N*/ Range aRange( Min( nTmpTop, nTmpBottom ), Max( nTmpTop, nTmpBottom ) ); +/*N*/ +/*N*/ SvLongs *pTmp = pTextRanger[ 0 ]->GetTextRanges( aRange ); +/*N*/ +/*N*/ MSHORT nCount; +/*N*/ if( 0 != ( nCount = pTmp->Count() ) ) +/*N*/ { +/*N*/ MSHORT nIdx = 0; +/*N*/ while( nIdx < nCount && (*pTmp)[ nIdx ] < nXPos ) +/*N*/ ++nIdx; +/*N*/ sal_Bool bOdd = nIdx % 2 ? sal_True : sal_False; +/*N*/ sal_Bool bSet = sal_True; +/*N*/ if( bOdd ) +/*N*/ --nIdx; // innerhalb eines Intervalls +/*N*/ else if( ! bRight && ( nIdx >= nCount || (*pTmp)[ nIdx ] != nXPos ) ) +/*N*/ { +/*N*/ if( nIdx ) +/*N*/ nIdx -= 2; // ein Intervall nach links gehen +/*N*/ else +/*N*/ bSet = sal_False; // vor dem erstem Intervall +/*N*/ } +/*N*/ +/*N*/ if( bSet && nIdx < nCount ) +/*N*/ { +/*N*/ (aRet.*fnRect->fnSetTopAndHeight)( (rLine.*fnRect->fnGetTop)(), +/*N*/ (rLine.*fnRect->fnGetHeight)() ); +/*N*/ (aRet.*fnRect->fnSetLeft)( (*pTmp)[ nIdx ] ); +/*N*/ (aRet.*fnRect->fnSetRight)( (*pTmp)[ nIdx + 1 ] + 1 ); +/*N*/ } +/*N*/ } +/*N*/ return aRet; +/*N*/ } + +/************************************************************************* + * SwContourCache::ShowContour() + * zeichnet die PolyPolygone des Caches zu Debugzwecken. + *************************************************************************/ +#ifdef DBG_UTIL + +#endif + +/************************************************************************* + * SwTxtFly::ShowContour() + * zeichnet die PolyPolygone des Caches zu Debugzwecken. + *************************************************************************/ +#ifdef DBG_UTIL + +#endif + +/************************************************************************* + * SwTxtFly::ForEach() + * + * sucht nach dem ersten Objekt, welches mit dem Rechteck ueberlappt + * + *************************************************************************/ + +/*M*/ sal_Bool SwTxtFly::ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const +/*M*/ { +/*M*/ SWAP_IF_SWAPPED( pCurrFrm ) +/*M*/ +/*M*/ sal_Bool bRet = sal_False; +/*M*/ MSHORT nCount; +/*M*/ if( bOn && ( 0 != ( nCount = GetFlyList()->Count() ) ) ) +/*M*/ { +/*M*/ for( MSHORT i = 0; i < nCount; ++i ) +/*M*/ { +/*M*/ const SdrObject *pObj = (*pFlyList)[ i ]; +/*M*/ +/*M*/ SwRect aRect( GetBoundRect( pObj ) ); +/*M*/ +/*M*/ // Optimierung +/*M*/ SWRECTFN( pCurrFrm ) +/*M*/ if( (aRect.*fnRect->fnGetLeft)() > (rRect.*fnRect->fnGetRight)() ) +/*M*/ break; +/*M*/ if( pCurrFly != pObj && aRect.IsOver( rRect ) ) +/*M*/ { +/*M*/ const SwFmt *pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt(); +/*M*/ const SwFmtSurround &rSur = pFmt->GetSurround(); +/*M*/ if( bAvoid ) +/*M*/ { +/*M*/ // Wenn der Text drunter durchlaeuft, bleibt die +/*M*/ // Formatierung unbeeinflusst. Im LineIter::DrawText() +/*M*/ // muessen "nur" geschickt die ClippingRegions gesetzt werden ... +/*M*/ const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); +/*M*/ if( ( SURROUND_THROUGHT == rSur.GetSurround() && +/*M*/ ( !rSur.IsAnchorOnly() || +/*N*/ GetMaster() == &lcl_TheAnchor( pObj ) || +/*N*/ ( FLY_AT_CNTNT != rAnchor.GetAnchorId() && +/*N*/ FLY_AUTO_CNTNT != rAnchor.GetAnchorId() ) ) ) +/*N*/ || aRect.Top() == WEIT_WECH ) +/*N*/ continue; +/*N*/ } +/*N*/ +/*N*/ if ( mbIgnoreCurrentFrame && pCurrFrm == &lcl_TheAnchor( pObj ) ) +/*N*/ continue; +/*N*/ +/*N*/ if( pRect ) +/*N*/ { +/*N*/ SwRect aFly = FlyToRect( pObj, rRect ); +/*N*/ if( aFly.IsEmpty() || !aFly.IsOver( rRect ) ) +/*N*/ continue; +/*N*/ if( !bRet || +/*N*/ ( !pCurrFrm->IsRightToLeft() && +/*N*/ ( (aFly.*fnRect->fnGetLeft)() < +/*N*/ (pRect->*fnRect->fnGetLeft)() ) || +/*N*/ ( pCurrFrm->IsRightToLeft() && +/*N*/ ( (aFly.*fnRect->fnGetRight)() > +/*N*/ (pRect->*fnRect->fnGetRight)() ) ) ) ) +/*N*/ *pRect = aFly; +/*N*/ if( rSur.IsContour() ) +/*N*/ { +/*N*/ bRet = sal_True; +/*N*/ continue; +/*N*/ } +/*N*/ } +/*N*/ bRet = sal_True; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( pCurrFrm ) +/*N*/ +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * SwTxtFly::GetPos() + * + * liefert die Position im sorted Array zurueck + *************************************************************************/ + +/*N*/ MSHORT SwTxtFly::GetPos( const SdrObject *pObj ) const +/*N*/ { +/*N*/ MSHORT nCount = GetFlyList()->Count(); +/*N*/ MSHORT nRet = 0; +/*N*/ while( nRet < nCount && pObj != (*pFlyList)[ nRet ] ) +/*N*/ ++nRet; +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFly::CalcRightMargin() + * + * pObj ist das Object, der uns gerade ueberlappt. + * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird. + * Der rechte Rand ist der rechte Rand oder + * er wird durch das naechste Object, welches in die Zeile ragt, bestimmt. + *************************************************************************/ + +/*N*/ void SwTxtFly::CalcRightMargin( SwRect &rFly, MSHORT nFlyPos, +/*N*/ const SwRect &rLine ) const +/*N*/ { +/*N*/ // Normalerweise ist der rechte Rand der rechte Rand der Printarea. +/*N*/ ASSERT( ! pCurrFrm->IsVertical() || ! pCurrFrm->IsSwapped(), +/*N*/ "SwTxtFly::CalcRightMargin with swapped frame" ) +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ SwTwips nRight = (pCurrFrm->Frm().*fnRect->fnGetLeft)() + +/*N*/ (pCurrFrm->Prt().*fnRect->fnGetRight)() + 1; +/*N*/ SwTwips nFlyRight = (rFly.*fnRect->fnGetRight)(); +/*N*/ SwRect aLine( rLine ); +/*N*/ (aLine.*fnRect->fnSetRight)( nRight ); +/*N*/ (aLine.*fnRect->fnSetLeft)( (rFly.*fnRect->fnGetLeft)() ); +/*N*/ +/*N*/ // Es koennte aber sein, dass in die gleiche Zeile noch ein anderes +/*N*/ // Object hineinragt, welches _ueber_ uns liegt. +/*N*/ // Wunder der Technik: Flys mit Durchlauf sind fuer die darunterliegenden +/*N*/ // unsichtbar, das heisst, dass sie bei der Berechnung der Raender +/*N*/ // anderer Flys ebenfalls nicht auffallen. +/*N*/ // 3301: pNext->Frm().IsOver( rLine ) ist noetig +/*N*/ _FlyCntnt eOrder; +/*N*/ +/*N*/ sal_Bool bStop = sal_False; +/*N*/ MSHORT nPos = 0; +/*N*/ +/*N*/ while( nPos < pFlyList->Count() && !bStop ) +/*N*/ { +/*N*/ if( nPos == nFlyPos ) +/*N*/ { +/*N*/ ++nPos; +/*N*/ continue; +/*N*/ } +/*N*/ const SdrObject *pNext = (*pFlyList)[ nPos++ ]; +/*N*/ if( pNext == pCurrFly ) +/*N*/ continue; +/*N*/ eOrder = GetOrder( pNext ); +/*N*/ if( SURROUND_THROUGHT == eOrder ) +/*N*/ continue; +/*N*/ +/*N*/ const SwRect aTmp( SwContourCache::CalcBoundRect +/*N*/ ( pNext, aLine, pCurrFrm, nFlyRight, sal_True ) ); +/*N*/ SwTwips nTmpRight = (aTmp.*fnRect->fnGetRight)(); +/*N*/ +/*N*/ // Optimierung: +/*N*/ // In nNextTop wird notiert, an welcher Y-Positon mit Aenderung der +/*N*/ // Rahmenverhaeltnisse gerechnet werden muss. Dies dient dazu, dass, +/*N*/ // obwohl nur die Rahmen in der aktuellen Zeilenhoehe betrachtet werden, +/*N*/ // bei Rahmen ohne Umlauf die Zeilenhoehe so erhoeht wird, dass mit einer +/*N*/ // einzigen Zeile die Unterkante das Rahmens oder ggf. die Oberkante des +/*N*/ // naechsten Rahmen erreicht wird. +/*N*/ // Insbesondere bei HTML-Dokumenten kommen oft (Dummy-)Absaetze in einer +/*N*/ // 2-Pt.-Schrift vor, bis diese einem groesseren Rahmen ausgewichen sind, +/*N*/ // erforderte es frueher Unmengen von Leerzeilen. +/*N*/ const long nTmpTop = (aTmp.*fnRect->fnGetTop)(); +/*N*/ if( (*fnRect->fnYDiff)( nTmpTop, (aLine.*fnRect->fnGetTop)() ) > 0 ) +/*N*/ { +/*N*/ if( (*fnRect->fnYDiff)( nNextTop, nTmpTop ) > 0 ) +/*N*/ SetNextTop( nTmpTop ); // Die Oberkante des "naechsten" Rahmens +/*N*/ } +/*N*/ else if( ! (aTmp.*fnRect->fnGetWidth)() ) // Typisch fuer Objekte mit Konturumlauf +/*N*/ { // Bei Objekten mit Konturumlauf, die vor der aktuellen Zeile beginnen +/*N*/ // und hinter ihr enden, trotzdem aber nicht mit ihr ueberlappen, +/*N*/ // muss die Optimierung ausgeschaltet werden, denn bereits in der +/*N*/ // naechsten Zeile kann sich dies aendern. +/*N*/ if( ! (aTmp.*fnRect->fnGetHeight)() || +/*N*/ (*fnRect->fnYDiff)( (aTmp.*fnRect->fnGetBottom)(), +/*N*/ (aLine.*fnRect->fnGetTop)() ) > 0 ) +/*N*/ SetNextTop( 0 ); +/*N*/ } +/*N*/ if( aTmp.IsOver( aLine ) && nTmpRight > nFlyRight ) +/*N*/ { +/*N*/ nFlyRight = nTmpRight; +/*N*/ switch( eOrder ) +/*N*/ { +/*N*/ case SURROUND_RIGHT : +/*N*/ case SURROUND_PARALLEL : +/*N*/ { +/*N*/ // der FlyFrm wird ueberstimmt. +/*N*/ if( nRight > nFlyRight ) +/*N*/ nRight = nFlyRight; +/*N*/ bStop = sal_True; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ (rFly.*fnRect->fnSetRight)( nRight ); +/*N*/ } + +/************************************************************************* + * SwTxtFly::CalcLeftMargin() + * + * pFly ist der FlyFrm, der uns gerade ueberlappt. + * pCurrFrm ist der aktuelle Textframe, der ueberlappt wird. + * Der linke Rand ist der linke Rand der aktuellen PrintArea oder + * er wird durch den vorigen FlyFrm, der in die Zeile ragt, bestimmt. + *************************************************************************/ + +/*N*/ void SwTxtFly::CalcLeftMargin( SwRect &rFly, MSHORT nFlyPos, +/*N*/ const SwRect &rLine ) const +/*N*/ { +/*N*/ ASSERT( ! pCurrFrm->IsVertical() || ! pCurrFrm->IsSwapped(), +/*N*/ "SwTxtFly::CalcLeftMargin with swapped frame" ) +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ SwTwips nLeft = (pCurrFrm->Frm().*fnRect->fnGetLeft)() + +/*N*/ (pCurrFrm->Prt().*fnRect->fnGetLeft)(); +/*N*/ const SwTwips nFlyLeft = (rFly.*fnRect->fnGetLeft)(); +/*N*/ +/*N*/ if( nLeft > nFlyLeft ) +/*N*/ nLeft = rFly.Left(); +/*N*/ +/*N*/ SwRect aLine( rLine ); +/*N*/ (aLine.*fnRect->fnSetLeft)( nLeft ); +/*N*/ +/*N*/ // Es koennte aber sein, dass in die gleiche Zeile noch ein anderes +/*N*/ // Object hineinragt, welches _ueber_ uns liegt. +/*N*/ // Wunder der Technik: Flys mit Durchlauf sind fuer die darunterliegenden +/*N*/ // unsichtbar, das heisst, dass sie bei der Berechnung der Raender +/*N*/ // anderer Flys ebenfalls nicht auffallen. +/*N*/ // 3301: pNext->Frm().IsOver( rLine ) ist noetig +/*N*/ +/*N*/ MSHORT nMyPos = nFlyPos; +/*N*/ while( ++nFlyPos < pFlyList->Count() ) +/*N*/ { +/*N*/ const SdrObject *pNext = (*pFlyList)[ nFlyPos ]; +/*N*/ const SwRect aTmp( GetBoundRect( pNext ) ); +/*N*/ if( (aTmp.*fnRect->fnGetLeft)() >= nFlyLeft ) +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ while( nFlyPos ) +/*N*/ { +/*N*/ if( --nFlyPos == nMyPos ) +/*N*/ continue; +/*N*/ const SdrObject *pNext = (*pFlyList)[ nFlyPos ]; +/*N*/ if( pNext == pCurrFly ) +/*N*/ continue; +/*N*/ _FlyCntnt eOrder = GetOrder( pNext ); +/*N*/ if( SURROUND_THROUGHT == eOrder ) +/*N*/ continue; +/*N*/ +/*N*/ const SwRect aTmp( SwContourCache::CalcBoundRect +/*N*/ ( pNext, aLine, pCurrFrm, nFlyLeft, sal_False ) ); +/*N*/ +/*N*/ if( (aTmp.*fnRect->fnGetLeft)() < nFlyLeft && aTmp.IsOver( aLine ) ) +/*N*/ { +/*N*/ SwTwips nTmpRight = (aTmp.*fnRect->fnGetRight)(); +/*N*/ if( nLeft <= nTmpRight ) +/*N*/ nLeft = nTmpRight + 1; +/*N*/ +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ (rFly.*fnRect->fnSetLeft)( nLeft ); +/*N*/ } + +/************************************************************************* + * SwTxtFly::FlyToRect() + * + * IN: dokumentglobal (rRect) + * OUT: dokumentglobal (return-Wert) + * Liefert zu einem SwFlyFrm das von ihm in Anspruch genommene Rechteck + * unter Beruecksichtigung der eingestellten Attribute fuer den Abstand + * zum Text zurueck. + *************************************************************************/ + +/*N*/ SwRect SwTxtFly::FlyToRect( const SdrObject *pObj, const SwRect &rLine ) const +/*N*/ { +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ +/*N*/ const long nXPos = pCurrFrm->IsRightToLeft() ? +/*N*/ rLine.Right() : +/*N*/ (rLine.*fnRect->fnGetLeft)(); +/*N*/ +/*N*/ SwRect aFly = mbIgnoreContour ? +/*N*/ GetBoundRect( pObj ) : +/*N*/ SwContourCache::CalcBoundRect( pObj, rLine, pCurrFrm, +/*N*/ nXPos, ! pCurrFrm->IsRightToLeft() ); +/*N*/ +/*N*/ if( !aFly.Width() ) +/*N*/ return aFly; +/*N*/ +/*N*/ SetNextTop( (aFly.*fnRect->fnGetBottom)() ); // Damit die Zeile ggf. bis zur Unterkante +/*N*/ // des Rahmens waechst. +/*N*/ MSHORT nFlyPos = GetPos( pObj ); +/*N*/ +/*N*/ // Bei LEFT und RIGHT vergroessern wir das Rechteck. +/*N*/ // Hier gibt es einige Probleme, wenn mehrere Frames zu sehen sind. +/*N*/ // Zur Zeit wird nur der einfachste Fall angenommen: +/*N*/ // LEFT bedeutet, dass der Text links vom Frame fliessen soll, +/*N*/ // d.h. der Frame blaeht sich bis zum rechten Rand der Printarea +/*N*/ // oder bis zum naechsten Frame auf. +/*N*/ // Bei RIGHT ist es umgekehrt. +/*N*/ // Ansonsten wird immer der eingestellte Abstand zwischen Text +/*N*/ // und Frame aufaddiert. +/*N*/ switch( GetOrder( pObj ) ) +/*N*/ { +/*N*/ case SURROUND_LEFT : +/*N*/ { +/*N*/ CalcRightMargin( aFly, nFlyPos, rLine ); +/*N*/ break; +/*N*/ } +/*N*/ case SURROUND_RIGHT : +/*N*/ { +/*N*/ CalcLeftMargin( aFly, nFlyPos, rLine ); +/*N*/ break; +/*N*/ } +/*N*/ case SURROUND_NONE : +/*N*/ { +/*N*/ CalcRightMargin( aFly, nFlyPos, rLine ); +/*N*/ CalcLeftMargin( aFly, nFlyPos, rLine ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ return aFly; +/*N*/ } + + +/************************************************************************* + * SwTxtFly::CalcSmart() + * + * CalcSmart() liefert die Umlaufform zurueck. + * + * Auf beiden Seiten ist weniger als 2 cm Platz fuer den Text + * => kein Umlauf ( SURROUND_NONE ) + * Auf genau einer Seite ist mehr als 2 cm Platz + * => Umlauf auf dieser Seite ( SURROUND_LEFT / SURROUND_RIGHT ) + * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist breiter als 1,5 cm + * => Umlauf auf der breiteren Seite ( SURROUND_LEFT / SURROUND_RIGHT ) + * Auf beiden Seiten ist mehr als 2 cm Platz, das Objekt ist schmaler als 1,5 cm + * => beidseitiger Umlauf ( SURROUND_PARALLEL ) + * + *************************************************************************/ + +// Umfluss nur auf Seiten mit mindestens 2 cm Platz fuer den Text +#define TEXT_MIN 1134 +// Beidseitiger Umfluss bis zu einer Rahmenbreite von maximal 1,5 cm +#define FRAME_MAX 850 + +/*N*/ _FlyCntnt SwTxtFly::CalcSmart( const SdrObject *pObj ) const +/*N*/ { +/*N*/ _FlyCntnt eOrder; +/*N*/ +/*N*/ // 11839: Nur die X-Positionen sind interessant, die Y-Positionen des +/*N*/ // CurrentFrames koennen sich noch aendern (wachsen). +/*N*/ +/*N*/ SWRECTFN( pCurrFrm ) +/*N*/ const long nCurrLeft = (pCurrFrm->*fnRect->fnGetPrtLeft)(); +/*N*/ const long nCurrRight = (pCurrFrm->*fnRect->fnGetPrtRight)(); +/*N*/ const SwRect aRect( GetBoundRect( pObj ) ); +/*N*/ long nFlyLeft = (aRect.*fnRect->fnGetLeft)(); +/*N*/ long nFlyRight = (aRect.*fnRect->fnGetRight)(); +/*N*/ +/*N*/ if ( nFlyRight < nCurrLeft || nFlyLeft > nCurrRight ) +/*N*/ eOrder = SURROUND_PARALLEL; +/*N*/ else +/*N*/ { +/*N*/ #ifndef USED +/*N*/ long nLeft = nFlyLeft - nCurrLeft; +/*N*/ long nRight = nCurrRight - nFlyRight; +/*N*/ if( nFlyRight - nFlyLeft > FRAME_MAX ) +/*N*/ { +/*N*/ if( nLeft < nRight ) +/*N*/ nLeft = 0; +/*N*/ else +/*N*/ nRight = 0; +/*N*/ } +/*N*/ if( nLeft < TEXT_MIN ) +/*N*/ nLeft = 0; +/*N*/ if( nRight < TEXT_MIN ) +/*N*/ nRight = 0; +/*N*/ if( nLeft ) +/*N*/ eOrder = nRight ? SURROUND_PARALLEL : SURROUND_LEFT; +/*N*/ else +/*N*/ eOrder = nRight ? SURROUND_RIGHT: SURROUND_NONE; +/*N*/ #else +/*N*/ if ( nFlyRight > nCurrRight ) +/*N*/ nFlyRight = nCurrRight; +/*N*/ if ( nFlyLeft < nCurrLeft ) +/*N*/ nFlyLeft = nCurrLeft; +/*N*/ const long nCurrPart = ( nCurrRight - nCurrLeft )/3; +/*N*/ const long nFlyWidth = nFlyRight - nFlyLeft; +/*N*/ +/*N*/ if( nFlyWidth < nCurrPart ) +/*N*/ eOrder = SURROUND_PARALLEL; +/*N*/ else +/*N*/ { +/*N*/ if( nFlyWidth > (nCurrPart * 2) ) +/*N*/ eOrder = SURROUND_NONE; +/*N*/ else +/*N*/ { +/*N*/ const long nHalfCurr = ( nCurrRight + nCurrLeft ) / 2; +/*N*/ const long nHalfFly = ( nFlyRight + nFlyLeft ) / 2 ; +/*N*/ if ( nHalfFly == nHalfCurr ) +/*N*/ eOrder = SURROUND_COLUMN; +/*N*/ else +/*N*/ eOrder = nHalfFly < nHalfCurr ? +/*N*/ SURROUND_RIGHT : SURROUND_LEFT; +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ } +/*N*/ +/*N*/ return eOrder; +/*N*/ } + +/************************************************************************* + * SwTxtFly::GetOrder() + *************************************************************************/ + +/*N*/ _FlyCntnt SwTxtFly::GetOrder( const SdrObject *pObj ) const +/*N*/ { +/*N*/ const SwFrmFmt *pFmt = ((SwContact*)GetUserCall(pObj))->GetFmt(); +/*N*/ const SwFmtSurround &rFlyFmt = pFmt->GetSurround(); +/*N*/ _FlyCntnt eOrder = rFlyFmt.GetSurround(); +/*N*/ +/*N*/ if( rFlyFmt.IsAnchorOnly() && &lcl_TheAnchor( pObj ) != GetMaster() ) +/*N*/ { +/*?*/ const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); +/*?*/ if( FLY_AT_CNTNT == rAnchor.GetAnchorId() || +/*?*/ FLY_AUTO_CNTNT == rAnchor.GetAnchorId() ) +/*?*/ return SURROUND_NONE; +/*N*/ } +/*N*/ +/*N*/ // Beim Durchlauf und Nowrap wird smart ignoriert. +/*N*/ if( SURROUND_THROUGHT == eOrder || SURROUND_NONE == eOrder ) +/*N*/ return eOrder; +/*N*/ +/*N*/ // left is left and right is right +/*N*/ if ( pCurrFrm->IsRightToLeft() ) +/*N*/ { +/*?*/ if ( SURROUND_LEFT == eOrder ) +/*?*/ eOrder = SURROUND_RIGHT; +/*?*/ else if ( SURROUND_RIGHT == eOrder ) +/*?*/ eOrder = SURROUND_LEFT; +/*N*/ } +/*N*/ +/*N*/ // "idealer Seitenumlauf": +/*N*/ if( SURROUND_IDEAL == eOrder ) +/*N*/ eOrder = CalcSmart( pObj ); //Bei SMART wird die Order automatisch berechnet: +/*N*/ +/*N*/ return eOrder; +/*N*/ } + +/************************************************************************* + * SwTxtFly::IsAnyFrm( SwRect ) + * + * IN: dokumentglobal + * + * dient zum Abschalten des SwTxtFly, wenn keine Objekte ueberlappen (Relax) + * + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFly::IsAnyFrm( const SwRect &rLine ) const +/*N*/ { +/*N*/ +/*N*/ SWAP_IF_SWAPPED( pCurrFrm ) +/*N*/ +/*N*/ ASSERT( bOn, "IsAnyFrm: Why?" ); +/*N*/ +/*N*/ const sal_Bool bRet = ForEach( rLine, NULL, sal_False ); +/*N*/ UNDO_SWAP( pCurrFrm ) +/*N*/ return bRet; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx b/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx new file mode 100644 index 000000000000..72d912a0e6ff --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtfrm.cxx @@ -0,0 +1,2064 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include <hintids.hxx> + +#include <bf_sfx2/printer.hxx> +#include <bf_svx/lspcitem.hxx> +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/pgrditem.hxx> + +#include <horiornt.hxx> + +#include <doc.hxx> // GetDoc() +#include <pagefrm.hxx> // InvalidateSpelling +#include <viewsh.hxx> // ViewShell +#include <paratr.hxx> +#include <hints.hxx> // SwInsChr +#include <viewopt.hxx> +#include <dflyobj.hxx> +#include <flyfrm.hxx> +#include <tabfrm.hxx> +#include <frmtool.hxx> +#include <pagedesc.hxx> // SwPageDesc +#include <tgrditem.hxx> +#include <dbg_lay.hxx> +#include <fmtfld.hxx> +#include <fmtftn.hxx> +#include <txtfld.hxx> +#include <txtftn.hxx> +#include <ftninfo.hxx> +#include <fmtline.hxx> +#include <sectfrm.hxx> // SwSectFrm +#include <itrform2.hxx> // Iteratoren +#include <widorp.hxx> // SwFrmBreak +#include <txtcache.hxx> +#include <fntcache.hxx> // GetLineSpace benutzt pLastFont +#include <frmsh.hxx> +#include <wrong.hxx> // SwWrongList +#include <lineinfo.hxx> + +#if OSL_DEBUG_LEVEL > 1 +namespace binfilter { +extern const sal_Char *GetPrepName( const enum PrepareHint ePrep ); +} //STRIP008 +#endif +namespace binfilter { +/*N*/ TYPEINIT1( SwTxtFrm, SwCntntFrm ); + +// Switches width and height of the text frame +/*N*/ void SwTxtFrm::SwapWidthAndHeight() +/*N*/ { +/*N*/ if ( ! bIsSwapped ) +/*N*/ { +/*N*/ const long nPrtOfstX = Prt().Pos().X(); +/*N*/ Prt().Pos().X() = Prt().Pos().Y(); +/*N*/ Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const long nPrtOfstY = Prt().Pos().Y(); +/*N*/ Prt().Pos().Y() = Prt().Pos().X(); +/*N*/ Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() ); +/*N*/ } +/*N*/ +/*N*/ const long nFrmWidth = Frm().Width(); +/*N*/ Frm().Width( Frm().Height() ); +/*N*/ Frm().Height( nFrmWidth ); +/*N*/ const long nPrtWidth = Prt().Width(); +/*N*/ Prt().Width( Prt().Height() ); +/*N*/ Prt().Height( nPrtWidth ); +/*N*/ +/*N*/ bIsSwapped = ! bIsSwapped; +/*N*/ } + +// Calculates the coordinates of a rectangle when switching from +// horizontal to vertical layout. + +// Calculates the coordinates of a point when switching from +// horizontal to vertical layout. + +// Calculates the a limit value when switching from +// horizontal to vertical layout. + +// Calculates the coordinates of a rectangle when switching from +// vertical to horizontal layout. +/*N*/ void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const +/*N*/ { +/*N*/ long nOfstX; +/*N*/ +/*N*/ // calc offset inside frame +/*N*/ if ( bIsSwapped ) +/*N*/ nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() ); +/*N*/ else +/*N*/ nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() ); +/*N*/ +/*N*/ const long nOfstY = rRect.Top() - Frm().Top(); +/*N*/ const long nWidth = rRect.Height(); +/*N*/ const long nHeight = rRect.Width(); +/*N*/ +/*N*/ // calc rotated coords +/*N*/ rRect.Left( Frm().Left() + nOfstY ); +/*N*/ rRect.Top( Frm().Top() + nOfstX ); +/*N*/ rRect.Width( nWidth ); +/*N*/ rRect.Height( nHeight ); +/*N*/ } + +// Calculates the coordinates of a point when switching from +// vertical to horizontal layout. +/*N*/ void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const +/*N*/ { +/*N*/ long nOfstX; +/*N*/ +/*N*/ // calc offset inside frame +/*N*/ if ( bIsSwapped ) +/*N*/ nOfstX = Frm().Left() + Frm().Height() - rPoint.X(); +/*N*/ else +/*N*/ nOfstX = Frm().Left() + Frm().Width() - rPoint.X(); +/*N*/ +/*N*/ const long nOfstY = rPoint.Y() - Frm().Top(); +/*N*/ +/*N*/ // calc rotated coords +/*N*/ rPoint.X() = Frm().Left() + nOfstY; +/*N*/ rPoint.Y() = Frm().Top() + nOfstX; +/*N*/ } +/*N*/ +/*N*/ SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, sal_Bool bSwapIfNotSwapped ) +/*N*/ : pFrm( pTxtFrm ), bUndo( sal_False ) +/*N*/ { +/*N*/ if ( pFrm->IsVertical() && +/*N*/ ( ( bSwapIfNotSwapped && ! pFrm->IsSwapped() ) || +/*N*/ ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) ) +/*N*/ { +/*?*/ bUndo = sal_True; +/*?*/ ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); +/*N*/ } +/*N*/ } + +/*N*/ SwFrmSwapper::~SwFrmSwapper() +/*N*/ { +/*N*/ if ( bUndo ) +/*?*/ ((SwTxtFrm*)pFrm)->SwapWidthAndHeight(); +/*N*/ } + +#ifdef BIDI + +/*N*/ void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const +/*N*/ { +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1; +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ } + +/*N*/ SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) : +/*N*/ rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() ) +/*N*/ { +/*N*/ } +/*N*/ +/*N*/ SwLayoutModeModifier::~SwLayoutModeModifier() +/*N*/ { +/*N*/ ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode ); +/*N*/ } + + +/*N*/ void SwLayoutModeModifier::SetAuto() +/*N*/ { +/*N*/ const ULONG nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG; +/*N*/ ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode ); +/*N*/ } + +#endif + +/************************************************************************* + * SwTxtFrm::Init() + *************************************************************************/ + +/*N*/ void SwTxtFrm::Init() +/*N*/ { +/*N*/ ASSERT( !IsLocked(), "+SwTxtFrm::Init: this ist locked." ); +/*N*/ if( !IsLocked() ) +/*N*/ { +/*N*/ ClearPara(); +/*N*/ ResetBlinkPor(); +/*N*/ //Die Flags direkt setzen um ResetPreps und damit ein unnuetzes GetPara +/*N*/ //einzusparen. +/*N*/ // Nicht bOrphan, bLocked oder bWait auf sal_False setzen ! +/*N*/ // bOrphan = bFlag7 = bFlag8 = sal_False; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* SwTxtFrm::CTORen/DTOR +|*************************************************************************/ + +/*N*/ void SwTxtFrm::InitCtor() +/*N*/ { +/*N*/ nCacheIdx = MSHRT_MAX; +/*N*/ nOfst = 0; +/*N*/ nAllLines = 0; +/*N*/ nThisLines = 0; +/*N*/ mnFlyAnchorOfst = 0; +/*N*/ mnFlyAnchorOfstNoWrap = 0; +/*N*/ +/*N*/ nType = FRMC_TXT; +/*N*/ bLocked = bFormatted = bWidow = bUndersized = bJustWidow = +/*N*/ bEmpty = bInFtnConnect = bFtn = bRepaint = bBlinkPor = +/*N*/ bFieldFollow = bHasAnimation = bIsSwapped = sal_False; + // OD 14.03.2003 #i11760# +/*N*/ mbFollowFormatAllowed = sal_True; +/*N*/ } + + +/*N*/ SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode) +/*N*/ : SwCntntFrm(pNode) +/*N*/ { +/*N*/ InitCtor(); +/*N*/ } +/*N*/ +/*N*/ const XubString& SwTxtFrm::GetTxt() const +/*N*/ { +/*N*/ return GetTxtNode()->GetTxt(); +/*N*/ } +/*N*/ +/*N*/ void SwTxtFrm::ResetPreps() +/*N*/ { +/*N*/ if ( GetCacheIdx() != MSHRT_MAX ) +/*N*/ { +/*N*/ SwParaPortion *pPara; +/*N*/ if( 0 != (pPara = GetPara()) ) +/*N*/ pPara->ResetPreps(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::IsHiddenNow() + *************************************************************************/ +// liefert nur sal_True zurueck, wenn das Outputdevice ein Printer ist +// und bHidden gesetzt ist. + +/*N*/ sal_Bool SwTxtFrm::IsHiddenNow() const +/*N*/ { +/*N*/ SwFrmSwapper aSwapper( this, sal_True ); +/*N*/ +/*N*/ if( !Frm().Width() && IsValid() && GetUpper()->IsValid() ) +/*N*/ //bei Stackueberlauf (StackHack) invalid! +/*N*/ { +/*N*/ ASSERT( Frm().Width(), "SwTxtFrm::IsHiddenNow: thin frame" ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ if( !GetTxtNode()->IsVisible() ) +/*N*/ { +/*N*/ const ViewShell *pVsh = GetShell(); +/*N*/ if ( !pVsh ) +/*N*/ return sal_False; +/*N*/ +/*N*/ return ! pVsh->GetWin() || +/*N*/ (!pVsh->GetViewOptions()->IsShowHiddenPara() && +/*N*/ !pVsh->GetViewOptions()->IsFldName()); +/*N*/ } +/*N*/ else +/*N*/ return sal_False; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::HideHidden() + *************************************************************************/ +// Entfernt die Anhaengsel des Textfrms wenn dieser hidden ist + +/*N*/ void SwTxtFrm::HideHidden() +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::FindBrk() + * + * Liefert die erste Trennmoeglichkeit in der aktuellen Zeile zurueck. + * Die Methode wird in SwTxtFrm::Format() benutzt, um festzustellen, ob + * die Vorgaengerzeile mitformatiert werden muss. + * nFound ist <= nEndLine. + *************************************************************************/ + +/*N*/ xub_StrLen SwTxtFrm::FindBrk( const XubString &rTxt, +/*N*/ const xub_StrLen nStart, const xub_StrLen nEnd ) const +/*N*/ { +/*N*/ xub_StrLen nFound = nStart; +/*N*/ const xub_StrLen nEndLine = Min( nEnd, rTxt.Len() ); +/*N*/ +/*N*/ // Wir ueberlesen erst alle Blanks am Anfang der Zeile (vgl. Bug 2235). +/*N*/ while( nFound <= nEndLine && ' ' == rTxt.GetChar( nFound ) ) +/*N*/ ++nFound; +/*N*/ +/*N*/ // Eine knifflige Sache mit den TxtAttr-Dummy-Zeichen (hier "$"): +/*N*/ // "Dr.$Meyer" am Anfang der zweiten Zeile. Dahinter ein Blank eingegeben +/*N*/ // und das Wort rutscht nicht in die erste Zeile, obwohl es ginge. +/*N*/ // Aus diesem Grund nehmen wir das Dummy-Zeichen noch mit. +/*N*/ while( nFound <= nEndLine && ' ' != rTxt.GetChar( nFound ) ) +/*N*/ ++nFound; +/*N*/ +/*N*/ return nFound; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::IsIdxInside() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const +/*N*/ { +/*N*/ if( GetOfst() > nPos + nLen ) // d.h., der Bereich liegt komplett vor uns. +/*N*/ return sal_False; +/*N*/ +/*N*/ if( !GetFollow() ) // der Bereich liegt nicht komplett vor uns, +/*N*/ return sal_True; // nach uns kommt niemand mehr. +/*N*/ +/*N*/ const xub_StrLen nMax = GetFollow()->GetOfst(); +/*N*/ +/*N*/ // der Bereich liegt nicht komplett hinter uns bzw. +/*N*/ // unser Text ist geloescht worden. +/*N*/ if( nMax > nPos || nMax > GetTxt().Len() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // changes made in the first line of a follow can modify the master +/*N*/ const SwParaPortion* pPara = GetFollow()->GetPara(); +/*N*/ return pPara && ( nPos <= nMax + pPara->GetLen() ); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::InvalidateRange() + *************************************************************************/ +/*N*/ inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD) +/*N*/ { +/*N*/ if ( IsIdxInside( aRange.Start(), aRange.Len() ) ) +/*N*/ _InvalidateRange( aRange, nD ); +/*N*/ } + +/************************************************************************* + * SwTxtFrm::_InvalidateRange() + *************************************************************************/ + +/*N*/ void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD) +/*N*/ { +/*N*/ if ( !HasPara() ) +/*N*/ { InvalidateSize(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ SetWidow( sal_False ); +/*N*/ SwParaPortion *pPara = GetPara(); +/*N*/ +/*N*/ sal_Bool bInv = sal_False; +/*N*/ if( 0 != nD ) +/*N*/ { +/*N*/ //Auf nDelta werden die Differenzen zwischen alter und +/*N*/ //neuer Zeilenlaenge aufaddiert, deshalb ist es negativ, +/*N*/ //wenn Zeichen eingefuegt wurden, positiv, wenn Zeichen +/*N*/ //geloescht wurden. +/*N*/ *(pPara->GetDelta()) += nD; +/*N*/ bInv = sal_True; +/*N*/ } +/*N*/ SwCharRange &rReformat = *(pPara->GetReformat()); +/*N*/ if(aRange != rReformat) { +/*N*/ if( STRING_LEN == rReformat.Len() ) +/*N*/ rReformat = aRange; +/*N*/ else +/*N*/ rReformat += aRange; +/*N*/ bInv = sal_True; +/*N*/ } +/*N*/ if(bInv) +/*N*/ { +/*N*/ // 90365: nD is passed to a follow two times +/*N*/ // if( GetFollow() ) +/*N*/ // ((SwTxtFrm*)GetFollow())->InvalidateRange( aRange, nD ); +/*N*/ InvalidateSize(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcLineSpace() + *************************************************************************/ + +/*N*/ void SwTxtFrm::CalcLineSpace() +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::CalcLineSpace with swapped frame!" ) +/*N*/ +/*N*/ if( IsLocked() || !HasPara() ) +/*N*/ return; +/*N*/ +/*N*/ SwParaPortion *pPara; +/*N*/ if( GetDrawObjs() || +/*N*/ GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() || +/*N*/ ( pPara = GetPara() )->IsFixLineHeight() ) +/*N*/ { +/*?*/ Init(); +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ Size aNewSize( Prt().SSize() ); +/*N*/ +/*N*/ SwTxtFormatInfo aInf( this ); +/*N*/ SwTxtFormatter aLine( this, &aInf ); +/*N*/ if( aLine.GetDropLines() ) +/*N*/ { +/*N*/ Init(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ aLine.Top(); +/*N*/ aLine.RecalcRealHeight(); +/*N*/ +/*N*/ aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight(); +/*N*/ +/*N*/ SwTwips nDelta = aNewSize.Height() - Prt().Height(); +/*N*/ // 4291: Unterlauf bei Flys +/*N*/ if( aInf.GetTxtFly()->IsOn() ) +/*N*/ { +/*N*/ SwRect aFrm( Frm() ); +/*N*/ if( nDelta < 0 ) +/*N*/ aFrm.Height( Prt().Height() ); +/*N*/ else +/*N*/ aFrm.Height( aNewSize.Height() ); +/*N*/ if( aInf.GetTxtFly()->Relax( aFrm ) ) +/*N*/ { +/*?*/ Init(); +/*?*/ return; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( nDelta ) +/*N*/ { +/*N*/ SwTxtFrmBreak aBreak( this ); +/*N*/ if( GetFollow() || aBreak.IsBreakNow( aLine ) ) +/*N*/ { +/*N*/ // Wenn es einen Follow() gibt, oder wenn wir an dieser +/*N*/ // Stelle aufbrechen muessen, so wird neu formatiert. +/*N*/ Init(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Alles nimmt seinen gewohnten Gang ... +/*N*/ pPara->SetPrepAdjust(); +/*N*/ pPara->SetPrep(); +/*N*/ #ifdef USED +/*N*/ if (nDelta > 0) +/*N*/ Grow(nDelta,pHeight); +/*N*/ else +/*N*/ Shrink(-nDelta,pHeight); +/*N*/ ASSERT( GetPara(), "+SwTxtFrm::CalcLineSpace: missing format information" ); +/*N*/ if( pPara ) +/*N*/ pPara->GetRepaint()->SSize( Prt().SSize() ); +/*N*/ #endif +/*N*/ } +/*N*/ } +/*N*/ } + +#define SET_WRONG( nPos, nCnt, fnFunc ) \ +{ \ + if ( !IsFollow() ) \ + { \ + if( GetTxtNode()->GetWrong() ) \ + GetTxtNode()->GetWrong()->fnFunc( nPos, nCnt ); \ + else if ( ! GetTxtNode()->IsWrongDirty() ) \ + { \ + GetTxtNode()->SetWrong( new SwWrongList() ); \ + GetTxtNode()->GetWrong()->SetInvalid( nPos, nPos + ( nCnt > 0 ? nCnt : 1 ) ); \ + } \ + GetNode()->SetWrongDirty( sal_True ); \ + GetNode()->SetAutoCompleteWordDirty( sal_True ); \ + } \ + SwPageFrm *pPage = FindPageFrm(); \ + if( pPage ) \ + { \ + pPage->InvalidateSpelling(); \ + pPage->InvalidateAutoCompleteWords(); \ + } \ +} + +#define SET_SCRIPT_INVAL( nPos )\ +{ \ + if( GetPara() ) \ + GetPara()->GetScriptInfo().SetInvalidity( nPos ); \ +} + +/*N*/ void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen ) +/*N*/ { +/*N*/ if( nLen < 0 ) +/*N*/ nPos -= nLen; +/*N*/ while( pFrm && pFrm->GetOfst() <= nPos ) +/*N*/ pFrm = pFrm->GetFollow(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ pFrm->ManipOfst( pFrm->GetOfst() + nLen ); +/*N*/ pFrm = pFrm->GetFollow(); +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwTxtFrm::Modify() + *************************************************************************/ + +/*M*/ void SwTxtFrm::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew ) +/*M*/ { +/*M*/ const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; +/*M*/ +/*M*/ //Wuensche die FrmAttribute betreffen werden von der Basisklasse +/*M*/ //verarbeitet. +/*M*/ if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich ) +/*M*/ { +/*M*/ SwCntntFrm::Modify( pOld, pNew ); +/*M*/ if( nWhich == RES_FMT_CHG && GetShell() ) +/*M*/ { +/*M*/ // Collection hat sich geaendert +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ); +/*N*/ SetDerivedR2L( sal_False ); +/*N*/ CheckDirChange(); +/*N*/ // OD 09.12.2002 #105576# - Force complete paint due to existing +/*N*/ // indents. +/*N*/ SetCompletePaint(); +/*M*/ InvalidateLineNum(); +/*M*/ } +/*M*/ return; +/*M*/ } +/*M*/ +/*M*/ // Im gelockten Zustand werden keine Bestellungen angenommen. +/*M*/ if( IsLocked() ) +/*M*/ return; +/*M*/ +/*M*/ // Dies spart Stack, man muss nur aufpassen, +/*M*/ // dass sie Variablen gesetzt werden. +/*M*/ xub_StrLen nPos, nLen; +/*M*/ sal_Bool bSetFldsDirty = sal_False; +/*M*/ sal_Bool bRecalcFtnFlag = sal_False; +/*M*/ +/*M*/ switch( nWhich ) +/*M*/ { +/*M*/ case RES_LINENUMBER: +/*M*/ { +/*M*/ InvalidateLineNum(); +/*M*/ } +/*M*/ break; +/*M*/ case RES_INS_CHR: +/*M*/ { +/*M*/ nPos = ((SwInsChr*)pNew)->nPos; +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), 1 ); +/*M*/ SET_WRONG( nPos, 1, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, 1 ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_INS_TXT: +/*M*/ { +/*M*/ nPos = ((SwInsTxt*)pNew)->nPos; +/*M*/ nLen = ((SwInsTxt*)pNew)->nLen; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ if( !nLen ) +/*M*/ { +/*M*/ // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen! +/*M*/ if( nPos ) +/*M*/ InvalidateSize(); +/*M*/ else +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, nLen ), nLen ); +/*M*/ } +/*M*/ SET_WRONG( nPos, nLen, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, nLen ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_DEL_CHR: +/*M*/ { +/*M*/ nPos = ((SwDelChr*)pNew)->nPos; +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), -1 ); +/*M*/ SET_WRONG( nPos, -1, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = bRecalcFtnFlag = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, -1 ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_DEL_TXT: +/*M*/ { +/*M*/ nPos = ((SwDelTxt*)pNew)->nStart; +/*M*/ nLen = ((SwDelTxt*)pNew)->nLen; +/*M*/ long m = nLen; +/*M*/ m *= -1; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ if( !nLen ) +/*M*/ InvalidateSize(); +/*M*/ else +/*M*/ InvalidateRange( SwCharRange( nPos, 1 ), m ); +/*M*/ } +/*M*/ SET_WRONG( nPos, m, Move ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ bSetFldsDirty = bRecalcFtnFlag = sal_True; +/*M*/ if( HasFollow() ) +/*M*/ lcl_ModifyOfst( this, nPos, nLen ); +/*M*/ } +/*M*/ break; +/*M*/ case RES_UPDATE_ATTR: +/*M*/ { +/*M*/ nPos = ((SwUpdateAttr*)pNew)->nStart; +/*M*/ nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos; +/*M*/ if( IsIdxInside( nPos, nLen ) ) +/*M*/ { +/*M*/ // Es muss in jedem Fall neu formatiert werden, +/*M*/ // auch wenn der invalidierte Bereich null ist. +/*M*/ // Beispiel: leere Zeile, 14Pt einstellen ! +/*M*/ // if( !nLen ) nLen = 1; +/*M*/ +/*M*/ // 6680: FtnNummern muessen formatiert werden. +/*M*/ if( !nLen ) +/*M*/ nLen = 1; +/*M*/ +/*M*/ _InvalidateRange( SwCharRange( nPos, nLen) ); +/*M*/ MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr; +/*M*/ +/*M*/ if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || +/*M*/ RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp ) +/*M*/ { +/*M*/ SET_WRONG( nPos, nPos + nLen, Invalidate ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ } +/*N*/ else if ( RES_CHRATR_LANGUAGE == nTmp || +/*N*/ RES_CHRATR_CJK_LANGUAGE == nTmp || +/*N*/ RES_CHRATR_CTL_LANGUAGE == nTmp ) +/*M*/ SET_WRONG( nPos, nPos + nLen, Invalidate ) +/*M*/ else if ( RES_CHRATR_FONT == nTmp || RES_CHRATR_CJK_FONT == nTmp || +/*M*/ RES_CHRATR_CTL_FONT == nTmp ) +/*M*/ SET_SCRIPT_INVAL( nPos ) +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ case RES_OBJECTDYING: +/*M*/ break; +/*M*/ +/*M*/ case RES_PARATR_LINESPACING: +/*M*/ { +/*M*/ CalcLineSpace(); +/*M*/ InvalidateSize(); +/*M*/ _InvalidatePrt(); +/*M*/ if( IsInSct() && !GetPrev() ) +/*M*/ { +/*M*/ SwSectionFrm *pSect = FindSctFrm(); +/*M*/ if( pSect->ContainsAny() == this ) +/*M*/ pSect->InvalidatePrt(); +/*M*/ } +/*M*/ SwFrm* pNxt; +/*M*/ if ( 0 != ( pNxt = GetIndNext() ) ) +/*M*/ { +/*M*/ pNxt->_InvalidatePrt(); +/*M*/ if ( pNxt->IsLayoutFrm() ) +/*M*/ pNxt->InvalidatePage(); +/*M*/ } +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ break; +/*M*/ case RES_TXTATR_FIELD: +/*M*/ { +/*M*/ nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ { +/*M*/ if( pNew == pOld ) +/*M*/ { +/*M*/ // Nur repainten +/*M*/ // opt: invalidate aufs Window ? +/*M*/ InvalidatePage(); +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, 1 ) ); +/*M*/ } +/*M*/ bSetFldsDirty = sal_True; +/*M*/ } +/*M*/ break; +/*M*/ case RES_TXTATR_FTN : +/*M*/ { +/*M*/ nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart(); +/*M*/ if( IsInFtn() || IsIdxInside( nPos, 1 ) ) +/*M*/ Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() ); +/*M*/ break; +/*M*/ } +/*M*/ +/*M*/ case RES_ATTRSET_CHG: +/*M*/ { +/*M*/ InvalidateLineNum(); +/*M*/ +/*M*/ SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet(); +/*M*/ const SfxPoolItem* pItem; +/*M*/ int nClear = 0; +/*M*/ MSHORT nCount = rNewSet.Count(); +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN, +/*M*/ sal_False, &pItem )) +/*M*/ { +/*M*/ nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ Prepare( PREP_FTN, pNew ); +/*M*/ nClear = 0x01; +/*M*/ --nCount; +/*M*/ } +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD, +/*M*/ sal_False, &pItem )) +/*M*/ { +/*M*/ nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart(); +/*M*/ if( IsIdxInside( nPos, 1 ) ) +/*M*/ { +/*M*/ const SfxPoolItem& rOldItem = ((SwAttrSetChg*)pOld)-> +/*M*/ GetChgSet()->Get( RES_TXTATR_FIELD ); +/*M*/ if( pItem == &rOldItem ) +/*M*/ { +/*M*/ // Nur repainten +/*M*/ // opt: invalidate aufs Window ? +/*M*/ InvalidatePage(); +/*M*/ SetCompletePaint(); +/*M*/ } +/*M*/ else +/*M*/ _InvalidateRange( SwCharRange( nPos, 1 ) ); +/*M*/ } +/*M*/ nClear |= 0x02; +/*M*/ --nCount; +/*M*/ } +/*M*/ sal_Bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState( +/*M*/ RES_PARATR_LINESPACING, sal_False ), +/*M*/ bRegister = SFX_ITEM_SET == rNewSet.GetItemState( +/*M*/ RES_PARATR_REGISTER, sal_False ); +/*M*/ if ( bLineSpace || bRegister ) +/*M*/ { +/*M*/ Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM ); +/*M*/ CalcLineSpace(); +/*M*/ InvalidateSize(); +/*M*/ _InvalidatePrt(); +/*M*/ SwFrm* pNxt; +/*M*/ if ( 0 == ( pNxt = GetIndNext() ) && +/*M*/ bLineSpace && IsInFtn() ) +/*M*/ pNxt = FindNext(); +/*M*/ if( pNxt ) +/*M*/ { +/*M*/ pNxt->_InvalidatePrt(); +/*M*/ if ( pNxt->IsLayoutFrm() ) +/*M*/ { +/*M*/ if( pNxt->IsSctFrm() ) +/*M*/ { +/*M*/ SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny(); +/*M*/ if( pCnt ) +/*M*/ pCnt->_InvalidatePrt(); +/*M*/ } +/*M*/ pNxt->InvalidatePage(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ SetCompletePaint(); +/*M*/ nClear |= 0x04; +/*M*/ if ( bLineSpace ) +/*M*/ { +/*M*/ --nCount; +/*M*/ if( IsInSct() && !GetPrev() ) +/*M*/ { +/*M*/ SwSectionFrm *pSect = FindSctFrm(); +/*M*/ if( pSect->ContainsAny() == this ) +/*M*/ pSect->InvalidatePrt(); +/*M*/ } +/*M*/ } +/*M*/ if ( bRegister ) +/*M*/ --nCount; +/*M*/ } +/*M*/ if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT, +/*M*/ sal_False )) +/*M*/ { +/*M*/ if ( GetPrev() ) +/*M*/ CheckKeep(); +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ InvalidateSize(); +/*M*/ nClear |= 0x08; +/*M*/ --nCount; +/*M*/ } +/*M*/ +/*M*/ if( SFX_ITEM_SET == rNewSet.GetItemState( RES_BACKGROUND, sal_False) +/*M*/ && !IsFollow() && GetDrawObjs() ) +/*M*/ { +/*M*/ SwDrawObjs *pObjs = GetDrawObjs(); +/*M*/ for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i ) +/*M*/ { +/*M*/ SdrObject *pO = (*pObjs)[MSHORT(i)]; +/*M*/ if ( pO->IsWriterFlyFrame() ) +/*M*/ { +/*M*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*M*/ if( !pFly->IsFlyInCntFrm() ) +/*M*/ { +/*M*/ const SvxBrushItem &rBack = +/*M*/ pFly->GetAttrSet()->GetBackground(); +/*M*/ /// OD 20.08.2002 #99657# #GetTransChg# +/*M*/ /// following condition determines, if the fly frame +/*M*/ /// "inherites" the background color of text frame. +/*M*/ /// This is the case, if fly frame background +/*M*/ /// color is "no fill"/"auto fill" and if the fly frame +/*M*/ /// has no background graphic. +/*M*/ /// Thus, check complete fly frame background +/*M*/ /// color and *not* only its transparency value +/*M*/ if ( (rBack.GetColor() == COL_TRANSPARENT) && +/*M*/ ///if( rBack.GetColor().GetTransparency() && +/*M*/ rBack.GetGraphicPos() == GPOS_NONE ) +/*M*/ { +/*M*/ pFly->SetCompletePaint(); +/*M*/ pFly->InvalidatePage(); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_TXTATR_CHARFMT, sal_False ) ) +/*M*/ { +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ) +/*M*/ SET_SCRIPT_INVAL( 0 ) +/*M*/ } +/*M*/ else if ( SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_LANGUAGE, sal_False ) || +/*N*/ SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, sal_False ) || +/*N*/ SFX_ITEM_SET == +/*N*/ rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, sal_False ) ) +/*M*/ SET_WRONG( 0, STRING_LEN, Invalidate ) +/*M*/ else if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_FONT, sal_False ) || +/*M*/ SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_CJK_FONT, sal_False ) || +/*M*/ SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_CHRATR_CTL_FONT, sal_False ) ) +/*M*/ SET_SCRIPT_INVAL( 0 ) +/*M*/ else if ( SFX_ITEM_SET == +/*M*/ rNewSet.GetItemState( RES_FRAMEDIR, sal_False ) ) +/*M*/ { +/*M*/ SetDerivedR2L( sal_False ); +/*M*/ CheckDirChange(); +/*N*/ // OD 09.12.2002 #105576# - Force complete paint due to existing +/*N*/ // indents. +/*N*/ SetCompletePaint(); +/*M*/ } +/*M*/ +/*M*/ +/*M*/ if( nCount ) +/*M*/ { +/*M*/ if( GetShell() ) +/*M*/ { +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ } +/*M*/ +/*M*/ if( nClear ) +/*M*/ { +/*M*/ SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); +/*M*/ SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); +/*M*/ +/*M*/ if( 0x01 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_TXTATR_FTN ); +/*M*/ aNewSet.ClearItem( RES_TXTATR_FTN ); +/*M*/ } +/*M*/ if( 0x02 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_TXTATR_FIELD ); +/*M*/ aNewSet.ClearItem( RES_TXTATR_FIELD ); +/*M*/ } +/*M*/ if ( 0x04 & nClear ) +/*M*/ { +/*M*/ if ( bLineSpace ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_LINESPACING ); +/*M*/ aNewSet.ClearItem( RES_PARATR_LINESPACING ); +/*M*/ } +/*M*/ if ( bRegister ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_REGISTER ); +/*M*/ aNewSet.ClearItem( RES_PARATR_REGISTER ); +/*M*/ } +/*M*/ } +/*M*/ if ( 0x08 & nClear ) +/*M*/ { +/*M*/ aOldSet.ClearItem( RES_PARATR_SPLIT ); +/*M*/ aNewSet.ClearItem( RES_PARATR_SPLIT ); +/*M*/ } +/*M*/ SwCntntFrm::Modify( &aOldSet, &aNewSet ); +/*M*/ } +/*M*/ else +/*M*/ SwCntntFrm::Modify( pOld, pNew ); +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ +/* Seit dem neuen Blocksatz muessen wir immer neu formatieren: + case RES_PARATR_ADJUST: + { + if( GetShell() ) + { + Prepare( PREP_CLEAR ); + } + break; + } +*/ +/*M*/ // 6870: SwDocPosUpdate auswerten. +/*M*/ case RES_DOCPOS_UPDATE: +/*M*/ { +/*M*/ if( pOld && pNew ) +/*M*/ { +/*M*/ const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld; +/*M*/ if( pDocPos->nDocPos <= aFrm.Top() ) +/*M*/ { +/*M*/ const SwFmtFld *pFld = (const SwFmtFld *)pNew; +/*M*/ InvalidateRange( +/*M*/ SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) ); +/*M*/ } +/*M*/ } +/*M*/ break; +/*M*/ } +/*M*/ case RES_PARATR_SPLIT: +/*M*/ if ( GetPrev() ) +/*M*/ CheckKeep(); +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ bSetFldsDirty = sal_True; +/*M*/ break; +/*M*/ case RES_FRAMEDIR : +/*M*/ SetDerivedR2L( sal_False ); +/*M*/ CheckDirChange(); +/*M*/ break; +/*M*/ default: +/*M*/ { +/*M*/ Prepare( PREP_CLEAR ); +/*M*/ _InvalidatePrt(); +/*M*/ if ( !nWhich ) +/*M*/ { +/*M*/ //Wird z.B. bei HiddenPara mit 0 gerufen. +/*M*/ SwFrm *pNxt; +/*M*/ if ( 0 != (pNxt = FindNext()) ) +/*M*/ pNxt->InvalidatePrt(); +/*M*/ } +/*M*/ } +/*M*/ } // switch +/*M*/ +/*M*/ if( bSetFldsDirty ) +/*M*/ GetNode()->GetDoc()->SetFieldsDirty( sal_True, GetNode(), 1 ); +/*M*/ +/*M*/ if ( bRecalcFtnFlag ) +/*M*/ CalcFtnFlag(); +/*M*/ } + +/*M*/ sal_Bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const +/*M*/ { +/*M*/ if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() ) +/*M*/ { +/*M*/ SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt; +/*M*/ const SwPageFrm *pPage = FindPageFrm(); +/*M*/ if ( pPage ) +/*M*/ { +/*M*/ if ( pPage == rInfo.GetOrigPage() && !GetPrev() ) +/*M*/ { +/*M*/ //Das sollte er sein (kann allenfalls temporaer anders sein, +/*M*/ // sollte uns das beunruhigen?) +/*M*/ rInfo.SetInfo( pPage, this ); +/*M*/ return sal_False; +/*M*/ } +/*M*/ if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() && +/*M*/ (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum())) +/*M*/ { +/*M*/ //Das koennte er sein. +/*M*/ rInfo.SetInfo( pPage, this ); +/*M*/ } +/*M*/ } +/*M*/ } +/*M*/ return sal_True; +/*M*/ } + +/************************************************************************* + * SwTxtFrm::PrepWidows() + *************************************************************************/ + +/*M*/ void SwTxtFrm::PrepWidows( const MSHORT nNeed, sal_Bool bNotify ) +/*M*/ { +/*M*/ ASSERT(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends"); +/*M*/ +/*M*/ SwParaPortion *pPara = GetPara(); +/*M*/ if ( !pPara ) +/*M*/ return; +/*M*/ pPara->SetPrepWidows( sal_True ); +/*M*/ +/*M*/ // These two lines of code have been deleted for #102340#. +/*M*/ // Obviously the widow control does not work if we have a +/*M*/ // pMaster->pFollow->pFollow situation: +/*M*/ +/*M*/ // returnen oder nicht ist hier die Frage. +/*M*/ // Ohne IsLocked() ist 5156 gefaehrlich, +/*M*/ // ohne IsFollow() werden die Orphans unterdrueckt: 6968. +/*M*/ // Abfrage auf IsLocked erst hier, weil das Flag gesetzt werden soll. +/*M*/ // if( IsLocked() && IsFollow() ) +/*M*/ // return; +/*M*/ +/*M*/ MSHORT nHave = nNeed; +/*M*/ +/*M*/ // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps() +/*M*/ SWAP_IF_NOT_SWAPPED( this ) +/*M*/ +/*M*/ SwTxtSizeInfo aInf( this ); +/*M*/ SwTxtMargin aLine( this, &aInf ); +/*M*/ aLine.Bottom(); +/*M*/ xub_StrLen nTmpLen = aLine.GetCurr()->GetLen(); +/*M*/ while( nHave && aLine.PrevLine() ) +/*M*/ { +/*M*/ if( nTmpLen ) +/*M*/ --nHave; +/*M*/ nTmpLen = aLine.GetCurr()->GetLen(); +/*M*/ } +/*M*/ // In dieser Ecke tummelten sich einige Bugs: 7513, 7606. +/*M*/ // Wenn feststeht, dass Zeilen abgegeben werden koennen, +/*M*/ // muss der Master darueber hinaus die Widow-Regel ueberpruefen. +/*M*/ if( !nHave ) +/*M*/ { +/*M*/ sal_Bool bSplit; +/*M*/ if( !IsFollow() ) //Nur ein Master entscheidet ueber Orphans +/*M*/ { +/*M*/ const WidowsAndOrphans aWidOrp( this ); +/*M*/ bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() && +/*M*/ aLine.GetLineNr() >= aLine.GetDropLines() ); +/*M*/ } +/*M*/ else +/*M*/ bSplit = sal_True; +/*M*/ +/*M*/ if( bSplit ) +/*M*/ { +/*M*/ GetFollow()->SetOfst( aLine.GetEnd() ); +/*M*/ aLine.TruncLines( sal_True ); +/*M*/ if( pPara->IsFollowField() ) +/*M*/ GetFollow()->SetFieldFollow( sal_True ); +/*M*/ } +/*M*/ } +/*M*/ if ( bNotify ) +/*M*/ { +/*M*/ _InvalidateSize(); +/*M*/ InvalidatePage(); +/*M*/ } +/*M*/ +/*M*/ UNDO_SWAP( this ) +/*M*/ } + +/************************************************************************* + * SwTxtFrm::Prepare + *************************************************************************/ + +/*N*/ sal_Bool lcl_ErgoVadis( SwTxtFrm* pFrm, xub_StrLen &rPos, const PrepareHint ePrep ) +/*N*/ { +/*N*/ const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo(); +/*N*/ if( ePrep == PREP_ERGOSUM ) +/*N*/ { +/*?*/ if( !rFtnInfo.aErgoSum.Len() ) +/*?*/ return sal_False;; +/*?*/ rPos = pFrm->GetOfst(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( !rFtnInfo.aQuoVadis.Len() ) +/*N*/ return sal_False; +/*?*/ if( pFrm->HasFollow() ) +/*?*/ rPos = pFrm->GetFollow()->GetOfst(); +/*?*/ else +/*?*/ rPos = pFrm->GetTxt().Len(); +/*?*/ if( rPos ) +/*?*/ --rPos; // unser letztes Zeichen +/*N*/ } +/*N*/ return sal_True; +/*N*/ } + +/*N*/ void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid, +/*N*/ sal_Bool bNotify ) +/*N*/ { +/*N*/ SwFrmSwapper aSwapper( this, sal_False ); +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ const SwTwips nDbgY = Frm().Top(); +/*N*/ #endif +/*N*/ +/*N*/ if ( IsEmpty() ) +/*N*/ { +/*N*/ switch ( ePrep ) +/*N*/ { +/*N*/ case PREP_BOSS_CHGD: +/*N*/ SetInvalidVert( TRUE ); // Test +/*N*/ case PREP_WIDOWS_ORPHANS: +/*N*/ case PREP_WIDOWS: +/*N*/ case PREP_FTN_GONE : return; +/*N*/ +/*N*/ case PREP_POS_CHGD : +/*N*/ { +/*N*/ // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig, +/*N*/ // damit formatiert wird und ggf. das bUndersized gesetzt wird. +/*N*/ if( IsInFly() || IsInSct() ) +/*N*/ { +/*N*/ SwTwips nTmpBottom = GetUpper()->Frm().Top() + +/*N*/ GetUpper()->Prt().Bottom(); +/*N*/ if( nTmpBottom < Frm().Bottom() ) +/*N*/ break; +/*N*/ } +/*N*/ // Gibt es ueberhaupt Flys auf der Seite ? +/*N*/ SwTxtFly aTxtFly( this ); +/*N*/ if( aTxtFly.IsOn() ) +/*N*/ { +/*N*/ // Ueberlappt irgendein Fly ? +/*N*/ aTxtFly.Relax(); +/*N*/ if ( aTxtFly.IsOn() || IsUndersized() ) +/*N*/ break; +/*N*/ } +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue()) +/*N*/ break; +/*N*/ +/*N*/ GETGRID( FindPageFrm() ) +/*N*/ if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() ) +/*N*/ break; +/*N*/ +/*N*/ return; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( !HasPara() && PREP_MUST_FIT != ePrep ) +/*N*/ { +/*N*/ SetInvalidVert( TRUE ); // Test +/*N*/ ASSERT( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" ); +/*N*/ if ( bNotify ) +/*N*/ InvalidateSize(); +/*N*/ else +/*N*/ _InvalidateSize(); +/*N*/ return; +/*N*/ } +/*N*/ +/*N*/ //Objekt mit Locking aus dem Cache holen. +/*N*/ SwTxtLineAccess aAccess( this ); +/*N*/ SwParaPortion *pPara = aAccess.GetPara(); +/*N*/ +/*N*/ switch( ePrep ) +/*N*/ { +/*?*/ case PREP_MOVEFTN : Frm().Height(0); +/*?*/ Prt().Height(0); +/*?*/ _InvalidatePrt(); +/*?*/ _InvalidateSize(); +/*N*/ // KEIN break +/*N*/ case PREP_ADJUST_FRM : pPara->SetPrepAdjust( sal_True ); +/*N*/ if( IsFtnNumFrm() != pPara->IsFtnNum() || +/*N*/ IsUndersized() ) +/*N*/ { +/*N*/ InvalidateRange( SwCharRange( 0, 1 ), 1); +/*N*/ if( GetOfst() && !IsFollow() ) +/*?*/ _SetOfst( 0 ); +/*N*/ } +/*N*/ break; +/*?*/ case PREP_MUST_FIT : pPara->SetPrepMustFit( sal_True ); +/*N*/ /* no break here */ +/*N*/ case PREP_WIDOWS_ORPHANS : pPara->SetPrepAdjust( sal_True ); +/*N*/ break; +/*N*/ +/*N*/ case PREP_WIDOWS : +/*N*/ // MustFit ist staerker als alles anderes +/*N*/ if( pPara->IsPrepMustFit() ) +/*N*/ return; +/*N*/ // Siehe Kommentar in WidowsAndOrphans::FindOrphans und CalcPreps() +/*N*/ PrepWidows( *(const MSHORT *)pVoid, bNotify ); +/*N*/ break; +/*N*/ +/*N*/ case PREP_FTN : +/*N*/ { +/*N*/ SwTxtFtn *pFtn = (SwTxtFtn *)pVoid; +/*N*/ if( IsInFtn() ) +/*N*/ { +/*N*/ // Bin ich der erste TxtFrm einer Fussnote ? +/*N*/ if( !GetPrev() ) +/*N*/ // Wir sind also ein TxtFrm der Fussnote, die +/*N*/ // die Fussnotenzahl zur Anzeige bringen muss. +/*N*/ // Oder den ErgoSum-Text... +/*N*/ InvalidateRange( SwCharRange( 0, 1 ), 1); +/*N*/ +/*N*/ if( !GetNext() ) +/*N*/ { +/*N*/ // Wir sind der letzte Ftn, jetzt muessten die +/*N*/ // QuoVadis-Texte geupdated werden. +/*N*/ const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo(); +/*N*/ if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) ) +/*N*/ { +/*N*/ xub_StrLen nPos = pPara->GetParLen(); +/*N*/ if( nPos ) +/*N*/ --nPos; +/*N*/ InvalidateRange( SwCharRange( nPos, 1 ), 1); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Wir sind also der TxtFrm _mit_ der Fussnote +/*N*/ const xub_StrLen nPos = *pFtn->GetStart(); +/*N*/ InvalidateRange( SwCharRange( nPos, 1 ), 1); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case PREP_BOSS_CHGD : +/*N*/ { +/*N*/ // Test +/*N*/ { +/*N*/ SetInvalidVert( FALSE ); +/*N*/ BOOL bOld = IsVertical(); +/*N*/ SetInvalidVert( TRUE ); +/*N*/ if( bOld != IsVertical() ) +/*?*/ InvalidateRange( SwCharRange( GetOfst(), STRING_LEN ) ); +/*N*/ } +/*N*/ +/*N*/ if( HasFollow() ) +/*N*/ { +/*N*/ xub_StrLen nNxtOfst = GetFollow()->GetOfst(); +/*N*/ if( nNxtOfst ) +/*N*/ --nNxtOfst; +/*N*/ InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1); +/*N*/ } +/*N*/ if( IsInFtn() ) +/*N*/ { +/*N*/ xub_StrLen nPos; +/*?*/ if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*?*/ if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*N*/ } +/*N*/ // 4739: Wenn wir ein Seitennummernfeld besitzen, muessen wir +/*N*/ // die Stellen invalidieren. +/*N*/ SwpHints *pHints = GetTxtNode()->GetpSwpHints(); +/*N*/ if( pHints ) +/*N*/ { +/*N*/ const MSHORT nSize = pHints->Count(); +/*N*/ const xub_StrLen nEnd = GetFollow() ? +/*N*/ GetFollow()->GetOfst() : STRING_LEN; +/*N*/ for( MSHORT i = 0; i < nSize; ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pHt = (*pHints)[i]; +/*N*/ const xub_StrLen nStart = *pHt->GetStart(); +/*N*/ if( nStart >= GetOfst() ) +/*N*/ { +/*N*/ if( nStart >= nEnd ) +/*N*/ i = nSize; // fuehrt das Ende herbei +/*N*/ else +/*N*/ { +/*N*/ // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so +/*N*/ // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im +/*N*/ // Weg steht, schicken wir uns ein ADJUST_FRM. +/*N*/ // pVoid != 0 bedeutet MoveBwd() +/*N*/ const MSHORT nWhich = pHt->Which(); +/*N*/ if( RES_TXTATR_FIELD == nWhich || +/*N*/ (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich)) +/*N*/ InvalidateRange( SwCharRange( nStart, 1 ), 1 ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // A new boss, a new chance for growing +/*N*/ if( IsUndersized() ) +/*N*/ { +/*?*/ _InvalidateSize(); +/*?*/ InvalidateRange( SwCharRange( GetOfst(), 1 ), 1); +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ case PREP_POS_CHGD : +/*N*/ { +/*N*/ if ( GetValidPrtAreaFlag() ) +/*N*/ { +/*N*/ GETGRID( FindPageFrm() ) +/*N*/ if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() ) +/*?*/ InvalidatePrt(); +/*N*/ } +/*N*/ +/*N*/ // Falls wir mit niemandem ueberlappen: +/*N*/ // Ueberlappte irgendein Fly _vor_ der Positionsaenderung ? +/*N*/ sal_Bool bFormat = pPara->HasFly(); +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ if( IsInFly() ) +/*N*/ { +/*N*/ SwTwips nTmpBottom = GetUpper()->Frm().Top() + +/*N*/ GetUpper()->Prt().Bottom(); +/*N*/ if( nTmpBottom < Frm().Bottom() ) +/*N*/ bFormat = sal_True; +/*N*/ } +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ if ( GetDrawObjs() ) +/*N*/ { +/*N*/ MSHORT nCnt = GetDrawObjs()->Count(); +/*N*/ for ( MSHORT i = 0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pO = (*GetDrawObjs())[i]; +/*N*/ if ( pO->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pO)->GetFlyFrm(); +/*N*/ if( pFly->IsAutoPos() ) +/*N*/ { +/*?*/ bFormat = sal_True; +/*?*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( !bFormat ) +/*N*/ { +/*N*/ // Gibt es ueberhaupt Flys auf der Seite ? +/*N*/ SwTxtFly aTxtFly( this ); +/*N*/ if( aTxtFly.IsOn() ) +/*N*/ { +/*N*/ // Ueberlappt irgendein Fly ? +/*N*/ aTxtFly.Relax(); +/*N*/ bFormat = aTxtFly.IsOn() || IsUndersized(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if( bFormat ) +/*N*/ { +/*N*/ if( !IsLocked() ) +/*N*/ { +/*N*/ if( pPara->GetRepaint()->HasArea() ) +/*N*/ SetCompletePaint(); +/*N*/ Init(); +/*N*/ pPara = 0; +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() ) +/*N*/ Prepare( PREP_REGISTER, 0, bNotify ); +/*N*/ // Durch Positionsverschiebungen mit Ftns muessen die +/*N*/ // Frames neu adjustiert werden. +/*N*/ else if( HasFtn() ) +/*N*/ { +/*N*/ Prepare( PREP_ADJUST_FRM, 0, bNotify ); +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ else +/*N*/ return; // damit kein SetPrep() erfolgt. +/*N*/ } +/*N*/ break; +/*N*/ } +/*N*/ case PREP_REGISTER: +/*N*/ if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() ) +/*N*/ { +/*N*/ pPara->SetPrepAdjust( sal_True ); +/*N*/ CalcLineSpace(); +/*N*/ InvalidateSize(); +/*N*/ _InvalidatePrt(); +/*N*/ SwFrm* pNxt; +/*N*/ if ( 0 != ( pNxt = GetIndNext() ) ) +/*N*/ { +/*N*/ pNxt->_InvalidatePrt(); +/*N*/ if ( pNxt->IsLayoutFrm() ) +/*N*/ pNxt->InvalidatePage(); +/*N*/ } +/*N*/ SetCompletePaint(); +/*N*/ } +/*N*/ break; +/*?*/ case PREP_FTN_GONE : +/*?*/ { +/*?*/ // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere +/*?*/ // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows +/*?*/ // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit +/*?*/ // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen. +/*?*/ ASSERT( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" ); +/*?*/ xub_StrLen nPos = GetFollow()->GetOfst(); +/*?*/ if( IsFollow() && GetOfst() == nPos ) // falls wir gar keine Textmasse besitzen, +/*?*/ FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters +/*?*/ if( nPos ) +/*?*/ --nPos; // das Zeichen vor unserem Follow +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*?*/ return; +/*?*/ } +/*N*/ case PREP_ERGOSUM: +/*N*/ case PREP_QUOVADIS: +/*N*/ { +/*N*/ xub_StrLen nPos; +/*N*/ if( lcl_ErgoVadis( this, nPos, ePrep ) ) +/*?*/ InvalidateRange( SwCharRange( nPos, 1 ), 0 ); +/*N*/ } +/*N*/ break; +/*N*/ case PREP_FLY_ATTR_CHG: +/*N*/ { +/*N*/ if( pVoid ) +/*N*/ { +/*N*/ xub_StrLen nWhere = CalcFlyPos( (SwFrmFmt*)pVoid ); +/*N*/ ASSERT( STRING_LEN != nWhere, "Prepare: Why me?" ); +/*N*/ InvalidateRange( SwCharRange( nWhere, 1 ) ); +/*N*/ return; +/*N*/ } +/*N*/ // else ... Laufe in den Default-Switch +/*N*/ } +/*N*/ case PREP_CLEAR: +/*N*/ default: +/*N*/ { +/*N*/ if( IsLocked() ) +/*N*/ { +/*N*/ if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep ) +/*N*/ { +/*N*/ xub_StrLen nLen = ( GetFollow() ? GetFollow()->GetOfst() : +/*N*/ STRING_LEN ) - GetOfst(); +/*N*/ InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 ); +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pPara->GetRepaint()->HasArea() ) +/*N*/ SetCompletePaint(); +/*N*/ Init(); +/*N*/ pPara = 0; +/*N*/ if( GetOfst() && !IsFollow() ) +/*?*/ _SetOfst( 0 ); +/*N*/ if ( bNotify ) +/*N*/ InvalidateSize(); +/*N*/ else +/*N*/ _InvalidateSize(); +/*N*/ } +/*N*/ return; // damit kein SetPrep() erfolgt. +/*N*/ } +/*N*/ } +/*N*/ if( pPara ) +/*N*/ pPara->SetPrep( sal_True ); +/*N*/ } + +/* -----------------11.02.99 17:56------------------- + * Kleine Hilfsklasse mit folgender Funktion: + * Sie soll eine Probeformatierung vorbereiten. + * Der Frame wird in Groesse und Position angepasst, sein SwParaPortion zur Seite + * gestellt und eine neue erzeugt, dazu wird formatiert mit gesetztem bTestFormat. + * Im Dtor wird der TxtFrm wieder in seinen alten Zustand zurueckversetzt. + * + * --------------------------------------------------*/ + +class SwTestFormat +{ + SwTxtFrm *pFrm; + SwParaPortion *pOldPara; + SwRect aOldFrm, aOldPrt; +public: + SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight ); + ~SwTestFormat(); +}; + +/*N*/ SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight ) +/*N*/ : pFrm( pTxtFrm ) +/*N*/ { +/*N*/ aOldFrm = pFrm->Frm(); +/*N*/ aOldPrt = pFrm->Prt(); +/*N*/ +/*N*/ SWRECTFN( pFrm ) +/*N*/ SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)(); +/*N*/ +/*N*/ pFrm->Frm() = pFrm->GetUpper()->Prt(); +/*N*/ pFrm->Frm() += pFrm->GetUpper()->Frm().Pos(); +/*N*/ +/*N*/ (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight ); +/*N*/ if( pFrm->GetPrev() ) +/*N*/ (pFrm->Frm().*fnRect->fnSetPosY)( +/*N*/ (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() - +/*N*/ ( bVert ? nMaxHeight + 1 : 0 ) ); +/*N*/ +/*N*/ SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm ); +/*N*/ const SwBorderAttrs &rAttrs = *aAccess.Get(); +/*N*/ (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) ); +/*N*/ +/*N*/ if( pPre ) +/*N*/ { +/*N*/ SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre ); +/*N*/ (pFrm->Prt().*fnRect->fnSetPosY)( nUpper ); +/*N*/ } +/*N*/ (pFrm->Prt().*fnRect->fnSetHeight)( +/*N*/ Max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() - +/*N*/ (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) ); +/*N*/ (pFrm->Prt().*fnRect->fnSetWidth)( +/*N*/ (pFrm->Frm().*fnRect->fnGetWidth)() - +/*N*/ // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)> +/*N*/ ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) ); +/*N*/ pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL; +/*N*/ pFrm->SetPara( new SwParaPortion(), sal_False ); +/*N*/ +/*N*/ ASSERT( ! pFrm->IsSwapped(), "A frame is swapped before _Format" ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwapWidthAndHeight(); +/*N*/ +/*N*/ SwTxtFormatInfo aInf( pFrm, sal_False, sal_True, sal_True ); +/*N*/ SwTxtFormatter aLine( pFrm, &aInf ); +/*N*/ +/*N*/ pFrm->_Format( aLine, aInf ); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*?*/ pFrm->SwapWidthAndHeight(); +/*N*/ +/*N*/ ASSERT( ! pFrm->IsSwapped(), "A frame is swapped after _Format" ); +/*N*/ } + +/*N*/ SwTestFormat::~SwTestFormat() +/*N*/ { +/*N*/ pFrm->Frm() = aOldFrm; +/*N*/ pFrm->Prt() = aOldPrt; +/*N*/ pFrm->SetPara( pOldPara ); +/*N*/ } + +/*N*/ sal_Bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, sal_Bool &bSplit ) +/*N*/ { +/*N*/ PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 ) +/*N*/ +/*N*/ if( IsLocked() && GetUpper()->Prt().Width() <= 0 ) +/*N*/ return sal_False; +/*N*/ +/*N*/ SwTestFormat aSave( this, pPrv, rMaxHeight ); +/*N*/ +/*N*/ return SwTxtFrm::WouldFit( rMaxHeight, bSplit ); +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::WouldFit() + *************************************************************************/ + +/* SwTxtFrm::WouldFit() + * sal_True: wenn ich aufspalten kann. + * Es soll und braucht nicht neu formatiert werden. + * Wir gehen davon aus, dass bereits formatiert wurde und dass + * die Formatierungsdaten noch aktuell sind. + * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und + * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans() + * gerufen. + * Die benoetigte Hoehe wird von nMaxHeight abgezogen! + */ + +/*N*/ sal_Bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, sal_Bool &bSplit ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::WouldFit with swapped frame" ); +/*N*/ SWRECTFN( this ); +/*N*/ +/*N*/ if( IsLocked() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ //Kann gut sein, dass mir der IdleCollector mir die gecachten +/*N*/ //Informationen entzogen hat. +/*N*/ if( !IsEmpty() ) +/*N*/ GetFormatted(); +/*N*/ +/*N*/ if ( IsEmpty() ) +/*N*/ { +/*N*/ bSplit = sal_False; +/*N*/ SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height(); +/*N*/ if( rMaxHeight < nHeight ) +/*N*/ return sal_False; +/*N*/ else +/*N*/ { +/*N*/ rMaxHeight -= nHeight; +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein. +/*N*/ // Dann returnen wir sal_True, um auf der neuen Seite noch einmal +/*N*/ // anformatiert zu werden. +/*N*/ ASSERT( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" ); +/*N*/ if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) ) +/*N*/ return sal_True; +/*N*/ +/*N*/ // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite +/*N*/ // Bedingung ueberprueft, ob die Rahmengroesse durch CalcPreps +/*N*/ // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen. +/*N*/ if( IsWidow() || ( bVert ? +/*N*/ ( 0 == Frm().Left() ) : +/*N*/ ( LONG_MAX - 20000 < Frm().Bottom() ) ) ) +/*N*/ { +/*?*/ SetWidow(sal_False); +/*?*/ if ( GetFollow() ) +/*?*/ { +/*?*/ // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet +/*?*/ // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer +/*?*/ // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms) +/*?*/ // ignorieren wir das IsWidow() und pruefen doch noch, ob wir +/*?*/ // genung Platz finden. +/*?*/ if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) || +/*?*/ ( bVert && 0 < Frm().Left() ) ) && +/*?*/ ( GetFollow()->IsVertical() ? +/*?*/ !GetFollow()->Frm().Width() : +/*?*/ !GetFollow()->Frm().Height() ) ) +/*?*/ { +/*?*/ SwTxtFrm* pFoll = GetFollow()->GetFollow(); +/*?*/ while( pFoll && +/*?*/ ( pFoll->IsVertical() ? +/*?*/ !pFoll->Frm().Width() : +/*?*/ !pFoll->Frm().Height() ) ) +/*?*/ pFoll = pFoll->GetFollow(); +/*?*/ if( pFoll ) +/*?*/ return sal_False; +/*?*/ } +/*?*/ else +/*?*/ return sal_False; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ); +/*N*/ +/*N*/ SwTxtSizeInfo aInf( this ); +/*N*/ SwTxtMargin aLine( this, &aInf ); +/*N*/ +/*N*/ WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit ); +/*N*/ +/*N*/ register sal_Bool bRet = sal_True; +/*N*/ +/*N*/ aLine.Bottom(); +/*N*/ // Ist Aufspalten ueberhaupt notwendig? +/*N*/ if ( 0 != ( bSplit = !aFrmBreak.IsInside( aLine ) ) ) +/*N*/ bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight ); +/*N*/ else +/*N*/ { +/*N*/ //Wir brauchen die Gesamthoehe inklusive der aktuellen Zeile +/*N*/ aLine.Top(); +/*N*/ do +/*N*/ { +/*N*/ rMaxHeight -= aLine.GetLineHeight(); +/*N*/ } while ( aLine.Next() ); +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return bRet; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::GetParHeight() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::GetParHeight() const +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::GetParHeight with swapped frame" ) +/*N*/ +/*N*/ if( !HasPara() ) +/*N*/ { // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir +/*N*/ // bei UnderSized ruhig nur 1 Twip mehr anfordern. +/*N*/ KSHORT nRet = (KSHORT)Prt().SSize().Height(); +/*N*/ if( IsUndersized() ) +/*N*/ { +/*N*/ if( IsEmpty() ) +/*N*/ nRet = (KSHORT)EmptyHeight(); +/*N*/ else +/*N*/ ++nRet; +/*N*/ } +/*N*/ return nRet; +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ SwTxtFrm *pThis = (SwTxtFrm*)this; +/*N*/ SwTxtSizeInfo aInf( pThis ); +/*N*/ SwTxtIter aLine( pThis, &aInf ); +/*N*/ KSHORT nHeight = aLine.GetLineHeight(); +/*N*/ if( GetOfst() && !IsFollow() ) // Ist dieser Absatz gescrollt? Dann ist unsere +/*?*/ nHeight += aLine.GetLineHeight(); // bisherige Hoehe mind. eine Zeilenhoehe zu gering +/*N*/ while( aLine.Next() ) +/*N*/ nHeight += aLine.GetLineHeight(); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return nHeight; +/*N*/ } + + +/************************************************************************* + * SwTxtFrm::GetFormatted() + *************************************************************************/ + +// returnt this _immer_ im formatierten Zustand! +/*N*/ SwTxtFrm *SwTxtFrm::GetFormatted() +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ //Kann gut sein, dass mir der IdleCollector mir die gecachten +/*N*/ //Informationen entzogen hat. Calc() ruft unser Format. +/*N*/ //Nicht bei leeren Absaetzen! +/*N*/ if( !HasPara() && !(IsValid() && IsEmpty()) ) +/*N*/ { +/*N*/ // Calc() muss gerufen werden, weil unsere Frameposition +/*N*/ // nicht stimmen muss. +/*N*/ const sal_Bool bFormat = GetValidSizeFlag(); +/*N*/ Calc(); +/*N*/ // Es kann durchaus sein, dass Calc() das Format() +/*N*/ // nicht anstiess (weil wir einst vom Idle-Zerstoerer +/*N*/ // aufgefordert wurden unsere Formatinformationen wegzuschmeissen). +/*N*/ // 6995: Optimierung mit FormatQuick() +/*N*/ if( bFormat && !FormatQuick() ) +/*N*/ Format(); +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return this; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::CalcFitToContent() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::GetLineSpace() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::GetLineSpace() const +/*N*/ { +/*N*/ KSHORT nRet = 0; +/*N*/ long nTmp; +/*N*/ +/*N*/ const SwAttrSet* pSet = GetAttrSet(); +/*N*/ const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing(); +/*N*/ +/*N*/ switch( rSpace.GetInterLineSpaceRule() ) +/*N*/ { +/*N*/ case SVX_INTER_LINE_SPACE_PROP: +/*N*/ { +/*N*/ ViewShell* pVsh = (ViewShell*)GetShell(); +/*N*/ if ( !pVsh ) +/*N*/ break; +/*N*/ OutputDevice *pOut = pVsh->GetOut(); +/*N*/ if( !pVsh->GetDoc()->IsBrowseMode() || +/*N*/ pVsh->GetViewOptions()->IsPrtFormat() ) +/*N*/ { +/*N*/ pOut = &GetTxtNode()->GetDoc()->GetRefDev(); +/*N*/ } +/*N*/ SwFont aFont( pSet, GetTxtNode()->GetDoc() ); +/*N*/ // Wir muessen dafuer sorgen, dass am OutputDevice der Font +/*N*/ // korrekt restauriert wird, sonst droht ein Last!=Owner. +/*N*/ if ( pLastFont ) +/*N*/ { +/*N*/ SwFntObj *pOldFont = pLastFont; +/*N*/ pLastFont = NULL; +/*N*/ aFont.SetFntChg( sal_True ); +/*N*/ aFont.ChgPhysFnt( pVsh, pOut ); +/*N*/ nRet = aFont.GetHeight( pVsh, pOut ); +/*N*/ pLastFont->Unlock(); +/*N*/ pLastFont = pOldFont; +/*N*/ pLastFont->SetDevFont( pVsh, pOut ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ Font aOldFont = pOut->GetFont(); +/*?*/ aFont.SetFntChg( sal_True ); +/*?*/ aFont.ChgPhysFnt( pVsh, pOut ); +/*?*/ nRet = aFont.GetHeight( pVsh, pOut ); +/*?*/ pLastFont->Unlock(); +/*?*/ pLastFont = NULL; +/*?*/ pOut->SetFont( aOldFont ); +/*N*/ } +/*N*/ nTmp = nRet; +/*N*/ nTmp *= rSpace.GetPropLineSpace(); +/*N*/ nTmp /= 100; +/*N*/ nTmp -= nRet; +/*N*/ if ( nTmp > 0 ) +/*N*/ nRet = (KSHORT)nTmp; +/*N*/ else +/*N*/ nRet = 0; +/*N*/ } +/*N*/ break; +/*?*/ case SVX_INTER_LINE_SPACE_FIX: +/*?*/ if ( rSpace.GetInterLineSpace() > 0 ) +/*?*/ nRet = (KSHORT)rSpace.GetInterLineSpace(); +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FirstLineHeight() + *************************************************************************/ + +/*N*/ KSHORT SwTxtFrm::FirstLineHeight() const +/*N*/ { +/*N*/ if ( !HasPara() ) +/*N*/ { +/*N*/ if( IsEmpty() && IsValid() ) +/*?*/ return IsVertical() ? (KSHORT)Prt().Width() : (KSHORT)Prt().Height(); +/*N*/ return KSHRT_MAX; +/*N*/ } +/*N*/ const SwParaPortion *pPara = GetPara(); +/*N*/ if ( !pPara ) +/*N*/ return KSHRT_MAX; +/*N*/ +/*N*/ return pPara->Height(); +/*N*/ } + + +/*N*/ void SwTxtFrm::ChgThisLines() +/*N*/ { +/*N*/ //not necassary to format here (GerFormatted etc.), because we have to come from there! +/*N*/ +/*N*/ ULONG nNew = 0; +/*N*/ const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo(); +/*N*/ if ( GetTxt().Len() && HasPara() ) +/*N*/ { +/*N*/ SwTxtSizeInfo aInf( this ); +/*N*/ SwTxtMargin aLine( this, &aInf ); +/*N*/ if ( rInf.IsCountBlankLines() ) +/*N*/ { +/*N*/ aLine.Bottom(); +/*N*/ nNew = (ULONG)aLine.GetLineNr(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ do +/*N*/ { +/*?*/ if( aLine.GetCurr()->HasCntnt() ) +/*?*/ ++nNew; +/*N*/ } while ( aLine.NextLine() ); +/*N*/ } +/*N*/ } +/*N*/ else if ( rInf.IsCountBlankLines() ) +/*N*/ nNew = 1; +/*N*/ +/*N*/ if ( nNew != nThisLines ) +/*N*/ { +/*N*/ if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() ) +/*N*/ { +/*N*/ nAllLines -= nThisLines; +/*N*/ nThisLines = nNew; +/*N*/ nAllLines += nThisLines; +/*N*/ SwFrm *pNxt = GetNextCntntFrm(); +/*N*/ while( pNxt && pNxt->IsInTab() ) +/*N*/ { +/*N*/ if( 0 != (pNxt = pNxt->FindTabFrm()) ) +/*N*/ pNxt = pNxt->FindNextCnt(); +/*N*/ } +/*N*/ if( pNxt ) +/*N*/ pNxt->InvalidateLineNum(); +/*N*/ +/*N*/ //Extend repaint to the bottom. +/*N*/ if ( HasPara() ) +/*N*/ { +/*N*/ SwRepaint *pRepaint = GetPara()->GetRepaint(); +/*N*/ pRepaint->Bottom( Max( pRepaint->Bottom(), +/*N*/ Frm().Top()+Prt().Bottom())); +/*N*/ } +/*N*/ } +/*N*/ else //Paragraphs which are not counted should not manipulate the AllLines. +/*N*/ nThisLines = nNew; +/*N*/ } +/*N*/ } + + +/*N*/ void SwTxtFrm::RecalcAllLines() +/*N*/ { +/*N*/ ValidateLineNum(); +/*N*/ +/*N*/ const SwAttrSet *pAttrSet = GetAttrSet(); +/*N*/ +/*N*/ if ( !IsInTab() ) +/*N*/ { +/*N*/ const ULONG nOld = GetAllLines(); +/*N*/ const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber(); +/*N*/ ULONG nNewNum; +/*N*/ +/*N*/ if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() ) +/*?*/ nNewNum = rLineNum.GetStartValue() - 1; +/*N*/ //If it is a follow or not has not be considered if it is a restart at each page; the +/*N*/ //restart should also take affekt at follows. +/*N*/ else if ( pAttrSet->GetDoc()->GetLineNumberInfo().IsRestartEachPage() && +/*N*/ FindPageFrm()->FindFirstBodyCntnt() == this ) +/*N*/ { +/*N*/ nNewNum = 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ SwCntntFrm *pPrv = GetPrevCntntFrm(); +/*N*/ while ( pPrv && +/*N*/ (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) ) +/*N*/ pPrv = pPrv->GetPrevCntntFrm(); +/*N*/ +/*N*/ nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0; +/*N*/ } +/*N*/ if ( rLineNum.IsCount() ) +/*N*/ nNewNum += GetThisLines(); +/*N*/ +/*N*/ if ( nOld != nNewNum ) +/*N*/ { +/*N*/ nAllLines = nNewNum; +/*N*/ SwCntntFrm *pNxt = GetNextCntntFrm(); +/*N*/ while ( pNxt && +/*N*/ (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) ) +/*N*/ pNxt = pNxt->GetNextCntntFrm(); +/*N*/ if ( pNxt ) +/*N*/ { +/*N*/ if ( pNxt->GetUpper() != GetUpper() ) +/*N*/ pNxt->InvalidateLineNum(); +/*N*/ else +/*N*/ pNxt->_InvalidateLineNum(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + + + +/************************************************************************* + * SwTxtFrm::GetScriptInfo() + *************************************************************************/ + +/*N*/ const SwScriptInfo* SwTxtFrm::GetScriptInfo() const +/*N*/ { +/*N*/ const SwParaPortion* pPara = GetPara(); +/*N*/ return pPara ? &pPara->GetScriptInfo() : 0; +/*N*/ } + +/************************************************************************* + * lcl_CalcFlyBasePos() + * Helper function for SwTxtFrm::CalcBasePosForFly() + *************************************************************************/ + +SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect, + SwTxtFly& rTxtFly ) +{ + SWRECTFN( (&rFrm) ) + SwTwips nRet = rFrm.IsRightToLeft() ? + (rFrm.Frm().*fnRect->fnGetRight)() : + (rFrm.Frm().*fnRect->fnGetLeft)(); + + do + { + SwRect aRect = rTxtFly.GetFrm( aFlyRect ); + if ( 0 != (aRect.*fnRect->fnGetWidth)() ) + { + if ( rFrm.IsRightToLeft() ) + { + if ( (aRect.*fnRect->fnGetRight)() - + (aFlyRect.*fnRect->fnGetRight)() >= 0 ) + { + (aFlyRect.*fnRect->fnSetRight)( + (aRect.*fnRect->fnGetLeft)() ); + nRet = (aRect.*fnRect->fnGetLeft)(); + } + else + break; + } + else + { + if ( (aFlyRect.*fnRect->fnGetLeft)() - + (aRect.*fnRect->fnGetLeft)() >= 0 ) + { + (aFlyRect.*fnRect->fnSetLeft)( + (aRect.*fnRect->fnGetRight)() + 1 ); + nRet = (aRect.*fnRect->fnGetRight)(); + } + else + break; + } + } + else + break; + } + while ( sal_True ); + + return nRet; +} + +/************************************************************************* + * SwTxtFrm::CalcBasePosForFly() + *************************************************************************/ + +void SwTxtFrm::CalcBaseOfstForFly() +{ + ASSERT( !IsVertical() || !IsSwapped(), + "SwTxtFrm::CalcBasePosForFly with swapped frame!" ) + + const SwNode* pNode = GetTxtNode(); + const SwDoc* pDoc = pNode->GetDoc(); + if ( !pDoc->IsAddFlyOffsets() ) + return; + + SWRECTFN( this ) + + SwTwips nTop = 0; + SwTwips nLineHeight = 200; + SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() ); + + // Get first 'real' line + const SwLineLayout* pLay = GetPara(); + while( pLay && pLay->IsDummy() ) + { + nTop += pLay->Height(); + pLay = pLay->GetNext(); + } + if ( pLay ) + nLineHeight = pLay->Height(); + + SwTwips nNewTop = (aFlyRect.*fnRect->fnGetTop)() + + ( bVert ? -nTop : nTop ); + (aFlyRect.*fnRect->fnSetTopAndHeight)( nNewTop, nLineHeight ); + + SwTxtFly aTxtFly( this ); + aTxtFly.SetIgnoreCurrentFrame( sal_True ); + aTxtFly.SetIgnoreContour( sal_True ); + SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly ); + aTxtFly.SetIgnoreCurrentFrame( sal_False ); + SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly ); + + // make values relative to frame start position + SwTwips nLeft = IsRightToLeft() ? + (Frm().*fnRect->fnGetRight)() : + (Frm().*fnRect->fnGetLeft)(); + + mnFlyAnchorOfst = nRet1 - nLeft; + mnFlyAnchorOfstNoWrap = nRet2 - nLeft; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtftn.cxx b/binfilter/bf_sw/source/core/text/sw_txtftn.cxx new file mode 100644 index 000000000000..d786a44876e8 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtftn.cxx @@ -0,0 +1,1414 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "viewsh.hxx" + +#include <horiornt.hxx> + +#include "doc.hxx" +#include "pagefrm.hxx" + +#include <txtftn.hxx> +#include <flyfrm.hxx> +#include <fmtftn.hxx> +#include <ftninfo.hxx> +#include <charfmt.hxx> +#include <dflyobj.hxx> +#include <bf_svx/brshitem.hxx> +#include <bf_svx/charrotateitem.hxx> +#include <com/sun/star/i18n/ScriptType.hdl> + +#include "txtcfg.hxx" +#include "porftn.hxx" +#include "porfly.hxx" +#include "itrform2.hxx" +#include "frmsh.hxx" +#include "ftnfrm.hxx" // FindErgoSumFrm(), FindQuoVadisFrm(), +#include "pagedesc.hxx" +#include "sectfrm.hxx" // SwSectionFrm +namespace binfilter { + +using namespace ::com::sun::star; + +extern BYTE WhichFont( xub_StrLen nIdx, const String* pTxt, + const SwScriptInfo* pSI ); + +/************************************************************************* + * _IsFtnNumFrm() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::_IsFtnNumFrm() const +/*N*/ { +/*N*/ const SwFtnFrm* pFtn = FindFtnFrm()->GetMaster(); +/*N*/ while( pFtn && !pFtn->ContainsCntnt() ) +/*?*/ pFtn = pFtn->GetMaster(); +/*N*/ return !pFtn; +/*N*/ } + +/************************************************************************* + * FindFtn() + *************************************************************************/ + +// Sucht innerhalb einer Master-Follow-Kette den richtigen TxtFrm zum SwTxtFtn + +/*N*/ SwTxtFrm *SwTxtFrm::FindFtnRef( const SwTxtFtn *pFtn ) +/*N*/ { +/*N*/ SwTxtFrm *pFrm = this; +/*N*/ const sal_Bool bFwd = *pFtn->GetStart() >= GetOfst(); +/*N*/ while( pFrm ) +/*N*/ { +/*N*/ if( SwFtnBossFrm::FindFtn( pFrm, pFtn ) ) +/*N*/ return pFrm; +/*N*/ pFrm = bFwd ? pFrm->GetFollow() : +/*N*/ pFrm->IsFollow() ? pFrm->FindMaster() : 0; +/*N*/ } +/*N*/ return pFrm; +/*N*/ } + +/************************************************************************* + * CalcFtnFlag() + *************************************************************************/ + +/*N*/ #ifndef DBG_UTIL +/*N*/ void SwTxtFrm::CalcFtnFlag() +/*N*/ #else +/*N*/ void SwTxtFrm::CalcFtnFlag( xub_StrLen nStop )//Fuer den Test von SplitFrm +/*N*/ #endif +/*N*/ { +/*N*/ bFtn = sal_False; +/*N*/ +/*N*/ const SwpHints *pHints = GetTxtNode()->GetpSwpHints(); +/*N*/ if( !pHints ) +/*N*/ return; +/*N*/ +/*N*/ const MSHORT nSize = pHints->Count(); +/*N*/ +/*N*/ #ifndef DBG_UTIL +/*N*/ const xub_StrLen nEnd = GetFollow() ? GetFollow()->GetOfst() : STRING_LEN; +/*N*/ #else +/*N*/ const xub_StrLen nEnd = nStop != STRING_LEN ? nStop +/*N*/ : GetFollow() ? GetFollow()->GetOfst() : STRING_LEN; +/*N*/ #endif +/*N*/ +/*N*/ for( MSHORT i = 0; i < nSize; ++i ) +/*N*/ { +/*N*/ const SwTxtAttr *pHt = (*pHints)[i]; +/*N*/ if ( pHt->Which() == RES_TXTATR_FTN ) +/*N*/ { +/*N*/ const xub_StrLen nIdx = *pHt->GetStart(); +/*N*/ if ( nEnd < nIdx ) +/*N*/ break; +/*N*/ if( GetOfst() <= nIdx ) +/*N*/ { +/*N*/ bFtn = sal_True; +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/************************************************************************* + * CalcPrepFtnAdjust() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrm::CalcPrepFtnAdjust() +/*N*/ { +/*N*/ ASSERT( HasFtn(), "Wer ruft mich da?" ); +/*N*/ SwFtnBossFrm *pBoss = FindFtnBossFrm( sal_True ); +/*N*/ const SwFtnFrm *pFtn = pBoss->FindFirstFtn( this ); +/*N*/ if( pFtn && FTNPOS_CHAPTER != GetNode()->GetDoc()->GetFtnInfo().ePos && +/*N*/ ( !pBoss->GetUpper()->IsSctFrm() || +/*N*/ !((SwSectionFrm*)pBoss->GetUpper())->IsFtnAtEnd() ) ) +/*N*/ { +/*N*/ const SwFtnContFrm *pCont = pBoss->FindFtnCont(); +/*N*/ sal_Bool bReArrange = sal_True; +/*N*/ +/*N*/ SWRECTFN( this ) +/*N*/ if ( pCont && (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), +/*N*/ (Frm().*fnRect->fnGetBottom)() ) > 0 ) +/*N*/ { +/*N*/ pBoss->RearrangeFtns( (Frm().*fnRect->fnGetBottom)(), sal_False, +/*N*/ pFtn->GetAttr() ); +/*N*/ ValidateBodyFrm(); +/*N*/ ValidateFrm(); +/*N*/ pFtn = pBoss->FindFirstFtn( this ); +/*N*/ } +/*N*/ else +/*N*/ bReArrange = sal_False; +/*N*/ if( !pCont || !pFtn || bReArrange != (pFtn->FindFtnBossFrm() == pBoss) ) +/*N*/ { +/*?*/ SwTxtFormatInfo aInf( this ); +/*?*/ SwTxtFormatter aLine( this, &aInf ); +/*?*/ aLine.TruncLines(); +/*?*/ SetPara( 0 ); //Wird ggf. geloescht! +/*?*/ ResetPreps(); +/*?*/ return sal_False; +/*N*/ } +/*N*/ } +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::GetFtnLine() + *************************************************************************/ + +/*N*/ SwTwips SwTxtFrm::GetFtnLine( const SwTxtFtn *pFtn, sal_Bool bLocked ) const +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::GetFtnLine with swapped frame" ) +/*N*/ +/*N*/ SwTxtFrm *pThis = (SwTxtFrm*)this; +/*N*/ +/*N*/ if( !HasPara() ) +/*N*/ { +/*N*/ // Es sieht ein wenig gehackt aus, aber man riskiert einen Haufen +/*N*/ // Aerger, wenn man versucht, per pThis->GetFormatted() doch +/*N*/ // noch an den richtigen Wert heranzukommen. Durch das PREP_ADJUST +/*N*/ // stellen wir sicher, dass wir noch einmal drankommen, dann aber +/*N*/ // von der Ref aus! +/*N*/ // Trotzdem wollen wir nichts unversucht lassen und geben die +/*N*/ // Unterkante des Frames zurueck. +/*?*/ if( !bLocked ) +/*?*/ pThis->Prepare( PREP_ADJUST_FRM ); +/*?*/ return IsVertical() ? Frm().Left() : Frm().Bottom(); +/*N*/ } +/*N*/ +/*N*/ SWAP_IF_NOT_SWAPPED( this ) +/*N*/ +/*N*/ SwTxtInfo aInf( pThis ); +/*N*/ SwTxtIter aLine( pThis, &aInf ); +/*N*/ const xub_StrLen nPos = *pFtn->GetStart(); +/*N*/ aLine.CharToLine( nPos ); +/*N*/ +/*N*/ SwTwips nRet = aLine.Y() + SwTwips(aLine.GetLineHeight()); +/*N*/ if( IsVertical() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nRet = SwitchHorizontalToVertical( nRet ); +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return nRet; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::GetFtnRstHeight() + *************************************************************************/ + +// Ermittelt die max. erreichbare Hoehe des TxtFrm im Ftn-Bereich. +// Sie wird eingeschraenkt durch den unteren Rand der Zeile mit +// der Ftn-Referenz. + +/*N*/ SwTwips SwTxtFrm::_GetFtnFrmHeight() const +/*N*/ { +/*N*/ ASSERT( !IsFollow() && IsInFtn(), "SwTxtFrm::SetFtnLine: moon walk" ); +/*N*/ +/*N*/ const SwFtnFrm *pFtnFrm = FindFtnFrm(); +/*N*/ const SwTxtFrm *pRef = (const SwTxtFrm *)pFtnFrm->GetRef(); +/*N*/ const SwFtnBossFrm *pBoss = FindFtnBossFrm(); +/*N*/ if( pBoss != pRef->FindFtnBossFrm( !pFtnFrm->GetAttr()-> +/*N*/ GetFtn().IsEndNote() ) ) +/*N*/ return 0; +/*N*/ +/*N*/ SWAP_IF_SWAPPED( this ) +/*N*/ +/*N*/ SwTwips nHeight = pRef->IsInFtnConnect() ? +/*N*/ 1 : pRef->GetFtnLine( pFtnFrm->GetAttr(), sal_False ); +/*N*/ if( nHeight ) +/*N*/ { +/*N*/ // So komisch es aussehen mag: Die erste Ftn auf der Seite darf sich +/*N*/ // nicht mit der Ftn-Referenz beruehren, wenn wir im Ftn-Bereich Text +/*N*/ // eingeben. +/*N*/ const SwFrm *pCont = pFtnFrm->GetUpper(); +/*N*/ //Hoehe innerhalb des Cont, die ich mir 'eh noch genehmigen darf. +/*N*/ SWRECTFN( pCont ) +/*N*/ SwTwips nTmp = (*fnRect->fnYDiff)( (pCont->*fnRect->fnGetPrtBottom)(), +/*N*/ (Frm().*fnRect->fnGetTop)() ); +/*N*/ +/*N*/ #ifdef DBG_UTIL +/*N*/ if( nTmp < 0 ) +/*N*/ { +/*?*/ sal_Bool bInvalidPos = sal_False; +/*?*/ const SwLayoutFrm* pTmp = GetUpper(); +/*?*/ while( !bInvalidPos && pTmp ) +/*?*/ { +/*?*/ bInvalidPos = !pTmp->GetValidPosFlag() || +/*?*/ !pTmp->Lower()->GetValidPosFlag(); +/*?*/ if( pTmp == pCont ) +/*?*/ break; +/*?*/ pTmp = pTmp->GetUpper(); +/*?*/ } +/*?*/ ASSERT( bInvalidPos, "Hanging below FtnCont" ); +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ if ( (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight) > 0 ) +/*N*/ { +/*N*/ //Wachstumspotential den Containers. +/*N*/ if ( !pRef->IsInFtnConnect() ) +/*N*/ { +/*N*/ SwSaveFtnHeight aSave( (SwFtnBossFrm*)pBoss, nHeight ); +/*N*/ nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX PHEIGHT, sal_True ); +/*N*/ } +/*N*/ else +/*N*/ nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX PHEIGHT, sal_True ); +/*N*/ +/*N*/ nHeight += nTmp; +/*N*/ if( nHeight < 0 ) +/*N*/ nHeight = 0; +/*N*/ } +/*N*/ else +/*?*/ { // The container has to shrink +/*?*/ nTmp += (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight); +/*?*/ if( nTmp > 0 ) +/*?*/ nHeight = nTmp; +/*?*/ else +/*?*/ nHeight = 0; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( this ) +/*N*/ +/*N*/ return nHeight; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::FindErgoSumFrm() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::FindQuoVadisFrm() + *************************************************************************/ + +/*N*/ SwTxtFrm *SwTxtFrm::FindQuoVadisFrm() +/*N*/ { +/*N*/ // Erstmal feststellen, ob wir in einem FtnFrm stehen: +/*N*/ if( GetIndPrev() || !IsInFtn() ) +/*N*/ return 0; +/*N*/ +/*N*/ // Zum Vorgaenger-FtnFrm +/*N*/ SwFtnFrm *pFtnFrm = FindFtnFrm()->GetMaster(); +/*N*/ if( !pFtnFrm ) +/*N*/ return 0; +/*N*/ +/*N*/ // Nun den letzten Cntnt: +/*?*/ const SwCntntFrm *pCnt = pFtnFrm->ContainsCntnt(); +/*?*/ if( !pCnt ) +/*?*/ return NULL; +/*?*/ const SwCntntFrm *pLast; +/*?*/ do +/*?*/ { pLast = pCnt; +/*?*/ pCnt = pCnt->GetNextCntntFrm(); +/*?*/ } while( pCnt && pFtnFrm->IsAnLower( pCnt ) ); +/*?*/ return (SwTxtFrm*)pLast; +/*N*/ } + +/************************************************************************* + * SwTxtFrm::SetErgoSumNum() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::RemoveFtn() + *************************************************************************/ + +/*N*/ void SwTxtFrm::RemoveFtn( const xub_StrLen nStart, const xub_StrLen nLen ) +/*N*/ { +/*N*/ if ( !IsFtnAllowed() ) +/*N*/ return; +/*N*/ +/*N*/ SwpHints *pHints = GetTxtNode()->GetpSwpHints(); +/*N*/ if( !pHints ) +/*N*/ return; +/*N*/ +/*N*/ sal_Bool bRollBack = nLen != STRING_LEN; +/*N*/ MSHORT nSize = pHints->Count(); +/*N*/ xub_StrLen nEnd; +/*N*/ SwTxtFrm* pSource; +/*N*/ if( bRollBack ) +/*N*/ { +/*?*/ nEnd = nStart + nLen; +/*?*/ pSource = GetFollow(); +/*?*/ if( !pSource ) +/*?*/ return; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nEnd = STRING_LEN; +/*N*/ pSource = this; +/*N*/ } +/*N*/ +/*N*/ if( nSize ) +/*N*/ { +/*N*/ SwPageFrm* pUpdate = NULL; +/*N*/ sal_Bool bRemove = sal_False; +/*N*/ SwFtnBossFrm *pFtnBoss = 0; +/*N*/ SwFtnBossFrm *pEndBoss = 0; +/*N*/ sal_Bool bFtnEndDoc +/*N*/ = FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos; +/*N*/ for( MSHORT i = nSize; i; ) +/*N*/ { +/*N*/ SwTxtAttr *pHt = pHints->GetHt(--i); +/*N*/ if ( RES_TXTATR_FTN != pHt->Which() ) +/*N*/ continue; +/*N*/ +/*N*/ const xub_StrLen nIdx = *pHt->GetStart(); +/*N*/ if( nStart > nIdx ) +/*N*/ break; +/*N*/ +/*?*/ if( nEnd >= nIdx ) +/*?*/ { +/*?*/ SwTxtFtn *pFtn = (SwTxtFtn*)pHt; +/*?*/ sal_Bool bEndn = pFtn->GetFtn().IsEndNote(); +/*?*/ +/*?*/ if( bEndn ) +/*?*/ { +/*?*/ if( !pEndBoss ) +/*?*/ pEndBoss = pSource->FindFtnBossFrm(); +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ if( !pFtnBoss ) +/*?*/ { +/*?*/ pFtnBoss = pSource->FindFtnBossFrm( sal_True ); +/*?*/ if( pFtnBoss->GetUpper()->IsSctFrm() ) +/*?*/ { +/*?*/ SwSectionFrm* pSect = (SwSectionFrm*) +/*?*/ pFtnBoss->GetUpper(); +/*?*/ if( pSect->IsFtnAtEnd() ) +/*?*/ bFtnEndDoc = sal_False; +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ // Wir loeschen nicht, sondern wollen die Ftn verschieben. +/*?*/ // Drei Faelle koennen auftreten: +/*?*/ // 1) Es gibt weder Follow noch PrevFollow +/*?*/ // -> RemoveFtn() (vielleicht sogar ein ASSERT wert) +/*?*/ // 2) nStart > GetOfst, ich habe einen Follow +/*?*/ // -> Ftn wandert in den Follow +/*?*/ // 3) nStart < GetOfst, ich bin ein Follow +/*?*/ // -> Ftn wandert in den PrevFollow +/*?*/ // beide muessen auf einer Seite/in einer Spalte stehen. +/*?*/ +/*?*/ SwFtnFrm *pFtnFrm = bEndn ? pEndBoss->FindFtn( pSource, pFtn ) : +/*?*/ pFtnBoss->FindFtn( pSource, pFtn ); +/*?*/ +/*?*/ if( pFtnFrm ) +/*?*/ { +/*?*/ const sal_Bool bEndDoc = bEndn ? sal_True : bFtnEndDoc; +/*?*/ if( bRollBack ) +/*?*/ { +/*?*/ while ( pFtnFrm ) +/*?*/ { +/*?*/ pFtnFrm->SetRef( this ); +/*?*/ pFtnFrm = pFtnFrm->GetFollow(); +/*?*/ SetFtn( sal_True ); +/*?*/ } +/*?*/ } +/*?*/ else if( GetFollow() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ { +/*?*/ else +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 if( !bEndDoc || ( bEndn && pEndBoss->IsInSct() && +/*?*/ } +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ if( pUpdate ) +/*?*/ pUpdate->UpdateFtnNum(); +/*N*/ // Wir bringen die Oszillation zum stehen: +/*N*/ if( bRemove && !bFtnEndDoc && HasPara() ) +/*N*/ { +/*?*/ ValidateBodyFrm(); +/*?*/ ValidateFrm(); +/*N*/ } +/*N*/ } +/*N*/ // Folgendes Problem: Aus dem FindBreak heraus wird das RemoveFtn aufgerufen, +/*N*/ // weil die letzte Zeile an den Follow abgegeben werden soll. Der Offset +/*N*/ // des Follows ist aber veraltet, er wird demnaechst gesetzt. CalcFntFlag ist +/*N*/ // auf einen richtigen Follow-Offset angewiesen. Deshalb wird hier kurzfristig +/*N*/ // der Follow-Offset manipuliert. +/*N*/ xub_StrLen nOldOfst = STRING_LEN; +/*N*/ if( HasFollow() && nStart > GetOfst() ) +/*N*/ { +/*N*/ nOldOfst = GetFollow()->GetOfst(); +/*N*/ GetFollow()->ManipOfst( nStart + ( bRollBack ? nLen : 0 ) ); +/*N*/ } +/*N*/ pSource->CalcFtnFlag(); +/*N*/ if( nOldOfst < STRING_LEN ) +/*N*/ GetFollow()->ManipOfst( nOldOfst ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::ConnectFtn() + *************************************************************************/ +// sal_False, wenn irgendetwas schief gegangen ist. +// Es gibt eigentlich nur zwei Moeglichkeiten: +// a) Die Ftn ist bereits vorhanden +// => dann wird sie gemoved, wenn ein anderer pSrcFrm gefunden wurde +// b) Die Ftn ist nicht vorhanden +// => dann wird sie fuer uns angelegt. +// Ob die Ftn schliesslich auf unserer Spalte/Seite landet oder nicht, +// spielt in diesem Zusammenhang keine Rolle. +// Optimierungen bei Endnoten. +// Noch ein Problem: wenn die Deadline im Ftn-Bereich liegt, muss die +// Ftn verschoben werden. + +/*N*/ void SwTxtFrm::ConnectFtn( SwTxtFtn *pFtn, const SwTwips nDeadLine ) +/*N*/ { +/*N*/ ASSERT( ! IsVertical() || ! IsSwapped(), +/*N*/ "SwTxtFrm::ConnectFtn with swapped frame" ); +/*N*/ +/*N*/ bFtn = sal_True; +/*N*/ bInFtnConnect = sal_True; //Bloss zuruecksetzen! +/*N*/ sal_Bool bEnd = pFtn->GetFtn().IsEndNote(); +/*N*/ +/*N*/ // Wir brauchen immer einen Boss (Spalte/Seite) +/*N*/ SwSectionFrm *pSect; +/*N*/ SwCntntFrm *pCntnt = this; +/*N*/ if( bEnd && IsInSct() ) +/*N*/ { +/*?*/ pSect = FindSctFrm(); +/*?*/ if( pSect->IsEndnAtEnd() ) +/*?*/ pCntnt = pSect->FindLastCntnt( FINDMODE_ENDNOTE ); +/*?*/ if( !pCntnt ) +/*?*/ pCntnt = this; +/*N*/ } +/*N*/ +/*N*/ SwFtnBossFrm *pBoss = pCntnt->FindFtnBossFrm( !bEnd ); +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ SwTwips nRstHeight = GetRstHeight(); +/*N*/ #endif +/*N*/ +/*N*/ pSect = pBoss->FindSctFrm(); +/*N*/ sal_Bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) : +/*N*/ ( !( pSect && pSect->IsFtnAtEnd() ) && +/*N*/ FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos ); +/*N*/ //Ftn kann beim Follow angemeldet sein. +/*N*/ SwCntntFrm *pSrcFrm = FindFtnRef( pFtn ); +/*N*/ +/*N*/ if( bDocEnd ) +/*N*/ { +/*?*/ if( pSect && pSrcFrm ) +/*?*/ { +/*?*/ SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn ); +/*?*/ if( pFtnFrm && pFtnFrm->IsInSct() ) +/*?*/ { +/*?*/ pBoss->RemoveFtn( pSrcFrm, pFtn ); +/*?*/ pSrcFrm = 0; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ else if( bEnd && pSect ) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFtnFrm *pFtnFrm = pSrcFrm ? pBoss->FindFtn( pSrcFrm, pFtn ) : NULL; +/*N*/ } +/*N*/ +/*N*/ if( bDocEnd || bEnd ) +/*N*/ { +/*?*/ if( !pSrcFrm ) +/*?*/ pBoss->AppendFtn( this, pFtn ); +/*?*/ else if( pSrcFrm != this ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pBoss->ChangeFtnRef( pSrcFrm, pFtn, this ); +/*?*/ bInFtnConnect = sal_False; +/*?*/ return; +/*N*/ } +/*N*/ +/*N*/ SwSaveFtnHeight aHeight( pBoss, nDeadLine ); +/*N*/ +/*N*/ if( !pSrcFrm ) // Es wurde ueberhaupt keine Ftn gefunden. +/*N*/ pBoss->AppendFtn( this, pFtn ); +/*N*/ else +/*N*/ { +/*N*/ SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn ); +/*N*/ SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm(); +/*N*/ +/*N*/ sal_Bool bBrutal = sal_False; +/*N*/ +/*N*/ if( pFtnBoss == pBoss ) // Ref und Ftn sind auf der selben Seite/Spalte. +/*N*/ { +/*N*/ SwFrm *pCont = pFtnFrm->GetUpper(); +/*N*/ +/*N*/ SWRECTFN ( pCont ) +/*N*/ long nDiff = (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), +/*N*/ nDeadLine ); +/*N*/ +/*N*/ if( nDiff >= 0 ) +/*N*/ { +/*N*/ //Wenn die Fussnote bei einem Follow angemeldet ist, so ist +/*N*/ //es jetzt an der Zeit sie umzumelden. +/*N*/ if ( pSrcFrm != this ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 pBoss->ChangeFtnRef( pSrcFrm, pFtn, this ); +/*N*/ //Es steht Platz zur Verfuegung, also kann die Fussnote evtl. +/*N*/ //wachsen. +/*N*/ if ( pFtnFrm->GetFollow() && nDiff > 0 ) +/*N*/ { +/*?*/ SwTwips nHeight = (pCont->Frm().*fnRect->fnGetHeight)(); +/*?*/ pBoss->RearrangeFtns( nDeadLine, sal_False, pFtn ); +/*?*/ ValidateBodyFrm(); +/*?*/ ValidateFrm(); +/*?*/ ViewShell *pSh = GetShell(); +/*?*/ if ( pSh && nHeight == (pCont->Frm().*fnRect->fnGetHeight)() ) +/*?*/ //Damit uns nix durch die Lappen geht. +/*?*/ pSh->InvalidateWindows( pCont->Frm() ); +/*?*/ } +/*?*/ bInFtnConnect = sal_False; +/*?*/ return; +/*N*/ } +/*N*/ else +/*N*/ bBrutal = sal_True; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Ref und Ftn sind nicht auf einer Seite, Move-Versuch ist noetig. +/*N*/ SwFrm* pTmp = this; +/*N*/ while( pTmp->GetNext() && pSrcFrm != pTmp ) +/*?*/ pTmp = pTmp->GetNext(); +/*N*/ if( pSrcFrm == pTmp ) +/*N*/ bBrutal = sal_True; +/*N*/ else +/*N*/ { // Wenn unser Boss in einem spaltigen Bereich sitzt, es aber auf +/*N*/ // der Seite schon einen FtnContainer gibt, hilft nur die brutale +/*N*/ // Methode + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ if( pSect && pSect->FindFtnBossFrm( !bEnd )->FindFtnCont() ) +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Die brutale Loesung: Fussnote entfernen und appenden. +/*N*/ // Es muss SetFtnDeadLine() gerufen werden, weil nach +/*N*/ // RemoveFtn die nMaxFtnHeight evtl. besser auf unsere Wuensche +/*N*/ // eingestellt werden kann. +/*N*/ if( bBrutal ) +/*N*/ { +/*N*/ pBoss->RemoveFtn( pSrcFrm, pFtn, sal_False ); +/*N*/ SwSaveFtnHeight *pHeight = bEnd ? NULL : +/*N*/ new SwSaveFtnHeight( pBoss, nDeadLine ); +/*N*/ pBoss->AppendFtn( this, pFtn ); +/*N*/ delete pHeight; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // In spaltigen Bereichen, die noch nicht bis zum Seitenrand gehen, +/*N*/ // ist kein RearrangeFtns sinnvoll, da der Fussnotencontainer noch +/*N*/ // nicht kalkuliert worden ist. +/*N*/ if( !pSect || !pSect->Growable() ) +/*N*/ { +/*N*/ // Umgebung validieren, um Oszillationen zu verhindern. +/*N*/ SwSaveFtnHeight aNochmal( pBoss, nDeadLine ); +/*N*/ ValidateBodyFrm(); +/*N*/ pBoss->RearrangeFtns( nDeadLine, sal_True ); +/*N*/ ValidateFrm(); +/*N*/ } +/*N*/ else if( pSect->IsFtnAtEnd() ) +/*N*/ { +/*?*/ ValidateBodyFrm(); +/*?*/ ValidateFrm(); +/*N*/ } +/*N*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*N*/ // pFtnFrm kann sich durch Calc veraendert haben ... +/*N*/ SwFtnFrm *pFtnFrm = pBoss->FindFtn( this, pFtn ); +/*N*/ if( pFtnFrm && pBoss != pFtnFrm->FindFtnBossFrm( !bEnd ) ) +/*N*/ { +/*N*/ int bla = 5; +/*N*/ } +/*N*/ nRstHeight = GetRstHeight(); +/*N*/ #endif +/*N*/ bInFtnConnect = sal_False; +/*N*/ return; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewFtnPortion() + *************************************************************************/ + +// Die Portion fuer die Ftn-Referenz im Text +/*N*/ SwFtnPortion *SwTxtFormatter::NewFtnPortion( SwTxtFormatInfo &rInf, +/*N*/ SwTxtAttr *pHint ) +/*N*/ { +/*N*/ ASSERT( ! pFrm->IsVertical() || pFrm->IsSwapped(), +/*N*/ "NewFtnPortion with unswapped frame" ); +/*N*/ +/*N*/ if( !pFrm->IsFtnAllowed() ) +/*N*/ return 0; +/*N*/ +/*N*/ SwTxtFtn *pFtn = (SwTxtFtn*)pHint; +/*N*/ SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn(); +/*N*/ SwDoc *pDoc = pFrm->GetNode()->GetDoc(); +/*N*/ +/*N*/ if( rInf.IsTest() ) +/*?*/ return new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ), pFrm, pFtn ); +/*N*/ +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ +/*N*/ KSHORT nReal; +/*N*/ { +/*N*/ KSHORT nOldReal = pCurr->GetRealHeight(); +/*N*/ KSHORT nOldAscent = pCurr->GetAscent(); +/*N*/ KSHORT nOldHeight = pCurr->Height(); +/*N*/ ((SwTxtFormatter*)this)->CalcRealHeight(); +/*N*/ nReal = pCurr->GetRealHeight(); +/*N*/ if( nReal < nOldReal ) +/*N*/ nReal = nOldReal; +/*N*/ pCurr->SetRealHeight( nOldReal ); +/*N*/ pCurr->Height( nOldHeight ); +/*N*/ pCurr->SetAscent( nOldAscent ); +/*N*/ } +/*N*/ +/*N*/ SwTwips nLower = Y() + nReal; +/*N*/ +/*N*/ SWRECTFN( pFrm ) +/*N*/ +/*N*/ if( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nLower = pFrm->SwitchHorizontalToVertical( nLower ); +/*N*/ +/*N*/ SwTwips nAdd; +/*N*/ +/*N*/ if( pFrm->IsInTab() && (!pFrm->IsInSct() || pFrm->FindSctFrm()->IsInTab()) ) +/*N*/ { +/*?*/ SwFrm *pRow = pFrm; +/*?*/ while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() ) +/*?*/ pRow = pRow->GetUpper(); +/*?*/ +/*?*/ const SwTwips nMin = (pRow->Frm().*fnRect->fnGetBottom)(); +/*?*/ +/*?*/ if( ( ! bVert && nMin > nLower ) || ( bVert && nMin < nLower ) ) +/*?*/ nLower = nMin; +/*?*/ +/*?*/ nAdd = (pRow->GetUpper()->*fnRect->fnGetBottomMargin)(); +/*N*/ } +/*N*/ else +/*N*/ nAdd = (pFrm->*fnRect->fnGetBottomMargin)(); +/*N*/ +/*N*/ if( nAdd > 0 ) +/*N*/ { +/*N*/ if ( bVert ) +/*N*/ nLower -= nAdd; +/*N*/ else +/*N*/ nLower += nAdd; +/*N*/ } +/*N*/ +/*N*/ // #i10770#: If there are fly frames anchored at previous paragraphs, +/*N*/ // the deadline should consider their lower borders. +/*N*/ SwFrm* pStartFrm = pFrm->GetUpper()->GetLower(); +/*N*/ ASSERT( pStartFrm, "Upper has no lower" ) +/*N*/ SwTwips nFlyLower = bVert ? LONG_MAX : 0; +/*N*/ while ( pStartFrm != pFrm ) +/*N*/ { +/*N*/ ASSERT( pStartFrm, "Frame chain is broken" ) +/*N*/ if ( pStartFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ const SwDrawObjs &rObjs = *pStartFrm->GetDrawObjs(); +/*N*/ for ( USHORT i = 0; i < rObjs.Count(); ++i ) +/*N*/ { +/*N*/ SdrObject *pO = rObjs[i]; +/*N*/ SwRect aRect( pO->GetBoundRect() ); +/*N*/ +/*N*/ if ( ! pO->IsWriterFlyFrame() || +/*N*/ ((SwVirtFlyDrawObj*)pO)->GetFlyFrm()->IsValid() ) +/*N*/ { +/*N*/ const SwTwips nBottom = (aRect.*fnRect->fnGetBottom)(); +/*N*/ if ( (*fnRect->fnYDiff)( nBottom, nFlyLower ) > 0 ) +/*N*/ nFlyLower = nBottom; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pStartFrm = pStartFrm->GetNext(); +/*N*/ } +/*N*/ +/*N*/ if ( bVert ) +/*N*/ nLower = Min( nLower, nFlyLower ); +/*N*/ else +/*N*/ nLower = Max( nLower, nFlyLower ); +/*N*/ +/*N*/ //6995: Wir frischen nur auf. Das Connect tut fuer diesen Fall nix +/*N*/ //Brauchbares, sondern wuerde stattdessen fuer diesen Fall meist die +/*N*/ //Ftn wegwerfen und neu erzeugen. +/*N*/ +/*N*/ if( !rInf.IsQuick() ) +/*N*/ pFrm->ConnectFtn( pFtn, nLower ); +/*N*/ +/*N*/ SwTxtFrm *pScrFrm = pFrm->FindFtnRef( pFtn ); +/*N*/ SwFtnBossFrm *pBoss = pFrm->FindFtnBossFrm( !rFtn.IsEndNote() ); +/*N*/ SwFtnFrm *pFtnFrm = NULL; +/*N*/ if( pScrFrm ) +/*N*/ { +/*N*/ pFtnFrm = pBoss->FindFtn( pScrFrm, pFtn ); +/*N*/ if( pFtnFrm && pFtnFrm->Lower() ) +/*N*/ { +/*N*/ SwTxtFrm *pTxtFrm = NULL; +/*N*/ if( pFtnFrm->Lower()->IsTxtFrm() ) +/*N*/ pTxtFrm = (SwTxtFrm*)pFtnFrm->Lower(); +/*N*/ else if( pFtnFrm->Lower()->IsSctFrm() ) +/*N*/ { +/*?*/ SwFrm* pCntnt = ((SwSectionFrm*)pFtnFrm->Lower())->ContainsCntnt(); +/*?*/ if( pCntnt && pCntnt->IsTxtFrm() ) +/*?*/ pTxtFrm = (SwTxtFrm*)pCntnt; +/*N*/ } +/*N*/ if ( pTxtFrm && pTxtFrm->HasPara() ) +/*N*/ { +/*N*/ SwParaPortion *pPara = pTxtFrm->GetPara(); +/*N*/ SwLinePortion *pTmp = pPara->GetPortion(); +/*N*/ while( pTmp ) +/*N*/ { +/*N*/ if( pTmp->IsFtnNumPortion() ) +/*N*/ { +/*N*/ SeekAndChg( rInf ); +/*N*/ if( ((SwFtnNumPortion*)pTmp)->DiffFont( rInf.GetFont() ) ) +/*N*/ pTxtFrm->Prepare(PREP_FTN); +/*N*/ break; +/*N*/ } +/*?*/ pTmp = pTmp->GetPortion(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // Wir erkundigen uns, ob durch unser Append irgendeine +/*N*/ // Fussnote noch auf der Seite/Spalte steht. Wenn nicht verschwindet +/*N*/ // auch unsere Zeile. Dies fuehrt zu folgendem erwuenschten +/*N*/ // Verhalten: Ftn1 pass noch auf die Seite/Spalte, Ftn2 nicht mehr. +/*N*/ // Also bleibt die Ftn2-Referenz auf der Seite/Spalte stehen. Die +/*N*/ // Fussnote selbst folgt aber erst auf der naechsten Seite/Spalte. +/*N*/ // Ausnahme: Wenn keine weitere Zeile auf diese Seite/Spalte passt, +/*N*/ // so sollte die Ftn2-Referenz auch auf die naechste wandern. +/*N*/ if( !rFtn.IsEndNote() ) +/*N*/ { +/*N*/ SwSectionFrm *pSct = pBoss->FindSctFrm(); +/*N*/ sal_Bool bAtSctEnd = pSct && pSct->IsFtnAtEnd(); +/*N*/ if( FTNPOS_CHAPTER != pDoc->GetFtnInfo().ePos || bAtSctEnd ) +/*N*/ { +/*N*/ SwFrm* pFtnCont = pBoss->FindFtnCont(); +/*N*/ // Wenn der Boss in einem Bereich liegt, kann es sich nur um eine +/*N*/ // Spalte dieses Bereichs handeln. Wenn dies nicht die erste Spalte +/*N*/ // ist, duerfen wir ausweichen +/*N*/ if( !pFrm->IsInTab() && ( GetLineNr() > 1 || pFrm->GetPrev() || +/*N*/ ( !bAtSctEnd && pFrm->GetIndPrev() ) || +/*N*/ ( pSct && pBoss->GetPrev() ) ) ) +/*N*/ { +/*N*/ if( !pFtnCont ) +/*N*/ { +/*?*/ rInf.SetStop( sal_True ); +/*?*/ UNDO_SWAP( pFrm ) +/*?*/ return 0; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // Es darf keine Fussnotencontainer in spaltigen Bereichen und +/*N*/ // gleichzeitig auf der Seite/Seitenspalte geben +/*N*/ if( pSct && !bAtSctEnd ) // liegt unser Container in einem (spaltigen) Bereich? +/*N*/ { +/*?*/ SwFtnBossFrm* pTmp = pBoss->FindSctFrm()->FindFtnBossFrm( sal_True ); +/*?*/ SwFtnContFrm* pFtnC = pTmp->FindFtnCont(); +/*?*/ if( pFtnC ) +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SwFtnFrm* pTmp = (SwFtnFrm*)pFtnC->Lower(); +/*?*/ } +/*N*/ } +/*N*/ // Ist dies die letzte passende Zeile? +/*N*/ SwTwips nTmpBot = Y() + nReal * 2; +/*N*/ +/*N*/ if( bVert ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nTmpBot = pFrm->SwitchHorizontalToVertical( nTmpBot ); +/*N*/ +/*N*/ SWRECTFN( pFtnCont ) +/*N*/ +/*N*/ long nDiff = (*fnRect->fnYDiff)( +/*N*/ (pFtnCont->Frm().*fnRect->fnGetTop)(), +/*N*/ nTmpBot ); +/*N*/ +/*N*/ if( pScrFrm && nDiff < 0 ) +/*N*/ { +/*?*/ if( pFtnFrm ) +/*?*/ { +/*?*/ SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm(); +/*?*/ if( pFtnBoss != pBoss ) +/*?*/ { +/*?*/ // Wir sind in der letzte Zeile und die Fussnote +/*?*/ // ist auf eine andere Seite gewandert, dann wollen +/*?*/ // wir mit ... +/*?*/ rInf.SetStop( sal_True ); +/*?*/ UNDO_SWAP( pFrm ) +/*?*/ return 0; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ // Endlich: FtnPortion anlegen und raus hier... +/*N*/ SwFtnPortion *pRet = new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ), +/*N*/ pFrm, pFtn, nReal ); +/*N*/ rInf.SetFtnInside( sal_True ); +/*N*/ +/*N*/ UNDO_SWAP( pFrm ) +/*N*/ +/*N*/ return pRet; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewFtnNumPortion() + *************************************************************************/ + +// Die Portion fuer die Ftn-Nummerierung im Ftn-Bereich + +/*N*/ SwNumberPortion *SwTxtFormatter::NewFtnNumPortion( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ ASSERT( pFrm->IsInFtn() && !pFrm->GetIndPrev() && !rInf.IsFtnDone(), +/*N*/ "This is the wrong place for a ftnnumber" ); +/*N*/ if( rInf.GetTxtStart() != nStart || +/*N*/ rInf.GetTxtStart() != rInf.GetIdx() ) +/*N*/ return 0; +/*N*/ +/*N*/ const SwFtnFrm *pFtnFrm = pFrm->FindFtnFrm(); +/*N*/ const SwTxtFtn *pFtn = pFtnFrm->GetAttr(); +/*N*/ +/*N*/ // Aha, wir sind also im Fussnotenbereich +/*N*/ SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn(); +/*N*/ +/*N*/ SwDoc *pDoc = pFrm->GetNode()->GetDoc(); +/*N*/ XubString aFtnTxt( rFtn.GetViewNumStr( *pDoc, sal_True )); +/*N*/ +/*N*/ const SwEndNoteInfo* pInfo; +/*N*/ if( rFtn.IsEndNote() ) +/*?*/ pInfo = &pDoc->GetEndNoteInfo(); +/*N*/ else +/*N*/ pInfo = &pDoc->GetFtnInfo(); +/*N*/ const SwAttrSet& rSet = pInfo->GetCharFmt(*pDoc)->GetAttrSet(); +/*N*/ +/*N*/ const SwAttrSet* pParSet = &rInf.GetCharAttr(); +/*N*/ SwFont *pFnt = new SwFont( pParSet, rInf.GetDoc() ); +/*N*/ pFnt->SetDiffFnt(&rSet, rInf.GetDoc() ); +/*N*/ SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn(); +/*N*/ if( pTxtFtn ) +/*N*/ { +/*N*/ SwScriptInfo aScriptInfo; +/*N*/ SwAttrIter aIter( (SwTxtNode&)pTxtFtn->GetTxtNode(), aScriptInfo ); +/*N*/ aIter.Seek( *pTxtFtn->GetStart() ); +/*N*/ // Achtung: Wenn die Kriterien, nach denen der FtnReferenz-Font +/*N*/ // auf den FtnNumerierungsfont wirkt, geaendert werden, muss die +/*N*/ // untenstehende Methode SwFtnNumPortion::DiffFont() angepasst +/*N*/ // werden. +/*N*/ if( aIter.GetFnt()->IsSymbol(rInf.GetVsh()) || aIter.GetFnt()->GetCharSet() != +/*N*/ pFnt->GetCharSet() ) +/*N*/ { +/*N*/ const BYTE nAct = pFnt->GetActual(); +/*N*/ pFnt->SetName( aIter.GetFnt()->GetName(), nAct ); +/*N*/ pFnt->SetStyleName( aIter.GetFnt()->GetStyleName(), nAct ); +/*N*/ pFnt->SetFamily( aIter.GetFnt()->GetFamily(),nAct ); +/*N*/ pFnt->SetCharSet( aIter.GetFnt()->GetCharSet(), nAct ); +/*N*/ } +/*N*/ } +/*N*/ +/*M*/ pFnt->SetVertical( pFnt->GetOrientation(), pFrm->IsVertical() ); +/*N*/ return new SwFtnNumPortion( aFtnTxt, pFnt ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewErgoSumPortion() + *************************************************************************/ + +/*?*/ XubString lcl_GetPageNumber( const SwPageFrm* pPage ) +/*?*/ { +/*?*/ ASSERT( pPage, "GetPageNumber: Homeless TxtFrm" ); +/*?*/ MSHORT nVirtNum = pPage->GetVirtPageNum(); +/*?*/ const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType(); +/*?*/ return rNum.GetNumStr( nVirtNum ); +/*?*/ } + +/*N*/ SwErgoSumPortion *SwTxtFormatter::NewErgoSumPortion( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ // Wir koennen nicht davon ausgehen, dass wir ein Follow sind +/*N*/ // 7983: GetIdx() nicht nStart +/*N*/ if( !pFrm->IsInFtn() || pFrm->GetPrev() || +/*N*/ rInf.IsErgoDone() || rInf.GetIdx() != pFrm->GetOfst() || +/*N*/ pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() ) +/*N*/ return 0; +/*N*/ +/*N*/ // Aha, wir sind also im Fussnotenbereich +/*N*/ const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo(); +/*N*/ SwTxtFrm *pQuoFrm = pFrm->FindQuoVadisFrm(); +/*N*/ if( !pQuoFrm ) +/*N*/ return 0; +/*?*/ const SwPageFrm* pPage = pFrm->FindPageFrm(); +/*?*/ const SwPageFrm* pQuoPage = pQuoFrm->FindPageFrm(); +/*?*/ if( pPage == pQuoFrm->FindPageFrm() ) +/*?*/ return 0; // Wenn der QuoVadis auf der selben (spaltigen) Seite steht + {DBG_BF_ASSERT(0, "STRIP");} return 0;//STRIP001 /*?*/ const XubString aPage = lcl_GetPageNumber( pPage ); +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::FormatQuoVadis() + *************************************************************************/ + +/*M*/ xub_StrLen SwTxtFormatter::FormatQuoVadis( const xub_StrLen nOffset ) +/*M*/ { +/*M*/ ASSERT( ! pFrm->IsVertical() || ! pFrm->IsSwapped(), +/*M*/ "SwTxtFormatter::FormatQuoVadis with swapped frame" ); +/*M*/ +/*M*/ if( !pFrm->IsInFtn() || pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() ) +/*M*/ return nOffset; +/*M*/ +/*M*/ const SwFrm* pErgoFrm = pFrm->FindFtnFrm()->GetFollow(); +/*M*/ if( !pErgoFrm && pFrm->HasFollow() ) +/*M*/ pErgoFrm = pFrm->GetFollow(); +/*M*/ if( !pErgoFrm ) +/*M*/ return nOffset; +/*M*/ +/*M*/ if( pErgoFrm == pFrm->GetNext() ) +/*M*/ { +/*M*/ SwFrm *pCol = pFrm->FindColFrm(); +/*M*/ while( pCol && !pCol->GetNext() ) +/*M*/ pCol = pCol->GetUpper()->FindColFrm(); +/*M*/ if( pCol ) +/*M*/ return nOffset; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ const SwPageFrm* pPage = pFrm->FindPageFrm(); +/*M*/ const SwPageFrm* pErgoPage = pErgoFrm->FindPageFrm(); +/*M*/ if( pPage == pErgoFrm->FindPageFrm() ) +/*M*/ return nOffset; // Wenn der ErgoSum auf der selben Seite steht +/*M*/ } +/*M*/ +/*M*/ SwTxtFormatInfo &rInf = GetInfo(); +/*M*/ const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo(); +/*M*/ if( !rFtnInfo.aQuoVadis.Len() ) +/*M*/ return nOffset; +/*M*/ +/*M*/ // Ein Wort zu QuoVadis/ErgoSum: +/*M*/ // Fuer diese Texte wird der am Absatz eingestellte Font verwendet. +/*M*/ // Wir initialisieren uns also: +/*M*/ // ResetFont(); +/*M*/ FeedInf( rInf ); +/*M*/ SeekStartAndChg( rInf, sal_True ); +/*M*/ if( GetRedln() && pCurr->HasRedline() ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); }//STRIP001 GetRedln()->Seek( *pFnt, nOffset, 0 ); +/*M*/ +/*M*/ // Ein fieser Sonderfall: Flyfrms reichen in die Zeile und stehen +/*M*/ // natuerlich da, wo wir unseren Quovadis Text reinsetzen wollen. +/*M*/ // Erst mal sehen, ob es so schlimm ist: +/*M*/ SwLinePortion *pPor = pCurr->GetFirstPortion(); +/*M*/ KSHORT nLastLeft = 0; +/*M*/ while( pPor ) +/*M*/ { +/*M*/ if ( pPor->IsFlyPortion() ) +/*M*/ nLastLeft = ( (SwFlyPortion*) pPor)->Fix() + +/*M*/ ( (SwFlyPortion*) pPor)->Width(); +/*M*/ pPor = pPor->GetPortion(); +/*M*/ } +/*M*/ // Das alte Spiel: wir wollen, dass die Zeile an einer bestimmten +/*M*/ // Stelle umbricht, also beeinflussen wir die Width. +/*M*/ // nLastLeft ist jetzt quasi der rechte Rand. +/*M*/ const KSHORT nOldRealWidth = rInf.RealWidth(); +/*M*/ rInf.RealWidth( nOldRealWidth - nLastLeft ); +/*M*/ +/*?*/ XubString aErgo = lcl_GetPageNumber( pErgoFrm->FindPageFrm() ); +/*?*/ SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFtnInfo.aQuoVadis, aErgo ); +/*M*/ pQuo->SetAscent( rInf.GetAscent() ); +/*M*/ pQuo->Height( rInf.GetTxtHeight() ); +/*M*/ pQuo->Format( rInf ); +/*M*/ USHORT nQuoWidth = pQuo->Width(); +/*M*/ SwLinePortion* pCurrPor = pQuo; +/*M*/ +/*M*/ while ( rInf.GetRest() ) +/*M*/ { +/*M*/ SwLinePortion* pFollow = rInf.GetRest(); +/*M*/ rInf.SetRest( 0 ); +/*M*/ pCurrPor->Move( rInf ); +/*M*/ +/*M*/ ASSERT( pFollow->IsQuoVadisPortion(), +/*M*/ "Quo Vadis, rest of QuoVadisPortion" ) +/*M*/ +/*M*/ // format the rest and append it to the other QuoVadis parts +/*M*/ pFollow->Format( rInf ); +/*M*/ nQuoWidth += pFollow->Width(); +/*M*/ +/*M*/ pCurrPor->Append( pFollow ); +/*M*/ pCurrPor = pFollow; +/*M*/ } +/*M*/ +/*M*/ nLastLeft = nOldRealWidth - nQuoWidth; +/*M*/ Right( Right() - nQuoWidth ); +/*M*/ +/*M*/ SWAP_IF_NOT_SWAPPED( pFrm ) +/*M*/ +/*M*/ const xub_StrLen nRet = FormatLine( nStart ); +/*M*/ +/*M*/ UNDO_SWAP( pFrm ) +/*M*/ +/*M*/ Right( rInf.Left() + nOldRealWidth - 1 ); +/*M*/ +/*M*/ nLastLeft = nOldRealWidth - pCurr->Width(); +/*M*/ FeedInf( rInf ); +/*M*/ #ifdef USED +/*M*/ ASSERT( nOldRealWidth == rInf.RealWidth() && nLastLeft >= pQuo->Width(), +/*M*/ "SwTxtFormatter::FormatQuoVadis: crime doesn't pay" ); +/*M*/ #endif +/*M*/ +/*M*/ // Es kann durchaus sein, dass am Ende eine Marginportion steht, +/*M*/ // die beim erneuten Aufspannen nur Aerger bereiten wuerde. +/*M*/ pPor = pCurr->FindLastPortion(); +/*M*/ SwGluePortion *pGlue = pPor->IsMarginPortion() ? +/*M*/ (SwMarginPortion*) pPor : 0; +/*M*/ if( pGlue ) +/*M*/ { +/*M*/ pGlue->Height( 0 ); +/*M*/ pGlue->Width( 0 ); +/*M*/ pGlue->SetLen( 0 ); +/*M*/ pGlue->SetAscent( 0 ); +/*M*/ pGlue->SetPortion( NULL ); +/*M*/ pGlue->SetFixWidth(0); +/*M*/ } +/*M*/ +/*M*/ // Luxus: Wir sorgen durch das Aufspannen von Glues dafuer, +/*M*/ // dass der QuoVadis-Text rechts erscheint: +/*M*/ nLastLeft -= nQuoWidth; +/*M*/ if( nLastLeft ) +/*M*/ { +/*M*/ if( nLastLeft > pQuo->GetAscent() ) // Mindestabstand +/*M*/ { +/*M*/ switch( GetAdjust() ) +/*M*/ { +/*M*/ case SVX_ADJUST_BLOCK: +/*M*/ { +/*M*/ if( !pCurr->GetLen() || +/*M*/ CH_BREAK != GetInfo().GetChar(nStart+pCurr->GetLen()-1)) +/*M*/ nLastLeft = pQuo->GetAscent(); +/*M*/ nQuoWidth += nLastLeft; +/*M*/ break; +/*M*/ } +/*M*/ case SVX_ADJUST_RIGHT: +/*M*/ { +/*M*/ nLastLeft = pQuo->GetAscent(); +/*M*/ nQuoWidth += nLastLeft; +/*M*/ break; +/*M*/ } +/*M*/ case SVX_ADJUST_CENTER: +/*M*/ { +/*M*/ nQuoWidth += pQuo->GetAscent(); +/*M*/ long nDiff = nLastLeft - nQuoWidth; +/*M*/ if( nDiff < 0 ) +/*M*/ { +/*M*/ nLastLeft = pQuo->GetAscent(); +/*M*/ nQuoWidth = -nDiff + nLastLeft; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ nQuoWidth = 0; +/*M*/ nLastLeft = ( pQuo->GetAscent() + nDiff ) / 2; +/*M*/ } +/*M*/ break; +/*M*/ } +/*M*/ default: +/*M*/ nQuoWidth += nLastLeft; +/*M*/ } +/*M*/ } +/*M*/ else +/*M*/ nQuoWidth += nLastLeft; +/*M*/ if( nLastLeft ) +/*M*/ { +/*M*/ pGlue = new SwGluePortion(0); +/*M*/ pGlue->Width( nLastLeft ); +/*M*/ pPor->Append( pGlue ); +/*M*/ pPor = pPor->GetPortion(); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ // Jetzt aber: die QuoVadis-Portion wird angedockt: +/*M*/ pCurrPor = pQuo; +/*M*/ while ( pCurrPor ) +/*M*/ { +/*M*/ // pPor->Append deletes the pPortoin pointer of pPor. Therefore +/*M*/ // we have to keep a pointer to the next portion +/*M*/ pQuo = (SwQuoVadisPortion*)pCurrPor->GetPortion(); +/*M*/ pPor->Append( pCurrPor ); +/*M*/ pPor = pPor->GetPortion(); +/*M*/ pCurrPor = pQuo; +/*M*/ } +/*M*/ +/*M*/ pCurr->Width( pCurr->Width() + KSHORT( nQuoWidth ) ); +/*M*/ +/*M*/ // Und noch einmal adjustieren wegen des Adjustment und nicht zu Letzt +/*M*/ // wegen folgendem Sonderfall: In der Zeile hat der DummUser durchgaengig +/*M*/ // einen kleineren Font eingestellt als der vom QuoVadis-Text ... +/*M*/ CalcAdjustLine( pCurr ); +/*M*/ +/*N*/ #if OSL_DEBUG_LEVEL > 1 +/*M*/ #endif +/*M*/ +/*M*/ // Uff... +/*M*/ return nRet; +/*M*/ } + + +/************************************************************************* + * SwTxtFormatter::MakeDummyLine() + *************************************************************************/ + +// MakeDummyLine() erzeugt eine Line, die bis zum unteren Seitenrand +// reicht. DummyLines bzw. DummyPortions sorgen dafuer, dass Oszillationen +// zum stehen kommen, weil Rueckflussmoeglichkeiten genommen werden. +// Sie werden bei absatzgebundenen Frames in Fussnoten und bei Ftn- +// Oszillationen verwendet. + + +/************************************************************************* + * SwFtnSave::SwFtnSave() + *************************************************************************/ + +/*M*/ SwFtnSave::SwFtnSave( const SwTxtSizeInfo &rInf, const SwTxtFtn* pTxtFtn ) +/*M*/ : pInf( &((SwTxtSizeInfo&)rInf) ) +/*M*/ { +/*M*/ if( pTxtFtn && rInf.GetTxtFrm() ) +/*M*/ { +/*M*/ pFnt = ((SwTxtSizeInfo&)rInf).GetFont(); +/*M*/ pOld = new SwFont( *pFnt ); +/*M*/ pOld->GetTox() = pFnt->GetTox(); +/*M*/ pFnt->GetTox() = 0; +/*M*/ SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn(); +/*M*/ const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc(); +/*M*/ +/*M*/ // examine text and set script +/*M*/ String aTmpStr( rFtn.GetViewNumStr( *pDoc ) ); +/*M*/ pFnt->SetActual( WhichFont( 0, &aTmpStr, 0 ) ); +/*M*/ +/*M*/ const SwEndNoteInfo* pInfo; +/*M*/ if( rFtn.IsEndNote() ) +/*M*/ pInfo = &pDoc->GetEndNoteInfo(); +/*M*/ else +/*M*/ pInfo = &pDoc->GetFtnInfo(); +/*M*/ const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet(); +/*M*/ pFnt->SetDiffFnt( &rSet, rInf.GetDoc() ); +/*M*/ +/*M*/ // we reduce footnote size, if we are inside a double line portion +/*M*/ if ( ! pOld->GetEscapement() && 50 == pOld->GetPropr() ) +/*M*/ { +/*M*/ Size aSize = pFnt->GetSize( pFnt->GetActual() ); +/*M*/ pFnt->SetSize( Size( (long)aSize.Width() / 2, +/*M*/ (long)aSize.Height() / 2 ), +/*M*/ pFnt->GetActual() ); +/*M*/ } +/*M*/ +/*M*/ // set the correct rotation at the footnote font +/*M*/ const SfxPoolItem* pItem; +/*M*/ if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ROTATE, +/*M*/ sal_True, &pItem )) +/*M*/ pFnt->SetVertical( ((SvxCharRotateItem*)pItem)->GetValue(), +/*M*/ rInf.GetTxtFrm()->IsVertical() ); +/*M*/ +/*M*/ pFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() ); +/*M*/ +/*M*/ if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_BACKGROUND, +/*M*/ sal_True, &pItem )) +/*M*/ pFnt->SetBackColor( new Color( ((SvxBrushItem*)pItem)->GetColor() ) ); +/*M*/ } +/*M*/ else +/*M*/ pFnt = NULL; +/*M*/ } + +/************************************************************************* + * SwFtnSave::~SwFtnSave() + *************************************************************************/ + +/*N*/ SwFtnSave::~SwFtnSave() +/*N*/ { +/*N*/ if( pFnt ) +/*N*/ { +/*N*/ // SwFont zurueckstellen +/*N*/ *pFnt = *pOld; +/*N*/ pFnt->GetTox() = pOld->GetTox(); +/*N*/ pFnt->ChgPhysFnt( pInf->GetVsh(), pInf->GetOut() ); +/*N*/ delete pOld; +/*N*/ } +/*N*/ } + +/************************************************************************* + * SwFtnPortion::SwFtnPortion() + *************************************************************************/ + +/*N*/ SwFtnPortion::SwFtnPortion( const XubString &rExpand, SwTxtFrm *pFrm, +/*N*/ SwTxtFtn *pFtn, KSHORT nReal ) +/*N*/ : SwFldPortion( rExpand, 0 ), pFrm(pFrm), pFtn(pFtn), nOrigHeight( nReal ) +/*N*/ { +/*N*/ SetLen(1); +/*N*/ SetWhichPor( POR_FTN ); +/*N*/ } + +/************************************************************************* + * SwFtnPortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwFtnPortion::GetExpTxt( const SwTxtSizeInfo &, XubString &rTxt ) const +/*N*/ { +/*N*/ rTxt = aExpand; +/*N*/ return sal_True; +/*N*/ } + + + +/************************************************************************* + * virtual SwFtnPortion::Format() + *************************************************************************/ + +/*N*/ sal_Bool SwFtnPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ SwFtnSave aFtnSave( rInf, pFtn ); +/*N*/ // the idx is manipulated in SwExpandPortion::Format +/*N*/ // this flag indicates, that a footnote is allowed to trigger +/*N*/ // an underflow during SwTxtGuess::Guess +/*N*/ rInf.SetFakeLineStart( rInf.GetIdx() > rInf.GetLineStart() ); +/*N*/ sal_Bool bFull = SwFldPortion::Format( rInf ); +/*N*/ rInf.SetFakeLineStart( sal_False ); +/*N*/ SetAscent( rInf.GetAscent() ); +/*N*/ Height( rInf.GetTxtHeight() ); +/*N*/ rInf.SetFtnDone( !bFull ); +/*N*/ if( !bFull ) +/*N*/ rInf.SetParaFtn(); +/*N*/ return bFull; +/*N*/ } + +/************************************************************************* + * virtual SwFtnPortion::Paint() + *************************************************************************/ + +/*N*/ void SwFtnPortion::Paint( const SwTxtPaintInfo &rInf ) const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 //STRIP001 SwFtnSave aFtnSave( rInf, pFtn ); +/*N*/ } + +/************************************************************************* + * virtual SwFtnPortion::GetTxtSize() + *************************************************************************/ + +/*N*/ SwPosSize SwFtnPortion::GetTxtSize( const SwTxtSizeInfo &rInfo ) const +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); return NULL;//STRIP001 SwFtnSave aFtnSave( rInfo, pFtn ); +/*N*/ } + +/************************************************************************* + * class SwQuoVadisPortion + *************************************************************************/ + + + +/************************************************************************* + * virtual SwQuoVadisPortion::Format() + *************************************************************************/ + + +/************************************************************************* + * virtual SwQuoVadisPortion::GetExpTxt() + *************************************************************************/ + + +/************************************************************************* + * virtual SwQuoVadisPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * virtual SwQuoVadisPortion::Paint() + *************************************************************************/ + + +/************************************************************************* + * class SwErgoSumPortion + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwErgoSumPortion::Format() + *************************************************************************/ + + +/************************************************************************* + * sal_Bool SwFtnNumPortion::DiffFont() + * liefert sal_True, wenn der Font der FtnReferenz (pFont) eine Aenderung + * des Fonts der FtnNumerierung (pFnt) erforderlich macht. + * Die Bedingungen sind ein Spiegel dessen, was in NewFtnNumPortion steht + *************************************************************************/ + +/*N*/ sal_Bool SwFtnNumPortion::DiffFont( SwFont* pFont ) +/*N*/ { +/*N*/ if( pFnt->GetName() != pFont->GetName() || +/*N*/ pFnt->GetStyleName() != pFont->GetStyleName() || +/*N*/ pFnt->GetFamily() != pFont->GetFamily() || +/*N*/ pFont->GetCharSet() != pFnt->GetCharSet() ) +/*N*/ return sal_True; +/*N*/ return sal_False; +/*N*/ } + +/************************************************************************* + * SwParaPortion::SetErgoSumNum() + *************************************************************************/ + + +/************************************************************************* + * SwParaPortion::UpdateQuoVadis() + * + * Wird im SwTxtFrm::Prepare() gerufen + *************************************************************************/ + +/*N*/ sal_Bool SwParaPortion::UpdateQuoVadis( const XubString &rQuo ) +/*N*/ { +/*N*/ SwLineLayout *pLay = this; +/*N*/ while( pLay->GetNext() ) +/*N*/ { +///*?*/ DBG_LOOP; +/*?*/ pLay = pLay->GetNext(); +/*N*/ } +/*N*/ SwLinePortion *pPor = pLay; +/*N*/ SwQuoVadisPortion *pQuo = 0; +/*N*/ while( pPor && !pQuo ) +/*N*/ { +/*N*/ if ( pPor->IsQuoVadisPortion() ) +/*?*/ pQuo = (SwQuoVadisPortion*)pPor; +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ +/*N*/ if( !pQuo ) +/*N*/ return sal_False; +/*N*/ + {DBG_BF_ASSERT(0, "STRIP");} return sal_False;//STRIP001 /*?*/ return pQuo->GetQuoTxt() == rQuo; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txthyph.cxx b/binfilter/bf_sw/source/core/text/sw_txthyph.cxx new file mode 100644 index 000000000000..44b69b9525b9 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txthyph.cxx @@ -0,0 +1,355 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + + +#include <viewopt.hxx> // SwViewOptions +#include <porhyph.hxx> // +#include <itrform2.hxx> // +#include <guess.hxx> // +namespace binfilter { + +#ifdef DBG_UTIL +extern const sal_Char *GetLangName( const MSHORT nLang ); +#endif + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::linguistic2; +using namespace ::com::sun::star::i18n; + +/************************************************************************* + * SwTxtFormatInfo::HyphWord() + *************************************************************************/ + + +/************************************************************************* + * SwTxtFrm::Hyphenate + * + * Wir formatieren eine Zeile fuer die interaktive Trennung + *************************************************************************/ + + +/************************************************************************* + * SwTxtFormatter::Hyphenate + * + * Wir formatieren eine Zeile fuer die interaktive Trennung + *************************************************************************/ +// Wir koennen davon ausgehen, dass bereits formatiert wurde. +// Fuer die CeBIT'93 gehen wir den einfachen, sicheren Weg: +// Die Zeile wird einfach neu formatiert, der Hyphenator wird dann +// so vorbereitet, wie ihn die UI erwartet. +// Hier stehen natuerlich enorme Optimierungsmoeglichkeiten offen. + + + +/************************************************************************* + * SwTxtPortion::CreateHyphen() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtPortion::CreateHyphen( SwTxtFormatInfo &rInf, SwTxtGuess &rGuess ) +/*N*/ { +/*N*/ ASSERT( !pPortion, "SwTxtPortion::Hyphenate: another portion, another planet..." ); +/*N*/ if( rInf.IsHyphForbud() || +/*N*/ pPortion || // robust +/*N*/ // Mehrzeilige Felder duerfen nicht interaktiv getrennt werden. +/*N*/ ( rInf.IsInterHyph() && InFldGrp() ) ) +/*N*/ return sal_False; +/*N*/ +/*N*/ Reference< XHyphenatedWord > xHyphWord = rGuess.HyphWord(); +/*N*/ SwHyphPortion *pHyphPor = NULL; +/*N*/ xub_StrLen nPorEnd = 0; +/*N*/ SwTxtSizeInfo aInf( rInf ); +/*N*/ +/*N*/ // first case: hyphenated word has alternative spelling +/*N*/ if ( xHyphWord.is() && xHyphWord->isAlternativeSpelling() ) { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SvxAlternativeSpelling aAltSpell; +/*N*/ } else { +/*N*/ // second case: no alternative spelling +/*N*/ SwHyphPortion aHyphPor; +/*N*/ aHyphPor.SetLen( 1 ); +/*N*/ +/*N*/ static const void* pLastMagicNo = 0; +/*N*/ static KSHORT aMiniCacheH = 0, aMiniCacheW = 0; +/*N*/ const void* pTmpMagic; +/*N*/ MSHORT nFntIdx; +/*N*/ rInf.GetFont()->GetMagic( pTmpMagic, nFntIdx, rInf.GetFont()->GetActual() ); +/*N*/ if( !pLastMagicNo || pLastMagicNo != pTmpMagic ) { +/*N*/ pLastMagicNo = pTmpMagic; +/*N*/ (SwPosSize&)aHyphPor = aHyphPor.GetTxtSize( rInf ); +/*N*/ aMiniCacheH = aHyphPor.Height(), aMiniCacheW = aHyphPor.Width(); +/*N*/ } else { +/*N*/ aHyphPor.Height( aMiniCacheH ), aHyphPor.Width( aMiniCacheW ); +/*N*/ } +/*N*/ aHyphPor.SetLen( 0 ); +/*N*/ pHyphPor = new SwHyphPortion( aHyphPor ); +/*N*/ +/*N*/ pHyphPor->SetWhichPor( POR_HYPH ); +/*N*/ +/*N*/ // values required for this +/*N*/ nPorEnd = xHyphWord->getHyphenPos() + 1 + rGuess.BreakStart() +/*N*/ - rGuess.FieldDiff(); +/*N*/ } +/*N*/ +/*N*/ // portion end must be in front of us +/*N*/ // we do not put hyphens at start of line +/*N*/ if ( nPorEnd > rInf.GetIdx() || +/*N*/ ( nPorEnd == rInf.GetIdx() && rInf.GetLineStart() != rInf.GetIdx() ) ) +/*N*/ { +/*N*/ aInf.SetLen( nPorEnd - rInf.GetIdx() ); +/*N*/ pHyphPor->SetAscent( GetAscent() ); +/*N*/ SetLen( aInf.GetLen() ); +/*N*/ CalcTxtSize( aInf ); +/*N*/ +/*N*/ Insert( pHyphPor ); +/*N*/ +/*N*/ short nKern = rInf.GetFont()->CheckKerning(); +/*N*/ if( nKern ) +/*N*/ new SwKernPortion( *this, nKern ); +/*N*/ +/*N*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ // last exit for the lost +/*N*/ delete pHyphPor; +/*N*/ BreakCut( rInf, rGuess ); +/*N*/ return sal_False; +/*N*/ } + + +/************************************************************************* + * virtual SwHyphPortion::GetExpTxt() + *************************************************************************/ + +/*N*/ sal_Bool SwHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ rTxt = '-'; +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * virtual SwHyphPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * virtual SwHyphPortion::Format() + *************************************************************************/ + +/*N*/ sal_Bool SwHyphPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ register const SwLinePortion *pLast = rInf.GetLast(); +/*N*/ Height( pLast->Height() ); +/*N*/ SetAscent( pLast->GetAscent() ); +/*N*/ XubString aTxt; +/*N*/ +/*N*/ if( !GetExpTxt( rInf, aTxt ) ) +/*N*/ return sal_False; +/*N*/ +/*N*/ PrtWidth( rInf.GetTxtSize( aTxt ).Width() ); +/*N*/ const sal_Bool bFull = rInf.Width() <= rInf.X() + PrtWidth(); +/*N*/ if( bFull && !rInf.IsUnderFlow() ) { +/*?*/ Truncate(); +/*?*/ rInf.SetUnderFlow( this ); +/*N*/ } +/*N*/ +/*N*/ return bFull; +/*N*/ } + +/************************************************************************* + * virtual SwHyphStrPortion::GetExpTxt() + *************************************************************************/ + + +/************************************************************************* + * virtual SwHyphStrPortion::HandlePortion() + *************************************************************************/ + + +/************************************************************************* + * class SwSoftHyphPortion + *************************************************************************/ + +/*N*/ SwLinePortion *SwSoftHyphPortion::Compress() { return this; } + +/*N*/ SwSoftHyphPortion::SwSoftHyphPortion() : +/*N*/ bExpand(sal_False), nViewWidth(0), nHyphWidth(0) +/*N*/ { +/*N*/ SetLen(1); +/*N*/ SetWhichPor( POR_SOFTHYPH ); +/*N*/ } + + +/* Faelle: + * 1) SoftHyph steht in der Zeile, ViewOpt aus. + * -> unsichtbar, Nachbarn unveraendert + * 2) SoftHyph steht in der Zeile, ViewOpt an. + * -> sichtbar, Nachbarn veraendert + * 3) SoftHyph steht am Zeilenende, ViewOpt aus/an. + * -> immer sichtbar, Nachbarn unveraendert + */ + + +/************************************************************************* + * virtual SwSoftHyphPortion::Format() + *************************************************************************/ + +/* Die endgueltige Breite erhalten wir im FormatEOL(). + * In der Underflow-Phase stellen wir fest, ob ueberhaupt ein + * alternatives Spelling vorliegt. Wenn ja ... + * + * Fall 1: "Au-to" + * 1) {Au}{-}{to}, {to} passt nicht mehr => Underflow + * 2) {-} ruft Hyphenate => keine Alternative + * 3) FormatEOL() und bFull = sal_True + * + * Fall 2: "Zuc-ker" + * 1) {Zuc}{-}{ker}, {ker} passt nicht mehr => Underflow + * 2) {-} ruft Hyphenate => Alternative! + * 3) Underflow() und bFull = sal_True + * 4) {Zuc} ruft Hyphenate => {Zuk}{-}{ker} + */ + +/*N*/ sal_Bool SwSoftHyphPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ sal_Bool bFull = sal_True; +/*N*/ +/*N*/ // special case for old german spelling +/*N*/ if( rInf.IsUnderFlow() ) +/*N*/ { +/*N*/ if( rInf.GetSoftHyphPos() ) +/*N*/ return sal_True; +/*N*/ +/*N*/ const sal_Bool bHyph = rInf.ChgHyph( sal_True ); +/*N*/ if( rInf.IsHyphenate() ) +/*N*/ { +/*N*/ rInf.SetSoftHyphPos( rInf.GetIdx() ); +/*N*/ Width(0); +/*N*/ // if the soft hyphend word has an alternative spelling +/*N*/ // when hyphenated (old german spelling), the soft hyphen +/*N*/ // portion has to trigger an underflow +/*N*/ SwTxtGuess aGuess; +/*N*/ bFull = rInf.IsInterHyph() || +/*N*/ !aGuess.AlternativeSpelling( rInf, rInf.GetIdx() - 1 ); +/*N*/ } +/*N*/ rInf.ChgHyph( bHyph ); +/*N*/ +/*N*/ if( bFull && !rInf.IsHyphForbud() ) +/*N*/ { +/*N*/ rInf.SetSoftHyphPos(0); +/*N*/ FormatEOL( rInf ); +/*N*/ if ( rInf.GetFly() ) +/*?*/ rInf.GetRoot()->SetMidHyph( sal_True ); +/*N*/ else +/*N*/ rInf.GetRoot()->SetEndHyph( sal_True ); +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ rInf.SetSoftHyphPos( rInf.GetIdx() ); +/*?*/ Truncate(); +/*?*/ rInf.SetUnderFlow( this ); +/*N*/ } +/*N*/ return sal_True; +/*N*/ } +/*N*/ +/*N*/ rInf.SetSoftHyphPos(0); +/*N*/ SetExpand( sal_True ); +/*N*/ bFull = SwHyphPortion::Format( rInf ); +/*N*/ SetExpand( sal_False ); +/*N*/ if( !bFull ) +/*N*/ { +/*N*/ // default-maessig besitzen wir keine Breite, aber eine Hoehe +/*N*/ nHyphWidth = Width(); +/*N*/ Width(0); +/*N*/ } +/*N*/ return bFull; +/*N*/ } + +/************************************************************************* + * virtual SwSoftHyphPortion::FormatEOL() + *************************************************************************/ +// Format end of Line + +/*N*/ void SwSoftHyphPortion::FormatEOL( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( !IsExpand() ) +/*N*/ { +/*N*/ SetExpand( sal_True ); +/*N*/ if( rInf.GetLast() == this ) +/*?*/ rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) ); +/*N*/ +/*N*/ // 5964: alte Werte muessen wieder zurueckgesetzt werden. +/*N*/ const KSHORT nOldX = rInf.X(); +/*N*/ const xub_StrLen nOldIdx = rInf.GetIdx(); +/*N*/ rInf.X( rInf.X() - PrtWidth() ); +/*N*/ rInf.SetIdx( rInf.GetIdx() - GetLen() ); +/*N*/ const sal_Bool bFull = SwHyphPortion::Format( rInf ); +/*N*/ nHyphWidth = Width(); +/*N*/ +/*N*/ // 6976: Eine truebe Sache: Wir werden erlaubterweise breiter, +/*N*/ // aber gleich wird noch ein Fly verarbeitet, der eine korrekte +/*N*/ // X-Position braucht. +/*N*/ if( bFull || !rInf.GetFly() ) +/*N*/ rInf.X( nOldX ); +/*N*/ else +/*?*/ rInf.X( nOldX + Width() ); +/*N*/ rInf.SetIdx( nOldIdx ); +/*N*/ } +/*N*/ } + +/************************************************************************* + * virtual SwSoftHyphPortion::GetExpTxt() + * + * Wir expandieren: + * - wenn die Sonderzeichen sichtbar sein sollen + * - wenn wir am Ende der Zeile stehen. + * - wenn wir vor einem (echten/emuliertem) Zeilenumbruch stehen + *************************************************************************/ + +/*N*/ sal_Bool SwSoftHyphPortion::GetExpTxt( const SwTxtSizeInfo &rInf, XubString &rTxt ) const +/*N*/ { +/*N*/ if( IsExpand() || ( rInf.OnWin() && rInf.GetOpt().IsSoftHyph() ) || +/*N*/ ( GetPortion() && ( GetPortion()->InFixGrp() || +/*N*/ GetPortion()->IsDropPortion() || GetPortion()->IsLayPortion() || +/*N*/ GetPortion()->IsParaPortion() || GetPortion()->IsBreakPortion() ) ) ) +/*N*/ { +/*N*/ return SwHyphPortion::GetExpTxt( rInf, rTxt ); +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtinit.cxx b/binfilter/bf_sw/source/core/text/sw_txtinit.cxx new file mode 100644 index 000000000000..71b0805ff0cd --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtinit.cxx @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "fntcache.hxx" // pFntCache ( SwFont/ScrFont-PrtFont Cache ) +#include "swfntcch.hxx" // pSwFontCache ( SwAttrSet/SwFont Cache ) +#include "txtfrm.hxx" +#include "txtcache.hxx" +#include "porrst.hxx" + +#include <horiornt.hxx> + +#include "pordrop.hxx" +#include "txtfly.hxx" // SwContourCache +#include "dbg_lay.hxx" // Layout Debug Fileausgabe +namespace binfilter { + +/*N*/ SwCache *SwTxtFrm::pTxtCache = 0; +/*N*/ long SwTxtFrm::nMinPrtLine = 0; +/*N*/ SwContourCache *pContourCache = 0; + +#ifndef PROFILE +// Code zum Initialisieren von Statics im eigenen Code-Segment +#ifdef _MSC_VER +#pragma code_seg( "SWSTATICS" ) +#endif +#endif + +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtLine, 50, 50 ) +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( SwParaPortion, 50, 50 ) //Absaetze +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( SwLineLayout, 150, 150 ) //Zeilen +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( SwHolePortion, 150, 150 ) //z.B. Blanks am Zeilenende +/*N*/ IMPL_FIXEDMEMPOOL_NEWDEL( SwTxtPortion, 200, 100 ) //Attributwechsel + +#ifndef PROFILE +#ifdef _MSC_VER +#pragma code_seg() +#endif +#endif + +/************************************************************************* + * _TextInit(), _TextFinit() + *************************************************************************/ + +// Werden _nur_ in init.cxx verwendet, dort stehen extern void _TextFinit() +// und extern void _TextInit(...) + +/*N*/ void _TextInit() +/*N*/ { +/*N*/ pFntCache = new SwFntCache; +/*N*/ pSwFontCache = new SwFontCache; +/*N*/ pWaveCol = new Color( COL_GRAY ); +/*N*/ +/*N*/ //Pauschale groesse 250, plus 100 pro Shell +/*N*/ SwCache *pTxtCache = new SwCache( 250, 100 +/*N*/ #ifdef DBG_UTIL +/*N*/ , "static SwTxtFrm::pTxtCache" +/*N*/ #endif +/*N*/ ); +/*N*/ SwTxtFrm::SetTxtCache( pTxtCache ); +/*N*/ PROTOCOL_INIT +/*N*/ } + +/*N*/ void _TextFinit() +/*N*/ { +/*N*/ PROTOCOL_STOP +/*N*/ delete SwTxtFrm::GetTxtCache(); +/*N*/ delete pSwFontCache; +/*N*/ delete pFntCache; +/*N*/ delete pWaveCol; +/*N*/ delete pContourCache; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txtio.cxx b/binfilter/bf_sw/source/core/text/sw_txtio.cxx new file mode 100644 index 000000000000..5d24e1d03c97 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txtio.cxx @@ -0,0 +1,1077 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "viewsh.hxx" // IsDbg() +#include "viewopt.hxx" // IsDbg() + +#ifndef DBG_UTIL +#error Wer fummelt denn an den makefiles? +#endif + +#define CONSTCHAR( name, string ) static const sal_Char __FAR_DATA name[] = string + +#include <horiornt.hxx> + +#include "flyfrms.hxx" +#include "inftxt.hxx" +#include "porfly.hxx" +#include "porftn.hxx" +#include "porhyph.hxx" +#include "porref.hxx" +#include "porrst.hxx" +#include "portab.hxx" +#include "portox.hxx" +#include "pordrop.hxx" +#include "pormulti.hxx" +#include "frmsh.hxx" + +// So kann man die Layoutstruktur ausgeben lassen +// #define AMA_LAYOUT +#ifdef AMA_LAYOUT +#include <stdio.h> +#include <stdlib.h> // getenv() +namespace binfilter { + + +/*N*/ void lcl_OutFollow( XubString &rTmp, const SwFrm* pFrm ) +/*N*/ { +/*N*/ if( pFrm->IsFlowFrm() ) +/*N*/ { +/*N*/ const SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm ); +/*N*/ if( pFlow->IsFollow() || pFlow->GetFollow() ) +/*N*/ { +/*N*/ rTmp += "("; +/*N*/ if( pFlow->IsFollow() ) +/*N*/ rTmp += "."; +/*N*/ if( pFlow->GetFollow() ) +/*N*/ { +/*N*/ MSHORT nFrmId = pFlow->GetFollow()->GetFrm()->GetFrmId(); +/*N*/ rTmp += nFrmId; +/*N*/ } +/*N*/ rTmp += ")"; +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void lcl_OutFrame( SvFileStream& rStr, const SwFrm* pFrm, ByteString& rSp, sal_Bool bNxt ) +/*N*/ { +/*N*/ if( !pFrm ) +/*N*/ return; +/*N*/ KSHORT nSpc = 0; +/*N*/ MSHORT nFrmId = pFrm->GetFrmId(); +/*N*/ ByteString aTmp; +/*N*/ if( pFrm->IsLayoutFrm() ) +/*N*/ { +/*N*/ if( pFrm->IsRootFrm() ) +/*N*/ aTmp = "R"; +/*N*/ else if( pFrm->IsPageFrm() ) +/*N*/ aTmp = "P"; +/*N*/ else if( pFrm->IsBodyFrm() ) +/*N*/ aTmp = "B"; +/*N*/ else if( pFrm->IsColumnFrm() ) +/*N*/ aTmp = "C"; +/*N*/ else if( pFrm->IsTabFrm() ) +/*N*/ aTmp = "Tb"; +/*N*/ else if( pFrm->IsRowFrm() ) +/*N*/ aTmp = "Rw"; +/*N*/ else if( pFrm->IsCellFrm() ) +/*N*/ aTmp = "Ce"; +/*N*/ else if( pFrm->IsSctFrm() ) +/*N*/ aTmp = "S"; +/*N*/ else if( pFrm->IsFlyFrm() ) +/*N*/ { +/*N*/ aTmp = "F"; +/*N*/ const SwFlyFrm *pFly = (SwFlyFrm*)pFrm; +/*N*/ if( pFly->IsFlyInCntFrm() ) +/*N*/ aTmp += "in"; +/*N*/ else if( pFly->IsFlyAtCntFrm() ) +/*N*/ { +/*N*/ aTmp += "a"; +/*N*/ if( pFly->IsAutoPos() ) +/*N*/ aTmp += "u"; +/*N*/ else +/*N*/ aTmp += "t"; +/*N*/ } +/*N*/ else +/*N*/ aTmp += "l"; +/*N*/ } +/*N*/ else if( pFrm->IsHeaderFrm() ) +/*N*/ aTmp = "H"; +/*N*/ else if( pFrm->IsFooterFrm() ) +/*N*/ aTmp = "Fz"; +/*N*/ else if( pFrm->IsFtnContFrm() ) +/*N*/ aTmp = "Fc"; +/*N*/ else if( pFrm->IsFtnFrm() ) +/*N*/ aTmp = "Fn"; +/*N*/ else +/*N*/ aTmp = "?L?"; +/*N*/ aTmp += nFrmId; +/*N*/ lcl_OutFollow( aTmp, pFrm ); +/*N*/ aTmp += " "; +/*N*/ rStr << aTmp; +/*N*/ nSpc = aTmp.Len(); +/*N*/ rSp.Expand( nSpc + rSp.Len() ); +/*N*/ lcl_OutFrame( rStr, ((SwLayoutFrm*)pFrm)->Lower(), rSp, sal_True ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if( pFrm->IsTxtFrm() ) +/*N*/ aTmp = "T"; +/*N*/ else if( pFrm->IsNoTxtFrm() ) +/*N*/ aTmp = "N"; +/*N*/ else +/*N*/ aTmp = "?C?"; +/*N*/ aTmp += nFrmId; +/*N*/ lcl_OutFollow( aTmp, pFrm ); +/*N*/ aTmp += " "; +/*N*/ rStr << aTmp; +/*N*/ nSpc = aTmp.Len(); +/*N*/ rSp.Expand( nSpc + rSp.Len() ); +/*N*/ } +/*N*/ if( pFrm->IsPageFrm() ) +/*N*/ { +/*N*/ const SwPageFrm* pPg = (SwPageFrm*)pFrm; +/*N*/ const SwSortDrawObjs *pSorted = pPg->GetSortedObjs(); +/*N*/ const MSHORT nCnt = pSorted ? pSorted->Count() : 0; +/*N*/ if( nCnt ) +/*N*/ { +/*N*/ for( MSHORT i=0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pSorted)[ i ]; +/*N*/ if( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ lcl_OutFrame( rStr, pFly, rSp, sal_False ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTmp = pObj->IsUnoObj() ? "UNO" : "Drw"; +/*N*/ rStr << aTmp; +/*N*/ } +/*N*/ if( i < nCnt - 1 ) +/*N*/ rStr << endl << rSp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else if( pFrm->GetDrawObjs() ) +/*N*/ { +/*N*/ MSHORT nCnt = pFrm->GetDrawObjs()->Count(); +/*N*/ if( nCnt ) +/*N*/ { +/*N*/ for( MSHORT i=0; i < nCnt; ++i ) +/*N*/ { +/*N*/ SdrObject *pObj = (*pFrm->GetDrawObjs())[ i ]; +/*N*/ if( pObj->IsWriterFlyFrame() ) +/*N*/ { +/*N*/ SwFlyFrm *pFly = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm(); +/*N*/ lcl_OutFrame( rStr, pFly, rSp, sal_False ); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ aTmp = pObj->IsUnoObj() ? "UNO" : "Drw"; +/*N*/ rStr << aTmp; +/*N*/ } +/*N*/ if( i < nCnt - 1 ) +/*N*/ rStr << endl << rSp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ if( nSpc ) +/*N*/ rSp.Erase( rSp.Len() - nSpc ); +/*N*/ if( bNxt && pFrm->GetNext() ) +/*N*/ { +/*N*/ do +/*N*/ { +/*N*/ pFrm = pFrm->GetNext(); +/*N*/ rStr << endl << rSp; +/*N*/ lcl_OutFrame( rStr, pFrm, rSp, sal_False ); +/*N*/ } while ( pFrm->GetNext() ); +/*N*/ } +/*N*/ } + +/*N*/ #ifdef USED +/*N*/ IsFtnContFrm() +/*N*/ IsFtnFrm() +/*N*/ #endif + +/*N*/ void LayOutPut( const SwFrm* pFrm ) +/*N*/ { +/*N*/ #ifndef MAC +/*N*/ static char *pOutName = 0; +/*N*/ const sal_Bool bFirstOpen = pOutName ? sal_False : sal_True; +/*N*/ if( bFirstOpen ) +/*N*/ { +/*N*/ char *pPath = getenv( "TEMP" ); +/*N*/ char *pName = "layout.txt"; +/*N*/ if( !pPath ) +/*N*/ pOutName = pName; +/*N*/ else +/*N*/ { +/*N*/ const int nLen = strlen(pPath); +/*N*/ // fuer dieses new wird es kein delete geben. +/*N*/ pOutName = new char[nLen + strlen(pName) + 3]; +/*N*/ if(nLen && (pPath[nLen-1] == '\\') || (pPath[nLen-1] == '/')) +/*N*/ snprintf( pOutName, sizeof(pOutName), "%s%s", pPath, pName ); +/*N*/ else +/*N*/ snprintf( pOutName, sizeof(pOutName), "%s/%s", pPath, pName ); +/*N*/ } +/*N*/ } +/*N*/ SvFileStream aStream( pOutName, (bFirstOpen +/*N*/ ? STREAM_WRITE | STREAM_TRUNC +/*N*/ : STREAM_WRITE )); +/*N*/ +/*N*/ if( !aStream.GetError() ) +/*N*/ { +/*N*/ if ( bFirstOpen ) +/*N*/ aStream << "Layout-Struktur"; +/*N*/ else +/*N*/ aStream.Seek( STREAM_SEEK_TO_END ); +/*N*/ aStream << endl; +/*N*/ aStream << "---------------------------------------------" << endl; +/*N*/ XubString aSpace; +/*N*/ lcl_OutFrame( aStream, pFrm, aSpace, sal_False ); +/*N*/ } +/*N*/ #endif +/*N*/ } +} //namespace binfilter +/*N*/ #endif +namespace binfilter {//STRIP009 +/*N*/ SvStream &operator<<( SvStream &rOs, const SwpHints &rHints ) //$ ostream +/*N*/ { +/*N*/ rOs << " {HINTS:"; +/*N*/ #ifdef JP_NEWCORE +/*N*/ for( MSHORT i = 0; i < rHints.GetSize(); ++i) +/*N*/ { +/*N*/ SwTxtHint *pHint = (SwTxtHint*) rHints[i]; +/*N*/ +/*N*/ if(0 != GetCharWidth(pHint)) +/*N*/ rOs << "CHARWIDTH" << ' '; // << GetCharWidth(pHint)->frCPI; +/*N*/ else if(0 != GetColor(pHint)) +/*N*/ rOs << "COLOR" << ' ' ; // << GetColor(pHint)->aColor; +/*N*/ else if(0 != GetCrossedOut(pHint)) +/*N*/ rOs << "CROSSEDOUT" << ' ' << (MSHORT)(GetCrossedOut(pHint)->nState); +/*N*/ else if(0 != GetAttrFont(pHint)) +/*N*/ rOs << "ATTRFONT" << ' ' << +/*N*/ (const char *)(GetAttrFont(pHint)->sFamilyName) << ',' << +/*N*/ ((MSHORT) GetAttrFont(pHint)->eFamily); +/*N*/ else if(0 != GetPosture(pHint)) +/*N*/ rOs << "POSTURE" << ' ' << GetPosture(pHint)->nPosture; +/*N*/ else if(0 != GetFontSize(pHint)) +/*N*/ rOs << "FONTSIZE" << ' ' << GetFontSize(pHint)->nSize; +/*N*/ else if(0 != GetUnderline(pHint)) +/*N*/ rOs << "UNDERLINE" << ' ' << (MSHORT)(GetUnderline(pHint)->nState); +/*N*/ else if(0 != GetWeight(pHint)) +/*N*/ rOs << "WEIGHT" << ' ' << GetWeight(pHint)->nWeight; +/*N*/ else if(0 != GetContour(pHint)) +/*N*/ rOs << "CONTOUR" << ' ' << GetContour(pHint)->nState; +/*N*/ else if(0 != GetShadowed(pHint)) +/*N*/ rOs << "SHADOWED" << ' ' << GetShadowed(pHint)->nState; +/*N*/ else if(0 != GetAutoKern(pHint)) +/*N*/ rOs << "AUTOKERN" << ' ' << GetAutoKern(pHint)->nState; +/*N*/ else if(0 != GetWordLineMode(pHint)) +/*N*/ rOs << "WORDLINEMODE" << ' ' << GetWordLineMode(pHint)->nState; +/*N*/ else +/*N*/ rOs << pHint->Which(); +/*N*/ +/*N*/ rOs << ',' << pHint->GetStart()->GetIndex() +/*N*/ << '-' +/*N*/ << (pHint->GetEnd() ? pHint->GetEnd()->GetIndex() : STRING_LEN) +/*N*/ << "\n"; +/*N*/ } +/*N*/ #endif +/*N*/ // JP_NEWCORE +/*N*/ +/*N*/ rOs << '}'; +/*N*/ return rOs; +/*N*/ } + +/************************************************************************* + * IsDbg() + *************************************************************************/ + +/*N*/ sal_Bool IsDbg( const SwTxtFrm *pFrm ) +/*N*/ { +/*N*/ if( pFrm && pFrm->GetShell() ) +/*N*/ return pFrm->GetShell()->GetViewOptions()->IsTest4(); +/*N*/ else +/*N*/ return sal_False; +/*N*/ } +} //namespace binfilter + +/*N*/ #if OSL_DEBUG_LEVEL < 2 +namespace binfilter {//STRIP009 +/*N*/ static void Error() +/*N*/ { +/*N*/ // wegen PM und BCC +/*N*/ sal_Bool bFalse = sal_False; +/*N*/ ASSERT( bFalse, "txtio: No debug version" ); +/*N*/ } + +#define IMPL_OUTOP(class) \ + SvStream &class::operator<<( SvStream &rOs ) const /*$ostream*/\ + { \ + Error(); \ + return rOs; \ + } + +/*N*/ IMPL_OUTOP( SwTxtPortion ) +/*N*/ IMPL_OUTOP( SwLinePortion ) +/*N*/ IMPL_OUTOP( SwBreakPortion ) +/*N*/ IMPL_OUTOP( SwGluePortion ) +/*N*/ IMPL_OUTOP( SwFldPortion ) +/*N*/ IMPL_OUTOP( SwHiddenPortion ) +/*N*/ IMPL_OUTOP( SwHyphPortion ) +/*N*/ IMPL_OUTOP( SwFixPortion ) +/*N*/ IMPL_OUTOP( SwFlyPortion ) +/*N*/ IMPL_OUTOP( SwFlyCntPortion ) +/*N*/ IMPL_OUTOP( SwMarginPortion ) +/*N*/ IMPL_OUTOP( SwNumberPortion ) +/*N*/ IMPL_OUTOP( SwBulletPortion ) +/*N*/ IMPL_OUTOP( SwGrfNumPortion ) +/*N*/ IMPL_OUTOP( SwLineLayout ) +/*N*/ IMPL_OUTOP( SwParaPortion ) +/*N*/ IMPL_OUTOP( SwFtnPortion ) +/*N*/ IMPL_OUTOP( SwFtnNumPortion ) +/*N*/ IMPL_OUTOP( SwHyphStrPortion ) +/*N*/ IMPL_OUTOP( SwExpandPortion ) +/*N*/ IMPL_OUTOP( SwBlankPortion ) +/*N*/ IMPL_OUTOP( SwToxPortion ) +/*N*/ IMPL_OUTOP( SwRefPortion ) +/*N*/ IMPL_OUTOP( SwIsoToxPortion ) +/*N*/ IMPL_OUTOP( SwIsoRefPortion ) +/*N*/ IMPL_OUTOP( SwSoftHyphPortion ) +/*N*/ IMPL_OUTOP( SwTabPortion ) +/*N*/ IMPL_OUTOP( SwTabLeftPortion ) +/*N*/ IMPL_OUTOP( SwTabRightPortion ) +/*N*/ IMPL_OUTOP( SwTabCenterPortion ) +/*N*/ IMPL_OUTOP( SwTabDecimalPortion ) +/*N*/ IMPL_OUTOP( SwPostItsPortion ) +/*N*/ IMPL_OUTOP( SwQuoVadisPortion ) +/*N*/ IMPL_OUTOP( SwErgoSumPortion ) +/*N*/ IMPL_OUTOP( SwHolePortion ) +/*N*/ IMPL_OUTOP( SwDropPortion ) +/*N*/ IMPL_OUTOP( SwKernPortion ) +/*N*/ IMPL_OUTOP( SwArrowPortion ) +/*N*/ IMPL_OUTOP( SwMultiPortion ) + +/*N*/ const char *GetPortionName( const MSHORT nType ) +/*N*/ { +/*N*/ return 0; +/*N*/ } + +/*N*/ const char *GetPrepName( const PrepareHint ePrep ) +/*N*/ { +/*N*/ return 0; +/*N*/ } + +/*N*/ void SwLineLayout::DebugPortions( SvStream &rOs, const XubString &rTxt, //$ ostream +/*N*/ const xub_StrLen nStart ) +/*N*/ { +/*N*/ } + +/*N*/ const char *GetLangName( const MSHORT nLang ) +/*N*/ { +/*N*/ return 0; +/*N*/ } +} //namespace binfilter +#else +# include <limits.h> +# include <stdlib.h> +# include "swtypes.hxx" // ZTCCONST +# include "swfont.hxx" // SwDropPortion +namespace binfilter {//STRIP009 +/*N*/ CONSTCHAR( pClose, "} " ); + +/************************************************************************* + * GetPortionName() + *************************************************************************/ + +/*N*/ CONSTCHAR( pPOR_LIN, "LIN" ); +/*N*/ CONSTCHAR( pPOR_TXT, "TXT" ); +/*N*/ CONSTCHAR( pPOR_SHADOW, "SHADOW" ); +/*N*/ CONSTCHAR( pPOR_TAB, "TAB" ); +/*N*/ CONSTCHAR( pPOR_TABLEFT, "TABLEFT" ); +/*N*/ CONSTCHAR( pPOR_TABRIGHT, "TABRIGHT" ); +/*N*/ CONSTCHAR( pPOR_TABCENTER, "TABCENTER" ); +/*N*/ CONSTCHAR( pPOR_TABDECIMAL, "TABDECIMAL" ); +/*N*/ CONSTCHAR( pPOR_EXP, "EXP" ); +/*N*/ CONSTCHAR( pPOR_HYPH, "HYPH" ); +/*N*/ CONSTCHAR( pPOR_HYPHSTR, "HYPHSTR" ); +/*N*/ CONSTCHAR( pPOR_FLD, "FLD" ); +/*N*/ CONSTCHAR( pPOR_FIX, "FIX" ); +/*N*/ CONSTCHAR( pPOR_FLY, "FLY" ); +/*N*/ CONSTCHAR( pPOR_FLYCNT, "FLYCNT" ); +/*N*/ CONSTCHAR( pPOR_MARGIN, "MARGIN" ); +/*N*/ CONSTCHAR( pPOR_GLUE, "GLUE" ); +/*N*/ CONSTCHAR( pPOR_HOLE, "HOLE" ); +/*N*/ CONSTCHAR( pPOR_END, "END" ); +/*N*/ CONSTCHAR( pPOR_BRK, "BRK" ); +/*N*/ CONSTCHAR( pPOR_LAY, "LAY" ); +/*N*/ CONSTCHAR( pPOR_BLANK, "BLANK" ); +/*N*/ CONSTCHAR( pPOR_FTN, "FTN" ); +/*N*/ CONSTCHAR( pPOR_FTNNUM, "FTNNUM" ); +/*N*/ CONSTCHAR( pPOR_POSTITS, "POSTITS" ); +/*N*/ CONSTCHAR( pPOR_SOFTHYPH, "SOFTHYPH" ); +/*N*/ CONSTCHAR( pPOR_SOFTHYPHSTR, "SOFTHYPHSTR" ); +/*N*/ CONSTCHAR( pPOR_TOX, "TOX" ); +/*N*/ CONSTCHAR( pPOR_REF, "REF" ); +/*N*/ +/*N*/ CONSTCHAR( pPOR_ISOTOX, "ISOTOX" ); +/*N*/ CONSTCHAR( pPOR_ISOREF, "ISOREF" ); +/*N*/ CONSTCHAR( pPOR_HIDDEN, "Hidden" ); +/*N*/ CONSTCHAR( pPOR_QUOVADIS, "QuoVadis" ); +/*N*/ CONSTCHAR( pPOR_ERGOSUM, "ErgoSum" ); +/*N*/ CONSTCHAR( pPOR_NUMBER, "NUMBER" ); +/*N*/ CONSTCHAR( pPOR_BULLET, "BULLET" ); +/*N*/ CONSTCHAR( pPOR_UNKW, "UNKW" ); +/*N*/ CONSTCHAR( pPOR_PAR, "PAR" ); + +/*N*/ const char *GetPortionName( const MSHORT nType ) +/*N*/ { +/*N*/ #ifdef USED +/*N*/ // Kurz und schmerzlos: +/*N*/ const char *ppNameArr[PORTYPE_END] = { +/*N*/ pPOR_LIN, pPOR_TXT, pPOR_HOLE, pPOR_SHADOW, +/*N*/ pPOR_TAB, pPOR_TABLEFT, pPOR_TABRIGHT, pPOR_TABCENTER, pPOR_TABDECIMAL, +/*N*/ pPOR_EXP, pPOR_HYPH, pPOR_HYPHSTR, pPOR_FLD, +/*N*/ pPOR_FIX, pPOR_FLY, pPOR_FLYCNT, pPOR_MARGIN, +/*N*/ pPOR_GLUE, pPOR_END, pPOR_BRK, pPOR_LAY, +/*N*/ pPOR_BLANK, pPOR_FTN, pPOR_FTNNUM, +/*N*/ pPOR_POSTITS, pPOR_SOFTHYPH, pPOR_SOFTHYPHSTR, +/*N*/ pPOR_TOX, pPOR_REF, pPOR_ISOTOX, pPOR_ISOREF, +/*N*/ pPOR_HIDDEN, pPOR_QUOVADIS, pPOR_ERGOSUM, +/*N*/ pPOR_NUMBER, pPOR_BULLET, pPOR_UNKW, pPOR_PAR +/*N*/ }; +/*N*/ ASSERT( eType < PORTYPE_END, "GetPortionName: bad type" ); +/*N*/ return( ppNameArr[eType] ); +/*N*/ #else +/*N*/ return 0; +/*N*/ #endif +/*N*/ } + +/*N*/ CONSTCHAR( pPREP_CLEAR, "CLEAR" ); +/*N*/ CONSTCHAR( pPREP_WIDOWS_ORPHANS, "WIDOWS_ORPHANS" ); +/*N*/ CONSTCHAR( pPREP_FIXSIZE_CHG, "FIXSIZE_CHG" ); +/*N*/ CONSTCHAR( pPREP_FOLLOW_FOLLOWS, "FOLLOW_FOLLOWS" ); +/*N*/ CONSTCHAR( pPREP_ADJUST_FRM, "ADJUST_FRM" ); +/*N*/ CONSTCHAR( pPREP_FREE_SPACE, "FREE_SPACE" ); +/*N*/ CONSTCHAR( pPREP_FLY_CHGD, "FLY_CHGD" ); +/*N*/ CONSTCHAR( pPREP_FLY_ATTR_CHG, "FLY_ATTR_CHG" ); +/*N*/ CONSTCHAR( pPREP_FLY_ARRIVE, "FLY_ARRIVE" ); +/*N*/ CONSTCHAR( pPREP_FLY_LEAVE, "FLY_LEAVE" ); +/*N*/ CONSTCHAR( pPREP_VIEWOPT, "VIEWOPT" ); +/*N*/ CONSTCHAR( pPREP_FTN, "FTN" ); +/*N*/ CONSTCHAR( pPREP_POS_CHGD, "POS" ); +/*N*/ CONSTCHAR( pPREP_UL_SPACE, "UL_SPACE" ); +/*N*/ CONSTCHAR( pPREP_MUST_FIT, "MUST_FIT" ); +/*N*/ CONSTCHAR( pPREP_WIDOWS, "ORPHANS" ); +/*N*/ CONSTCHAR( pPREP_QUOVADIS, "QUOVADIS" ); +/*N*/ CONSTCHAR( pPREP_PAGE, "PAGE" ); + +/*N*/ const char *GetPrepName( const PrepareHint ePrep ) +/*N*/ { +/*N*/ // Kurz und schmerzlos: +/*N*/ const char *ppNameArr[PREP_END] = +/*N*/ { +/*N*/ pPREP_CLEAR, pPREP_WIDOWS_ORPHANS, pPREP_FIXSIZE_CHG, +/*N*/ pPREP_FOLLOW_FOLLOWS, pPREP_ADJUST_FRM, pPREP_FREE_SPACE, +/*N*/ pPREP_FLY_CHGD, pPREP_FLY_ATTR_CHG, pPREP_FLY_ARRIVE, +/*N*/ pPREP_FLY_LEAVE, pPREP_VIEWOPT, pPREP_FTN, pPREP_POS_CHGD, +/*N*/ pPREP_UL_SPACE, pPREP_MUST_FIT, pPREP_WIDOWS, pPREP_QUOVADIS, +/*N*/ pPREP_PAGE +/*N*/ }; +/*N*/ ASSERT( ePrep < PREP_END, "GetPrepName: unknown PrepareHint" ); +/*N*/ return( ppNameArr[ePrep] ); +/*N*/ } + +/************************************************************************* + * SwLineLayout::DebugPortions() + * + * DebugPortion() iteriert ueber alle Portions einer Zeile und deckt die + * internen Strukturen auf. + * Im Gegensatz zum Ausgabe-Operator werden auch die Textteile ausgegeben. + *************************************************************************/ + +/*N*/ void SwLineLayout::DebugPortions( SvStream &rOs, const XubString &rTxt, //$ ostream +/*N*/ const xub_StrLen nStart ) +/*N*/ { +/*N*/ SwLinePortion *pPortion = GetPortion(); +/*N*/ +/*N*/ xub_StrLen nPos = 0; +/*N*/ MSHORT nNr = 0; +/*N*/ KSHORT nPrtWidth, nLastPrt; +/*N*/ nPrtWidth = nLastPrt = 0; +/*N*/ +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << '\"' << endl; +/*N*/ +/*N*/ while( pPortion ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ SwTxtPortion *pTxtPor = pPortion->InTxtGrp() ? +/*N*/ (SwTxtPortion *)pPortion : NULL ; +/*N*/ ++nNr; +/*N*/ nLastPrt = nPrtWidth; +/*N*/ nPrtWidth += pPortion->PrtWidth(); +/*N*/ rOs << "\tNr:" << nNr +/*N*/ << " Pos:" << nPos +/*N*/ << " Org:" << nLastPrt +/*N*/ << endl; +/*N*/ +/*N*/ rOs << "\t"; +/*N*/ pPortion->operator<<( rOs ); +/*N*/ rOs << endl; +/*N*/ nPos += pPortion->GetLen(); +/*N*/ pPortion = pPortion->GetPortion(); +/*N*/ } +/*N*/ } + +/*N*/ #ifdef USED +/*N*/ CONSTCHAR( pRES_LNG_ALBANIAN, "ALBANIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_ARABIC, "ARABIC" ); +/*N*/ CONSTCHAR( pRES_LNG_AUS_ENGLISH, "AUS_ENGLISH" ); +/*N*/ CONSTCHAR( pRES_LNG_BAHASA, "BAHASA" ); +/*N*/ CONSTCHAR( pRES_LNG_BELGIAN_DUTCH, "BELGIAN_DUTCH" ); +/*N*/ CONSTCHAR( pRES_LNG_BELGIAN_FRENCH, "BELGIAN_FRENCH" ); +/*N*/ CONSTCHAR( pRES_LNG_BRAZIL_PORT, "BRAZIL_PORT" ); +/*N*/ CONSTCHAR( pRES_LNG_BULGARIAN, "BULGARIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_CANADA_FRENCH, "CANADA_FRENCH" ); +/*N*/ CONSTCHAR( pRES_LNG_CAST_SPANISH, "CAST_SPANISH" ); +/*N*/ CONSTCHAR( pRES_LNG_CATALAN, "CATALAN" ); +/*N*/ CONSTCHAR( pRES_LNG_CROATO_SERBIAN, "CROATO_SERBIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_CZECH, "CZECH" ); +/*N*/ CONSTCHAR( pRES_LNG_DANISH, "DANISH" ); +/*N*/ CONSTCHAR( pRES_LNG_DUTCH, "DUTCH" ); +/*N*/ CONSTCHAR( pRES_LNG_FINNISH, "FINNISH" ); +/*N*/ CONSTCHAR( pRES_LNG_FRENCH, "FRENCH" ); +/*N*/ CONSTCHAR( pRES_LNG_GERMAN, "GERMAN" ); +/*N*/ CONSTCHAR( pRES_LNG_GREEK, "GREEK" ); +/*N*/ CONSTCHAR( pRES_LNG_HEBREW, "HEBREW" ); +/*N*/ CONSTCHAR( pRES_LNG_HUNGARIAN, "HUNGARIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_ICELANDIC, "ICELANDIC" ); +/*N*/ CONSTCHAR( pRES_LNG_ITALIAN, "ITALIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_JAPANESE, "JAPANESE" ); +/*N*/ CONSTCHAR( pRES_LNG_KOREAN, "KOREAN" ); +/*N*/ CONSTCHAR( pRES_LNG_MEXICAN_SPANISH, "MEXICAN_SPANISH" ); +/*N*/ CONSTCHAR( pRES_LNG_NORWEG_BOKMAL, "NORWEG_BOKMAL" ); +/*N*/ CONSTCHAR( pRES_LNG_NORWEG_NYNORSK, "NORWEG_NYNORSK" ); +/*N*/ CONSTCHAR( pRES_LNG_POLISH, "POLISH" ); +/*N*/ CONSTCHAR( pRES_LNG_PORTUGUESE, "PORTUGUESE" ); +/*N*/ CONSTCHAR( pRES_LNG_RHAETO_ROMANIC, "RHAETO_ROMANIC" ); +/*N*/ CONSTCHAR( pRES_LNG_ROMANIAN, "ROMANIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_RUSSIAN, "RUSSIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_SERBO_CROATIAN, "SERBO_CROATIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_SIM_CHINESE, "SIM_CHINESE" ); +/*N*/ CONSTCHAR( pRES_LNG_SLOVAKIAN, "SLOVAKIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_SWEDISH, "SWEDISH" ); +/*N*/ CONSTCHAR( pRES_LNG_SWISS_FRENCH, "SWISS_FRENCH" ); +/*N*/ CONSTCHAR( pRES_LNG_SWISS_GERMAN, "SWISS_GERMAN" ); +/*N*/ CONSTCHAR( pRES_LNG_SWISS_ITALIAN, "SWISS_ITALIAN" ); +/*N*/ CONSTCHAR( pRES_LNG_THAI, "THAI" ); +/*N*/ CONSTCHAR( pRES_LNG_TRD_CHINESE, "TRD_CHINESE" ); +/*N*/ CONSTCHAR( pRES_LNG_TURKISH, "TURKISH" ); +/*N*/ CONSTCHAR( pRES_LNG_UK_ENGLISH, "UK_ENGLISH" ); +/*N*/ CONSTCHAR( pRES_LNG_URDU, "URDU" ); +/*N*/ CONSTCHAR( pRES_LNG_US_ENGLISH, "US_ENGLISH" ); +/*N*/ CONSTCHAR( pRES_LNG_NOLANGUAGE, "NOLANGUAGE" ); +/*N*/ +/*N*/ const char *GetLangName( const MSHORT nLang ) +/*N*/ { +/*N*/ switch( nLang ) +/*N*/ { +/*N*/ case 0x041c : return pRES_LNG_ALBANIAN; +/*N*/ case 0x0401 : return pRES_LNG_ARABIC; +/*N*/ case 0x0c09 : return pRES_LNG_AUS_ENGLISH; +/*N*/ case 0x0421 : return pRES_LNG_BAHASA; +/*N*/ case 0x0813 : return pRES_LNG_BELGIAN_DUTCH; +/*N*/ case 0x080c : return pRES_LNG_BELGIAN_FRENCH; +/*N*/ case 0x0416 : return pRES_LNG_BRAZIL_PORT; +/*N*/ case 0x0402 : return pRES_LNG_BULGARIAN; +/*N*/ case 0x0c0c : return pRES_LNG_CANADA_FRENCH; +/*N*/ case 0x040a : return pRES_LNG_CAST_SPANISH; +/*N*/ case 0x0403 : return pRES_LNG_CATALAN; +/*N*/ case 0x041a : return pRES_LNG_CROATO_SERBIAN; +/*N*/ case 0x0405 : return pRES_LNG_CZECH; +/*N*/ case 0x0406 : return pRES_LNG_DANISH; +/*N*/ case 0x0413 : return pRES_LNG_DUTCH; +/*N*/ case 0x040b : return pRES_LNG_FINNISH; +/*N*/ case 0x040c : return pRES_LNG_FRENCH; +/*N*/ case 0x0407 : return pRES_LNG_GERMAN; +/*N*/ case 0x0408 : return pRES_LNG_GREEK; +/*N*/ case 0x040d : return pRES_LNG_HEBREW; +/*N*/ case 0x040e : return pRES_LNG_HUNGARIAN; +/*N*/ case 0x040f : return pRES_LNG_ICELANDIC; +/*N*/ case 0x0410 : return pRES_LNG_ITALIAN; +/*N*/ case 0x0411 : return pRES_LNG_JAPANESE; +/*N*/ case 0x0412 : return pRES_LNG_KOREAN; +/*N*/ case 0x080a : return pRES_LNG_MEXICAN_SPANISH; +/*N*/ case 0x0414 : return pRES_LNG_NORWEG_BOKMAL; +/*N*/ case 0x0814 : return pRES_LNG_NORWEG_NYNORSK; +/*N*/ case 0x0415 : return pRES_LNG_POLISH; +/*N*/ case 0x0816 : return pRES_LNG_PORTUGUESE; +/*N*/ case 0x0417 : return pRES_LNG_RHAETO_ROMANIC; +/*N*/ case 0x0418 : return pRES_LNG_ROMANIAN; +/*N*/ case 0x0419 : return pRES_LNG_RUSSIAN; +/*N*/ case 0x081a : return pRES_LNG_SERBO_CROATIAN; +/*N*/ case 0x0804 : return pRES_LNG_SIM_CHINESE; +/*N*/ case 0x041b : return pRES_LNG_SLOVAKIAN; +/*N*/ case 0x041d : return pRES_LNG_SWEDISH; +/*N*/ case 0x100c : return pRES_LNG_SWISS_FRENCH; +/*N*/ case 0x0807 : return pRES_LNG_SWISS_GERMAN; +/*N*/ case 0x0810 : return pRES_LNG_SWISS_ITALIAN; +/*N*/ case 0x041e : return pRES_LNG_THAI; +/*N*/ case 0x0404 : return pRES_LNG_TRD_CHINESE; +/*N*/ case 0x041f : return pRES_LNG_TURKISH; +/*N*/ case 0x0809 : return pRES_LNG_UK_ENGLISH; +/*N*/ case 0x0420 : return pRES_LNG_URDU; +/*N*/ case 0x0409 : return pRES_LNG_US_ENGLISH; +/*N*/ default : return pRES_LNG_NOLANGUAGE; +/*N*/ } +/*N*/ } +/*N*/ #else +/*N*/ +/*N*/ const char *GetLangName( const MSHORT nLang ) +/*N*/ { +/*N*/ return "???"; +/*N*/ } +/*N*/ #endif +/*N*/ +/*N*/ SvStream &SwLinePortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ rOs << " {"; +/*N*/ rOs << "L:" << nLineLength; +/*N*/ rOs << " H:" << Height(); +/*N*/ rOs << " W:" << PrtWidth(); +/*N*/ rOs << " A:" << nAscent; +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTxtPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TXT:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwBreakPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {BREAK:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwKernPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {KERN:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwArrowPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {ARROW:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwMultiPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {MULTI:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwLineLayout::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {LINE:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ SwLinePortion *pPos = GetPortion(); +/*N*/ while( pPos ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ rOs << "\t"; +/*N*/ pPos->operator<<( rOs ); +/*N*/ pPos = pPos->GetPortion(); +/*N*/ } +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwGluePortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {GLUE:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << " F:" << GetFixWidth(); +/*N*/ rOs << " G:" << GetPrtGlue(); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFixPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FIX:" ); +/*N*/ rOs << pTxt; +/*N*/ SwGluePortion::operator<<( rOs ); +/*N*/ rOs << " Fix:" << nFix; +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFlyPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FLY:" ); +/*N*/ rOs << pTxt; +/*N*/ SwFixPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwMarginPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {MAR:" ); +/*N*/ rOs << pTxt; +/*N*/ SwGluePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFlyCntPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FLYCNT:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ if( bDraw ) +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {DRAWINCNT" ); +/*N*/ rOs << pTxt; +/*N*/ rOs << pClose; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FRM:" ); +/*N*/ rOs << pTxt; +/*N*/ rOs << " {FRM:" << GetFlyFrm()->Frm() << pClose; +/*N*/ rOs << " {PRT:" << GetFlyFrm()->Prt() << pClose; +/*N*/ rOs << pClose; +/*N*/ } +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwExpandPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {EXP:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFtnPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FTN:" ); +/*N*/ rOs << pTxt; +/*N*/ SwExpandPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFtnNumPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FTNNUM:" ); +/*N*/ rOs << pTxt; +/*N*/ SwNumberPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwNumberPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {NUMBER:" ); +/*N*/ rOs << pTxt; +/*N*/ SwExpandPortion::operator<<( rOs ); +/*N*/ rOs << " Exp:\"" << '\"'; +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwBulletPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {BULLET:" ); +/*N*/ rOs << pTxt; +/*N*/ SwNumberPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwGrfNumPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {GRFNUM:" ); +/*N*/ rOs << pTxt; +/*N*/ SwGrfNumPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwHiddenPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {Hidden:" ); +/*N*/ rOs << pTxt; +/*N*/ SwFldPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwToxPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TOX:" ); +/*N*/ rOs << pTxt; +/*N*/ SwTxtPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwRefPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {Ref:" ); +/*N*/ rOs << pTxt; +/*N*/ SwTxtPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwIsoToxPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {ISOTOX:" ); +/*N*/ rOs << pTxt; +/*N*/ SwToxPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwIsoRefPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {ISOREF:" ); +/*N*/ rOs << pTxt; +/*N*/ SwRefPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwHyphPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {HYPH:" ); +/*N*/ rOs << pTxt; +/*N*/ SwExpandPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwHyphStrPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {HYPHSTR:" ); +/*N*/ rOs << pTxt; +/*N*/ SwExpandPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwSoftHyphPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {SOFTHYPH:" ); +/*N*/ rOs << pTxt; +/*N*/ SwHyphPortion::operator<<( rOs ); +/*N*/ rOs << (IsExpand() ? " on" : " off"); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwBlankPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {BLANK:" ); +/*N*/ rOs << pTxt; +/*N*/ SwExpandPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwFldPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {FLD:" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ if( IsFollow() ) +/*N*/ rOs << " F!"; +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwPostItsPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {POSTITS" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTabPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TAB" ); +/*N*/ rOs << pTxt; +/*N*/ SwFixPortion::operator<<( rOs ); +/*N*/ rOs << " T:" << nTabPos; +/*N*/ if( IsFilled() ) +/*N*/ rOs << " \"" << cFill << '\"'; +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTabLeftPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TABLEFT" ); +/*N*/ rOs << pTxt; +/*N*/ SwTabPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTabRightPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TABRIGHT" ); +/*N*/ rOs << pTxt; +/*N*/ SwTabPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTabCenterPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TABCENTER" ); +/*N*/ rOs << pTxt; +/*N*/ SwTabPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwTabDecimalPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {TABDECIMAL" ); +/*N*/ rOs << pTxt; +/*N*/ SwTabPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwParaPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {PAR" ); +/*N*/ rOs << pTxt; +/*N*/ SwLineLayout::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwHolePortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {HOLE" ); +/*N*/ rOs << pTxt; +/*N*/ SwLinePortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwQuoVadisPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {QUOVADIS" ); +/*N*/ rOs << pTxt; +/*N*/ SwFldPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwErgoSumPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {ERGOSUM" ); +/*N*/ rOs << pTxt; +/*N*/ SwFldPortion::operator<<( rOs ); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &operator<<( SvStream &rOs, const SwTxtSizeInfo &rInf ) //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {SIZEINFO:" ); +/*N*/ rOs << pTxt; +/*N*/ rOs << ' ' << (rInf.OnWin() ? "WIN:" : "PRT:" ); +/*N*/ rOs << " Idx:" << rInf.GetIdx(); +/*N*/ rOs << " Len:" << rInf.GetLen(); +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +/*N*/ +/*N*/ SvStream &SwDropPortion::operator<<( SvStream &rOs ) const //$ ostream +/*N*/ { +/*N*/ CONSTCHAR( pTxt, " {DROP:" ); +/*N*/ rOs << pTxt; +/*N*/ SwTxtPortion::operator<<( rOs ); +/*N*/ if( pPart && nDropHeight ) +/*N*/ { +/*N*/ rOs << " H:" << nDropHeight; +/*N*/ rOs << " L:" << nLines; +/*N*/ rOs <<" Fnt:" << pPart->GetFont().GetHeight(); +/*N*/ if( nX || nY ) +/*N*/ rOs << " [" << nX << '/' << nY << ']'; +/*N*/ } +/*N*/ rOs << pClose; +/*N*/ return rOs; +/*N*/ } +} //namespace binfilter +/*N*/ #endif /* OSL_DEBUG_LEVEL */ + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_txttab.cxx b/binfilter/bf_sw/source/core/text/sw_txttab.cxx new file mode 100644 index 000000000000..fba2b5ab74d4 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_txttab.cxx @@ -0,0 +1,418 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "hintids.hxx" + +#include <bf_svx/lrspitem.hxx> +#include <bf_svx/tstpitem.hxx> + +#include <frmatr.hxx> + +#include "txtcfg.hxx" +#include "portab.hxx" +#include "itrform2.hxx" +namespace binfilter { + + +/************************************************************************* + * SwLineInfo::GetTabStop() + *************************************************************************/ + +/* Die Werte in SvxTabStop::nTabPos liegen immer relativ zum linken PrtRand + * vor. Tabs, die im Bereich des Erstzeileneinzugs liegen, sind also negativ. + * nLeft ist der linke PrtRand + * nRight ist der rechte PrtRand + * nLinePos die aktuelle Position. + * Es wird der erste Tabstop returnt, der groesser ist als nLinePos. + */ + + + +/*N*/ const SvxTabStop *SwLineInfo::GetTabStop( const SwTwips nLinePos, +/*N*/ const SwTwips nLeft, const SwTwips nRight ) const +/*N*/ { +/*N*/ // Mit den KSHORTs aufpassen, falls nLinePos < nLeft +/*N*/ SwTwips nPos = nLinePos; +/*N*/ nPos -= nLeft; +/*N*/ for( MSHORT i = 0; i < pRuler->Count(); ++i ) +/*N*/ { +/*N*/ const SvxTabStop &rTabStop = pRuler->operator[](i); +/*N*/ if( rTabStop.GetTabPos() > SwTwips(nRight) ) +/*N*/ { +/*N*/ if ( i ) +/*N*/ return 0; +/*N*/ else +/*N*/ return &rTabStop; +/*N*/ } +/*N*/ if( rTabStop.GetTabPos() > nPos ) +/*N*/ return &rTabStop; +/*N*/ } +/*N*/ return 0; +/*N*/ } + +/************************************************************************* + * SwTxtFormatter::NewTabPortion() + *************************************************************************/ + + + +/*N*/ SwTabPortion *SwTxtFormatter::NewTabPortion( SwTxtFormatInfo &rInf ) const +/*N*/ { +/*N*/ SwTabPortion *pTabPor; +/*N*/ SwTabPortion *pLastTab = rInf.GetLastTab(); +/*N*/ if( pLastTab && pLastTab->IsTabCntPortion() ) +/*N*/ if( pLastTab->PostFormat( rInf ) ) +/*N*/ return 0; +/*N*/ +/*N*/ // Wir suchen den naechsten Tab. Wenn gerade ein rechts-Tab unterwegs +/*N*/ // ist, so koennen wir uns nicht auf rInf.X() beziehen. +/*N*/ KSHORT nTabPos = rInf.GetLastTab() ? rInf.GetLastTab()->GetTabPos() : 0; +/*N*/ if( nTabPos < rInf.X() ) +/*N*/ nTabPos = rInf.X(); +/*N*/ +/*N*/ xub_Unicode cFill, cDec; +/*N*/ SvxTabAdjust eAdj; +/*N*/ +/*N*/ KSHORT nNewTabPos; +/*N*/ { + /* + nPos ist der Offset in der Zeile. + Die Tabulatoren haben ihren 0-Punkt bei Frm().Left(). + Die Zeilen beginnen ab Frm.Left() + Prt.Left(). + In dieser Methode wird zwischen beiden Koordinatensystemen + konvertiert (vgl. rInf.GetTabPos). + */ +/*N*/ const SwTwips nTabLeft = pFrm->Frm().Left() + +/*N*/ ( pFrm->IsRightToLeft() ? +/*N*/ pFrm->GetAttrSet()->GetLRSpace().GetRight() : +/*N*/ pFrm->GetAttrSet()->GetLRSpace().GetTxtLeft() ); +/*N*/ +/*N*/ const SwTwips nLinePos = GetLeftMargin(); +/*N*/ const SwTwips nLineTab = nLinePos + nTabPos; +/*N*/ SwTwips nRight = Right(); +/*N*/ +/*N*/ if ( pFrm->IsVertical() ) +/*N*/ { +/*N*/ Point aRightTop( nRight, pFrm->Frm().Top() ); +/*N*/ pFrm->SwitchHorizontalToVertical( aRightTop ); +/*N*/ nRight = aRightTop.Y(); +/*N*/ } +/*N*/ +/*N*/ SwTwips nNextPos; +/*N*/ const SvxTabStop* pTabStop = +/*N*/ aLineInf.GetTabStop( nLineTab, nTabLeft, nRight ); +/*N*/ if( pTabStop ) +/*N*/ { +/*N*/ cFill = ' ' != pTabStop->GetFill() ? pTabStop->GetFill() : 0; +/*N*/ cDec = pTabStop->GetDecimal(); +/*N*/ eAdj = pTabStop->GetAdjustment(); +/*N*/ nNextPos = pTabStop->GetTabPos(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ KSHORT nDefTabDist = aLineInf.GetDefTabStop(); +/*N*/ if( KSHRT_MAX == nDefTabDist ) +/*N*/ { +/*N*/ const SvxTabStopItem& rTab = +/*N*/ (const SvxTabStopItem &)pFrm->GetAttrSet()-> +/*N*/ GetPool()->GetDefaultItem( RES_PARATR_TABSTOP ); +/*N*/ if( rTab.Count() ) +/*N*/ nDefTabDist = (KSHORT)rTab.GetStart()->GetTabPos(); +/*N*/ else +/*N*/ nDefTabDist = SVX_TAB_DEFDIST; +/*N*/ aLineInf.SetDefTabStop( nDefTabDist ); +/*N*/ } +/*N*/ SwTwips nCount = nLineTab; +/*N*/ nCount -= nTabLeft; +/*N*/ // Bei negativen Werten rundet "/" auf, "%" liefert negative Reste, +/*N*/ // bei positiven Werten rundet "/" ab, "%" liefert positvie Reste! +/*N*/ KSHORT nPlus = nCount < 0 ? 0 : 1; +/*N*/ nCount /= nDefTabDist; +/*N*/ nNextPos = ( nCount + nPlus ) * nDefTabDist ; +/*N*/ if( nNextPos + nTabLeft <= nLineTab + 50 ) +/*N*/ nNextPos += nDefTabDist; +/*N*/ cFill = 0; +/*N*/ eAdj = SVX_TAB_ADJUST_LEFT; +/*N*/ } +/*N*/ long nForced = 0; +/*N*/ if( pCurr->HasForcedLeftMargin() ) +/*N*/ { +/*?*/ SwLinePortion* pPor = pCurr->GetPortion(); +/*?*/ while( pPor && !pPor->IsFlyPortion() ) +/*?*/ pPor = pPor->GetPortion(); +/*?*/ if( pPor ) +/*?*/ nForced = pPor->Width(); +/*N*/ } +/*N*/ if( nTabLeft + nForced > nLineTab && nNextPos > 0 ) +/*N*/ { +/*N*/ eAdj = SVX_TAB_ADJUST_DEFAULT; +/*N*/ cFill = 0; +/*N*/ nNextPos = nForced; +/*N*/ } +/*N*/ nNextPos += nTabLeft; +/*N*/ nNextPos -= nLinePos; +/*N*/ ASSERT( nNextPos >= 0, "GetTabStop: Don't go back!" ); +/*N*/ nNewTabPos = KSHORT(nNextPos); +/*N*/ } +/*N*/ +/*N*/ switch( eAdj ) +/*N*/ { +/*N*/ case SVX_TAB_ADJUST_RIGHT : +/*N*/ { +/*N*/ pTabPor = new SwTabRightPortion( nNewTabPos, cFill ); +/*N*/ break; +/*N*/ } +/*N*/ case SVX_TAB_ADJUST_CENTER : +/*N*/ { +/*N*/ pTabPor = new SwTabCenterPortion( nNewTabPos, cFill ); +/*N*/ break; +/*N*/ } +/*N*/ case SVX_TAB_ADJUST_DECIMAL : +/*N*/ { +/*?*/ pTabPor = new SwTabDecimalPortion( nNewTabPos, cDec, cFill ); +/*?*/ break; +/*N*/ } +/*N*/ default: +/*N*/ { +/*N*/ ASSERT( SVX_TAB_ADJUST_LEFT == eAdj || SVX_TAB_ADJUST_DEFAULT == eAdj, +/*N*/ "+SwTxtFormatter::NewTabPortion: unknown adjustment" ); +/*N*/ pTabPor = new SwTabLeftPortion( nNewTabPos, cFill ); +/*N*/ break; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Vorhandensein von Tabulatoren anzeigen ... ist nicht mehr noetig +/*N*/ // pCurr->SetTabulation(); +/*N*/ // Aus Sicherheitsgruenden lassen wir uns die Daten errechnen +/*N*/ // pTabPor->Height( pLast->Height() ); +/*N*/ // pTabPor->SetAscent( pLast->GetAscent() ); +/*N*/ return pTabPor; +/*N*/ } + +/************************************************************************* + * SwTabPortion::SwTabPortion() + *************************************************************************/ + +// Die Basisklasse wird erstmal ohne alles initialisiert. + + +/*N*/ SwTabPortion::SwTabPortion( const KSHORT nTabPos, const xub_Unicode cFill ) +/*N*/ : SwFixPortion( 0, 0 ), nTabPos(nTabPos), cFill(cFill) +/*N*/ { +/*N*/ nLineLength = 1; +/*N*/ #ifdef DBG_UTIL +/*N*/ if( IsFilled() ) +/*N*/ { +/*N*/ ASSERT( ' ' != cFill, "SwTabPortion::CTOR: blanks ?!" ); +/*N*/ } +/*N*/ #endif +/*N*/ SetWhichPor( POR_TAB ); +/*N*/ } + +/************************************************************************* + * virtual SwTabPortion::Format() + *************************************************************************/ + + + +/*N*/ sal_Bool SwTabPortion::Format( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ SwTabPortion *pLastTab = rInf.GetLastTab(); +/*N*/ if( pLastTab == this ) +/*?*/ return PostFormat( rInf ); +/*N*/ if( pLastTab ) +/*?*/ pLastTab->PostFormat( rInf ); +/*N*/ return PreFormat( rInf ); +/*N*/ } + +/************************************************************************* + * virtual SwTabPortion::FormatEOL() + *************************************************************************/ + + + +/*N*/ void SwTabPortion::FormatEOL( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ if( rInf.GetLastTab() == this && !IsTabLeftPortion() ) +/*N*/ PostFormat( rInf ); +/*N*/ } + +/************************************************************************* + * SwTabPortion::PreFormat() + *************************************************************************/ + + + +/*M*/ sal_Bool SwTabPortion::PreFormat( SwTxtFormatInfo &rInf ) +/*M*/ { +/*M*/ ASSERT( rInf.X() <= GetTabPos(), "SwTabPortion::PreFormat: rush hour" ); +/*M*/ +/*M*/ // Hier lassen wir uns nieder... +/*M*/ Fix( rInf.X() ); +/*M*/ +/*M*/ // Die Mindestbreite eines Tabs ist immer mindestens ein Blank +/*M*/ { +/*M*/ XubString aTmp( ' ' ); +/*M*/ SwTxtSizeInfo aInf( rInf, aTmp ); +/*M*/ PrtWidth( aInf.GetTxtSize().Width() ); +/*M*/ } +/*M*/ +/*M*/ // 8532: CenterTabs, deren Blankbreite nicht mehr in die Zeile passt +/*M*/ sal_Bool bFull = rInf.Width() <= rInf.X() + PrtWidth(); +/*M*/ +/*M*/ // #95477# Rotated tab stops get the width of one blank +/*N*/ const USHORT nDir = rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() ); +/*M*/ +/*M*/ if( ! bFull && 0 == nDir ) +/*M*/ { +/*M*/ const MSHORT nWhich = GetWhichPor(); +/*M*/ switch( nWhich ) +/*M*/ { +/*M*/ case POR_TABRIGHT: +/*M*/ case POR_TABDECIMAL: +/*M*/ case POR_TABCENTER: +/*M*/ { +/*M*/ if( POR_TABDECIMAL == nWhich ) +/*M*/ rInf.SetTabDecimal( +/*M*/ ((SwTabDecimalPortion*)this)->GetTabDecimal()); +/*M*/ rInf.SetLastTab( this ); +/*M*/ break; +/*M*/ } +/*M*/ case POR_TABLEFT: +/*M*/ { +/*M*/ PrtWidth( GetTabPos() - rInf.X() ); +/*M*/ bFull = rInf.Width() <= rInf.X() + PrtWidth(); +/*M*/ break; +/*M*/ } +/*M*/ default: ASSERT( !this, "SwTabPortion::PreFormat: unknown adjustment" ); +/*M*/ } +/*M*/ } +/*M*/ +/*M*/ if( bFull ) +/*M*/ { +/*M*/ // Wir muessen aufpassen, dass wir nicht endlos schleifen, +/*M*/ // wenn die Breite kleiner ist, als ein Blank ... +/*M*/ if( rInf.GetIdx() == rInf.GetLineStart() ) +/*M*/ { +/*M*/ PrtWidth( rInf.Width() - rInf.X() ); +/*M*/ SetFixWidth( PrtWidth() ); +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ Height( 0 ); +/*M*/ Width( 0 ); +/*M*/ SetLen( 0 ); +/*M*/ SetAscent( 0 ); +/*M*/ SetPortion( NULL ); //????? +/*M*/ } +/*M*/ return sal_True; +/*M*/ } +/*M*/ else +/*M*/ { +/*M*/ // Ein Kunstgriff mit Effekt: Die neuen Tabportions verhalten sich nun +/*M*/ // so, wie FlyFrms, die in der Zeile stehen - inklusive Adjustment ! +/*M*/ SetFixWidth( PrtWidth() ); +/*M*/ return sal_False; +/*M*/ } +/*M*/ } + +/************************************************************************* + * SwTabPortion::PostFormat() + *************************************************************************/ + + + +/*N*/ sal_Bool SwTabPortion::PostFormat( SwTxtFormatInfo &rInf ) +/*N*/ { +/*N*/ const KSHORT nRight = Min( GetTabPos(), rInf.Width() ); +/*N*/ const SwLinePortion *pPor = GetPortion(); +/*N*/ KSHORT nPorWidth = 0; +/*N*/ while( pPor ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ nPorWidth += pPor->Width(); +/*N*/ pPor = pPor->GetPortion(); +/*N*/ } +/*N*/ +/*N*/ const MSHORT nWhich = GetWhichPor(); +/*N*/ ASSERT( POR_TABLEFT != nWhich, "SwTabPortion::PostFormat: already formatted" ); +/*N*/ const KSHORT nDiffWidth = nRight - Fix(); +/*N*/ +/*N*/ if( POR_TABCENTER == nWhich ) +/*N*/ { +/*N*/ // zentrierte Tabs bereiten Probleme: +/*N*/ // Wir muessen den Anteil herausfinden, der noch auf die Zeile passt. +/*N*/ KSHORT nNewWidth = nPorWidth /2; +/*N*/ if( nNewWidth > rInf.Width() - nRight ) +/*?*/ nNewWidth = nPorWidth - (rInf.Width() - nRight); +/*N*/ nPorWidth = nNewWidth; +/*N*/ } +/*N*/ +/*N*/ if( nDiffWidth > nPorWidth ) +/*N*/ { +/*N*/ const KSHORT nOldWidth = GetFixWidth(); +/*N*/ const KSHORT nAdjDiff = nDiffWidth - nPorWidth; +/*N*/ if( nAdjDiff > GetFixWidth() ) +/*N*/ PrtWidth( nAdjDiff ); +/*N*/ // Nicht erschrecken: wir muessen rInf weiterschieben. +/*N*/ // Immerhin waren wir als Rechtstab bislang nur ein Blank breit. +/*N*/ // Da wir uns jetzt aufgespannt haben, muss der Differenzbetrag +/*N*/ // auf rInf.X() addiert werden ! +/*N*/ rInf.X( rInf.X() + PrtWidth() - nOldWidth ); +/*N*/ } +/*N*/ SetFixWidth( PrtWidth() ); +/*N*/ // letzte Werte zuruecksetzen +/*N*/ rInf.SetLastTab(0); +/*N*/ if( POR_TABDECIMAL == nWhich ) +/*?*/ rInf.SetTabDecimal(0); +/*N*/ +/*N*/ return rInf.Width() <= rInf.X(); +/*N*/ } + +/************************************************************************* + * virtual SwTabPortion::Paint() + * + * Ex: LineIter::DrawTab() + *************************************************************************/ + + + + +/************************************************************************* + * virtual SwTabPortion::HandlePortion() + *************************************************************************/ + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_widorp.cxx b/binfilter/bf_sw/source/core/text/sw_widorp.cxx new file mode 100644 index 000000000000..ef9e671688f2 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_widorp.cxx @@ -0,0 +1,537 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "ftnboss.hxx" +#include "paratr.hxx" +#ifdef DBG_UTIL +#endif + +#include <bf_svx/orphitem.hxx> +#include <bf_svx/widwitem.hxx> +#include <bf_svx/keepitem.hxx> +#include <bf_svx/spltitem.hxx> +#include <frmatr.hxx> +#include <txtftn.hxx> +#include <fmtftn.hxx> + +#include "txtcfg.hxx" +#include "widorp.hxx" +#include "sectfrm.hxx" //SwSectionFrm +#include "ftnfrm.hxx" +namespace binfilter { + +#undef WIDOWTWIPS + + +/************************************************************************* + * inline IsNastyFollow() + *************************************************************************/ +// Ein Follow, der auf der selben Seite steht, wie sein Master ist nasty. +/*N*/ inline sal_Bool IsNastyFollow( const SwTxtFrm *pFrm ) +/*N*/ { +/*N*/ ASSERT( !pFrm->IsFollow() || !pFrm->GetPrev() || +/*N*/ ((const SwTxtFrm*)pFrm->GetPrev())->GetFollow() == pFrm, +/*N*/ "IsNastyFollow: Was ist denn hier los?" ); +/*N*/ return pFrm->IsFollow() && pFrm->GetPrev(); +/*N*/ } + +/************************************************************************* + * SwTxtFrmBreak::SwTxtFrmBreak() + *************************************************************************/ + +/*N*/ SwTxtFrmBreak::SwTxtFrmBreak( SwTxtFrm *pFrm, const SwTwips nRst ) +/*N*/ : pFrm(pFrm), nRstHeight(nRst) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ SWRECTFN( pFrm ) +/*N*/ nOrigin = (pFrm->*fnRect->fnGetPrtTop)(); +/*N*/ SwSectionFrm* pSct; +/*N*/ bKeep = !pFrm->IsMoveable() || IsNastyFollow( pFrm ) || +/*N*/ ( pFrm->IsInSct() && (pSct=pFrm->FindSctFrm())->Lower()->IsColumnFrm() +/*N*/ && !pSct->MoveAllowed( pFrm ) ) || +/*N*/ !pFrm->GetTxtNode()->GetSwAttrSet().GetSplit().GetValue() || +/*N*/ pFrm->GetTxtNode()->GetSwAttrSet().GetKeep().GetValue(); +/*N*/ bBreak = sal_False; +/*N*/ +/*N*/ if( !nRstHeight && !pFrm->IsFollow() && pFrm->IsInFtn() && pFrm->HasPara() ) +/*N*/ { +/*N*/ nRstHeight = pFrm->GetFtnFrmHeight(); +/*N*/ nRstHeight += (pFrm->Prt().*fnRect->fnGetHeight)() - +/*N*/ (pFrm->Frm().*fnRect->fnGetHeight)(); +/*N*/ if( nRstHeight < 0 ) +/*N*/ nRstHeight = 0; +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( pFrm ) +/*N*/ } + +/* BP 18.6.93: Widows. + * Im Gegensatz zur ersten Implementierung werden die Widows nicht + * mehr vorausschauend berechnet, sondern erst beim Formatieren des + * gesplitteten Follows festgestellt. Im Master faellt die Widows- + * Berechnung also generell weg (nWidows wird manipuliert). + * Wenn der Follow feststellt, dass die Widowsregel zutrifft, + * verschickt er an seinen Vorgaenger ein Prepare. + * Ein besonderes Problem ergibt sich, wenn die Widows zuschlagen, + * aber im Master noch ein paar Zeilen zur Verfuegung stehen. + * + */ + +/************************************************************************* + * SwTxtFrmBreak::IsInside() + *************************************************************************/ + +/* BP(22.07.92): Berechnung von Witwen und Waisen. + * Die Methode liefert sal_True zurueck, wenn eine dieser Regelung zutrifft. + * + * Eine Schwierigkeit gibt es im Zusammenhang mit Widows und + * unterschiedlichen Formaten zwischen Master- und Folgeframes: + * Beispiel: Wenn die erste Spalte 3cm und die zweite 4cm breit ist + * und Widows auf sagen wir 3 gesetzt ist, so ist erst bei der Formatierung + * des Follows entscheidbar, ob die Widowsbedingung einhaltbar ist oder + * nicht. Leider ist davon abhaengig, ob der Absatz als Ganzes auf die + * naechste Seite rutscht. + */ + +/*N*/ sal_Bool SwTxtFrmBreak::IsInside( SwTxtMargin &rLine ) const +/*N*/ { +/*N*/ register sal_Bool bFit = sal_False; +/*N*/ +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ SWRECTFN( pFrm ) +/*N*/ // nOrigin is an absolut value, rLine referes to the swapped situation. +/*N*/ +/*N*/ SwTwips nTmpY; +/*N*/ if ( pFrm->IsVertical() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ nTmpY = pFrm->SwitchHorizontalToVertical( rLine.Y() + rLine.GetLineHeight() ); +/*N*/ else +/*N*/ nTmpY = rLine.Y() + rLine.GetLineHeight(); +/*N*/ +/*N*/ SwTwips nLineHeight = (*fnRect->fnYDiff)( nTmpY , nOrigin ); +/*N*/ +/*N*/ // 7455 und 6114: Raum fuer die Umrandung unten einkalkulieren. +/*N*/ nLineHeight += (pFrm->*fnRect->fnGetBottomMargin)(); +/*N*/ +/*N*/ +/*N*/ if( nRstHeight ) +/*N*/ bFit = nRstHeight >= nLineHeight; +/*N*/ else +/*N*/ { +/*N*/ // Der Frm besitzt eine Hoehe, mit der er auf die Seite passt. +/*N*/ SwTwips nHeight = +/*N*/ (*fnRect->fnYDiff)( (pFrm->GetUpper()->*fnRect->fnGetPrtBottom)(), nOrigin ); +/*N*/ +/*N*/ // Wenn sich alles innerhalb des bestehenden Frames abspielt, +/*N*/ // ist das Ergebnis sal_True; +/*N*/ bFit = nHeight >= nLineHeight; +/*N*/ if( !bFit ) +/*N*/ { +/*N*/ // Die LineHeight sprengt die aktuelle Frm-Hoehe. +/*N*/ // Nun rufen wir ein Probe-Grow, um zu ermitteln, ob der +/*N*/ // Frame um den gewuenschten Bereich wachsen wuerde. +/*N*/ nHeight += pFrm->GrowTst( LONG_MAX ); +/*N*/ +/*N*/ // Das Grow() returnt die Hoehe, um die der Upper des TxtFrm +/*N*/ // den TxtFrm wachsen lassen wuerde. +/*N*/ // Der TxtFrm selbst darf wachsen wie er will. +/*N*/ bFit = nHeight >= nLineHeight; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( pFrm ); +/*N*/ +/*N*/ return bFit; +/*N*/ } + +/************************************************************************* + * SwTxtFrmBreak::IsBreakNow() + *************************************************************************/ + +/*N*/ sal_Bool SwTxtFrmBreak::IsBreakNow( SwTxtMargin &rLine ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ +/*N*/ // bKeep ist staerker als IsBreakNow() +/*N*/ // Ist noch genug Platz ? +/*N*/ if( bKeep || IsInside( rLine ) ) +/*N*/ bBreak = sal_False; +/*N*/ else +/*N*/ { + /* Diese Klasse geht davon aus, dass der SwTxtMargin von Top nach Bottom + * durchgearbeitet wird. Aus Performancegruenden wird in folgenden + * Faellen der Laden fuer das weitere Aufspalten dicht gemacht: + * Wenn eine einzige Zeile nicht mehr passt. + * Sonderfall: bei DummyPortions ist LineNr == 1, obwohl wir splitten + * wollen. + */ +/*N*/ // 6010: DropLines mit einbeziehen +/*N*/ +/*N*/ sal_Bool bFirstLine = 1 == rLine.GetLineNr() && !rLine.GetPrev(); +/*N*/ bBreak = sal_True; +/*N*/ if( ( bFirstLine && pFrm->GetIndPrev() ) +/*N*/ || ( rLine.GetLineNr() <= rLine.GetDropLines() ) ) +/*N*/ { +/*N*/ bKeep = sal_True; +/*N*/ bBreak = sal_False; +/*N*/ } +/*N*/ else if(bFirstLine && pFrm->IsInFtn() && !pFrm->FindFtnFrm()->GetPrev()) +/*N*/ { +/*?*/ SwLayoutFrm* pTmp = pFrm->FindFtnBossFrm()->FindBodyCont(); +/*?*/ if( !pTmp || !pTmp->Lower() ) +/*?*/ bBreak = sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( pFrm ) +/*N*/ +/*N*/ return bBreak; +/*N*/ } + + +/*MA ehemals fuer COMPACT +// WouldFit() liefert sal_True, wenn der Absatz ganz oder teilweise passen wuerde + +sal_Bool SwTxtFrmBreak::WouldFit( SwTxtMargin &rLine ) +{ + rLine.Bottom(); + if( IsInside( rLine ) ) + return sal_True; + + rLine.Top(); + // Suche die erste Trennmoeglichkeit ... + while( !IsBreakNow( rLine ) ) + { + DBG_LOOP; + if( !rLine.NextLine() ) + return sal_False; + } + return sal_True; +} +*/ + +/************************************************************************* + * WidowsAndOrphans::WidowsAndOrphans() + *************************************************************************/ + +/*N*/ WidowsAndOrphans::WidowsAndOrphans( SwTxtFrm *pFrm, const SwTwips nRst, +/*N*/ sal_Bool bChkKeep ) +/*N*/ : SwTxtFrmBreak( pFrm, nRst ), nOrphLines( 0 ), nWidLines( 0 ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ SWRECTFN( pFrm ) +/*N*/ +/*N*/ if( bKeep ) +/*N*/ { +/*N*/ // 5652: bei Absaetzen, die zusammengehalten werden sollen und +/*N*/ // groesser sind als die Seite wird bKeep aufgehoben. +/*N*/ if( bChkKeep && !pFrm->GetPrev() && !pFrm->IsInFtn() && +/*N*/ pFrm->IsMoveable() && +/*N*/ ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) ) +/*N*/ bKeep = sal_False; +/*N*/ //Auch bei gesetztem Keep muessen Orphans beachtet werden, +/*N*/ //z.B. bei verketteten Rahmen erhaelt ein Follow im letzten Rahmen ein Keep, +/*N*/ //da er nicht (vorwaerts) Moveable ist, +/*N*/ //er darf aber trotzdem vom Master Zeilen anfordern wg. der Orphanregel. +/*N*/ if( pFrm->IsFollow() ) +/*N*/ nWidLines = pFrm->GetTxtNode()->GetSwAttrSet().GetWidows().GetValue(); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet(); +/*N*/ const SvxOrphansItem &rOrph = rSet.GetOrphans(); +/*N*/ if ( rOrph.GetValue() > 1 ) +/*N*/ nOrphLines = rOrph.GetValue(); +/*N*/ if ( pFrm->IsFollow() ) +/*N*/ nWidLines = rSet.GetWidows().GetValue(); +/*N*/ +/*N*/ } +/*N*/ if( pFrm->IsInFtn() && !pFrm->GetIndPrev() && +/*N*/ ( bKeep || nWidLines || nOrphLines ) ) +/*N*/ { +/*N*/ // Innerhalb von Fussnoten gibt es gute Gruende, das Keep-Attribut und +/*N*/ // die Widows/Orphans abzuschalten. +/*?*/ SwFtnFrm *pFtn = pFrm->FindFtnFrm(); +/*?*/ sal_Bool bFt = !pFtn->GetAttr()->GetFtn().IsEndNote(); +/*?*/ if( !pFtn->GetPrev() && +/*?*/ pFtn->FindFtnBossFrm( bFt ) != pFtn->GetRef()->FindFtnBossFrm( bFt ) +/*?*/ && ( !pFrm->IsInSct() || pFrm->FindSctFrm()->MoveAllowed(pFrm) ) ) +/*?*/ { +/*?*/ bKeep = sal_False; +/*?*/ nOrphLines = 0; +/*?*/ nWidLines = 0; +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ UNDO_SWAP( pFrm ) +/*N*/ } + +/************************************************************************* + * WidowsAndOrphans::FindBreak() + *************************************************************************/ + +/* Die Find*-Methoden suchen nicht nur, sondern stellen den SwTxtMargin auf + * die Zeile ein, wo der Absatz gebrochen werden soll und kuerzen ihn dort. + * FindBreak() + */ + +/*N*/ sal_Bool WidowsAndOrphans::FindBreak( SwTxtFrm *pFrame, SwTxtMargin &rLine, +/*N*/ sal_Bool bHasToFit ) +/*N*/ { +/*N*/ SWAP_IF_SWAPPED( pFrm ) +/*N*/ +/*N*/ sal_Bool bRet = sal_True; +/*N*/ MSHORT nOldOrphans = nOrphLines; +/*N*/ if( bHasToFit ) +/*N*/ nOrphLines = 0; +/*N*/ rLine.Bottom(); +/*N*/ if( !IsBreakNow( rLine ) ) +/*N*/ bRet = sal_False; +/*N*/ if( !FindWidows( pFrame, rLine ) ) +/*N*/ { +/*N*/ sal_Bool bBack = sal_False; +/*N*/ while( IsBreakNow( rLine ) ) +/*N*/ { +/*N*/ if( rLine.PrevLine() ) +/*N*/ bBack = sal_True; +/*N*/ else +/*N*/ break; +/*N*/ } +/*N*/ // Eigentlich werden bei HasToFit Schusterjungen (Orphans) nicht +/*N*/ // beruecksichtigt, wenn allerdings Dummy-Lines im Spiel sind und +/*N*/ // die Orphansregel verletzt wird, machen wir mal eine Ausnahme: +/*N*/ // Wir lassen einfach eine Dummyline zurueck und wandern mit dem Text +/*N*/ // komplett auf die naechste Seite/Spalte. +/*N*/ if( rLine.GetLineNr() <= nOldOrphans && +/*N*/ rLine.GetInfo().GetParaPortion()->IsDummy() && +/*N*/ ( ( bHasToFit && bRet ) || SwTxtFrmBreak::IsBreakNow( rLine ) ) ) +/*N*/ rLine.Top(); +/*N*/ +/*N*/ rLine.TruncLines( sal_True ); +/*N*/ bRet = bBack; +/*N*/ } +/*N*/ nOrphLines = nOldOrphans; +/*N*/ +/*N*/ UNDO_SWAP( pFrm ) +/*N*/ +/*N*/ return bRet; +/*N*/ } + +/************************************************************************* + * WidowsAndOrphans::FindWidows() + *************************************************************************/ + +/* FindWidows positioniert den SwTxtMargin des Masters auf die umzubrechende + * Zeile, indem der Follow formatiert und untersucht wird. + * Liefert sal_True zurueck, wenn die Widows-Regelung in Kraft tritt, + * d.h. der Absatz _zusammengehalten_ werden soll ! + */ + +/*N*/ sal_Bool WidowsAndOrphans::FindWidows( SwTxtFrm *pFrm, SwTxtMargin &rLine ) +/*N*/ { +/*N*/ ASSERT( ! pFrm->IsVertical() || ! pFrm->IsSwapped(), +/*N*/ "WidowsAndOrphans::FindWidows with swapped frame" ) +/*N*/ +/*N*/ if( !nWidLines || !pFrm->IsFollow() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ rLine.Bottom(); +/*N*/ +/*N*/ // Wir koennen noch was abzwacken +/*N*/ SwTxtFrm *pMaster = pFrm->FindMaster(); +/*N*/ ASSERT(pMaster, "+WidowsAndOrphans::FindWidows: Widows in a master?"); +/*N*/ if( !pMaster ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // 5156: Wenn die erste Zeile des Follows nicht passt, wird der Master +/*N*/ // wohl voll mit Dummies sein. In diesem Fall waere ein PREP_WIDOWS fatal. +/*N*/ if( pMaster->GetOfst() == pFrm->GetOfst() ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // Resthoehe des Masters +/*N*/ SWRECTFN( pFrm ) +/*N*/ +/*N*/ const SwTwips nDocPrtTop = (pFrm->*fnRect->fnGetPrtTop)(); +/*N*/ SwTwips nOldHeight; +/*N*/ SwTwips nTmpY = rLine.Y() + rLine.GetLineHeight(); +/*N*/ +/*N*/ if ( bVert ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ nTmpY = pFrm->SwitchHorizontalToVertical( nTmpY ); +/*N*/ } +/*N*/ else +/*N*/ nOldHeight = (pFrm->Prt().*fnRect->fnGetHeight)(); +/*N*/ +/*N*/ const SwTwips nChg = (*fnRect->fnYDiff)( nTmpY, nDocPrtTop + nOldHeight ); +/*N*/ +/*N*/ // Unterhalb der Widows-Schwelle... +/*N*/ if( rLine.GetLineNr() >= nWidLines ) +/*N*/ { +/*N*/ // 8575: Follow to Master I +/*N*/ // Wenn der Follow *waechst*, so besteht fuer den Master die Chance, +/*N*/ // Zeilen entgegenzunehmen, die er vor Kurzem gezwungen war an den +/*N*/ // Follow abzugeben: Prepare(Need); diese Abfrage unterhalb von nChg! +/*N*/ // (0W, 2O, 2M, 2F) + 1F = 3M, 2F +/*N*/ if( rLine.GetLineNr() > nWidLines && pFrm->IsJustWidow() ) +/*N*/ { +/*?*/ // Wenn der Master gelockt ist, so hat er vermutlich gerade erst +/*?*/ // eine Zeile an uns abgegeben, diese geben nicht zurueck, nur +/*?*/ // weil bei uns daraus mehrere geworden sind (z.B. durch Rahmen). +/*?*/ if( !pMaster->IsLocked() && pMaster->GetUpper() ) +/*?*/ { +/*?*/ const SwTwips nRstHeight = (pMaster->Frm().*fnRect->fnBottomDist) +/*?*/ ( (pMaster->GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*?*/ if ( nRstHeight >= +/*?*/ SwTwips(rLine.GetInfo().GetParaPortion()->Height() ) ) +/*?*/ { +/*?*/ pMaster->Prepare( PREP_ADJUST_FRM ); +/*?*/ pMaster->_InvalidateSize(); +/*?*/ pMaster->InvalidatePage(); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ pFrm->SetJustWidow( sal_False ); +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + + // 8575: Follow to Master II + // Wenn der Follow *schrumpft*, so besteht fuer den Master die Chance, + // den kompletten Orphan zu inhalieren. + // (0W, 2O, 2M, 1F) - 1F = 3M, 0F -> PREP_ADJUST_FRM + // (0W, 2O, 3M, 2F) - 1F = 2M, 2F -> PREP_WIDOWS + +/*N*/ if( 0 > nChg && !pMaster->IsLocked() && pMaster->GetUpper() ) +/*N*/ { +/*N*/ SwTwips nRstHeight = (pMaster->Frm().*fnRect->fnBottomDist) +/*N*/ ( (pMaster->GetUpper()->*fnRect->fnGetPrtBottom)() ); +/*N*/ if( nRstHeight >= SwTwips(rLine.GetInfo().GetParaPortion()->Height() ) ) +/*N*/ { +/*N*/ pMaster->Prepare( PREP_ADJUST_FRM ); +/*N*/ pMaster->_InvalidateSize(); +/*N*/ pMaster->InvalidatePage(); +/*N*/ pFrm->SetJustWidow( sal_False ); +/*N*/ return sal_False; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // Master to Follow +/*N*/ // Wenn der Follow nach seiner Formatierung weniger Zeilen enthaelt +/*N*/ // als Widows, so besteht noch die Chance, einige Zeilen des Masters +/*N*/ // abzuzwacken. Wenn dadurch die Orphans-Regel des Masters in Kraft +/*N*/ // tritt muss im CalcPrep() des Master-Frame der Frame so vergroessert +/*N*/ // werden, dass er nicht mehr auf seine urspruengliche Seite passt. +/*N*/ // Wenn er noch ein paar Zeilen entbehren kann, dann muss im CalcPrep() +/*N*/ // ein Shrink() erfolgen, der Follow mit dem Widows rutscht dann auf +/*N*/ // die Seite des Masters, haelt sich aber zusammen, so dass er (endlich) +/*N*/ // auf die naechste Seite rutscht. - So die Theorie! +/*N*/ +/*N*/ +/*N*/ // Wir fordern nur noch ein Zeile zur Zeit an, weil eine Zeile des Masters +/*N*/ // bei uns durchaus mehrere Zeilen ergeben koennten. +/*N*/ // Dafuer behaelt CalcFollow solange die Kontrolle, bis der Follow alle +/*N*/ // notwendigen Zeilen bekommen hat. +/*N*/ MSHORT nNeed = 1; // frueher: nWidLines - rLine.GetLineNr(); +/*N*/ +/*N*/ // Special case: Master cannot give lines to follow +/*N*/ if ( ! pMaster->GetIndPrev() && pMaster->GetThisLines() <= nNeed ) +/*N*/ return sal_False; +/*N*/ +/*N*/ pMaster->Prepare( PREP_WIDOWS, (void*)&nNeed ); +/*N*/ return sal_True; +/*N*/ } + +/************************************************************************* + * WidowsAndOrphans::WouldFit() + *************************************************************************/ + +/*N*/ sal_Bool WidowsAndOrphans::WouldFit( SwTxtMargin &rLine, SwTwips &rMaxHeight ) +/*N*/ { +/*N*/ // Here it does not matter, if pFrm is swapped or not. +/*N*/ // IsInside() takes care for itself +/*N*/ +/*N*/ // Wir erwarten, dass rLine auf der letzten Zeile steht!! +/*N*/ ASSERT( !rLine.GetNext(), "WouldFit: aLine::Bottom missed!" ); +/*N*/ MSHORT nLineCnt = rLine.GetLineNr(); +/*N*/ +/*N*/ // Erstmal die Orphansregel und den Initialenwunsch erfuellen ... +/*N*/ #ifndef USED +/*N*/ const MSHORT nMinLines = Max( GetOrphansLines(), rLine.GetDropLines() ); +/*N*/ #else +/*N*/ const MSHORT nMinLines = rLine.GetDropLines(); +/*N*/ #endif +/*N*/ if ( nLineCnt < nMinLines ) +/*N*/ return sal_False; +/*N*/ +/*N*/ rLine.Top(); +/*N*/ SwTwips nLineSum = rLine.GetLineHeight(); +/*N*/ +/*N*/ while( nMinLines > rLine.GetLineNr() ) +/*N*/ { +///*N*/ DBG_LOOP; +/*N*/ if( !rLine.NextLine() ) +/*N*/ return sal_False; +/*N*/ nLineSum += rLine.GetLineHeight(); +/*N*/ } +/*N*/ +/*N*/ // Wenn wir jetzt schon nicht mehr passen ... +/*N*/ if( !IsInside( rLine ) ) +/*N*/ return sal_False; +/*N*/ +/*N*/ // Jetzt noch die Widows-Regel ueberpruefen +/*N*/ if( !nWidLines && !pFrm->IsFollow() ) +/*N*/ { +/*N*/ // I.A. brauchen Widows nur ueberprueft werden, wenn wir ein Follow +/*N*/ // sind. Bei WouldFit muss aber auch fuer den Master die Regel ueber- +/*N*/ // prueft werden, weil wir ja gerade erst die Trennstelle ermitteln. +/*N*/ // Im Ctor von WidowsAndOrphans wurde nWidLines aber nur fuer Follows +/*N*/ // aus dem AttrSet ermittelt, deshalb holen wir es hier nach: +/*N*/ const SwAttrSet& rSet = pFrm->GetTxtNode()->GetSwAttrSet(); +/*N*/ nWidLines = rSet.GetWidows().GetValue(); +/*N*/ } +/*N*/ +/*N*/ // Sind nach Orphans/Initialen noch genug Zeilen fuer die Widows uebrig? +/*N*/ if( nLineCnt - nMinLines >= GetWidowsLines() ) +/*N*/ { +/*N*/ if( rMaxHeight >= nLineSum ) +/*N*/ { +/*N*/ rMaxHeight -= nLineSum; +/*N*/ return sal_True; +/*N*/ } +/*N*/ } +/*N*/ return sal_False; +/*N*/ } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/sw_wrong.cxx b/binfilter/bf_sw/source/core/text/sw_wrong.cxx new file mode 100644 index 000000000000..0a81cb9d46ad --- /dev/null +++ b/binfilter/bf_sw/source/core/text/sw_wrong.cxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include "wrong.hxx" +namespace binfilter { + +/************************************************************************* + * sal_Bool SwWrongList::InWrongWord() gibt den Anfang und die Laenge des Wortes + * zurueck, wenn es als falsch markiert ist. + *************************************************************************/ + +/************************************************************************* + * sal_Bool SwWrongList::Check() liefert den ersten falschen Bereich + *************************************************************************/ + +/************************************************************************* + * xub_StrLen SwWrongList::NextWrong() liefert die naechste Fehlerposition + *************************************************************************/ + + +/************************************************************************* + * xub_StrLen SwWrongList::LastWrong() liefert die letzte Fehlerposition + *************************************************************************/ + + +/************************************************************************* + * MSHORT SwWrongList::GetPos( xub_StrLen nValue ) + * sucht die erste Position im Array, die groessergleich nValue ist, + * dies kann natuerlich auch hinter dem letzten Element sein! + *************************************************************************/ + + +/************************************************************************* + * void SwWrongList::Invalidate() + *************************************************************************/ + +/*N*/ void SwWrongList::_Invalidate( xub_StrLen nBegin, xub_StrLen nEnd ) +/*N*/ { +/*N*/ if ( nBegin < GetBeginInv() ) +/*N*/ nBeginInvalid = nBegin; +/*N*/ if ( nEnd > GetEndInv() ) +/*N*/ nEndInvalid = nEnd; +/*N*/ } + +/************************************************************************* + * SwWrongList::Move( xub_StrLen nPos, long nDiff ) + * veraendert alle Positionen ab nPos um den angegebenen Wert, + * wird nach Einfuegen oder Loeschen von Buchstaben benoetigt. + *************************************************************************/ + + +/************************************************************************* + * SwWrongList::Clear()/( xub_StrLen nBegin, xub_StrLen nEnd ) + * loescht das Array im angegebenen Bereich + *************************************************************************/ + + + +/************************************************************************* + * SwWrongList::Fresh + * + * In this method the wrong list is updated, new wrong words are inserted, + * and by evaluating the postiztion of wrong words, we also know, which + * words are not wrong any longer and have to be removed. + * Note: Fresh has to be called at the end of the check of the invalid region, + * in order to find words, which are behind the last wrong word but not wrong + * any longer + *************************************************************************/ + +/*N*/ sal_Bool SwWrongList::InvalidateWrong( ) +/*N*/ { +/*N*/ if( Count() ) +/*N*/ { +/*N*/ xub_StrLen nFirst = WRPOS( 0 ); +/*N*/ xub_StrLen nLast = WRPOS( Count() - 1 ) + WRLEN( Count() - 1 ); +/*N*/ Invalidate( nFirst, nLast ); +/*N*/ return sal_True; +/*N*/ } +/*N*/ else +/*N*/ return sal_False; +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/txtcache.hxx b/binfilter/bf_sw/source/core/text/txtcache.hxx new file mode 100644 index 000000000000..c31c7a63cf25 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/txtcache.hxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TXTCACHE_HXX +#define _TXTCACHE_HXX + +#include <sal/types.h> + +#include <tools/mempool.hxx> +#include "swcache.hxx" +namespace binfilter { + +class SwParaPortion; +class SwTxtFrm; + +class SwTxtLine : public SwCacheObj +{ + SwParaPortion *pLine; + +public: + DECL_FIXEDMEMPOOL_NEWDEL(SwTxtLine) + + SwTxtLine( SwTxtFrm *pFrm, SwParaPortion *pNew = 0 ); + virtual ~SwTxtLine(); + + inline SwParaPortion *GetPara() { return pLine; } + inline const SwParaPortion *GetPara() const { return pLine; } + + inline void SetPara( SwParaPortion *pNew ) { pLine = pNew; } +}; + + +class SwTxtLineAccess : public SwCacheAccess +{ + +protected: + virtual SwCacheObj *NewObj(); + +public: + SwTxtLineAccess( const SwTxtFrm *pOwner ); + + SwParaPortion *GetPara(); + + inline SwTxtLine &GetTxtLine(); + + virtual sal_Bool IsAvailable() const; +}; + + +inline SwTxtLine &SwTxtLineAccess::GetTxtLine() +{ + return *((SwTxtLine*)Get()); +} + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/txtcfg.hxx b/binfilter/bf_sw/source/core/text/txtcfg.hxx new file mode 100644 index 000000000000..c98c876d4701 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/txtcfg.hxx @@ -0,0 +1,59 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TXTCFG_HXX +#define _TXTCFG_HXX + +//#if OSL_DEBUG_LEVEL > 1 +//// auto strip #include "dbgloop.hxx" // DBG_LOOP +//#else +//#ifdef DBG_LOOP //kann per precompiled hereinkommen +//#undef DBG_LOOP +//#undef DBG_LOOP_RESET +//#endif +//#define DBG_LOOP +//#define DBG_LOOP_RESET +//#endif +namespace binfilter { + +// Toleranzwert in der Formatierung und Textausgabe. +#define SLOPPY_TWIPS 5 + +#define CONSTCHAR( name, string ) static const sal_Char __FAR_DATA name[] = string + +// Allgemeines ... + +#ifndef CONST +#define CONST const +#endif + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/txtfly.hxx b/binfilter/bf_sw/source/core/text/txtfly.hxx new file mode 100644 index 000000000000..8783fe4f410d --- /dev/null +++ b/binfilter/bf_sw/source/core/text/txtfly.hxx @@ -0,0 +1,231 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TXTFLY_HXX +#define _TXTFLY_HXX + +#include <bf_svtools/svarray.hxx> + +#include "swtypes.hxx" +#include "swrect.hxx" +class OutputDevice; +class VirtualDevice; +class PolyPolygon; +class Color; +namespace binfilter { + + +class SwFont; +class SwCntntFrm; +class SwFlyFrm; +class SwPageFrm; +class SwTxtFly; +class SdrObject; +class SwWrongList; +class SwTxtPaintInfo; +class SwFmt; + +class TextRanger; + + +// eine kleine Schweinerei, weil enums nicht forward-deklariert werden koennen. +typedef MSHORT _FlyCntnt; + +SV_DECL_PTRARR( SwFlyList, SdrObject*, 10, 10 ) + +/************************************************************************* + * class SwFlyIter + *************************************************************************/ +enum PAGESIDE { LEFT_SIDE, RIGHT_SIDE, DONTKNOW_SIDE }; + +/************************************************************************* + * class SwContourCache + *************************************************************************/ + +class SwDrawTextInfo; +// Contour-Cache, globale Variable, in txtinit.cxx initialisiert/zerstoert +// und in txtfly.cxx benutzt bei Konturumfluss +class SwContourCache; +extern SwContourCache *pContourCache; + +#ifdef VERTICAL_LAYOUT +class SwTxtFrm; +#endif + +#define POLY_CNT 20 +#define POLY_MIN 5 +#define POLY_MAX 4000 + +class SwContourCache +{ + friend void ClrContourCache(); + const SdrObject *pSdrObj[ POLY_CNT ]; + TextRanger *pTextRanger[ POLY_CNT ]; + long nPntCnt; + MSHORT nObjCnt; +#ifdef VERTICAL_LAYOUT + const SwRect ContourRect( const SwFmt* pFmt, const SdrObject* pObj, + const SwTxtFrm* pFrm, const SwRect &rLine, const long nXPos, + const sal_Bool bRight ); +#else + const SwRect ContourRect( const SwFmt* pFmt, const SdrObject* pObj, + const SwRect &rLine, const long nXPos, const sal_Bool bRight ); +#endif + +public: + SwContourCache(); + ~SwContourCache(); + const SdrObject* GetObject( MSHORT nPos ){ return pSdrObj[ nPos ]; } + MSHORT GetCount() const { return nObjCnt; } + void ClrObject( MSHORT nPos ); +#ifdef VERTICAL_LAYOUT + static const SwRect CalcBoundRect( const SdrObject* pObj, + const SwRect &rLine, const SwTxtFrm* pFrm, const long nXPos, + const sal_Bool bRight ); +#else + static const SwRect CalcBoundRect( const SdrObject* pObj, + const SwRect &rLine, const long nXPos, const sal_Bool bRight ); +#endif +#ifdef DBG_UTIL +#endif +}; + +/************************************************************************* + * class SwTxtFly + *************************************************************************/ + +class SwTxtFly +{ + const SwPageFrm *pPage; + const SdrObject *pCurrFly; + +#ifdef VERTICAL_LAYOUT + const SwTxtFrm *pCurrFrm; +#else + const SwCntntFrm *pCurrFrm; +#endif + + const SwCntntFrm *pMaster; + SwFlyList *pFlyList; + + long nMinBottom; + long nNextTop; // Hier wird die Oberkante des "naechsten" Rahmens gespeichert + ULONG nIndex; + sal_Bool bOn : 1; + sal_Bool bLeftSide : 1; + sal_Bool bTopRule: 1; + sal_Bool mbIgnoreCurrentFrame: 1; + sal_Bool mbIgnoreContour: 1; + SwRect _GetFrm( const SwRect &rPortion, sal_Bool bTop ) const; + SwFlyList* InitFlyList(); + // iteriert ueber die Fly-Liste + sal_Bool ForEach( const SwRect &rRect, SwRect* pRect, sal_Bool bAvoid ) const; + _FlyCntnt CalcSmart( const SdrObject *pObj ) const; + // liefert die Order eines FlyFrms + _FlyCntnt GetOrder( const SdrObject *pObj ) const; + void CalcRightMargin( SwRect &rFly, MSHORT nPos, const SwRect &rLine ) const; + void CalcLeftMargin( SwRect &rFly, MSHORT nPos, const SwRect &rLine ) const; + MSHORT GetPos( const SdrObject *pObj ) const; + sal_Bool GetTop( const SdrObject *pNew, const sal_Bool bInFtn, + const sal_Bool bInFooterOrHeader ); + SwTwips CalcMinBottom() const; + const SwCntntFrm* _GetMaster(); + +public: + inline SwTxtFly() { mbIgnoreCurrentFrame = sal_False; + mbIgnoreCurrentFrame = sal_False; + pFlyList = 0; pMaster = 0; } + inline SwTxtFly( const SwTxtFrm *pFrm ) + { CtorInit( pFrm ); } + + SwTxtFly( const SwTxtFly& rTxtFly ); + inline ~SwTxtFly() { delete pFlyList; } +#ifdef VERTICAL_LAYOUT + void CtorInit( const SwTxtFrm *pFrm ); +#else + void CtorInit( const SwCntntFrm *pFrm ); +#endif + void SetTopRule(){ bTopRule = sal_False; } + + SwFlyList* GetFlyList() const + { return pFlyList ? pFlyList : ((SwTxtFly*)this)->InitFlyList(); } + inline SwRect GetFrm( const SwRect &rPortion, sal_Bool bTop = sal_True ) const; + inline sal_Bool IsOn() const { return bOn; } + inline sal_Bool Relax( const SwRect &rRect ); + inline sal_Bool Relax(); + inline SwTwips GetMinBottom() const + { return pFlyList ? nMinBottom : CalcMinBottom(); } + inline const SwCntntFrm* GetMaster() const + { return pMaster ? pMaster : ((SwTxtFly*)this)->_GetMaster(); } + inline long GetNextTop() const { return nNextTop; } + // Diese temporaere Variable darf auch in const-Methoden manipuliert werden + inline void SetNextTop( long nNew ) const + { ((SwTxtFly*)this)->nNextTop = nNew; } + + // Liefert zu einem SdrObject das von ihm _beanspruchte_ Rect + // (unter Beruecksichtigung der Order) zurueck. + SwRect FlyToRect( const SdrObject *pObj, const SwRect &rRect ) const; + + // Die Drawmethoden stellen sicher, dass ueberlappende Frames + // (ausser bei transparenten Frames) nicht uebergepinselt werden. + + + // Liefert zurueck, ob die Zeile von einem Frame ueberlappt wird. + sal_Bool IsAnyFrm( const SwRect &rLine ) const; + sal_Bool IsAnyFrm() const; + //Das Rechteck kann leer sein, es gilt dann der Frm. + sal_Bool IsAnyObj( const SwRect& ) const; + + void SetIgnoreCurrentFrame( sal_Bool bNew ) { mbIgnoreCurrentFrame = bNew; } + void SetIgnoreContour( sal_Bool bNew ) { mbIgnoreContour = bNew; } + +#ifdef DBG_UTIL +#endif +}; + +// Wenn in das rRect (meist die aktuelle Zeile) kein freifliegender +// Frame ragt, dann schalten wir uns ab. +// rRect ist dokumentglobal ! +inline sal_Bool SwTxtFly::Relax( const SwRect &rRect ) +{ + return 0 != (bOn = bOn && IsAnyFrm( rRect )); +} + +inline sal_Bool SwTxtFly::Relax() +{ + return 0 != (bOn = bOn && IsAnyFrm()); +} + +inline SwRect SwTxtFly::GetFrm( const SwRect &rRect, sal_Bool bTop ) const +{ + return bOn ? _GetFrm( rRect, bTop ) : SwRect(); +} + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/txtpaint.hxx b/binfilter/bf_sw/source/core/text/txtpaint.hxx new file mode 100644 index 000000000000..7c6c07503e29 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/txtpaint.hxx @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TXTPAINT_HXX +#define _TXTPAINT_HXX + +#include <vcl/outdev.hxx> + + +class SwRect; // SwSaveClip + +#ifdef VERTICAL_LAYOUT +#endif +namespace binfilter { + +/************************************************************************* + * class SwSaveClip + *************************************************************************/ + +class SwSaveClip +{ + Region aClip; + const sal_Bool bOn; + sal_Bool bChg; +protected: + OutputDevice *pOut; +public: + inline SwSaveClip( OutputDevice *pOut ); + inline ~SwSaveClip(); + void Reset(){DBG_BF_ASSERT(0, "STRIP");} ;//STRIP001 void Reset(); + inline sal_Bool IsOn() const { return bOn; } + inline sal_Bool IsChg() const { return bChg; } + inline sal_Bool IsOut() const { return 0 != pOut; } + inline OutputDevice *GetOut() { return pOut; } +}; + +inline SwSaveClip::SwSaveClip( OutputDevice *pOut ) : + pOut(pOut), + bOn( pOut && pOut->IsClipRegion() ), + bChg( sal_False ) +{} + +inline SwSaveClip::~SwSaveClip() +{ + Reset(); +} + +#ifdef DBG_UTIL + +/************************************************************************* + * class SwDbgOut + *************************************************************************/ + +class SwDbgOut +{ +protected: + OutputDevice *pOut; +public: + inline SwDbgOut( OutputDevice *pOutDev, const sal_Bool bOn = sal_True ); +}; + +/************************************************************************* + * class DbgPen + *************************************************************************/ + +//class DbgPen : public SwDbgOut +//{ +// Pen aPen; +//public: +// inline DbgPen( OutputDevice *pOutDev, const sal_Bool bOn = sal_True, +// const ColorName eColor = COL_BLACK ); +// inline ~DbgPen(); +//}; + +/************************************************************************* + * class DbgColor + *************************************************************************/ + +class DbgColor +{ + Font *pFnt; + Color aColor; +public: + inline DbgColor( Font *pFont, const sal_Bool bOn = sal_True, + const ColorData eColor = COL_BLUE ); + inline ~DbgColor(); +}; + +/************************************************************************* + * class DbgBrush + *************************************************************************/ + +class DbgBackColor : public SwDbgOut +{ + Color aOldFillColor; +public: + DbgBackColor( OutputDevice *pOut, const sal_Bool bOn = sal_True, + ColorData nColor = COL_YELLOW ); + ~DbgBackColor(); +}; + +/************************************************************************* + * class DbgRect + *************************************************************************/ + +class DbgRect : public SwDbgOut +{ +public: + DbgRect( OutputDevice *pOut, const Rectangle &rRect, + const sal_Bool bOn = sal_True, + ColorData eColor = COL_LIGHTBLUE ); +}; + +/************************************************************************* + * Inline-Implementierung + *************************************************************************/ + +inline SwDbgOut::SwDbgOut( OutputDevice *pOutDev, const sal_Bool bOn ) + :pOut( bOn ? pOutDev : 0 ) +{ } + +//inline DbgPen::DbgPen( OutputDevice *pOutDev, const sal_Bool bOn, +// const ColorName eColor ) +// : SwDbgOut( pOutDev, bOn) +//{ +// if( pOut ) +// { +// const Color aColor( eColor ); +// Pen aTmpPen( aColor ); +// aPen = pOut->GetPen( ); +// pOut->SetPen( aTmpPen ); +// } +//} + +//inline DbgPen::~DbgPen() +//{ +// if( pOut ) +// pOut->SetPen(aPen); +//} + +inline DbgColor::DbgColor( Font *pFont, const sal_Bool bOn, + const ColorData eColor ) + :pFnt( bOn ? pFont : 0 ) +{ + if( pFnt ) + { + aColor = pFnt->GetColor(); + pFnt->SetColor( Color( eColor ) ); + } +} + +inline DbgColor::~DbgColor() +{ + if( pFnt ) + pFnt->SetColor( aColor ); +} + +inline DbgBackColor::DbgBackColor( OutputDevice *pOutDev, const sal_Bool bOn, + ColorData eColor ) + :SwDbgOut( pOutDev, bOn ) +{ + if( pOut ) + { + aOldFillColor = pOut->GetFillColor(); + pOut->SetFillColor( Color(eColor) ); + } +} + +inline DbgBackColor::~DbgBackColor() +{ + if( pOut ) + { + pOut->SetFillColor( aOldFillColor ); + } +} + +inline DbgRect::DbgRect( OutputDevice *pOutDev, const Rectangle &rRect, + const sal_Bool bOn, + ColorData eColor ) + : SwDbgOut( pOutDev, bOn ) +{ + if( pOut ) + { + const Color aColor( eColor ); + Color aLineColor = pOut->GetLineColor(); + pOut->SetLineColor( aColor ); + Color aFillColor = pOut->GetFillColor(); + pOut->SetFillColor( Color(COL_TRANSPARENT) ); + pOut->DrawRect( rRect ); + pOut->SetLineColor( aLineColor ); + pOut->SetFillColor( aFillColor ); + } +} + +#endif + + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/binfilter/bf_sw/source/core/text/widorp.hxx b/binfilter/bf_sw/source/core/text/widorp.hxx new file mode 100644 index 000000000000..e8e2b66bc426 --- /dev/null +++ b/binfilter/bf_sw/source/core/text/widorp.hxx @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _WIDORP_HXX +#define _WIDORP_HXX + +class SwTxtFrm; + +#include "swtypes.hxx" +#include "itrtxt.hxx" +namespace binfilter { + +class SwTxtFrmBreak +{ +private: + SwTwips nRstHeight; +#ifdef VERTICAL_LAYOUT + SwTwips nOrigin; +#else + const SwTwips nOrigin; +#endif +protected: + SwTxtFrm *pFrm; + sal_Bool bBreak; + sal_Bool bKeep; +public: + SwTxtFrmBreak( SwTxtFrm *pFrm, const SwTwips nRst = 0 ); + sal_Bool IsBreakNow( SwTxtMargin &rLine ); + + sal_Bool IsBroken() const { return bBreak; } + sal_Bool IsKeepAlways() const { return bKeep; } + void Keep() { bKeep = sal_True; } + void Break() { bKeep = sal_False; bBreak = sal_True; } + + inline sal_Bool GetKeep() const { return bKeep; } + inline void SetKeep( const sal_Bool bNew ) { bKeep = bNew; } + + sal_Bool IsInside( SwTxtMargin &rLine ) const; + + // Um Sonderfaelle mit Ftn behandeln zu koennen. + // Mit SetRstHeight wird dem SwTxtFrmBreak die Resthoehe eingestellt, + // Um TruncLines() rufen zu koennen, ohne dass IsBreakNow() einen + // anderen Wert zurueckliefert. + // Es wird dabei davon ausgegangen, dass rLine auf der letzten Zeile + // steht, die nicht mehr passt. + +#ifdef VERTICAL_LAYOUT + void SetRstHeight( const SwTxtMargin &rLine ) + { + if ( pFrm->IsVertical() ) + {DBG_BF_ASSERT(0, "STRIP");} //STRIP001 nRstHeight = nOrigin - pFrm->SwitchHorizontalToVertical( rLine.Y() ); + else + nRstHeight = rLine.Y() - nOrigin; + } +#else + void SetRstHeight( const SwTxtMargin &rLine ) { nRstHeight = rLine.Y() - nOrigin; } +#endif + + SwTwips GetRstHeight() const { return nRstHeight; } +}; + +class WidowsAndOrphans : public SwTxtFrmBreak +{ +private: + MSHORT nWidLines, nOrphLines; + +public: + WidowsAndOrphans( SwTxtFrm *pFrm, const SwTwips nRst = 0, + sal_Bool bCheckKeep = sal_True ); + sal_Bool FindWidows( SwTxtFrm *pFrm, SwTxtMargin &rLine ); + MSHORT GetWidowsLines() const + { return nWidLines; } + MSHORT GetOrphansLines() const + { return nOrphLines; } + void ClrOrphLines(){ nOrphLines = 0; } + + sal_Bool FindBreak( SwTxtFrm *pFrm, SwTxtMargin &rLine, sal_Bool bHasToFit ); + sal_Bool WouldFit( SwTxtMargin &rLine, SwTwips &rMaxHeight ); + sal_Bool IsBreakNow( SwTxtMargin &rLine ) + { return ( rLine.GetLineNr() > nOrphLines ) && + SwTxtFrmBreak::IsBreakNow( rLine ); } +}; + + +} //namespace binfilter +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |