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_svtools.hxx"
26 
27 #define CTRLTOOL_CXX
28 
29 #include <string.h>
30 
31 #include <tools/debug.hxx>
32 #include <i18npool/mslangid.hxx>
33 #include <vcl/window.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/wrkwin.hxx>
36 #include <svtools/svtools.hrc>
37 #include <svtools/svtdata.hxx>
38 #include <svtools/ctrltool.hxx>
39 
40 // =======================================================================
41 
42 // Standard Fontgroessen fuer scalierbare Fonts
43 static long aStdSizeAry[] =
44 {
45 	 60,
46 	 70,
47 	 80,
48 	 90,
49 	100,
50 	105,
51 	110,
52 	120,
53 	130,
54 	140,
55 	150,
56 	160,
57 	180,
58 	200,
59 	220,
60 	240,
61 	260,
62 	280,
63 	320,
64 	360,
65 	400,
66 	440,
67 	480,
68 	540,
69 	600,
70 	660,
71 	720,
72 	800,
73 	880,
74 	960,
75 	0
76 };
77 
78 // =======================================================================
79 
80 // -----------------------------
81 // - class ImplFontListFonInfo -
82 // -----------------------------
83 
84 class ImplFontListFontInfo : public FontInfo
85 {
86 	friend class FontList;
87 
88 private:
89 	OutputDevice*			mpDevice;
90 	ImplFontListFontInfo*	mpNext;
91 
92 public:
ImplFontListFontInfo(const FontInfo & rInfo,OutputDevice * pDev)93 							ImplFontListFontInfo( const FontInfo& rInfo,
94 												  OutputDevice* pDev ) :
95 								FontInfo( rInfo )
96 							{
97 								mpDevice = pDev;
98 							}
99 
GetDevice() const100 	OutputDevice*			GetDevice() const { return mpDevice; }
101 };
102 
103 // ------------------------------
104 // - class ImplFontListNameInfo -
105 // ------------------------------
106 
107 class ImplFontListNameInfo
108 {
109 	friend class FontList;
110 
111 private:
112 	XubString				maSearchName;
113 	ImplFontListFontInfo*	mpFirst;
114 	sal_uInt16					mnType;
115 
ImplFontListNameInfo(const XubString & rSearchName)116 							ImplFontListNameInfo( const XubString& rSearchName ) :
117 								maSearchName( rSearchName )
118 							{}
119 
GetSearchName() const120 	const XubString&		GetSearchName() const { return maSearchName; }
121 };
122 
123 // =======================================================================
124 
ImplCompareFontInfo(ImplFontListFontInfo * pInfo1,ImplFontListFontInfo * pInfo2)125 static StringCompare ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
126 										  ImplFontListFontInfo* pInfo2 )
127 {
128 	if ( pInfo1->GetWeight() < pInfo2->GetWeight() )
129 		return COMPARE_LESS;
130 	else if ( pInfo1->GetWeight() > pInfo2->GetWeight() )
131 		return COMPARE_GREATER;
132 
133 	if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
134 		return COMPARE_LESS;
135 	else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
136 		return COMPARE_GREATER;
137 
138 	return pInfo1->GetStyleName().CompareTo( pInfo2->GetStyleName() );
139 }
140 
141 // =======================================================================
142 
ImplMakeSearchString(XubString & rStr)143 static void ImplMakeSearchString( XubString& rStr )
144 {
145 	rStr.ToLowerAscii();
146 }
147 
148 // -----------------------------------------------------------------------
149 
ImplMakeSearchStringFromName(XubString & rStr)150 static void ImplMakeSearchStringFromName( XubString& rStr )
151 {
152     // check for features before alternate font separator
153     if (rStr.Search(':') < rStr.Search(';'))
154         rStr = rStr.GetToken( 0, ':' );
155     else
156         rStr = rStr.GetToken( 0, ';' );
157 	ImplMakeSearchString( rStr );
158 }
159 
160 // -----------------------------------------------------------------------
161 
ImplFind(const XubString & rSearchName,sal_uLong * pIndex) const162 ImplFontListNameInfo* FontList::ImplFind( const XubString& rSearchName, sal_uLong* pIndex ) const
163 {
164 	// Wenn kein Eintrag in der Liste oder der Eintrag groesser ist als
165 	// der Letzte, dann hinten dranhaengen. Wir vergleichen erst mit dem
166 	// letzten Eintrag, da die Liste von VCL auch sortiert zurueckkommt
167 	// und somit die Wahrscheinlichkeit das hinten angehaengt werden muss
168 	// sehr gross ist.
169 	StringCompare eComp;
170 	sal_uLong nCnt = Count();
171 	if ( !nCnt )
172 	{
173 		if ( pIndex )
174 			*pIndex = LIST_APPEND;
175 		return NULL;
176 	}
177 	else
178 	{
179 		ImplFontListNameInfo* pCmpData = (ImplFontListNameInfo*)List::GetObject( nCnt-1 );
180 		eComp = rSearchName.CompareTo( pCmpData->maSearchName );
181 		if ( eComp == COMPARE_GREATER )
182 		{
183 			if ( pIndex )
184 				*pIndex = LIST_APPEND;
185 			return NULL;
186 		}
187 		else if ( eComp == COMPARE_EQUAL )
188 			return pCmpData;
189 	}
190 
191 	// Fonts in der Liste suchen
192 	ImplFontListNameInfo*	pCompareData;
193 	ImplFontListNameInfo*	pFoundData = NULL;
194 	sal_uLong					nLow = 0;
195 	sal_uLong					nHigh = nCnt-1;
196 	sal_uLong					nMid;
197 
198 	do
199 	{
200 		nMid = (nLow + nHigh) / 2;
201 		pCompareData = (ImplFontListNameInfo*)List::GetObject( nMid );
202 		eComp = rSearchName.CompareTo( pCompareData->maSearchName );
203 		if ( eComp == COMPARE_LESS )
204 		{
205 			if ( !nMid )
206 				break;
207 			nHigh = nMid-1;
208 		}
209 		else
210 		{
211 			if ( eComp == COMPARE_GREATER )
212 				nLow = nMid + 1;
213 			else
214 			{
215 				pFoundData = pCompareData;
216 				break;
217 			}
218 		}
219 	}
220 	while ( nLow <= nHigh );
221 
222 	if ( pIndex )
223 	{
224 		eComp = rSearchName.CompareTo( pCompareData->maSearchName );
225 		if ( eComp == COMPARE_GREATER )
226 			*pIndex = (nMid+1);
227 		else
228 			*pIndex = nMid;
229 	}
230 
231 	return pFoundData;
232 }
233 
234 // -----------------------------------------------------------------------
235 
ImplFindByName(const XubString & rStr) const236 ImplFontListNameInfo* FontList::ImplFindByName( const XubString& rStr ) const
237 {
238 	XubString aSearchName = rStr;
239 	ImplMakeSearchStringFromName( aSearchName );
240 	return ImplFind( aSearchName, NULL );
241 }
242 
243 // -----------------------------------------------------------------------
244 
ImplInsertFonts(OutputDevice * pDevice,sal_Bool bAll,sal_Bool bInsertData)245 void FontList::ImplInsertFonts( OutputDevice* pDevice, sal_Bool bAll,
246 								sal_Bool bInsertData )
247 {
248 	rtl_TextEncoding eSystemEncoding = gsl_getSystemTextEncoding();
249 
250 	sal_uInt16 nType;
251 	if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
252 		nType = FONTLIST_FONTNAMETYPE_SCREEN;
253 	else
254 		nType = FONTLIST_FONTNAMETYPE_PRINTER;
255 
256 	// Alle Fonts vom Device abfragen
257 	int n = pDevice->GetDevFontCount();
258 	sal_uInt16	i;
259 	for( i = 0; i < n; i++ )
260 	{
261 		FontInfo aFontInfo = pDevice->GetDevFont( i );
262 
263 		// Wenn keine Raster-Schriften angezeigt werden sollen,
264 		// dann diese ignorieren
265 		if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
266 			continue;
267 
268 		XubString				aSearchName = aFontInfo.GetName();
269 		ImplFontListNameInfo*	pData;
270 		sal_uLong					nIndex;
271 		ImplMakeSearchString( aSearchName );
272 		pData = ImplFind( aSearchName, &nIndex );
273 
274 		if ( !pData )
275 		{
276 			if ( bInsertData )
277 			{
278 				ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
279 				pData = new ImplFontListNameInfo( aSearchName );
280 				pData->mpFirst		= pNewInfo;
281 				pNewInfo->mpNext	= NULL;
282 				pData->mnType		= 0;
283 				Insert( (void*)pData, nIndex );
284 			}
285 		}
286 		else
287 		{
288 			if ( bInsertData )
289 			{
290 				sal_Bool					bInsert = sal_True;
291 				ImplFontListFontInfo*	pPrev = NULL;
292 				ImplFontListFontInfo*	pTemp = pData->mpFirst;
293 				ImplFontListFontInfo*	pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
294 				while ( pTemp )
295 				{
296 					StringCompare eComp = ImplCompareFontInfo( pNewInfo, pTemp );
297 					if ( (eComp == COMPARE_LESS) || (eComp == COMPARE_EQUAL) )
298 					{
299 						if ( eComp == COMPARE_EQUAL )
300 						{
301 							// Overwrite charset, because charset should match
302 							// with the system charset
303 							if ( (pTemp->GetCharSet() != eSystemEncoding) &&
304 								 (pNewInfo->GetCharSet() == eSystemEncoding) )
305 							{
306 								ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
307 								*((FontInfo*)pTemp) = *((FontInfo*)pNewInfo);
308 								pTemp->mpNext = pTemp2;
309 							}
310 							delete pNewInfo;
311 							bInsert = sal_False;
312 						}
313 
314 						break;
315 					}
316 
317 					pPrev = pTemp;
318 					pTemp = pTemp->mpNext;
319 				}
320 
321 				if ( bInsert )
322 				{
323 					pNewInfo->mpNext = pTemp;
324 					if ( pPrev )
325 						pPrev->mpNext = pNewInfo;
326 					else
327 						pData->mpFirst = pNewInfo;
328 				}
329 			}
330 		}
331 
332 		if ( pData )
333 		{
334 			pData->mnType |= nType;
335 			if ( aFontInfo.GetType() != TYPE_RASTER )
336 				pData->mnType |= FONTLIST_FONTNAMETYPE_SCALABLE;
337 		}
338 	}
339 }
340 
341 // =======================================================================
342 
FontList(OutputDevice * pDevice,OutputDevice * pDevice2,sal_Bool bAll)343 FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, sal_Bool bAll ) :
344 	List( 4096, sal::static_int_cast< sal_uInt16 >(pDevice->GetDevFontCount()), 32 )
345 {
346 	// Variablen initialisieren
347 	mpDev = pDevice;
348 	mpDev2 = pDevice2;
349 	mpSizeAry = NULL;
350 
351 	// Stylenamen festlegen
352 	maLight 		= XubString( SvtResId( STR_SVT_STYLE_LIGHT ) );
353 	maLightItalic	= XubString( SvtResId( STR_SVT_STYLE_LIGHT_ITALIC ) );
354 	maNormal		= XubString( SvtResId( STR_SVT_STYLE_NORMAL ) );
355 	maNormalItalic	= XubString( SvtResId( STR_SVT_STYLE_NORMAL_ITALIC ) );
356 	maBold			= XubString( SvtResId( STR_SVT_STYLE_BOLD ) );
357 	maBoldItalic	= XubString( SvtResId( STR_SVT_STYLE_BOLD_ITALIC ) );
358 	maBlack 		= XubString( SvtResId( STR_SVT_STYLE_BLACK ) );
359 	maBlackItalic	= XubString( SvtResId( STR_SVT_STYLE_BLACK_ITALIC ) );
360 
361 	ImplInsertFonts( pDevice, bAll, sal_True );
362 
363 	// Gegebenenfalls muessen wir mit den Bildschirmfonts vergleichen,
364 	// damit dort die eigentlich doppelten auf Equal mappen koennen
365 	sal_Bool bCompareWindow = sal_False;
366 	if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
367 	{
368 		bCompareWindow = sal_True;
369 		pDevice2 = Application::GetDefaultDevice();
370 	}
371 
372 	if ( pDevice2 &&
373 		 (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
374 		ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
375 }
376 
377 // -----------------------------------------------------------------------
378 
~FontList()379 FontList::~FontList()
380 {
381 	// Gegebenenfalls SizeArray loeschen
382 	if ( mpSizeAry )
383 		delete[] mpSizeAry;
384 
385 	// FontInfos loeschen
386 	ImplFontListNameInfo* pData = (ImplFontListNameInfo*)First();
387 	while ( pData )
388 	{
389 		ImplFontListFontInfo* pTemp;
390 		ImplFontListFontInfo* pInfo = pData->mpFirst;
391 		while ( pInfo )
392 		{
393 			pTemp = pInfo->mpNext;
394 			delete pInfo;
395 			pInfo = pTemp;
396 		}
397 		ImplFontListNameInfo* pNext = (ImplFontListNameInfo*)Next();
398 		delete pData;
399 		pData = pNext;
400 	}
401 }
402 // -----------------------------------------------------------------------
Clone() const403 FontList* FontList::Clone() const
404 {
405     FontList* pReturn = new FontList(
406             mpDev, mpDev2, GetFontNameCount() == mpDev->GetDevFontCount());
407     return pReturn;
408 }
409 
410 // -----------------------------------------------------------------------
411 
GetStyleName(FontWeight eWeight,FontItalic eItalic) const412 const XubString& FontList::GetStyleName( FontWeight eWeight, FontItalic eItalic ) const
413 {
414 	if ( eWeight > WEIGHT_BOLD )
415 	{
416 		if ( eItalic > ITALIC_NONE )
417 			return maBlackItalic;
418 		else
419 			return maBlack;
420 	}
421 	else if ( eWeight > WEIGHT_MEDIUM )
422 	{
423 		if ( eItalic > ITALIC_NONE )
424 			return maBoldItalic;
425 		else
426 			return maBold;
427 	}
428 	else if ( eWeight > WEIGHT_LIGHT )
429 	{
430 		if ( eItalic > ITALIC_NONE )
431 			return maNormalItalic;
432 		else
433 			return maNormal;
434 	}
435 	else if ( eWeight != WEIGHT_DONTKNOW )
436 	{
437 		if ( eItalic > ITALIC_NONE )
438 			return maLightItalic;
439 		else
440 			return maLight;
441 	}
442 	else
443 	{
444 		if ( eItalic > ITALIC_NONE )
445 			return maNormalItalic;
446 		else
447 			return maNormal;
448 	}
449 }
450 
451 // -----------------------------------------------------------------------
452 
GetStyleName(const FontInfo & rInfo) const453 XubString FontList::GetStyleName( const FontInfo& rInfo ) const
454 {
455 	XubString	aStyleName = rInfo.GetStyleName();
456 	FontWeight	eWeight = rInfo.GetWeight();
457 	FontItalic	eItalic = rInfo.GetItalic();
458 
459 	// Nur wenn kein StyleName gesetzt ist, geben wir einen syntetischen
460 	// Namen zurueck
461 	if ( !aStyleName.Len() )
462 		aStyleName = GetStyleName( eWeight, eItalic );
463 	else
464 	{
465 		// Translate StyleName to localized name
466 		XubString aCompareStyleName = aStyleName;
467 		aCompareStyleName.ToLowerAscii();
468 		aCompareStyleName.EraseAllChars( ' ' );
469 		if ( aCompareStyleName.EqualsAscii( "bold" ) )
470 			aStyleName = maBold;
471 		else if ( aCompareStyleName.EqualsAscii( "bolditalic" ) )
472 			aStyleName = maBoldItalic;
473 		else if ( aCompareStyleName.EqualsAscii( "italic" ) )
474 			aStyleName = maNormalItalic;
475 		else if ( aCompareStyleName.EqualsAscii( "standard" ) )
476 			aStyleName = maNormal;
477 		else if ( aCompareStyleName.EqualsAscii( "regular" ) )
478 			aStyleName = maNormal;
479 		else if ( aCompareStyleName.EqualsAscii( "medium" ) )
480 			aStyleName = maNormal;
481 		else if ( aCompareStyleName.EqualsAscii( "light" ) )
482 			aStyleName = maLight;
483 		else if ( aCompareStyleName.EqualsAscii( "lightitalic" ) )
484 			aStyleName = maLightItalic;
485 		else if ( aCompareStyleName.EqualsAscii( "black" ) )
486 			aStyleName = maBlack;
487 		else if ( aCompareStyleName.EqualsAscii( "blackitalic" ) )
488 			aStyleName = maBlackItalic;
489 
490 		// fix up StyleName, because the PS Printer driver from
491 		// W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
492 		// for Helvetica)
493 		if ( eItalic > ITALIC_NONE )
494 		{
495 			if ( (aStyleName == maNormal) ||
496 				 (aStyleName == maBold) ||
497 				 (aStyleName == maLight) ||
498 				 (aStyleName == maBlack) )
499 				aStyleName = GetStyleName( eWeight, eItalic );
500 		}
501 	}
502 
503 	return aStyleName;
504 }
505 
506 // -----------------------------------------------------------------------
507 
GetFontMapText(const FontInfo & rInfo) const508 XubString FontList::GetFontMapText( const FontInfo& rInfo ) const
509 {
510 	if ( !rInfo.GetName().Len() )
511 	{
512 		XubString aEmptryStr;
513 		return aEmptryStr;
514 	}
515 
516 	// Search Fontname
517 	ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
518 	if ( !pData )
519 	{
520 		if ( !maMapNotAvailable.Len() )
521 			((FontList*)this)->maMapNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_NOTAVAILABLE ) );
522 		return maMapNotAvailable;
523 	}
524 
525 	// search for synthetic style
526 	sal_uInt16				nType		= pData->mnType;
527 	const XubString&	rStyleName	= rInfo.GetStyleName();
528 	if ( rStyleName.Len() )
529 	{
530 		sal_Bool					bNotSynthetic = sal_False;
531 		sal_Bool					bNoneAvailable = sal_False;
532 		FontWeight				eWeight = rInfo.GetWeight();
533 		FontItalic				eItalic = rInfo.GetItalic();
534 		ImplFontListFontInfo*	pFontInfo = pData->mpFirst;
535 		while ( pFontInfo )
536 		{
537 			if ( (eWeight == pFontInfo->GetWeight()) &&
538 				 (eItalic == pFontInfo->GetItalic()) )
539 			{
540 				bNotSynthetic = sal_True;
541 				break;
542 			}
543 
544 			pFontInfo = pFontInfo->mpNext;
545 		}
546 
547 		if ( bNoneAvailable )
548 		{
549 			XubString aEmptryStr;
550 			return aEmptryStr;
551 		}
552 		else if ( !bNotSynthetic )
553 		{
554 			if ( !maMapStyleNotAvailable.Len() )
555 				((FontList*)this)->maMapStyleNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_STYLENOTAVAILABLE ) );
556 			return maMapStyleNotAvailable;
557 		}
558 	}
559 
560 	/* Size not available not implemented yet
561 	if ( !(nType & FONTLIST_FONTNAMETYPE_SCALABLE) )
562 	{
563 		...
564 		{
565 			if ( !maMapSizeNotAvailable.Len() )
566 				 ((FontList*)this)->maMapSizeNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_SIZENOTAVAILABLE ) );
567 			return maMapSizeNotAvailable;
568 		}
569 	}
570 	*/
571 
572 	// Only Printer-Font?
573 	if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
574 	{
575 		if ( !maMapPrinterOnly.Len() )
576 			((FontList*)this)->maMapPrinterOnly = XubString( SvtResId( STR_SVT_FONTMAP_PRINTERONLY ) );
577 		return maMapPrinterOnly;
578 	}
579 	// Only Screen-Font?
580     else if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_SCREEN
581             && rInfo.GetType() == TYPE_RASTER )
582 	{
583 		if ( !maMapScreenOnly.Len() )
584 			((FontList*)this)->maMapScreenOnly = XubString( SvtResId( STR_SVT_FONTMAP_SCREENONLY ) );
585 		return maMapScreenOnly;
586 	}
587 	else
588 	{
589 		if ( !maMapBoth.Len() )
590 			((FontList*)this)->maMapBoth = XubString( SvtResId( STR_SVT_FONTMAP_BOTH ) );
591 		return maMapBoth;
592 	}
593 }
594 
595 // -----------------------------------------------------------------------
596 
GetFontNameType(const XubString & rFontName) const597 sal_uInt16 FontList::GetFontNameType( const XubString& rFontName ) const
598 {
599 	ImplFontListNameInfo* pData = ImplFindByName( rFontName );
600 	if ( pData )
601 		return pData->mnType;
602 	else
603 		return 0;
604 }
605 
606 // -----------------------------------------------------------------------
607 
Get(const XubString & rName,const XubString & rStyleName) const608 FontInfo FontList::Get( const XubString& rName, const XubString& rStyleName ) const
609 {
610 	ImplFontListNameInfo* pData = ImplFindByName( rName );
611 	ImplFontListFontInfo* pFontInfo = NULL;
612 	ImplFontListFontInfo* pFontNameInfo = NULL;
613 	if ( pData )
614 	{
615 		ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
616 		pFontNameInfo = pSearchInfo;
617 		pSearchInfo = pData->mpFirst;
618 		while ( pSearchInfo )
619 		{
620 			if ( rStyleName.EqualsIgnoreCaseAscii( GetStyleName( *pSearchInfo ) ) )
621 			{
622 				pFontInfo = pSearchInfo;
623 				break;
624 			}
625 
626 			pSearchInfo = pSearchInfo->mpNext;
627 		}
628 	}
629 
630 	// Konnten die Daten nicht gefunden werden, dann muessen bestimmte
631 	// Attribute nachgebildet werden
632 	FontInfo aInfo;
633 	if ( !pFontInfo )
634 	{
635 		if ( pFontNameInfo )
636 			aInfo = *pFontNameInfo;
637 
638 		if ( rStyleName == maNormal )
639 		{
640 			aInfo.SetItalic( ITALIC_NONE );
641 			aInfo.SetWeight( WEIGHT_NORMAL );
642 		}
643 		else if ( rStyleName == maNormalItalic )
644 		{
645 			aInfo.SetItalic( ITALIC_NORMAL );
646 			aInfo.SetWeight( WEIGHT_NORMAL );
647 		}
648 		else if ( rStyleName == maBold )
649 		{
650 			aInfo.SetItalic( ITALIC_NONE );
651 			aInfo.SetWeight( WEIGHT_BOLD );
652 		}
653 		else if ( rStyleName == maBoldItalic )
654 		{
655 			aInfo.SetItalic( ITALIC_NORMAL );
656 			aInfo.SetWeight( WEIGHT_BOLD );
657 		}
658 		else if ( rStyleName == maLight )
659 		{
660 			aInfo.SetItalic( ITALIC_NONE );
661 			aInfo.SetWeight( WEIGHT_LIGHT );
662 		}
663 		else if ( rStyleName == maLightItalic )
664 		{
665 			aInfo.SetItalic( ITALIC_NORMAL );
666 			aInfo.SetWeight( WEIGHT_LIGHT );
667 		}
668 		else if ( rStyleName == maBlack )
669 		{
670 			aInfo.SetItalic( ITALIC_NONE );
671 			aInfo.SetWeight( WEIGHT_BLACK );
672 		}
673 		else if ( rStyleName == maBlackItalic )
674 		{
675 			aInfo.SetItalic( ITALIC_NORMAL );
676 			aInfo.SetWeight( WEIGHT_BLACK );
677 		}
678 		else
679 		{
680 			aInfo.SetItalic( ITALIC_NONE );
681 			aInfo.SetWeight( WEIGHT_DONTKNOW );
682 		}
683 	}
684 	else
685 		aInfo = *pFontInfo;
686 
687 	// set Fontname to keep FontAlias
688 	aInfo.SetName( rName );
689 	aInfo.SetStyleName( rStyleName );
690 
691 	return aInfo;
692 }
693 
694 // -----------------------------------------------------------------------
695 
Get(const XubString & rName,FontWeight eWeight,FontItalic eItalic) const696 FontInfo FontList::Get( const XubString& rName,
697 						FontWeight eWeight, FontItalic eItalic ) const
698 {
699 	ImplFontListNameInfo* pData = ImplFindByName( rName );
700 	ImplFontListFontInfo* pFontInfo = NULL;
701 	ImplFontListFontInfo* pFontNameInfo = NULL;
702 	if ( pData )
703 	{
704 		ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
705 		pFontNameInfo = pSearchInfo;
706 		while ( pSearchInfo )
707 		{
708 			if ( (eWeight == pSearchInfo->GetWeight()) &&
709 				 (eItalic == pSearchInfo->GetItalic()) )
710 			{
711 				pFontInfo = pSearchInfo;
712 				break;
713 			}
714 
715 			pSearchInfo = pSearchInfo->mpNext;
716 		}
717 	}
718 
719 	// Konnten die Daten nicht gefunden werden, dann muessen bestimmte
720 	// Attribute nachgebildet werden
721 	FontInfo aInfo;
722 	if ( !pFontInfo )
723 	{
724 		// Falls der Fontname stimmt, uebernehmen wir soviel wie moeglich
725 		if ( pFontNameInfo )
726 		{
727 			aInfo = *pFontNameInfo;
728 			aInfo.SetStyleName( XubString() );
729 		}
730 
731 		aInfo.SetWeight( eWeight );
732 		aInfo.SetItalic( eItalic );
733 	}
734 	else
735 		aInfo = *pFontInfo;
736 
737 	// set Fontname to keep FontAlias
738 	aInfo.SetName( rName );
739 
740 	return aInfo;
741 }
742 
743 // -----------------------------------------------------------------------
744 
IsAvailable(const XubString & rName) const745 sal_Bool FontList::IsAvailable( const XubString& rName ) const
746 {
747 	return (ImplFindByName( rName ) != 0);
748 }
749 
750 // -----------------------------------------------------------------------
751 
GetFontName(sal_uInt16 nFont) const752 const FontInfo& FontList::GetFontName( sal_uInt16 nFont ) const
753 {
754 	DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
755 
756 	ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
757 	return *(pData->mpFirst);
758 }
759 
760 // -----------------------------------------------------------------------
761 
GetFontNameType(sal_uInt16 nFont) const762 sal_uInt16 FontList::GetFontNameType( sal_uInt16 nFont ) const
763 {
764 	DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontNameType(): nFont >= Count" );
765 
766 	ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
767 	return pData->mnType;
768 }
769 
770 // -----------------------------------------------------------------------
771 
GetFirstFontInfo(const XubString & rName) const772 sal_Handle FontList::GetFirstFontInfo( const XubString& rName ) const
773 {
774 	ImplFontListNameInfo* pData = ImplFindByName( rName );
775 	if ( !pData )
776 		return (sal_Handle)NULL;
777 	else
778 		return (sal_Handle)pData->mpFirst;
779 }
780 
781 // -----------------------------------------------------------------------
782 
GetNextFontInfo(sal_Handle hFontInfo) const783 sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo ) const
784 {
785 	ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
786 	return (sal_Handle)(pInfo->mpNext);
787 }
788 
789 // -----------------------------------------------------------------------
790 
GetFontInfo(sal_Handle hFontInfo) const791 const FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo ) const
792 {
793 	ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
794 	return *pInfo;
795 }
796 
797 // -----------------------------------------------------------------------
798 
GetSizeAry(const FontInfo & rInfo) const799 const long* FontList::GetSizeAry( const FontInfo& rInfo ) const
800 {
801 	// Size-Array vorher loeschen
802 	if ( mpSizeAry )
803 	{
804 		delete[] ((FontList*)this)->mpSizeAry;
805 		((FontList*)this)->mpSizeAry = NULL;
806 	}
807 
808 	// Falls kein Name, dann Standardgroessen
809 	if ( !rInfo.GetName().Len() )
810 		return aStdSizeAry;
811 
812 	// Zuerst nach dem Fontnamen suchen um das Device dann von dem
813 	// entsprechenden Font zu nehmen
814 	OutputDevice*			pDevice = mpDev;
815 	ImplFontListNameInfo*	pData = ImplFindByName( rInfo.GetName() );
816 	if ( pData )
817 		pDevice = pData->mpFirst->GetDevice();
818 
819 	int nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
820 	if ( !nDevSizeCount ||
821 		 (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
822 		return aStdSizeAry;
823 
824 	MapMode aOldMapMode = pDevice->GetMapMode();
825 	MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
826 	pDevice->SetMapMode( aMap );
827 
828 	sal_uInt16	i;
829 	sal_uInt16	nRealCount = 0;
830 	long	nOldHeight = 0;
831 	((FontList*)this)->mpSizeAry = new long[nDevSizeCount+1];
832 	for ( i = 0; i < nDevSizeCount; i++ )
833 	{
834 		Size aSize = pDevice->GetDevFontSize( rInfo, i );
835 		if ( aSize.Height() != nOldHeight )
836 		{
837 			nOldHeight = aSize.Height();
838 			((FontList*)this)->mpSizeAry[nRealCount] = nOldHeight;
839 			nRealCount++;
840 		}
841 	}
842 	((FontList*)this)->mpSizeAry[nRealCount] = 0;
843 
844 	pDevice->SetMapMode( aOldMapMode );
845 	return mpSizeAry;
846 }
847 
848 // -----------------------------------------------------------------------
849 
GetStdSizeAry()850 const long* FontList::GetStdSizeAry()
851 {
852 	return aStdSizeAry;
853 }
854 
855 // =======================================================================
856 
857 // ---------------------------------
858 // - FontSizeNames & FsizeNameItem -
859 // ---------------------------------
860 
861 struct ImplFSNameItem
862 {
863 	long		mnSize;
864 	const char* mszUtf8Name;
865 };
866 
867 //------------------------------------------------------------------------
868 
869 static ImplFSNameItem aImplSimplifiedChinese[] =
870 {
871 	{  50, "\xe5\x85\xab\xe5\x8f\xb7" },
872 	{  55, "\xe4\xb8\x83\xe5\x8f\xb7" },
873 	{  65, "\xe5\xb0\x8f\xe5\x85\xad" },
874 	{  75, "\xe5\x85\xad\xe5\x8f\xb7" },
875 	{  90, "\xe5\xb0\x8f\xe4\xba\x94" },
876 	{ 105, "\xe4\xba\x94\xe5\x8f\xb7" },
877 	{ 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
878 	{ 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
879 	{ 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
880 	{ 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
881 	{ 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
882 	{ 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
883 	{ 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
884 	{ 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
885 	{ 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
886 	{ 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
887 };
888 
889 // -----------------------------------------------------------------------
890 
891 #if 0 // #i89077# disabled by popular request
892 static ImplFSNameItem aImplTraditionalChinese[] =
893 {
894 	{  50, "\xe5\x85\xab\xe8\x99\x9f" },
895 	{  55, "\xe4\xb8\x83\xe8\x99\x9f" },
896 	{  65, "\xe5\xb0\x8f\xe5\x85\xad" },
897 	{  75, "\xe5\x85\xad\xe8\x99\x9f" },
898 	{  90, "\xe5\xb0\x8f\xe4\xba\x94" },
899 	{ 105, "\xe4\xba\x94\xe8\x99\x9f" },
900 	{ 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
901 	{ 140, "\xe5\x9b\x9b\xe8\x99\x9f" },
902 	{ 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
903 	{ 160, "\xe4\xb8\x89\xe8\x99\x9f" },
904 	{ 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
905 	{ 220, "\xe4\xba\x8c\xe8\x99\x9f" },
906 	{ 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
907 	{ 260, "\xe4\xb8\x80\xe8\x99\x9f" },
908 	{ 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
909 	{ 420, "\xe5\x88\x9d\xe8\x99\x9f" }
910 };
911 #endif
912 
913 //------------------------------------------------------------------------
914 
FontSizeNames(LanguageType eLanguage)915 FontSizeNames::FontSizeNames( LanguageType eLanguage )
916 {
917 	if ( eLanguage == LANGUAGE_DONTKNOW )
918 		eLanguage = Application::GetSettings().GetUILanguage();
919 	if ( eLanguage == LANGUAGE_SYSTEM )
920 		eLanguage = MsLangId::getSystemUILanguage();
921 
922 	switch( eLanguage )
923 	{
924 		case LANGUAGE_CHINESE:
925 		case LANGUAGE_CHINESE_SIMPLIFIED:
926 			mpArray = aImplSimplifiedChinese;
927 			mnElem = sizeof(aImplSimplifiedChinese) / sizeof(aImplSimplifiedChinese[0]);
928 			break;
929 
930 #if 0 // #i89077# disabled by popular request
931 		case LANGUAGE_CHINESE_HONGKONG:
932 		case LANGUAGE_CHINESE_SINGAPORE:
933 		case LANGUAGE_CHINESE_MACAU:
934 		case LANGUAGE_CHINESE_TRADITIONAL:
935 			mpArray = aImplTraditionalChinese;
936 			mnElem = sizeof(aImplTraditionalChinese) / sizeof(aImplTraditionalChinese[0]);
937 			break;
938 #endif
939 
940 		default:
941 			mpArray = NULL;
942 			mnElem = 0;
943 			break;
944 	};
945 }
946 
947 //------------------------------------------------------------------------
948 
Name2Size(const String & rName) const949 long FontSizeNames::Name2Size( const String& rName ) const
950 {
951 	if ( mnElem )
952 	{
953 		ByteString aName( rName, RTL_TEXTENCODING_UTF8 );
954 
955 		// linear search is sufficient for this rare case
956 		for( long i = mnElem; --i >= 0; )
957 			if ( aName == mpArray[i].mszUtf8Name )
958 				return mpArray[i].mnSize;
959 	}
960 
961 	return 0;
962 }
963 
964 //------------------------------------------------------------------------
965 
Size2Name(long nValue) const966 String FontSizeNames::Size2Name( long nValue ) const
967 {
968 	String aStr;
969 
970 	// binary search
971 	for( long lower = 0, upper = mnElem - 1; lower <= upper; )
972 	{
973 		long mid = (upper + lower) >> 1;
974 		if ( nValue == mpArray[mid].mnSize )
975 		{
976 			aStr = String( mpArray[mid].mszUtf8Name, RTL_TEXTENCODING_UTF8 );
977 			break;
978 		}
979 		else if ( nValue < mpArray[mid].mnSize )
980 			upper = mid - 1;
981 		else /* ( nValue > mpArray[mid].mnSize ) */
982 			lower = mid + 1;
983 	}
984 
985 	return aStr;
986 }
987 
988 //------------------------------------------------------------------------
989 
GetIndexName(sal_uLong nIndex) const990 String FontSizeNames::GetIndexName( sal_uLong nIndex ) const
991 {
992 	String aStr;
993 
994 	if ( nIndex < mnElem )
995 		aStr = String( mpArray[nIndex].mszUtf8Name, RTL_TEXTENCODING_UTF8 );
996 
997 	return aStr;
998 }
999 
1000 //------------------------------------------------------------------------
1001 
GetIndexSize(sal_uLong nIndex) const1002 long FontSizeNames::GetIndexSize( sal_uLong nIndex ) const
1003 {
1004 	if ( nIndex >= mnElem )
1005 		return 0;
1006 	return mpArray[nIndex].mnSize;
1007 }
1008