Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the tools applications of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "mainwindow.h" |
43 | |
44 | #include <QFontComboBox> |
45 | #include <QFontDatabase> |
46 | #include <QFileDialog> |
47 | #include <QMessageBox> |
48 | #include <QListWidget> |
49 | #include <QDebug> |
50 | #include <QShortcut> |
51 | #include <QCompleter> |
52 | #include <QDirModel> |
53 | #include <QTextCodec> |
54 | |
55 | QT_BEGIN_NAMESPACE |
56 | |
57 | MainWindow::MainWindow(const QString &customFont) |
58 | { |
59 | setupUi(this); |
60 | pixelSize->setValue(QFontInfo(QFont()).pixelSize()); |
61 | populateCharacterRanges(); |
62 | |
63 | { |
64 | weightCombo->addItem(QLatin1String("Light"), QVariant(int(QFont::Light))); |
65 | const int normalIdx = weightCombo->count(); |
66 | weightCombo->addItem(QLatin1String("Normal"), QVariant(int(QFont::Normal))); |
67 | weightCombo->addItem(QLatin1String("DemiBold"), QVariant(int(QFont::DemiBold))); |
68 | weightCombo->addItem(QLatin1String("Bold"), QVariant(int(QFont::Bold))); |
69 | weightCombo->addItem(QLatin1String("Black"), QVariant(int(QFont::Black))); |
70 | |
71 | weightCombo->setCurrentIndex(normalIdx); |
72 | } |
73 | |
74 | QShortcut *sc = new QShortcut(Qt::ControlModifier + Qt::Key_A, this); |
75 | connect(sc, SIGNAL(activated()), |
76 | this, SLOT(on_selectAll_clicked())); |
77 | sc = new QShortcut(Qt::ControlModifier + Qt::Key_D, this); |
78 | connect(sc, SIGNAL(activated()), |
79 | this, SLOT(on_deselectAll_clicked())); |
80 | sc = new QShortcut(Qt::ControlModifier + Qt::Key_I, this); |
81 | connect(sc, SIGNAL(activated()), |
82 | this, SLOT(on_invertSelection_clicked())); |
83 | |
84 | QCompleter *completer = new QCompleter(this); |
85 | completer->setModel(new QDirModel(this)); |
86 | path->setCompleter(completer); |
87 | path->setText(QDir::currentPath()); |
88 | |
89 | completer = new QCompleter(this); |
90 | completer->setModel(new QDirModel(this)); |
91 | sampleFile->setCompleter(completer); |
92 | charCount->setText(QString()); |
93 | |
94 | if (!customFont.isEmpty()) |
95 | addCustomFont(customFont); |
96 | |
97 | fontChanged(); |
98 | |
99 | connect(fontComboBox, SIGNAL(currentFontChanged(QFont)), |
100 | this, SLOT(fontChanged())); |
101 | connect(pixelSize, SIGNAL(valueChanged(int)), |
102 | this, SLOT(fontChanged())); |
103 | connect(italic, SIGNAL(stateChanged(int)), |
104 | this, SLOT(fontChanged())); |
105 | connect(weightCombo, SIGNAL(currentIndexChanged(int)), |
106 | this, SLOT(fontChanged())); |
107 | } |
108 | |
109 | void MainWindow::on_actionAdd_Custom_Font_triggered() |
110 | { |
111 | QString fontFile = QFileDialog::getOpenFileName(this, tr("Add Custom Font")); |
112 | if (fontFile.isEmpty()) |
113 | return; |
114 | addCustomFont(fontFile); |
115 | } |
116 | |
117 | void MainWindow::on_selectAll_clicked() |
118 | { |
119 | for (int i = 0; i < characterRangeView->count(); ++i) |
120 | characterRangeView->item(i)->setCheckState(Qt::Checked); |
121 | } |
122 | |
123 | void MainWindow::on_deselectAll_clicked() |
124 | { |
125 | for (int i = 0; i < characterRangeView->count(); ++i) |
126 | characterRangeView->item(i)->setCheckState(Qt::Unchecked); |
127 | } |
128 | |
129 | void MainWindow::on_invertSelection_clicked() |
130 | { |
131 | for (int i = 0; i < characterRangeView->count(); ++i) { |
132 | QListWidgetItem *item = characterRangeView->item(i); |
133 | if (item->checkState() == Qt::Checked) |
134 | item->setCheckState(Qt::Unchecked); |
135 | else |
136 | item->setCheckState(Qt::Checked); |
137 | } |
138 | } |
139 | |
140 | void MainWindow::fontChanged() |
141 | { |
142 | QFont f = preview->font(); |
143 | f.setStyleStrategy(QFont::NoFontMerging); |
144 | f.setPixelSize(pixelSize->value()); |
145 | f.setFamily(fontComboBox->currentFont().family()); |
146 | f.setItalic(italic->isChecked()); |
147 | f.setWeight(weightCombo->itemData(weightCombo->currentIndex()).toInt()); |
148 | |
149 | if (!preview->isModified()) { |
150 | QFontDatabase db; |
151 | QFontDatabase::WritingSystem ws = db.writingSystems(f.family()).value(0, QFontDatabase::Any); |
152 | QString sample = db.writingSystemSample(ws); |
153 | preview->setText(sample); |
154 | preview->setModified(false); |
155 | } |
156 | |
157 | fileName->setText(QPF::fileNameForFont(f)); |
158 | |
159 | preview->setFont(f); |
160 | } |
161 | |
162 | void MainWindow::on_browsePath_clicked() |
163 | { |
164 | QString dir = QFileDialog::getExistingDirectory(this, tr("Select Directory")); |
165 | if (!dir.isEmpty()) |
166 | path->setText(dir); |
167 | } |
168 | |
169 | void MainWindow::on_browseSampleFile_clicked() |
170 | { |
171 | QString dir = QFileDialog::getOpenFileName(this, tr("Select Sample File")); |
172 | if (!dir.isEmpty()) { |
173 | sampleFile->setText(dir); |
174 | on_sampleFile_editingFinished(); |
175 | } |
176 | } |
177 | |
178 | void MainWindow::on_generate_clicked() |
179 | { |
180 | QFile f(path->text() + QDir::separator() + fileName->text()); |
181 | if (f.exists()) { |
182 | if (QMessageBox::warning(this, QString(), |
183 | tr("%1 already exists.\nDo you want to replace it?").arg(f.fileName()), |
184 | QMessageBox::Yes | QMessageBox::No, QMessageBox::No) |
185 | != QMessageBox::Yes) { |
186 | statusBar()->showMessage(tr("Pre-rendering aborted...")); |
187 | return; |
188 | } |
189 | } |
190 | |
191 | QList<QPF::CharacterRange> ranges; |
192 | |
193 | if (chooseFromSampleFile->isChecked()) { |
194 | ranges = sampleFileRanges; |
195 | } else if (chooseFromCodePoints->isChecked()) { |
196 | ranges.clear(); |
197 | for (int i = 0; i < characterRangeView->count(); ++i) { |
198 | QListWidgetItem *item = characterRangeView->item(i); |
199 | if (item->checkState() != Qt::Checked) |
200 | continue; |
201 | |
202 | QPF::CharacterRange range = qvariant_cast<QPF::CharacterRange>(item->data(Qt::UserRole)); |
203 | ranges.append(range); |
204 | } |
205 | } |
206 | |
207 | const int generationOptions = QPF::IncludeCMap | QPF::RenderGlyphs; |
208 | QByteArray qpf = QPF::generate(preview->font(), generationOptions, ranges); |
209 | f.open(QIODevice::WriteOnly | QIODevice::Truncate); |
210 | f.write(qpf); |
211 | f.close(); |
212 | |
213 | statusBar()->showMessage(tr("Font successfully pre-rendered to %1").arg(fileName->text())); |
214 | } |
215 | |
216 | void MainWindow::on_sampleFile_editingFinished() |
217 | { |
218 | sampleFileRanges.clear(); |
219 | QFile f(sampleFile->text()); |
220 | if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { |
221 | sampleFileRanges.append(QPF::CharacterRange()); // default = all |
222 | return; |
223 | } |
224 | QTextStream stream(&f); |
225 | stream.setCodec(QTextCodec::codecForName("utf-8")); |
226 | stream.setAutoDetectUnicode(true); |
227 | QString text = stream.readAll(); |
228 | |
229 | QSet<QChar> coverage; |
230 | for (int i = 0; i < text.length(); ++i) |
231 | coverage.insert(text.at(i)); |
232 | |
233 | QList<QChar> sortedCoverage = QList<QChar>::fromSet(coverage); |
234 | qSort(sortedCoverage); |
235 | // play simple :) |
236 | foreach (QChar ch, sortedCoverage) { |
237 | QPF::CharacterRange r; |
238 | r.start = ch.unicode(); |
239 | r.end = r.start; |
240 | sampleFileRanges.append(r); |
241 | } |
242 | |
243 | charCount->setText(tr("(%1 unique characters found)").arg(sortedCoverage.count())); |
244 | } |
245 | |
246 | void MainWindow::populateCharacterRanges() |
247 | { |
248 | QFile f(":/Blocks.txt"); |
249 | if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) |
250 | return; |
251 | |
252 | QRegExp rangeExpr("([0-9a-f]+)\\.\\.([0-9a-f]+); (.+)"); |
253 | rangeExpr.setCaseSensitivity(Qt::CaseInsensitive); |
254 | |
255 | QString ellipsis(QChar(0x2026)); |
256 | if (!characterRangeView->fontMetrics().inFont(ellipsis.at(0))) |
257 | ellipsis = QLatin1String("..."); |
258 | |
259 | while (!f.atEnd()) { |
260 | QString line = QString::fromAscii(f.readLine()); |
261 | |
262 | if (line.endsWith(QLatin1Char( |
263 | line.chop(1); |
264 | if (line.endsWith(QLatin1Char( |
265 | line.chop(1); |
266 | |
267 | line = line.trimmed(); |
268 | |
269 | if (line.isEmpty() || line.startsWith(QLatin1Char( |
270 | continue; |
271 | |
272 | if (!rangeExpr.exactMatch(line) || rangeExpr.captureCount() != 3) |
273 | continue; |
274 | |
275 | QPF::CharacterRange range; |
276 | |
277 | bool ok = false; |
278 | range.start = rangeExpr.cap(1).toUInt(&ok, /*base*/16); |
279 | if (!ok) |
280 | continue; |
281 | range.end = rangeExpr.cap(2).toUInt(&ok, /*base*/16); |
282 | if (!ok) |
283 | continue; |
284 | |
285 | if (range.start >= 0xffff || range.end >= 0xffff) |
286 | continue; |
287 | |
288 | QString description = rangeExpr.cap(3); |
289 | |
290 | QListWidgetItem *item = new QListWidgetItem(characterRangeView); |
291 | QString text = description; |
292 | text.append(QLatin1String(" (")); |
293 | text.append(rangeExpr.cap(1)); |
294 | text.append(ellipsis); |
295 | text.append(rangeExpr.cap(2)); |
296 | text.append(QLatin1String(")")); |
297 | item->setText(text); |
298 | item->setCheckState(Qt::Checked); |
299 | |
300 | item->setData(Qt::UserRole, QVariant::fromValue(range)); |
301 | } |
302 | } |
303 | |
304 | void MainWindow::addCustomFont(const QString &fontFile) |
305 | { |
306 | int id = QFontDatabase::addApplicationFont(fontFile); |
307 | if (id < 0) { |
308 | QMessageBox::warning(this, tr("Error Adding Custom Font"), |
309 | tr("The custom font %s could not be loaded.").arg(fontFile)); |
310 | return; |
311 | } |
312 | const QStringList families = QFontDatabase::applicationFontFamilies(id); |
313 | if (families.isEmpty()) { |
314 | QMessageBox::warning(this, tr("Error Adding Custom Font"), |
315 | tr("The custom font %s provides no font families.").arg(fontFile)); |
316 | return; |
317 | } |
318 | QFont f(families.first()); |
319 | fontComboBox->setCurrentFont(f); |
320 | } |
321 | |
322 | QT_END_NAMESPACE |
323 |
Warning: That file was not part of the compilation database. It may have many parsing errors.