summaryrefslogtreecommitdiff
path: root/sw/source/core/text/inftxt.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/text/inftxt.cxx')
-rw-r--r--sw/source/core/text/inftxt.cxx1975
1 files changed, 1975 insertions, 0 deletions
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
new file mode 100644
index 000000000000..1fe2c363d70e
--- /dev/null
+++ b/sw/source/core/text/inftxt.cxx
@@ -0,0 +1,1975 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <com/sun/star/uno/Sequence.h>
+#include <unotools/linguprops.hxx>
+#include <unotools/lingucfg.hxx>
+#include <hintids.hxx>
+#include <sfx2/printer.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/splwrap.hxx>
+#include <editeng/pgrditem.hxx>
+// --> OD 2008-01-17 #newlistlevelattrs#
+#ifndef _SVX_TSTPITEM_HXX
+#include <editeng/tstpitem.hxx>
+#endif
+// <--
+
+#include <SwSmartTagMgr.hxx>
+#include <linguistic/lngprops.hxx>
+#include <editeng/unolingu.hxx>
+#include <breakit.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <txatbase.hxx>
+#include <fmtinfmt.hxx>
+#include <swmodule.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <viewsh.hxx> // ViewShell
+#include <viewopt.hxx> // SwViewOptions
+#include <frmtool.hxx> // DrawGraphic
+#include <IDocumentSettingAccess.hxx>
+#ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
+#include <IDocumentDeviceAccess.hxx>
+#endif
+#include <paratr.hxx> // SwFmtDrop
+#include <rootfrm.hxx> // SwRootFrm
+#include <inftxt.hxx> // SwTxtInfo
+#include <blink.hxx> // SwBlink
+#include <noteurl.hxx> // SwNoteURL
+#include <porftn.hxx> // SwFtnPortion
+#include <porrst.hxx> // SwHangingPortion
+#include <itratr.hxx>
+#include <accessibilityoptions.hxx>
+#include <wrong.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <SwGrammarMarkUp.hxx>
+#include <cstdio>
+// --> FME 2004-06-08 #i12836# enhanced pdf export
+#include <EnhancedPDFExportHelper.hxx>
+// <--
+
+#include <unomid.h>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+
+#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)
+
+#define DRAW_SPECIAL_OPTIONS_CENTER 1
+#define DRAW_SPECIAL_OPTIONS_ROTATE 2
+
+// --> OD 2006-06-27 #b6440955#
+// variable moved to class <numfunc:GetDefBulletConfig>
+//extern const sal_Char __FAR_DATA sBulletFntName[];
+namespace numfunc
+{
+ extern const String& GetDefBulletFontname();
+ extern bool IsDefBulletFontUserDefined();
+}
+// <--
+
+#ifdef DBG_UTIL
+// Test2: WYSIWYG++
+// Test4: WYSIWYG debug
+static sal_Bool bDbgLow = sal_False;
+#endif
+
+#ifdef DBG_UTIL
+
+sal_Bool SwTxtSizeInfo::IsOptCalm() const { return !GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptLow() const { return bDbgLow; }
+
+sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest1() const { return GetOpt().IsTest1(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest2() const { return GetOpt().IsTest2(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest3() const { return GetOpt().IsTest3(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest4() const { return GetOpt().IsTest4(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest5() const { return GetOpt().IsTest5(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest6() const { return GetOpt().IsTest6(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest7() const { return GetOpt().IsTest7(); }
+
+sal_Bool SwTxtSizeInfo::IsOptTest8() const { return GetOpt().IsTest8(); }
+
+#endif
+
+/*************************************************************************
+ * SwLineInfo::SwLineInfo()
+ *************************************************************************/
+
+// --> OD 2008-01-17 #newlistlevelattrs#
+SwLineInfo::SwLineInfo()
+ : pRuler( 0 ),
+ pSpace( 0 ),
+ nVertAlign( 0 ),
+ nDefTabStop( 0 ),
+ bListTabStopIncluded( false ),
+ nListTabStopPosition( 0 )
+{
+}
+
+SwLineInfo::~SwLineInfo()
+{
+ delete pRuler;
+}
+void SwLineInfo::CtorInitLineInfo( const SwAttrSet& rAttrSet,
+ const SwTxtNode& rTxtNode )
+// <--
+{
+ // --> OD 2008-01-17 #newlistlevelattrs#
+// pRuler = &rAttrSet.GetTabStops();
+ delete pRuler;
+ pRuler = new SvxTabStopItem( rAttrSet.GetTabStops() );
+ if ( rTxtNode.GetListTabStopPosition( nListTabStopPosition ) )
+ {
+ bListTabStopIncluded = true;
+
+ // insert the list tab stop into SvxTabItem instance <pRuler>
+ const SvxTabStop aListTabStop( nListTabStopPosition,
+ SVX_TAB_ADJUST_LEFT );
+ pRuler->Insert( aListTabStop );
+
+ // remove default tab stops, which are before the inserted list tab stop
+ for ( USHORT i = 0; i < pRuler->Count(); i++ )
+ {
+ if ( (*pRuler)[i].GetTabPos() < nListTabStopPosition &&
+ (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
+ {
+ pRuler->Remove(i);
+ continue;
+ }
+ }
+ }
+ // <--
+ // --> OD 2008-02-15 #newlistlevelattrs#
+ if ( !rTxtNode.getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
+ {
+ // remove default tab stop at position 0
+ for ( USHORT i = 0; i < pRuler->Count(); i++ )
+ {
+ if ( (*pRuler)[i].GetTabPos() == 0 &&
+ (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
+ {
+ pRuler->Remove(i);
+ break;
+ }
+ }
+ }
+ // <--
+ pSpace = &rAttrSet.GetLineSpacing();
+ nVertAlign = rAttrSet.GetParaVertAlign().GetValue();
+ nDefTabStop = MSHRT_MAX;
+}
+
+/*************************************************************************
+ * SwTxtInfo::CtorInitTxtInfo()
+ *************************************************************************/
+
+void SwTxtInfo::CtorInitTxtInfo( SwTxtFrm *pFrm )
+{
+ pPara = pFrm->GetPara();
+ nTxtStart = pFrm->GetOfst();
+ if( !pPara )
+ {
+ ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" );
+ pFrm->Format();
+ pPara = pFrm->GetPara();
+ }
+}
+
+SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf )
+ : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ),
+ nTxtStart( rInf.GetTxtStart() )
+{ }
+
+
+#ifdef DBG_UTIL
+/*************************************************************************
+ * ChkOutDev()
+ *************************************************************************/
+
+void ChkOutDev( const SwTxtSizeInfo &rInf )
+{
+ if ( !rInf.GetVsh() )
+ return;
+
+ const OutputDevice* pOut = rInf.GetOut();
+ const OutputDevice* pRef = rInf.GetRefDev();
+ ASSERT( pOut && pRef, "ChkOutDev: invalid output devices" )
+}
+#endif // PRODUCT
+
+
+inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf )
+{
+ const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen();
+ return Min( rInf.GetTxt().Len(), nInfLen );
+}
+
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew )
+ : SwTxtInfo( rNew ),
+ pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
+ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+ pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+ pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
+ pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+ pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
+ pFrm(rNew.pFrm),
+ pOpt(&rNew.GetOpt()),
+ pTxt(&rNew.GetTxt()),
+ nIdx(rNew.GetIdx()),
+ nLen(rNew.GetLen()),
+ nKanaIdx( rNew.GetKanaIdx() ),
+ bOnWin( rNew.OnWin() ),
+ bNotEOL( rNew.NotEOL() ),
+ bURLNotify( rNew.URLNotify() ),
+ bStopUnderFlow( rNew.StopUnderFlow() ),
+ bFtnInside( rNew.IsFtnInside() ),
+ bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ),
+ bMulti( rNew.IsMulti() ),
+ bFirstMulti( rNew.IsFirstMulti() ),
+ bRuby( rNew.IsRuby() ),
+ bHanging( rNew.IsHanging() ),
+ bScriptSpace( rNew.HasScriptSpace() ),
+ bForbiddenChars( rNew.HasForbiddenChars() ),
+ bSnapToGrid( rNew.SnapToGrid() ),
+ nDirection( rNew.GetDirection() )
+{
+#ifdef DBG_UTIL
+ ChkOutDev( *this );
+#endif
+}
+
+void SwTxtSizeInfo::CtorInitTxtSizeInfo( SwTxtFrm *pFrame, SwFont *pNewFnt,
+ const xub_StrLen nNewIdx, const xub_StrLen nNewLen )
+{
+ pKanaComp = NULL;
+ nKanaIdx = 0;
+ pFrm = pFrame;
+ CtorInitTxtInfo( pFrm );
+ const SwTxtNode *pNd = pFrm->GetTxtNode();
+ pVsh = pFrm->GetShell();
+
+ // Get the output and reference device
+ if ( pVsh )
+ {
+ pOut = pVsh->GetOut();
+ pRef = &pVsh->GetRefDev();
+ bOnWin = pVsh->GetWin() || OUTDEV_WINDOW == pOut->GetOutDevType();
+ }
+ else
+ {
+ //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
+ if ( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
+ {
+ //in Ermangelung eines Besseren kann hier ja wohl nur noch das
+ //AppWin genommen werden?
+ pOut = GetpApp()->GetDefaultDevice();
+ }
+ else
+ pOut = pNd->getIDocumentDeviceAccess()->getPrinter( false );
+
+ pRef = pOut;
+ }
+
+#ifdef DBG_UTIL
+ ChkOutDev( *this );
+#endif
+
+ // Set default layout mode ( LTR or RTL ).
+ if ( pFrm->IsRightToLeft() )
+ {
+ pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
+ pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
+ nDirection = DIR_RIGHT2LEFT;
+ }
+ else
+ {
+ pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
+ pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
+ nDirection = DIR_LEFT2RIGHT;
+ }
+
+/* LanguageType eLang;
+ const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
+ if ( SvtCTLOptions::NUMERALS_HINDI == rCTLOptions.GetCTLTextNumerals() )
+ eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
+ else if ( SvtCTLOptions::NUMERALS_ARABIC == rCTLOptions.GetCTLTextNumerals() )
+ eLang = LANGUAGE_ENGLISH;
+ else
+ eLang = (LanguageType)::GetAppLanguage();
+
+ pOut->SetDigitLanguage( eLang );
+ pRef->SetDigitLanguage( eLang );*/
+
+ //
+ // The Options
+ //
+ pOpt = pVsh ?
+ pVsh->GetViewOptions() :
+ SW_MOD()->GetViewOption( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) ); //Options vom Module wg. StarONE
+
+ // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet
+ // TODO: Aufdr?seln
+ bURLNotify = pNoteURL && !bOnWin;
+
+ SetSnapToGrid( pNd->GetSwAttrSet().GetParaGrid().GetValue() &&
+ pFrm->IsInDocBody() );
+
+ pFnt = pNewFnt;
+ pUnderFnt = 0;
+ pTxt = &pNd->GetTxt();
+
+ nIdx = nNewIdx;
+ nLen = nNewLen;
+ bNotEOL = sal_False;
+ bStopUnderFlow = bFtnInside = bOtherThanFtnInside = sal_False;
+ bMulti = bFirstMulti = bRuby = bHanging = bScriptSpace =
+ bForbiddenChars = sal_False;
+
+ SetLen( GetMinLen( *this ) );
+}
+
+SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt,
+ const xub_StrLen nIndex, const xub_StrLen nLength )
+ : SwTxtInfo( rNew ),
+ pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
+ pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
+ pOut(((SwTxtSizeInfo&)rNew).GetOut()),
+ pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
+ pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
+ pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
+ pFrm( rNew.pFrm ),
+ pOpt(&rNew.GetOpt()),
+ pTxt(&rTxt),
+ nIdx(nIndex),
+ nLen(nLength),
+ nKanaIdx( rNew.GetKanaIdx() ),
+ bOnWin( rNew.OnWin() ),
+ bNotEOL( rNew.NotEOL() ),
+ bURLNotify( rNew.URLNotify() ),
+ bStopUnderFlow( rNew.StopUnderFlow() ),
+ bFtnInside( rNew.IsFtnInside() ),
+ bOtherThanFtnInside( rNew.IsOtherThanFtnInside() ),
+ bMulti( rNew.IsMulti() ),
+ bFirstMulti( rNew.IsFirstMulti() ),
+ bRuby( rNew.IsRuby() ),
+ bHanging( rNew.IsHanging() ),
+ bScriptSpace( rNew.HasScriptSpace() ),
+ bForbiddenChars( rNew.HasForbiddenChars() ),
+ bSnapToGrid( rNew.SnapToGrid() ),
+ nDirection( rNew.GetDirection() )
+{
+#ifdef DBG_UTIL
+ ChkOutDev( *this );
+#endif
+ SetLen( GetMinLen( *this ) );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::SelectFont()
+ *************************************************************************/
+
+void SwTxtSizeInfo::SelectFont()
+{
+ // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet
+ // der FontMetricCache durcheinander. In diesem Fall steht pLastMet
+ // auf dem alten Wert.
+ // Falsch: GetOut()->SetFont( GetFont()->GetFnt() );
+ GetFont()->Invalidate();
+ GetFont()->ChgPhysFnt( pVsh, *GetOut() );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::NoteAnimation()
+ *************************************************************************/
+
+void SwTxtSizeInfo::NoteAnimation() const
+{
+ if( OnWin() )
+ SwRootFrm::FlushVout();
+
+ ASSERT( pOut == pVsh->GetOut(),
+ "SwTxtSizeInfo::NoteAnimation() changed pOut" )
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev,
+ const SwScriptInfo* pSI,
+ const XubString& rTxt,
+ const xub_StrLen nIndex,
+ const xub_StrLen nLength,
+ const USHORT nComp ) const
+{
+ SwDrawTextInfo aDrawInf( pVsh, *pOutDev, pSI, rTxt, nIndex, nLength );
+ aDrawInf.SetFrm( pFrm );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ aDrawInf.SetKanaComp( nComp );
+ SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
+ return aSize;
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::GetTxtSize()
+ *************************************************************************/
+
+SwPosSize SwTxtSizeInfo::GetTxtSize() const
+{
+ const SwScriptInfo& rSI =
+ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
+
+ // in some cases, compression is not allowed or surpressed for
+ // performance reasons
+ USHORT nComp =( SW_CJK == GetFont()->GetActual() &&
+ rSI.CountCompChg() &&
+ ! IsMulti() ) ?
+ GetKanaComp() :
+ 0 ;
+
+ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rSI, *pTxt, nIdx, nLen );
+ aDrawInf.SetFrm( pFrm );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ aDrawInf.SetKanaComp( nComp );
+ return pFnt->_GetTxtSize( aDrawInf );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::GetTxtSize()
+ *************************************************************************/
+
+void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIndex,
+ const xub_StrLen nLength, const USHORT nComp,
+ USHORT& nMinSize, USHORT& nMaxSizeDiff ) const
+{
+ SwDrawTextInfo aDrawInf( pVsh, *pOut, pSI, *pTxt, nIndex, nLength );
+ aDrawInf.SetFrm( pFrm );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ aDrawInf.SetKanaComp( nComp );
+ SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
+ nMaxSizeDiff = (USHORT)aDrawInf.GetKanaDiff();
+ nMinSize = aSize.Width();
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::GetTxtBreak()
+ *************************************************************************/
+
+xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
+ const xub_StrLen nMaxLen,
+ const USHORT nComp ) const
+{
+ const SwScriptInfo& rScriptInfo =
+ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
+
+ ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" )
+ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
+ *pTxt, GetIdx(), nMaxLen );
+ aDrawInf.SetFrm( pFrm );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ aDrawInf.SetKanaComp( nComp );
+ aDrawInf.SetHyphPos( 0 );
+
+ return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
+}
+
+/*************************************************************************
+ * SwTxtSizeInfo::GetTxtBreak()
+ *************************************************************************/
+
+xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
+ const xub_StrLen nMaxLen,
+ const USHORT nComp,
+ xub_StrLen& rExtraCharPos ) const
+{
+ const SwScriptInfo& rScriptInfo =
+ ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
+
+ ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" )
+ SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
+ *pTxt, GetIdx(), nMaxLen );
+ aDrawInf.SetFrm( pFrm );
+ aDrawInf.SetFont( pFnt );
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ aDrawInf.SetKanaComp( nComp );
+ aDrawInf.SetHyphPos( &rExtraCharPos );
+
+ return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::CtorInitTxtPaintInfo()
+ *************************************************************************/
+
+void SwTxtPaintInfo::CtorInitTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint )
+{
+ CtorInitTxtSizeInfo( pFrame );
+ aTxtFly.CtorInitTxtFly( pFrame ),
+ aPaintRect = rPaint;
+ nSpaceIdx = 0;
+ pSpaceAdd = NULL;
+ pWrongList = NULL;
+ pGrammarCheckList = NULL;
+ pSmartTags = NULL; // SMARTTAGS
+
+#ifndef DBG_UTIL
+ pBrushItem = 0;
+#else
+ pBrushItem = ((SvxBrushItem*)-1);
+#endif
+}
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt )
+ : SwTxtSizeInfo( rInf, rTxt ),
+ pWrongList( rInf.GetpWrongList() ),
+ pGrammarCheckList( rInf.GetGrammarCheckList() ),
+ pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS
+ pSpaceAdd( rInf.GetpSpaceAdd() ),
+ pBrushItem( rInf.GetBrushItem() ),
+ aTxtFly( *rInf.GetTxtFly() ),
+ aPos( rInf.GetPos() ),
+ aPaintRect( rInf.GetPaintRect() ),
+ nSpaceIdx( rInf.GetSpaceIdx() )
+{ }
+
+SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf )
+ : SwTxtSizeInfo( rInf ),
+ pWrongList( rInf.GetpWrongList() ),
+ pGrammarCheckList( rInf.GetGrammarCheckList() ),
+ pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS
+ pSpaceAdd( rInf.GetpSpaceAdd() ),
+ pBrushItem( rInf.GetBrushItem() ),
+ aTxtFly( *rInf.GetTxtFly() ),
+ aPos( rInf.GetPos() ),
+ aPaintRect( rInf.GetPaintRect() ),
+ nSpaceIdx( rInf.GetSpaceIdx() )
+{ }
+
+extern Color aGlobalRetoucheColor;
+
+/*************************************************************************
+ * lcl_IsDarkBackground
+ *
+ * Returns if the current background color is dark.
+ *************************************************************************/
+
+sal_Bool lcl_IsDarkBackground( const SwTxtPaintInfo& rInf )
+{
+ const Color* pCol = rInf.GetFont()->GetBackColor();
+ if( ! pCol || COL_TRANSPARENT == pCol->GetColor() )
+ {
+ const SvxBrushItem* pItem;
+ SwRect aOrigBackRect;
+
+ /// OD 21.08.2002
+ /// consider, that [GetBackgroundBrush(...)] can set <pCol>
+ /// - see implementation in /core/layout/paintfrm.cxx
+ /// OD 21.08.2002 #99657#
+ /// There is a background color, if there is a background brush and
+ /// its color is *not* "no fill"/"auto fill".
+ if( rInf.GetTxtFrm()->GetBackgroundBrush( pItem, pCol, aOrigBackRect, FALSE ) )
+ {
+ if ( !pCol )
+ pCol = &pItem->GetColor();
+
+ /// OD 30.08.2002 #99657#
+ /// determined color <pCol> can be <COL_TRANSPARENT>. Thus, check it.
+ if ( pCol->GetColor() == COL_TRANSPARENT)
+ pCol = NULL;
+ }
+ else
+ pCol = NULL;
+ }
+
+
+ if( !pCol )
+ pCol = &aGlobalRetoucheColor;
+
+ return pCol->IsDark();
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::_DrawText()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor,
+ const xub_StrLen nStart, const xub_StrLen nLength,
+ const sal_Bool bKern, const sal_Bool bWrong,
+ const sal_Bool bSmartTag,
+ const sal_Bool bGrammarCheck ) // SMARTTAGS
+{
+ if( !nLength )
+ return;
+
+ if( GetFont()->IsBlink() && OnWin() && rPor.Width() )
+ {
+ // check if accessibility options allow blinking portions:
+ const ViewShell* pSh = GetTxtFrm()->GetShell();
+ if ( pSh && ! pSh->GetAccessibilityOptions()->IsStopAnimatedText() &&
+ ! pSh->IsPreView() )
+ {
+ if( !pBlink )
+ pBlink = new SwBlink();
+
+ Point aPoint( aPos );
+
+ if ( GetTxtFrm()->IsRightToLeft() )
+ GetTxtFrm()->SwitchLTRtoRTL( aPoint );
+
+ if ( TEXT_LAYOUT_BIDI_STRONG != GetOut()->GetLayoutMode() )
+ aPoint.X() -= rPor.Width();
+
+ if ( GetTxtFrm()->IsVertical() )
+ GetTxtFrm()->SwitchHorizontalToVertical( aPoint );
+
+ pBlink->Insert( aPoint, &rPor, GetTxtFrm(), pFnt->GetOrientation() );
+
+ if( !pBlink->IsVisible() )
+ return;
+ }
+ else
+ {
+ delete pBlink;
+ pBlink = NULL;
+ }
+ }
+
+ // The SwScriptInfo is useless if we are inside a field portion
+ SwScriptInfo* pSI = 0;
+ if ( ! rPor.InFldGrp() )
+ pSI = &GetParaPortion()->GetScriptInfo();
+
+ // in some cases, kana compression is not allowed or surpressed for
+ // performance reasons
+ USHORT nComp = 0;
+ if ( ! IsMulti() )
+ nComp = GetKanaComp();
+
+ sal_Bool bCfgIsAutoGrammar = sal_False;
+ SvtLinguConfig().GetProperty( C2U( UPN_IS_GRAMMAR_AUTO ) ) >>= bCfgIsAutoGrammar;
+ const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol();
+ const sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell();
+ const sal_Bool bTmpGrammarCheck = bGrammarCheck && OnWin() && bCfgIsAutoGrammar && GetOpt().IsOnlineSpell();
+ const sal_Bool bTmpSmart = bSmartTag && OnWin() && !GetOpt().IsPagePreview() && SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
+
+ ASSERT( GetParaPortion(), "No paragraph!");
+ SwDrawTextInfo aDrawInf( pFrm->GetShell(), *pOut, pSI, rText, nStart, nLength,
+ rPor.Width(), bBullet );
+
+ aDrawInf.SetLeft( GetPaintRect().Left() );
+ aDrawInf.SetRight( GetPaintRect().Right() );
+ aDrawInf.SetUnderFnt( pUnderFnt );
+
+ const long nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() ||
+ rPor.InNumberGrp() ) ? 0 : GetSpaceAdd();
+ if ( nSpaceAdd )
+ {
+ xub_StrLen nCharCnt;
+ // --> FME 2005-04-04 #i41860# Thai justified alignemt needs some
+ // additional information:
+ aDrawInf.SetNumberOfBlanks( rPor.InTxtGrp() ?
+ static_cast<const SwTxtPortion&>(rPor).GetSpaceCnt( *this, nCharCnt ) :
+ 0 );
+ // <--
+ }
+
+ aDrawInf.SetSpace( nSpaceAdd );
+ aDrawInf.SetKanaComp( nComp );
+
+ // the font is used to identify the current script via nActual
+ aDrawInf.SetFont( pFnt );
+ // the frame is used to identify the orientation
+ aDrawInf.SetFrm( GetTxtFrm() );
+ // we have to know if the paragraph should snap to grid
+ aDrawInf.SetSnapToGrid( SnapToGrid() );
+ // for underlining we must know when not to add extra space behind
+ // a character in justified mode
+ aDrawInf.SetSpaceStop( ! rPor.GetPortion() ||
+ rPor.GetPortion()->InFixMargGrp() ||
+ rPor.GetPortion()->IsHolePortion() );
+
+ if( GetTxtFly()->IsOn() )
+ {
+ // aPos muss als TopLeft vorliegen, weil die ClipRects sonst
+ // nicht berechnet werden koennen.
+ const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() );
+ const Size aSize( rPor.Width(), rPor.Height() );
+ aDrawInf.SetPos( aPoint );
+ aDrawInf.SetSize( aSize );
+ aDrawInf.SetAscent( rPor.GetAscent() );
+ aDrawInf.SetKern( bKern ? rPor.Width() : 0 );
+ aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+ aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
+ aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS
+ GetTxtFly()->DrawTextOpaque( aDrawInf );
+ }
+ else
+ {
+ aDrawInf.SetPos( aPos );
+ if( bKern )
+ pFnt->_DrawStretchText( aDrawInf );
+ else
+ {
+ aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
+ aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
+ aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS
+ pFnt->_DrawText( aDrawInf );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::CalcRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor,
+ SwRect* pRect, SwRect* pIntersect ) const
+{
+ Size aSize( rPor.Width(), rPor.Height() );
+ if( rPor.IsHangingPortion() )
+ aSize.Width() = ((SwHangingPortion&)rPor).GetInnerWidth();
+ if( rPor.InSpaceGrp() && GetSpaceAdd() )
+ {
+ SwTwips nAdd = rPor.CalcSpacing( GetSpaceAdd(), *this );
+ if( rPor.InFldGrp() && GetSpaceAdd() < 0 && nAdd )
+ nAdd += GetSpaceAdd() / SPACING_PRECISION_FACTOR;
+ aSize.Width() += nAdd;
+ }
+
+ Point aPoint;
+
+ if( IsRotated() )
+ {
+ long nTmp = aSize.Width();
+ aSize.Width() = aSize.Height();
+ aSize.Height() = nTmp;
+ if ( 1 == GetDirection() )
+ {
+ aPoint.A() = X() - rPor.GetAscent();
+ aPoint.B() = Y() - aSize.Height();
+ }
+ else
+ {
+ aPoint.A() = X() - rPor.Height() + rPor.GetAscent();
+ aPoint.B() = Y();
+ }
+ }
+ else
+ {
+ aPoint.A() = X();
+ aPoint.B() = Y() - rPor.GetAscent();
+ }
+
+ // Adjust x coordinate if we are inside a bidi portion
+ const BOOL bFrmDir = GetTxtFrm()->IsRightToLeft();
+ BOOL bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == GetDirection() ) ||
+ ( bFrmDir && DIR_LEFT2RIGHT == GetDirection() );
+
+ if ( bCounterDir )
+ aPoint.A() -= aSize.Width();
+
+ SwRect aRect( aPoint, aSize );
+
+ if ( GetTxtFrm()->IsRightToLeft() )
+ GetTxtFrm()->SwitchLTRtoRTL( aRect );
+
+ if ( GetTxtFrm()->IsVertical() )
+ GetTxtFrm()->SwitchHorizontalToVertical( aRect );
+
+ if ( pRect )
+ *pRect = aRect;
+
+ if( aRect.HasArea() && pIntersect )
+ {
+ ::SwAlignRect( aRect, (ViewShell*)GetVsh() );
+
+ if ( GetOut()->IsClipRegion() )
+ {
+ SwRect aClip( GetOut()->GetClipRegion().GetBoundRect() );
+ aRect.Intersection( aClip );
+ }
+
+ *pIntersect = aRect;
+ }
+}
+
+/*************************************************************************
+ * 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
+ *************************************************************************/
+
+static void lcl_DrawSpecial( const SwTxtPaintInfo& rInf, const SwLinePortion& rPor,
+ SwRect& rRect, const Color* pCol, sal_Unicode cChar,
+ BYTE nOptions )
+{
+ sal_Bool bCenter = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_CENTER );
+ sal_Bool bRotate = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_ROTATE );
+
+ // rRect is given in absolute coordinates
+ if ( rInf.GetTxtFrm()->IsRightToLeft() )
+ rInf.GetTxtFrm()->SwitchRTLtoLTR( rRect );
+ if ( rInf.GetTxtFrm()->IsVertical() )
+ rInf.GetTxtFrm()->SwitchVerticalToHorizontal( rRect );
+
+ const SwFont* pOldFnt = rInf.GetFont();
+
+ // Font is generated only once:
+ static SwFont* pFnt = 0;
+ if ( ! pFnt )
+ {
+ pFnt = new SwFont( *pOldFnt );
+ pFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
+ pFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
+ pFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
+ pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
+ }
+
+ // Some of the current values are set at the font:
+ if ( ! bRotate )
+ pFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
+ else
+ pFnt->SetVertical( pOldFnt->GetOrientation() );
+
+ if ( pCol )
+ pFnt->SetColor( *pCol );
+ else
+ pFnt->SetColor( pOldFnt->GetColor() );
+
+ Size aFontSize( 0, SPECIAL_FONT_HEIGHT );
+ pFnt->SetSize( aFontSize, pFnt->GetActual() );
+
+ ((SwTxtPaintInfo&)rInf).SetFont( pFnt );
+
+ // The maximum width depends on the current orientation
+ const USHORT nDir = pFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
+ SwTwips nMaxWidth = 0;
+ switch ( nDir )
+ {
+ case 0 :
+ nMaxWidth = rRect.Width();
+ break;
+ case 900 :
+ case 2700 :
+ nMaxWidth = rRect.Height();
+ break;
+ default:
+ ASSERT( sal_False, "Unknown direction set at font" )
+ break;
+ }
+
+ // check if char fits into rectangle
+ const XubString aTmp( cChar );
+ aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
+ while ( aFontSize.Width() > nMaxWidth )
+ {
+ SwTwips nFactor = ( 100 * aFontSize.Width() ) / nMaxWidth;
+ const SwTwips nOldWidth = aFontSize.Width();
+
+ // new height for font
+ const BYTE nAct = pFnt->GetActual();
+ aFontSize.Height() = ( 100 * pFnt->GetSize( nAct ).Height() ) / nFactor;
+ aFontSize.Width() = ( 100 * pFnt->GetSize( nAct).Width() ) / nFactor;
+
+ if ( !aFontSize.Width() && !aFontSize.Height() )
+ break;
+
+ pFnt->SetSize( aFontSize, nAct );
+
+ aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
+
+ if ( aFontSize.Width() >= nOldWidth )
+ break;
+ }
+
+ const Point aOldPos( rInf.GetPos() );
+
+ // adjust values so that tab is vertically and horizontally centered
+ SwTwips nX = rRect.Left();
+ SwTwips nY = rRect.Top();
+ switch ( nDir )
+ {
+ case 0 :
+ if ( bCenter )
+ nX += ( rRect.Width() - aFontSize.Width() ) / 2;
+ nY += ( rRect.Height() - aFontSize.Height() ) / 2 + rInf.GetAscent();
+ break;
+ case 900 :
+ if ( bCenter )
+ nX += ( rRect.Width() - aFontSize.Height() ) / 2 + rInf.GetAscent();
+ nY += ( rRect.Height() + aFontSize.Width() ) / 2;
+ break;
+ case 2700 :
+ if ( bCenter )
+ nX += ( rRect.Width() + aFontSize.Height() ) / 2 - rInf.GetAscent();
+ nY += ( rRect.Height() - aFontSize.Width() ) / 2;
+ break;
+ }
+
+ Point aTmpPos( nX, nY );
+ ((SwTxtPaintInfo&)rInf).SetPos( aTmpPos );
+ USHORT nOldWidth = rPor.Width();
+ ((SwLinePortion&)rPor).Width( (USHORT)aFontSize.Width() );
+ rInf.DrawText( aTmp, rPor );
+ ((SwLinePortion&)rPor).Width( nOldWidth );
+ ((SwTxtPaintInfo&)rInf).SetFont( (SwFont*)pOldFnt );
+ ((SwTxtPaintInfo&)rInf).SetPos( aOldPos );
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawRect()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic,
+ sal_Bool bRetouche ) const
+{
+ if ( OnWin() || !bRetouche )
+ {
+ if( aTxtFly.IsOn() )
+ ((SwTxtPaintInfo*)this)->GetTxtFly()->
+ DrawFlyRect( pOut, rRect, *this, bNoGraphic );
+ else if ( bNoGraphic )
+ pOut->DrawRect( rRect.SVRect() );
+ else
+ {
+ ASSERT( ((SvxBrushItem*)-1) != pBrushItem, "DrawRect: Uninitialized BrushItem!" );
+ ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect );
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawTab()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const
+{
+ if( OnWin() )
+ {
+ SwRect aRect;
+ CalcRect( rPor, &aRect );
+
+ if ( ! aRect.HasArea() )
+ return;
+
+ const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
+ CHAR_TAB_RTL : CHAR_TAB;
+ const BYTE nOptions = DRAW_SPECIAL_OPTIONS_CENTER |
+ DRAW_SPECIAL_OPTIONS_ROTATE;
+ lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawLineBreak()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const
+{
+ if( OnWin() )
+ {
+ KSHORT nOldWidth = rPor.Width();
+ ((SwLinePortion&)rPor).Width( LINE_BREAK_WIDTH );
+
+ SwRect aRect;
+ CalcRect( rPor, &aRect );
+
+ if( aRect.HasArea() )
+ {
+ const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
+ CHAR_LINEBREAK_RTL : CHAR_LINEBREAK;
+ const BYTE nOptions = 0;
+ lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
+ }
+
+ ((SwLinePortion&)rPor).Width( nOldWidth );
+ }
+}
+
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawRedArrow()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawRedArrow( const SwLinePortion &rPor ) const
+{
+ Size aSize( SPECIAL_FONT_HEIGHT, SPECIAL_FONT_HEIGHT );
+ SwRect aRect( ((SwArrowPortion&)rPor).GetPos(), aSize );
+ sal_Unicode cChar;
+ if( ((SwArrowPortion&)rPor).IsLeft() )
+ {
+ aRect.Pos().Y() += 20 - GetAscent();
+ aRect.Pos().X() += 20;
+ if( aSize.Height() > rPor.Height() )
+ aRect.Height( rPor.Height() );
+ cChar = CHAR_LEFT_ARROW;
+ }
+ else
+ {
+ if( aSize.Height() > rPor.Height() )
+ aRect.Height( rPor.Height() );
+ aRect.Pos().Y() -= aRect.Height() + 20;
+ aRect.Pos().X() -= aRect.Width() + 20;
+ cChar = CHAR_RIGHT_ARROW;
+ }
+
+ if ( GetTxtFrm()->IsVertical() )
+ GetTxtFrm()->SwitchHorizontalToVertical( aRect );
+
+ Color aCol( COL_LIGHTRED );
+
+ if( aRect.HasArea() )
+ {
+ const BYTE nOptions = 0;
+ lcl_DrawSpecial( *this, rPor, aRect, &aCol, cChar, nOptions );
+ }
+}
+
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawPostIts()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawPostIts( const SwLinePortion&, sal_Bool bScript ) const
+{
+ if( OnWin() && pOpt->IsPostIts() )
+ {
+ Size aSize;
+ Point aTmp;
+
+ const USHORT nPostItsWidth = pOpt->GetPostItsWidth( GetOut() );
+ const USHORT nFontHeight = pFnt->GetHeight( pVsh, *GetOut() );
+ const USHORT nFontAscent = pFnt->GetAscent( pVsh, *GetOut() );
+
+ switch ( pFnt->GetOrientation( GetTxtFrm()->IsVertical() ) )
+ {
+ case 0 :
+ aSize.Width() = nPostItsWidth;
+ aSize.Height() = nFontHeight;
+ aTmp.X() = aPos.X();
+ aTmp.Y() = aPos.Y() - nFontAscent;
+ break;
+ case 900 :
+ aSize.Height() = nPostItsWidth;
+ aSize.Width() = nFontHeight;
+ aTmp.X() = aPos.X() - nFontAscent;
+ aTmp.Y() = aPos.Y();
+ break;
+ case 2700 :
+ aSize.Height() = nPostItsWidth;
+ aSize.Width() = nFontHeight;
+ aTmp.X() = aPos.X() - nFontHeight +
+ nFontAscent;
+ aTmp.Y() = aPos.Y();
+ break;
+ }
+
+ SwRect aTmpRect( aTmp, aSize );
+
+ if ( GetTxtFrm()->IsRightToLeft() )
+ GetTxtFrm()->SwitchLTRtoRTL( aTmpRect );
+
+ if ( GetTxtFrm()->IsVertical() )
+ GetTxtFrm()->SwitchHorizontalToVertical( aTmpRect );
+
+ const Rectangle aRect( aTmpRect.SVRect() );
+ pOpt->PaintPostIts( (OutputDevice*)GetOut(), aRect, bScript );
+ }
+}
+
+void SwTxtPaintInfo::DrawCheckBox( const SwFieldFormPortion &rPor, bool checked) const
+{
+ SwRect aIntersect;
+ CalcRect( rPor, &aIntersect, 0 );
+ if ( aIntersect.HasArea() )
+ {
+ if (OnWin() && SwViewOption::IsFieldShadings() &&
+ !GetOpt().IsPagePreview())
+ {
+ OutputDevice* pOut_ = (OutputDevice*)GetOut();
+ pOut_->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ pOut_->SetFillColor( SwViewOption::GetFieldShadingsColor() );
+ pOut_->SetLineColor();
+ pOut_->DrawRect( aIntersect.SVRect() );
+ pOut_->Pop();
+ }
+ const int delta=10;
+ Rectangle r(aIntersect.Left()+delta, aIntersect.Top()+delta, aIntersect.Right()-delta, aIntersect.Bottom()-delta);
+ pOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ pOut->SetLineColor( Color(0, 0, 0));
+ pOut->SetFillColor();
+ pOut->DrawRect( r );
+ if (checked) {
+ pOut->DrawLine(r.TopLeft(), r.BottomRight());
+ pOut->DrawLine(r.TopRight(), r.BottomLeft());
+ }
+ pOut->Pop();
+ }
+}
+/*************************************************************************
+ * SwTxtPaintInfo::DrawBackGround()
+ *************************************************************************/
+void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
+{
+ ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer polution ?" );
+
+ SwRect aIntersect;
+ CalcRect( rPor, 0, &aIntersect );
+
+ if ( aIntersect.HasArea() )
+ {
+ OutputDevice* pTmpOut = (OutputDevice*)GetOut();
+ pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+
+ // For dark background we do not want to have a filled rectangle
+ if ( GetVsh() && GetVsh()->GetWin() && lcl_IsDarkBackground( *this ) )
+ {
+ pTmpOut->SetLineColor( SwViewOption::GetFontColor().GetColor() );
+ }
+ else
+ {
+ pTmpOut->SetFillColor( SwViewOption::GetFieldShadingsColor() );
+ pTmpOut->SetLineColor();
+ }
+
+ DrawRect( aIntersect, sal_True );
+ pTmpOut->Pop();
+ }
+}
+
+void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
+{
+ {
+ SwRect aIntersect;
+ CalcRect( rPor, &aIntersect, 0 );
+ if(aIntersect.HasArea())
+ {
+ SwTxtNode *pNd = pFrm->GetTxtNode();
+ const ::sw::mark::IMark* pFieldmark = NULL;
+ if(pNd)
+ {
+ const SwDoc *doc=pNd->GetDoc();
+ if(doc)
+ {
+ SwIndex aIndex(pNd, GetIdx());
+ SwPosition aPosition(*pNd, aIndex);
+ pFieldmark=doc->getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
+ }
+ }
+ bool bIsStartMark=(1==GetLen() && CH_TXT_ATR_FIELDSTART==GetTxt().GetChar(GetIdx()));
+ if(pFieldmark) {
+ OSL_TRACE("Found Fieldmark");
+#if DEBUG
+ rtl::OUString str = pFieldmark->ToString( );
+ fprintf( stderr, "%s\n", rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr( ) );
+#endif
+ }
+ if(bIsStartMark) OSL_TRACE("Found StartMark");
+ if (OnWin() && (pFieldmark!=NULL || bIsStartMark) &&
+ SwViewOption::IsFieldShadings() &&
+ !GetOpt().IsPagePreview())
+ {
+ OutputDevice* pOutDev = (OutputDevice*)GetOut();
+ pOutDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ pOutDev->SetFillColor( SwViewOption::GetFieldShadingsColor() );
+ pOutDev->SetLineColor( );
+ pOutDev->DrawRect( aIntersect.SVRect() );
+ pOutDev->Pop();
+ }
+ }
+ }
+ if( !pFnt->GetBackColor() ) return;
+
+ ASSERT( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
+
+ SwRect aIntersect;
+ CalcRect( rPor, 0, &aIntersect );
+
+ if ( aIntersect.HasArea() )
+ {
+ OutputDevice* pTmpOut = (OutputDevice*)GetOut();
+
+ // --> FME 2004-06-24 #i16816# tagged pdf support
+ SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pTmpOut );
+ // <--
+
+ pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+
+ pTmpOut->SetFillColor( *pFnt->GetBackColor() );
+ pTmpOut->SetLineColor();
+
+ DrawRect( aIntersect, sal_True, sal_False );
+
+ pTmpOut->Pop();
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::DrawViewOpt()
+ *************************************************************************/
+
+void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
+ const MSHORT nWhich ) const
+{
+ if( OnWin() && !IsMulti() )
+ {
+ sal_Bool bDraw = sal_False;
+ switch( nWhich )
+ {
+ case POR_FTN:
+ case POR_QUOVADIS:
+ case POR_NUMBER:
+ case POR_FLD:
+ case POR_URL:
+ case POR_HIDDEN:
+ case POR_TOX:
+ case POR_REF:
+ case POR_META:
+ case POR_CONTROLCHAR:
+ if ( !GetOpt().IsPagePreview() &&
+ !GetOpt().IsReadonly() &&
+ SwViewOption::IsFieldShadings() &&
+ (POR_NUMBER != nWhich ||
+ pFrm->GetTxtNode()->HasMarkedLabel())) // #i27615#
+ bDraw = sal_True;
+ break;
+ case POR_TAB: if ( GetOpt().IsTab() ) bDraw = sal_True; break;
+ case POR_SOFTHYPH: if ( GetOpt().IsSoftHyph() )bDraw = sal_True; break;
+ case POR_BLANK: if ( GetOpt().IsHardBlank())bDraw = sal_True; break;
+ default:
+ {
+ ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
+ break;
+ }
+ }
+ if ( bDraw )
+ DrawBackground( rPor );
+ }
+}
+
+/*************************************************************************
+ * SwTxtPaintInfo::_NotifyURL()
+ *************************************************************************/
+
+void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
+{
+ ASSERT( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" );
+
+ SwRect aIntersect;
+ CalcRect( rPor, 0, &aIntersect );
+
+ if( aIntersect.HasArea() )
+ {
+ SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
+ SwTxtAttr *const pAttr =
+ pNd->GetTxtAttrAt(GetIdx(), RES_TXTATR_INETFMT);
+ if( pAttr )
+ {
+ const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
+ pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(),
+ aIntersect );
+ }
+ }
+}
+
+/*************************************************************************
+ * lcl_InitHyphValues()
+ *************************************************************************/
+
+static void lcl_InitHyphValues( PropertyValues &rVals,
+ INT16 nMinLeading, INT16 nMinTrailing )
+{
+ INT32 nLen = rVals.getLength();
+
+ if (0 == nLen) // yet to be initialized?
+ {
+ rVals.realloc( 2 );
+ PropertyValue *pVal = rVals.getArray();
+
+ pVal[0].Name = C2U( UPN_HYPH_MIN_LEADING );
+ pVal[0].Handle = UPH_HYPH_MIN_LEADING;
+ pVal[0].Value <<= nMinLeading;
+
+ pVal[1].Name = C2U( UPN_HYPH_MIN_TRAILING );
+ pVal[1].Handle = UPH_HYPH_MIN_TRAILING;
+ pVal[1].Value <<= nMinTrailing;
+ }
+ else if (2 == nLen) // already initialized once?
+ {
+ PropertyValue *pVal = rVals.getArray();
+ pVal[0].Value <<= nMinLeading;
+ pVal[1].Value <<= nMinTrailing;
+ }
+ else {
+ DBG_ERROR( "unxpected size of sequence" );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::GetHyphValues()
+ *************************************************************************/
+
+const PropertyValues & SwTxtFormatInfo::GetHyphValues() const
+{
+ DBG_ASSERT( 2 == aHyphVals.getLength(),
+ "hyphenation values not yet initialized" );
+ return aHyphVals;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::InitHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyphen )
+{
+ const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
+ SetHanging( rAttrSet.GetHangingPunctuation().GetValue() );
+ SetScriptSpace( rAttrSet.GetScriptSpace().GetValue() );
+ SetForbiddenChars( rAttrSet.GetForbiddenRule().GetValue() );
+ const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone();
+ MaxHyph() = rAttr.GetMaxHyphens();
+ sal_Bool bAuto = bAutoHyphen || rAttr.IsHyphen();
+ if( bAuto || bInterHyph )
+ {
+ nHyphStart = nHyphWrdStart = STRING_LEN;
+ nHyphWrdLen = 0;
+
+ const INT16 nMinimalLeading = Max(rAttr.GetMinLead(), sal_uInt8(2));
+ const INT16 nMinimalTrailing = rAttr.GetMinTrail();
+ lcl_InitHyphValues( aHyphVals, nMinimalLeading, nMinimalTrailing);
+ }
+ return bAuto;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::CtorInitTxtFormatInfo()
+ *************************************************************************/
+
+void SwTxtFormatInfo::CtorInitTxtFormatInfo( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph,
+ const sal_Bool bNewQuick, const sal_Bool bTst )
+{
+ CtorInitTxtPaintInfo( pNewFrm, SwRect() );
+
+ bQuick = bNewQuick;
+ bInterHyph = bNewInterHyph;
+
+ //! needs to be done in this order
+ nMinLeading = 2;
+ nMinTrailing = 2;
+ nMinWordLength = 0;
+ bAutoHyph = InitHyph();
+
+ bIgnoreFly = sal_False;
+ bFakeLineStart = sal_False;
+ bShift = sal_False;
+ bDropInit = sal_False;
+ bTestFormat = bTst;
+ nLeft = 0;
+ nRight = 0;
+ nFirst = 0;
+ nRealWidth = 0;
+ nForcedLeftMargin = 0;
+ pRest = 0;
+ nLineHeight = 0;
+ nLineNettoHeight = 0;
+ SetLineStart(0);
+ Init();
+}
+
+/*************************************************************************
+ * 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.
+
+sal_Bool SwTxtFormatInfo::IsHyphenate() const
+{
+ if( !bInterHyph && !bAutoHyph )
+ return sal_False;
+
+ LanguageType eTmp = GetFont()->GetLanguage();
+ if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp )
+ return sal_False;
+
+ uno::Reference< XHyphenator > xHyph = ::GetHyphenator();
+ if (bInterHyph && xHyph.is())
+ SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
+
+ if( !xHyph.is() || !xHyph->hasLocale( pBreakIt->GetLocale(eTmp) ) )
+ return sal_False;
+ return sal_True;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::GetDropFmt()
+ *************************************************************************/
+
+// Dropcaps vom SwTxtFormatter::CTOR gerufen.
+const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const
+{
+ const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop();
+ if( 1 >= pDrop->GetLines() ||
+ ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) )
+ pDrop = 0;
+ return pDrop;
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::Init()
+ *************************************************************************/
+
+void SwTxtFormatInfo::Init()
+{
+ // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth
+ X(0);
+ bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph =
+ bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False;
+
+ // generally we do not allow number portions in follows, except...
+ if ( GetTxtFrm()->IsFollow() )
+ {
+ const SwTxtFrm* pMaster = GetTxtFrm()->FindMaster();
+ const SwLinePortion* pTmpPara = pMaster->GetPara();
+
+ // there is a master for this follow and the master does not have
+ // any contents (especially it does not have a number portion)
+ bNumDone = ! pTmpPara ||
+ ! ((SwParaPortion*)pTmpPara)->GetFirstPortion()->IsFlyPortion();
+ }
+
+ pRoot = 0;
+ pLast = 0;
+ pFly = 0;
+ pLastFld = 0;
+ pLastTab = 0;
+ pUnderFlow = 0;
+ cTabDecimal = 0;
+ nWidth = nRealWidth;
+ nForcedLeftMargin = 0;
+ nSoftHyphPos = 0;
+ nUnderScorePos = STRING_LEN;
+ cHookChar = 0;
+ SetIdx(0);
+ SetLen( GetTxt().Len() );
+ SetPaintOfst(0);
+}
+
+/*-----------------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::SwTxtFormatInfo( const SwTxtFormatInfo& rInf,
+ SwLineLayout& rLay, SwTwips nActWidth ) : SwTxtPaintInfo( rInf )
+{
+ pRoot = &rLay;
+ pLast = &rLay;
+ pFly = NULL;
+ pLastFld = NULL;
+ pUnderFlow = NULL;
+ pRest = NULL;
+ pLastTab = NULL;
+
+ nSoftHyphPos = 0;
+ nUnderScorePos = STRING_LEN;
+ nHyphStart = 0;
+ nHyphWrdStart = 0;
+ nHyphWrdLen = 0;
+ nLineStart = rInf.GetIdx();
+ nLeft = rInf.nLeft;
+ nRight = rInf.nRight;
+ nFirst = rInf.nLeft;
+ nRealWidth = KSHORT(nActWidth);
+ nWidth = nRealWidth;
+ nLineHeight = 0;
+ nLineNettoHeight = 0;
+ nForcedLeftMargin = 0;
+
+ nMinLeading = 0;
+ nMinTrailing = 0;
+ nMinWordLength = 0;
+ bFull = FALSE;
+ bFtnDone = TRUE;
+ bErgoDone = TRUE;
+ bNumDone = TRUE;
+ bArrowDone = TRUE;
+ bStop = FALSE;
+ bNewLine = TRUE;
+ bShift = FALSE;
+ bUnderFlow = FALSE;
+ bInterHyph = FALSE;
+ bAutoHyph = FALSE;
+ bDropInit = FALSE;
+ bQuick = rInf.bQuick;
+ bNoEndHyph = FALSE;
+ bNoMidHyph = FALSE;
+ bIgnoreFly = FALSE;
+ bFakeLineStart = FALSE;
+
+ cTabDecimal = 0;
+ cHookChar = 0;
+ nMaxHyph = 0;
+ bTestFormat = rInf.bTestFormat;
+ SetMulti( sal_True );
+ SetFirstMulti( rInf.IsFirstMulti() );
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::_CheckFtnPortion()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr )
+{
+ KSHORT nHeight = pCurr->GetRealHeight();
+ SwLinePortion *pPor = pCurr->GetPortion();
+ sal_Bool bRet = sal_False;
+ while( pPor )
+ {
+ if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() )
+ {
+ bRet = sal_True;
+ SetLineHeight( nHeight );
+ SetLineNettoHeight( pCurr->Height() );
+ break;
+ }
+ pPor = pPor->GetPortion();
+ }
+ return bRet;
+}
+
+
+
+
+/*************************************************************************
+ * SwTxtFormatInfo::ScanPortionEnd()
+ *************************************************************************/
+xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart,
+ const xub_StrLen nEnd )
+{
+ cHookChar = 0;
+ xub_StrLen i = nStart;
+
+ //
+ // Used for decimal tab handling:
+ //
+ const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0;
+ const xub_Unicode cThousandSep = ',' == cTabDec ? '.' : ',';
+ // --> FME 2006-01-23 #i45951# German (Switzerland) uses ' as thousand separator:
+ const xub_Unicode cThousandSep2 = ',' == cTabDec ? '.' : '\'';
+ // <--
+
+ bool bNumFound = false;
+ const bool bTabCompat = GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
+
+ // Removed for i7288. bSkip used to be passed from SwFldPortion::Format
+ // as IsFollow(). Therefore more than one special character was not
+ // handled correctly at the beginning of follow fields.
+// if ( bSkip && i < nEnd )
+// ++i;
+
+ for( ; i < nEnd; ++i )
+ {
+ const xub_Unicode cPos = GetChar( i );
+ switch( cPos )
+ {
+ case CH_TXTATR_BREAKWORD:
+ case CH_TXTATR_INWORD:
+ if( !HasHint( i ))
+ break;
+ // no break;
+
+ case CHAR_SOFTHYPHEN:
+ case CHAR_HARDHYPHEN:
+ case CHAR_HARDBLANK:
+ case CH_TAB:
+ case CH_BREAK:
+ case CHAR_ZWSP :
+ case CHAR_ZWNBSP :
+// case CHAR_RLM :
+// case CHAR_LRM :
+ cHookChar = cPos;
+ return i;
+
+ case CHAR_UNDERSCORE:
+ if ( STRING_LEN == nUnderScorePos )
+ nUnderScorePos = i;
+ break;
+
+ default:
+ if ( cTabDec )
+ {
+ if( cTabDec == cPos )
+ {
+ ASSERT( cPos, "Unexpected end of string" );
+ if( cPos ) // robust
+ {
+ cHookChar = cPos;
+ return i;
+ }
+ }
+
+ //
+ // Compatibility: First non-digit character behind a
+ // a digit character becomes the hook character
+ //
+ if ( bTabCompat )
+ {
+ if ( ( 0x2F < cPos && cPos < 0x3A ) ||
+ ( bNumFound && ( cPos == cThousandSep || cPos == cThousandSep2 ) ) )
+ {
+ bNumFound = true;
+ }
+ else
+ {
+ if ( bNumFound )
+ {
+ cHookChar = cPos;
+ SetTabDecimal( cPos );
+ return i;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // --> FME 2006-01-13 #130210# Check if character *behind* the portion has
+ // to become the hook:
+ if ( i == nEnd && i < GetTxt().Len() && bNumFound )
+ {
+ const xub_Unicode cPos = GetChar( i );
+ if ( cPos != cTabDec && cPos != cThousandSep && cPos !=cThousandSep2 && ( 0x2F >= cPos || cPos >= 0x3A ) )
+ {
+ cHookChar = GetChar( i );
+ SetTabDecimal( cHookChar );
+ }
+ }
+
+ return i;
+}
+
+BOOL SwTxtFormatInfo::LastKernPortion()
+{
+ if( GetLast() )
+ {
+ if( GetLast()->IsKernPortion() )
+ return TRUE;
+ if( GetLast()->Width() || ( GetLast()->GetLen() &&
+ !GetLast()->IsHolePortion() ) )
+ return FALSE;
+ }
+ SwLinePortion* pPor = GetRoot();
+ SwLinePortion *pKern = NULL;
+ while( pPor )
+ {
+ if( pPor->IsKernPortion() )
+ pKern = pPor;
+ else if( pPor->Width() || ( pPor->GetLen() && !pPor->IsHolePortion() ) )
+ pKern = NULL;
+ pPor = pPor->GetPortion();
+ }
+ if( pKern )
+ {
+ SetLast( pKern );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*************************************************************************
+ * class SwTxtSlot
+ *************************************************************************/
+
+SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
+ bool bTxtLen, bool bExgLists, const sal_Char *pCh )
+ : pOldTxt( 0 ),
+ pOldSmartTagList( 0 ),
+ pOldGrammarCheckList( 0 ),
+ pTempList( 0 )
+{
+ if( pCh )
+ {
+ aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 );
+ bOn = sal_True;
+ }
+ else
+ bOn = pPor->GetExpTxt( *pNew, aTxt );
+
+ // Der Text wird ausgetauscht...
+ if( bOn )
+ {
+ pInf = (SwTxtSizeInfo*)pNew;
+ nIdx = pInf->GetIdx();
+ nLen = pInf->GetLen();
+ pOldTxt = &(pInf->GetTxt());
+ pInf->SetTxt( aTxt );
+ pInf->SetIdx( 0 );
+ pInf->SetLen( bTxtLen ? pInf->GetTxt().Len() : pPor->GetLen() );
+
+ // ST2
+ if ( bExgLists )
+ {
+ pOldSmartTagList = static_cast<SwTxtPaintInfo*>(pInf)->GetSmartTags();
+ if ( pOldSmartTagList )
+ {
+ const USHORT nPos = pOldSmartTagList->GetWrongPos(nIdx);
+ const xub_StrLen nListPos = pOldSmartTagList->Pos(nPos);
+ if( nListPos == nIdx )
+ ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList->SubList( nPos ) );
+ else if( !pTempList && nPos < pOldSmartTagList->Count() && nListPos < nIdx && aTxt.Len() )
+ {
+ pTempList = new SwWrongList( WRONGLIST_SMARTTAG );
+ pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 );
+ ((SwTxtPaintInfo*)pInf)->SetSmartTags( pTempList );
+ }
+ else
+ ((SwTxtPaintInfo*)pInf)->SetSmartTags( 0);
+ }
+ pOldGrammarCheckList = static_cast<SwTxtPaintInfo*>(pInf)->GetGrammarCheckList();
+ if ( pOldGrammarCheckList )
+ {
+ const USHORT nPos = pOldGrammarCheckList->GetWrongPos(nIdx);
+ const xub_StrLen nListPos = pOldGrammarCheckList->Pos(nPos);
+ if( nListPos == nIdx )
+ ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList->SubList( nPos ) );
+ else if( !pTempList && nPos < pOldGrammarCheckList->Count() && nListPos < nIdx && aTxt.Len() )
+ {
+ pTempList = new SwWrongList( WRONGLIST_GRAMMAR );
+ pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 );
+ ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pTempList );
+ }
+ else
+ ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( 0);
+ }
+ }
+ }
+}
+
+/*************************************************************************
+ * SwTxtSlot::~SwTxtSlot()
+ *************************************************************************/
+
+SwTxtSlot::~SwTxtSlot()
+{
+ if( bOn )
+ {
+ pInf->SetTxt( *pOldTxt );
+ pInf->SetIdx( nIdx );
+ pInf->SetLen( nLen );
+
+ // ST2
+ // Restore old smart tag list
+ if ( pOldSmartTagList )
+ ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList );
+ if ( pOldGrammarCheckList )
+ ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList );
+ delete pTempList;
+ }
+}
+
+/*************************************************************************
+ * SwFontSave::SwFontSave()
+ *************************************************************************/
+
+SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNew,
+ SwAttrIter* pItr )
+ : pFnt( pNew ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 )
+{
+ if( pFnt )
+ {
+ pInf = &((SwTxtSizeInfo&)rInf);
+ // In these cases we temporarily switch to the new font:
+ // 1. the fonts have a different magic number
+ // 2. they have different script types
+ // 3. their background colors differ (this is not covered by 1.)
+ if( pFnt->DifferentMagic( pNew, pFnt->GetActual() ) ||
+ pNew->GetActual() != pFnt->GetActual() ||
+ ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) ||
+ ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) ||
+ ( pNew->GetBackColor() && pFnt->GetBackColor() &&
+ ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) )
+ {
+ pNew->SetTransparent( sal_True );
+ pNew->SetAlign( ALIGN_BASELINE );
+ pInf->SetFont( pNew );
+ }
+ else
+ pFnt = 0;
+ pNew->Invalidate();
+ pNew->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
+ if( pItr && pItr->GetFnt() == pFnt )
+ {
+ pIter = pItr;
+ pIter->SetFnt( pNew );
+ }
+ else
+ pIter = NULL;
+ }
+}
+
+/*************************************************************************
+ * SwFontSave::~SwFontSave()
+ *************************************************************************/
+
+SwFontSave::~SwFontSave()
+{
+ if( pFnt )
+ {
+ // SwFont zurueckstellen
+ pFnt->Invalidate();
+ pInf->SetFont( pFnt );
+ if( pIter )
+ {
+ pIter->SetFnt( pFnt );
+ pIter->nPos = STRING_LEN;
+ }
+ }
+}
+
+/*************************************************************************
+ * SwDefFontSave::SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf )
+ : pFnt( ((SwTxtSizeInfo&)rInf).GetFont() )
+{
+ const BOOL bTmpAlter = pFnt->GetFixKerning() ||
+ ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) )
+ ;
+
+ const sal_Bool bFamily = bTmpAlter &&
+ pFnt->GetName( pFnt->GetActual() ) != numfunc::GetDefBulletFontname();
+ const sal_Bool bRotation = (sal_Bool)pFnt->GetOrientation() &&
+ ! rInf.GetTxtFrm()->IsVertical();
+
+ if( bFamily || bRotation )
+ {
+ pNewFnt = new SwFont( *pFnt );
+
+ if ( bFamily )
+ {
+ pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
+ pNewFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
+ pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
+ pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
+ pNewFnt->SetFixKerning( 0 );
+ }
+
+ if ( bRotation )
+ pNewFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
+
+ pInf = &((SwTxtSizeInfo&)rInf);
+ pNewFnt->Invalidate();
+ pInf->SetFont( pNewFnt );
+ }
+ else
+ {
+ pFnt = 0;
+ pNewFnt = 0;
+ }
+}
+
+/*************************************************************************
+ * SwDefFontSave::~SwDefFontSave()
+ *************************************************************************/
+
+SwDefFontSave::~SwDefFontSave()
+{
+ if( pFnt )
+ {
+ delete pNewFnt;
+ // SwFont zurueckstellen
+ pFnt->Invalidate();
+ pInf->SetFont( pFnt );
+ }
+}
+
+/*************************************************************************
+ * SwTxtFormatInfo::ChgHyph()
+ *************************************************************************/
+
+sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew )
+{
+ const sal_Bool bOld = bAutoHyph;
+ if( bAutoHyph != bNew )
+ {
+ bAutoHyph = bNew;
+ InitHyph( bNew );
+ // 5744: Sprache am Hyphenator einstellen.
+ if( pFnt )
+ pFnt->ChgPhysFnt( pVsh, *pOut );
+ }
+ return bOld;
+}
+
+