Qt 4.8
qbasicunixfontdatabase.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qbasicunixfontdatabase.h"
43 
44 #include <QtGui/private/qapplication_p.h>
45 #include <QtGui/QPlatformScreen>
46 
47 #include <QtCore/QFile>
48 #include <QtCore/QLibraryInfo>
49 #include <QtCore/QDir>
50 
51 #undef QT_NO_FREETYPE
52 #include <QtGui/private/qfontengine_ft_p.h>
53 #include <QtGui/private/qfontengine_p.h>
54 
55 #include <ft2build.h>
56 #include FT_TRUETYPE_TABLES_H
57 
58 #define SimplifiedChineseCsbBit 18
59 #define TraditionalChineseCsbBit 20
60 #define JapaneseCsbBit 17
61 #define KoreanCsbBit 21
62 
64  // Any,
65  { 127, 127 },
66  // Latin,
67  { 0, 127 },
68  // Greek,
69  { 7, 127 },
70  // Cyrillic,
71  { 9, 127 },
72  // Armenian,
73  { 10, 127 },
74  // Hebrew,
75  { 11, 127 },
76  // Arabic,
77  { 13, 127 },
78  // Syriac,
79  { 71, 127 },
80  //Thaana,
81  { 72, 127 },
82  //Devanagari,
83  { 15, 127 },
84  //Bengali,
85  { 16, 127 },
86  //Gurmukhi,
87  { 17, 127 },
88  //Gujarati,
89  { 18, 127 },
90  //Oriya,
91  { 19, 127 },
92  //Tamil,
93  { 20, 127 },
94  //Telugu,
95  { 21, 127 },
96  //Kannada,
97  { 22, 127 },
98  //Malayalam,
99  { 23, 127 },
100  //Sinhala,
101  { 73, 127 },
102  //Thai,
103  { 24, 127 },
104  //Lao,
105  { 25, 127 },
106  //Tibetan,
107  { 70, 127 },
108  //Myanmar,
109  { 74, 127 },
110  // Georgian,
111  { 26, 127 },
112  // Khmer,
113  { 80, 127 },
114  // SimplifiedChinese,
115  { 126, 127 },
116  // TraditionalChinese,
117  { 126, 127 },
118  // Japanese,
119  { 126, 127 },
120  // Korean,
121  { 56, 127 },
122  // Vietnamese,
123  { 0, 127 }, // same as latin1
124  // Other,
125  { 126, 127 },
126  // Ogham,
127  { 78, 127 },
128  // Runic,
129  { 79, 127 },
130  // Nko,
131  { 14, 127 },
132 };
133 
135 {
136  QSupportedWritingSystems writingSystems;
137  bool hasScript = false;
138 
139  int i;
140  for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
141  int bit = requiredUnicodeBits[i][0];
142  int index = bit/32;
143  int flag = 1 << (bit&31);
144  if (bit != 126 && unicodeRange[index] & flag) {
145  bit = requiredUnicodeBits[i][1];
146  index = bit/32;
147 
148  flag = 1 << (bit&31);
149  if (bit == 127 || unicodeRange[index] & flag) {
150  writingSystems.setSupported(QFontDatabase::WritingSystem(i));
151  hasScript = true;
152  // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
153  }
154  }
155  }
156  if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
158  hasScript = true;
159  //qDebug("font %s supports Simplified Chinese", familyName.latin1());
160  }
161  if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
163  hasScript = true;
164  //qDebug("font %s supports Traditional Chinese", familyName.latin1());
165  }
166  if(codePageRange[0] & (1 << JapaneseCsbBit)) {
167  writingSystems.setSupported(QFontDatabase::Japanese);
168  hasScript = true;
169  //qDebug("font %s supports Japanese", familyName.latin1());
170  }
171  if(codePageRange[0] & (1 << KoreanCsbBit)) {
172  writingSystems.setSupported(QFontDatabase::Korean);
173  hasScript = true;
174  //qDebug("font %s supports Korean", familyName.latin1());
175  }
176  if (!hasScript)
177  writingSystems.setSupported(QFontDatabase::Symbol);
178 
179  return writingSystems;
180 }
181 
182 static inline bool scriptRequiresOpenType(int script)
183 {
184  return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
185  || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
186 }
187 
189 {
191  QString fontpath = fontDir();
192 
193  if(!QFile::exists(fontpath)) {
194  qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
195  qPrintable(fontpath));
196  }
197 
198  QDir dir(fontpath);
199  dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
200  << QLatin1String("*.ttc") << QLatin1String("*.pfa")
201  << QLatin1String("*.pfb"));
202  dir.refresh();
203  for (int i = 0; i < int(dir.count()); ++i) {
204  const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
205 // qDebug() << "looking at" << file;
206  addTTFile(QByteArray(), file);
207  }
208 }
209 
211 {
212  QFontEngineFT *engine;
213  FontFile *fontfile = static_cast<FontFile *> (usrPtr);
215  fid.filename = fontfile->fileName.toLocal8Bit();
216  fid.index = fontfile->indexValue;
217  engine = new QFontEngineFT(fontDef);
218 
219  bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
221  if (!engine->init(fid,antialias,format)) {
222  delete engine;
223  engine = 0;
224  return engine;
225  }
226  if (engine->invalid()) {
227  delete engine;
228  engine = 0;
229  } else if (scriptRequiresOpenType(script)) {
230  HB_Face hbFace = engine->harfbuzzFace();
231  if (!hbFace || !hbFace->supported_scripts[script]) {
232  delete engine;
233  engine = 0;
234  }
235  }
236 
237  return engine;
238 }
239 
241 {
242  Q_UNUSED(family);
243  Q_UNUSED(style);
244  Q_UNUSED(styleHint);
245  Q_UNUSED(script);
246  return QStringList();
247 }
248 
250 {
251  return addTTFile(fontData,fileName.toLocal8Bit());
252 }
253 
255 {
256  FontFile *file = static_cast<FontFile *>(handle);
257  delete file;
258 }
259 
261 {
262  extern FT_Library qt_getFreetype();
263  FT_Library library = qt_getFreetype();
264 
265  int index = 0;
266  int numFaces = 0;
267  QStringList families;
268  do {
269  FT_Face face;
270  FT_Error error;
271  if (!fontData.isEmpty()) {
272  error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
273  } else {
274  error = FT_New_Face(library, file.constData(), index, &face);
275  }
276  if (error != FT_Err_Ok) {
277  qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
278  break;
279  }
280  numFaces = face->num_faces;
281 
282  QFont::Weight weight = QFont::Normal;
283 
285  if (face->style_flags & FT_STYLE_FLAG_ITALIC)
286  style = QFont::StyleItalic;
287 
288  if (face->style_flags & FT_STYLE_FLAG_BOLD)
289  weight = QFont::Bold;
290 
291  QSupportedWritingSystems writingSystems;
292  // detect symbol fonts
293  for (int i = 0; i < face->num_charmaps; ++i) {
294  FT_CharMap cm = face->charmaps[i];
295  if (cm->encoding == ft_encoding_adobe_custom
296  || cm->encoding == ft_encoding_symbol) {
297  writingSystems.setSupported(QFontDatabase::Symbol);
298  break;
299  }
300  }
301 
302  TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
303  if (os2) {
304  quint32 unicodeRange[4] = {
305  quint32(os2->ulUnicodeRange1), quint32(os2->ulUnicodeRange2),
306  quint32(os2->ulUnicodeRange3), quint32(os2->ulUnicodeRange4)
307  };
308  quint32 codePageRange[2] = {
309  quint32(os2->ulCodePageRange1), quint32(os2->ulCodePageRange2)
310  };
311 
312  writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
313  }
314 
315  QString family = QString::fromAscii(face->family_name);
316  FontFile *fontFile = new FontFile;
317  fontFile->fileName = file;
318  fontFile->indexValue = index;
319 
321 
322  registerFont(family,"",weight,style,stretch,true,true,0,writingSystems,fontFile);
323 
324  families.append(family);
325 
326  FT_Done_Face(face);
327  ++index;
328  } while (index < numFaces);
329  return families;
330 }
The QDir class provides access to directory structures and their contents.
Definition: qdir.h:58
void setSupported(QFontDatabase::WritingSystem, bool supported=true)
Sets the supported state of the writing system given by writingSystem to the value specified by suppo...
static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file)
void populateFontDatabase()
This function is called once at startup by Qts internal fontdatabase.
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
QString absoluteFilePath(const QString &fileName) const
Returns the absolute path name of a file in the directory.
Definition: qdir.cpp:701
#define error(msg)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
Weight
Qt uses a weighting scale from 0 to 99 similar to, but not the same as, the scales used in Windows or...
Definition: qfont.h:103
The QString class provides a Unicode character string.
Definition: qstring.h:83
uint count() const
Returns the total number of directories and files in the directory.
Definition: qdir.cpp:1247
Stretch
Predefined stretch values that follow the CSS naming convention.
Definition: qfont.h:117
Q_CORE_EXPORT QTextStream & hex(QTextStream &s)
void setNameFilters(const QStringList &nameFilters)
Sets the name filters used by entryList() and entryInfoList() to the list of filters specified by nam...
Definition: qdir.cpp:966
bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat=Format_None, const QByteArray &fontData=QByteArray())
bool exists() const
Returns true if the file specified by fileName() exists; otherwise returns false. ...
Definition: qfile.cpp:626
void refresh() const
Refreshes the directory information.
Definition: qdir.cpp:2218
Q_CORE_EXPORT void qDebug(const char *,...)
#define SimplifiedChineseCsbBit
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
Returns a list of alternative fonts for the specified family and style and script using the styleHint...
struct FT_FaceRec_ * FT_Face
Definition: qfont.h:50
static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **freetype, int *synth)
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
The QSupportedWritingSystems class is used when registering fonts with the internal Qt fontdatabase...
virtual QString fontDir() const
Returns the path to the font directory.
const char * styleHint(const QFontDef &request)
#define JapaneseCsbBit
#define TraditionalChineseCsbBit
#define KoreanCsbBit
static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2]
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
Style
This enum describes the different styles of glyphs that are used to display text. ...
Definition: qfont.h:111
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName)
Adds an application font described by the font contained supplied fontData or using the font containe...
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QFontEngine * fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
Returns the font engine that can be used to render the font described by the font definition...
Q_CORE_EXPORT void qFatal(const char *,...)
StyleHint
Style hints are used by the font matching algorithm to find an appropriate default family if a select...
Definition: qfont.h:69
static void registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *handle)
Registers a font with the given set of attributes describing the font&#39;s foundry, family name...
unsigned int quint32
Definition: qglobal.h:938
static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
quint16 index
virtual void populateFontDatabase()
This function is called once at startup by Qts internal fontdatabase.
static QByteArray encodeName(const QString &fileName)
By default, this function converts fileName to the local 8-bit encoding determined by the user&#39;s loca...
Definition: qfile.cpp:528
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
FT_Library qt_getFreetype()
bool invalid() const
static bool scriptRequiresOpenType(int script)
#define qPrintable(string)
Definition: qglobal.h:1750
uint styleStrategy
Definition: qfont_p.h:92
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
static QString fileName(const QString &fileUrl)
void releaseHandle(void *handle)
Releases the font handle and deletes any associated data loaded from a file.
HB_Face harfbuzzFace() const