Get started with patching up the Qt GUI docs
[profile/ivi/qtbase.git] / src / gui / text / qplatformfontdatabase_qpa.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformfontdatabase.h"
43 #include <QtGui/private/qfontengine_p.h>
44 #include <QtGui/private/qfontengine_qpa_p.h>
45 #include <QtCore/QLibraryInfo>
46 #include <QtCore/QDir>
47
48 QT_BEGIN_NAMESPACE
49
50 extern void qt_registerFont(const QString &familyname, const QString &foundryname, int weight,
51                             QFont::Style style, int stretch, bool antialiased,
52                             bool scalable, int pixelSize, bool fixedPitch,
53                             const QSupportedWritingSystems &writingSystems, void *hanlde);
54
55 /*!
56     \fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
57
58     Registers the pre-rendered QPF2 font contained in the given \a dataArray.
59
60     \sa registerFont()
61 */
62 void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
63 {
64     if (dataArray.size() == 0)
65         return;
66
67     const uchar *data = reinterpret_cast<const uchar *>(dataArray.constData());
68     if (QFontEngineQPA::verifyHeader(data, dataArray.size())) {
69         QString fontName = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_FontName).toString();
70         int pixelSize = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_PixelSize).toInt();
71         QVariant weight = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Weight);
72         QVariant style = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Style);
73         QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray();
74
75         if (!fontName.isEmpty() && pixelSize) {
76             QFont::Weight fontWeight = QFont::Normal;
77             if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt)
78                 fontWeight = QFont::Weight(weight.toInt());
79
80             QFont::Style fontStyle = static_cast<QFont::Style>(style.toInt());
81
82             QSupportedWritingSystems writingSystems;
83             for (int i = 0; i < writingSystemBits.count(); ++i) {
84                 uchar currentByte = writingSystemBits.at(i);
85                 for (int j = 0; j < 8; ++j) {
86                     if (currentByte & 1)
87                         writingSystems.setSupported(QFontDatabase::WritingSystem(i * 8 + j));
88                     currentByte >>= 1;
89                 }
90             }
91             QFont::Stretch stretch = QFont::Unstretched;
92             registerFont(fontName,QString(),fontWeight,fontStyle,stretch,true,false,pixelSize,false,writingSystems,handle);
93         }
94     } else {
95         qDebug() << "header verification of QPF2 font failed. maybe it is corrupt?";
96     }
97 }
98
99 /*!
100     Registers a font with the given set of attributes describing the font's
101     foundry, family name, style and stretch information, pixel size, and
102     supported writing systems. Additional information about whether the font
103     can be scaled and antialiased can also be provided.
104
105     The foundry name and font family are described by \a foundryName and
106     \a familyName. The font weight (light, normal, bold, etc.), style (normal,
107     oblique, italic) and stretch information (condensed, expanded, unstretched,
108     etc.) are specified by \a weight, \a style and \a stretch.
109
110     Some fonts can be antialiased and scaled; \a scalable and \a antialiased
111     can be set to true for fonts with these attributes. The intended pixel
112     size of non-scalable fonts is specified by \a pixelSize; this value will be
113     ignored for scalable fonts.
114
115     The writing systems supported by the font are specified by the
116     \a writingSystems argument.
117
118     \sa registerQPF2Font()
119 */
120 void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight,
121                                          QFont::Style style, QFont::Stretch stretch, bool antialiased,
122                                          bool scalable, int pixelSize, bool fixedPitch,
123                                          const QSupportedWritingSystems &writingSystems, void *usrPtr)
124 {
125     if (scalable)
126         pixelSize = 0;
127
128     qt_registerFont(familyname, foundryname, weight, style,
129                     stretch, antialiased, scalable, pixelSize,
130                     fixedPitch, writingSystems, usrPtr);
131 }
132
133 class QWritingSystemsPrivate
134 {
135 public:
136     QWritingSystemsPrivate()
137         : ref(1)
138         , vector(QFontDatabase::WritingSystemsCount,false)
139     {
140     }
141
142     QWritingSystemsPrivate(const QWritingSystemsPrivate *other)
143         : ref(1)
144         , vector(other->vector)
145     {
146     }
147
148     QAtomicInt ref;
149     QVector<bool> vector;
150 };
151
152 /*!
153     Constructs a new object to handle supported writing systems.
154 */
155 QSupportedWritingSystems::QSupportedWritingSystems()
156 {
157     d = new QWritingSystemsPrivate;
158 }
159
160 /*!
161     Constructs a copy of the \a other writing systems object.
162 */
163 QSupportedWritingSystems::QSupportedWritingSystems(const QSupportedWritingSystems &other)
164 {
165     d = other.d;
166     d->ref.ref();
167 }
168
169 /*!
170     Constructs a copy of the \a other writing systems object.
171 */
172 QSupportedWritingSystems &QSupportedWritingSystems::operator=(const QSupportedWritingSystems &other)
173 {
174     if (d != other.d) {
175         other.d->ref.ref();
176         if (!d->ref.deref())
177             delete d;
178         d = other.d;
179     }
180     return *this;
181 }
182
183 /*!
184     Destroys the supported writing systems object.
185 */
186 QSupportedWritingSystems::~QSupportedWritingSystems()
187 {
188     if (!d->ref.deref())
189         delete d;
190 }
191
192 /*!
193     \internal
194 */
195 void QSupportedWritingSystems::detach()
196 {
197     if (d->ref.load() != 1) {
198         QWritingSystemsPrivate *newd = new QWritingSystemsPrivate(d);
199         if (!d->ref.deref())
200             delete d;
201         d = newd;
202     }
203 }
204
205 /*!
206     Sets or clears support for the specified \a writingSystem based on the
207     value given by \a support.
208 */
209 void QSupportedWritingSystems::setSupported(QFontDatabase::WritingSystem writingSystem, bool support)
210 {
211     detach();
212     d->vector[writingSystem] = support;
213 }
214
215 /*!
216     Returns true if the writing system specified by \a writingSystem is
217     supported; otherwise returns false.
218 */
219 bool QSupportedWritingSystems::supported(QFontDatabase::WritingSystem writingSystem) const
220 {
221     return d->vector.at(writingSystem);
222 }
223
224 /*!
225     \class QSupportedWritingSystems
226     \brief The QSupportedWritingSystems class is used when registering fonts with the internal Qt
227     fontdatabase
228     \ingroup painting
229     \inmodule QtGui
230
231     Its to provide an easy to use interface for indicating what writing systems a specific font
232     supports.
233
234 */
235
236 /*!
237     \internal
238  */
239 QPlatformFontDatabase::~QPlatformFontDatabase()
240 {
241 }
242
243 /*!
244   This function is called once at startup by Qt's internal font database.
245   Reimplement this function in a subclass for a convenient place to initialize
246   the internal font database.
247
248   The default implementation looks in the fontDir() location and registers all
249   QPF2 fonts.
250 */
251 void QPlatformFontDatabase::populateFontDatabase()
252 {
253     QString fontpath = fontDir();
254     if(!QFile::exists(fontpath)) {
255         qWarning("QFontDatabase: Cannot find font directory '%s' - is Qt installed correctly?",
256                  qPrintable(QDir::toNativeSeparators(fontpath)));
257         return;
258     }
259
260     QDir dir(fontpath);
261     dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
262     dir.refresh();
263     for (int i = 0; i < int(dir.count()); ++i) {
264         const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));
265         QFile file(QString::fromLocal8Bit(fileName));
266         if (file.open(QFile::ReadOnly)) {
267             const QByteArray fileData = file.readAll();
268             QByteArray *fileDataPtr = new QByteArray(fileData);
269             registerQPF2Font(fileData, fileDataPtr);
270         }
271     }
272 }
273
274 /*!
275     Returns a multi font engine in the specified \a script to encapsulate \a fontEngine with the
276     option to fall back to to the fonts given by \a fallbacks if \a fontEngine does not support
277     a certain character.
278 */
279 QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine,
280                                                          QUnicodeTables::Script script)
281 {
282     return new QFontEngineMultiQPA(fontEngine, script);
283 }
284
285 /*!
286     Returns the font engine that can be used to render the font described by
287     the font definition, \a fontDef, in the specified \a script.
288 */
289 QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
290 {
291     Q_UNUSED(script);
292     Q_UNUSED(handle);
293     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
294     QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
295     //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
296     return engine;
297 }
298
299 QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
300                                                QFont::HintingPreference hintingPreference)
301 {
302     Q_UNUSED(fontData);
303     Q_UNUSED(pixelSize);
304     Q_UNUSED(hintingPreference);
305     qWarning("This plugin does not support font engines created directly from font data");
306     return 0;
307 }
308
309 /*!
310     Returns a list of alternative fonts for the specified \a family and
311     \a style and \a script using the \a styleHint given.
312 */
313 QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
314 {
315     Q_UNUSED(family);
316     Q_UNUSED(style);
317     Q_UNUSED(styleHint);
318     Q_UNUSED(script);
319     return QStringList();
320 }
321
322 /*!
323     Adds an application font described by the font contained supplied \a fontData
324     or using the font contained in the file referenced by \a fileName. Returns
325     a list of family names, or an empty list if the font could not be added.
326
327     \note The default implementation of this function does not add an application
328     font. Subclasses should reimplement this function to perform the necessary
329     loading and registration of fonts.
330 */
331 QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
332 {
333     Q_UNUSED(fontData);
334     Q_UNUSED(fileName);
335
336     qWarning("This plugin does not support application fonts");
337     return QStringList();
338 }
339
340 /*!
341     Releases the specified font \a handle.
342 */
343 void QPlatformFontDatabase::releaseHandle(void *handle)
344 {
345     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
346     delete fileDataPtr;
347 }
348
349 /*!
350     Returns the directory containing the fonts used by the database.
351 */
352 QString QPlatformFontDatabase::fontDir() const
353 {
354     QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR"));
355     if (fontpath.isEmpty()) {
356 #ifndef QT_NO_SETTINGS
357         fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath);
358         fontpath += QLatin1String("/fonts");
359 #endif
360     }
361
362     return fontpath;
363 }
364
365 /*!
366     Returns the default system font.
367
368     \sa QGuiApplication::font()
369     \since 5.0
370 */
371
372 QFont QPlatformFontDatabase::defaultFont() const
373 {
374     return QFont(QLatin1String("Helvetica"));
375 }
376
377 /*!
378     Resolve alias to actual font family names.
379
380     \since 5.0
381  */
382
383 QString QPlatformFontDatabase::resolveFontFamilyAlias(const QString &family) const
384 {
385     return family;
386 }
387
388 /*!
389     Return true if all fonts are considered scalable when using this font database.
390     Defaults to false.
391
392     \since 5.0
393  */
394
395 bool QPlatformFontDatabase::fontsAlwaysScalable() const
396 {
397     return false;
398 }
399
400 /*!
401     Return list of standard font sizes when using this font database.
402
403     \since 5.0
404  */
405
406  QList<int> QPlatformFontDatabase::standardSizes() const
407 {
408     QList<int> ret;
409     static const unsigned short standard[] =
410         { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
411     ret.reserve(int(sizeof(standard) / sizeof(standard[0])));
412     const unsigned short *sizes = standard;
413     while (*sizes) ret << *sizes++;
414     return ret;
415 }
416
417 /*!
418     \class QPlatformFontDatabase
419     \since 5.0
420     \internal
421     \preliminary
422     \ingroup qpa
423     \ingroup painting
424
425     \brief The QPlatformFontDatabase class makes it possible to customize how fonts
426     are discovered and how they are rendered
427
428     QPlatformFontDatabase is the superclass which is intended to let platform implementations use
429     native font handling.
430
431     Qt has its internal font database which it uses to discover available fonts on the
432     user's system. To be able to populate this database subclass this class, and
433     reimplement populateFontDatabase().
434
435     Use the function registerFont() to populate the internal font database.
436
437     Sometimes a specified font does not have the required glyphs; in such a case, the
438     fallbackForFamily() function is called automatically to find alternative font
439     families that can supply alternatives to the missing glyphs.
440
441     \sa QSupportedWritingSystems
442 */
443 QT_END_NAMESPACE