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>
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>
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
78 #include <accessibilityoptions.hxx>
82 #include <SwGrammarMarkUp.hxx>
84 // --> FME 2004-06-08 #i12836# enhanced pdf export
85 #include <EnhancedPDFExportHelper.hxx>
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[];
112 extern const String
& GetDefBulletFontname();
113 extern bool IsDefBulletFontUserDefined();
119 // Test4: WYSIWYG debug
120 static sal_Bool bDbgLow
= sal_False
;
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(); }
149 /*************************************************************************
150 * SwLineInfo::SwLineInfo()
151 *************************************************************************/
153 // --> OD 2008-01-17 #newlistlevelattrs#
154 SwLineInfo::SwLineInfo()
159 bListTabStopIncluded( false ),
160 nListTabStopPosition( 0 )
164 SwLineInfo::~SwLineInfo()
168 void SwLineInfo::CtorInitLineInfo( const SwAttrSet
& rAttrSet
,
169 const SwTxtNode
& rTxtNode
)
172 // --> OD 2008-01-17 #newlistlevelattrs#
173 // pRuler = &rAttrSet.GetTabStops();
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
)
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
)
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();
227 ASSERT( pPara
, "+SwTxtInfo::CTOR: missing paragraph information" );
229 pPara
= pFrm
->GetPara();
233 SwTxtInfo::SwTxtInfo( const SwTxtInfo
&rInf
)
234 : pPara( ((SwTxtInfo
&)rInf
).GetParaPortion() ),
235 nTxtStart( rInf
.GetTxtStart() )
240 /*************************************************************************
242 *************************************************************************/
244 void ChkOutDev( const SwTxtSizeInfo
&rInf
)
246 if ( !rInf
.GetVsh() )
249 const OutputDevice
* pOut
= rInf
.GetOut();
250 const OutputDevice
* pRef
= rInf
.GetRefDev();
251 ASSERT( pOut
&& pRef
, "ChkOutDev: invalid output devices" )
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
)
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()),
272 pOpt(&rNew
.GetOpt()),
273 pTxt(&rNew
.GetTxt()),
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() )
296 void SwTxtSizeInfo::CtorInitTxtSizeInfo( SwTxtFrm
*pFrame
, SwFont
*pNewFnt
,
297 const xub_StrLen nNewIdx
, const xub_StrLen nNewLen
)
302 CtorInitTxtInfo( pFrm
);
303 const SwTxtNode
*pNd
= pFrm
->GetTxtNode();
304 pVsh
= pFrm
->GetShell();
306 // Get the output and reference device
309 pOut
= pVsh
->GetOut();
310 pRef
= &pVsh
->GetRefDev();
311 bOnWin
= pVsh
->GetWin() || OUTDEV_WINDOW
== pOut
->GetOutDevType();
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();
323 pOut
= pNd
->getIDocumentDeviceAccess()->getPrinter( false );
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
;
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;
353 eLang = (LanguageType)::GetAppLanguage();
355 pOut->SetDigitLanguage( eLang );
356 pRef->SetDigitLanguage( eLang );*/
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
367 bURLNotify
= pNoteURL
&& !bOnWin
;
369 SetSnapToGrid( pNd
->GetSwAttrSet().GetParaGrid().GetValue() &&
370 pFrm
->IsInDocBody() );
374 pTxt
= &pNd
->GetTxt();
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
)
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()),
396 pOpt(&rNew
.GetOpt()),
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() )
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
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
);
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() &&
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
,
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
),
570 pGrammarCheckList
= NULL
;
571 pSmartTags
= NULL
; // SMARTTAGS
576 pBrushItem
= ((SvxBrushItem
*)-1);
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
;
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
) )
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
)
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
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() &&
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() )
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
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();
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
) :
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
);
766 aDrawInf
.SetPos( aPos
);
768 pFnt
->_DrawStretchText( aDrawInf
);
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
;
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();
811 aPoint
.A() = X() - rPor
.Height() + rPor
.GetAscent();
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() );
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
);
840 if( aRect
.HasArea() && pIntersect
)
842 ::SwAlignRect( aRect
, (ViewShell
*)GetVsh() );
844 if ( GetOut()->IsClipRegion() )
846 SwRect
aClip( GetOut()->GetClipRegion().GetBoundRect() );
847 aRect
.Intersection( aClip
);
854 /*************************************************************************
857 * Draws a special portion, e.g., line break portion, tab 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
,
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;
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:
893 pFnt
->SetVertical( 0, rInf
.GetTxtFrm()->IsVertical() );
895 pFnt
->SetVertical( pOldFnt
->GetOrientation() );
898 pFnt
->SetColor( *pCol
);
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;
913 nMaxWidth
= rRect
.Width();
917 nMaxWidth
= rRect
.Height();
920 ASSERT( sal_False
, "Unknown direction set at font" )
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() )
940 pFnt
->SetSize( aFontSize
, nAct
);
942 aFontSize
= rInf
.GetTxtSize( aTmp
).SvLSize();
944 if ( aFontSize
.Width() >= nOldWidth
)
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();
957 nX
+= ( rRect
.Width() - aFontSize
.Width() ) / 2;
958 nY
+= ( rRect
.Height() - aFontSize
.Height() ) / 2 + rInf
.GetAscent();
962 nX
+= ( rRect
.Width() - aFontSize
.Height() ) / 2 + rInf
.GetAscent();
963 nY
+= ( rRect
.Height() + aFontSize
.Width() ) / 2;
967 nX
+= ( rRect
.Width() + aFontSize
.Height() ) / 2 - rInf
.GetAscent();
968 nY
+= ( rRect
.Height() - aFontSize
.Width() ) / 2;
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
)
992 ((SwTxtPaintInfo
*)this)->GetTxtFly()->
993 DrawFlyRect( pOut
, rRect
, *this, bNoGraphic
);
994 else if ( bNoGraphic
)
995 pOut
->DrawRect( rRect
.SVRect() );
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
1013 CalcRect( rPor
, &aRect
);
1015 if ( ! aRect
.HasArea() )
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
1034 KSHORT nOldWidth
= rPor
.Width();
1035 ((SwLinePortion
&)rPor
).Width( LINE_BREAK_WIDTH
);
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
);
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
;
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() )
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() ) )
1110 aSize
.Width() = nPostItsWidth
;
1111 aSize
.Height() = nFontHeight
;
1112 aTmp
.X() = aPos
.X();
1113 aTmp
.Y() = aPos
.Y() - nFontAscent
;
1116 aSize
.Height() = nPostItsWidth
;
1117 aSize
.Width() = nFontHeight
;
1118 aTmp
.X() = aPos
.X() - nFontAscent
;
1119 aTmp
.Y() = aPos
.Y();
1122 aSize
.Height() = nPostItsWidth
;
1123 aSize
.Width() = nFontHeight
;
1124 aTmp
.X() = aPos
.X() - nFontHeight
+
1126 aTmp
.Y() = aPos
.Y();
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
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() );
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
);
1167 pOut
->DrawLine(r
.TopLeft(), r
.BottomRight());
1168 pOut
->DrawLine(r
.TopRight(), r
.BottomLeft());
1174 /*************************************************************************
1175 * SwTxtPaintInfo::DrawBackGround()
1176 *************************************************************************/
1177 void SwTxtPaintInfo::DrawBackground( const SwLinePortion
&rPor
) const
1179 ASSERT( OnWin(), "SwTxtPaintInfo::DrawBackground: printer polution ?" );
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() );
1196 pTmpOut
->SetFillColor( SwViewOption::GetFieldShadingsColor() );
1197 pTmpOut
->SetLineColor();
1200 DrawRect( aIntersect
, sal_True
);
1205 void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion
&rPor
) const
1209 CalcRect( rPor
, &aIntersect
, 0 );
1210 if(aIntersect
.HasArea())
1212 SwTxtNode
*pNd
= pFrm
->GetTxtNode();
1213 const ::sw::mark::IMark
* pFieldmark
= NULL
;
1216 const SwDoc
*doc
=pNd
->GetDoc();
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()));
1226 OSL_TRACE("Found Fieldmark");
1228 rtl::OUString str
= pFieldmark
->toString( );
1229 fprintf( stderr
, "%s\n", rtl::OUStringToOString( str
, RTL_TEXTENCODING_UTF8
).getStr( ) );
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() );
1246 if( !pFnt
->GetBackColor() ) return;
1248 ASSERT( pFnt
->GetBackColor(), "DrawBackBrush: Lost Color" );
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
);
1261 pTmpOut
->Push( PUSH_LINECOLOR
| PUSH_FILLCOLOR
);
1263 pTmpOut
->SetFillColor( *pFnt
->GetBackColor() );
1264 pTmpOut
->SetLineColor();
1266 DrawRect( aIntersect
, sal_True
, sal_False
);
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
;
1292 case POR_CONTROLCHAR
:
1293 if ( !GetOpt().IsPagePreview() &&
1294 !GetOpt().IsReadonly() &&
1295 SwViewOption::IsFieldShadings() &&
1296 (POR_NUMBER
!= nWhich
||
1297 pFrm
->GetTxtNode()->HasMarkedLabel())) // #i27615#
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;
1305 ASSERT( !this, "SwTxtPaintInfo::DrawViewOpt: don't know how to draw this" );
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!" );
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
);
1332 const SwFmtINetFmt
& rFmt
= pAttr
->GetINetFmt();
1333 pNoteURL
->InsertURLNote( rFmt
.GetValue(), rFmt
.GetTargetFrame(),
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?
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
;
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" );
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
;
1401 const INT16 nMinimalLeading
= Max(rAttr
.GetMinLead(), sal_uInt8(2));
1402 const INT16 nMinimalTrailing
= rAttr
.GetMinTrail();
1403 lcl_InitHyphValues( aHyphVals
, nMinimalLeading
, nMinimalTrailing
);
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() );
1418 bInterHyph
= bNewInterHyph
;
1420 //! needs to be done in this order
1424 bAutoHyph
= InitHyph();
1426 bIgnoreFly
= sal_False
;
1427 bFakeLineStart
= sal_False
;
1429 bDropInit
= sal_False
;
1435 nForcedLeftMargin
= 0;
1438 nLineNettoHeight
= 0;
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
)
1458 LanguageType eTmp
= GetFont()->GetLanguage();
1459 if( LANGUAGE_DONTKNOW
== eTmp
|| LANGUAGE_NONE
== eTmp
)
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
) ) )
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() ) )
1485 /*************************************************************************
1486 * SwTxtFormatInfo::Init()
1487 *************************************************************************/
1489 void SwTxtFormatInfo::Init()
1491 // Nicht initialisieren: pRest, nLeft, nRight, nFirst, nRealWidth
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();
1515 nWidth
= nRealWidth
;
1516 nForcedLeftMargin
= 0;
1518 nUnderScorePos
= STRING_LEN
;
1521 SetLen( GetTxt().Len() );
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
)
1546 nUnderScorePos
= STRING_LEN
;
1550 nLineStart
= rInf
.GetIdx();
1552 nRight
= rInf
.nRight
;
1553 nFirst
= rInf
.nLeft
;
1554 nRealWidth
= KSHORT(nActWidth
);
1555 nWidth
= nRealWidth
;
1557 nLineNettoHeight
= 0;
1558 nForcedLeftMargin
= 0;
1575 bQuick
= rInf
.bQuick
;
1579 bFakeLineStart
= FALSE
;
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
;
1600 if( pPor
->IsFtnPortion() && nHeight
> ((SwFtnPortion
*)pPor
)->Orig() )
1603 SetLineHeight( nHeight
);
1604 SetLineNettoHeight( pCurr
->Height() );
1607 pPor
= pPor
->GetPortion();
1615 /*************************************************************************
1616 * SwTxtFormatInfo::ScanPortionEnd()
1617 *************************************************************************/
1618 xub_StrLen
SwTxtFormatInfo::ScanPortionEnd( const xub_StrLen nStart
,
1619 const xub_StrLen nEnd
)
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
? '.' : '\'';
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 )
1642 for( ; i
< nEnd
; ++i
)
1644 const xub_Unicode cPos
= GetChar( i
);
1647 case CH_TXTATR_BREAKWORD
:
1648 case CH_TXTATR_INWORD
:
1653 case CHAR_SOFTHYPHEN
:
1654 case CHAR_HARDHYPHEN
:
1655 case CHAR_HARDBLANK
:
1665 case CHAR_UNDERSCORE
:
1666 if ( STRING_LEN
== nUnderScorePos
)
1673 if( cTabDec
== cPos
)
1675 ASSERT( cPos
, "Unexpected end of string" );
1676 if( cPos
) // robust
1684 // Compatibility: First non-digit character behind a
1685 // a digit character becomes the hook character
1689 if ( ( 0x2F < cPos
&& cPos
< 0x3A ) ||
1690 ( bNumFound
&& ( cPos
== cThousandSep
|| cPos
== cThousandSep2
) ) )
1699 SetTabDecimal( cPos
);
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
);
1723 BOOL
SwTxtFormatInfo::LastKernPortion()
1727 if( GetLast()->IsKernPortion() )
1729 if( GetLast()->Width() || ( GetLast()->GetLen() &&
1730 !GetLast()->IsHolePortion() ) )
1733 SwLinePortion
* pPor
= GetRoot();
1734 SwLinePortion
*pKern
= NULL
;
1737 if( pPor
->IsKernPortion() )
1739 else if( pPor
->Width() || ( pPor
->GetLen() && !pPor
->IsHolePortion() ) )
1741 pPor
= pPor
->GetPortion();
1751 /*************************************************************************
1753 *************************************************************************/
1755 SwTxtSlot::SwTxtSlot( const SwTxtSizeInfo
*pNew
, const SwLinePortion
*pPor
,
1756 bool bTxtLen
, bool bExgLists
, const sal_Char
*pCh
)
1758 pOldSmartTagList( 0 ),
1759 pOldGrammarCheckList( 0 ),
1764 aTxt
= XubString( pCh
, RTL_TEXTENCODING_MS_1252
);
1768 bOn
= pPor
->GetExpTxt( *pNew
, aTxt
);
1770 // Der Text wird ausgetauscht...
1773 pInf
= (SwTxtSizeInfo
*)pNew
;
1774 nIdx
= pInf
->GetIdx();
1775 nLen
= pInf
->GetLen();
1776 pOldTxt
= &(pInf
->GetTxt());
1777 pInf
->SetTxt( aTxt
);
1779 pInf
->SetLen( bTxtLen
? pInf
->GetTxt().Len() : pPor
->GetLen() );
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
);
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
);
1814 ((SwTxtPaintInfo
*)pInf
)->SetGrammarCheckList( 0);
1820 /*************************************************************************
1821 * SwTxtSlot::~SwTxtSlot()
1822 *************************************************************************/
1824 SwTxtSlot::~SwTxtSlot()
1828 pInf
->SetTxt( *pOldTxt
);
1829 pInf
->SetIdx( nIdx
);
1830 pInf
->SetLen( nLen
);
1833 // Restore old smart tag list
1834 if ( pOldSmartTagList
)
1835 ((SwTxtPaintInfo
*)pInf
)->SetSmartTags( pOldSmartTagList
);
1836 if ( pOldGrammarCheckList
)
1837 ((SwTxtPaintInfo
*)pInf
)->SetGrammarCheckList( pOldGrammarCheckList
);
1842 /*************************************************************************
1843 * SwFontSave::SwFontSave()
1844 *************************************************************************/
1846 SwFontSave::SwFontSave( const SwTxtSizeInfo
&rInf
, SwFont
*pNew
,
1848 : pFnt( pNew
? ((SwTxtSizeInfo
&)rInf
).GetFont() : 0 )
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
);
1871 pNew
->ChgPhysFnt( pInf
->GetVsh(), *pInf
->GetOut() );
1872 if( pItr
&& pItr
->GetFnt() == pFnt
)
1875 pIter
->SetFnt( pNew
);
1882 /*************************************************************************
1883 * SwFontSave::~SwFontSave()
1884 *************************************************************************/
1886 SwFontSave::~SwFontSave()
1890 // SwFont zurueckstellen
1892 pInf
->SetFont( pFnt
);
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
);
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 );
1931 pNewFnt
->SetVertical( 0, rInf
.GetTxtFrm()->IsVertical() );
1933 pInf
= &((SwTxtSizeInfo
&)rInf
);
1934 pNewFnt
->Invalidate();
1935 pInf
->SetFont( pNewFnt
);
1944 /*************************************************************************
1945 * SwDefFontSave::~SwDefFontSave()
1946 *************************************************************************/
1948 SwDefFontSave::~SwDefFontSave()
1953 // SwFont zurueckstellen
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
)
1970 // 5744: Sprache am Hyphenator einstellen.
1972 pFnt
->ChgPhysFnt( pVsh
, *pOut
);