summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfontdatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qfontdatabase.cpp')
-rw-r--r--src/gui/text/qfontdatabase.cpp222
1 files changed, 195 insertions, 27 deletions
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 8d5b460..a90d826 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -56,6 +56,11 @@
#include <stdlib.h>
#include <limits.h>
+#if (defined(Q_WS_QWS) || defined(Q_WS_S60)) && !defined(QT_NO_FREETYPE)
+# include <ft2build.h>
+# include FT_TRUETYPE_TABLES_H
+#endif
+
// #define QFONTDATABASE_DEBUG
#ifdef QFONTDATABASE_DEBUG
# define FD_DEBUG qDebug
@@ -76,6 +81,8 @@
QT_BEGIN_NAMESPACE
+#define SMOOTH_SCALABLE 0xffff
+
extern int qt_defaultDpiY(); // in qfont.cpp
Q_GUI_EXPORT bool qt_enable_test_font = false;
@@ -141,10 +148,10 @@ struct QtFontSize
QtFontEncoding *encodingID(int id, uint xpoint = 0, uint xres = 0,
uint yres = 0, uint avgwidth = 0, bool add = false);
#endif // Q_WS_X11
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60)
QByteArray fileName;
int fileIndex;
-#endif
+#endif // defined(Q_WS_QWS) || defined(Q_WS_S60)
};
@@ -160,10 +167,13 @@ QtFontEncoding *QtFontSize::encodingID(int id, uint xpoint, uint xres,
if (!add) return 0;
- if (!(count % 4))
- encodings = (QtFontEncoding *)
+ if (!(count % 4)) {
+ QtFontEncoding *newEncodings = (QtFontEncoding *)
realloc(encodings,
(((count+4) >> 2) << 2) * sizeof(QtFontEncoding));
+ Q_CHECK_PTR(newEncodings);
+ encodings = newEncodings;
+ }
encodings[count].encoding = id;
encodings[count].xpoint = xpoint;
encodings[count].xres = xres;
@@ -215,12 +225,12 @@ struct QtFontStyle
delete [] weightName;
delete [] setwidthName;
#endif
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_S60)
while (count--) {
#ifdef Q_WS_X11
free(pixelSizes[count].encodings);
#endif
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60)
pixelSizes[count].fileName.~QByteArray();
#endif
}
@@ -238,7 +248,7 @@ struct QtFontStyle
const char *weightName;
const char *setwidthName;
#endif // Q_WS_X11
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60)
bool antialiased;
#endif
@@ -267,16 +277,19 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
if (!add)
return 0;
- if (!(count % 8))
- pixelSizes = (QtFontSize *)
+ if (!(count % 8)) {
+ QtFontSize *newPixelSizes = (QtFontSize *)
realloc(pixelSizes,
(((count+8) >> 3) << 3) * sizeof(QtFontSize));
+ Q_CHECK_PTR(newPixelSizes);
+ pixelSizes = newPixelSizes;
+ }
pixelSizes[count].pixelSize = size;
#ifdef Q_WS_X11
pixelSizes[count].count = 0;
pixelSizes[count].encodings = 0;
#endif
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60)
new (&pixelSizes[count].fileName) QByteArray;
pixelSizes[count].fileIndex = 0;
#endif
@@ -321,12 +334,16 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
return 0;
// qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos);
- if (!(count % 8))
- styles = (QtFontStyle **)
+ if (!(count % 8)) {
+ QtFontStyle **newStyles = (QtFontStyle **)
realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *));
+ Q_CHECK_PTR(newStyles);
+ styles = newStyles;
+ }
+ QtFontStyle *style = new QtFontStyle(key);
memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
- styles[pos] = new QtFontStyle(key);
+ styles[pos] = style;
count++;
return styles[pos];
}
@@ -358,7 +375,7 @@ struct QtFontFamily
fixedPitchComputed(false),
#endif
name(n), count(0), foundries(0)
-#if defined(Q_WS_QWS)
+#if defined(Q_WS_QWS) || defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
, bogusWritingSystems(false)
#endif
{
@@ -388,7 +405,7 @@ struct QtFontFamily
#endif
QString name;
-#ifdef Q_WS_X11
+#if defined(Q_WS_X11) || defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
QByteArray fontFilename;
int fontFileIndex;
#endif
@@ -398,7 +415,7 @@ struct QtFontFamily
int count;
QtFontFoundry **foundries;
-#ifdef Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
bool bogusWritingSystems;
QStringList fallbackFamilies;
#endif
@@ -431,10 +448,13 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
if (!create)
return 0;
- if (!(count % 8))
- foundries = (QtFontFoundry **)
+ if (!(count % 8)) {
+ QtFontFoundry **newFoundries = (QtFontFoundry **)
realloc(foundries,
(((count+8) >> 3) << 3) * sizeof(QtFontFoundry *));
+ Q_CHECK_PTR(newFoundries);
+ foundries = newFoundries;
+ }
foundries[count] = new QtFontFoundry(f);
return foundries[count++];
@@ -442,7 +462,7 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
// ### copied to tools/makeqpf/qpf2.cpp
-#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
+#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_WS_S60) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
// see the Unicode subset bitfields in the MSDN docs
static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
// Any,
@@ -563,6 +583,15 @@ static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBi
}
#endif
+#if defined(Q_WS_S60) && defined(QT_NO_FREETYPE)
+// class with virtual destructor, derived in qfontdatabase_s60.cpp
+class QFontDatabaseS60Store
+{
+public:
+ virtual ~QFontDatabaseS60Store() {};
+};
+#endif
+
class QFontDatabasePrivate
{
public:
@@ -571,6 +600,9 @@ public:
#if defined(Q_WS_QWS)
, stream(0)
#endif
+#if defined(Q_WS_S60) && defined(QT_NO_FREETYPE)
+ , s60Store(0)
+#endif
{ }
~QFontDatabasePrivate() {
free();
@@ -582,6 +614,12 @@ public:
::free(families);
families = 0;
count = 0;
+#if defined(Q_WS_S60) && defined(QT_NO_FREETYPE)
+ if (s60Store) {
+ delete s60Store;
+ s60Store = 0;
+ }
+#endif
// don't clear the memory fonts!
}
@@ -609,17 +647,22 @@ public:
#if defined(Q_WS_QWS)
bool loadFromCache(const QString &fontPath);
+ void addQPF2File(const QByteArray &file);
+#endif // Q_WS_QWS
+#if defined(Q_WS_QWS) || defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
void addFont(const QString &familyname, const char *foundryname, int weight,
bool italic, int pixelSize, const QByteArray &file, int fileIndex,
bool antialiased,
const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>());
- void addQPF2File(const QByteArray &file);
#ifndef QT_NO_FREETYPE
QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());
+#endif // QT_NO_FREETYPE
#endif
-
+#if defined(Q_WS_QWS)
QDataStream *stream;
QStringList fallbackFamilies;
+#elif defined(Q_WS_S60) && defined(QT_NO_FREETYPE)
+ const QFontDatabaseS60Store *s60Store;
#endif
};
@@ -654,17 +697,133 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
pos++;
// qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
- if (!(count % 8))
- families = (QtFontFamily **)
+ if (!(count % 8)) {
+ QtFontFamily **newFamilies = (QtFontFamily **)
realloc(families,
(((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
+ Q_CHECK_PTR(newFamilies);
+ families = newFamilies;
+ }
+ QtFontFamily *family = new QtFontFamily(f);
memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
- families[pos] = new QtFontFamily(f);
+ families[pos] = family;
count++;
return families[pos];
}
+#if defined(Q_WS_QWS) || defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
+void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize,
+ const QByteArray &file, int fileIndex, bool antialiased,
+ const QList<QFontDatabase::WritingSystem> &writingSystems)
+{
+// qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
+ QtFontStyle::Key styleKey;
+ styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
+ styleKey.weight = weight;
+ styleKey.stretch = 100;
+ QtFontFamily *f = family(familyname, true);
+
+ if (writingSystems.isEmpty()) {
+ for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
+ f->writingSystems[ws] = QtFontFamily::Supported;
+ }
+ f->bogusWritingSystems = true;
+ } else {
+ for (int i = 0; i < writingSystems.count(); ++i) {
+ f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported;
+ }
+ }
+
+ QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
+ QtFontStyle *style = foundry->style(styleKey, true);
+ style->smoothScalable = (pixelSize == 0);
+ style->antialiased = antialiased;
+ QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
+ size->fileName = file;
+ size->fileIndex = fileIndex;
+
+#if defined(Q_WS_QWS)
+ if (stream) {
+ *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize
+ << file << fileIndex << quint8(antialiased);
+ *stream << quint8(writingSystems.count());
+ for (int i = 0; i < writingSystems.count(); ++i)
+ *stream << quint8(writingSystems.at(i));
+ }
+#else // ..in case of defined(Q_WS_S60) && !defined(QT_NO_FREETYPE)
+ f->fontFilename = file;
+ f->fontFileIndex = fileIndex;
+#endif
+}
+#endif
+
+#if (defined(Q_WS_QWS) || defined(Q_WS_S60)) && !defined(QT_NO_FREETYPE)
+QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData)
+{
+ QStringList families;
+ extern FT_Library qt_getFreetype();
+ FT_Library library = qt_getFreetype();
+
+ int index = 0;
+ int numFaces = 0;
+ do {
+ FT_Face face;
+ FT_Error error;
+ if (!fontData.isEmpty()) {
+ error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
+ } else {
+ error = FT_New_Face(library, file, index, &face);
+ }
+ if (error != FT_Err_Ok) {
+ qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
+ break;
+ }
+ numFaces = face->num_faces;
+
+ int weight = QFont::Normal;
+ bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC;
+
+ if (face->style_flags & FT_STYLE_FLAG_BOLD)
+ weight = QFont::Bold;
+
+ QList<QFontDatabase::WritingSystem> writingSystems;
+ // detect symbol fonts
+ for (int i = 0; i < face->num_charmaps; ++i) {
+ FT_CharMap cm = face->charmaps[i];
+ if (cm->encoding == ft_encoding_adobe_custom
+ || cm->encoding == ft_encoding_symbol) {
+ writingSystems.append(QFontDatabase::Symbol);
+ break;
+ }
+ }
+ if (writingSystems.isEmpty()) {
+ TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ if (os2) {
+ quint32 unicodeRange[4] = {
+ os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
+ };
+ quint32 codePageRange[2] = {
+ os2->ulCodePageRange1, os2->ulCodePageRange2
+ };
+
+ writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ //for (int i = 0; i < writingSystems.count(); ++i)
+ // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i));
+ }
+ }
+
+ QString family = QString::fromAscii(face->family_name);
+ families.append(family);
+ addFont(family, /*foundry*/ "", weight, italic,
+ /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems);
+
+ FT_Done_Face(face);
+ ++index;
+ } while (index < numFaces);
+ return families;
+}
+#endif
static const int scriptForWritingSystem[] = {
QUnicodeTables::Common, // Any
@@ -814,7 +973,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe
#endif
#endif
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_S60)
static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
{
// look for the requested font in the engine data cache
@@ -866,8 +1025,6 @@ QMutex *qt_fontdatabase_mutex()
return fontDatabaseMutex();
}
-#define SMOOTH_SCALABLE 0xffff
-
QT_BEGIN_INCLUDE_NAMESPACE
#if defined(Q_WS_X11)
# include "qfontdatabase_x11.cpp"
@@ -877,6 +1034,8 @@ QT_BEGIN_INCLUDE_NAMESPACE
# include "qfontdatabase_win.cpp"
#elif defined(Q_WS_QWS)
# include "qfontdatabase_qws.cpp"
+#elif defined(Q_WS_S60)
+# include "qfontdatabase_s60.cpp"
#endif
QT_END_INCLUDE_NAMESPACE
@@ -2254,7 +2413,16 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem)
sample += QChar(0xac2f);
break;
case Vietnamese:
+ {
+ static const char vietnameseUtf8[] = {
+ char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97),
+ char(0xe1), char(0xbb), char(0x99),
+ char(0xe1), char(0xbb), char(0x91),
+ char(0xe1), char(0xbb), char(0x93),
+ };
+ sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8));
break;
+ }
case Ogham:
sample += QChar(0x1681);
sample += QChar(0x1682);