Use MsLangId::getConfiguredSystemUILanguage()
[LibreOffice.git] / svtools / source / control / ctrltool.cxx
blob3d908b342ab81122e2aa816a6c0e0a3110eae6a0
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 <sal/config.h>
22 #include <memory>
23 #include <string.h>
24 #include <string_view>
26 #include <tools/debug.hxx>
27 #include <tools/fract.hxx>
28 #include <i18nlangtag/languagetag.hxx>
29 #include <i18nlangtag/mslangid.hxx>
30 #include <vcl/outdev.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/settings.hxx>
33 #include <sal/macros.h>
34 #include <svtools/strings.hrc>
35 #include <svtools/svtresid.hxx>
36 #include <svtools/ctrltool.hxx>
37 #include <o3tl/typed_flags_set.hxx>
38 #include <comphelper/lok.hxx>
40 // Standard fontsizes for scalable Fonts
41 const int FontList::aStdSizeAry[] =
43 60,
44 70,
45 80,
46 90,
47 100,
48 105,
49 110,
50 120,
51 130,
52 140,
53 150,
54 160,
55 180,
56 200,
57 220,
58 240,
59 260,
60 280,
61 320,
62 360,
63 400,
64 440,
65 480,
66 540,
67 600,
68 660,
69 720,
70 800,
71 880,
72 960,
76 namespace {
78 class ImplFontListFontMetric : public FontMetric
80 friend FontList;
82 private:
83 ImplFontListFontMetric* mpNext;
85 public:
86 ImplFontListFontMetric( const FontMetric& rInfo ) :
87 FontMetric( rInfo ), mpNext(nullptr)
93 enum class FontListFontNameType
95 NONE = 0x00,
96 PRINTER = 0x01,
97 SCREEN = 0x02,
101 namespace o3tl
103 template<> struct typed_flags<FontListFontNameType> : is_typed_flags<FontListFontNameType, 0x3> {};
106 class ImplFontListNameInfo
108 friend class FontList;
110 private:
111 OUString maSearchName;
112 ImplFontListFontMetric* mpFirst;
113 FontListFontNameType mnType;
115 explicit ImplFontListNameInfo(const OUString& rSearchName)
116 : maSearchName(rSearchName)
117 , mpFirst(nullptr)
118 , mnType(FontListFontNameType::NONE)
123 //sort normal to the start
124 static int sortWeightValue(FontWeight eWeight)
126 if (eWeight < WEIGHT_NORMAL)
127 return eWeight + 1;
128 if (eWeight > WEIGHT_NORMAL)
129 return eWeight - 1;
130 return 0; // eWeight == WEIGHT_NORMAL
133 static sal_Int32 ImplCompareFontMetric( ImplFontListFontMetric* pInfo1,
134 ImplFontListFontMetric* pInfo2 )
136 //Sort non italic before italics
137 if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
138 return -1;
139 else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
140 return 1;
142 //Sort normal weight to the start, followed by lightest to heaviest weights
143 int nWeight1 = sortWeightValue(pInfo1->GetWeight());
144 int nWeight2 = sortWeightValue(pInfo2->GetWeight());
146 if ( nWeight1 < nWeight2 )
147 return -1;
148 else if ( nWeight1 > nWeight2 )
149 return 1;
151 return pInfo1->GetStyleName().compareTo( pInfo2->GetStyleName() );
154 static OUString ImplMakeSearchString(const OUString& rStr)
156 return rStr.toAsciiLowerCase();
159 static OUString ImplMakeSearchStringFromName(const OUString& rStr)
161 // check for features before alternate font separator
162 if (sal_Int32 nColon = rStr.indexOf(':'); nColon != -1)
163 if (sal_Int32 nSemiColon = rStr.indexOf(';'); nSemiColon == -1 || nColon < nSemiColon)
164 return ImplMakeSearchString(rStr.getToken( 0, ':' ));
165 return ImplMakeSearchString(rStr.getToken( 0, ';' ));
168 ImplFontListNameInfo* FontList::ImplFind(const OUString& rSearchName, sal_uInt32* pIndex) const
170 // Append if there is no entry in the list or if the entry is larger
171 // then the last one. We only compare to the last entry as the list of VCL
172 // is returned sorted, which increases the probability that appending
173 // is more likely
174 if (m_Entries.empty())
176 if ( pIndex )
177 *pIndex = SAL_MAX_UINT32;
178 return nullptr;
180 else
182 const ImplFontListNameInfo* pCmpData = m_Entries.back().get();
183 sal_Int32 nComp = rSearchName.compareTo( pCmpData->maSearchName );
184 if (nComp > 0)
186 if ( pIndex )
187 *pIndex = SAL_MAX_UINT32;
188 return nullptr;
190 else if (nComp == 0)
191 return const_cast<ImplFontListNameInfo*>(pCmpData);
194 // search fonts in the list
195 const ImplFontListNameInfo* pCompareData;
196 const ImplFontListNameInfo* pFoundData = nullptr;
197 size_t nLow = 0;
198 size_t nHigh = m_Entries.size() - 1;
199 size_t nMid;
203 nMid = (nLow + nHigh) / 2;
204 pCompareData = m_Entries[nMid].get();
205 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
206 if (nComp < 0)
208 if ( !nMid )
209 break;
210 nHigh = nMid-1;
212 else
214 if (nComp > 0)
215 nLow = nMid + 1;
216 else
218 pFoundData = pCompareData;
219 break;
223 while ( nLow <= nHigh );
225 if ( pIndex )
227 sal_Int32 nComp = rSearchName.compareTo(pCompareData->maSearchName);
228 if (nComp > 0)
229 *pIndex = (nMid+1);
230 else
231 *pIndex = nMid;
234 return const_cast<ImplFontListNameInfo*>(pFoundData);
237 ImplFontListNameInfo* FontList::ImplFindByName(const OUString& rStr) const
239 OUString aSearchName = ImplMakeSearchStringFromName(rStr);
240 return ImplFind( aSearchName, nullptr );
243 void FontList::ImplInsertFonts(OutputDevice* pDevice, bool bInsertData)
245 rtl_TextEncoding eSystemEncoding = osl_getThreadTextEncoding();
247 FontListFontNameType nType;
248 if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
249 nType = FontListFontNameType::SCREEN;
250 else
251 nType = FontListFontNameType::PRINTER;
253 // inquire all fonts from the device
254 int n = pDevice->GetFontFaceCollectionCount();
255 if (n == 0 && comphelper::LibreOfficeKit::isActive())
257 pDevice->RefreshFontData(true);
258 n = pDevice->GetFontFaceCollectionCount();
261 for (int i = 0; i < n; ++i)
263 FontMetric aFontMetric = pDevice->GetFontMetricFromCollection( i );
264 OUString aSearchName(aFontMetric.GetFamilyName());
265 ImplFontListNameInfo* pData;
266 sal_uInt32 nIndex;
267 aSearchName = ImplMakeSearchString(aSearchName);
268 pData = ImplFind( aSearchName, &nIndex );
270 if ( !pData )
272 if ( bInsertData )
274 ImplFontListFontMetric* pNewInfo = new ImplFontListFontMetric( aFontMetric );
275 pData = new ImplFontListNameInfo( aSearchName );
276 pData->mpFirst = pNewInfo;
277 pNewInfo->mpNext = nullptr;
279 if (nIndex < static_cast<sal_uInt32>(m_Entries.size()))
280 m_Entries.insert(m_Entries.begin()+nIndex,
281 std::unique_ptr<ImplFontListNameInfo>(pData));
282 else
283 m_Entries.push_back(std::unique_ptr<ImplFontListNameInfo>(pData));
286 else
288 if ( bInsertData )
290 bool bInsert = true;
291 ImplFontListFontMetric* pPrev = nullptr;
292 ImplFontListFontMetric* pTemp = pData->mpFirst;
293 ImplFontListFontMetric* pNewInfo = new ImplFontListFontMetric( aFontMetric );
294 while ( pTemp )
296 sal_Int32 eComp = ImplCompareFontMetric( pNewInfo, pTemp );
297 if ( eComp <= 0 )
299 if ( eComp == 0 )
301 // Overwrite charset, because charset should match
302 // with the system charset
303 if ( (pTemp->GetCharSet() != eSystemEncoding) &&
304 (pNewInfo->GetCharSet() == eSystemEncoding) )
306 ImplFontListFontMetric* pTemp2 = pTemp->mpNext;
307 *static_cast<FontMetric*>(pTemp) = *static_cast<FontMetric*>(pNewInfo);
308 pTemp->mpNext = pTemp2;
310 delete pNewInfo;
311 bInsert = false;
314 break;
317 pPrev = pTemp;
318 pTemp = pTemp->mpNext;
321 if ( bInsert )
323 pNewInfo->mpNext = pTemp;
324 if ( pPrev )
325 pPrev->mpNext = pNewInfo;
326 else
327 pData->mpFirst = pNewInfo;
332 if ( pData )
333 pData->mnType |= nType;
337 FontList::FontList(OutputDevice* pDevice, OutputDevice* pDevice2)
339 // initialise variables
340 mpDev = pDevice;
341 mpDev2 = pDevice2;
343 // store style names
344 maLight = SvtResId(STR_SVT_STYLE_LIGHT);
345 maLightItalic = SvtResId(STR_SVT_STYLE_LIGHT_ITALIC);
346 maNormal = SvtResId(STR_SVT_STYLE_NORMAL);
347 maNormalItalic = SvtResId(STR_SVT_STYLE_NORMAL_ITALIC);
348 maBold = SvtResId(STR_SVT_STYLE_BOLD);
349 maBoldItalic = SvtResId(STR_SVT_STYLE_BOLD_ITALIC);
350 maBlack = SvtResId(STR_SVT_STYLE_BLACK);
351 maBlackItalic = SvtResId(STR_SVT_STYLE_BLACK_ITALIC);
353 ImplInsertFonts(pDevice, true);
355 // if required compare to the screen fonts
356 // in order to map the duplicates to Equal
357 bool bCompareWindow = false;
358 if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
360 bCompareWindow = true;
361 pDevice2 = Application::GetDefaultDevice();
364 if ( pDevice2 &&
365 (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
366 ImplInsertFonts(pDevice2, !bCompareWindow);
369 FontList::~FontList()
371 // delete FontMetrics
372 ImplFontListFontMetric *pTemp, *pInfo;
373 for (auto const& it : m_Entries)
375 pInfo = it->mpFirst;
376 while ( pInfo )
378 pTemp = pInfo->mpNext;
379 delete pInfo;
380 pInfo = pTemp;
385 std::unique_ptr<FontList> FontList::Clone() const
387 return std::unique_ptr<FontList>(new FontList(mpDev, mpDev2));
390 const OUString& FontList::GetStyleName(FontWeight eWeight, FontItalic eItalic) const
392 if ( eWeight > WEIGHT_BOLD )
394 if ( eItalic > ITALIC_NONE )
395 return maBlackItalic;
396 else
397 return maBlack;
399 else if ( eWeight > WEIGHT_MEDIUM )
401 if ( eItalic > ITALIC_NONE )
402 return maBoldItalic;
403 else
404 return maBold;
406 else if ( eWeight > WEIGHT_LIGHT )
408 if ( eItalic > ITALIC_NONE )
409 return maNormalItalic;
410 else
411 return maNormal;
413 else if ( eWeight != WEIGHT_DONTKNOW )
415 if ( eItalic > ITALIC_NONE )
416 return maLightItalic;
417 else
418 return maLight;
420 else
422 if ( eItalic > ITALIC_NONE )
423 return maNormalItalic;
424 else
425 return maNormal;
429 OUString FontList::GetStyleName(const FontMetric& rInfo) const
431 OUString aStyleName = rInfo.GetStyleName();
432 FontWeight eWeight = rInfo.GetWeight();
433 FontItalic eItalic = rInfo.GetItalic();
435 // return synthetic Name if no StyleName was set
436 if (aStyleName.isEmpty())
437 aStyleName = GetStyleName(eWeight, eItalic);
438 else
440 // Translate StyleName to localized name
441 OUString aCompareStyleName = aStyleName.toAsciiLowerCase().replaceAll(" ", "");
442 if (aCompareStyleName == "bold")
443 aStyleName = maBold;
444 else if (aCompareStyleName == "bolditalic")
445 aStyleName = maBoldItalic;
446 else if (aCompareStyleName == "italic")
447 aStyleName = maNormalItalic;
448 else if (aCompareStyleName == "standard")
449 aStyleName = maNormal;
450 else if (aCompareStyleName == "regular")
451 aStyleName = maNormal;
452 else if (aCompareStyleName == "medium")
453 aStyleName = maNormal;
454 else if (aCompareStyleName == "light")
455 aStyleName = maLight;
456 else if (aCompareStyleName == "lightitalic")
457 aStyleName = maLightItalic;
458 else if (aCompareStyleName == "black")
459 aStyleName = maBlack;
460 else if (aCompareStyleName == "blackitalic")
461 aStyleName = maBlackItalic;
462 /* tdf#107700 support some less common style names with localization */
463 else if (aCompareStyleName == "book")
464 aStyleName = SvtResId(STR_SVT_STYLE_BOOK);
465 else if (aCompareStyleName == "boldoblique")
466 aStyleName = SvtResId(STR_SVT_STYLE_BOLD_OBLIQUE);
467 else if (aCompareStyleName == "condensed")
468 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED);
469 else if (aCompareStyleName == "condensedbold")
470 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED_BOLD);
471 else if (aCompareStyleName == "condensedbolditalic")
472 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED_BOLD_ITALIC);
473 else if (aCompareStyleName == "condensedboldoblique")
474 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED_BOLD_OBLIQUE);
475 else if (aCompareStyleName == "condenseditalic")
476 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED_ITALIC);
477 else if (aCompareStyleName == "condensedoblique")
478 aStyleName = SvtResId(STR_SVT_STYLE_CONDENSED_OBLIQUE);
479 else if (aCompareStyleName == "extralight")
480 aStyleName = SvtResId(STR_SVT_STYLE_EXTRALIGHT);
481 else if (aCompareStyleName == "extralightitalic")
482 aStyleName = SvtResId(STR_SVT_STYLE_EXTRALIGHT_ITALIC);
483 /* Medium is synonym with Normal */
484 else if (aCompareStyleName == "mediumitalic")
485 aStyleName = maNormalItalic;
486 else if (aCompareStyleName == "oblique")
487 aStyleName = SvtResId(STR_SVT_STYLE_OBLIQUE);
488 else if (aCompareStyleName == "semibold")
489 aStyleName = SvtResId(STR_SVT_STYLE_SEMIBOLD);
490 else if (aCompareStyleName == "semibolditalic")
491 aStyleName = SvtResId(STR_SVT_STYLE_SEMIBOLD_ITALIC);
493 // fix up StyleName, because the PS Printer driver from
494 // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
495 // for Helvetica)
496 if ( eItalic > ITALIC_NONE )
498 if ( (aStyleName == maNormal) ||
499 (aStyleName == maBold) ||
500 (aStyleName == maLight) ||
501 (aStyleName == maBlack) )
502 aStyleName = GetStyleName( eWeight, eItalic );
506 return aStyleName;
509 OUString FontList::GetFontMapText( const FontMetric& rInfo ) const
511 if ( rInfo.GetFamilyName().isEmpty() )
513 return OUString();
516 // Search Fontname
517 ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetFamilyName() );
518 if ( !pData )
520 if (maMapNotAvailable.isEmpty())
521 maMapNotAvailable = SvtResId(STR_SVT_FONTMAP_NOTAVAILABLE);
522 return maMapNotAvailable;
525 // search for synthetic style
526 FontListFontNameType nType = pData->mnType;
527 const OUString& rStyleName = rInfo.GetStyleName();
528 if (!rStyleName.isEmpty())
530 bool bNotSynthetic = false;
531 FontWeight eWeight = rInfo.GetWeight();
532 FontItalic eItalic = rInfo.GetItalic();
533 ImplFontListFontMetric* pFontMetric = pData->mpFirst;
534 while ( pFontMetric )
536 if ( (eWeight == pFontMetric->GetWeight()) &&
537 (eItalic == pFontMetric->GetItalic()) )
539 bNotSynthetic = true;
540 break;
543 pFontMetric = pFontMetric->mpNext;
546 if ( !bNotSynthetic )
548 if (maMapStyleNotAvailable.isEmpty())
549 const_cast<FontList*>(this)->maMapStyleNotAvailable = SvtResId(STR_SVT_FONTMAP_STYLENOTAVAILABLE);
550 return maMapStyleNotAvailable;
554 // Only Printer-Font?
555 if ( nType == FontListFontNameType::PRINTER )
557 if (maMapPrinterOnly.isEmpty())
558 const_cast<FontList*>(this)->maMapPrinterOnly = SvtResId(STR_SVT_FONTMAP_PRINTERONLY);
559 return maMapPrinterOnly;
561 else
563 if (maMapBoth.isEmpty())
564 const_cast<FontList*>(this)->maMapBoth = SvtResId(STR_SVT_FONTMAP_BOTH);
565 return maMapBoth;
569 namespace
571 FontMetric makeMissing(ImplFontListFontMetric const * pFontNameInfo, std::u16string_view rName,
572 FontWeight eWeight, FontItalic eItalic)
574 FontMetric aInfo;
575 // if the fontname matches, we copy as much as possible
576 if (pFontNameInfo)
578 aInfo = *pFontNameInfo;
579 aInfo.SetStyleName(OUString());
582 aInfo.SetWeight(eWeight);
583 aInfo.SetItalic(eItalic);
585 //If this is a known but uninstalled symbol font which we can remap to
586 //OpenSymbol then toggle its charset to be a symbol font
587 if (ConvertChar::GetRecodeData(rName, u"OpenSymbol"))
588 aInfo.SetCharSet(RTL_TEXTENCODING_SYMBOL);
590 return aInfo;
594 FontMetric FontList::Get(const OUString& rName, const OUString& rStyleName) const
596 ImplFontListNameInfo* pData = ImplFindByName( rName );
597 ImplFontListFontMetric* pFontMetric = nullptr;
598 ImplFontListFontMetric* pFontNameInfo = nullptr;
599 if ( pData )
601 ImplFontListFontMetric* pSearchInfo = pData->mpFirst;
602 pFontNameInfo = pSearchInfo;
603 pSearchInfo = pData->mpFirst;
604 while ( pSearchInfo )
606 if (rStyleName.equalsIgnoreAsciiCase(GetStyleName(*pSearchInfo)))
608 pFontMetric = pSearchInfo;
609 break;
612 pSearchInfo = pSearchInfo->mpNext;
616 // reproduce attributes if data could not be found
617 FontMetric aInfo;
618 if ( !pFontMetric )
620 FontWeight eWeight = WEIGHT_DONTKNOW;
621 FontItalic eItalic = ITALIC_NONE;
623 if ( rStyleName == maNormal )
625 eItalic = ITALIC_NONE;
626 eWeight = WEIGHT_NORMAL;
628 else if ( rStyleName == maNormalItalic )
630 eItalic = ITALIC_NORMAL;
631 eWeight = WEIGHT_NORMAL;
633 else if ( rStyleName == maBold )
635 eItalic = ITALIC_NONE;
636 eWeight = WEIGHT_BOLD;
638 else if ( rStyleName == maBoldItalic )
640 eItalic = ITALIC_NORMAL;
641 eWeight = WEIGHT_BOLD;
643 else if ( rStyleName == maLight )
645 eItalic = ITALIC_NONE;
646 eWeight = WEIGHT_LIGHT;
648 else if ( rStyleName == maLightItalic )
650 eItalic = ITALIC_NORMAL;
651 eWeight = WEIGHT_LIGHT;
653 else if ( rStyleName == maBlack )
655 eItalic = ITALIC_NONE;
656 eWeight = WEIGHT_BLACK;
658 else if ( rStyleName == maBlackItalic )
660 eItalic = ITALIC_NORMAL;
661 eWeight = WEIGHT_BLACK;
663 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
665 else
666 aInfo = *pFontMetric;
668 // set Fontname to keep FontAlias
669 aInfo.SetFamilyName( rName );
670 aInfo.SetStyleName( rStyleName );
672 return aInfo;
675 FontMetric FontList::Get(const OUString& rName,
676 FontWeight eWeight, FontItalic eItalic) const
678 ImplFontListNameInfo* pData = ImplFindByName( rName );
679 ImplFontListFontMetric* pFontMetric = nullptr;
680 ImplFontListFontMetric* pFontNameInfo = nullptr;
681 if ( pData )
683 ImplFontListFontMetric* pSearchInfo = pData->mpFirst;
684 pFontNameInfo = pSearchInfo;
685 while ( pSearchInfo )
687 if ( (eWeight == pSearchInfo->GetWeight()) &&
688 (eItalic == pSearchInfo->GetItalic()) )
690 pFontMetric = pSearchInfo;
691 break;
694 pSearchInfo = pSearchInfo->mpNext;
698 // reproduce attributes if data could not be found
699 FontMetric aInfo;
700 if ( !pFontMetric )
701 aInfo = makeMissing(pFontNameInfo, rName, eWeight, eItalic);
702 else
703 aInfo = *pFontMetric;
705 // set Fontname to keep FontAlias
706 aInfo.SetFamilyName( rName );
708 return aInfo;
711 bool FontList::IsAvailable(const OUString& rName) const
713 return (ImplFindByName( rName ) != nullptr);
716 const FontMetric& FontList::GetFontName(size_t const nFont) const
718 DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
720 return *(m_Entries[nFont]->mpFirst);
723 sal_Handle FontList::GetFirstFontMetric(const OUString& rName) const
725 ImplFontListNameInfo* pData = ImplFindByName( rName );
726 if ( !pData )
727 return nullptr;
728 else
729 return static_cast<sal_Handle>(pData->mpFirst);
732 sal_Handle FontList::GetNextFontMetric( sal_Handle hFontMetric )
734 ImplFontListFontMetric* pInfo = static_cast<ImplFontListFontMetric*>(hFontMetric);
735 return static_cast<sal_Handle>(pInfo->mpNext);
738 const FontMetric& FontList::GetFontMetric( sal_Handle hFontMetric )
740 ImplFontListFontMetric* pInfo = static_cast<ImplFontListFontMetric*>(hFontMetric);
741 return *pInfo;
744 struct ImplFSNameItem
746 sal_Int32 mnSize;
747 const char* mszUtf8Name;
750 const ImplFSNameItem aImplSimplifiedChinese[] =
752 { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
753 { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
754 { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
755 { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
756 { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
757 { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
758 { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
759 { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
760 { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
761 { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
762 { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
763 { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
764 { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
765 { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
766 { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
767 { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
770 FontSizeNames::FontSizeNames( LanguageType eLanguage )
772 if ( eLanguage == LANGUAGE_DONTKNOW )
773 eLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
774 if ( eLanguage == LANGUAGE_SYSTEM )
775 eLanguage = MsLangId::getConfiguredSystemUILanguage();
777 if (MsLangId::isSimplifiedChinese(eLanguage))
779 // equivalent for traditional chinese disabled by popular request, #i89077#
780 mpArray = aImplSimplifiedChinese;
781 mnElem = SAL_N_ELEMENTS(aImplSimplifiedChinese);
783 else
785 mpArray = nullptr;
786 mnElem = 0;
790 sal_Int32 FontSizeNames::Name2Size( std::u16string_view rName ) const
792 if ( mnElem )
794 OString aName(OUStringToOString(rName,
795 RTL_TEXTENCODING_UTF8));
797 // linear search is sufficient for this rare case
798 for( tools::Long i = mnElem; --i >= 0; )
799 if ( aName == mpArray[i].mszUtf8Name )
800 return mpArray[i].mnSize;
803 return 0;
806 OUString FontSizeNames::Size2Name( sal_Int32 nValue ) const
808 OUString aStr;
810 // binary search
811 for( tools::Long lower = 0, upper = mnElem - 1; lower <= upper; )
813 tools::Long mid = (upper + lower) >> 1;
814 if ( nValue == mpArray[mid].mnSize )
816 aStr = OUString( mpArray[mid].mszUtf8Name, strlen(mpArray[mid].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
817 break;
819 else if ( nValue < mpArray[mid].mnSize )
820 upper = mid - 1;
821 else /* ( nValue > mpArray[mid].mnSize ) */
822 lower = mid + 1;
825 return aStr;
828 OUString FontSizeNames::GetIndexName( sal_Int32 nIndex ) const
830 OUString aStr;
832 if ( nIndex < mnElem )
833 aStr = OUString( mpArray[nIndex].mszUtf8Name, strlen(mpArray[nIndex].mszUtf8Name), RTL_TEXTENCODING_UTF8 );
835 return aStr;
838 sal_Int32 FontSizeNames::GetIndexSize( sal_Int32 nIndex ) const
840 if ( nIndex >= mnElem )
841 return 0;
842 return mpArray[nIndex].mnSize;
845 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */