Fix uses of qRound on non-floating-point types.
[profile/ivi/qtbase.git] / src / gui / text / qplatformfontdatabase_qpa.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformfontdatabase_qpa.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,bool scalable, int pixelSize,
52                                          const QSupportedWritingSystems &writingSystems, void *hanlde);
53
54 /*!
55     \fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
56
57     Registers the pre-rendered QPF2 font contained in the given \a dataArray.
58
59     \sa registerFont()
60 */
61 void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
62 {
63     if (dataArray.size() == 0)
64         return;
65
66     const uchar *data = reinterpret_cast<const uchar *>(dataArray.constData());
67     if (QFontEngineQPA::verifyHeader(data, dataArray.size())) {
68         QString fontName = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_FontName).toString();
69         int pixelSize = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_PixelSize).toInt();
70         QVariant weight = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Weight);
71         QVariant style = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Style);
72         QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray();
73
74         if (!fontName.isEmpty() && pixelSize) {
75             QFont::Weight fontWeight = QFont::Normal;
76             if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt)
77                 fontWeight = QFont::Weight(weight.toInt());
78
79             QFont::Style fontStyle = static_cast<QFont::Style>(style.toInt());
80
81             QSupportedWritingSystems writingSystems;
82             for (int i = 0; i < writingSystemBits.count(); ++i) {
83                 uchar currentByte = writingSystemBits.at(i);
84                 for (int j = 0; j < 8; ++j) {
85                     if (currentByte & 1)
86                         writingSystems.setSupported(QFontDatabase::WritingSystem(i * 8 + j));
87                     currentByte >>= 1;
88                 }
89             }
90             QFont::Stretch stretch = QFont::Unstretched;
91             registerFont(fontName,QString(),fontWeight,fontStyle,stretch,true,false,pixelSize,writingSystems,handle);
92         }
93     } else {
94         qDebug() << "header verification of QPF2 font failed. maybe it is corrupt?";
95     }
96 }
97
98 /*!
99     \fn void QPlatformFontDatabase::registerFont(const QString &familyName,
100         const QString &foundryName, QFont::Weight weight, QFont::Style style,
101         QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize,
102         const QSupportedWritingSystems &writingSystems, void *usrPtr)
103
104     Registers a font with the given set of attributes describing the font's
105     foundry, family name, style and stretch information, pixel size, and
106     supported writing systems. Additional information about whether the font
107     can be scaled and antialiased can also be provided.
108
109     The foundry name and font family are described by \a foundryName and
110     \a familyName. The font weight (light, normal, bold, etc.), style (normal,
111     oblique, italic) and stretch information (condensed, expanded, unstretched,
112     etc.) are specified by \a weight, \a style and \a stretch.
113
114     Some fonts can be antialiased and scaled; \a scalable and \a antialiased
115     can be set to true for fonts with these attributes. The intended pixel
116     size of non-scalable fonts is specified by \a pixelSize; this value will be
117     ignored for scalable fonts.
118
119     The writing systems supported by the font are specified by the
120     \a writingSystems argument.
121
122     \sa registerQPF2Font()
123 */
124 void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight,
125                                          QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize,
126                                          const QSupportedWritingSystems &writingSystems, void *usrPtr)
127 {
128     if (scalable)
129         pixelSize = 0;
130     qt_registerFont(familyname,foundryname,weight,style,stretch,antialiased,scalable,pixelSize,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 != 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
230     Its to provide an easy to use interface for indicating what writing systems a specific font
231     supports.
232
233 */
234
235 /*!
236   This function is called once at startup by Qt's internal font database.
237   Reimplement this function in a subclass for a convenient place to initialize
238   the internal font database.
239
240   The default implementation looks in the fontDir() location and registers all
241   QPF2 fonts.
242 */
243 void QPlatformFontDatabase::populateFontDatabase()
244 {
245     QString fontpath = fontDir();
246
247     if(!QFile::exists(fontpath)) {
248         qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
249                qPrintable(fontpath));
250     }
251
252     QDir dir(fontpath);
253     dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
254     dir.refresh();
255     for (int i = 0; i < int(dir.count()); ++i) {
256         const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));
257         QFile file(QString::fromLocal8Bit(fileName));
258         if (file.open(QFile::ReadOnly)) {
259             const QByteArray fileData = file.readAll();
260             QByteArray *fileDataPtr = new QByteArray(fileData);
261             registerQPF2Font(fileData, fileDataPtr);
262         }
263     }
264 }
265
266 /*!
267     Returns the font engine that can be used to render the font described by
268     the font definition, \a fontDef, in the specified \a script.
269 */
270 QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
271 {
272     Q_UNUSED(script);
273     Q_UNUSED(handle);
274     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
275     QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
276     //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
277     return engine;
278 }
279
280 QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
281                                                QFont::HintingPreference hintingPreference)
282 {
283     Q_UNUSED(fontData);
284     Q_UNUSED(pixelSize);
285     Q_UNUSED(hintingPreference);
286     qWarning("This plugin does not support font engines created directly from font data");
287     return 0;
288 }
289
290 /*!
291     Returns a list of alternative fonts for the specified \a family and
292     \a style and \a script using the \a styleHint given.
293 */
294 QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
295 {
296     Q_UNUSED(family);
297     Q_UNUSED(style);
298     Q_UNUSED(styleHint);
299     Q_UNUSED(script);
300     return QStringList();
301 }
302
303 /*!
304     Adds an application font described by the font contained supplied \a fontData
305     or using the font contained in the file referenced by \a fileName. Returns
306     a list of family names, or an empty list if the font could not be added.
307
308     \note The default implementation of this function does not add an application
309     font. Subclasses should reimplement this function to perform the necessary
310     loading and registration of fonts.
311 */
312 QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
313 {
314     Q_UNUSED(fontData);
315     Q_UNUSED(fileName);
316
317     qWarning("This plugin does not support application fonts");
318     return QStringList();
319 }
320
321 /*!
322     Releases the specified font \a handle.
323 */
324 void QPlatformFontDatabase::releaseHandle(void *handle)
325 {
326     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
327     delete fileDataPtr;
328 }
329
330 /*!
331     Returns the directory containing the fonts used by the database.
332 */
333 QString QPlatformFontDatabase::fontDir() const
334 {
335     QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR"));
336     if (fontpath.isEmpty()) {
337 #ifndef QT_NO_SETTINGS
338         fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath);
339         fontpath += QLatin1String("/fonts");
340 #endif
341     }
342
343     return fontpath;
344 }
345
346 /*!
347     \class QPlatformFontDatabase
348     \brief The QPlatformFontDatabase class makes it possible to customize how fonts
349     are discovered and how they are rendered
350
351     \ingroup painting
352
353     QPlatformFontDatabase is the superclass which is intended to let platform implementations use
354     native font handling.
355
356     Qt has its internal font database which it uses to discover available fonts on the
357     user's system. To be able to populate this database subclass this class, and
358     reimplement populateFontDatabase().
359
360     Use the function registerFont() to populate the internal font database.
361
362     Sometimes a specified font does not have the required glyphs; in such a case, the
363     fallbackForFamily() function is called automatically to find alternative font
364     families that can supply alternatives to the missing glyphs.
365
366     \sa QSupportedWritingSystems
367 */
368 QT_END_NAMESPACE