update dev300-m58
[ooovba.git] / sw / source / core / text / inftxt.cxx
blob1838124ecda41a03cc376e498b8796f47f5c4e19
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inftxt.cxx,v $
10 * $Revision: 1.123.20.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <com/sun/star/uno/Sequence.h>
36 #include <svtools/linguprops.hxx>
37 #include <svtools/lingucfg.hxx>
38 #include <hintids.hxx>
39 #include <sfx2/printer.hxx>
40 #include <svx/hyznitem.hxx>
41 #include <svx/escpitem.hxx>
42 #include <svx/hngpnctitem.hxx>
43 #include <svx/scriptspaceitem.hxx>
44 #include <svx/brshitem.hxx>
45 #include <svx/splwrap.hxx>
46 #include <svx/pgrditem.hxx>
47 // --> OD 2008-01-17 #newlistlevelattrs#
48 #ifndef _SVX_TSTPITEM_HXX
49 #include <svx/tstpitem.hxx>
50 #endif
51 // <--
53 #include <SwSmartTagMgr.hxx>
54 #include <linguistic/lngprops.hxx>
55 #include <svx/unolingu.hxx>
56 #include <breakit.hxx>
57 #include <svx/forbiddenruleitem.hxx>
58 #include <txatbase.hxx>
59 #include <fmtinfmt.hxx>
60 #include <swmodule.hxx>
61 #include <vcl/svapp.hxx>
62 #include <vcl/wrkwin.hxx>
63 #include <viewsh.hxx> // ViewShell
64 #include <viewopt.hxx> // SwViewOptions
65 #include <frmtool.hxx> // DrawGraphic
66 #include <IDocumentSettingAccess.hxx>
67 #ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
68 #include <IDocumentDeviceAccess.hxx>
69 #endif
70 #include <paratr.hxx> // SwFmtDrop
71 #include <rootfrm.hxx> // SwRootFrm
72 #include <inftxt.hxx> // SwTxtInfo
73 #include <blink.hxx> // SwBlink
74 #include <noteurl.hxx> // SwNoteURL
75 #include <porftn.hxx> // SwFtnPortion
76 #include <porrst.hxx> // SwHangingPortion
77 #include <itratr.hxx>
78 #include <accessibilityoptions.hxx>
79 #include <wrong.hxx>
80 #include <doc.hxx>
81 #include <pam.hxx>
82 #include <SwGrammarMarkUp.hxx>
84 // --> FME 2004-06-08 #i12836# enhanced pdf export
85 #include <EnhancedPDFExportHelper.hxx>
86 // <--
88 #include <unomid.h>
90 using namespace ::com::sun::star;
91 using namespace ::com::sun::star::linguistic2;
92 using namespace ::com::sun::star::uno;
93 using namespace ::com::sun::star::beans;
96 #define CHAR_UNDERSCORE ((sal_Unicode)0x005F)
97 #define CHAR_LEFT_ARROW ((sal_Unicode)0x25C0)
98 #define CHAR_RIGHT_ARROW ((sal_Unicode)0x25B6)
99 #define CHAR_TAB ((sal_Unicode)0x2192)
100 #define CHAR_TAB_RTL ((sal_Unicode)0x2190)
101 #define CHAR_LINEBREAK ((sal_Unicode)0x21B5)
102 #define CHAR_LINEBREAK_RTL ((sal_Unicode)0x21B3)
104 #define DRAW_SPECIAL_OPTIONS_CENTER 1
105 #define DRAW_SPECIAL_OPTIONS_ROTATE 2
107 // --> OD 2006-06-27 #b6440955#
108 // variable moved to class <numfunc:GetDefBulletConfig>
109 //extern const sal_Char __FAR_DATA sBulletFntName[];
110 namespace numfunc
112 extern const String& GetDefBulletFontname();
113 extern bool IsDefBulletFontUserDefined();
115 // <--
117 #ifndef PRODUCT
118 // Test2: WYSIWYG++
119 // Test4: WYSIWYG debug
120 static sal_Bool bDbgLow = sal_False;
121 #endif
123 #ifndef PRODUCT
125 sal_Bool SwTxtSizeInfo::IsOptCalm() const { return !GetOpt().IsTest3(); }
127 sal_Bool SwTxtSizeInfo::IsOptLow() const { return bDbgLow; }
129 sal_Bool SwTxtSizeInfo::IsOptDbg() const { return GetOpt().IsTest4(); }
131 sal_Bool SwTxtSizeInfo::IsOptTest1() const { return GetOpt().IsTest1(); }
133 sal_Bool SwTxtSizeInfo::IsOptTest2() const { return GetOpt().IsTest2(); }
135 sal_Bool SwTxtSizeInfo::IsOptTest3() const { return GetOpt().IsTest3(); }
137 sal_Bool SwTxtSizeInfo::IsOptTest4() const { return GetOpt().IsTest4(); }
139 sal_Bool SwTxtSizeInfo::IsOptTest5() const { return GetOpt().IsTest5(); }
141 sal_Bool SwTxtSizeInfo::IsOptTest6() const { return GetOpt().IsTest6(); }
143 sal_Bool SwTxtSizeInfo::IsOptTest7() const { return GetOpt().IsTest7(); }
145 sal_Bool SwTxtSizeInfo::IsOptTest8() const { return GetOpt().IsTest8(); }
147 #endif
149 /*************************************************************************
150 * SwLineInfo::SwLineInfo()
151 *************************************************************************/
153 // --> OD 2008-01-17 #newlistlevelattrs#
154 SwLineInfo::SwLineInfo()
155 : pRuler( 0 ),
156 pSpace( 0 ),
157 nVertAlign( 0 ),
158 nDefTabStop( 0 ),
159 bListTabStopIncluded( false ),
160 nListTabStopPosition( 0 )
164 SwLineInfo::~SwLineInfo()
166 delete pRuler;
168 void SwLineInfo::CtorInitLineInfo( const SwAttrSet& rAttrSet,
169 const SwTxtNode& rTxtNode )
170 // <--
172 // --> OD 2008-01-17 #newlistlevelattrs#
173 // pRuler = &rAttrSet.GetTabStops();
174 delete pRuler;
175 pRuler = new SvxTabStopItem( rAttrSet.GetTabStops() );
176 if ( rTxtNode.GetListTabStopPosition( nListTabStopPosition ) )
178 bListTabStopIncluded = true;
180 // insert the list tab stop into SvxTabItem instance <pRuler>
181 const SvxTabStop aListTabStop( nListTabStopPosition,
182 SVX_TAB_ADJUST_LEFT );
183 pRuler->Insert( aListTabStop );
185 // remove default tab stops, which are before the inserted list tab stop
186 for ( USHORT i = 0; i < pRuler->Count(); i++ )
188 if ( (*pRuler)[i].GetTabPos() < nListTabStopPosition &&
189 (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
191 pRuler->Remove(i);
192 continue;
196 // <--
197 // --> OD 2008-02-15 #newlistlevelattrs#
198 if ( !rTxtNode.getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT) )
200 // remove default tab stop at position 0
201 for ( USHORT i = 0; i < pRuler->Count(); i++ )
203 if ( (*pRuler)[i].GetTabPos() == 0 &&
204 (*pRuler)[i].GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
206 pRuler->Remove(i);
207 break;
211 // <--
212 pSpace = &rAttrSet.GetLineSpacing();
213 nVertAlign = rAttrSet.GetParaVertAlign().GetValue();
214 nDefTabStop = MSHRT_MAX;
217 /*************************************************************************
218 * SwTxtInfo::CtorInitTxtInfo()
219 *************************************************************************/
221 void SwTxtInfo::CtorInitTxtInfo( SwTxtFrm *pFrm )
223 pPara = pFrm->GetPara();
224 nTxtStart = pFrm->GetOfst();
225 if( !pPara )
227 ASSERT( pPara, "+SwTxtInfo::CTOR: missing paragraph information" );
228 pFrm->Format();
229 pPara = pFrm->GetPara();
233 SwTxtInfo::SwTxtInfo( const SwTxtInfo &rInf )
234 : pPara( ((SwTxtInfo&)rInf).GetParaPortion() ),
235 nTxtStart( rInf.GetTxtStart() )
239 #ifndef PRODUCT
240 /*************************************************************************
241 * ChkOutDev()
242 *************************************************************************/
244 void ChkOutDev( const SwTxtSizeInfo &rInf )
246 if ( !rInf.GetVsh() )
247 return;
249 const OutputDevice* pOut = rInf.GetOut();
250 const OutputDevice* pRef = rInf.GetRefDev();
251 ASSERT( pOut && pRef, "ChkOutDev: invalid output devices" )
253 #endif // PRODUCT
256 inline xub_StrLen GetMinLen( const SwTxtSizeInfo &rInf )
258 const xub_StrLen nInfLen = rInf.GetIdx() + rInf.GetLen();
259 return Min( rInf.GetTxt().Len(), nInfLen );
263 SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew )
264 : SwTxtInfo( rNew ),
265 pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
266 pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
267 pOut(((SwTxtSizeInfo&)rNew).GetOut()),
268 pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
269 pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
270 pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
271 pFrm(rNew.pFrm),
272 pOpt(&rNew.GetOpt()),
273 pTxt(&rNew.GetTxt()),
274 nIdx(rNew.GetIdx()),
275 nLen(rNew.GetLen()),
276 nKanaIdx( rNew.GetKanaIdx() ),
277 bOnWin( rNew.OnWin() ),
278 bNotEOL( rNew.NotEOL() ),
279 bURLNotify( rNew.URLNotify() ),
280 bStopUnderFlow( rNew.StopUnderFlow() ),
281 bFtnInside( rNew.IsFtnInside() ),
282 bMulti( rNew.IsMulti() ),
283 bFirstMulti( rNew.IsFirstMulti() ),
284 bRuby( rNew.IsRuby() ),
285 bHanging( rNew.IsHanging() ),
286 bScriptSpace( rNew.HasScriptSpace() ),
287 bForbiddenChars( rNew.HasForbiddenChars() ),
288 bSnapToGrid( rNew.SnapToGrid() ),
289 nDirection( rNew.GetDirection() )
291 #ifndef PRODUCT
292 ChkOutDev( *this );
293 #endif
296 void SwTxtSizeInfo::CtorInitTxtSizeInfo( SwTxtFrm *pFrame, SwFont *pNewFnt,
297 const xub_StrLen nNewIdx, const xub_StrLen nNewLen )
299 pKanaComp = NULL;
300 nKanaIdx = 0;
301 pFrm = pFrame;
302 CtorInitTxtInfo( pFrm );
303 const SwTxtNode *pNd = pFrm->GetTxtNode();
304 pVsh = pFrm->GetShell();
306 // Get the output and reference device
307 if ( pVsh )
309 pOut = pVsh->GetOut();
310 pRef = &pVsh->GetRefDev();
311 bOnWin = pVsh->GetWin() || OUTDEV_WINDOW == pOut->GetOutDevType();
313 else
315 //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
316 if ( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
318 //in Ermangelung eines Besseren kann hier ja wohl nur noch das
319 //AppWin genommen werden?
320 pOut = GetpApp()->GetDefaultDevice();
322 else
323 pOut = pNd->getIDocumentDeviceAccess()->getPrinter( false );
325 pRef = pOut;
328 #ifndef PRODUCT
329 ChkOutDev( *this );
330 #endif
332 // Set default layout mode ( LTR or RTL ).
333 if ( pFrm->IsRightToLeft() )
335 pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
336 pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL );
337 nDirection = DIR_RIGHT2LEFT;
339 else
341 pOut->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
342 pRef->SetLayoutMode( TEXT_LAYOUT_BIDI_STRONG );
343 nDirection = DIR_LEFT2RIGHT;
346 /* LanguageType eLang;
347 const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions();
348 if ( SvtCTLOptions::NUMERALS_HINDI == rCTLOptions.GetCTLTextNumerals() )
349 eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
350 else if ( SvtCTLOptions::NUMERALS_ARABIC == rCTLOptions.GetCTLTextNumerals() )
351 eLang = LANGUAGE_ENGLISH;
352 else
353 eLang = (LanguageType)::GetAppLanguage();
355 pOut->SetDigitLanguage( eLang );
356 pRef->SetDigitLanguage( eLang );*/
359 // The Options
361 pOpt = pVsh ?
362 pVsh->GetViewOptions() :
363 SW_MOD()->GetViewOption( pNd->getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) ); //Options vom Module wg. StarONE
365 // bURLNotify wird gesetzt, wenn MakeGraphic dies vorbereitet
366 // TODO: Aufdr?seln
367 bURLNotify = pNoteURL && !bOnWin;
369 SetSnapToGrid( pNd->GetSwAttrSet().GetParaGrid().GetValue() &&
370 pFrm->IsInDocBody() );
372 pFnt = pNewFnt;
373 pUnderFnt = 0;
374 pTxt = &pNd->GetTxt();
376 nIdx = nNewIdx;
377 nLen = nNewLen;
378 bNotEOL = sal_False;
379 bStopUnderFlow = bFtnInside = sal_False;
380 bMulti = bFirstMulti = bRuby = bHanging = bScriptSpace =
381 bForbiddenChars = sal_False;
383 SetLen( GetMinLen( *this ) );
386 SwTxtSizeInfo::SwTxtSizeInfo( const SwTxtSizeInfo &rNew, const XubString &rTxt,
387 const xub_StrLen nIndex, const xub_StrLen nLength )
388 : SwTxtInfo( rNew ),
389 pKanaComp(((SwTxtSizeInfo&)rNew).GetpKanaComp()),
390 pVsh(((SwTxtSizeInfo&)rNew).GetVsh()),
391 pOut(((SwTxtSizeInfo&)rNew).GetOut()),
392 pRef(((SwTxtSizeInfo&)rNew).GetRefDev()),
393 pFnt(((SwTxtSizeInfo&)rNew).GetFont()),
394 pUnderFnt(((SwTxtSizeInfo&)rNew).GetUnderFnt()),
395 pFrm( rNew.pFrm ),
396 pOpt(&rNew.GetOpt()),
397 pTxt(&rTxt),
398 nIdx(nIndex),
399 nLen(nLength),
400 nKanaIdx( rNew.GetKanaIdx() ),
401 bOnWin( rNew.OnWin() ),
402 bNotEOL( rNew.NotEOL() ),
403 bURLNotify( rNew.URLNotify() ),
404 bStopUnderFlow( rNew.StopUnderFlow() ),
405 bFtnInside( rNew.IsFtnInside() ),
406 bMulti( rNew.IsMulti() ),
407 bFirstMulti( rNew.IsFirstMulti() ),
408 bRuby( rNew.IsRuby() ),
409 bHanging( rNew.IsHanging() ),
410 bScriptSpace( rNew.HasScriptSpace() ),
411 bForbiddenChars( rNew.HasForbiddenChars() ),
412 bSnapToGrid( rNew.SnapToGrid() ),
413 nDirection( rNew.GetDirection() )
415 #ifndef PRODUCT
416 ChkOutDev( *this );
417 #endif
418 SetLen( GetMinLen( *this ) );
421 /*************************************************************************
422 * SwTxtSizeInfo::SelectFont()
423 *************************************************************************/
425 void SwTxtSizeInfo::SelectFont()
427 // 8731: Der Weg muss ueber ChgPhysFnt gehen, sonst geraet
428 // der FontMetricCache durcheinander. In diesem Fall steht pLastMet
429 // auf dem alten Wert.
430 // Falsch: GetOut()->SetFont( GetFont()->GetFnt() );
431 GetFont()->Invalidate();
432 GetFont()->ChgPhysFnt( pVsh, *GetOut() );
435 /*************************************************************************
436 * SwTxtSizeInfo::NoteAnimation()
437 *************************************************************************/
439 void SwTxtSizeInfo::NoteAnimation() const
441 if( OnWin() )
442 SwRootFrm::FlushVout();
444 ASSERT( pOut == pVsh->GetOut(),
445 "SwTxtSizeInfo::NoteAnimation() changed pOut" )
448 /*************************************************************************
449 * SwTxtSizeInfo::GetTxtSize()
450 *************************************************************************/
452 SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev,
453 const SwScriptInfo* pSI,
454 const XubString& rTxt,
455 const xub_StrLen nIndex,
456 const xub_StrLen nLength,
457 const USHORT nComp ) const
459 SwDrawTextInfo aDrawInf( pVsh, *pOutDev, pSI, rTxt, nIndex, nLength );
460 aDrawInf.SetFrm( pFrm );
461 aDrawInf.SetFont( pFnt );
462 aDrawInf.SetSnapToGrid( SnapToGrid() );
463 aDrawInf.SetKanaComp( nComp );
464 SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
465 return aSize;
468 /*************************************************************************
469 * SwTxtSizeInfo::GetTxtSize()
470 *************************************************************************/
472 SwPosSize SwTxtSizeInfo::GetTxtSize() const
474 const SwScriptInfo& rSI =
475 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
477 // in some cases, compression is not allowed or surpressed for
478 // performance reasons
479 USHORT nComp =( SW_CJK == GetFont()->GetActual() &&
480 rSI.CountCompChg() &&
481 ! IsMulti() ) ?
482 GetKanaComp() :
485 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rSI, *pTxt, nIdx, nLen );
486 aDrawInf.SetFrm( pFrm );
487 aDrawInf.SetFont( pFnt );
488 aDrawInf.SetSnapToGrid( SnapToGrid() );
489 aDrawInf.SetKanaComp( nComp );
490 return pFnt->_GetTxtSize( aDrawInf );
493 /*************************************************************************
494 * SwTxtSizeInfo::GetTxtSize()
495 *************************************************************************/
497 void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const xub_StrLen nIndex,
498 const xub_StrLen nLength, const USHORT nComp,
499 USHORT& nMinSize, USHORT& nMaxSizeDiff ) const
501 SwDrawTextInfo aDrawInf( pVsh, *pOut, pSI, *pTxt, nIndex, nLength );
502 aDrawInf.SetFrm( pFrm );
503 aDrawInf.SetFont( pFnt );
504 aDrawInf.SetSnapToGrid( SnapToGrid() );
505 aDrawInf.SetKanaComp( nComp );
506 SwPosSize aSize = pFnt->_GetTxtSize( aDrawInf );
507 nMaxSizeDiff = (USHORT)aDrawInf.GetKanaDiff();
508 nMinSize = aSize.Width();
511 /*************************************************************************
512 * SwTxtSizeInfo::GetTxtBreak()
513 *************************************************************************/
515 xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
516 const xub_StrLen nMaxLen,
517 const USHORT nComp ) const
519 const SwScriptInfo& rScriptInfo =
520 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
522 ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" )
523 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
524 *pTxt, GetIdx(), nMaxLen );
525 aDrawInf.SetFrm( pFrm );
526 aDrawInf.SetFont( pFnt );
527 aDrawInf.SetSnapToGrid( SnapToGrid() );
528 aDrawInf.SetKanaComp( nComp );
529 aDrawInf.SetHyphPos( 0 );
531 return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
534 /*************************************************************************
535 * SwTxtSizeInfo::GetTxtBreak()
536 *************************************************************************/
538 xub_StrLen SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
539 const xub_StrLen nMaxLen,
540 const USHORT nComp,
541 xub_StrLen& rExtraCharPos ) const
543 const SwScriptInfo& rScriptInfo =
544 ( (SwParaPortion*)GetParaPortion() )->GetScriptInfo();
546 ASSERT( pRef == pOut, "GetTxtBreak is supposed to use the RefDev" )
547 SwDrawTextInfo aDrawInf( pVsh, *pOut, &rScriptInfo,
548 *pTxt, GetIdx(), nMaxLen );
549 aDrawInf.SetFrm( pFrm );
550 aDrawInf.SetFont( pFnt );
551 aDrawInf.SetSnapToGrid( SnapToGrid() );
552 aDrawInf.SetKanaComp( nComp );
553 aDrawInf.SetHyphPos( &rExtraCharPos );
555 return pFnt->GetTxtBreak( aDrawInf, nLineWidth );
558 /*************************************************************************
559 * SwTxtPaintInfo::CtorInitTxtPaintInfo()
560 *************************************************************************/
562 void SwTxtPaintInfo::CtorInitTxtPaintInfo( SwTxtFrm *pFrame, const SwRect &rPaint )
564 CtorInitTxtSizeInfo( pFrame );
565 aTxtFly.CtorInitTxtFly( pFrame ),
566 aPaintRect = rPaint;
567 nSpaceIdx = 0;
568 pSpaceAdd = NULL;
569 pWrongList = NULL;
570 pGrammarCheckList = NULL;
571 pSmartTags = NULL; // SMARTTAGS
573 #ifdef PRODUCT
574 pBrushItem = 0;
575 #else
576 pBrushItem = ((SvxBrushItem*)-1);
577 #endif
580 SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf, const XubString &rTxt )
581 : SwTxtSizeInfo( rInf, rTxt ),
582 pWrongList( rInf.GetpWrongList() ),
583 pGrammarCheckList( rInf.GetGrammarCheckList() ),
584 pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS
585 pSpaceAdd( rInf.GetpSpaceAdd() ),
586 pBrushItem( rInf.GetBrushItem() ),
587 aTxtFly( *rInf.GetTxtFly() ),
588 aPos( rInf.GetPos() ),
589 aPaintRect( rInf.GetPaintRect() ),
590 nSpaceIdx( rInf.GetSpaceIdx() )
593 SwTxtPaintInfo::SwTxtPaintInfo( const SwTxtPaintInfo &rInf )
594 : SwTxtSizeInfo( rInf ),
595 pWrongList( rInf.GetpWrongList() ),
596 pGrammarCheckList( rInf.GetGrammarCheckList() ),
597 pSmartTags( rInf.GetSmartTags() ), // SMARTTAGS
598 pSpaceAdd( rInf.GetpSpaceAdd() ),
599 pBrushItem( rInf.GetBrushItem() ),
600 aTxtFly( *rInf.GetTxtFly() ),
601 aPos( rInf.GetPos() ),
602 aPaintRect( rInf.GetPaintRect() ),
603 nSpaceIdx( rInf.GetSpaceIdx() )
606 extern Color aGlobalRetoucheColor;
608 /*************************************************************************
609 * lcl_IsDarkBackground
611 * Returns if the current background color is dark.
612 *************************************************************************/
614 sal_Bool lcl_IsDarkBackground( const SwTxtPaintInfo& rInf )
616 const Color* pCol = rInf.GetFont()->GetBackColor();
617 if( ! pCol || COL_TRANSPARENT == pCol->GetColor() )
619 const SvxBrushItem* pItem;
620 SwRect aOrigBackRect;
622 /// OD 21.08.2002
623 /// consider, that [GetBackgroundBrush(...)] can set <pCol>
624 /// - see implementation in /core/layout/paintfrm.cxx
625 /// OD 21.08.2002 #99657#
626 /// There is a background color, if there is a background brush and
627 /// its color is *not* "no fill"/"auto fill".
628 if( rInf.GetTxtFrm()->GetBackgroundBrush( pItem, pCol, aOrigBackRect, FALSE ) )
630 if ( !pCol )
631 pCol = &pItem->GetColor();
633 /// OD 30.08.2002 #99657#
634 /// determined color <pCol> can be <COL_TRANSPARENT>. Thus, check it.
635 if ( pCol->GetColor() == COL_TRANSPARENT)
636 pCol = NULL;
638 else
639 pCol = NULL;
643 if( !pCol )
644 pCol = &aGlobalRetoucheColor;
646 return pCol->IsDark();
649 /*************************************************************************
650 * SwTxtPaintInfo::_DrawText()
651 *************************************************************************/
653 void SwTxtPaintInfo::_DrawText( const XubString &rText, const SwLinePortion &rPor,
654 const xub_StrLen nStart, const xub_StrLen nLength,
655 const sal_Bool bKern, const sal_Bool bWrong,
656 const sal_Bool bSmartTag,
657 const sal_Bool bGrammarCheck ) // SMARTTAGS
659 if( !nLength )
660 return;
662 if( GetFont()->IsBlink() && OnWin() && rPor.Width() )
664 // check if accessibility options allow blinking portions:
665 const ViewShell* pSh = GetTxtFrm()->GetShell();
666 if ( pSh && ! pSh->GetAccessibilityOptions()->IsStopAnimatedText() &&
667 ! pSh->IsPreView() )
669 if( !pBlink )
670 pBlink = new SwBlink();
672 Point aPoint( aPos );
674 if ( GetTxtFrm()->IsRightToLeft() )
675 GetTxtFrm()->SwitchLTRtoRTL( aPoint );
677 if ( TEXT_LAYOUT_BIDI_STRONG != GetOut()->GetLayoutMode() )
678 aPoint.X() -= rPor.Width();
680 if ( GetTxtFrm()->IsVertical() )
681 GetTxtFrm()->SwitchHorizontalToVertical( aPoint );
683 pBlink->Insert( aPoint, &rPor, GetTxtFrm(), pFnt->GetOrientation() );
685 if( !pBlink->IsVisible() )
686 return;
688 else
690 delete pBlink;
691 pBlink = NULL;
695 // The SwScriptInfo is useless if we are inside a field portion
696 SwScriptInfo* pSI = 0;
697 if ( ! rPor.InFldGrp() )
698 pSI = &GetParaPortion()->GetScriptInfo();
700 // in some cases, kana compression is not allowed or surpressed for
701 // performance reasons
702 USHORT nComp = 0;
703 if ( ! IsMulti() )
704 nComp = GetKanaComp();
706 sal_Bool bCfgIsAutoGrammar = sal_False;
707 SvtLinguConfig().GetProperty( C2U( UPN_IS_GRAMMAR_AUTO ) ) >>= bCfgIsAutoGrammar;
708 const sal_Bool bBullet = OnWin() && GetOpt().IsBlank() && IsNoSymbol();
709 const sal_Bool bTmpWrong = bWrong && OnWin() && GetOpt().IsOnlineSpell();
710 const sal_Bool bTmpGrammarCheck = bGrammarCheck && OnWin() && bCfgIsAutoGrammar && GetOpt().IsOnlineSpell();
711 const sal_Bool bTmpSmart = bSmartTag && OnWin() && !GetOpt().IsPagePreview() && SwSmartTagMgr::Get().IsSmartTagsEnabled(); // SMARTTAGS
713 ASSERT( GetParaPortion(), "No paragraph!");
714 SwDrawTextInfo aDrawInf( pFrm->GetShell(), *pOut, pSI, rText, nStart, nLength,
715 rPor.Width(), bBullet );
717 aDrawInf.SetLeft( GetPaintRect().Left() );
718 aDrawInf.SetRight( GetPaintRect().Right() );
719 aDrawInf.SetUnderFnt( pUnderFnt );
721 const long nSpaceAdd = ( rPor.IsBlankPortion() || rPor.IsDropPortion() ||
722 rPor.InNumberGrp() ) ? 0 : GetSpaceAdd();
723 if ( nSpaceAdd )
725 xub_StrLen nCharCnt;
726 // --> FME 2005-04-04 #i41860# Thai justified alignemt needs some
727 // additional information:
728 aDrawInf.SetNumberOfBlanks( rPor.InTxtGrp() ?
729 static_cast<const SwTxtPortion&>(rPor).GetSpaceCnt( *this, nCharCnt ) :
730 0 );
731 // <--
734 aDrawInf.SetSpace( nSpaceAdd );
735 aDrawInf.SetKanaComp( nComp );
737 // the font is used to identify the current script via nActual
738 aDrawInf.SetFont( pFnt );
739 // the frame is used to identify the orientation
740 aDrawInf.SetFrm( GetTxtFrm() );
741 // we have to know if the paragraph should snap to grid
742 aDrawInf.SetSnapToGrid( SnapToGrid() );
743 // for underlining we must know when not to add extra space behind
744 // a character in justified mode
745 aDrawInf.SetSpaceStop( ! rPor.GetPortion() ||
746 rPor.GetPortion()->InFixMargGrp() ||
747 rPor.GetPortion()->IsHolePortion() );
749 if( GetTxtFly()->IsOn() )
751 // aPos muss als TopLeft vorliegen, weil die ClipRects sonst
752 // nicht berechnet werden koennen.
753 const Point aPoint( aPos.X(), aPos.Y() - rPor.GetAscent() );
754 const Size aSize( rPor.Width(), rPor.Height() );
755 aDrawInf.SetPos( aPoint );
756 aDrawInf.SetSize( aSize );
757 aDrawInf.SetAscent( rPor.GetAscent() );
758 aDrawInf.SetKern( bKern ? rPor.Width() : 0 );
759 aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
760 aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
761 aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS
762 GetTxtFly()->DrawTextOpaque( aDrawInf );
764 else
766 aDrawInf.SetPos( aPos );
767 if( bKern )
768 pFnt->_DrawStretchText( aDrawInf );
769 else
771 aDrawInf.SetWrong( bTmpWrong ? pWrongList : NULL );
772 aDrawInf.SetGrammarCheck( bTmpGrammarCheck ? pGrammarCheckList : NULL );
773 aDrawInf.SetSmartTags( bTmpSmart ? pSmartTags : NULL ); // SMARTTAGS
774 pFnt->_DrawText( aDrawInf );
779 /*************************************************************************
780 * SwTxtPaintInfo::CalcRect()
781 *************************************************************************/
783 void SwTxtPaintInfo::CalcRect( const SwLinePortion& rPor,
784 SwRect* pRect, SwRect* pIntersect ) const
786 Size aSize( rPor.Width(), rPor.Height() );
787 if( rPor.IsHangingPortion() )
788 aSize.Width() = ((SwHangingPortion&)rPor).GetInnerWidth();
789 if( rPor.InSpaceGrp() && GetSpaceAdd() )
791 SwTwips nAdd = rPor.CalcSpacing( GetSpaceAdd(), *this );
792 if( rPor.InFldGrp() && GetSpaceAdd() < 0 && nAdd )
793 nAdd += GetSpaceAdd() / SPACING_PRECISION_FACTOR;
794 aSize.Width() += nAdd;
797 Point aPoint;
799 if( IsRotated() )
801 long nTmp = aSize.Width();
802 aSize.Width() = aSize.Height();
803 aSize.Height() = nTmp;
804 if ( 1 == GetDirection() )
806 aPoint.A() = X() - rPor.GetAscent();
807 aPoint.B() = Y() - aSize.Height();
809 else
811 aPoint.A() = X() - rPor.Height() + rPor.GetAscent();
812 aPoint.B() = Y();
815 else
817 aPoint.A() = X();
818 aPoint.B() = Y() - rPor.GetAscent();
821 // Adjust x coordinate if we are inside a bidi portion
822 const BOOL bFrmDir = GetTxtFrm()->IsRightToLeft();
823 BOOL bCounterDir = ( ! bFrmDir && DIR_RIGHT2LEFT == GetDirection() ) ||
824 ( bFrmDir && DIR_LEFT2RIGHT == GetDirection() );
826 if ( bCounterDir )
827 aPoint.A() -= aSize.Width();
829 SwRect aRect( aPoint, aSize );
831 if ( GetTxtFrm()->IsRightToLeft() )
832 GetTxtFrm()->SwitchLTRtoRTL( aRect );
834 if ( GetTxtFrm()->IsVertical() )
835 GetTxtFrm()->SwitchHorizontalToVertical( aRect );
837 if ( pRect )
838 *pRect = aRect;
840 if( aRect.HasArea() && pIntersect )
842 ::SwAlignRect( aRect, (ViewShell*)GetVsh() );
844 if ( GetOut()->IsClipRegion() )
846 SwRect aClip( GetOut()->GetClipRegion().GetBoundRect() );
847 aRect.Intersection( aClip );
850 *pIntersect = aRect;
854 /*************************************************************************
855 * lcl_DrawSpecial
857 * Draws a special portion, e.g., line break portion, tab portion.
858 * rPor - The portion
859 * rRect - The rectangle surrounding the character
860 * pCol - Specify a color for the character
861 * bCenter - Draw the character centered, otherwise left aligned
862 * bRotate - Rotate the character if character rotation is set
863 *************************************************************************/
865 static void lcl_DrawSpecial( const SwTxtPaintInfo& rInf, const SwLinePortion& rPor,
866 SwRect& rRect, const Color* pCol, sal_Unicode cChar,
867 BYTE nOptions )
869 sal_Bool bCenter = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_CENTER );
870 sal_Bool bRotate = 0 != ( nOptions & DRAW_SPECIAL_OPTIONS_ROTATE );
872 // rRect is given in absolute coordinates
873 if ( rInf.GetTxtFrm()->IsRightToLeft() )
874 rInf.GetTxtFrm()->SwitchRTLtoLTR( rRect );
875 if ( rInf.GetTxtFrm()->IsVertical() )
876 rInf.GetTxtFrm()->SwitchVerticalToHorizontal( rRect );
878 const SwFont* pOldFnt = rInf.GetFont();
880 // Font is generated only once:
881 static SwFont* pFnt = 0;
882 if ( ! pFnt )
884 pFnt = new SwFont( *pOldFnt );
885 pFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
886 pFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
887 pFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
888 pFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
891 // Some of the current values are set at the font:
892 if ( ! bRotate )
893 pFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
894 else
895 pFnt->SetVertical( pOldFnt->GetOrientation() );
897 if ( pCol )
898 pFnt->SetColor( *pCol );
899 else
900 pFnt->SetColor( pOldFnt->GetColor() );
902 Size aFontSize( 0, SPECIAL_FONT_HEIGHT );
903 pFnt->SetSize( aFontSize, pFnt->GetActual() );
905 ((SwTxtPaintInfo&)rInf).SetFont( pFnt );
907 // The maximum width depends on the current orientation
908 const USHORT nDir = pFnt->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
909 SwTwips nMaxWidth = 0;
910 switch ( nDir )
912 case 0 :
913 nMaxWidth = rRect.Width();
914 break;
915 case 900 :
916 case 2700 :
917 nMaxWidth = rRect.Height();
918 break;
919 default:
920 ASSERT( sal_False, "Unknown direction set at font" )
921 break;
924 // check if char fits into rectangle
925 const XubString aTmp( cChar );
926 aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
927 while ( aFontSize.Width() > nMaxWidth )
929 SwTwips nFactor = ( 100 * aFontSize.Width() ) / nMaxWidth;
930 const SwTwips nOldWidth = aFontSize.Width();
932 // new height for font
933 const BYTE nAct = pFnt->GetActual();
934 aFontSize.Height() = ( 100 * pFnt->GetSize( nAct ).Height() ) / nFactor;
935 aFontSize.Width() = ( 100 * pFnt->GetSize( nAct).Width() ) / nFactor;
937 if ( !aFontSize.Width() && !aFontSize.Height() )
938 break;
940 pFnt->SetSize( aFontSize, nAct );
942 aFontSize = rInf.GetTxtSize( aTmp ).SvLSize();
944 if ( aFontSize.Width() >= nOldWidth )
945 break;
948 const Point aOldPos( rInf.GetPos() );
950 // adjust values so that tab is vertically and horizontally centered
951 SwTwips nX = rRect.Left();
952 SwTwips nY = rRect.Top();
953 switch ( nDir )
955 case 0 :
956 if ( bCenter )
957 nX += ( rRect.Width() - aFontSize.Width() ) / 2;
958 nY += ( rRect.Height() - aFontSize.Height() ) / 2 + rInf.GetAscent();
959 break;
960 case 900 :
961 if ( bCenter )
962 nX += ( rRect.Width() - aFontSize.Height() ) / 2 + rInf.GetAscent();
963 nY += ( rRect.Height() + aFontSize.Width() ) / 2;
964 break;
965 case 2700 :
966 if ( bCenter )
967 nX += ( rRect.Width() + aFontSize.Height() ) / 2 - rInf.GetAscent();
968 nY += ( rRect.Height() - aFontSize.Width() ) / 2;
969 break;
972 Point aTmpPos( nX, nY );
973 ((SwTxtPaintInfo&)rInf).SetPos( aTmpPos );
974 USHORT nOldWidth = rPor.Width();
975 ((SwLinePortion&)rPor).Width( (USHORT)aFontSize.Width() );
976 rInf.DrawText( aTmp, rPor );
977 ((SwLinePortion&)rPor).Width( nOldWidth );
978 ((SwTxtPaintInfo&)rInf).SetFont( (SwFont*)pOldFnt );
979 ((SwTxtPaintInfo&)rInf).SetPos( aOldPos );
982 /*************************************************************************
983 * SwTxtPaintInfo::DrawRect()
984 *************************************************************************/
986 void SwTxtPaintInfo::DrawRect( const SwRect &rRect, sal_Bool bNoGraphic,
987 sal_Bool bRetouche ) const
989 if ( OnWin() || !bRetouche )
991 if( aTxtFly.IsOn() )
992 ((SwTxtPaintInfo*)this)->GetTxtFly()->
993 DrawFlyRect( pOut, rRect, *this, bNoGraphic );
994 else if ( bNoGraphic )
995 pOut->DrawRect( rRect.SVRect() );
996 else
998 ASSERT( ((SvxBrushItem*)-1) != pBrushItem, "DrawRect: Uninitialized BrushItem!" );
999 ::DrawGraphic( pBrushItem, pOut, aItemRect, rRect );
1004 /*************************************************************************
1005 * SwTxtPaintInfo::DrawTab()
1006 *************************************************************************/
1008 void SwTxtPaintInfo::DrawTab( const SwLinePortion &rPor ) const
1010 if( OnWin() )
1012 SwRect aRect;
1013 CalcRect( rPor, &aRect );
1015 if ( ! aRect.HasArea() )
1016 return;
1018 const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
1019 CHAR_TAB_RTL : CHAR_TAB;
1020 const BYTE nOptions = DRAW_SPECIAL_OPTIONS_CENTER |
1021 DRAW_SPECIAL_OPTIONS_ROTATE;
1022 lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
1026 /*************************************************************************
1027 * SwTxtPaintInfo::DrawLineBreak()
1028 *************************************************************************/
1030 void SwTxtPaintInfo::DrawLineBreak( const SwLinePortion &rPor ) const
1032 if( OnWin() )
1034 KSHORT nOldWidth = rPor.Width();
1035 ((SwLinePortion&)rPor).Width( LINE_BREAK_WIDTH );
1037 SwRect aRect;
1038 CalcRect( rPor, &aRect );
1040 if( aRect.HasArea() )
1042 const sal_Unicode cChar = GetTxtFrm()->IsRightToLeft() ?
1043 CHAR_LINEBREAK_RTL : CHAR_LINEBREAK;
1044 const BYTE nOptions = 0;
1045 lcl_DrawSpecial( *this, rPor, aRect, 0, cChar, nOptions );
1048 ((SwLinePortion&)rPor).Width( nOldWidth );
1053 /*************************************************************************
1054 * SwTxtPaintInfo::DrawRedArrow()
1055 *************************************************************************/
1057 void SwTxtPaintInfo::DrawRedArrow( const SwLinePortion &rPor ) const
1059 Size aSize( SPECIAL_FONT_HEIGHT, SPECIAL_FONT_HEIGHT );
1060 SwRect aRect( ((SwArrowPortion&)rPor).GetPos(), aSize );
1061 sal_Unicode cChar;
1062 if( ((SwArrowPortion&)rPor).IsLeft() )
1064 aRect.Pos().Y() += 20 - GetAscent();
1065 aRect.Pos().X() += 20;
1066 if( aSize.Height() > rPor.Height() )
1067 aRect.Height( rPor.Height() );
1068 cChar = CHAR_LEFT_ARROW;
1070 else
1072 if( aSize.Height() > rPor.Height() )
1073 aRect.Height( rPor.Height() );
1074 aRect.Pos().Y() -= aRect.Height() + 20;
1075 aRect.Pos().X() -= aRect.Width() + 20;
1076 cChar = CHAR_RIGHT_ARROW;
1079 if ( GetTxtFrm()->IsVertical() )
1080 GetTxtFrm()->SwitchHorizontalToVertical( aRect );
1082 Color aCol( COL_LIGHTRED );
1084 if( aRect.HasArea() )
1086 const BYTE nOptions = 0;
1087 lcl_DrawSpecial( *this, rPor, aRect, &aCol, cChar, nOptions );
1092 /*************************************************************************
1093 * SwTxtPaintInfo::DrawPostIts()
1094 *************************************************************************/
1096 void SwTxtPaintInfo::DrawPostIts( const SwLinePortion&, sal_Bool bScript ) const
1098 if( OnWin() && pOpt->IsPostIts() )
1100 Size aSize;
1101 Point aTmp;
1103 const USHORT nPostItsWidth = pOpt->GetPostItsWidth( GetOut() );
1104 const USHORT nFontHeight = pFnt->GetHeight( pVsh, *GetOut() );
1105 const USHORT nFontAscent = pFnt->GetAscent( pVsh, *GetOut() );
1107 switch ( pFnt->GetOrientation( GetTxtFrm()->IsVertical() ) )
1109 case 0 :
1110 aSize.Width() = nPostItsWidth;
1111 aSize.Height() = nFontHeight;
1112 aTmp.X() = aPos.X();
1113 aTmp.Y() = aPos.Y() - nFontAscent;
1114 break;
1115 case 900 :
1116 aSize.Height() = nPostItsWidth;
1117 aSize.Width() = nFontHeight;
1118 aTmp.X() = aPos.X() - nFontAscent;
1119 aTmp.Y() = aPos.Y();
1120 break;
1121 case 2700 :
1122 aSize.Height() = nPostItsWidth;
1123 aSize.Width() = nFontHeight;
1124 aTmp.X() = aPos.X() - nFontHeight +
1125 nFontAscent;
1126 aTmp.Y() = aPos.Y();
1127 break;
1130 SwRect aTmpRect( aTmp, aSize );
1132 if ( GetTxtFrm()->IsRightToLeft() )
1133 GetTxtFrm()->SwitchLTRtoRTL( aTmpRect );
1135 if ( GetTxtFrm()->IsVertical() )
1136 GetTxtFrm()->SwitchHorizontalToVertical( aTmpRect );
1138 const Rectangle aRect( aTmpRect.SVRect() );
1139 pOpt->PaintPostIts( (OutputDevice*)GetOut(), aRect, bScript );
1144 void SwTxtPaintInfo::DrawCheckBox( const SwFieldFormPortion &rPor, bool checked) const
1146 SwRect aIntersect;
1147 CalcRect( rPor, &aIntersect, 0 );
1148 if ( aIntersect.HasArea() )
1150 if (OnWin() && SwViewOption::IsFieldShadings() &&
1151 !GetOpt().IsPagePreview())
1153 OutputDevice* pOut_ = (OutputDevice*)GetOut();
1154 pOut_->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
1155 pOut_->SetFillColor( SwViewOption::GetFieldShadingsColor() );
1156 pOut_->SetLineColor();
1157 pOut_->DrawRect( aIntersect.SVRect() );
1158 pOut_->Pop();
1160 const int delta=10;
1161 Rectangle r(aIntersect.Left()+delta, aIntersect.Top()+delta, aIntersect.Right()-delta, aIntersect.Bottom()-delta);
1162 pOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
1163 pOut->SetLineColor( Color(0, 0, 0));
1164 pOut->SetFillColor();
1165 pOut->DrawRect( r );
1166 if (checked) {
1167 pOut->DrawLine(r.TopLeft(), r.BottomRight());
1168 pOut->DrawLine(r.TopRight(), r.BottomLeft());
1170 pOut->Pop();
1174 /*************************************************************************
1175 * SwTxtPaintInfo::DrawBackGround()
1176 *************************************************************************/
1177 void SwTxtPaintInfo::DrawBackground( const SwLinePortion &rPor ) const
1179 ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer polution ?" );
1181 SwRect aIntersect;
1182 CalcRect( rPor, 0, &aIntersect );
1184 if ( aIntersect.HasArea() )
1186 OutputDevice* pTmpOut = (OutputDevice*)GetOut();
1187 pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
1189 // For dark background we do not want to have a filled rectangle
1190 if ( GetVsh() && GetVsh()->GetWin() && lcl_IsDarkBackground( *this ) )
1192 pTmpOut->SetLineColor( SwViewOption::GetFontColor().GetColor() );
1194 else
1196 pTmpOut->SetFillColor( SwViewOption::GetFieldShadingsColor() );
1197 pTmpOut->SetLineColor();
1200 DrawRect( aIntersect, sal_True );
1201 pTmpOut->Pop();
1205 void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
1208 SwRect aIntersect;
1209 CalcRect( rPor, &aIntersect, 0 );
1210 if(aIntersect.HasArea())
1212 SwTxtNode *pNd = pFrm->GetTxtNode();
1213 const ::sw::mark::IMark* pFieldmark = NULL;
1214 if(pNd)
1216 const SwDoc *doc=pNd->GetDoc();
1217 if(doc)
1219 SwIndex aIndex(pNd, GetIdx());
1220 SwPosition aPosition(*pNd, aIndex);
1221 pFieldmark=doc->getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
1224 bool bIsStartMark=(1==GetLen() && CH_TXT_ATR_FIELDSTART==GetTxt().GetChar(GetIdx()));
1225 if(pFieldmark) {
1226 OSL_TRACE("Found Fieldmark");
1227 #if DEBUG
1228 rtl::OUString str = pFieldmark->toString( );
1229 fprintf( stderr, "%s\n", rtl::OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr( ) );
1230 #endif
1232 if(bIsStartMark) OSL_TRACE("Found StartMark");
1233 if (OnWin() && (pFieldmark!=NULL || bIsStartMark) &&
1234 SwViewOption::IsFieldShadings() &&
1235 !GetOpt().IsPagePreview())
1237 OutputDevice* pOutDev = (OutputDevice*)GetOut();
1238 pOutDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
1239 pOutDev->SetFillColor( SwViewOption::GetFieldShadingsColor() );
1240 pOutDev->SetLineColor( );
1241 pOutDev->DrawRect( aIntersect.SVRect() );
1242 pOutDev->Pop();
1246 if( !pFnt->GetBackColor() ) return;
1248 ASSERT( pFnt->GetBackColor(), "DrawBackBrush: Lost Color" );
1250 SwRect aIntersect;
1251 CalcRect( rPor, 0, &aIntersect );
1253 if ( aIntersect.HasArea() )
1255 OutputDevice* pTmpOut = (OutputDevice*)GetOut();
1257 // --> FME 2004-06-24 #i16816# tagged pdf support
1258 SwTaggedPDFHelper aTaggedPDFHelper( 0, 0, 0, *pTmpOut );
1259 // <--
1261 pTmpOut->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
1263 pTmpOut->SetFillColor( *pFnt->GetBackColor() );
1264 pTmpOut->SetLineColor();
1266 DrawRect( aIntersect, sal_True, sal_False );
1268 pTmpOut->Pop();
1272 /*************************************************************************
1273 * SwTxtPaintInfo::DrawViewOpt()
1274 *************************************************************************/
1276 void SwTxtPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
1277 const MSHORT nWhich ) const
1279 if( OnWin() && !IsMulti() )
1281 sal_Bool bDraw = sal_False;
1282 switch( nWhich )
1284 case POR_FTN:
1285 case POR_QUOVADIS:
1286 case POR_NUMBER:
1287 case POR_FLD:
1288 case POR_URL:
1289 case POR_HIDDEN:
1290 case POR_TOX:
1291 case POR_REF :
1292 case POR_CONTROLCHAR:
1293 if ( !GetOpt().IsPagePreview() &&
1294 !GetOpt().IsReadonly() &&
1295 SwViewOption::IsFieldShadings() &&
1296 (POR_NUMBER != nWhich ||
1297 pFrm->GetTxtNode()->HasMarkedLabel())) // #i27615#
1298 bDraw = sal_True;
1299 break;
1300 case POR_TAB: if ( GetOpt().IsTab() ) bDraw = sal_True; break;
1301 case POR_SOFTHYPH: if ( GetOpt().IsSoftHyph() )bDraw = sal_True; break;
1302 case POR_BLANK: if ( GetOpt().IsHardBlank())bDraw = sal_True; break;
1303 default:
1305 ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
1306 break;
1309 if ( bDraw )
1310 DrawBackground( rPor );
1314 /*************************************************************************
1315 * SwTxtPaintInfo::_NotifyURL()
1316 *************************************************************************/
1318 void SwTxtPaintInfo::_NotifyURL( const SwLinePortion &rPor ) const
1320 ASSERT( pNoteURL, "NotifyURL: pNoteURL gone with the wind!" );
1322 SwRect aIntersect;
1323 CalcRect( rPor, 0, &aIntersect );
1325 if( aIntersect.HasArea() )
1327 SwTxtNode *pNd = (SwTxtNode*)GetTxtFrm()->GetTxtNode();
1328 SwIndex aIndex( pNd, GetIdx() );
1329 SwTxtAttr *pAttr = pNd->GetTxtAttr( aIndex, RES_TXTATR_INETFMT );
1330 if( pAttr )
1332 const SwFmtINetFmt& rFmt = pAttr->GetINetFmt();
1333 pNoteURL->InsertURLNote( rFmt.GetValue(), rFmt.GetTargetFrame(),
1334 aIntersect );
1339 /*************************************************************************
1340 * lcl_InitHyphValues()
1341 *************************************************************************/
1343 static void lcl_InitHyphValues( PropertyValues &rVals,
1344 INT16 nMinLeading, INT16 nMinTrailing )
1346 INT32 nLen = rVals.getLength();
1348 if (0 == nLen) // yet to be initialized?
1350 rVals.realloc( 2 );
1351 PropertyValue *pVal = rVals.getArray();
1353 pVal[0].Name = C2U( UPN_HYPH_MIN_LEADING );
1354 pVal[0].Handle = UPH_HYPH_MIN_LEADING;
1355 pVal[0].Value <<= nMinLeading;
1357 pVal[1].Name = C2U( UPN_HYPH_MIN_TRAILING );
1358 pVal[1].Handle = UPH_HYPH_MIN_TRAILING;
1359 pVal[1].Value <<= nMinTrailing;
1361 else if (2 == nLen) // already initialized once?
1363 PropertyValue *pVal = rVals.getArray();
1364 pVal[0].Value <<= nMinLeading;
1365 pVal[1].Value <<= nMinTrailing;
1367 else {
1368 DBG_ERROR( "unxpected size of sequence" );
1372 /*************************************************************************
1373 * SwTxtFormatInfo::GetHyphValues()
1374 *************************************************************************/
1376 const PropertyValues & SwTxtFormatInfo::GetHyphValues() const
1378 DBG_ASSERT( 2 == aHyphVals.getLength(),
1379 "hyphenation values not yet initialized" );
1380 return aHyphVals;
1383 /*************************************************************************
1384 * SwTxtFormatInfo::InitHyph()
1385 *************************************************************************/
1387 sal_Bool SwTxtFormatInfo::InitHyph( const sal_Bool bAutoHyphen )
1389 const SwAttrSet& rAttrSet = GetTxtFrm()->GetTxtNode()->GetSwAttrSet();
1390 SetHanging( rAttrSet.GetHangingPunctuation().GetValue() );
1391 SetScriptSpace( rAttrSet.GetScriptSpace().GetValue() );
1392 SetForbiddenChars( rAttrSet.GetForbiddenRule().GetValue() );
1393 const SvxHyphenZoneItem &rAttr = rAttrSet.GetHyphenZone();
1394 MaxHyph() = rAttr.GetMaxHyphens();
1395 sal_Bool bAuto = bAutoHyphen || rAttr.IsHyphen();
1396 if( bAuto || bInterHyph )
1398 nHyphStart = nHyphWrdStart = STRING_LEN;
1399 nHyphWrdLen = 0;
1401 const INT16 nMinimalLeading = Max(rAttr.GetMinLead(), sal_uInt8(2));
1402 const INT16 nMinimalTrailing = rAttr.GetMinTrail();
1403 lcl_InitHyphValues( aHyphVals, nMinimalLeading, nMinimalTrailing);
1405 return bAuto;
1408 /*************************************************************************
1409 * SwTxtFormatInfo::CtorInitTxtFormatInfo()
1410 *************************************************************************/
1412 void SwTxtFormatInfo::CtorInitTxtFormatInfo( SwTxtFrm *pNewFrm, const sal_Bool bNewInterHyph,
1413 const sal_Bool bNewQuick, const sal_Bool bTst )
1415 CtorInitTxtPaintInfo( pNewFrm, SwRect() );
1417 bQuick = bNewQuick;
1418 bInterHyph = bNewInterHyph;
1420 //! needs to be done in this order
1421 nMinLeading = 2;
1422 nMinTrailing = 2;
1423 nMinWordLength = 0;
1424 bAutoHyph = InitHyph();
1426 bIgnoreFly = sal_False;
1427 bFakeLineStart = sal_False;
1428 bShift = sal_False;
1429 bDropInit = sal_False;
1430 bTestFormat = bTst;
1431 nLeft = 0;
1432 nRight = 0;
1433 nFirst = 0;
1434 nRealWidth = 0;
1435 nForcedLeftMargin = 0;
1436 pRest = 0;
1437 nLineHeight = 0;
1438 nLineNettoHeight = 0;
1439 SetLineStart(0);
1440 Init();
1443 /*************************************************************************
1444 * SwTxtFormatInfo::IsHyphenate()
1445 *************************************************************************/
1446 // Trennen oder nicht trennen, das ist hier die Frage:
1447 // - in keinem Fall trennen, wenn der Hyphenator ERROR zurueckliefert,
1448 // oder wenn als Sprache NOLANGUAGE eingestellt ist.
1449 // - ansonsten immer trennen, wenn interaktive Trennung vorliegt
1450 // - wenn keine interakt. Trennung, dann nur trennen, wenn im ParaFmt
1451 // automatische Trennung eingestellt ist.
1453 sal_Bool SwTxtFormatInfo::IsHyphenate() const
1455 if( !bInterHyph && !bAutoHyph )
1456 return sal_False;
1458 LanguageType eTmp = GetFont()->GetLanguage();
1459 if( LANGUAGE_DONTKNOW == eTmp || LANGUAGE_NONE == eTmp )
1460 return sal_False;
1462 uno::Reference< XHyphenator > xHyph = ::GetHyphenator();
1463 if (bInterHyph && xHyph.is())
1464 SvxSpellWrapper::CheckHyphLang( xHyph, eTmp );
1466 if( !xHyph.is() || !xHyph->hasLocale( pBreakIt->GetLocale(eTmp) ) )
1467 return sal_False;
1468 return sal_True;
1471 /*************************************************************************
1472 * SwTxtFormatInfo::GetDropFmt()
1473 *************************************************************************/
1475 // Dropcaps vom SwTxtFormatter::CTOR gerufen.
1476 const SwFmtDrop *SwTxtFormatInfo::GetDropFmt() const
1478 const SwFmtDrop *pDrop = &GetTxtFrm()->GetTxtNode()->GetSwAttrSet().GetDrop();
1479 if( 1 >= pDrop->GetLines() ||
1480 ( !pDrop->GetChars() && !pDrop->GetWholeWord() ) )
1481 pDrop = 0;
1482 return pDrop;
1485 /*************************************************************************
1486 * SwTxtFormatInfo::Init()
1487 *************************************************************************/
1489 void SwTxtFormatInfo::Init()
1491 // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth
1492 X(0);
1493 bArrowDone = bFull = bFtnDone = bErgoDone = bNumDone = bNoEndHyph =
1494 bNoMidHyph = bStop = bNewLine = bUnderFlow = sal_False;
1496 // generally we do not allow number portions in follows, except...
1497 if ( GetTxtFrm()->IsFollow() )
1499 const SwTxtFrm* pMaster = GetTxtFrm()->FindMaster();
1500 const SwLinePortion* pTmpPara = pMaster->GetPara();
1502 // there is a master for this follow and the master does not have
1503 // any contents (especially it does not have a number portion)
1504 bNumDone = ! pTmpPara ||
1505 ! ((SwParaPortion*)pTmpPara)->GetFirstPortion()->IsFlyPortion();
1508 pRoot = 0;
1509 pLast = 0;
1510 pFly = 0;
1511 pLastFld = 0;
1512 pLastTab = 0;
1513 pUnderFlow = 0;
1514 cTabDecimal = 0;
1515 nWidth = nRealWidth;
1516 nForcedLeftMargin = 0;
1517 nSoftHyphPos = 0;
1518 nUnderScorePos = STRING_LEN;
1519 cHookChar = 0;
1520 SetIdx(0);
1521 SetLen( GetTxt().Len() );
1522 SetPaintOfst(0);
1525 /*-----------------16.10.00 11:39-------------------
1526 * There are a few differences between a copy constructor
1527 * and the following constructor for multi-line formatting.
1528 * The root is the first line inside the multi-portion,
1529 * the line start is the actual position in the text,
1530 * the line width is the rest width from the surrounding line
1531 * and the bMulti and bFirstMulti-flag has to be set correctly.
1532 * --------------------------------------------------*/
1534 SwTxtFormatInfo::SwTxtFormatInfo( const SwTxtFormatInfo& rInf,
1535 SwLineLayout& rLay, SwTwips nActWidth ) : SwTxtPaintInfo( rInf )
1537 pRoot = &rLay;
1538 pLast = &rLay;
1539 pFly = NULL;
1540 pLastFld = NULL;
1541 pUnderFlow = NULL;
1542 pRest = NULL;
1543 pLastTab = NULL;
1545 nSoftHyphPos = 0;
1546 nUnderScorePos = STRING_LEN;
1547 nHyphStart = 0;
1548 nHyphWrdStart = 0;
1549 nHyphWrdLen = 0;
1550 nLineStart = rInf.GetIdx();
1551 nLeft = rInf.nLeft;
1552 nRight = rInf.nRight;
1553 nFirst = rInf.nLeft;
1554 nRealWidth = KSHORT(nActWidth);
1555 nWidth = nRealWidth;
1556 nLineHeight = 0;
1557 nLineNettoHeight = 0;
1558 nForcedLeftMargin = 0;
1560 nMinLeading = 0;
1561 nMinTrailing = 0;
1562 nMinWordLength = 0;
1563 bFull = FALSE;
1564 bFtnDone = TRUE;
1565 bErgoDone = TRUE;
1566 bNumDone = TRUE;
1567 bArrowDone = TRUE;
1568 bStop = FALSE;
1569 bNewLine = TRUE;
1570 bShift = FALSE;
1571 bUnderFlow = FALSE;
1572 bInterHyph = FALSE;
1573 bAutoHyph = FALSE;
1574 bDropInit = FALSE;
1575 bQuick = rInf.bQuick;
1576 bNoEndHyph = FALSE;
1577 bNoMidHyph = FALSE;
1578 bIgnoreFly = FALSE;
1579 bFakeLineStart = FALSE;
1581 cTabDecimal = 0;
1582 cHookChar = 0;
1583 nMaxHyph = 0;
1584 bTestFormat = rInf.bTestFormat;
1585 SetMulti( sal_True );
1586 SetFirstMulti( rInf.IsFirstMulti() );
1589 /*************************************************************************
1590 * SwTxtFormatInfo::_CheckFtnPortion()
1591 *************************************************************************/
1593 sal_Bool SwTxtFormatInfo::_CheckFtnPortion( SwLineLayout* pCurr )
1595 KSHORT nHeight = pCurr->GetRealHeight();
1596 SwLinePortion *pPor = pCurr->GetPortion();
1597 sal_Bool bRet = sal_False;
1598 while( pPor )
1600 if( pPor->IsFtnPortion() && nHeight > ((SwFtnPortion*)pPor)->Orig() )
1602 bRet = sal_True;
1603 SetLineHeight( nHeight );
1604 SetLineNettoHeight( pCurr->Height() );
1605 break;
1607 pPor = pPor->GetPortion();
1609 return bRet;
1615 /*************************************************************************
1616 * SwTxtFormatInfo::ScanPortionEnd()
1617 *************************************************************************/
1618 xub_StrLen SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart,
1619 const xub_StrLen nEnd )
1621 cHookChar = 0;
1622 xub_StrLen i = nStart;
1625 // Used for decimal tab handling:
1627 const xub_Unicode cTabDec = GetLastTab() ? (sal_Unicode)GetTabDecimal() : 0;
1628 const xub_Unicode cThousandSep = ',' == cTabDec ? '.' : ',';
1629 // --> FME 2006-01-23 #i45951# German (Switzerland) uses ' as thousand separator:
1630 const xub_Unicode cThousandSep2 = ',' == cTabDec ? '.' : '\'';
1631 // <--
1633 bool bNumFound = false;
1634 const bool bTabCompat = GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
1636 // Removed for i7288. bSkip used to be passed from SwFldPortion::Format
1637 // as IsFollow(). Therefore more than one special character was not
1638 // handled correctly at the beginning of follow fields.
1639 // if ( bSkip && i < nEnd )
1640 // ++i;
1642 for( ; i < nEnd; ++i )
1644 const xub_Unicode cPos = GetChar( i );
1645 switch( cPos )
1647 case CH_TXTATR_BREAKWORD:
1648 case CH_TXTATR_INWORD:
1649 if( !HasHint( i ))
1650 break;
1651 // no break;
1653 case CHAR_SOFTHYPHEN:
1654 case CHAR_HARDHYPHEN:
1655 case CHAR_HARDBLANK:
1656 case CH_TAB:
1657 case CH_BREAK:
1658 case CHAR_ZWSP :
1659 case CHAR_ZWNBSP :
1660 // case CHAR_RLM :
1661 // case CHAR_LRM :
1662 cHookChar = cPos;
1663 return i;
1665 case CHAR_UNDERSCORE:
1666 if ( STRING_LEN == nUnderScorePos )
1667 nUnderScorePos = i;
1668 break;
1670 default:
1671 if ( cTabDec )
1673 if( cTabDec == cPos )
1675 ASSERT( cPos, "Unexpected end of string" );
1676 if( cPos ) // robust
1678 cHookChar = cPos;
1679 return i;
1684 // Compatibility: First non-digit character behind a
1685 // a digit character becomes the hook character
1687 if ( bTabCompat )
1689 if ( ( 0x2F < cPos && cPos < 0x3A ) ||
1690 ( bNumFound && ( cPos == cThousandSep || cPos == cThousandSep2 ) ) )
1692 bNumFound = true;
1694 else
1696 if ( bNumFound )
1698 cHookChar = cPos;
1699 SetTabDecimal( cPos );
1700 return i;
1708 // --> FME 2006-01-13 #130210# Check if character *behind* the portion has
1709 // to become the hook:
1710 if ( i == nEnd && i < GetTxt().Len() && bNumFound )
1712 const xub_Unicode cPos = GetChar( i );
1713 if ( cPos != cTabDec && cPos != cThousandSep && cPos !=cThousandSep2 && ( 0x2F >= cPos || cPos >= 0x3A ) )
1715 cHookChar = GetChar( i );
1716 SetTabDecimal( cHookChar );
1720 return i;
1723 BOOL SwTxtFormatInfo::LastKernPortion()
1725 if( GetLast() )
1727 if( GetLast()->IsKernPortion() )
1728 return TRUE;
1729 if( GetLast()->Width() || ( GetLast()->GetLen() &&
1730 !GetLast()->IsHolePortion() ) )
1731 return FALSE;
1733 SwLinePortion* pPor = GetRoot();
1734 SwLinePortion *pKern = NULL;
1735 while( pPor )
1737 if( pPor->IsKernPortion() )
1738 pKern = pPor;
1739 else if( pPor->Width() || ( pPor->GetLen() && !pPor->IsHolePortion() ) )
1740 pKern = NULL;
1741 pPor = pPor->GetPortion();
1743 if( pKern )
1745 SetLast( pKern );
1746 return TRUE;
1748 return FALSE;
1751 /*************************************************************************
1752 * class SwTxtSlot
1753 *************************************************************************/
1755 SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo *pNew, const SwLinePortion *pPor,
1756 bool bTxtLen, bool bExgLists, const sal_Char *pCh )
1757 : pOldTxt( 0 ),
1758 pOldSmartTagList( 0 ),
1759 pOldGrammarCheckList( 0 ),
1760 pTempList( 0 )
1762 if( pCh )
1764 aTxt = XubString( pCh, RTL_TEXTENCODING_MS_1252 );
1765 bOn = sal_True;
1767 else
1768 bOn = pPor->GetExpTxt( *pNew, aTxt );
1770 // Der Text wird ausgetauscht...
1771 if( bOn )
1773 pInf = (SwTxtSizeInfo*)pNew;
1774 nIdx = pInf->GetIdx();
1775 nLen = pInf->GetLen();
1776 pOldTxt = &(pInf->GetTxt());
1777 pInf->SetTxt( aTxt );
1778 pInf->SetIdx( 0 );
1779 pInf->SetLen( bTxtLen ? pInf->GetTxt().Len() : pPor->GetLen() );
1781 // ST2
1782 if ( bExgLists )
1784 pOldSmartTagList = static_cast<SwTxtPaintInfo*>(pInf)->GetSmartTags();
1785 if ( pOldSmartTagList )
1787 const USHORT nPos = pOldSmartTagList->GetWrongPos(nIdx);
1788 const xub_StrLen nListPos = pOldSmartTagList->Pos(nPos);
1789 if( nListPos == nIdx )
1790 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList->SubList( nPos ) );
1791 else if( !pTempList && nPos < pOldSmartTagList->Count() && nListPos < nIdx && aTxt.Len() )
1793 pTempList = new SwWrongList( WRONGLIST_SMARTTAG );
1794 pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 );
1795 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pTempList );
1797 else
1798 ((SwTxtPaintInfo*)pInf)->SetSmartTags( 0);
1800 pOldGrammarCheckList = static_cast<SwTxtPaintInfo*>(pInf)->GetGrammarCheckList();
1801 if ( pOldGrammarCheckList )
1803 const USHORT nPos = pOldGrammarCheckList->GetWrongPos(nIdx);
1804 const xub_StrLen nListPos = pOldGrammarCheckList->Pos(nPos);
1805 if( nListPos == nIdx )
1806 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList->SubList( nPos ) );
1807 else if( !pTempList && nPos < pOldGrammarCheckList->Count() && nListPos < nIdx && aTxt.Len() )
1809 pTempList = new SwWrongList( WRONGLIST_GRAMMAR );
1810 pTempList->Insert( rtl::OUString(), 0, 0, aTxt.Len(), 0 );
1811 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pTempList );
1813 else
1814 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( 0);
1820 /*************************************************************************
1821 * SwTxtSlot::~SwTxtSlot()
1822 *************************************************************************/
1824 SwTxtSlot::~SwTxtSlot()
1826 if( bOn )
1828 pInf->SetTxt( *pOldTxt );
1829 pInf->SetIdx( nIdx );
1830 pInf->SetLen( nLen );
1832 // ST2
1833 // Restore old smart tag list
1834 if ( pOldSmartTagList )
1835 ((SwTxtPaintInfo*)pInf)->SetSmartTags( pOldSmartTagList );
1836 if ( pOldGrammarCheckList )
1837 ((SwTxtPaintInfo*)pInf)->SetGrammarCheckList( pOldGrammarCheckList );
1838 delete pTempList;
1842 /*************************************************************************
1843 * SwFontSave::SwFontSave()
1844 *************************************************************************/
1846 SwFontSave::SwFontSave( const SwTxtSizeInfo &rInf, SwFont *pNew,
1847 SwAttrIter* pItr )
1848 : pFnt( pNew ? ((SwTxtSizeInfo&)rInf).GetFont() : 0 )
1850 if( pFnt )
1852 pInf = &((SwTxtSizeInfo&)rInf);
1853 // In these cases we temporarily switch to the new font:
1854 // 1. the fonts have a different magic number
1855 // 2. they have different script types
1856 // 3. their background colors differ (this is not covered by 1.)
1857 if( pFnt->DifferentMagic( pNew, pFnt->GetActual() ) ||
1858 pNew->GetActual() != pFnt->GetActual() ||
1859 ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) ||
1860 ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) ||
1861 ( pNew->GetBackColor() && pFnt->GetBackColor() &&
1862 ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) )
1864 pNew->SetTransparent( sal_True );
1865 pNew->SetAlign( ALIGN_BASELINE );
1866 pInf->SetFont( pNew );
1868 else
1869 pFnt = 0;
1870 pNew->Invalidate();
1871 pNew->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
1872 if( pItr && pItr->GetFnt() == pFnt )
1874 pIter = pItr;
1875 pIter->SetFnt( pNew );
1877 else
1878 pIter = NULL;
1882 /*************************************************************************
1883 * SwFontSave::~SwFontSave()
1884 *************************************************************************/
1886 SwFontSave::~SwFontSave()
1888 if( pFnt )
1890 // SwFont zurueckstellen
1891 pFnt->Invalidate();
1892 pInf->SetFont( pFnt );
1893 if( pIter )
1895 pIter->SetFnt( pFnt );
1896 pIter->nPos = STRING_LEN;
1901 /*************************************************************************
1902 * SwDefFontSave::SwDefFontSave()
1903 *************************************************************************/
1905 SwDefFontSave::SwDefFontSave( const SwTxtSizeInfo &rInf )
1906 : pFnt( ((SwTxtSizeInfo&)rInf).GetFont() )
1908 const BOOL bTmpAlter = pFnt->GetFixKerning() ||
1909 ( RTL_TEXTENCODING_SYMBOL == pFnt->GetCharSet(pFnt->GetActual()) )
1912 const sal_Bool bFamily = bTmpAlter &&
1913 pFnt->GetName( pFnt->GetActual() ) != numfunc::GetDefBulletFontname();
1914 const sal_Bool bRotation = (sal_Bool)pFnt->GetOrientation() &&
1915 ! rInf.GetTxtFrm()->IsVertical();
1917 if( bFamily || bRotation )
1919 pNewFnt = new SwFont( *pFnt );
1921 if ( bFamily )
1923 pNewFnt->SetFamily( FAMILY_DONTKNOW, pFnt->GetActual() );
1924 pNewFnt->SetName( numfunc::GetDefBulletFontname(), pFnt->GetActual() );
1925 pNewFnt->SetStyleName( aEmptyStr, pFnt->GetActual() );
1926 pNewFnt->SetCharSet( RTL_TEXTENCODING_SYMBOL, pFnt->GetActual() );
1927 pNewFnt->SetFixKerning( 0 );
1930 if ( bRotation )
1931 pNewFnt->SetVertical( 0, rInf.GetTxtFrm()->IsVertical() );
1933 pInf = &((SwTxtSizeInfo&)rInf);
1934 pNewFnt->Invalidate();
1935 pInf->SetFont( pNewFnt );
1937 else
1939 pFnt = 0;
1940 pNewFnt = 0;
1944 /*************************************************************************
1945 * SwDefFontSave::~SwDefFontSave()
1946 *************************************************************************/
1948 SwDefFontSave::~SwDefFontSave()
1950 if( pFnt )
1952 delete pNewFnt;
1953 // SwFont zurueckstellen
1954 pFnt->Invalidate();
1955 pInf->SetFont( pFnt );
1959 /*************************************************************************
1960 * SwTxtFormatInfo::ChgHyph()
1961 *************************************************************************/
1963 sal_Bool SwTxtFormatInfo::ChgHyph( const sal_Bool bNew )
1965 const sal_Bool bOld = bAutoHyph;
1966 if( bAutoHyph != bNew )
1968 bAutoHyph = bNew;
1969 InitHyph( bNew );
1970 // 5744: Sprache am Hyphenator einstellen.
1971 if( pFnt )
1972 pFnt->ChgPhysFnt( pVsh, *pOut );
1974 return bOld;