GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / control / ctrltool.cxx
blob4f8fc91e5d6c0d1ba3ed1d5eab57b155f19f90ec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
22 #include <comphelper/string.hxx>
23 #include <tools/debug.hxx>
24 #include <i18nlangtag/mslangid.hxx>
25 #include <vcl/window.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/wrkwin.hxx>
28 #include <sal/macros.h>
29 #include <svtools/svtools.hrc>
30 #include <svtools/svtresid.hxx>
31 #include <svtools/ctrltool.hxx>
33 // =======================================================================
35 // Standard Fontgroessen fuer scalierbare Fonts
36 static const sal_IntPtr aStdSizeAry[] =
38 60,
39 70,
40 80,
41 90,
42 100,
43 105,
44 110,
45 120,
46 130,
47 140,
48 150,
49 160,
50 180,
51 200,
52 220,
53 240,
54 260,
55 280,
56 320,
57 360,
58 400,
59 440,
60 480,
61 540,
62 600,
63 660,
64 720,
65 800,
66 880,
67 960,
71 // =======================================================================
73 // -----------------------------
74 // - class ImplFontListFonInfo -
75 // -----------------------------
77 class ImplFontListFontInfo : public FontInfo
79 friend class FontList;
81 private:
82 OutputDevice* mpDevice;
83 ImplFontListFontInfo* mpNext;
85 public:
86 ImplFontListFontInfo( const FontInfo& rInfo,
87 OutputDevice* pDev ) :
88 FontInfo( rInfo ), mpNext(NULL)
90 mpDevice = pDev;
93 OutputDevice* GetDevice() const { return mpDevice; }
96 // ------------------------------
97 // - class ImplFontListNameInfo -
98 // ------------------------------
100 class ImplFontListNameInfo
102 friend class FontList;
104 private:
105 OUString maSearchName;
106 ImplFontListFontInfo* mpFirst;
107 sal_uInt16 mnType;
109 ImplFontListNameInfo(const OUString& rSearchName)
110 : maSearchName( rSearchName )
111 , mnType(0)
116 //sort normal to the start
117 static int sortWeightValue(FontWeight eWeight)
119 if (eWeight < WEIGHT_NORMAL)
120 return eWeight + 1;
121 if (eWeight > WEIGHT_NORMAL)
122 return eWeight - 1;
123 return 0; // eWeight == WEIGHT_NORMAL
126 static sal_Int32 ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
127 ImplFontListFontInfo* pInfo2 )
129 //Sort non italic before italics
130 if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
131 return -1;
132 else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
133 return 1;
135 //Sort normal weight to the start, followed by lightest to heaviest weights
136 int nWeight1 = sortWeightValue(pInfo1->GetWeight());
137 int nWeight2 = sortWeightValue(pInfo2->GetWeight());
139 if ( nWeight1 < nWeight2 )
140 return -1;
141 else if ( nWeight1 > nWeight2 )
142 return 1;
144 return pInfo1->GetStyleName().compareTo( pInfo2->GetStyleName() );
147 // =======================================================================
149 static OUString ImplMakeSearchString(const OUString& rStr)
151 return rStr.toAsciiLowerCase();
154 // -----------------------------------------------------------------------
156 static OUString ImplMakeSearchStringFromName(const OUString& rStr)
158 // check for features before alternate font separator
159 sal_Int32 nColon = rStr.indexOf(':');
160 sal_Int32 nSemiColon = rStr.indexOf(';');
161 if (nColon != -1 && (nSemiColon == -1 || nColon < nSemiColon))
162 return ImplMakeSearchString(rStr.getToken( 0, ':' ));
163 return ImplMakeSearchString(rStr.getToken( 0, ';' ));
166 // -----------------------------------------------------------------------
168 ImplFontListNameInfo* FontList::ImplFind(const OUString& rSearchName, sal_uLong* pIndex) const
170 // Wenn kein Eintrag in der Liste oder der Eintrag groesser ist als
171 // der Letzte, dann hinten dranhaengen. Wir vergleichen erst mit dem
172 // letzten Eintrag, da die Liste von VCL auch sortiert zurueckkommt
173 // und somit die Wahrscheinlichkeit das hinten angehaengt werden muss
174 // sehr gross ist.
175 sal_uLong nCnt = maEntries.size();
176 if ( !nCnt )
178 if ( pIndex )
179 *pIndex = ULONG_MAX;
180 return NULL;
182 else
184 const ImplFontListNameInfo* pCmpData = &maEntries[nCnt-1];
185 sal_Int32 nComp = rSearchName.compareTo( pCmpData->maSearchName );
186 if (nComp > 0)
188 if ( pIndex )
189 *pIndex = ULONG_MAX;
190 return NULL;
192 else if (nComp == 0)
193 return const_cast<ImplFontListNameInfo*>(pCmpData);
196 // Fonts in der Liste suchen
197 const ImplFontListNameInfo* pCompareData;
198 const ImplFontListNameInfo* pFoundData = NULL;
199 sal_uLong nLow = 0;
200 sal_uLong nHigh = nCnt-1;
201 sal_uLong nMid;
205 nMid = (nLow + nHigh) / 2;
206 pCompareData = &maEntries[nMid];
207 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
208 if (nComp < 0)
210 if ( !nMid )
211 break;
212 nHigh = nMid-1;
214 else
216 if (nComp > 0)
217 nLow = nMid + 1;
218 else
220 pFoundData = pCompareData;
221 break;
225 while ( nLow <= nHigh );
227 if ( pIndex )
229 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
230 if (nComp > 0)
231 *pIndex = (nMid+1);
232 else
233 *pIndex = nMid;
236 return const_cast<ImplFontListNameInfo*>(pFoundData);
239 ImplFontListNameInfo* FontList::ImplFindByName(const OUString& rStr) const
241 OUString aSearchName = ImplMakeSearchStringFromName(rStr);
242 return ImplFind( aSearchName, NULL );
245 void FontList::ImplInsertFonts( OutputDevice* pDevice, sal_Bool bAll,
246 sal_Bool bInsertData )
248 rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
250 sal_uInt16 nType;
251 if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
252 nType = FONTLIST_FONTNAMETYPE_SCREEN;
253 else
254 nType = FONTLIST_FONTNAMETYPE_PRINTER;
256 // Alle Fonts vom Device abfragen
257 int n = pDevice->GetDevFontCount();
258 sal_uInt16 i;
259 for( i = 0; i < n; i++ )
261 FontInfo aFontInfo = pDevice->GetDevFont( i );
263 // Wenn keine Raster-Schriften angezeigt werden sollen,
264 // dann diese ignorieren
265 if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
266 continue;
268 OUString aSearchName(aFontInfo.GetName());
269 ImplFontListNameInfo* pData;
270 sal_uLong nIndex;
271 aSearchName = ImplMakeSearchString(aSearchName);
272 pData = ImplFind( aSearchName, &nIndex );
274 if ( !pData )
276 if ( bInsertData )
278 ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
279 pData = new ImplFontListNameInfo( aSearchName );
280 pData->mpFirst = pNewInfo;
281 pNewInfo->mpNext = NULL;
283 if (nIndex < maEntries.size())
284 maEntries.insert(maEntries.begin()+nIndex,pData);
285 else
286 maEntries.push_back(pData);
289 else
291 if ( bInsertData )
293 sal_Bool bInsert = sal_True;
294 ImplFontListFontInfo* pPrev = NULL;
295 ImplFontListFontInfo* pTemp = pData->mpFirst;
296 ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
297 while ( pTemp )
299 sal_Int32 eComp = ImplCompareFontInfo( pNewInfo, pTemp );
300 if ( eComp <= 0 )
302 if ( eComp == 0 )
304 // Overwrite charset, because charset should match
305 // with the system charset
306 if ( (pTemp->GetCharSet() != eSystemEncoding) &&
307 (pNewInfo->GetCharSet() == eSystemEncoding) )
309 ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
310 *((FontInfo*)pTemp) = *((FontInfo*)pNewInfo);
311 pTemp->mpNext = pTemp2;
313 delete pNewInfo;
314 bInsert = sal_False;
317 break;
320 pPrev = pTemp;
321 pTemp = pTemp->mpNext;
324 if ( bInsert )
326 pNewInfo->mpNext = pTemp;
327 if ( pPrev )
328 pPrev->mpNext = pNewInfo;
329 else
330 pData->mpFirst = pNewInfo;
335 if ( pData )
336 pData->mnType |= nType;
340 // =======================================================================
342 FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, sal_Bool bAll )
344 // Variablen initialisieren
345 mpDev = pDevice;
346 mpDev2 = pDevice2;
347 mpSizeAry = NULL;
349 // Stylenamen festlegen
350 maLight = SVT_RESSTR(STR_SVT_STYLE_LIGHT);
351 maLightItalic = SVT_RESSTR(STR_SVT_STYLE_LIGHT_ITALIC);
352 maNormal = SVT_RESSTR(STR_SVT_STYLE_NORMAL);
353 maNormalItalic = SVT_RESSTR(STR_SVT_STYLE_NORMAL_ITALIC);
354 maBold = SVT_RESSTR(STR_SVT_STYLE_BOLD);
355 maBoldItalic = SVT_RESSTR(STR_SVT_STYLE_BOLD_ITALIC);
356 maBlack = SVT_RESSTR(STR_SVT_STYLE_BLACK);
357 maBlackItalic = SVT_RESSTR(STR_SVT_STYLE_BLACK_ITALIC);
359 ImplInsertFonts( pDevice, bAll, sal_True );
361 // Gegebenenfalls muessen wir mit den Bildschirmfonts vergleichen,
362 // damit dort die eigentlich doppelten auf Equal mappen koennen
363 sal_Bool bCompareWindow = sal_False;
364 if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
366 bCompareWindow = sal_True;
367 pDevice2 = Application::GetDefaultDevice();
370 if ( pDevice2 &&
371 (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
372 ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
375 // -----------------------------------------------------------------------
377 FontList::~FontList()
379 // Gegebenenfalls SizeArray loeschen
380 delete[] mpSizeAry;
382 // FontInfos loeschen
383 ImplFontListFontInfo *pTemp, *pInfo;
384 boost::ptr_vector<ImplFontListNameInfo>::iterator it;
385 for (it = maEntries.begin(); it != maEntries.end(); ++it)
387 pInfo = it->mpFirst;
388 while ( pInfo )
390 pTemp = pInfo->mpNext;
391 delete pInfo;
392 pInfo = pTemp;
396 // -----------------------------------------------------------------------
397 FontList* FontList::Clone() const
399 FontList* pReturn = new FontList(
400 mpDev, mpDev2, GetFontNameCount() == mpDev->GetDevFontCount());
401 return pReturn;
404 // -----------------------------------------------------------------------
406 const OUString& FontList::GetStyleName(FontWeight eWeight, FontItalic eItalic) const
408 if ( eWeight > WEIGHT_BOLD )
410 if ( eItalic > ITALIC_NONE )
411 return maBlackItalic;
412 else
413 return maBlack;
415 else if ( eWeight > WEIGHT_MEDIUM )
417 if ( eItalic > ITALIC_NONE )
418 return maBoldItalic;
419 else
420 return maBold;
422 else if ( eWeight > WEIGHT_LIGHT )
424 if ( eItalic > ITALIC_NONE )
425 return maNormalItalic;
426 else
427 return maNormal;
429 else if ( eWeight != WEIGHT_DONTKNOW )
431 if ( eItalic > ITALIC_NONE )
432 return maLightItalic;
433 else
434 return maLight;
436 else
438 if ( eItalic > ITALIC_NONE )
439 return maNormalItalic;
440 else
441 return maNormal;
445 // -----------------------------------------------------------------------
447 OUString FontList::GetStyleName(const FontInfo& rInfo) const
449 OUString aStyleName = rInfo.GetStyleName();
450 FontWeight eWeight = rInfo.GetWeight();
451 FontItalic eItalic = rInfo.GetItalic();
453 // Nur wenn kein StyleName gesetzt ist, geben wir einen syntetischen
454 // Namen zurueck
455 if (aStyleName.isEmpty())
456 aStyleName = GetStyleName(eWeight, eItalic);
457 else
459 // Translate StyleName to localized name
460 OUString aCompareStyleName = aStyleName.toAsciiLowerCase();
461 aCompareStyleName = comphelper::string::remove(aCompareStyleName, ' ');
462 if (aCompareStyleName == "bold")
463 aStyleName = maBold;
464 else if (aCompareStyleName == "bolditalic")
465 aStyleName = maBoldItalic;
466 else if (aCompareStyleName == "italic")
467 aStyleName = maNormalItalic;
468 else if (aCompareStyleName == "standard")
469 aStyleName = maNormal;
470 else if (aCompareStyleName == "regular")
471 aStyleName = maNormal;
472 else if (aCompareStyleName == "medium")
473 aStyleName = maNormal;
474 else if (aCompareStyleName == "light")
475 aStyleName = maLight;
476 else if (aCompareStyleName == "lightitalic")
477 aStyleName = maLightItalic;
478 else if (aCompareStyleName == "black")
479 aStyleName = maBlack;
480 else if (aCompareStyleName == "blackitalic")
481 aStyleName = maBlackItalic;
483 // fix up StyleName, because the PS Printer driver from
484 // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
485 // for Helvetica)
486 if ( eItalic > ITALIC_NONE )
488 if ( (aStyleName == maNormal) ||
489 (aStyleName == maBold) ||
490 (aStyleName == maLight) ||
491 (aStyleName == maBlack) )
492 aStyleName = GetStyleName( eWeight, eItalic );
496 return aStyleName;
499 // -----------------------------------------------------------------------
501 OUString FontList::GetFontMapText( const FontInfo& rInfo ) const
503 if ( rInfo.GetName().isEmpty() )
505 return OUString();
508 // Search Fontname
509 ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
510 if ( !pData )
512 if (maMapNotAvailable.isEmpty())
513 maMapNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_NOTAVAILABLE);
514 return maMapNotAvailable;
517 // search for synthetic style
518 sal_uInt16 nType = pData->mnType;
519 const OUString& rStyleName = rInfo.GetStyleName();
520 if (!rStyleName.isEmpty())
522 sal_Bool bNotSynthetic = sal_False;
523 sal_Bool bNoneAvailable = sal_False;
524 FontWeight eWeight = rInfo.GetWeight();
525 FontItalic eItalic = rInfo.GetItalic();
526 ImplFontListFontInfo* pFontInfo = pData->mpFirst;
527 while ( pFontInfo )
529 if ( (eWeight == pFontInfo->GetWeight()) &&
530 (eItalic == pFontInfo->GetItalic()) )
532 bNotSynthetic = sal_True;
533 break;
536 pFontInfo = pFontInfo->mpNext;
539 if ( bNoneAvailable )
541 return OUString();
543 else if ( !bNotSynthetic )
545 if (maMapStyleNotAvailable.isEmpty())
546 ((FontList*)this)->maMapStyleNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_STYLENOTAVAILABLE);
547 return maMapStyleNotAvailable;
551 // Only Printer-Font?
552 if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
554 if (maMapPrinterOnly.isEmpty())
555 ((FontList*)this)->maMapPrinterOnly = SVT_RESSTR(STR_SVT_FONTMAP_PRINTERONLY);
556 return maMapPrinterOnly;
558 // Only Screen-Font?
559 else if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_SCREEN
560 && rInfo.GetType() == TYPE_RASTER )
562 if (maMapScreenOnly.isEmpty())
563 ((FontList*)this)->maMapScreenOnly = SVT_RESSTR(STR_SVT_FONTMAP_SCREENONLY);
564 return maMapScreenOnly;
566 else
568 if (maMapBoth.isEmpty())
569 ((FontList*)this)->maMapBoth = SVT_RESSTR(STR_SVT_FONTMAP_BOTH);
570 return maMapBoth;
574 namespace
576 FontInfo makeMissing(ImplFontListFontInfo* pFontNameInfo, const OUString &rName,
577 FontWeight eWeight, FontItalic eItalic)
579 FontInfo aInfo;
580 // Falls der Fontname stimmt, uebernehmen wir soviel wie moeglich
581 if (pFontNameInfo)
583 aInfo = *pFontNameInfo;
584 aInfo.SetStyleName(OUString());
587 aInfo.SetWeight(eWeight);
588 aInfo.SetItalic(eItalic);
590 //If this is a known but uninstalled symbol font which we can remap to
591 //OpenSymbol then toggle its charset to be a symbol font
592 if (ConvertChar::GetRecodeData(rName, OUString("OpenSymbol")))
593 aInfo.SetCharSet(RTL_TEXTENCODING_SYMBOL);
595 return aInfo;
599 FontInfo FontList::Get(const OUString& rName, const OUString& rStyleName) const
601 ImplFontListNameInfo* pData = ImplFindByName( rName );
602 ImplFontListFontInfo* pFontInfo = NULL;
603 ImplFontListFontInfo* pFontNameInfo = NULL;
604 if ( pData )
606 ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
607 pFontNameInfo = pSearchInfo;
608 pSearchInfo = pData->mpFirst;
609 while ( pSearchInfo )
611 if (rStyleName.equalsIgnoreAsciiCase(GetStyleName(*pSearchInfo)))
613 pFontInfo = pSearchInfo;
614 break;
617 pSearchInfo = pSearchInfo->mpNext;
621 // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
622 // Attribute nachgebildet werden
623 FontInfo aInfo;
624 if ( !pFontInfo )
626 FontWeight eWeight = WEIGHT_DONTKNOW;
627 FontItalic eItalic = ITALIC_NONE;
629 if ( rStyleName == maNormal )
631 eItalic = ITALIC_NONE;
632 eWeight = WEIGHT_NORMAL;
634 else if ( rStyleName == maNormalItalic )
636 eItalic = ITALIC_NORMAL;
637 eWeight = WEIGHT_NORMAL;
639 else if ( rStyleName == maBold )
641 eItalic = ITALIC_NONE;
642 eWeight = WEIGHT_BOLD;
644 else if ( rStyleName == maBoldItalic )
646 eItalic = ITALIC_NORMAL;
647 eWeight = WEIGHT_BOLD;
649 else if ( rStyleName == maLight )
651 eItalic = ITALIC_NONE;
652 eWeight = WEIGHT_LIGHT;
654 else if ( rStyleName == maLightItalic )
656 eItalic = ITALIC_NORMAL;
657 eWeight = WEIGHT_LIGHT;
659 else if ( rStyleName == maBlack )
661 eItalic = ITALIC_NONE;
662 eWeight = WEIGHT_BLACK;
664 else if ( rStyleName == maBlackItalic )
666 eItalic = ITALIC_NORMAL;
667 eWeight = WEIGHT_BLACK;
669 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
671 else
672 aInfo = *pFontInfo;
674 // set Fontname to keep FontAlias
675 aInfo.SetName( rName );
676 aInfo.SetStyleName( rStyleName );
678 return aInfo;
681 // -----------------------------------------------------------------------
683 FontInfo FontList::Get(const OUString& rName,
684 FontWeight eWeight, FontItalic eItalic) const
686 ImplFontListNameInfo* pData = ImplFindByName( rName );
687 ImplFontListFontInfo* pFontInfo = NULL;
688 ImplFontListFontInfo* pFontNameInfo = NULL;
689 if ( pData )
691 ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
692 pFontNameInfo = pSearchInfo;
693 while ( pSearchInfo )
695 if ( (eWeight == pSearchInfo->GetWeight()) &&
696 (eItalic == pSearchInfo->GetItalic()) )
698 pFontInfo = pSearchInfo;
699 break;
702 pSearchInfo = pSearchInfo->mpNext;
706 // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
707 // Attribute nachgebildet werden
708 FontInfo aInfo;
709 if ( !pFontInfo )
710 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
711 else
712 aInfo = *pFontInfo;
714 // set Fontname to keep FontAlias
715 aInfo.SetName( rName );
717 return aInfo;
720 // -----------------------------------------------------------------------
722 sal_Bool FontList::IsAvailable(const OUString& rName) const
724 return (ImplFindByName( rName ) != 0);
727 // -----------------------------------------------------------------------
729 const FontInfo& FontList::GetFontName( sal_uInt16 nFont ) const
731 DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
733 return *(maEntries[nFont].mpFirst);
736 // -----------------------------------------------------------------------
738 sal_Handle FontList::GetFirstFontInfo(const OUString& rName) const
740 ImplFontListNameInfo* pData = ImplFindByName( rName );
741 if ( !pData )
742 return (sal_Handle)NULL;
743 else
744 return (sal_Handle)pData->mpFirst;
747 // -----------------------------------------------------------------------
749 sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo ) const
751 ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
752 return (sal_Handle)(pInfo->mpNext);
755 // -----------------------------------------------------------------------
757 const FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo ) const
759 ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
760 return *pInfo;
763 // -----------------------------------------------------------------------
765 const sal_IntPtr* FontList::GetSizeAry( const FontInfo& rInfo ) const
767 // Size-Array vorher loeschen
768 if ( mpSizeAry )
770 delete[] ((FontList*)this)->mpSizeAry;
771 ((FontList*)this)->mpSizeAry = NULL;
774 // Falls kein Name, dann Standardgroessen
775 if ( rInfo.GetName().isEmpty() )
776 return aStdSizeAry;
778 // Zuerst nach dem Fontnamen suchen um das Device dann von dem
779 // entsprechenden Font zu nehmen
780 OutputDevice* pDevice = mpDev;
781 ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
782 if ( pData )
783 pDevice = pData->mpFirst->GetDevice();
785 int nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
786 if ( !nDevSizeCount ||
787 (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
788 return aStdSizeAry;
790 MapMode aOldMapMode = pDevice->GetMapMode();
791 MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
792 pDevice->SetMapMode( aMap );
794 sal_uInt16 i;
795 sal_uInt16 nRealCount = 0;
796 long nOldHeight = 0;
797 ((FontList*)this)->mpSizeAry = new sal_IntPtr[nDevSizeCount+1];
798 for ( i = 0; i < nDevSizeCount; i++ )
800 Size aSize = pDevice->GetDevFontSize( rInfo, i );
801 if ( aSize.Height() != nOldHeight )
803 nOldHeight = aSize.Height();
804 ((FontList*)this)->mpSizeAry[nRealCount] = nOldHeight;
805 nRealCount++;
808 ((FontList*)this)->mpSizeAry[nRealCount] = 0;
810 pDevice->SetMapMode( aOldMapMode );
811 return mpSizeAry;
814 // -----------------------------------------------------------------------
816 const sal_IntPtr* FontList::GetStdSizeAry()
818 return aStdSizeAry;
821 // =======================================================================
823 // ---------------------------------
824 // - FontSizeNames & FsizeNameItem -
825 // ---------------------------------
827 struct ImplFSNameItem
829 long mnSize;
830 const char* mszUtf8Name;
833 //------------------------------------------------------------------------
835 static const ImplFSNameItem aImplSimplifiedChinese[] =
837 { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
838 { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
839 { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
840 { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
841 { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
842 { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
843 { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
844 { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
845 { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
846 { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
847 { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
848 { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
849 { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
850 { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
851 { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
852 { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
855 //------------------------------------------------------------------------
857 FontSizeNames::FontSizeNames( LanguageType eLanguage )
859 if ( eLanguage == LANGUAGE_DONTKNOW )
860 eLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
861 if ( eLanguage == LANGUAGE_SYSTEM )
862 eLanguage = MsLangId::getSystemUILanguage();
864 if (MsLangId::isSimplifiedChinese(eLanguage))
866 // equivalent for traditional chinese disabled by popular request, #i89077#
867 mpArray = aImplSimplifiedChinese;
868 mnElem = SAL_N_ELEMENTS(aImplSimplifiedChinese);
870 else
872 mpArray = NULL;
873 mnElem = 0;
877 //------------------------------------------------------------------------
879 long FontSizeNames::Name2Size( const OUString& rName ) const
881 if ( mnElem )
883 OString aName(OUStringToOString(rName,
884 RTL_TEXTENCODING_UTF8));
886 // linear search is sufficient for this rare case
887 for( long i = mnElem; --i >= 0; )
888 if ( aName.equals(mpArray[i].mszUtf8Name) )
889 return mpArray[i].mnSize;
892 return 0;
895 //------------------------------------------------------------------------
897 OUString FontSizeNames::Size2Name( long nValue ) const
899 OUString aStr;
901 // binary search
902 for( long lower = 0, upper = mnElem - 1; lower <= upper; )
904 long mid = (upper + lower) >> 1;
905 if ( nValue == mpArray[mid].mnSize )
907 aStr = OUString( mpArray[mid].mszUtf8Name, strlen(mpArray[mid].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
908 break;
910 else if ( nValue < mpArray[mid].mnSize )
911 upper = mid - 1;
912 else /* ( nValue > mpArray[mid].mnSize ) */
913 lower = mid + 1;
916 return aStr;
919 //------------------------------------------------------------------------
921 OUString FontSizeNames::GetIndexName( sal_uLong nIndex ) const
923 OUString aStr;
925 if ( nIndex < mnElem )
926 aStr = OUString( mpArray[nIndex].mszUtf8Name, strlen(mpArray[nIndex].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
928 return aStr;
931 //------------------------------------------------------------------------
933 long FontSizeNames::GetIndexSize( sal_uLong nIndex ) const
935 if ( nIndex >= mnElem )
936 return 0;
937 return mpArray[nIndex].mnSize;
940 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */