xref: /trunk/main/svx/source/dialog/fntctrl.cxx (revision f6e50924)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 // include ---------------------------------------------------------------
28 #include <sfx2/viewsh.hxx>		// SfxViewShell
29 #include <sfx2/printer.hxx>		// Printer
30 #include <vcl/metric.hxx>
31 #include <vcl/svapp.hxx>
32 #include <unicode/uchar.h>
33 #include <com/sun/star/uno/Reference.h>
34 #include <com/sun/star/i18n/XBreakIterator.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <comphelper/processfactory.hxx>
37 
38 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
39 #include <com/sun/star/i18n/ScriptType.hdl>
40 #endif
41 
42 #ifndef _SVSTDARR_HXX
43 #define _SVSTDARR_USHORTS
44 #define _SVSTDARR_ULONGS
45 #define _SVSTDARR_XUB_STRLEN
46 #include <svl/svstdarr.hxx>
47 #endif
48 #include <svtools/colorcfg.hxx>
49 
50 #include <svx/fntctrl.hxx>
51 #include <svx/dialogs.hrc>
52 #define TEXT_WIDTH	20
53 
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::lang;
56 using ::com::sun::star::i18n::XBreakIterator;
57 
58 // -----------------------------------------------------------------------
59 // small helper functions to set fonts
60 // -----------------------------------------------------------------------
61 namespace
62 {
scaleFontWidth(Font & _rFont,const OutputDevice & rOutDev,long & _n100PercentFont)63 	void scaleFontWidth(Font& _rFont,const OutputDevice& rOutDev,long& _n100PercentFont)
64 	{
65 		_rFont.SetWidth( 0 );
66 		_n100PercentFont = rOutDev.GetFontMetric( _rFont ).GetWidth();
67 	}
68 	// -----------------------------------------------------------------------
initFont(Font & _rFont)69 	void initFont(Font& _rFont)
70 	{
71 		_rFont.SetTransparent(sal_True);
72 		_rFont.SetAlign(ALIGN_BASELINE);
73 	}
74 	// -----------------------------------------------------------------------
setFontSize(Font & _rFont)75 	void setFontSize(Font& _rFont)
76 	{
77 		Size aSize( _rFont.GetSize() );
78         aSize.Height() = ( aSize.Height() * 3 ) / 5;
79         aSize.Width() = ( aSize.Width() * 3 ) / 5;
80         _rFont.SetSize( aSize );
81 	}
82 	// -----------------------------------------------------------------------
calcFontHeightAnyAscent(OutputDevice * _pWin,Font & _rFont,long & _nHeight,long & _nAscent)83 	void calcFontHeightAnyAscent(OutputDevice* _pWin,Font& _rFont,long& _nHeight,long& _nAscent)
84 	{
85         if ( !_nHeight )
86         {
87             _pWin->SetFont( _rFont );
88             FontMetric aMetric( _pWin->GetFontMetric() );
89             _nHeight = aMetric.GetLineHeight();
90             _nAscent = aMetric.GetAscent();
91         }
92 	}
93 	// -----------------------------------------------------------------------
setFont(const SvxFont & rNewFont,SvxFont & rImplFont)94 	void setFont( const SvxFont& rNewFont, SvxFont& rImplFont )
95 	{
96 		rImplFont = rNewFont;
97 		rImplFont.SetTransparent( sal_True );
98 		rImplFont.SetAlign( ALIGN_BASELINE );
99 	}
100 
101 }
102 // -----------------------------------------------------------------------
103 
104 
105 // class FontPrevWin_Impl -----------------------------------------------
106 
107 class FontPrevWin_Impl
108 {
109 	friend class SvxFontPrevWindow;
110 
111 	SvxFont         				aFont;
112 	Printer*        				pPrinter;
113 	sal_Bool            				bDelPrinter;
114 
115 	Reference < XBreakIterator >	xBreak;
116 	SvULongs						aTextWidth;
117 	SvXub_StrLens					aScriptChg;
118 	SvUShorts						aScriptType;
119 	SvxFont							aCJKFont;
120 	SvxFont							aCTLFont;
121 	String							aText;
122 	String							aScriptText;
123 	Color*							pColor;
124 	Color*							pBackColor;
125 	long							nAscent;
126 	sal_Unicode						cStartBracket;
127 	sal_Unicode						cEndBracket;
128 
129 	long							n100PercentFontWidth;		// initial -1 -> not set yet
130 	long							n100PercentFontWidthCJK;
131 	long							n100PercentFontWidthCTL;
132 	sal_uInt16							nFontWidthScale;
133 
134 	sal_Bool							bSelection		: 1,
135 									bGetSelection   : 1,
136 									bUseResText     : 1,
137 									bTwoLines       : 1,
138 									bIsCJKUI        : 1,
139                                     bIsCTLUI        : 1,
140                                     bUseFontNameAsText : 1,
141                                     bTextInited     : 1;
142 
143 	void				_CheckScript();
144 public:
FontPrevWin_Impl()145 	inline FontPrevWin_Impl() :
146 		pPrinter( NULL ), bDelPrinter( sal_False ),
147         pColor( NULL ), pBackColor( 0 ),
148         cStartBracket( 0 ), cEndBracket( 0 ), nFontWidthScale( 100 ),
149         bSelection( sal_False ), bGetSelection( sal_False ), bUseResText( sal_False ),
150         bTwoLines( sal_False ),
151         bIsCJKUI( sal_False ), bIsCTLUI( sal_False ),
152         bUseFontNameAsText( sal_False ), bTextInited( sal_False )
153 		{
154 			Invalidate100PercentFontWidth();
155 		}
156 
~FontPrevWin_Impl()157 	inline ~FontPrevWin_Impl()
158 	{
159         delete pColor;
160         delete pBackColor;
161         if( bDelPrinter )
162 			delete pPrinter;
163 	}
164 
165 	void				CheckScript();
166     Size				CalcTextSize( OutputDevice* pWin, OutputDevice* pPrt, SvxFont &rFont );
167     void				DrawPrev( OutputDevice* pWin, Printer* pPrt, Point &rPt, SvxFont &rFont );
168 
169 	sal_Bool				SetFontWidthScale( sal_uInt16 nScaleInPercent );
170 	inline void			Invalidate100PercentFontWidth();
171 	inline sal_Bool			Is100PercentFontWidthValid() const;
172 	void				ScaleFontWidth( const OutputDevice& rOutDev );
173 							// scales rNonCJKFont and aCJKFont depending on nFontWidthScale and
174 							//  sets the 100%-Font-Widths
175 };
176 
CheckScript()177 void FontPrevWin_Impl::CheckScript()
178 {
179 	if( aText != aScriptText )
180 		_CheckScript();
181 }
182 
Invalidate100PercentFontWidth()183 inline void FontPrevWin_Impl::Invalidate100PercentFontWidth()
184 {
185 	n100PercentFontWidth = n100PercentFontWidthCJK = n100PercentFontWidthCTL = -1;
186 }
187 
Is100PercentFontWidthValid() const188 inline sal_Bool FontPrevWin_Impl::Is100PercentFontWidthValid() const
189 {
190 	DBG_ASSERT(	( n100PercentFontWidth == -1 && n100PercentFontWidthCJK == -1 ) ||
191 				( n100PercentFontWidth != -1 && n100PercentFontWidthCJK != -1 ) ||
192 				( n100PercentFontWidth == -1 && n100PercentFontWidthCTL == -1 ) ||
193 				( n100PercentFontWidth != -1 && n100PercentFontWidthCTL != -1 ),
194 				"*FontPrevWin_Impl::Is100PercentFontWidthValid(): 100PercentFontWidth's not synchronous" );
195 	return n100PercentFontWidth != -1;
196 }
197 
198 // class FontPrevWin_Impl -----------------------------------------------
199 
200 /*-----------------19.7.2001 08:44------------------
201  * void FontPrevWin_Impl::_CheckScript()
202  * evalutates the scripttypes of the actual string.
203  * Afterwards the positions of script change are notified in aScriptChg,
204  * the scripttypes in aScriptType.
205  * The aTextWidth array will be filled with zero.
206  * --------------------------------------------------*/
207 
_CheckScript()208 void FontPrevWin_Impl::_CheckScript()
209 {
210     aScriptText = aText;
211     size_t nCnt = aScriptChg.size();
212     if( nCnt )
213     {
214         aScriptChg.clear();
215         aScriptType.Remove( 0, nCnt );
216         aTextWidth.Remove( 0, nCnt );
217         nCnt = 0;
218     }
219     if( !xBreak.is() )
220     {
221         Reference< XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
222         xBreak = Reference< XBreakIterator >(xMSF->createInstance(
223 				::rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ),UNO_QUERY);
224     }
225     if( xBreak.is() )
226     {
227         sal_uInt16 nScript = xBreak->getScriptType( aText, 0 );
228         sal_uInt16 nChg = 0;
229         if( com::sun::star::i18n::ScriptType::WEAK == nScript )
230         {
231             nChg = (xub_StrLen)xBreak->endOfScript( aText, nChg, nScript );
232             if( nChg < aText.Len() )
233                 nScript = xBreak->getScriptType( aText, nChg );
234             else
235                 nScript = com::sun::star::i18n::ScriptType::LATIN;
236         }
237 
238         do
239         {
240             nChg = (xub_StrLen)xBreak->endOfScript( aText, nChg, nScript );
241             if (nChg < aText.Len() && nChg > 0 &&
242                 (com::sun::star::i18n::ScriptType::WEAK ==
243                  xBreak->getScriptType(aText, nChg - 1)))
244             {
245                 int8_t nType = u_charType(aText.GetChar(nChg) );
246                 if (nType == U_NON_SPACING_MARK || nType == U_ENCLOSING_MARK ||
247                     nType == U_COMBINING_SPACING_MARK )
248                 {
249                     aScriptChg.push_back( nChg - 1 );
250                 }
251                 else
252                 {
253                     aScriptChg.push_back( nChg );
254                 }
255             }
256             else
257             {
258                 aScriptChg.push_back( nChg );
259             }
260             aScriptType.Insert( nScript, nCnt );
261             aTextWidth.Insert( sal_uIntPtr(0), nCnt++ );
262 
263             if( nChg < aText.Len() )
264                 nScript = xBreak->getScriptType( aText, nChg );
265             else
266                 break;
267         } while( sal_True );
268     }
269 }
270 
271 /*-----------------19.7.2001 08:48------------------
272  * Size FontPrevWin_Impl::CalcTextSize(..)
273  * fills the aTextWidth array with the text width of every part
274  * of the actual string without a script change inside.
275  * For Latin parts the given rFont will be used,
276  * for Asian parts the aCJKFont.
277  * The returned size contains the whole string.
278  * The member nAscent is calculated to the maximal ascent of all used fonts.
279  * --------------------------------------------------*/
280 
CalcTextSize(OutputDevice * pWin,OutputDevice * _pPrinter,SvxFont & rFont)281 Size FontPrevWin_Impl::CalcTextSize( OutputDevice* pWin, OutputDevice* _pPrinter,
282     SvxFont &rFont )
283 {
284     sal_uInt16 nScript;
285     sal_uInt16 nIdx = 0;
286     xub_StrLen nStart = 0;
287     xub_StrLen nEnd;
288     size_t nCnt = aScriptChg.size();
289     if( nCnt )
290     {
291         nEnd = aScriptChg[ nIdx ];
292         nScript = aScriptType[ nIdx ];
293     }
294     else
295     {
296         nEnd = aText.Len();
297         nScript = com::sun::star::i18n::ScriptType::LATIN;
298     }
299     long nTxtWidth = 0;
300     long nCJKHeight = 0;
301 	long nCTLHeight = 0;
302     long nHeight = 0;
303     nAscent = 0;
304     long nCJKAscent = 0;
305 	long nCTLAscent = 0;
306     do
307     {
308         SvxFont& rFnt = (nScript==com::sun::star::i18n::ScriptType::ASIAN) ? aCJKFont : ((nScript==com::sun::star::i18n::ScriptType::COMPLEX) ? aCTLFont : rFont);
309         sal_uIntPtr nWidth = rFnt.GetTxtSize( _pPrinter, aText, nStart, nEnd-nStart ).
310                        Width();
311         aTextWidth[ nIdx++ ] = nWidth;
312         nTxtWidth += nWidth;
313 		switch(nScript)
314 		{
315 			case com::sun::star::i18n::ScriptType::ASIAN:
316 				calcFontHeightAnyAscent(pWin,aCJKFont,nCJKHeight,nCJKAscent);
317 				break;
318 			case com::sun::star::i18n::ScriptType::COMPLEX:
319 				calcFontHeightAnyAscent(pWin,aCTLFont,nCTLHeight,nCTLAscent);
320 				break;
321 			default:
322 				calcFontHeightAnyAscent(pWin,rFont,nHeight,nAscent);
323 		}
324 
325         if( nEnd < aText.Len() && nIdx < nCnt )
326         {
327             nStart = nEnd;
328             nEnd = aScriptChg[ nIdx ];
329             nScript = aScriptType[ nIdx ];
330         }
331         else
332             break;
333     }
334     while( sal_True );
335     nHeight -= nAscent;
336     nCJKHeight -= nCJKAscent;
337 	nCTLHeight -= nCTLAscent;
338     if( nHeight < nCJKHeight )
339         nHeight = nCJKHeight;
340     if( nAscent < nCJKAscent )
341         nAscent = nCJKAscent;
342 	if( nHeight < nCTLHeight )
343         nHeight = nCTLHeight;
344     if( nAscent < nCTLAscent )
345         nAscent = nCTLAscent;
346     nHeight += nAscent;
347 
348     Size aTxtSize( nTxtWidth, nHeight );
349     return aTxtSize;
350 }
351 
352 /*-----------------19.7.2001 08:54------------------
353  * void FontPrevWin_Impl::DrawPrev(..)
354  * calls SvxFont::DrawPrev(..) for every part of the string without a script
355  * change inside, for Asian parts the aCJKFont will be used, otherwise the
356  * given rFont.
357  * --------------------------------------------------*/
358 
DrawPrev(OutputDevice * pWin,Printer * _pPrinter,Point & rPt,SvxFont & rFont)359 void FontPrevWin_Impl::DrawPrev( OutputDevice* pWin, Printer* _pPrinter,
360     Point &rPt, SvxFont &rFont )
361 {
362     Font aOldFont = _pPrinter->GetFont();
363     sal_uInt16 nScript;
364     sal_uInt16 nIdx = 0;
365     xub_StrLen nStart = 0;
366     xub_StrLen nEnd;
367     size_t nCnt = aScriptChg.size();
368     if( nCnt )
369     {
370         nEnd = aScriptChg[ nIdx ];
371         nScript = aScriptType[ nIdx ];
372     }
373     else
374     {
375         nEnd = aText.Len();
376         nScript = com::sun::star::i18n::ScriptType::LATIN;
377     }
378     do
379     {
380         SvxFont& rFnt = (nScript==com::sun::star::i18n::ScriptType::ASIAN) ? aCJKFont : ((nScript==com::sun::star::i18n::ScriptType::COMPLEX) ? aCTLFont : rFont);
381         _pPrinter->SetFont( rFnt );
382 
383         rFnt.DrawPrev( pWin, _pPrinter, rPt, aText, nStart, nEnd - nStart );
384 
385         rPt.X() += aTextWidth[ nIdx++ ];
386         if( nEnd < aText.Len() && nIdx < nCnt )
387         {
388             nStart = nEnd;
389             nEnd = aScriptChg[ nIdx ];
390             nScript = aScriptType[ nIdx ];
391         }
392         else
393             break;
394     }
395     while( sal_True );
396     _pPrinter->SetFont( aOldFont );
397 }
398 
399 // -----------------------------------------------------------------------
400 
SetFontWidthScale(sal_uInt16 nScale)401 sal_Bool FontPrevWin_Impl::SetFontWidthScale( sal_uInt16 nScale )
402 {
403 	if( nFontWidthScale != nScale )
404 	{
405 		nFontWidthScale = nScale;
406 		return sal_True;
407 	}
408 
409 	return sal_False;
410 }
411 
412 
413 // -----------------------------------------------------------------------
414 
ScaleFontWidth(const OutputDevice & rOutDev)415 void FontPrevWin_Impl::ScaleFontWidth( const OutputDevice& rOutDev )
416 {
417 	if( !Is100PercentFontWidthValid() )
418 	{
419 		scaleFontWidth(aFont,rOutDev,n100PercentFontWidth);
420 		scaleFontWidth(aCJKFont,rOutDev,n100PercentFontWidthCJK);
421 		scaleFontWidth(aCTLFont,rOutDev,n100PercentFontWidthCTL);
422 	}
423 
424 	aFont.SetWidth( n100PercentFontWidth * nFontWidthScale / 100 );
425 	aCJKFont.SetWidth( n100PercentFontWidthCJK * nFontWidthScale / 100 );
426 	aCTLFont.SetWidth( n100PercentFontWidthCTL * nFontWidthScale / 100 );
427 }
428 
429 // class SvxFontPrevWindow -----------------------------------------------
430 
InitSettings(sal_Bool bForeground,sal_Bool bBackground)431 void SvxFontPrevWindow::InitSettings( sal_Bool bForeground, sal_Bool bBackground )
432 {
433 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
434 
435 	if ( bForeground )
436 	{
437 		svtools::ColorConfig aColorConfig;
438 		Color aTextColor( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
439 
440 		if ( IsControlForeground() )
441 			aTextColor = GetControlForeground();
442 		SetTextColor( aTextColor );
443 	}
444 
445 	if ( bBackground )
446 	{
447 		if ( IsControlBackground() )
448 			SetBackground( GetControlBackground() );
449 		else
450 			SetBackground( rStyleSettings.GetWindowColor() );
451 	}
452 	Invalidate();
453 }
454 
455 // -----------------------------------------------------------------------
456 
SvxFontPrevWindow(Window * pParent,const ResId & rId)457 SvxFontPrevWindow::SvxFontPrevWindow( Window* pParent, const ResId& rId ) :
458 
459 	Window     ( pParent, rId )
460 {
461 	pImpl = new FontPrevWin_Impl;
462 	SfxViewShell* pSh = SfxViewShell::Current();
463 
464 	if ( pSh )
465 		pImpl->pPrinter = pSh->GetPrinter();
466 
467 	if ( !pImpl->pPrinter )
468 	{
469 		pImpl->pPrinter = new Printer;
470 		pImpl->bDelPrinter = sal_True;
471 	}
472 	SetMapMode( MapMode( MAP_TWIP ) );
473 	initFont(pImpl->aFont);
474 	initFont(pImpl->aCJKFont);
475 	initFont(pImpl->aCTLFont);
476 	InitSettings( sal_True, sal_True );
477     SetBorderStyle( WINDOW_BORDER_MONO );
478 
479     LanguageType eLanguage = Application::GetSettings().GetUILanguage();
480     switch( eLanguage )
481     {
482         case LANGUAGE_CHINESE:
483         case LANGUAGE_JAPANESE:
484         case LANGUAGE_KOREAN:
485         case LANGUAGE_KOREAN_JOHAB:
486         case LANGUAGE_CHINESE_SIMPLIFIED:
487         case LANGUAGE_CHINESE_HONGKONG:
488         case LANGUAGE_CHINESE_SINGAPORE:
489         case LANGUAGE_CHINESE_MACAU:
490         case LANGUAGE_CHINESE_TRADITIONAL:
491             pImpl->bIsCJKUI = sal_True;
492             break;
493         // TODO: CTL Locale
494         //  pImpl->bIsCTLUI = sal_True;
495         //  break;
496         default:
497             pImpl->bIsCJKUI = pImpl->bIsCTLUI = sal_False;
498             break;
499     }
500 }
501 
502 // -----------------------------------------------------------------------
503 
~SvxFontPrevWindow()504 SvxFontPrevWindow::~SvxFontPrevWindow()
505 {
506     delete pImpl;
507 }
508 
509 // -----------------------------------------------------------------------
GetCTLFont()510 SvxFont& SvxFontPrevWindow::GetCTLFont()
511 {
512     return pImpl->aCTLFont;
513 }
514 
515 // -----------------------------------------------------------------------
516 
GetCJKFont()517 SvxFont& SvxFontPrevWindow::GetCJKFont()
518 {
519     return pImpl->aCJKFont;
520 }
521 
522 // -----------------------------------------------------------------------
523 
StateChanged(StateChangedType nType)524 void SvxFontPrevWindow::StateChanged( StateChangedType nType )
525 {
526 	if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
527 		InitSettings( sal_True, sal_False );
528 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
529 		InitSettings( sal_False, sal_True );
530 
531 	Window::StateChanged( nType );
532 }
533 
534 // -----------------------------------------------------------------------
535 
DataChanged(const DataChangedEvent & rDCEvt)536 void SvxFontPrevWindow::DataChanged( const DataChangedEvent& rDCEvt )
537 {
538 	if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
539 		InitSettings( sal_True, sal_True );
540 	else
541 		Window::DataChanged( rDCEvt );
542 }
543 
GetFont()544 SvxFont& SvxFontPrevWindow::GetFont()
545 {
546 	pImpl->Invalidate100PercentFontWidth();		// because the user might change the size
547 	return pImpl->aFont;
548 }
549 
GetFont() const550 const SvxFont& SvxFontPrevWindow::GetFont() const
551 {
552 	return pImpl->aFont;
553 }
554 
555 // -----------------------------------------------------------------------
556 
SetPreviewText(const::rtl::OUString & rString)557 void SvxFontPrevWindow::SetPreviewText( const ::rtl::OUString& rString )
558 {
559     pImpl->aText = rString;
560     pImpl->bTextInited = sal_True;
561 }
562 
563 // -----------------------------------------------------------------------
564 
SetFontNameAsPreviewText()565 void SvxFontPrevWindow::SetFontNameAsPreviewText()
566 {
567     pImpl->bUseFontNameAsText = sal_True;
568 }
569 
570 // -----------------------------------------------------------------------
571 
SetFont(const SvxFont & rOutFont)572 void SvxFontPrevWindow::SetFont( const SvxFont& rOutFont )
573 {
574 	setFont( rOutFont, pImpl->aFont );
575 
576 	pImpl->Invalidate100PercentFontWidth();
577 	Invalidate();
578 }
579 
580 // -----------------------------------------------------------------------
581 
SetFont(const SvxFont & rNormalOutFont,const SvxFont & rCJKOutFont,const SvxFont & rCTLFont)582 void SvxFontPrevWindow::SetFont( const SvxFont& rNormalOutFont, const SvxFont& rCJKOutFont, const SvxFont& rCTLFont )
583 {
584 	setFont( rNormalOutFont, pImpl->aFont );
585 	setFont( rCJKOutFont, pImpl->aCJKFont );
586 	setFont( rCTLFont, pImpl->aCTLFont );
587 
588 
589 	pImpl->Invalidate100PercentFontWidth();
590 	Invalidate();
591 }
592 
593 // -----------------------------------------------------------------------
594 
SetCJKFont(const SvxFont & rCJKOutFont)595 void SvxFontPrevWindow::SetCJKFont( const SvxFont &rCJKOutFont )
596 {
597 	setFont( rCJKOutFont, pImpl->aCJKFont );
598 
599 	pImpl->Invalidate100PercentFontWidth();
600 	Invalidate();
601 }
602 // -----------------------------------------------------------------------------
SetCTLFont(const SvxFont & rCTLOutFont)603 void SvxFontPrevWindow::SetCTLFont( const SvxFont &rCTLOutFont )
604 {
605 	setFont( rCTLOutFont, pImpl->aCTLFont );
606 
607 	pImpl->Invalidate100PercentFontWidth();
608 	Invalidate();
609 }
610 
611 // -----------------------------------------------------------------------
612 
SetColor(const Color & rColor)613 void SvxFontPrevWindow::SetColor(const Color &rColor)
614 {
615 	delete pImpl->pColor;
616 	pImpl->pColor = new Color( rColor );
617 	Invalidate();
618 }
619 // -----------------------------------------------------------------------
620 
ResetColor()621 void SvxFontPrevWindow::ResetColor()
622 {
623     delete pImpl->pColor;
624     pImpl->pColor = 0;
625     Invalidate();
626 }
627 
628 // -----------------------------------------------------------------------
629 
SetBackColor(const Color & rColor)630 void SvxFontPrevWindow::SetBackColor(const Color &rColor)
631 {
632     delete pImpl->pBackColor;
633     pImpl->pBackColor = new Color( rColor );
634 	Invalidate();
635 }
636 
637 // -----------------------------------------------------------------------
638 
UseResourceText(sal_Bool bUse)639 void SvxFontPrevWindow::UseResourceText( sal_Bool bUse )
640 {
641 	pImpl->bUseResText = bUse;
642 }
643 
644 // -----------------------------------------------------------------------
645 
Paint(const Rectangle &)646 void SvxFontPrevWindow::Paint( const Rectangle& )
647 {
648 	Printer* pPrinter = pImpl->pPrinter;
649 	SvxFont& rFont = pImpl->aFont;
650 	SvxFont& rCJKFont = pImpl->aCJKFont;
651 	// TODO: SvxFont& rCTLFont = pImpl->aCTLFont;
652 
653     if ( pImpl->bUseResText )
654 		pImpl->aText = GetText();
655 	else if ( !pImpl->bSelection && !pImpl->bTextInited )
656 	{
657 		SfxViewShell* pSh = SfxViewShell::Current();
658 
659 		if ( pSh && !pImpl->bGetSelection && !pImpl->bUseFontNameAsText )
660 		{
661 			pImpl->aText = pSh->GetSelectionText();
662 			pImpl->bGetSelection = sal_True;
663 			pImpl->bSelection = pImpl->aText.Len() != 0;
664 
665 		}
666 
667 		if ( !pImpl->bSelection || pImpl->bUseFontNameAsText )
668         {
669 			pImpl->aText = rFont.GetName();
670             if( pImpl->bIsCJKUI )
671                 pImpl->aText += rCJKFont.GetName();
672             //TODO bIsCTLUI
673         }
674 
675 		if ( !pImpl->aText.Len() )
676 			pImpl->aText = GetText();
677 
678         // remove line feeds and carriage returns from string
679         bool bNotEmpty = false;
680         for ( xub_StrLen i = 0; i < pImpl->aText.Len(); ++i )
681         {
682             if ( 0xa == pImpl->aText.GetChar( i ) ||
683                  0xd == pImpl->aText.GetChar( i ) )
684                  pImpl->aText.SetChar( i, ' ' );
685             else
686                 bNotEmpty = true;
687         }
688         if ( !bNotEmpty )
689 			pImpl->aText = GetText();
690 
691 		if ( pImpl->aText.Len() > (TEXT_WIDTH-1) )
692 			pImpl->aText.Erase( pImpl->aText.Search( sal_Unicode( ' ' ), TEXT_WIDTH ) );
693 	}
694 
695 	// calculate text width scaling
696 	pImpl->ScaleFontWidth( *this/*, rFont*/ );
697 
698     pImpl->CheckScript();
699     Size aTxtSize = pImpl->CalcTextSize( this, pPrinter, rFont );
700 
701 	const Size aLogSize( GetOutputSize() );
702 
703 	long nX = aLogSize.Width()  / 2 - aTxtSize.Width() / 2;
704 	long nY = aLogSize.Height() / 2 - aTxtSize.Height() / 2;
705 
706     if ( nY + pImpl->nAscent > aLogSize.Height() )
707         nY = aLogSize.Height() - pImpl->nAscent;
708 
709     if ( pImpl->pBackColor )
710 	{
711         Rectangle aRect( Point( 0, 0 ), aLogSize );
712 		Color aLineCol = GetLineColor();
713 		Color aFillCol = GetFillColor();
714 		SetLineColor();
715         SetFillColor( *pImpl->pBackColor );
716 		DrawRect( aRect );
717 		SetLineColor( aLineCol );
718 		SetFillColor( aFillCol );
719 	}
720     if ( pImpl->pColor )
721 	{
722 		Rectangle aRect( Point( nX, nY ), aTxtSize );
723 		Color aLineCol = GetLineColor();
724 		Color aFillCol = GetFillColor();
725 		SetLineColor();
726 		SetFillColor( *pImpl->pColor );
727 		DrawRect( aRect );
728 		SetLineColor( aLineCol );
729 		SetFillColor( aFillCol );
730 	}
731 
732     long nStdAscent = pImpl->nAscent;
733 	nY += nStdAscent;
734 
735 	if(pImpl->bTwoLines)
736 	{
737 		SvxFont aSmallFont( rFont );
738 		Size aOldSize = pImpl->aCJKFont.GetSize();
739 		setFontSize(aSmallFont);
740 		setFontSize(pImpl->aCJKFont);
741 
742 		long nStartBracketWidth = 0;
743 		long nEndBracketWidth = 0;
744 		long nTextWidth = 0;
745 		if(pImpl->cStartBracket)
746 		{
747 			String sBracket(pImpl->cStartBracket);
748 			nStartBracketWidth = rFont.GetTxtSize( pPrinter, sBracket ).Width();
749 		}
750 		if(pImpl->cEndBracket)
751 		{
752 			String sBracket(pImpl->cEndBracket);
753 			nEndBracketWidth = rFont.GetTxtSize( pPrinter, sBracket ).Width();
754 		}
755         nTextWidth = pImpl->CalcTextSize( this, pPrinter, aSmallFont ).Width();
756 		long nResultWidth = nStartBracketWidth;
757 		nResultWidth += nEndBracketWidth;
758 		nResultWidth += nTextWidth;
759 
760         long _nX = (aLogSize.Width() - nResultWidth) / 2;
761         DrawLine( Point( 0,  nY ), Point( _nX, nY ) );
762         DrawLine( Point( _nX + nResultWidth, nY ), Point( aLogSize.Width(), nY ) );
763 
764         long nSmallAscent = pImpl->nAscent;
765 		long nOffset = (nStdAscent - nSmallAscent ) / 2;
766 
767 		if(pImpl->cStartBracket)
768 		{
769 			String sBracket(pImpl->cStartBracket);
770             rFont.DrawPrev( this, pPrinter, Point( _nX, nY - nOffset - 4), sBracket );
771             _nX += nStartBracketWidth;
772 		}
773 
774         Point aTmpPoint1( _nX, nY - nSmallAscent - 2 );
775         Point aTmpPoint2( _nX, nY );
776         pImpl->DrawPrev( this, pPrinter, aTmpPoint1, aSmallFont );
777         pImpl->DrawPrev( this, pPrinter, aTmpPoint2, aSmallFont );
778 
779         _nX += nTextWidth;
780 		if(pImpl->cEndBracket)
781 		{
782             Point aTmpPoint( _nX + 1, nY - nOffset - 4);
783 			String sBracket(pImpl->cEndBracket);
784 			rFont.DrawPrev( this, pPrinter, aTmpPoint, sBracket );
785 		}
786         pImpl->aCJKFont.SetSize( aOldSize );
787 	}
788 	else
789 	{
790 		Color aLineCol = GetLineColor();
791 
792 		SetLineColor( rFont.GetColor() );
793         DrawLine( Point( 0,  nY ), Point( nX, nY ) );
794         DrawLine( Point( nX + aTxtSize.Width(), nY ), Point( aLogSize.Width(), nY ) );
795 
796 		SetLineColor( aLineCol );
797 
798         Point aTmpPoint( nX, nY );
799         pImpl->DrawPrev( this, pPrinter, aTmpPoint, rFont );
800 	}
801 }
802 /* -----------------------------04.12.00 16:26--------------------------------
803 
804  ---------------------------------------------------------------------------*/
IsTwoLines() const805 sal_Bool SvxFontPrevWindow::IsTwoLines() const
806 {
807 	return pImpl->bTwoLines;
808 }
809 /* -----------------------------04.12.00 16:26--------------------------------
810 
811  ---------------------------------------------------------------------------*/
SetTwoLines(sal_Bool bSet)812 void SvxFontPrevWindow::SetTwoLines(sal_Bool bSet)
813 {
814 	pImpl->bTwoLines = bSet;}
815 
816 /* -----------------------------04.12.00 16:26--------------------------------
817 
818  ---------------------------------------------------------------------------*/
SetBrackets(sal_Unicode cStart,sal_Unicode cEnd)819 void SvxFontPrevWindow::SetBrackets(sal_Unicode cStart, sal_Unicode cEnd)
820 {
821 	pImpl->cStartBracket = cStart;
822 	pImpl->cEndBracket = cEnd;
823 }
824 
825 // -----------------------------------------------------------------------
826 
SetFontWidthScale(sal_uInt16 n)827 void SvxFontPrevWindow::SetFontWidthScale( sal_uInt16 n )
828 {
829 	if( pImpl->SetFontWidthScale( n ) )
830 		Invalidate();
831 }
832 
833 // -----------------------------------------------------------------------
834 
AutoCorrectFontColor(void)835 void SvxFontPrevWindow::AutoCorrectFontColor( void )
836 {
837 	Color	aFontColor( GetTextColor() );
838 
839 	if( COL_AUTO == pImpl->aFont.GetColor().GetColor() )
840 		pImpl->aFont.SetColor( aFontColor );
841 
842 	if( COL_AUTO == pImpl->aCJKFont.GetColor().GetColor() )
843 		pImpl->aCJKFont.SetColor( aFontColor );
844 
845 	if( COL_AUTO == pImpl->aCTLFont.GetColor().GetColor() )
846 		pImpl->aCTLFont.SetColor( aFontColor );
847 }
848