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

Last change on this file since 624 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 9.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia 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
132void 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
180void QFont::cleanup()
181{
182 QFontCache::cleanup();
183}
184
185/*!
186 \internal
187 X11 Only: Returns the screen with which this font is associated.
188*/
189int QFont::x11Screen() const
190{
191 return d->screen;
192}
193
194/*! \internal
195 X11 Only: Associate the font with the specified \a screen.
196*/
197void 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
209Qt::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
221FT_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
241QString 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}
251struct QtFontDesc;
252
253void 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
270QString QFont::lastResortFamily() const
271{
272 return QString::fromLatin1("Helvetica");
273}
274
275QString 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::Decorative:
285 return QString::fromLatin1("Old English");
286
287 case QFont::Helvetica:
288 case QFont::System:
289 default:
290 return QString::fromLatin1("Helvetica");
291 }
292}
293
294/*
295 Returns a last resort raw font name for the font matching algorithm.
296 This is used if even the last resort family is not available. It
297 returns \e something, almost no matter what. The current
298 implementation tries a wide variety of common fonts, returning the
299 first one it finds. The implementation may change at any time.
300*/
301static const char * const tryFonts[] = {
302 "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
303 "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
304 "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
305 "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
306 "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
307 "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
308 "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
309 "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
310 "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
311 "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
312 "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
313 "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
314 "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
315 "6x13",
316 "7x13",
317 "8x13",
318 "9x15",
319 "fixed",
320 0
321};
322
323// Returns true if the font exists, false otherwise
324static bool fontExists(const QString &fontName)
325{
326 int count;
327 char **fontNames = XListFonts(QX11Info::display(), (char*)fontName.toLatin1().constData(), 32768, &count);
328 if (fontNames) XFreeFontNames(fontNames);
329
330 return count != 0;
331}
332
333QString QFont::lastResortFont() const
334{
335 static QString last;
336
337 // already found
338 if (! last.isNull())
339 return last;
340
341 int i = 0;
342 const char* f;
343
344 while ((f = tryFonts[i])) {
345 last = QString::fromLatin1(f);
346
347 if (fontExists(last))
348 return last;
349
350 i++;
351 }
352
353#if defined(CHECK_NULL)
354 qFatal("QFontPrivate::lastResortFont: Cannot find any reasonable font");
355#endif
356 return last;
357}
358
359QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.