1 /*
2     SPDX-FileCopyrightText: 2008 Chusslove Illich <caslav.ilic@gmx.net>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 #ifndef FONTHELPERS_P_H
7 #define FONTHELPERS_P_H
8 
9 // i18n-related helpers for fonts, common to KFont* widgets.
10 
11 #include <QCoreApplication>
12 #include <QString>
13 #include <QStringList>
14 
15 #include <map>
16 
17 #ifdef NEVERDEFINE // never true
18 // Font names up for translation, listed for extraction.
19 
20 //: Generic sans serif font presented in font choosers. When selected,
21 //: the system will choose a real font, mandated by distro settings.
22 QT_TRANSLATE_NOOP3("FontHelpers", "Sans Serif", "@item Font name");
23 //: Generic serif font presented in font choosers. When selected,
24 //: the system will choose a real font, mandated by distro settings.
25 QT_TRANSLATE_NOOP3("FontHelpers", "Serif", "@item Font name");
26 //: Generic monospace font presented in font choosers. When selected,
27 //: the system will choose a real font, mandated by distro settings.
28 QT_TRANSLATE_NOOP3("FontHelpers", "Monospace", "@item Font name");
29 
30 #endif
31 
32 /**
33  * @internal
34  *
35  * Split the compound raw font name into family and foundry.
36  *
37  * @param name the raw font name reported by Qt
38  * @param family the storage for family name
39  * @param foundry the storage for foundry name
40  */
41 inline void splitFontString(QStringView name, QString *family, QString *foundry = nullptr)
42 {
43     int p1 = name.indexOf(QLatin1Char('['));
44     if (p1 < 0) {
45         if (family) {
46             *family = name.trimmed().toString();
47         }
48         if (foundry) {
49             foundry->clear();
50         }
51     } else {
52         int p2 = name.indexOf(QLatin1Char(']'), p1);
53         p2 = p2 > p1 ? p2 : name.length();
54         if (family) {
55             *family = name.left(p1).trimmed().toString();
56         }
57         if (foundry) {
58             *foundry = name.mid(p1 + 1, p2 - p1 - 1).trimmed().toString();
59         }
60     }
61 }
62 
63 /**
64  * @internal
65  *
66  * Translate the font name for the user.
67  * Primarily for generic fonts like Serif, Sans-Serif, etc.
68  *
69  * @param name the raw font name reported by Qt
70  * @return translated font name
71  */
translateFontName(QStringView name)72 inline QString translateFontName(QStringView name)
73 {
74     QString family;
75     QString foundry;
76     splitFontString(name, &family, &foundry);
77 
78     // Obtain any regular translations for the family and foundry.
79     QString trFamily = QCoreApplication::translate("FontHelpers", family.toUtf8().constData(), "@item Font name");
80     QString trFoundry = foundry;
81     if (!foundry.isEmpty()) {
82         trFoundry = QCoreApplication::translate("FontHelpers", foundry.toUtf8().constData(), "@item Font foundry");
83     }
84 
85     // Assemble full translation.
86     QString trfont;
87     if (foundry.isEmpty()) {
88         // i18n: Filter by which the translators can translate, or otherwise
89         // operate on the font names not put up for regular translation.
90         trfont = QCoreApplication::translate("FontHelpers", "%1", "@item Font name").arg(trFamily);
91     } else {
92         // i18n: Filter by which the translators can translate, or otherwise
93         // operate on the font names not put up for regular translation.
94         trfont = QCoreApplication::translate("FontHelpers", "%1 [%2]", "@item Font name [foundry]").arg(trFamily, trFoundry);
95     }
96     return trfont;
97 }
98 
fontFamilyCompare(const QString & a,const QString & b)99 static bool fontFamilyCompare(const QString &a, const QString &b)
100 {
101     return QString::localeAwareCompare(a, b) < 0;
102 }
103 
104 using FontFamiliesMap = std::map<QString, QString, decltype(fontFamilyCompare) *>;
105 
106 /**
107  * @internal
108  *
109  * Compose locale-aware sorted list of translated font names,
110  * with generic fonts handled in a special way.
111  * The mapping of translated to raw names can be reported too if required.
112  *
113  * @param names raw font names as reported by Qt
114  * @param trToRawNames storage for mapping of translated to raw names
115  * @return sorted list of translated font names
116  */
translateFontNameList(const QStringList & names)117 inline FontFamiliesMap translateFontNameList(const QStringList &names)
118 {
119     FontFamiliesMap trMap(fontFamilyCompare);
120 
121     for (const QString &fName : names) {
122         trMap.insert({translateFontName(fName), fName});
123     }
124 
125     return trMap;
126 }
127 
128 #endif
129