1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include <tools/debug.hxx>
24 #include <tools/fract.hxx>
25 #include <i18nlangtag/languagetag.hxx>
26 #include <i18nlangtag/mslangid.hxx>
27 #include <vcl/outdev.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/settings.hxx>
30 #include <sal/macros.h>
31 #include <svtools/strings.hrc>
32 #include <svtools/svtresid.hxx>
33 #include <svtools/ctrltool.hxx>
34 #include <o3tl/typed_flags_set.hxx>
35 #include <comphelper/lok.hxx>
37 // Standard fontsizes for scalable Fonts
38 const int FontList::aStdSizeAry
[] =
75 class ImplFontListFontMetric
: public FontMetric
80 VclPtr
<OutputDevice
> mpDevice
;
81 ImplFontListFontMetric
* mpNext
;
84 ImplFontListFontMetric( const FontMetric
& rInfo
,
85 OutputDevice
* pDev
) :
86 FontMetric( rInfo
), mpDevice(pDev
), mpNext(nullptr)
90 OutputDevice
* GetDevice() const { return mpDevice
; }
93 enum class FontListFontNameType
104 template<> struct typed_flags
<FontListFontNameType
> : is_typed_flags
<FontListFontNameType
, 0x3> {};
107 class ImplFontListNameInfo
109 friend class FontList
;
112 OUString maSearchName
;
113 ImplFontListFontMetric
* mpFirst
;
114 FontListFontNameType mnType
;
116 explicit ImplFontListNameInfo(const OUString
& rSearchName
)
117 : maSearchName(rSearchName
)
119 , mnType(FontListFontNameType::NONE
)
124 //sort normal to the start
125 static int sortWeightValue(FontWeight eWeight
)
127 if (eWeight
< WEIGHT_NORMAL
)
129 if (eWeight
> WEIGHT_NORMAL
)
131 return 0; // eWeight == WEIGHT_NORMAL
134 static sal_Int32
ImplCompareFontMetric( ImplFontListFontMetric
* pInfo1
,
135 ImplFontListFontMetric
* pInfo2
)
137 //Sort non italic before italics
138 if ( pInfo1
->GetItalic() < pInfo2
->GetItalic() )
140 else if ( pInfo1
->GetItalic() > pInfo2
->GetItalic() )
143 //Sort normal weight to the start, followed by lightest to heaviest weights
144 int nWeight1
= sortWeightValue(pInfo1
->GetWeight());
145 int nWeight2
= sortWeightValue(pInfo2
->GetWeight());
147 if ( nWeight1
< nWeight2
)
149 else if ( nWeight1
> nWeight2
)
152 return pInfo1
->GetStyleName().compareTo( pInfo2
->GetStyleName() );
155 static OUString
ImplMakeSearchString(const OUString
& rStr
)
157 return rStr
.toAsciiLowerCase();
160 static OUString
ImplMakeSearchStringFromName(const OUString
& rStr
)
162 // check for features before alternate font separator
163 sal_Int32 nColon
= rStr
.indexOf(':');
164 sal_Int32 nSemiColon
= rStr
.indexOf(';');
165 if (nColon
!= -1 && (nSemiColon
== -1 || nColon
< nSemiColon
))
166 return ImplMakeSearchString(rStr
.getToken( 0, ':' ));
167 return ImplMakeSearchString(rStr
.getToken( 0, ';' ));
170 ImplFontListNameInfo
* FontList::ImplFind(const OUString
& rSearchName
, sal_uInt32
* pIndex
) const
172 // Append if there is no entry in the list or if the entry is larger
173 // then the last one. We only compare to the last entry as the list of VCL
174 // is returned sorted, which increases the probability that appending
176 if (m_Entries
.empty())
179 *pIndex
= SAL_MAX_UINT32
;
184 const ImplFontListNameInfo
* pCmpData
= m_Entries
.back().get();
185 sal_Int32 nComp
= rSearchName
.compareTo( pCmpData
->maSearchName
);
189 *pIndex
= SAL_MAX_UINT32
;
193 return const_cast<ImplFontListNameInfo
*>(pCmpData
);
196 // search fonts in the list
197 const ImplFontListNameInfo
* pCompareData
;
198 const ImplFontListNameInfo
* pFoundData
= nullptr;
200 size_t nHigh
= m_Entries
.size() - 1;
205 nMid
= (nLow
+ nHigh
) / 2;
206 pCompareData
= m_Entries
[nMid
].get();
207 sal_Int32 nComp
= rSearchName
.compareTo(pCompareData
->maSearchName
);
220 pFoundData
= pCompareData
;
225 while ( nLow
<= nHigh
);
229 sal_Int32 nComp
= rSearchName
.compareTo(pCompareData
->maSearchName
);
236 return const_cast<ImplFontListNameInfo
*>(pFoundData
);
239 ImplFontListNameInfo
* FontList::ImplFindByName(const OUString
& rStr
) const
241 OUString aSearchName
= ImplMakeSearchStringFromName(rStr
);
242 return ImplFind( aSearchName
, nullptr );
245 void FontList::ImplInsertFonts(OutputDevice
* pDevice
, bool bInsertData
)
247 rtl_TextEncoding eSystemEncoding
= osl_getThreadTextEncoding();
249 FontListFontNameType nType
;
250 if ( pDevice
->GetOutDevType() != OUTDEV_PRINTER
)
251 nType
= FontListFontNameType::SCREEN
;
253 nType
= FontListFontNameType::PRINTER
;
255 // inquire all fonts from the device
256 int n
= pDevice
->GetDevFontCount();
257 if (n
== 0 && comphelper::LibreOfficeKit::isActive())
259 pDevice
->RefreshFontData(true);
260 n
= pDevice
->GetDevFontCount();
263 for (int i
= 0; i
< n
; ++i
)
265 FontMetric aFontMetric
= pDevice
->GetDevFont( i
);
266 OUString
aSearchName(aFontMetric
.GetFamilyName());
267 ImplFontListNameInfo
* pData
;
269 aSearchName
= ImplMakeSearchString(aSearchName
);
270 pData
= ImplFind( aSearchName
, &nIndex
);
276 ImplFontListFontMetric
* pNewInfo
= new ImplFontListFontMetric( aFontMetric
, pDevice
);
277 pData
= new ImplFontListNameInfo( aSearchName
);
278 pData
->mpFirst
= pNewInfo
;
279 pNewInfo
->mpNext
= nullptr;
281 if (nIndex
< static_cast<sal_uInt32
>(m_Entries
.size()))
282 m_Entries
.insert(m_Entries
.begin()+nIndex
,
283 std::unique_ptr
<ImplFontListNameInfo
>(pData
));
285 m_Entries
.push_back(std::unique_ptr
<ImplFontListNameInfo
>(pData
));
293 ImplFontListFontMetric
* pPrev
= nullptr;
294 ImplFontListFontMetric
* pTemp
= pData
->mpFirst
;
295 ImplFontListFontMetric
* pNewInfo
= new ImplFontListFontMetric( aFontMetric
, pDevice
);
298 sal_Int32 eComp
= ImplCompareFontMetric( pNewInfo
, pTemp
);
303 // Overwrite charset, because charset should match
304 // with the system charset
305 if ( (pTemp
->GetCharSet() != eSystemEncoding
) &&
306 (pNewInfo
->GetCharSet() == eSystemEncoding
) )
308 ImplFontListFontMetric
* pTemp2
= pTemp
->mpNext
;
309 *static_cast<FontMetric
*>(pTemp
) = *static_cast<FontMetric
*>(pNewInfo
);
310 pTemp
->mpNext
= pTemp2
;
320 pTemp
= pTemp
->mpNext
;
325 pNewInfo
->mpNext
= pTemp
;
327 pPrev
->mpNext
= pNewInfo
;
329 pData
->mpFirst
= pNewInfo
;
335 pData
->mnType
|= nType
;
339 FontList::FontList(OutputDevice
* pDevice
, OutputDevice
* pDevice2
)
341 // initialise variables
346 maLight
= SvtResId(STR_SVT_STYLE_LIGHT
);
347 maLightItalic
= SvtResId(STR_SVT_STYLE_LIGHT_ITALIC
);
348 maNormal
= SvtResId(STR_SVT_STYLE_NORMAL
);
349 maNormalItalic
= SvtResId(STR_SVT_STYLE_NORMAL_ITALIC
);
350 maBold
= SvtResId(STR_SVT_STYLE_BOLD
);
351 maBoldItalic
= SvtResId(STR_SVT_STYLE_BOLD_ITALIC
);
352 maBlack
= SvtResId(STR_SVT_STYLE_BLACK
);
353 maBlackItalic
= SvtResId(STR_SVT_STYLE_BLACK_ITALIC
);
355 ImplInsertFonts(pDevice
, true);
357 // if required compare to the screen fonts
358 // in order to map the duplicates to Equal
359 bool bCompareWindow
= false;
360 if ( !pDevice2
&& (pDevice
->GetOutDevType() == OUTDEV_PRINTER
) )
362 bCompareWindow
= true;
363 pDevice2
= Application::GetDefaultDevice();
367 (pDevice2
->GetOutDevType() != pDevice
->GetOutDevType()) )
368 ImplInsertFonts(pDevice2
, !bCompareWindow
);
371 FontList::~FontList()
373 // delete FontMetrics
374 ImplFontListFontMetric
*pTemp
, *pInfo
;
375 for (auto const& it
: m_Entries
)
380 pTemp
= pInfo
->mpNext
;
387 std::unique_ptr
<FontList
> FontList::Clone() const
389 return std::unique_ptr
<FontList
>(new FontList(mpDev
, mpDev2
));
392 const OUString
& FontList::GetStyleName(FontWeight eWeight
, FontItalic eItalic
) const
394 if ( eWeight
> WEIGHT_BOLD
)
396 if ( eItalic
> ITALIC_NONE
)
397 return maBlackItalic
;
401 else if ( eWeight
> WEIGHT_MEDIUM
)
403 if ( eItalic
> ITALIC_NONE
)
408 else if ( eWeight
> WEIGHT_LIGHT
)
410 if ( eItalic
> ITALIC_NONE
)
411 return maNormalItalic
;
415 else if ( eWeight
!= WEIGHT_DONTKNOW
)
417 if ( eItalic
> ITALIC_NONE
)
418 return maLightItalic
;
424 if ( eItalic
> ITALIC_NONE
)
425 return maNormalItalic
;
431 OUString
FontList::GetStyleName(const FontMetric
& rInfo
) const
433 OUString aStyleName
= rInfo
.GetStyleName();
434 FontWeight eWeight
= rInfo
.GetWeight();
435 FontItalic eItalic
= rInfo
.GetItalic();
437 // return synthetic Name if no StyleName was set
438 if (aStyleName
.isEmpty())
439 aStyleName
= GetStyleName(eWeight
, eItalic
);
442 // Translate StyleName to localized name
443 OUString aCompareStyleName
= aStyleName
.toAsciiLowerCase().replaceAll(" ", "");
444 if (aCompareStyleName
== "bold")
446 else if (aCompareStyleName
== "bolditalic")
447 aStyleName
= maBoldItalic
;
448 else if (aCompareStyleName
== "italic")
449 aStyleName
= maNormalItalic
;
450 else if (aCompareStyleName
== "standard")
451 aStyleName
= maNormal
;
452 else if (aCompareStyleName
== "regular")
453 aStyleName
= maNormal
;
454 else if (aCompareStyleName
== "medium")
455 aStyleName
= maNormal
;
456 else if (aCompareStyleName
== "light")
457 aStyleName
= maLight
;
458 else if (aCompareStyleName
== "lightitalic")
459 aStyleName
= maLightItalic
;
460 else if (aCompareStyleName
== "black")
461 aStyleName
= maBlack
;
462 else if (aCompareStyleName
== "blackitalic")
463 aStyleName
= maBlackItalic
;
464 /* tdf#107700 support some less common style names with localization */
465 else if (aCompareStyleName
== "book")
466 aStyleName
= SvtResId(STR_SVT_STYLE_BOOK
);
467 else if (aCompareStyleName
== "boldoblique")
468 aStyleName
= SvtResId(STR_SVT_STYLE_BOLD_OBLIQUE
);
469 else if (aCompareStyleName
== "condensed")
470 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED
);
471 else if (aCompareStyleName
== "condensedbold")
472 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED_BOLD
);
473 else if (aCompareStyleName
== "condensedbolditalic")
474 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED_BOLD_ITALIC
);
475 else if (aCompareStyleName
== "condensedboldoblique")
476 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED_BOLD_OBLIQUE
);
477 else if (aCompareStyleName
== "condenseditalic")
478 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED_ITALIC
);
479 else if (aCompareStyleName
== "condensedoblique")
480 aStyleName
= SvtResId(STR_SVT_STYLE_CONDENSED_OBLIQUE
);
481 else if (aCompareStyleName
== "extralight")
482 aStyleName
= SvtResId(STR_SVT_STYLE_EXTRALIGHT
);
483 else if (aCompareStyleName
== "extralightitalic")
484 aStyleName
= SvtResId(STR_SVT_STYLE_EXTRALIGHT_ITALIC
);
485 /* Medium is synonym with Normal */
486 else if (aCompareStyleName
== "mediumitalic")
487 aStyleName
= maNormalItalic
;
488 else if (aCompareStyleName
== "oblique")
489 aStyleName
= SvtResId(STR_SVT_STYLE_OBLIQUE
);
490 else if (aCompareStyleName
== "semibold")
491 aStyleName
= SvtResId(STR_SVT_STYLE_SEMIBOLD
);
492 else if (aCompareStyleName
== "semibolditalic")
493 aStyleName
= SvtResId(STR_SVT_STYLE_SEMIBOLD_ITALIC
);
495 // fix up StyleName, because the PS Printer driver from
496 // W2000 returns wrong StyleNames (e.g. Bold instead of Bold Italic
498 if ( eItalic
> ITALIC_NONE
)
500 if ( (aStyleName
== maNormal
) ||
501 (aStyleName
== maBold
) ||
502 (aStyleName
== maLight
) ||
503 (aStyleName
== maBlack
) )
504 aStyleName
= GetStyleName( eWeight
, eItalic
);
511 OUString
FontList::GetFontMapText( const FontMetric
& rInfo
) const
513 if ( rInfo
.GetFamilyName().isEmpty() )
519 ImplFontListNameInfo
* pData
= ImplFindByName( rInfo
.GetFamilyName() );
522 if (maMapNotAvailable
.isEmpty())
523 maMapNotAvailable
= SvtResId(STR_SVT_FONTMAP_NOTAVAILABLE
);
524 return maMapNotAvailable
;
527 // search for synthetic style
528 FontListFontNameType nType
= pData
->mnType
;
529 const OUString
& rStyleName
= rInfo
.GetStyleName();
530 if (!rStyleName
.isEmpty())
532 bool bNotSynthetic
= false;
533 FontWeight eWeight
= rInfo
.GetWeight();
534 FontItalic eItalic
= rInfo
.GetItalic();
535 ImplFontListFontMetric
* pFontMetric
= pData
->mpFirst
;
536 while ( pFontMetric
)
538 if ( (eWeight
== pFontMetric
->GetWeight()) &&
539 (eItalic
== pFontMetric
->GetItalic()) )
541 bNotSynthetic
= true;
545 pFontMetric
= pFontMetric
->mpNext
;
548 if ( !bNotSynthetic
)
550 if (maMapStyleNotAvailable
.isEmpty())
551 const_cast<FontList
*>(this)->maMapStyleNotAvailable
= SvtResId(STR_SVT_FONTMAP_STYLENOTAVAILABLE
);
552 return maMapStyleNotAvailable
;
556 // Only Printer-Font?
557 if ( nType
== FontListFontNameType::PRINTER
)
559 if (maMapPrinterOnly
.isEmpty())
560 const_cast<FontList
*>(this)->maMapPrinterOnly
= SvtResId(STR_SVT_FONTMAP_PRINTERONLY
);
561 return maMapPrinterOnly
;
565 if (maMapBoth
.isEmpty())
566 const_cast<FontList
*>(this)->maMapBoth
= SvtResId(STR_SVT_FONTMAP_BOTH
);
573 FontMetric
makeMissing(ImplFontListFontMetric
const * pFontNameInfo
, const OUString
&rName
,
574 FontWeight eWeight
, FontItalic eItalic
)
577 // if the fontname matches, we copy as much as possible
580 aInfo
= *pFontNameInfo
;
581 aInfo
.SetStyleName(OUString());
584 aInfo
.SetWeight(eWeight
);
585 aInfo
.SetItalic(eItalic
);
587 //If this is a known but uninstalled symbol font which we can remap to
588 //OpenSymbol then toggle its charset to be a symbol font
589 if (ConvertChar::GetRecodeData(rName
, "OpenSymbol"))
590 aInfo
.SetCharSet(RTL_TEXTENCODING_SYMBOL
);
596 FontMetric
FontList::Get(const OUString
& rName
, const OUString
& rStyleName
) const
598 ImplFontListNameInfo
* pData
= ImplFindByName( rName
);
599 ImplFontListFontMetric
* pFontMetric
= nullptr;
600 ImplFontListFontMetric
* pFontNameInfo
= nullptr;
603 ImplFontListFontMetric
* pSearchInfo
= pData
->mpFirst
;
604 pFontNameInfo
= pSearchInfo
;
605 pSearchInfo
= pData
->mpFirst
;
606 while ( pSearchInfo
)
608 if (rStyleName
.equalsIgnoreAsciiCase(GetStyleName(*pSearchInfo
)))
610 pFontMetric
= pSearchInfo
;
614 pSearchInfo
= pSearchInfo
->mpNext
;
618 // reproduce attributes if data could not be found
622 FontWeight eWeight
= WEIGHT_DONTKNOW
;
623 FontItalic eItalic
= ITALIC_NONE
;
625 if ( rStyleName
== maNormal
)
627 eItalic
= ITALIC_NONE
;
628 eWeight
= WEIGHT_NORMAL
;
630 else if ( rStyleName
== maNormalItalic
)
632 eItalic
= ITALIC_NORMAL
;
633 eWeight
= WEIGHT_NORMAL
;
635 else if ( rStyleName
== maBold
)
637 eItalic
= ITALIC_NONE
;
638 eWeight
= WEIGHT_BOLD
;
640 else if ( rStyleName
== maBoldItalic
)
642 eItalic
= ITALIC_NORMAL
;
643 eWeight
= WEIGHT_BOLD
;
645 else if ( rStyleName
== maLight
)
647 eItalic
= ITALIC_NONE
;
648 eWeight
= WEIGHT_LIGHT
;
650 else if ( rStyleName
== maLightItalic
)
652 eItalic
= ITALIC_NORMAL
;
653 eWeight
= WEIGHT_LIGHT
;
655 else if ( rStyleName
== maBlack
)
657 eItalic
= ITALIC_NONE
;
658 eWeight
= WEIGHT_BLACK
;
660 else if ( rStyleName
== maBlackItalic
)
662 eItalic
= ITALIC_NORMAL
;
663 eWeight
= WEIGHT_BLACK
;
665 aInfo
= makeMissing(pFontNameInfo
, rName
, eWeight
, eItalic
);
668 aInfo
= *pFontMetric
;
670 // set Fontname to keep FontAlias
671 aInfo
.SetFamilyName( rName
);
672 aInfo
.SetStyleName( rStyleName
);
677 FontMetric
FontList::Get(const OUString
& rName
,
678 FontWeight eWeight
, FontItalic eItalic
) const
680 ImplFontListNameInfo
* pData
= ImplFindByName( rName
);
681 ImplFontListFontMetric
* pFontMetric
= nullptr;
682 ImplFontListFontMetric
* pFontNameInfo
= nullptr;
685 ImplFontListFontMetric
* pSearchInfo
= pData
->mpFirst
;
686 pFontNameInfo
= pSearchInfo
;
687 while ( pSearchInfo
)
689 if ( (eWeight
== pSearchInfo
->GetWeight()) &&
690 (eItalic
== pSearchInfo
->GetItalic()) )
692 pFontMetric
= pSearchInfo
;
696 pSearchInfo
= pSearchInfo
->mpNext
;
700 // reproduce attributes if data could not be found
703 aInfo
= makeMissing(pFontNameInfo
, rName
, eWeight
, eItalic
);
705 aInfo
= *pFontMetric
;
707 // set Fontname to keep FontAlias
708 aInfo
.SetFamilyName( rName
);
713 bool FontList::IsAvailable(const OUString
& rName
) const
715 return (ImplFindByName( rName
) != nullptr);
718 const FontMetric
& FontList::GetFontName(size_t const nFont
) const
720 DBG_ASSERT( nFont
< GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
722 return *(m_Entries
[nFont
]->mpFirst
);
725 sal_Handle
FontList::GetFirstFontMetric(const OUString
& rName
) const
727 ImplFontListNameInfo
* pData
= ImplFindByName( rName
);
731 return static_cast<sal_Handle
>(pData
->mpFirst
);
734 sal_Handle
FontList::GetNextFontMetric( sal_Handle hFontMetric
)
736 ImplFontListFontMetric
* pInfo
= static_cast<ImplFontListFontMetric
*>(hFontMetric
);
737 return static_cast<sal_Handle
>(pInfo
->mpNext
);
740 const FontMetric
& FontList::GetFontMetric( sal_Handle hFontMetric
)
742 ImplFontListFontMetric
* pInfo
= static_cast<ImplFontListFontMetric
*>(hFontMetric
);
746 const int* FontList::GetSizeAry( const FontMetric
& rInfo
) const
748 // first delete Size-Array
751 // use standard sizes if no name
752 if ( rInfo
.GetFamilyName().isEmpty() )
755 // first search fontname in order to use device from the matching font
756 OutputDevice
* pDevice
= mpDev
;
757 ImplFontListNameInfo
* pData
= ImplFindByName( rInfo
.GetFamilyName() );
759 pDevice
= pData
->mpFirst
->GetDevice();
761 int nDevSizeCount
= pDevice
->GetDevFontSizeCount( rInfo
);
762 if ( !nDevSizeCount
||
763 (pDevice
->GetDevFontSize( rInfo
, 0 ).Height() == 0) )
766 MapMode aOldMapMode
= pDevice
->GetMapMode();
767 MapMode
aMap( MapUnit::Map10thInch
, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
768 pDevice
->SetMapMode( aMap
);
771 tools::Long nOldHeight
= 0;
772 mpSizeAry
.reset(new int[nDevSizeCount
+1] );
773 for (int i
= 0; i
< nDevSizeCount
; ++i
)
775 Size aSize
= pDevice
->GetDevFontSize( rInfo
, i
);
776 if ( aSize
.Height() != nOldHeight
)
778 nOldHeight
= aSize
.Height();
779 mpSizeAry
[nRealCount
] = nOldHeight
;
783 mpSizeAry
[nRealCount
] = 0;
785 pDevice
->SetMapMode( aOldMapMode
);
786 return mpSizeAry
.get();
789 struct ImplFSNameItem
792 const char* mszUtf8Name
;
795 const ImplFSNameItem aImplSimplifiedChinese
[] =
797 { 50, "\xe5\x85\xab\xe5\x8f\xb7" },
798 { 55, "\xe4\xb8\x83\xe5\x8f\xb7" },
799 { 65, "\xe5\xb0\x8f\xe5\x85\xad" },
800 { 75, "\xe5\x85\xad\xe5\x8f\xb7" },
801 { 90, "\xe5\xb0\x8f\xe4\xba\x94" },
802 { 105, "\xe4\xba\x94\xe5\x8f\xb7" },
803 { 120, "\xe5\xb0\x8f\xe5\x9b\x9b" },
804 { 140, "\xe5\x9b\x9b\xe5\x8f\xb7" },
805 { 150, "\xe5\xb0\x8f\xe4\xb8\x89" },
806 { 160, "\xe4\xb8\x89\xe5\x8f\xb7" },
807 { 180, "\xe5\xb0\x8f\xe4\xba\x8c" },
808 { 220, "\xe4\xba\x8c\xe5\x8f\xb7" },
809 { 240, "\xe5\xb0\x8f\xe4\xb8\x80" },
810 { 260, "\xe4\xb8\x80\xe5\x8f\xb7" },
811 { 360, "\xe5\xb0\x8f\xe5\x88\x9d" },
812 { 420, "\xe5\x88\x9d\xe5\x8f\xb7" }
815 FontSizeNames::FontSizeNames( LanguageType eLanguage
)
817 if ( eLanguage
== LANGUAGE_DONTKNOW
)
818 eLanguage
= Application::GetSettings().GetUILanguageTag().getLanguageType();
819 if ( eLanguage
== LANGUAGE_SYSTEM
)
820 eLanguage
= MsLangId::getSystemUILanguage();
822 if (MsLangId::isSimplifiedChinese(eLanguage
))
824 // equivalent for traditional chinese disabled by popular request, #i89077#
825 mpArray
= aImplSimplifiedChinese
;
826 mnElem
= SAL_N_ELEMENTS(aImplSimplifiedChinese
);
835 sal_Int32
FontSizeNames::Name2Size( const OUString
& rName
) const
839 OString
aName(OUStringToOString(rName
,
840 RTL_TEXTENCODING_UTF8
));
842 // linear search is sufficient for this rare case
843 for( tools::Long i
= mnElem
; --i
>= 0; )
844 if ( aName
== mpArray
[i
].mszUtf8Name
)
845 return mpArray
[i
].mnSize
;
851 OUString
FontSizeNames::Size2Name( sal_Int32 nValue
) const
856 for( tools::Long lower
= 0, upper
= mnElem
- 1; lower
<= upper
; )
858 tools::Long mid
= (upper
+ lower
) >> 1;
859 if ( nValue
== mpArray
[mid
].mnSize
)
861 aStr
= OUString( mpArray
[mid
].mszUtf8Name
, strlen(mpArray
[mid
].mszUtf8Name
), RTL_TEXTENCODING_UTF8
);
864 else if ( nValue
< mpArray
[mid
].mnSize
)
866 else /* ( nValue > mpArray[mid].mnSize ) */
873 OUString
FontSizeNames::GetIndexName( sal_Int32 nIndex
) const
877 if ( nIndex
< mnElem
)
878 aStr
= OUString( mpArray
[nIndex
].mszUtf8Name
, strlen(mpArray
[nIndex
].mszUtf8Name
), RTL_TEXTENCODING_UTF8
);
883 sal_Int32
FontSizeNames::GetIndexSize( sal_Int32 nIndex
) const
885 if ( nIndex
>= mnElem
)
887 return mpArray
[nIndex
].mnSize
;
890 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */