1 #include "asemanfonthandler.h"
2 #include "asemanlistrecord.h"
3 
4 #include <QFont>
5 #include <QHash>
6 #include <QDebug>
7 
8 #ifdef QT_WIDGETS_LIB
9 #include <QDialog>
10 #include <QFontDialog>
11 #include <QComboBox>
12 #include <QVBoxLayout>
13 #endif
14 
15 QMap<int,QString> aseman_font_handler_scipts;
16 
17 class AsemanFontHandlerPrivate
18 {
19 public:
20     QVariantMap fonts;
21 #ifdef QT_WIDGETS_LIB
22     QHash<QComboBox*, QFontDialog*> combo_hash;
23     QHash<QComboBox*, QVariantMap> combo_cache;
24 #endif
25 };
26 
AsemanFontHandler(QObject * parent)27 AsemanFontHandler::AsemanFontHandler(QObject *parent) :
28     QObject(parent)
29 {
30     p = new AsemanFontHandlerPrivate;
31 
32     if(aseman_font_handler_scipts.isEmpty())
33     {
34         aseman_font_handler_scipts[QChar::Script_Unknown] = "unknown";
35         aseman_font_handler_scipts[QChar::Script_Inherited] = "inherited";
36         aseman_font_handler_scipts[QChar::Script_Common] = "common";
37         aseman_font_handler_scipts[QChar::Script_Latin] = "latin";
38         aseman_font_handler_scipts[QChar::Script_Greek] = "greek";
39         aseman_font_handler_scipts[QChar::Script_Cyrillic] = "cyrillic";
40         aseman_font_handler_scipts[QChar::Script_Armenian] = "armenian";
41         aseman_font_handler_scipts[QChar::Script_Hebrew] = "hebrew";
42         aseman_font_handler_scipts[QChar::Script_Arabic] = "arabic";
43         aseman_font_handler_scipts[QChar::Script_Syriac] = "syriac";
44         aseman_font_handler_scipts[QChar::Script_Thaana] = "thaana";
45         aseman_font_handler_scipts[QChar::Script_Devanagari] = "devanagari";
46         aseman_font_handler_scipts[QChar::Script_Bengali] = "bengali";
47         aseman_font_handler_scipts[QChar::Script_Gurmukhi] = "gurmukhi";
48         aseman_font_handler_scipts[QChar::Script_Gujarati] = "gujarati";
49         aseman_font_handler_scipts[QChar::Script_Oriya] = "oriya";
50         aseman_font_handler_scipts[QChar::Script_Tamil] = "tamil";
51         aseman_font_handler_scipts[QChar::Script_Telugu] = "telugu";
52         aseman_font_handler_scipts[QChar::Script_Kannada] = "kannada";
53         aseman_font_handler_scipts[QChar::Script_Malayalam] = "malayalam";
54         aseman_font_handler_scipts[QChar::Script_Sinhala] = "sinhala";
55         aseman_font_handler_scipts[QChar::Script_Thai] = "thai";
56         aseman_font_handler_scipts[QChar::Script_Lao] = "lao";
57         aseman_font_handler_scipts[QChar::Script_Tibetan] = "tibetan";
58         aseman_font_handler_scipts[QChar::Script_Myanmar] = "myanmar";
59         aseman_font_handler_scipts[QChar::Script_Georgian] = "georgian";
60         aseman_font_handler_scipts[QChar::Script_Hangul] = "hangul";
61         aseman_font_handler_scipts[QChar::Script_Ethiopic] = "ethiopic";
62         aseman_font_handler_scipts[QChar::Script_Cherokee] = "cherokee";
63         aseman_font_handler_scipts[QChar::Script_CanadianAboriginal] = "canadianAboriginal";
64         aseman_font_handler_scipts[QChar::Script_Ogham] = "ogham";
65         aseman_font_handler_scipts[QChar::Script_Runic] = "runic";
66         aseman_font_handler_scipts[QChar::Script_Khmer] = "khmer";
67         aseman_font_handler_scipts[QChar::Script_Mongolian] = "mongolian";
68         aseman_font_handler_scipts[QChar::Script_Hiragana] = "hiragana";
69         aseman_font_handler_scipts[QChar::Script_Katakana] = "katakana";
70         aseman_font_handler_scipts[QChar::Script_Bopomofo] = "bopomofo";
71         aseman_font_handler_scipts[QChar::Script_Han] = "han";
72         aseman_font_handler_scipts[QChar::Script_Yi] = "yi";
73         aseman_font_handler_scipts[QChar::Script_OldItalic] = "oldItalic";
74         aseman_font_handler_scipts[QChar::Script_Gothic] = "gothic";
75         aseman_font_handler_scipts[QChar::Script_Deseret] = "deseret";
76         aseman_font_handler_scipts[QChar::Script_Tagalog] = "tagalog";
77         aseman_font_handler_scipts[QChar::Script_Hanunoo] = "hanunoo";
78         aseman_font_handler_scipts[QChar::Script_Buhid] = "buhid";
79         aseman_font_handler_scipts[QChar::Script_Tagbanwa] = "tagbanwa";
80         aseman_font_handler_scipts[QChar::Script_Coptic] = "coptic";
81         aseman_font_handler_scipts[QChar::Script_Limbu] = "limbu";
82         aseman_font_handler_scipts[QChar::Script_TaiLe] = "taiLe";
83         aseman_font_handler_scipts[QChar::Script_LinearB] = "linearB";
84         aseman_font_handler_scipts[QChar::Script_Ugaritic] = "ugaritic";
85         aseman_font_handler_scipts[QChar::Script_Shavian] = "shavian";
86         aseman_font_handler_scipts[QChar::Script_Osmanya] = "osmanya";
87         aseman_font_handler_scipts[QChar::Script_Cypriot] = "cypriot";
88         aseman_font_handler_scipts[QChar::Script_Braille] = "braille";
89         aseman_font_handler_scipts[QChar::Script_Buginese] = "buginese";
90         aseman_font_handler_scipts[QChar::Script_NewTaiLue] = "newTaiLue";
91         aseman_font_handler_scipts[QChar::Script_Glagolitic] = "glagolitic";
92         aseman_font_handler_scipts[QChar::Script_Tifinagh] = "tifinagh";
93         aseman_font_handler_scipts[QChar::Script_SylotiNagri] = "sylotiNagri";
94         aseman_font_handler_scipts[QChar::Script_OldPersian] = "oldPersian";
95         aseman_font_handler_scipts[QChar::Script_Kharoshthi] = "kharoshthi";
96         aseman_font_handler_scipts[QChar::Script_Balinese] = "balinese";
97         aseman_font_handler_scipts[QChar::Script_Cuneiform] = "cuneiform";
98         aseman_font_handler_scipts[QChar::Script_Phoenician] = "phoenician";
99         aseman_font_handler_scipts[QChar::Script_PhagsPa] = "phagsPa";
100         aseman_font_handler_scipts[QChar::Script_Nko] = "nko";
101         aseman_font_handler_scipts[QChar::Script_Sundanese] = "sundanese";
102         aseman_font_handler_scipts[QChar::Script_Lepcha] = "lepcha";
103         aseman_font_handler_scipts[QChar::Script_OlChiki] = "olChiki";
104         aseman_font_handler_scipts[QChar::Script_Vai] = "vai";
105         aseman_font_handler_scipts[QChar::Script_Saurashtra] = "saurashtra";
106         aseman_font_handler_scipts[QChar::Script_KayahLi] = "kayahLi";
107         aseman_font_handler_scipts[QChar::Script_Rejang] = "rejang";
108         aseman_font_handler_scipts[QChar::Script_Lycian] = "lycian";
109         aseman_font_handler_scipts[QChar::Script_Carian] = "carian";
110         aseman_font_handler_scipts[QChar::Script_Lydian] = "lydian";
111         aseman_font_handler_scipts[QChar::Script_Cham] = "cham";
112         aseman_font_handler_scipts[QChar::Script_TaiTham] = "taiTham";
113         aseman_font_handler_scipts[QChar::Script_TaiViet] = "taiViet";
114         aseman_font_handler_scipts[QChar::Script_Avestan] = "avestan";
115         aseman_font_handler_scipts[QChar::Script_EgyptianHieroglyphs] = "egyptianHieroglyphs";
116         aseman_font_handler_scipts[QChar::Script_Samaritan] = "samaritan";
117         aseman_font_handler_scipts[QChar::Script_Lisu] = "lisu";
118         aseman_font_handler_scipts[QChar::Script_Bamum] = "bamum";
119         aseman_font_handler_scipts[QChar::Script_Javanese] = "javanese";
120         aseman_font_handler_scipts[QChar::Script_MeeteiMayek] = "meeteiMayek";
121         aseman_font_handler_scipts[QChar::Script_ImperialAramaic] = "imperialAramaic";
122         aseman_font_handler_scipts[QChar::Script_OldSouthArabian] = "oldSouthArabian";
123         aseman_font_handler_scipts[QChar::Script_InscriptionalParthian] = "inscriptionalParthian";
124         aseman_font_handler_scipts[QChar::Script_InscriptionalPahlavi] = "inscriptionalPahlavi";
125         aseman_font_handler_scipts[QChar::Script_OldTurkic] = "oldTurkic";
126         aseman_font_handler_scipts[QChar::Script_Kaithi] = "kaithi";
127         aseman_font_handler_scipts[QChar::Script_Batak] = "batak";
128         aseman_font_handler_scipts[QChar::Script_Brahmi] = "brahmi";
129         aseman_font_handler_scipts[QChar::Script_Mandaic] = "mandaic";
130         aseman_font_handler_scipts[QChar::Script_Chakma] = "chakma";
131         aseman_font_handler_scipts[QChar::Script_MeroiticCursive] = "meroiticCursive";
132         aseman_font_handler_scipts[QChar::Script_MeroiticHieroglyphs] = "meroiticHieroglyphs";
133         aseman_font_handler_scipts[QChar::Script_Miao] = "miao";
134         aseman_font_handler_scipts[QChar::Script_Sharada] = "sharada";
135         aseman_font_handler_scipts[QChar::Script_SoraSompeng] = "soraSompeng";
136         aseman_font_handler_scipts[QChar::Script_Takri] = "takri";
137     }
138 
139     init();
140 }
141 
fonts()142 QVariantMap AsemanFontHandler::fonts()
143 {
144     return p->fonts;
145 }
146 
setFonts(const QVariantMap & fonts)147 void AsemanFontHandler::setFonts(const QVariantMap &fonts)
148 {
149     if(p->fonts == fonts)
150         return;
151 
152     p->fonts = fonts;
153     emit fontsChanged();
154 }
155 
fontOf(int script)156 QFont AsemanFontHandler::fontOf(int script)
157 {
158     const QString &key = aseman_font_handler_scipts.value(static_cast<QChar::Script>(script));
159     return p->fonts.value(key).value<QFont>();
160 }
161 
textToHtml(const QString & text)162 QString AsemanFontHandler::textToHtml(const QString &text)
163 {
164     QString result;
165     QChar::Script lastScript = QChar::Script_Unknown;
166 
167     int level = 0;
168     for(int i=0; i<text.length(); i++)
169     {
170         const QChar &ch = text.at(i);
171         if(ch == '<')
172             level++;
173         if(level > 0)
174         {
175             if(ch == '>')
176                 level--;
177 
178             result += ch;
179             continue;
180         }
181 
182         QChar::Script script = (ch=='&'? QChar::Script_Latin : ch.script());
183         if(script <= QChar::Script_Common && lastScript != QChar::Script_Unknown)
184             script = lastScript;
185 
186         if(lastScript != script)
187         {
188             if(lastScript != QChar::Script_Unknown)
189                 result += "</span>";
190 
191             QString scriptKey = aseman_font_handler_scipts.value(script);
192             QFont font = p->fonts.value(scriptKey).value<QFont>();
193 
194             result += QString("<span style=\"font-family:'%1'; font-size:%2pt; font-style:%3;\">")
195                     .arg(font.family()).arg(font.pointSize()).arg(font.styleName());
196         }
197 
198         result += ch;
199         lastScript = script;
200     }
201 
202     return result;
203 }
204 
save()205 QByteArray AsemanFontHandler::save()
206 {
207     AsemanListRecord list;
208     QMapIterator<QString, QVariant> i(p->fonts);
209     while(i.hasNext())
210     {
211         i.next();
212         AsemanListRecord record;
213         record << i.key().toUtf8();
214         record << i.value().toString().toUtf8();
215 
216         list << record.toQByteArray();
217     }
218 
219     return list.toQByteArray();
220 }
221 
load(const QByteArray & data)222 void AsemanFontHandler::load(const QByteArray &data)
223 {
224     AsemanListRecord list(data);
225     for(int i=0; i<list.count(); i++)
226     {
227         AsemanListRecord record(list.at(i));
228         if(record.count() != 2)
229             continue;
230 
231         QFont font;
232         font.fromString(record.last());
233         p->fonts[record.first()] = font;
234     }
235 
236     emit fontsChanged();
237 }
238 
239 #ifdef QT_WIDGETS_LIB
openFontChooser()240 void AsemanFontHandler::openFontChooser()
241 {
242     QDialog dialog;
243     dialog.resize(QSize(500, 400));
244 
245     QComboBox *comboBox = new QComboBox();
246     comboBox->addItems(p->fonts.keys());
247 
248     QFontDialog *fontDlg = new QFontDialog();
249     fontDlg->setWindowFlags(Qt::Widget);
250     fontDlg->setWindowTitle(tr("Select font"));
251     fontDlg->setOption(QFontDialog::DontUseNativeDialog);
252 
253     p->combo_hash[comboBox] = fontDlg;
254     p->combo_cache[comboBox] = p->fonts;
255 
256     QVBoxLayout *layout = new QVBoxLayout(&dialog);
257     layout->addWidget(comboBox);
258     layout->addWidget(fontDlg);
259     layout->setContentsMargins(0,0,0,0);
260     layout->setSpacing(1);
261 
262     connect(comboBox, SIGNAL(currentIndexChanged(QString)), SLOT(currentIndexChanged(QString)));
263     connect(fontDlg , SIGNAL(currentFontChanged(QFont))   , SLOT(currentFontChanged(QFont))   );
264 
265     connect(fontDlg, SIGNAL(accepted()), &dialog, SLOT(accept()));
266     connect(fontDlg, SIGNAL(rejected()), &dialog, SLOT(reject()));
267 
268     comboBox->setCurrentText("latin");
269     comboBox->currentIndexChanged("latin");
270 
271     if(dialog.exec() == QDialog::Accepted)
272         p->fonts = p->combo_cache[comboBox];
273 
274     p->combo_hash.remove(comboBox);
275     p->combo_cache.remove(comboBox);
276 
277     emit fontsChanged();
278 }
279 
currentIndexChanged(const QString & key)280 void AsemanFontHandler::currentIndexChanged(const QString &key)
281 {
282     QComboBox *comboBox = static_cast<QComboBox*>(sender());
283     QFontDialog *fontDlg = p->combo_hash.value(comboBox);
284     QFont font = p->combo_cache[comboBox][key].value<QFont>();
285     fontDlg->setCurrentFont(font);
286 }
287 
currentFontChanged(const QFont & font)288 void AsemanFontHandler::currentFontChanged(const QFont &font)
289 {
290     QFontDialog *fontDlg = static_cast<QFontDialog*>(sender());
291     QComboBox *comboBox = p->combo_hash.key(fontDlg);
292     QString key = comboBox->currentText();
293     p->combo_cache[comboBox][key] = font;
294 }
295 #endif
296 
init()297 void AsemanFontHandler::init()
298 {
299     p->fonts.clear();
300     QFont defaultFont;
301     QMapIterator<int, QString> i(aseman_font_handler_scipts);
302     while(i.hasNext())
303     {
304         i.next();
305         p->fonts[i.value()] = defaultFont;
306     }
307 }
308 
~AsemanFontHandler()309 AsemanFontHandler::~AsemanFontHandler()
310 {
311     delete p;
312 }
313 
314