source: trunk/src/gui/text/qfont_x11.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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
72QT_BEGIN_NAMESPACE
73
74double 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
83double 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*/
98static 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
110typedef QHash<int, QString> FallBackHash;
111Q_GLOBAL_STATIC(FallBackHash, fallBackHash)
112
113// Returns the user-configured fallback family for the specified script.
114QString 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.
121Q_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
130int QFontPrivate::defaultEncodingID = -1;
131
132/*!
133 Internal function that initializes the font system.
134
135 \internal
136 The font cache and font dict do not alloc the keys. The key is a QString
137 which is shared between QFontPrivate and QXFontName.
138*/
139void QFont::initialize()
140{
141 extern int qt_encoding_id_for_mib(int mib); // from qfontdatabase_x11.cpp
142 QTextCodec *codec = QTextCodec::codecForLocale();
143 // determine the default encoding id using the locale, otherwise
144 // fallback to latin1 (mib == 4)
145 int mib = codec ? codec->mibEnum() : 4;
146
147 // for asian locales, use the mib for the font codec instead of the locale codec
148 switch (mib) {
149 case 38: // eucKR
150 mib = 36;
151 break;
152
153 case 2025: // GB2312
154 mib = 57;
155 break;
156
157 case 113: // GBK
158 mib = -113;
159 break;
160
161 case 114: // GB18030
162 mib = -114;
163 break;
164
165 case 2026: // Big5
166 mib = -2026;
167 break;
168
169 case 2101: // Big5-HKSCS
170 mib = -2101;
171 break;
172
173 case 16: // JIS7
174 mib = 15;
175 break;
176
177 case 17: // SJIS
178 case 18: // eucJP
179 mib = 63;
180 break;
181 }
182
183 // get the default encoding id for the locale encoding...
184 QFontPrivate::defaultEncodingID = qt_encoding_id_for_mib(mib);
185}
186
187/*! \internal
188
189 Internal function that cleans up the font system.
190*/
191void QFont::cleanup()
192{
193 QFontCache::cleanup();
194}
195
196/*!
197 \internal
198 X11 Only: Returns the screen with which this font is associated.
199*/
200int QFont::x11Screen() const
201{
202 return d->screen;
203}
204
205/*! \internal
206 X11 Only: Associate the font with the specified \a screen.
207*/
208void QFont::x11SetScreen(int screen)
209{
210 if (screen < 0) // assume default
211 screen = QX11Info::appScreen();
212
213 if (screen == d->screen)
214 return; // nothing to do
215
216 detach();
217 d->screen = screen;
218}
219
220Qt::HANDLE QFont::handle() const
221{
222 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
223 Q_ASSERT(engine != 0);
224 if (engine->type() == QFontEngine::Multi)
225 engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
226 if (engine->type() == QFontEngine::XLFD)
227 return static_cast<QFontEngineXLFD *>(engine)->fontStruct()->fid;
228 return 0;
229}
230
231
232FT_Face QFont::freetypeFace() const
233{
234#ifndef QT_NO_FREETYPE
235 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
236 if (engine->type() == QFontEngine::Multi)
237 engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
238#ifndef QT_NO_FONTCONFIG
239 if (engine->type() == QFontEngine::Freetype) {
240 const QFontEngineFT *ft = static_cast<const QFontEngineFT *>(engine);
241 return ft->non_locked_face();
242 } else
243#endif
244 if (engine->type() == QFontEngine::XLFD) {
245 const QFontEngineXLFD *xlfd = static_cast<const QFontEngineXLFD *>(engine);
246 return xlfd->non_locked_face();
247 }
248#endif
249 return 0;
250}
251
252QString QFont::rawName() const
253{
254 QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
255 Q_ASSERT(engine != 0);
256 if (engine->type() == QFontEngine::Multi)
257 engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
258 if (engine->type() == QFontEngine::XLFD)
259 return QString::fromLatin1(engine->name());
260 return QString();
261}
262struct QtFontDesc;
263
264void QFont::setRawName(const QString &name)
265{
266 detach();
267
268 // from qfontdatabase_x11.cpp
269 extern bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc);
270
271 if (!qt_fillFontDef(qt_fixXLFD(name.toLatin1()), &d->request, d->dpi, 0)) {
272 qWarning("QFont::setRawName: Invalid XLFD: \"%s\"", name.toLatin1().constData());
273
274 setFamily(name);
275 setRawMode(true);
276 } else {
277 resolve_mask = QFont::AllPropertiesResolved;
278 }
279}
280
281QString QFont::lastResortFamily() const
282{
283 return QString::fromLatin1("Helvetica");
284}
285
286QString QFont::defaultFamily() const
287{
288 switch (d->request.styleHint) {
289 case QFont::Times:
290 return QString::fromLatin1("Times");
291
292 case QFont::Courier:
293 return QString::fromLatin1("Courier");
294
295 case QFont::Decorative:
296 return QString::fromLatin1("Old English");
297
298 case QFont::Helvetica:
299 case QFont::System:
300 default:
301 return QString::fromLatin1("Helvetica");
302 }
303}
304
305/*
306 Returns a last resort raw font name for the font matching algorithm.
307 This is used if even the last resort family is not available. It
308 returns \e something, almost no matter what. The current
309 implementation tries a wide variety of common fonts, returning the
310 first one it finds. The implementation may change at any time.
311*/
312static const char * const tryFonts[] = {
313 "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
314 "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
315 "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
316 "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
317 "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
318 "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
319 "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
320 "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
321 "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
322 "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
323 "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
324 "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
325 "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
326 "6x13",
327 "7x13",
328 "8x13",
329 "9x15",
330 "fixed",
331 0
332};
333
334// Returns true if the font exists, false otherwise
335static bool fontExists(const QString &fontName)
336{
337 int count;
338 char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
339 if (fontNames) XFreeFontNames(fontNames);
340
341 return count != 0;
342}
343
344QString QFont::lastResortFont() const
345{
346 static QString last;
347
348 // already found
349 if (! last.isNull())
350 return last;
351
352 int i = 0;
353 const char* f;
354
355 while ((f = tryFonts[i])) {
356 last = QString::fromLatin1(f);
357
358 if (fontExists(last))
359 return last;
360
361 i++;
362 }
363
364#if defined(CHECK_NULL)
365 qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
366#endif
367 return last;
368}
369
370QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.