xref: /AOO41X/main/svtools/source/control/ctrltool.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
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