Bump version to 5.0-14
[LibreOffice.git] / svtools / source / control / ctrltool.cxx
blobb8d32ec1cc23b2caf974077040a43c152b3d3085
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 <tools/fract.hxx>
25 #include <i18nlangtag/mslangid.hxx>
26 #include <vcl/window.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/wrkwin.hxx>
29 #include <vcl/settings.hxx>
30 #include <sal/macros.h>
31 #include <svtools/svtools.hrc>
32 #include <svtools/svtresid.hxx>
33 #include <svtools/ctrltool.hxx>
34 #include <o3tl/typed_flags_set.hxx>
36 // Standard Fontgroessen fuer scalierbare Fonts
37 const sal_IntPtr FontList::aStdSizeAry[] =
39 60,
40 70,
41 80,
42 90,
43 100,
44 105,
45 110,
46 120,
47 130,
48 140,
49 150,
50 160,
51 180,
52 200,
53 220,
54 240,
55 260,
56 280,
57 320,
58 360,
59 400,
60 440,
61 480,
62 540,
63 600,
64 660,
65 720,
66 800,
67 880,
68 960,
72 class ImplFontListFontInfo : public vcl::FontInfo
74 friend class FontList;
76 private:
77 VclPtr<OutputDevice> mpDevice;
78 ImplFontListFontInfo* mpNext;
80 public:
81 ImplFontListFontInfo( const vcl::FontInfo& rInfo,
82 OutputDevice* pDev ) :
83 vcl::FontInfo( rInfo ), mpNext(NULL)
85 mpDevice = pDev;
88 OutputDevice* GetDevice() const { return mpDevice; }
91 enum class FontListFontNameType
93 NONE = 0x00,
94 PRINTER = 0x01,
95 SCREEN = 0x02,
97 namespace o3tl
99 template<> struct typed_flags<FontListFontNameType> : is_typed_flags<FontListFontNameType, 0x3> {};
102 class ImplFontListNameInfo
104 friend class FontList;
106 private:
107 OUString maSearchName;
108 ImplFontListFontInfo* mpFirst;
109 FontListFontNameType mnType;
111 ImplFontListNameInfo(const OUString& rSearchName)
112 : maSearchName(rSearchName)
113 , mpFirst(NULL)
114 , mnType(FontListFontNameType::NONE)
119 //sort normal to the start
120 static int sortWeightValue(FontWeight eWeight)
122 if (eWeight < WEIGHT_NORMAL)
123 return eWeight + 1;
124 if (eWeight > WEIGHT_NORMAL)
125 return eWeight - 1;
126 return 0; // eWeight == WEIGHT_NORMAL
129 static sal_Int32 ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
130 ImplFontListFontInfo* pInfo2 )
132 //Sort non italic before italics
133 if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
134 return -1;
135 else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
136 return 1;
138 //Sort normal weight to the start, followed by lightest to heaviest weights
139 int nWeight1 = sortWeightValue(pInfo1->GetWeight());
140 int nWeight2 = sortWeightValue(pInfo2->GetWeight());
142 if ( nWeight1 < nWeight2 )
143 return -1;
144 else if ( nWeight1 > nWeight2 )
145 return 1;
147 return pInfo1->GetStyleName().compareTo( pInfo2->GetStyleName() );
150 static OUString ImplMakeSearchString(const OUString& rStr)
152 return rStr.toAsciiLowerCase();
155 static OUString ImplMakeSearchStringFromName(const OUString& rStr)
157 // check for features before alternate font separator
158 sal_Int32 nColon = rStr.indexOf(':');
159 sal_Int32 nSemiColon = rStr.indexOf(';');
160 if (nColon != -1 && (nSemiColon == -1 || nColon < nSemiColon))
161 return ImplMakeSearchString(rStr.getToken( 0, ':' ));
162 return ImplMakeSearchString(rStr.getToken( 0, ';' ));
165 ImplFontListNameInfo* FontList::ImplFind(const OUString& rSearchName, sal_uLong* pIndex) const
167 // Append if there is no enty in the list or if the entry is larger
168 // then the last one. We only compare to the last entry as the list of VCL
169 // is returned sorted, which increases the probability that appending
170 // is more likely
171 sal_uLong nCnt = maEntries.size();
172 if ( !nCnt )
174 if ( pIndex )
175 *pIndex = ULONG_MAX;
176 return NULL;
178 else
180 const ImplFontListNameInfo* pCmpData = &maEntries[nCnt-1];
181 sal_Int32 nComp = rSearchName.compareTo( pCmpData->maSearchName );
182 if (nComp > 0)
184 if ( pIndex )
185 *pIndex = ULONG_MAX;
186 return NULL;
188 else if (nComp == 0)
189 return const_cast<ImplFontListNameInfo*>(pCmpData);
192 // search fonts in the list
193 const ImplFontListNameInfo* pCompareData;
194 const ImplFontListNameInfo* pFoundData = NULL;
195 sal_uLong nLow = 0;
196 sal_uLong nHigh = nCnt-1;
197 sal_uLong nMid;
201 nMid = (nLow + nHigh) / 2;
202 pCompareData = &maEntries[nMid];
203 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
204 if (nComp < 0)
206 if ( !nMid )
207 break;
208 nHigh = nMid-1;
210 else
212 if (nComp > 0)
213 nLow = nMid + 1;
214 else
216 pFoundData = pCompareData;
217 break;
221 while ( nLow <= nHigh );
223 if ( pIndex )
225 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
226 if (nComp > 0)
227 *pIndex = (nMid+1);
228 else
229 *pIndex = nMid;
232 return const_cast<ImplFontListNameInfo*>(pFoundData);
235 ImplFontListNameInfo* FontList::ImplFindByName(const OUString& rStr) const
237 OUString aSearchName = ImplMakeSearchStringFromName(rStr);
238 return ImplFind( aSearchName, NULL );
241 void FontList::ImplInsertFonts( OutputDevice* pDevice, bool bAll,
242 bool bInsertData )
244 rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
246 FontListFontNameType nType;
247 if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
248 nType = FontListFontNameType::SCREEN;
249 else
250 nType = FontListFontNameType::PRINTER;
252 // inquire all fonts from the device
253 int n = pDevice->GetDevFontCount();
254 sal_uInt16 i;
255 for( i = 0; i < n; i++ )
257 vcl::FontInfo aFontInfo = pDevice->GetDevFont( i );
259 // ignore raster-fonts if they are not to be displayed
260 if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
261 continue;
263 OUString aSearchName(aFontInfo.GetName());
264 ImplFontListNameInfo* pData;
265 sal_uLong nIndex;
266 aSearchName = ImplMakeSearchString(aSearchName);
267 pData = ImplFind( aSearchName, &nIndex );
269 if ( !pData )
271 if ( bInsertData )
273 ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
274 pData = new ImplFontListNameInfo( aSearchName );
275 pData->mpFirst = pNewInfo;
276 pNewInfo->mpNext = NULL;
278 if (nIndex < maEntries.size())
279 maEntries.insert(maEntries.begin()+nIndex,pData);
280 else
281 maEntries.push_back(pData);
284 else
286 if ( bInsertData )
288 bool bInsert = true;
289 ImplFontListFontInfo* pPrev = NULL;
290 ImplFontListFontInfo* pTemp = pData->mpFirst;
291 ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
292 while ( pTemp )
294 sal_Int32 eComp = ImplCompareFontInfo( pNewInfo, pTemp );
295 if ( eComp <= 0 )
297 if ( eComp == 0 )
299 // Overwrite charset, because charset should match
300 // with the system charset
301 if ( (pTemp->GetCharSet() != eSystemEncoding) &&
302 (pNewInfo->GetCharSet() == eSystemEncoding) )
304 ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
305 *((vcl::FontInfo*)pTemp) = *((vcl::FontInfo*)pNewInfo);
306 pTemp->mpNext = pTemp2;
308 delete pNewInfo;
309 bInsert = false;
312 break;
315 pPrev = pTemp;
316 pTemp = pTemp->mpNext;
319 if ( bInsert )
321 pNewInfo->mpNext = pTemp;
322 if ( pPrev )
323 pPrev->mpNext = pNewInfo;
324 else
325 pData->mpFirst = pNewInfo;
330 if ( pData )
331 pData->mnType |= nType;
335 FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, bool bAll )
337 // initialise variables
338 mpDev = pDevice;
339 mpDev2 = pDevice2;
340 mpSizeAry = NULL;
342 // store style names
343 maLight = SVT_RESSTR(STR_SVT_STYLE_LIGHT);
344 maLightItalic = SVT_RESSTR(STR_SVT_STYLE_LIGHT_ITALIC);
345 maNormal = SVT_RESSTR(STR_SVT_STYLE_NORMAL);
346 maNormalItalic = SVT_RESSTR(STR_SVT_STYLE_NORMAL_ITALIC);
347 maBold = SVT_RESSTR(STR_SVT_STYLE_BOLD);
348 maBoldItalic = SVT_RESSTR(STR_SVT_STYLE_BOLD_ITALIC);
349 maBlack = SVT_RESSTR(STR_SVT_STYLE_BLACK);
350 maBlackItalic = SVT_RESSTR(STR_SVT_STYLE_BLACK_ITALIC);
352 ImplInsertFonts( pDevice, bAll, true );
354 // if required compare to the screen fonts
355 // in order to map the duplicates to Equal
356 bool bCompareWindow = false;
357 if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
359 bCompareWindow = true;
360 pDevice2 = Application::GetDefaultDevice();
363 if ( pDevice2 &&
364 (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
365 ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
368 FontList::~FontList()
370 // delete SizeArray if required
371 delete[] mpSizeAry;
373 // delete FontInfos
374 ImplFontListFontInfo *pTemp, *pInfo;
375 boost::ptr_vector<ImplFontListNameInfo>::iterator it;
376 for (it = maEntries.begin(); it != maEntries.end(); ++it)
378 pInfo = it->mpFirst;
379 while ( pInfo )
381 pTemp = pInfo->mpNext;
382 delete pInfo;
383 pInfo = pTemp;
388 FontList* FontList::Clone() const
390 FontList* pReturn = new FontList(
391 mpDev, mpDev2, GetFontNameCount() == mpDev->GetDevFontCount());
392 return pReturn;
395 const OUString& FontList::GetStyleName(FontWeight eWeight, FontItalic eItalic) const
397 if ( eWeight > WEIGHT_BOLD )
399 if ( eItalic > ITALIC_NONE )
400 return maBlackItalic;
401 else
402 return maBlack;
404 else if ( eWeight > WEIGHT_MEDIUM )
406 if ( eItalic > ITALIC_NONE )
407 return maBoldItalic;
408 else
409 return maBold;
411 else if ( eWeight > WEIGHT_LIGHT )
413 if ( eItalic > ITALIC_NONE )
414 return maNormalItalic;
415 else
416 return maNormal;
418 else if ( eWeight != WEIGHT_DONTKNOW )
420 if ( eItalic > ITALIC_NONE )
421 return maLightItalic;
422 else
423 return maLight;
425 else
427 if ( eItalic > ITALIC_NONE )
428 return maNormalItalic;
429 else
430 return maNormal;
434 OUString FontList::GetStyleName(const vcl::FontInfo& rInfo) const
436 OUString aStyleName = rInfo.GetStyleName();
437 FontWeight eWeight = rInfo.GetWeight();
438 FontItalic eItalic = rInfo.GetItalic();
440 // return synthetic Name if no StyleName was set
441 if (aStyleName.isEmpty())
442 aStyleName = GetStyleName(eWeight, eItalic);
443 else
445 // Translate StyleName to localized name
446 OUString aCompareStyleName = aStyleName.toAsciiLowerCase();
447 aCompareStyleName = comphelper::string::remove(aCompareStyleName, ' ');
448 if (aCompareStyleName == "bold")
449 aStyleName = maBold;
450 else if (aCompareStyleName == "bolditalic")
451 aStyleName = maBoldItalic;
452 else if (aCompareStyleName == "italic")
453 aStyleName = maNormalItalic;
454 else if (aCompareStyleName == "standard")
455 aStyleName = maNormal;
456 else if (aCompareStyleName == "regular")
457 aStyleName = maNormal;
458 else if (aCompareStyleName == "medium")
459 aStyleName = maNormal;
460 else if (aCompareStyleName == "light")
461 aStyleName = maLight;
462 else if (aCompareStyleName == "lightitalic")
463 aStyleName = maLightItalic;
464 else if (aCompareStyleName == "black")
465 aStyleName = maBlack;
466 else if (aCompareStyleName == "blackitalic")
467 aStyleName = maBlackItalic;
469 // fix up StyleName, because the PS Printer driver from
470 // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
471 // for Helvetica)
472 if ( eItalic > ITALIC_NONE )
474 if ( (aStyleName == maNormal) ||
475 (aStyleName == maBold) ||
476 (aStyleName == maLight) ||
477 (aStyleName == maBlack) )
478 aStyleName = GetStyleName( eWeight, eItalic );
482 return aStyleName;
485 OUString FontList::GetFontMapText( const vcl::FontInfo& rInfo ) const
487 if ( rInfo.GetName().isEmpty() )
489 return OUString();
492 // Search Fontname
493 ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
494 if ( !pData )
496 if (maMapNotAvailable.isEmpty())
497 maMapNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_NOTAVAILABLE);
498 return maMapNotAvailable;
501 // search for synthetic style
502 FontListFontNameType nType = pData->mnType;
503 const OUString& rStyleName = rInfo.GetStyleName();
504 if (!rStyleName.isEmpty())
506 bool bNotSynthetic = false;
507 FontWeight eWeight = rInfo.GetWeight();
508 FontItalic eItalic = rInfo.GetItalic();
509 ImplFontListFontInfo* pFontInfo = pData->mpFirst;
510 while ( pFontInfo )
512 if ( (eWeight == pFontInfo->GetWeight()) &&
513 (eItalic == pFontInfo->GetItalic()) )
515 bNotSynthetic = true;
516 break;
519 pFontInfo = pFontInfo->mpNext;
522 if ( !bNotSynthetic )
524 if (maMapStyleNotAvailable.isEmpty())
525 const_cast<FontList*>(this)->maMapStyleNotAvailable = SVT_RESSTR(STR_SVT_FONTMAP_STYLENOTAVAILABLE);
526 return maMapStyleNotAvailable;
530 // Only Printer-Font?
531 if ( nType == FontListFontNameType::PRINTER )
533 if (maMapPrinterOnly.isEmpty())
534 const_cast<FontList*>(this)->maMapPrinterOnly = SVT_RESSTR(STR_SVT_FONTMAP_PRINTERONLY);
535 return maMapPrinterOnly;
537 // Only Screen-Font?
538 else if ( nType == FontListFontNameType::SCREEN
539 && rInfo.GetType() == TYPE_RASTER )
541 if (maMapScreenOnly.isEmpty())
542 const_cast<FontList*>(this)->maMapScreenOnly = SVT_RESSTR(STR_SVT_FONTMAP_SCREENONLY);
543 return maMapScreenOnly;
545 else
547 if (maMapBoth.isEmpty())
548 const_cast<FontList*>(this)->maMapBoth = SVT_RESSTR(STR_SVT_FONTMAP_BOTH);
549 return maMapBoth;
553 namespace
555 vcl::FontInfo makeMissing(ImplFontListFontInfo* pFontNameInfo, const OUString &rName,
556 FontWeight eWeight, FontItalic eItalic)
558 vcl::FontInfo aInfo;
559 // if the fontname matches, we copy as much as possible
560 if (pFontNameInfo)
562 aInfo = *pFontNameInfo;
563 aInfo.SetStyleName(OUString());
566 aInfo.SetWeight(eWeight);
567 aInfo.SetItalic(eItalic);
569 //If this is a known but uninstalled symbol font which we can remap to
570 //OpenSymbol then toggle its charset to be a symbol font
571 if (ConvertChar::GetRecodeData(rName, OUString("OpenSymbol")))
572 aInfo.SetCharSet(RTL_TEXTENCODING_SYMBOL);
574 return aInfo;
578 vcl::FontInfo FontList::Get(const OUString& rName, const OUString& rStyleName) const
580 ImplFontListNameInfo* pData = ImplFindByName( rName );
581 ImplFontListFontInfo* pFontInfo = NULL;
582 ImplFontListFontInfo* pFontNameInfo = NULL;
583 if ( pData )
585 ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
586 pFontNameInfo = pSearchInfo;
587 pSearchInfo = pData->mpFirst;
588 while ( pSearchInfo )
590 if (rStyleName.equalsIgnoreAsciiCase(GetStyleName(*pSearchInfo)))
592 pFontInfo = pSearchInfo;
593 break;
596 pSearchInfo = pSearchInfo->mpNext;
600 // reproduce attributes if data could not be found
601 vcl::FontInfo aInfo;
602 if ( !pFontInfo )
604 FontWeight eWeight = WEIGHT_DONTKNOW;
605 FontItalic eItalic = ITALIC_NONE;
607 if ( rStyleName == maNormal )
609 eItalic = ITALIC_NONE;
610 eWeight = WEIGHT_NORMAL;
612 else if ( rStyleName == maNormalItalic )
614 eItalic = ITALIC_NORMAL;
615 eWeight = WEIGHT_NORMAL;
617 else if ( rStyleName == maBold )
619 eItalic = ITALIC_NONE;
620 eWeight = WEIGHT_BOLD;
622 else if ( rStyleName == maBoldItalic )
624 eItalic = ITALIC_NORMAL;
625 eWeight = WEIGHT_BOLD;
627 else if ( rStyleName == maLight )
629 eItalic = ITALIC_NONE;
630 eWeight = WEIGHT_LIGHT;
632 else if ( rStyleName == maLightItalic )
634 eItalic = ITALIC_NORMAL;
635 eWeight = WEIGHT_LIGHT;
637 else if ( rStyleName == maBlack )
639 eItalic = ITALIC_NONE;
640 eWeight = WEIGHT_BLACK;
642 else if ( rStyleName == maBlackItalic )
644 eItalic = ITALIC_NORMAL;
645 eWeight = WEIGHT_BLACK;
647 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
649 else
650 aInfo = *pFontInfo;
652 // set Fontname to keep FontAlias
653 aInfo.SetName( rName );
654 aInfo.SetStyleName( rStyleName );
656 return aInfo;
659 vcl::FontInfo FontList::Get(const OUString& rName,
660 FontWeight eWeight, FontItalic eItalic) const
662 ImplFontListNameInfo* pData = ImplFindByName( rName );
663 ImplFontListFontInfo* pFontInfo = NULL;
664 ImplFontListFontInfo* pFontNameInfo = NULL;
665 if ( pData )
667 ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
668 pFontNameInfo = pSearchInfo;
669 while ( pSearchInfo )
671 if ( (eWeight == pSearchInfo->GetWeight()) &&
672 (eItalic == pSearchInfo->GetItalic()) )
674 pFontInfo = pSearchInfo;
675 break;
678 pSearchInfo = pSearchInfo->mpNext;
682 // reproduce attributes if data could not be found
683 vcl::FontInfo aInfo;
684 if ( !pFontInfo )
685 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
686 else
687 aInfo = *pFontInfo;
689 // set Fontname to keep FontAlias
690 aInfo.SetName( rName );
692 return aInfo;
695 bool FontList::IsAvailable(const OUString& rName) const
697 return (ImplFindByName( rName ) != 0);
700 const vcl::FontInfo& FontList::GetFontName( sal_uInt16 nFont ) const
702 DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
704 return *(maEntries[nFont].mpFirst);
707 sal_Handle FontList::GetFirstFontInfo(const OUString& rName) const
709 ImplFontListNameInfo* pData = ImplFindByName( rName );
710 if ( !pData )
711 return (sal_Handle)NULL;
712 else
713 return (sal_Handle)pData->mpFirst;
716 sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo )
718 ImplFontListFontInfo* pInfo = static_cast<ImplFontListFontInfo*>((void*)hFontInfo);
719 return (sal_Handle)(pInfo->mpNext);
722 const vcl::FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo )
724 ImplFontListFontInfo* pInfo = static_cast<ImplFontListFontInfo*>((void*)hFontInfo);
725 return *pInfo;
728 const sal_IntPtr* FontList::GetSizeAry( const vcl::FontInfo& rInfo ) const
730 // first delete Size-Array
731 if ( mpSizeAry )
733 delete[] const_cast<FontList*>(this)->mpSizeAry;
734 const_cast<FontList*>(this)->mpSizeAry = NULL;
737 // use standarad sizes if no name
738 if ( rInfo.GetName().isEmpty() )
739 return aStdSizeAry;
741 // first search fontname in order to use device from the matching font
742 OutputDevice* pDevice = mpDev;
743 ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
744 if ( pData )
745 pDevice = pData->mpFirst->GetDevice();
747 int nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
748 if ( !nDevSizeCount ||
749 (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
750 return aStdSizeAry;
752 MapMode aOldMapMode = pDevice->GetMapMode();
753 MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
754 pDevice->SetMapMode( aMap );
756 sal_uInt16 i;
757 sal_uInt16 nRealCount = 0;
758 long nOldHeight = 0;
759 const_cast<FontList*>(this)->mpSizeAry = new sal_IntPtr[nDevSizeCount+1];
760 for ( i = 0; i < nDevSizeCount; i++ )
762 Size aSize = pDevice->GetDevFontSize( rInfo, i );
763 if ( aSize.Height() != nOldHeight )
765 nOldHeight = aSize.Height();
766 const_cast<FontList*>(this)->mpSizeAry[nRealCount] = nOldHeight;
767 nRealCount++;
770 const_cast<FontList*>(this)->mpSizeAry[nRealCount] = 0;
772 pDevice->SetMapMode( aOldMapMode );
773 return mpSizeAry;
776 struct ImplFSNameItem
778 long mnSize;
779 const char* mszUtf8Name;
782 static const ImplFSNameItem aImplSimplifiedChinese[] =
784 { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
785 { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
786 { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
787 { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
788 { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
789 { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
790 { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
791 { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
792 { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
793 { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
794 { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
795 { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
796 { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
797 { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
798 { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
799 { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
802 FontSizeNames::FontSizeNames( LanguageType eLanguage )
804 if ( eLanguage == LANGUAGE_DONTKNOW )
805 eLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
806 if ( eLanguage == LANGUAGE_SYSTEM )
807 eLanguage = MsLangId::getSystemUILanguage();
809 if (MsLangId::isSimplifiedChinese(eLanguage))
811 // equivalent for traditional chinese disabled by popular request, #i89077#
812 mpArray = aImplSimplifiedChinese;
813 mnElem = SAL_N_ELEMENTS(aImplSimplifiedChinese);
815 else
817 mpArray = NULL;
818 mnElem = 0;
822 long FontSizeNames::Name2Size( const OUString& rName ) const
824 if ( mnElem )
826 OString aName(OUStringToOString(rName,
827 RTL_TEXTENCODING_UTF8));
829 // linear search is sufficient for this rare case
830 for( long i = mnElem; --i >= 0; )
831 if ( aName.equals(mpArray[i].mszUtf8Name) )
832 return mpArray[i].mnSize;
835 return 0;
838 OUString FontSizeNames::Size2Name( long nValue ) const
840 OUString aStr;
842 // binary search
843 for( long lower = 0, upper = mnElem - 1; lower <= upper; )
845 long mid = (upper + lower) >> 1;
846 if ( nValue == mpArray[mid].mnSize )
848 aStr = OUString( mpArray[mid].mszUtf8Name, strlen(mpArray[mid].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
849 break;
851 else if ( nValue < mpArray[mid].mnSize )
852 upper = mid - 1;
853 else /* ( nValue > mpArray[mid].mnSize ) */
854 lower = mid + 1;
857 return aStr;
860 OUString FontSizeNames::GetIndexName( sal_uLong nIndex ) const
862 OUString aStr;
864 if ( nIndex < mnElem )
865 aStr = OUString( mpArray[nIndex].mszUtf8Name, strlen(mpArray[nIndex].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
867 return aStr;
870 long FontSizeNames::GetIndexSize( sal_uLong nIndex ) const
872 if ( nIndex >= mnElem )
873 return 0;
874 return mpArray[nIndex].mnSize;
877 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */