Fix uses of qRound on non-floating-point types.
[profile/ivi/qtbase.git] / src / gui / text / qfont_x11.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 #define QT_FATAL_ASSERT
43
44 #include "qplatformdefs.h"
45
46 #include "qfont.h"
47 #include "qapplication.h"
48 #include "qfontinfo.h"
49 #include "qfontdatabase.h"
50 #include "qfontmetrics.h"
51 #include "qpaintdevice.h"
52 #include "qtextcodec.h"
53 #include "qiodevice.h"
54 #include "qhash.h"
55
56 #include <private/qunicodetables_p.h>
57 #include "qfont_p.h"
58 #include "qfontengine_p.h"
59 #include "qfontengine_x11_p.h"
60 #include "qtextengine_p.h"
61
62 #include <private/qt_x11_p.h>
63 #include "qx11info_x11.h"
64
65 #include <time.h>
66 #include <stdlib.h>
67 #include <ctype.h>
68
69 #define QFONTLOADER_DEBUG
70 #define QFONTLOADER_DEBUG_VERBOSE
71
72 QT_BEGIN_NAMESPACE
73
74 double qt_pixelSize(double pointSize, int dpi)
75 {
76     if (pointSize < 0)
77         return -1.;
78     if (dpi == 75) // the stupid 75 dpi setting on X11
79         dpi = 72;
80     return (pointSize * dpi) /72.;
81 }
82
83 double qt_pointSize(double pixelSize, int dpi)
84 {
85     if (pixelSize < 0)
86         return -1.;
87     if (dpi == 75) // the stupid 75 dpi setting on X11
88         dpi = 72;
89     return pixelSize * 72. / ((double) dpi);
90 }
91
92 /*
93   Removes wildcards from an XLFD.
94
95   Returns \a xlfd with all wildcards removed if a match for \a xlfd is
96   found, otherwise it returns \a xlfd.
97 */
98 static QByteArray qt_fixXLFD(const QByteArray &xlfd)
99 {
100     QByteArray ret = xlfd;
101     int count = 0;
102     char **fontNames =
103         XListFonts(QX11Info::display(), xlfd, 32768, &count);
104     if (count > 0)
105         ret = fontNames[0];
106     XFreeFontNames(fontNames);
107     return ret ;
108 }
109
110 typedef QHash<int, QString> FallBackHash;
111 Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
112
113 // Returns the user-configured fallback family for the specified script.
114 QString qt_fallback_font_family(int script)
115 {
116     FallBackHash *hash = fallBackHash();
117     return hash->value(script);
118 }
119
120 // Sets the fallback family for the specified script.
121 Q_GUI_EXPORT void qt_x11_set_fallback_font_family(int script, const QString &family)
122 {
123     FallBackHash *hash = fallBackHash();
124     if (!family.isEmpty())
125         hash->insert(script, family);
126     else
127         hash->remove(script);
128 }
129
130 int QFontPrivate::defaultEncodingID = -1;
131
132 void QFont::initialize()
133 {
134     extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
135     QTextCodec *codec = QTextCodec::codecForLocale();
136     // determine the default encoding id using the locale, otherwise
137     // fallback to latin1 (mib == 4)
138     int mib = codec ? codec->mibEnum() : 4;
139
140     // for asian locales, use the mib for the font codec instead of the locale codec
141     switch (mib) {
142     case 38: // eucKR
143         mib = 36;
144         break;
145
146     case 2025: // GB2312
147         mib = 57;
148         break;
149
150     case 113: // GBK
151         mib = -113;
152         break;
153
154     case 114: // GB18030
155         mib = -114;
156         break;
157
158     case 2026: // Big5
159         mib = -2026;
160         break;
161
162     case 2101: // Big5-HKSCS
163         mib = -2101;
164         break;
165
166     case 16: // JIS7
167         mib = 15;
168         break;
169
170     case 17: // SJIS
171     case 18: // eucJP
172         mib = 63;
173         break;
174     }
175
176     // get the default encoding id for the locale encoding...
177     QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
178 }
179
180 void QFont::cleanup()
181 {
182     QFontCache::cleanup();
183 }
184
185 /*!
186   \internal
187   X11 Only: Returns the screen with which this font is associated.
188 */
189 int QFont::x11Screen() const
190 {
191     return d->screen;
192 }
193
194 /*! \internal
195     X11 Only: Associate the font with the specified \a screen.
196 */
197 void QFont::x11SetScreen(int screen)
198 {
199     if (screen < 0) // assume default
200         screen = QX11Info::appScreen();
201
202     if (screen == d->screen)
203         return; // nothing to do
204
205     detach();
206     d->screen = screen;
207 }
208
209 Qt::HANDLE QFont::handle() const
210 {
211     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
212     Q_ASSERT(engine != 0);
213     if (engine->type() == QFontEngine::Multi)
214         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
215     if (engine->type() == QFontEngine::XLFD)
216         return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
217     return 0;
218 }
219
220
221 FT_Face QFont::freetypeFace() const
222 {
223 #ifndef QT_NO_FREETYPE
224     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
225     if (engine->type() == QFontEngine::Multi)
226         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
227 #ifndef QT_NO_FONTCONFIG
228     if (engine->type() == QFontEngine::Freetype) {
229         const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
230         return ft->non_locked_face();
231     } else
232 #endif
233     if (engine->type() == QFontEngine::XLFD) {
234         const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
235         return xlfd->non_locked_face();
236     }
237 #endif
238     return 0;
239 }
240
241 QString QFont::rawName() const
242 {
243     QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
244     Q_ASSERT(engine != 0);
245     if (engine->type() == QFontEngine::Multi)
246         engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
247     if (engine->type() == QFontEngine::XLFD)
248         return QString::fromLatin1(engine->name());
249     return QString();
250 }
251 struct QtFontDesc;
252
253 void QFont::setRawName(const QString &name)
254 {
255     detach();
256
257     // from qfontdatabase_x11.cpp
258     extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
259
260     if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
261         qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
262
263         setFamily(name);
264         setRawMode(true);
265     } else {
266         resolve_mask = QFont::AllPropertiesResolved;
267     }
268 }
269
270 QString QFont::lastResortFamily() const
271 {
272     return QString::fromLatin1("Helvetica");
273 }
274
275 QString QFont::defaultFamily() const
276 {
277     switch (d->request.styleHint) {
278     case QFont::Times:
279         return QString::fromLatin1("Times");
280
281     case QFont::Courier:
282         return QString::fromLatin1("Courier");
283
284     case QFont::Monospace:
285         return QString::fromLatin1("Courier New");
286
287     case QFont::Cursive:
288         return QString::fromLatin1("Comic Sans MS");
289
290     case QFont::Fantasy:
291         return QString::fromLatin1("Impact");
292
293     case QFont::Decorative:
294         return QString::fromLatin1("Old English");
295
296     case QFont::Helvetica:
297     case QFont::System:
298     default:
299         return QString::fromLatin1("Helvetica");
300     }
301 }
302
303 /*
304   Returns a last resort raw font name for the font matching algorithm.
305   This is used if even the last resort family is not available. It
306   returns \e something, almost no matter what.  The current
307   implementation tries a wide variety of common fonts, returning the
308   first one it finds. The implementation may change at any time.
309 */
310 static const char * const tryFonts[] = {
311     "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
312     "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
313     "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
314     "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
315     "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
316     "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
317     "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
318     "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
319     "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
320     "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
321     "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
322     "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
323     "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
324     "6x13",
325     "7x13",
326     "8x13",
327     "9x15",
328     "fixed",
329     0
330 };
331
332 // Returns true if the font exists, false otherwise
333 static bool fontExists(const QString &fontName)
334 {
335     int count;
336     char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
337     if (fontNames) XFreeFontNames(fontNames);
338
339     return count != 0;
340 }
341
342 QString QFont::lastResortFont() const
343 {
344     static QString last;
345
346     // already found
347     if (! last.isNull())
348         return last;
349
350     int i = 0;
351     const char* f;
352
353     while ((f = tryFonts[i])) {
354         last = QString::fromLatin1(f);
355
356         if (fontExists(last))
357             return last;
358
359         i++;
360     }
361
362 #if defined(CHECK_NULL)
363     qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
364 #endif
365     return last;
366 }
367
368 QT_END_NAMESPACE