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