summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2010-08-20 12:33:33 +0200
committerJørgen Lind <jorgen.lind@nokia.com>2010-09-02 15:25:37 +0200
commit5e7fdcc7a4a2bb070ad7ece920ac5db81e3e6f77 (patch)
tree5a67130cd7144084adceed7c5e1697e650cee20f
parentde66ffa4d7d057f0c782edc45374ad58322a0c4c (diff)
Initial pluggable fontdatabase
QPlatformFontDatabase added. QPlatformIntegration now has a new virtual function: QPlatformDatabase::fontDatabase() const. Most unix platform plugins wants to follow the pattern implemented in directfb, linuxfb, vnc etc. In the pro file do: include(../fontdatabases/genericunix/genericunix.pri) In the QPlatformIntegration class do: and instansiate a QGenericFontDatabase in the constructor and return it in the getter function.
-rwxr-xr-xconfigure24
-rw-r--r--lib/fonts/dejavu_sans_11_50.qpf2bin0 -> 405944 bytes
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp11
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h4
-rw-r--r--src/gui/painting/qpaintengine.h2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp31
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/text/qfont.h4
-rw-r--r--src/gui/text/qfont_qpa.cpp114
-rw-r--r--src/gui/text/qfontdatabase.cpp67
-rw-r--r--src/gui/text/qfontdatabase.h1
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp392
-rw-r--r--src/gui/text/qfontengine.cpp2
-rw-r--r--src/gui/text/qfontengine_ft.cpp7
-rw-r--r--src/gui/text/qfontengine_ft_p.h16
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qfontengine_qpa.cpp650
-rw-r--r--src/gui/text/qfontengine_qpa_p.h262
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.cpp195
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.h65
-rw-r--r--src/gui/text/text.pri22
-rw-r--r--src/plugins/platforms/directfb/directfb.pro2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp7
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h4
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pro2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp8
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h3
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/basicunix.pri82
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp281
-rw-r--r--src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h26
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri12
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp528
-rw-r--r--src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h15
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/genericunix.pri10
-rw-r--r--src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h12
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro1
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp7
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h3
-rw-r--r--src/plugins/platforms/platforms.pro12
-rw-r--r--src/plugins/platforms/qvfb/qvfb.pro2
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.cpp8
-rw-r--r--src/plugins/platforms/qvfb/qvfbintegration.h3
-rw-r--r--src/plugins/platforms/testlite/qtestliteintegration.cpp8
-rw-r--r--src/plugins/platforms/testlite/qtestliteintegration.h3
-rw-r--r--src/plugins/platforms/testlite/qtestlitewindow.cpp10
-rw-r--r--src/plugins/platforms/testlite/testlite.pro21
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp8
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h4
-rw-r--r--src/plugins/platforms/vnc/vnc.pro1
49 files changed, 2894 insertions, 62 deletions
diff --git a/configure b/configure
index bdf458836d..94a0c0ff53 100755
--- a/configure
+++ b/configure
@@ -6093,6 +6093,30 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
exit 1
fi
fi
+
+ # auto-detect FontConfig support
+ if [ "$CFG_FONTCONFIG" != "no" ]; then
+ if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists fontconfig --exists freetype2 2>/dev/null; then
+ QT_CFLAGS_FONTCONFIG=`$PKG_CONFIG --cflags fontconfig --cflags freetype2 2>/dev/null`
+ QT_LIBS_FONTCONFIG=`$PKG_CONFIG --libs fontconfig --libs freetype2 2>/dev/null`
+ else
+ QT_CFLAGS_FONTCONFIG=
+ QT_LIBS_FONTCONFIG="-lfreetype -lfontconfig"
+ fi
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/fontconfig "FontConfig" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS $QT_CFLAGS_FONTCONFIG $QT_LIBS_FONTCONFIG; then
+ QT_CONFIG="$QT_CONFIG fontconfig"
+ QMakeVar set QMAKE_CFLAGS_FONTCONFIG "$QT_CFLAGS_FONTCONFIG"
+ QMakeVar set QMAKE_LIBS_FONTCONFIG "$QT_LIBS_FONTCONFIG"
+ CFG_LIBFREETYPE=system
+ fi
+ fi
+
+ # MIT_SHM is required for testlite
+ if [ "$CFG_MITSHM" != "no" ]; then
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/x11/mitshm "mitshm" $L_FLAGS $I_FLAGS $l_FLAGS $X11TESTS_FLAGS; then
+ QT_CONFIG="$QT_CONFIG mitshm"
+ fi
+ fi
fi
diff --git a/lib/fonts/dejavu_sans_11_50.qpf2 b/lib/fonts/dejavu_sans_11_50.qpf2
new file mode 100644
index 0000000000..c88d099092
--- /dev/null
+++ b/lib/fonts/dejavu_sans_11_50.qpf2
Binary files differ
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index b4987f23ed..e2a493d20f 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -41,6 +41,8 @@
#include "qplatformintegration_qpa.h"
+#include <QtGui/QPlatformFontDatabase>
+
QT_BEGIN_NAMESPACE
QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
@@ -63,4 +65,13 @@ bool QPlatformIntegration::hasOpenGL() const
return false;
}
+QPlatformFontDatabase *QPlatformIntegration::fontDatabase() const
+{
+ static QPlatformFontDatabase *db = 0;
+ if (!db) {
+ db = new QPlatformFontDatabase;
+ }
+ return db;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 94609107d8..b1f4e5f5db 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -58,6 +58,7 @@ class QWindowSurface;
class QBlittable;
class QWidget;
class QPlatformEventLoopIntegration;
+class QPlatformFontDatabase;
class Q_GUI_EXPORT QPlatformIntegration
{
@@ -75,6 +76,9 @@ public:
virtual bool isVirtualDesktop() { return false; }
virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
+//Fontdatabase integration.
+ virtual QPlatformFontDatabase *fontDatabase() const;
+
// Experimental in mainthread eventloop integration
// This should only be used if it is only possible to do window system event processing in
// the gui thread. All of the functions in QWindowSystemInterface are thread safe.
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index ddb6195fdd..ee9b457943 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -272,7 +272,7 @@ private:
friend class QProxyFontEngine;
#endif
#ifdef Q_WS_QPA
- friend class QProxyFontEngine;
+ friend class QFontEngineQPA;
#endif
friend class QPainter;
friend class QPainterPrivate;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index df32ea8cab..7dee7e4b9d 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3396,9 +3396,36 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
}
#endif // Q_WS_QWS
-#if (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_QPA)) && !defined(QT_NO_FREETYPE)
+#ifdef Q_WS_QPA
+ if (s->matrix.type() < QTransform::TxScale) {
-#if (defined(Q_WS_QWS) || defined(Q_WS_QPA)) && !defined(QT_NO_QWS_QPF2)
+ QVarLengthArray<QFixedPoint> positions;
+ QVarLengthArray<glyph_t> glyphs;
+ QTransform matrix = state()->transform();
+
+ qreal _x = qFloor(p.x() + aliasedCoordinateDelta);
+ qreal _y = qFloor(p.y() + aliasedCoordinateDelta);
+ matrix.translate(_x, _y);
+
+ fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ if (glyphs.size() == 0)
+ return;
+
+ for(int i = 0; i < glyphs.size(); i++) {
+ QImage img = fontEngine->alphaMapForGlyph(glyphs[i]);
+ glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]);
+ alphaPenBlt(img.bits(), img.bytesPerLine(), img.depth(),
+ qRound(positions[i].x + metrics.x),
+ qRound(positions[i].y + metrics.y),
+ img.width(), img.height());
+ }
+ return;
+ }
+#endif //Q_WS_QPA
+
+#if (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_QPF2)
if (fontEngine->type() == QFontEngine::QPF2) {
QFontEngine *renderingEngine = static_cast<QFontEngineQPF *>(fontEngine)->renderingEngine();
if (renderingEngine)
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 6e02435a43..fdb84e0a7c 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -916,7 +916,7 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize)
}
-QByteArray QPdf::stripSpecialCharacters(const QByteArray &string)
+Q_GUI_EXPORT QByteArray QPdf::stripSpecialCharacters(const QByteArray &string)
{
QByteArray s = string;
s.replace(' ', "");
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index fd1a2dd0a9..2cc41e1da0 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -46,7 +46,7 @@
#include <QtCore/qstring.h>
#include <QtCore/qsharedpointer.h>
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
typedef struct FT_FaceRec_* FT_Face;
#endif
@@ -236,7 +236,7 @@ public:
#ifdef Q_WS_MAC
quint32 macFontID() const;
#endif
-#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
FT_Face freetypeFace() const;
#endif
diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp
new file mode 100644
index 0000000000..5fed18bc5e
--- /dev/null
+++ b/src/gui/text/qfont_qpa.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/QPlatformFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+void QFont::initialize()
+{
+ QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
+}
+
+void QFont::cleanup()
+{
+ QFontCache::cleanup();
+}
+
+
+/*****************************************************************************
+ QFont member functions
+ *****************************************************************************/
+
+Qt::HANDLE QFont::handle() const
+{
+ return 0;
+}
+
+QString QFont::rawName() const
+{
+ return QLatin1String("unknown");
+}
+
+void QFont::setRawName(const QString &)
+{
+}
+
+QString QFont::defaultFamily() const
+{
+ QString familyName;
+ switch(d->request.styleHint) {
+ case QFont::Times:
+ familyName = QString::fromLatin1("times");
+ case QFont::Courier:
+ case QFont::Monospace:
+ familyName = QString::fromLatin1("monospace");
+ case QFont::Decorative:
+ familyName = QString::fromLatin1("old english");
+ case QFont::Helvetica:
+ case QFont::System:
+ default:
+ familyName = QString::fromLatin1("helvetica");
+ }
+
+ QStringList list = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(familyName,QFont::StyleNormal,QUnicodeTables::Common);
+ if (list.size()) {
+ familyName = list.at(0);
+ }
+ return familyName;
+}
+
+QString QFont::lastResortFamily() const
+{
+ return QString::fromLatin1("helvetica");
+}
+
+QString QFont::lastResortFont() const
+{
+ qFatal("QFont::lastResortFont: Cannot find any reasonable font");
+ // Shut compiler up
+ return QString();
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7ece6eaa32..72ffb1cf27 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -50,13 +50,19 @@
#include "private/qunicodetables_p.h"
#include "qfontengine_p.h"
+#ifdef Q_WS_QPA
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/qplatformfontdatabase_qpa.h>
+#include "qabstractfileengine.h"
+#endif
+
#ifdef Q_WS_X11
#include <locale.h>
#endif
#include <stdlib.h>
#include <limits.h>
-#if (defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
+#if (defined(Q_WS_QWS)|| defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
# include <ft2build.h>
# include FT_TRUETYPE_TABLES_H
#endif
@@ -143,7 +149,7 @@ struct QtFontEncoding
uchar pitch : 8;
};
-struct QtFontSize
+struct QtFontSize
{
#ifdef Q_WS_X11
QtFontEncoding *encodings;
@@ -152,10 +158,13 @@ struct QtFontSize
unsigned short count : 16;
#endif // Q_WS_X11
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
QByteArray fileName;
int fileIndex;
#endif // defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QPA)
+ void *handle;
+#endif
unsigned short pixelSize : 16;
};
@@ -238,9 +247,15 @@ struct QtFontStyle
#ifdef Q_WS_X11
free(pixelSizes[count].encodings);
#endif
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
pixelSizes[count].fileName.~QByteArray();
#endif
+#if defined (Q_WS_QPA)
+ QPlatformIntegration *integration = QApplicationPrivate::platformIntegration();
+ if (integration) { //on shut down there will be some that we don't release.
+ integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
+ }
+#endif
}
#endif
free(pixelSizes);
@@ -302,10 +317,13 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
pixelSizes[count].count = 0;
pixelSizes[count].encodings = 0;
#endif
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
new (&pixelSizes[count].fileName) QByteArray;
pixelSizes[count].fileIndex = 0;
#endif
+#if defined(Q_WS_QPA)
+ pixelSizes[count].handle = 0;
+#endif
return pixelSizes + (count++);
}
@@ -362,7 +380,7 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
}
-struct QtFontFamily
+struct QtFontFamily
{
enum WritingSystemStatus {
Unknown = 0,
@@ -391,6 +409,9 @@ struct QtFontFamily
#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
, bogusWritingSystems(false)
#endif
+#if defined(Q_WS_QPA)
+ , askedForFallback(false)
+#endif
{
memset(writingSystems, 0, sizeof(writingSystems));
}
@@ -432,6 +453,9 @@ struct QtFontFamily
bool bogusWritingSystems;
QStringList fallbackFamilies;
#endif
+#if defined (Q_WS_QPA)
+ bool askedForFallback;
+#endif
unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
QtFontFoundry *foundry(const QString &f, bool = false);
@@ -475,7 +499,7 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
// ### copied to tools/makeqpf/qpf2.cpp
-#if ((defined(Q_WS_QWS) || defined(Q_WS_QPA)) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
+#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
// see the Unicode subset bitfields in the MSDN docs
static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
@@ -617,7 +641,7 @@ class QFontDatabasePrivate
public:
QFontDatabasePrivate()
: count(0), families(0), reregisterAppFonts(false)
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#if defined(Q_WS_QWS)
, stream(0)
#endif
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
@@ -665,11 +689,11 @@ public:
void invalidate();
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#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_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !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,
@@ -678,12 +702,14 @@ public:
QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());
#endif // QT_NO_FREETYPE
#endif
-#if defined(Q_WS_QWS) || defined (Q_WS_QPA)
+#if defined(Q_WS_QWS)
QDataStream *stream;
- QStringList fallbackFamilies;
#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
const QSymbianFontDatabaseExtras *symbianExtras;
#endif
+#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+ QStringList fallbackFamilies;
+#endif
};
void QFontDatabasePrivate::invalidate()
@@ -732,7 +758,7 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
return families[pos];
}
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !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)
@@ -763,7 +789,7 @@ void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundr
size->fileName = file;
size->fileIndex = fileIndex;
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#if defined(Q_WS_QWS)
if (stream) {
*stream << familyname << foundry->name << weight << quint8(italic) << pixelSize
<< file << fileIndex << quint8(antialiased);
@@ -778,7 +804,7 @@ void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundr
}
#endif
-#if (defined(Q_WS_QWS) || defined (Q_WS_QPA) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
+#if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData)
{
QStringList families;
@@ -891,7 +917,7 @@ static const int scriptForWritingSystem[] = {
};
-#if defined Q_WS_QWS || defined(Q_WS_QPA) || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN)
+#if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN)
static inline bool requiresOpenType(int writingSystem)
{
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
@@ -994,7 +1020,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe
#endif
#endif
-#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || defined(Q_WS_QPA)
static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
{
// look for the requested font in the engine data cache
@@ -1053,8 +1079,10 @@ QT_BEGIN_INCLUDE_NAMESPACE
# include "qfontdatabase_mac.cpp"
#elif defined(Q_WS_WIN)
# include "qfontdatabase_win.cpp"
-#elif defined(Q_WS_QWS) || defined(Q_WS_QPA)
+#elif defined(Q_WS_QWS)
# include "qfontdatabase_qws.cpp"
+#elif defined(Q_WS_QPA)
+# include "qfontdatabase_qpa.cpp"
#elif defined(Q_OS_SYMBIAN)
# include "qfontdatabase_s60.cpp"
#endif
@@ -1340,6 +1368,7 @@ static void match(int script, const QFontDef &request,
styleKey.stretch = request.stretch;
char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
+
FM_DEBUG("QFontDatabase::match\n"
" request:\n"
" family: %s [%s], script: %d\n"
@@ -2485,7 +2514,7 @@ void QFontDatabase::createDatabase()
{ initializeDb(); }
// used from qfontengine_ft.cpp
-QByteArray qt_fontdata_from_index(int index)
+Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)
{
QMutexLocker locker(fontDatabaseMutex());
return privateDb()->applicationFonts.value(index).data;
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 6a09b77712..f31c19ce19 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -167,6 +167,7 @@ private:
friend class QFontEngineMultiXLFD;
friend class QFontEngineMultiQWS;
friend class QFontEngineMultiS60;
+ friend class QFontEngineMultiQPA;
QFontDatabasePrivate *d;
};
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
new file mode 100644
index 0000000000..53594aa6b8
--- /dev/null
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlibraryinfo.h"
+#include <QtCore/qsettings.h>
+
+#include "qfontengine_qpa_p.h"
+#include "qplatformdefs.h"
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/qplatformfontdatabase_qpa.h>
+
+#include <QtCore/qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &foundryname, int weight,
+ QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize,
+ const QSupportedWritingSystems &writingSystems, void *handle)
+{
+ QFontDatabasePrivate *d = privateDb();
+ // qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
+ QtFontStyle::Key styleKey;
+ styleKey.style = style;
+ styleKey.weight = weight;
+ styleKey.stretch = stretch;
+ QtFontFamily *f = d->family(familyName, true);
+
+ for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(i))) {
+ f->writingSystems[i] = QtFontFamily::Supported;
+ } else {
+ f->writingSystems[i] = QtFontFamily::Unsupported;
+ }
+ }
+
+ QtFontFoundry *foundry = f->foundry(foundryname, true);
+ QtFontStyle *fontStyle = foundry->style(styleKey, true);
+ fontStyle->smoothScalable = scalable;
+ fontStyle->antialiased = antialiased;
+ QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
+ size->handle = handle;
+}
+
+static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QUnicodeTables::Script &script)
+{
+ QStringList retList = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,script);
+ QFontDatabasePrivate *db = privateDb();
+
+ QStringList::iterator i;
+ for (i = retList.begin(); i != retList.end(); ++i) {
+ bool contains = false;
+ for (int j = 0; j < db->count; j++) {
+ QtFontFamily *qtFamily = db->families[j];
+ if (!(i->compare(qtFamily->name,Qt::CaseInsensitive))) {
+ contains = true;
+ break;
+ }
+ }
+ if (!contains) {
+ i = retList.erase(i);
+ i--;
+ }
+ }
+ return retList;
+}
+
+static void initializeDb()
+{
+ static int initialized = false;
+
+ if (!initialized) {
+ //init by asking for the platformfontdb for the first time :)
+ QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
+ initialized = true;
+ }
+}
+
+#ifndef QT_NO_SETTINGS
+// called from qapplication_qws.cpp
+void qt_applyFontDatabaseSettings(const QSettings &settings)
+{
+ initializeDb();
+ QFontDatabasePrivate *db = privateDb();
+ for (int i = 0; i < db->count; ++i) {
+ QtFontFamily *family = db->families[i];
+ if (settings.contains(family->name))
+ family->fallbackFamilies = settings.value(family->name).toStringList();
+ }
+
+ if (settings.contains(QLatin1String("Global Fallbacks")))
+ db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
+}
+#endif // QT_NO_SETTINGS
+
+static inline void load(const QString & = QString(), int = -1)
+{
+ initializeDb();
+}
+
+static
+QFontEngine *loadSingleEngine(int script,
+ const QFontDef &request,
+ QtFontFoundry *foundry,
+ QtFontStyle *style, QtFontSize *size)
+{
+ Q_UNUSED(foundry);
+
+ Q_ASSERT(size);
+ int pixelSize = size->pixelSize;
+ if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE))
+ pixelSize = request.pixelSize;
+
+ QFontDef def = request;
+ def.pixelSize = pixelSize;
+
+ QFontCache::Key key(def,script);
+ QFontEngine *engine = QFontCache::instance()->findEngine(key);
+ if (!engine) {
+ QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
+ if (size->handle) {
+ engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle);
+ if (engine) {
+ QFontCache::Key key(def,script);
+ QFontCache::instance()->instance()->insertEngine(key,engine);
+ }
+ }
+
+ }
+ return engine;
+}
+
+static
+QFontEngine *loadEngine(int script, const QFontDef &request,
+ QtFontFamily *family, QtFontFoundry *foundry,
+ QtFontStyle *style, QtFontSize *size)
+{
+
+ QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
+ //make sure that the db has all fallback families
+ if (engine
+ && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
+
+ if (family && !family->askedForFallback) {
+ family->fallbackFamilies = fallbackFamilies(family->name,QFont::Style(style->key.style),QUnicodeTables::Script(script));
+
+ family->askedForFallback = true;
+ }
+
+ QStringList fallbacks = privateDb()->fallbackFamilies;
+ if (family && !family->fallbackFamilies.isEmpty())
+ fallbacks = family->fallbackFamilies;
+
+ engine = new QFontEngineMultiQPA(engine, script, fallbacks);
+ }
+
+ return engine;
+}
+
+static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
+{
+ QFontDatabasePrivate *db = privateDb();
+
+ QApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
+ db->reregisterAppFonts = true;
+}
+
+bool QFontDatabase::removeApplicationFont(int handle)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+
+ QFontDatabasePrivate *db = privateDb();
+ if (handle < 0 || handle >= db->applicationFonts.count())
+ return false;
+
+ db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
+
+ db->reregisterAppFonts = true;
+ db->invalidate();
+ return true;
+}
+
+bool QFontDatabase::removeAllApplicationFonts()
+{
+ QMutexLocker locker(fontDatabaseMutex());
+
+ QFontDatabasePrivate *db = privateDb();
+ if (db->applicationFonts.isEmpty())
+ return false;
+
+ db->applicationFonts.clear();
+ db->invalidate();
+ return true;
+}
+
+bool QFontDatabase::supportsThreadedFontRendering()
+{
+ return true;
+}
+
+/*!
+ \internal
+*/
+QFontEngine *
+QFontDatabase::findFont(int script, const QFontPrivate *fp,
+ const QFontDef &request)
+{
+ QMutexLocker locker(fontDatabaseMutex());
+
+ const int force_encoding_id = -1;
+
+ if (!privateDb()->count)
+ initializeDb();
+
+ QFontEngine *engine;
+ QFontCache::Key key(request, script);
+ engine = QFontCache::instance()->findEngine(key);
+ if (engine) {
+ qDebug() << "Cache hit level 1";
+ return engine;
+ }
+
+ QString family_name, foundry_name;
+
+ parseFontName(request.family, foundry_name, family_name);
+
+ if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
+ engine =new QTestFontEngine(request.pixelSize);
+ engine->fontDef = request;
+ }
+
+ QtFontDesc desc;
+ match(script, request, family_name, foundry_name, force_encoding_id, &desc);
+ if (desc.family != 0 && desc.foundry != 0 && desc.style != 0) {
+ engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
+ } else {
+ FM_DEBUG(" NO MATCH FOUND\n");
+ }
+
+ if (engine) {
+ initFontDef(desc, request, &engine->fontDef);
+
+ if (fp) {
+ QFontDef def = request;
+ if (def.family.isEmpty()) {
+ def.family = fp->request.family;
+ def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
+ }
+ }
+ }
+
+ if (!engine) {
+ if (!request.family.isEmpty()) {
+ QStringList fallbacks = fallbackFamilies(request.family,QFont::Style(request.style),QUnicodeTables::Script(script));
+ for (int i = 0; i < fallbacks.size(); i++) {
+ QFontDef def = request;
+ def.family = fallbacks.at(i);
+ QFontCache::Key key(def,script);
+ engine = QFontCache::instance()->findEngine(key);
+ if (!engine) {
+ QtFontDesc desc;
+ match(script, def, def.family, QLatin1String(""), 0, &desc);
+ if (desc.family == 0 && desc.foundry == 0 && desc.style == 0) {
+ continue;
+ }
+ engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size);
+ if (engine) {
+ initFontDef(desc, def, &engine->fontDef);
+ break;
+ }
+ }
+ }
+ }
+
+ if (!engine)
+ engine = new QFontEngineBox(request.pixelSize);
+
+ FM_DEBUG("returning box engine");
+ }
+
+ if (fp && fp->dpi > 0) {
+ engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi));
+ } else {
+ engine->fontDef.pointSize = request.pointSize;
+ }
+
+ return engine;
+}
+
+void QFontDatabase::load(const QFontPrivate *d, int script)
+{
+ QFontDef req = d->request;
+
+ if (req.pixelSize == -1) {
+ req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
+ req.pixelSize = qRound(req.pixelSize);
+ }
+ if (req.pointSize < 0)
+ req.pointSize = req.pixelSize*72.0/d->dpi;
+ if (req.weight == 0)
+ req.weight = QFont::Normal;
+ if (req.stretch == 0)
+ req.stretch = 100;
+
+ QFontCache::Key key(req, script);
+
+ if (!d->engineData)
+ getEngineData(d, key);
+
+ // the cached engineData could have already loaded the engine we want
+ if (d->engineData->engines[script])
+ return;
+
+ QFontEngine *fe = QFontCache::instance()->findEngine(key);
+
+ // list of families to try
+ QStringList family_list;
+
+ if (!req.family.isEmpty()) {
+ family_list = familyList(req);
+
+ // add the default family
+ QString defaultFamily = QApplication::font().family();
+ if (! family_list.contains(defaultFamily))
+ family_list << defaultFamily;
+
+ }
+
+ // null family means find the first font matching the specified script
+ family_list << QString();
+
+ QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
+ for (; !fe && it != end; ++it) {
+ req.family = *it;
+
+ fe = QFontDatabase::findFont(script, d, req);
+ if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty())
+ fe = 0;
+ }
+
+ if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
+ for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
+ if (!d->engineData->engines[i]) {
+ d->engineData->engines[i] = fe;
+ fe->ref.ref();
+ }
+ }
+ } else {
+ d->engineData->engines[script] = fe;
+ fe->ref.ref();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index fdb86ce004..1c705ae911 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -481,7 +481,7 @@ static void collectSingleContour(qreal x0, qreal y0, uint *grid, int x, int y, i
path->closeSubpath();
}
-void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path)
+Q_GUI_EXPORT void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path)
{
uint *grid = new uint[(w+1)*(h+1)];
// set up edges
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 2c4fbab41a..1ee714444b 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -717,7 +717,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format)
metrics = face->size->metrics;
-#if defined(Q_WS_QWS)
+#if defined(Q_WS_QWS) || defined(Q_WS_QPA)
/*
TrueType fonts with embedded bitmaps may have a bitmap font specific
ascent/descent in the EBLC table. There is no direct public API
@@ -749,6 +749,11 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format)
return true;
}
+void QFontEngineFT::setDefaultHintStyle(HintStyle style)
+{
+ default_hint_style = style;
+}
+
QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph) const
{
Glyph *g = set->getGlyph(glyph);
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 372ad0c8c3..f40ce046e5 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -271,7 +271,7 @@ private:
QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix);
bool loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format = Format_Render);
-#if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
+#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
virtual void draw(QPaintEngine * /*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt & /*si*/) {}
#endif
@@ -282,6 +282,14 @@ private:
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
+ enum HintStyle {
+ HintNone,
+ HintLight,
+ HintMedium,
+ HintFull
+ };
+
+ void setDefaultHintStyle(HintStyle style);
protected:
void freeGlyphSets();
@@ -293,12 +301,6 @@ protected:
QFreetypeFace *freetype;
int default_load_flags;
- enum HintStyle {
- HintNone,
- HintLight,
- HintMedium,
- HintFull
- };
HintStyle default_hint_style;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index fb4556b115..897f76f774 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -168,7 +168,7 @@ public:
virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const {}
virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
-#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
+#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_QPA)
virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si) = 0;
#endif
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
new file mode 100644
index 0000000000..910bbfe62e
--- /dev/null
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -0,0 +1,650 @@
+#include "qfontengine_qpa_p.h"
+
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDir>
+#include <QtCore/QBuffer>
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/QPlatformFontDatabase>
+#include <QtGui/private/qpaintengine_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+//#define DEBUG_HEADER
+//#define DEBUG_FONTENGINE
+
+static QFontEngineQPA::TagType tagTypes[QFontEngineQPA::NumTags] = {
+ QFontEngineQPA::StringType, // FontName
+ QFontEngineQPA::StringType, // FileName
+ QFontEngineQPA::UInt32Type, // FileIndex
+ QFontEngineQPA::UInt32Type, // FontRevision
+ QFontEngineQPA::StringType, // FreeText
+ QFontEngineQPA::FixedType, // Ascent
+ QFontEngineQPA::FixedType, // Descent
+ QFontEngineQPA::FixedType, // Leading
+ QFontEngineQPA::FixedType, // XHeight
+ QFontEngineQPA::FixedType, // AverageCharWidth
+ QFontEngineQPA::FixedType, // MaxCharWidth
+ QFontEngineQPA::FixedType, // LineThickness
+ QFontEngineQPA::FixedType, // MinLeftBearing
+ QFontEngineQPA::FixedType, // MinRightBearing
+ QFontEngineQPA::FixedType, // UnderlinePosition
+ QFontEngineQPA::UInt8Type, // GlyphFormat
+ QFontEngineQPA::UInt8Type, // PixelSize
+ QFontEngineQPA::UInt8Type, // Weight
+ QFontEngineQPA::UInt8Type, // Style
+ QFontEngineQPA::StringType, // EndOfHeader
+ QFontEngineQPA::BitFieldType// WritingSystems
+};
+
+
+#if defined(DEBUG_HEADER)
+# define DEBUG_VERIFY qDebug
+#else
+# define DEBUG_VERIFY if (0) qDebug
+#endif
+
+#define READ_VERIFY(type, variable) \
+ if (tagPtr + sizeof(type) > endPtr) { \
+ DEBUG_VERIFY() << "read verify failed in line" << __LINE__; \
+ return 0; \
+ } \
+ variable = qFromBigEndian<type>(tagPtr); \
+ DEBUG_VERIFY() << "read value" << variable << "of type " #type; \
+ tagPtr += sizeof(type)
+
+template <typename T>
+T readValue(const uchar *&data)
+{
+ T value = qFromBigEndian<T>(data);
+ data += sizeof(T);
+ return value;
+}
+
+#define VERIFY(condition) \
+ if (!(condition)) { \
+ DEBUG_VERIFY() << "condition " #condition " failed in line" << __LINE__; \
+ return 0; \
+ }
+
+#define VERIFY_TAG(condition) \
+ if (!(condition)) { \
+ DEBUG_VERIFY() << "verifying tag condition " #condition " failed in line" << __LINE__ << "with tag" << tag; \
+ return 0; \
+ }
+
+static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr)
+{
+ quint16 tag, length;
+ READ_VERIFY(quint16, tag);
+ READ_VERIFY(quint16, length);
+ if (tag == QFontEngineQPA::Tag_EndOfHeader)
+ return endPtr;
+ if (tag < QFontEngineQPA::NumTags) {
+ switch (tagTypes[tag]) {
+ case QFontEngineQPA::BitFieldType:
+ case QFontEngineQPA::StringType:
+ // can't do anything...
+ break;
+ case QFontEngineQPA::UInt32Type:
+ VERIFY_TAG(length == sizeof(quint32));
+ break;
+ case QFontEngineQPA::FixedType:
+ VERIFY_TAG(length == sizeof(quint32));
+ break;
+ case QFontEngineQPA::UInt8Type:
+ VERIFY_TAG(length == sizeof(quint8));
+ break;
+ }
+#if defined(DEBUG_HEADER)
+ if (length == 1)
+ qDebug() << "tag data" << hex << *tagPtr;
+ else if (length == 4)
+ qDebug() << "tag data" << hex << tagPtr[0] << tagPtr[1] << tagPtr[2] << tagPtr[3];
+#endif
+ }
+ return tagPtr + length;
+}
+
+const QFontEngineQPA::Glyph *QFontEngineQPA::findGlyph(glyph_t g) const
+{
+ if (!g || g >= glyphMapEntries)
+ return 0;
+ const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);
+ quint32 glyphPos = qFromBigEndian<quint32>(gmapPtr[g]);
+ if (glyphPos > glyphDataSize) {
+ if (glyphPos == 0xffffffff)
+ return 0;
+#if defined(DEBUG_FONTENGINE)
+ qDebug() << "glyph" << g << "outside of glyphData, remapping font file";
+#endif
+ if (glyphPos > glyphDataSize)
+ return 0;
+ }
+ return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos);
+}
+
+bool QFontEngineQPA::verifyHeader(const uchar *data, int size)
+{
+ VERIFY(size >= int(sizeof(Header)));
+ const Header *header = reinterpret_cast<const Header *>(data);
+ if (header->magic[0] != 'Q'
+ || header->magic[1] != 'P'
+ || header->magic[2] != 'F'
+ || header->magic[3] != '2')
+ return false;
+
+ VERIFY(header->majorVersion <= CurrentMajorVersion);
+ const quint16 dataSize = qFromBigEndian<quint16>(header->dataSize);
+ VERIFY(size >= int(sizeof(Header)) + dataSize);
+
+ const uchar *tagPtr = data + sizeof(Header);
+ const uchar *tagEndPtr = tagPtr + dataSize;
+ while (tagPtr < tagEndPtr - 3) {
+ tagPtr = verifyTag(tagPtr, tagEndPtr);
+ VERIFY(tagPtr);
+ }
+
+ VERIFY(tagPtr <= tagEndPtr);
+ return true;
+}
+
+QVariant QFontEngineQPA::extractHeaderField(const uchar *data, HeaderTag requestedTag)
+{
+ const Header *header = reinterpret_cast<const Header *>(data);
+ const uchar *tagPtr = data + sizeof(Header);
+ const uchar *endPtr = tagPtr + qFromBigEndian<quint16>(header->dataSize);
+ while (tagPtr < endPtr - 3) {
+ quint16 tag = readValue<quint16>(tagPtr);
+ quint16 length = readValue<quint16>(tagPtr);
+ if (tag == requestedTag) {
+ switch (tagTypes[requestedTag]) {
+ case StringType:
+ return QVariant(QString::fromUtf8(reinterpret_cast<const char *>(tagPtr), length));
+ case UInt32Type:
+ return QVariant(readValue<quint32>(tagPtr));
+ case UInt8Type:
+ return QVariant(uint(*tagPtr));
+ case FixedType:
+ return QVariant(QFixed::fromFixed(readValue<quint32>(tagPtr)).toReal());
+ case BitFieldType:
+ return QVariant(QByteArray(reinterpret_cast<const char *>(tagPtr), length));
+ }
+ return QVariant();
+ } else if (tag == Tag_EndOfHeader) {
+ break;
+ }
+ tagPtr += length;
+ }
+
+ return QVariant();
+}
+
+
+
+static inline unsigned int getChar(const QChar *str, int &i, const int len)
+{
+ unsigned int uc = str[i].unicode();
+ if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) {
+ uint low = str[i+1].unicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ ++i;
+ }
+ }
+ return uc;
+}
+
+QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data)
+ : fontData(reinterpret_cast<const uchar *>(data.constData())), dataSize(data.size())
+{
+ fontDef = def;
+ cache_cost = 100;
+ externalCMap = 0;
+ cmapOffset = 0;
+ cmapSize = 0;
+ glyphMapOffset = 0;
+ glyphMapEntries = 0;
+ glyphDataOffset = 0;
+ glyphDataSize = 0;
+ kerning_pairs_loaded = false;
+ readOnly = true;
+
+#if defined(DEBUG_FONTENGINE)
+ qDebug() << "QFontEngineQPA::QFontEngineQPA( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')';
+#endif
+
+ if (!verifyHeader(fontData, dataSize)) {
+#if defined(DEBUG_FONTENGINE)
+ qDebug() << "verifyHeader failed!";
+#endif
+ return;
+ }
+
+ const Header *header = reinterpret_cast<const Header *>(fontData);
+
+ readOnly = (header->lock == 0xffffffff);
+
+ const uchar *imgData = fontData + sizeof(Header) + qFromBigEndian<quint16>(header->dataSize);
+ const uchar *endPtr = fontData + dataSize;
+ while (imgData <= endPtr - 8) {
+ quint16 blockTag = readValue<quint16>(imgData);
+ imgData += 2; // skip padding
+ quint32 blockSize = readValue<quint32>(imgData);
+
+ if (blockTag == CMapBlock) {
+ cmapOffset = imgData - fontData;
+ cmapSize = blockSize;
+ } else if (blockTag == GMapBlock) {
+ glyphMapOffset = imgData - fontData;
+ glyphMapEntries = blockSize / 4;
+ } else if (blockTag == GlyphBlock) {
+ glyphDataOffset = imgData - fontData;
+ glyphDataSize = blockSize;
+ }
+
+ imgData += blockSize;
+ }
+
+ face_id.filename = QFile::encodeName(extractHeaderField(fontData, Tag_FileName).toString());
+ face_id.index = extractHeaderField(fontData, Tag_FileIndex).toInt();
+
+ // get the real cmap
+ if (cmapOffset) {
+ int tableSize = cmapSize;
+ const uchar *cmapPtr = getCMap(fontData + cmapOffset, tableSize, &symbol, &cmapSize);
+ if (cmapPtr)
+ cmapOffset = cmapPtr - fontData;
+ else
+ cmapOffset = 0;
+ } else if (externalCMap) {
+ int tableSize = cmapSize;
+ externalCMap = getCMap(externalCMap, tableSize, &symbol, &cmapSize);
+ }
+
+ // verify all the positions in the glyphMap
+ if (glyphMapOffset) {
+ const quint32 *gmapPtr = reinterpret_cast<const quint32 *>(fontData + glyphMapOffset);
+ for (uint i = 0; i < glyphMapEntries; ++i) {
+ quint32 glyphDataPos = qFromBigEndian<quint32>(gmapPtr[i]);
+ if (glyphDataPos == 0xffffffff)
+ continue;
+ if (glyphDataPos >= glyphDataSize) {
+ // error
+ glyphMapOffset = 0;
+ glyphMapEntries = 0;
+ break;
+ }
+ }
+ }
+
+#if defined(DEBUG_FONTENGINE)
+ if (!isValid())
+ qDebug() << "fontData" << fontData << "dataSize" << dataSize
+ << "externalCMap" << externalCMap << "cmapOffset" << cmapOffset
+ << "glyphMapOffset" << glyphMapOffset << "glyphDataOffset" << glyphDataOffset
+ << "fd" << fd << "glyphDataSize" << glyphDataSize;
+#endif
+}
+
+QFontEngineQPA::~QFontEngineQPA()
+{
+}
+
+bool QFontEngineQPA::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ Q_UNUSED(tag);
+ Q_UNUSED(buffer);
+ *length = 0;
+ return false;
+}
+
+bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ if (*nglyphs < len) {
+ *nglyphs = len;
+ return false;
+ }
+
+#if defined(DEBUG_FONTENGINE)
+ QSet<QChar> seenGlyphs;
+#endif
+
+ const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset);
+
+ bool mirrored = flags & QTextEngine::RightToLeft;
+ int glyph_pos = 0;
+ if (symbol) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(str, i, len);
+ if (mirrored)
+ uc = QChar::mirroredChar(uc);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+ if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
+ ++glyph_pos;
+ }
+ } else {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(str, i, len);
+ if (mirrored)
+ uc = QChar::mirroredChar(uc);
+ glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
+#if 0 && defined(DEBUG_FONTENGINE)
+ QChar c(uc);
+ if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
+ qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph;
+
+ seenGlyphs.insert(c);
+#endif
+ ++glyph_pos;
+ }
+ }
+
+ *nglyphs = glyph_pos;
+ glyphs->numGlyphs = glyph_pos;
+ recalcAdvances(glyphs, flags);
+ return true;
+}
+
+void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const
+{
+ for (int i = 0; i < glyphs->numGlyphs; ++i) {
+ const Glyph *g = findGlyph(glyphs->glyphs[i]);
+ if (!g) {
+ glyphs->glyphs[i] = 0;
+ continue;
+ }
+ glyphs->advances_x[i] = g->advance;
+ glyphs->advances_y[i] = 0;
+ }
+}
+
+QImage QFontEngineQPA::alphaMapForGlyph(glyph_t g)
+{
+ const Glyph *glyph = findGlyph(g);
+ if (!glyph)
+ return QImage();
+
+ const uchar *bits = ((const uchar *) glyph) + sizeof(Glyph);
+
+ QImage image(bits,glyph->width, glyph->height, glyph->bytesPerLine, QImage::Format_Indexed8);
+
+ return image;
+}
+
+void QFontEngineQPA::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
+{
+ addBitmapFontToPath(x, y, glyphs, path, flags);
+}
+
+glyph_metrics_t QFontEngineQPA::boundingBox(const QGlyphLayout &glyphs)
+{
+ glyph_metrics_t overall;
+ // initialize with line height, we get the same behaviour on all platforms
+ overall.y = -ascent();
+ overall.height = ascent() + descent() + 1;
+
+ QFixed ymax = 0;
+ QFixed xmax = 0;
+ for (int i = 0; i < glyphs.numGlyphs; i++) {
+ const Glyph *g = findGlyph(glyphs.glyphs[i]);
+ if (!g)
+ continue;
+
+ QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
+ QFixed y = overall.yoff + glyphs.offsets[i].y + g->y;
+ overall.x = qMin(overall.x, x);
+ overall.y = qMin(overall.y, y);
+ xmax = qMax(xmax, x + g->width);
+ ymax = qMax(ymax, y + g->height);
+ overall.xoff += g->advance;
+ }
+ overall.height = qMax(overall.height, ymax - overall.y);
+ overall.width = xmax - overall.x;
+
+ return overall;
+}
+
+glyph_metrics_t QFontEngineQPA::boundingBox(glyph_t glyph)
+{
+ glyph_metrics_t overall;
+ const Glyph *g = findGlyph(glyph);
+ if (!g)
+ return overall;
+ overall.x = g->x;
+ overall.y = g->y;
+ overall.width = g->width;
+ overall.height = g->height;
+ overall.xoff = g->advance;
+ return overall;
+}
+
+QFixed QFontEngineQPA::ascent() const
+{
+ return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>());
+}
+
+QFixed QFontEngineQPA::descent() const
+{
+ return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>());
+}
+
+QFixed QFontEngineQPA::leading() const
+{
+ return QFixed::fromReal(extractHeaderField(fontData, Tag_Leading).value<qreal>());
+}
+
+qreal QFontEngineQPA::maxCharWidth() const
+{
+ return extractHeaderField(fontData, Tag_MaxCharWidth).value<qreal>();
+}
+
+qreal QFontEngineQPA::minLeftBearing() const
+{
+ return extractHeaderField(fontData, Tag_MinLeftBearing).value<qreal>();
+}
+
+qreal QFontEngineQPA::minRightBearing() const
+{
+ return extractHeaderField(fontData, Tag_MinRightBearing).value<qreal>();
+}
+
+QFixed QFontEngineQPA::underlinePosition() const
+{
+ return QFixed::fromReal(extractHeaderField(fontData, Tag_UnderlinePosition).value<qreal>());
+}
+
+QFixed QFontEngineQPA::lineThickness() const
+{
+ return QFixed::fromReal(extractHeaderField(fontData, Tag_LineThickness).value<qreal>());
+}
+
+QFontEngine::Type QFontEngineQPA::type() const
+{
+ return QFontEngine::QPF2;
+}
+
+bool QFontEngineQPA::canRender(const QChar *string, int len)
+{
+ const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset);
+
+ if (symbol) {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ glyph_t g = getTrueTypeGlyphIndex(cmap, uc);
+ if(!g && uc < 0x100)
+ g = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
+ if (!g)
+ return false;
+ }
+ } else {
+ for (int i = 0; i < len; ++i) {
+ unsigned int uc = getChar(string, i, len);
+ if (!getTrueTypeGlyphIndex(cmap, uc))
+ return false;
+ }
+ }
+ return true;
+}
+
+bool QFontEngineQPA::isValid() const
+{
+ return fontData && dataSize && (cmapOffset || externalCMap)
+ && glyphMapOffset && glyphDataOffset && glyphDataSize > 0;
+}
+
+void QPAGenerator::generate()
+{
+ writeHeader();
+ writeGMap();
+ writeBlock(QFontEngineQPA::GlyphBlock, QByteArray());
+
+ dev->seek(4); // position of header.lock
+ writeUInt32(0);
+}
+
+void QPAGenerator::writeHeader()
+{
+ QFontEngineQPA::Header header;
+
+ header.magic[0] = 'Q';
+ header.magic[1] = 'P';
+ header.magic[2] = 'F';
+ header.magic[3] = '2';
+ header.lock = 1;
+ header.majorVersion = QFontEngineQPA::CurrentMajorVersion;
+ header.minorVersion = QFontEngineQPA::CurrentMinorVersion;
+ header.dataSize = 0;
+ dev->write((const char *)&header, sizeof(header));
+
+ writeTaggedString(QFontEngineQPA::Tag_FontName, fe->fontDef.family.toUtf8());
+
+ QFontEngine::FaceId face = fe->faceId();
+ writeTaggedString(QFontEngineQPA::Tag_FileName, face.filename);
+ writeTaggedUInt32(QFontEngineQPA::Tag_FileIndex, face.index);
+
+ {
+ uchar data[4];
+ uint len = 4;
+ bool ok = fe->getSfntTableData(MAKE_TAG('h', 'e', 'a', 'd'), data, &len);
+ if (ok) {
+ const quint32 revision = qFromBigEndian<quint32>(data);
+ writeTaggedUInt32(QFontEngineQPA::Tag_FontRevision, revision);
+ }
+ }
+
+ writeTaggedQFixed(QFontEngineQPA::Tag_Ascent, fe->ascent());
+ writeTaggedQFixed(QFontEngineQPA::Tag_Descent, fe->descent());
+ writeTaggedQFixed(QFontEngineQPA::Tag_Leading, fe->leading());
+ writeTaggedQFixed(QFontEngineQPA::Tag_XHeight, fe->xHeight());
+ writeTaggedQFixed(QFontEngineQPA::Tag_AverageCharWidth, fe->averageCharWidth());
+ writeTaggedQFixed(QFontEngineQPA::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth()));
+ writeTaggedQFixed(QFontEngineQPA::Tag_LineThickness, fe->lineThickness());
+ writeTaggedQFixed(QFontEngineQPA::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing()));
+ writeTaggedQFixed(QFontEngineQPA::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing()));
+ writeTaggedQFixed(QFontEngineQPA::Tag_UnderlinePosition, fe->underlinePosition());
+ writeTaggedUInt8(QFontEngineQPA::Tag_PixelSize, fe->fontDef.pixelSize);
+ writeTaggedUInt8(QFontEngineQPA::Tag_Weight, fe->fontDef.weight);
+ writeTaggedUInt8(QFontEngineQPA::Tag_Style, fe->fontDef.style);
+
+ writeTaggedUInt8(QFontEngineQPA::Tag_GlyphFormat, QFontEngineQPA::AlphamapGlyphs);
+
+ writeTaggedString(QFontEngineQPA::Tag_EndOfHeader, QByteArray());
+ align4();
+
+ const quint64 size = dev->pos();
+ header.dataSize = qToBigEndian<quint16>(size - sizeof(header));
+ dev->seek(0);
+ dev->write((const char *)&header, sizeof(header));
+ dev->seek(size);
+}
+
+void QPAGenerator::writeGMap()
+{
+ const quint16 glyphCount = fe->glyphCount();
+
+ writeUInt16(QFontEngineQPA::GMapBlock);
+ writeUInt16(0); // padding
+ writeUInt32(glyphCount * 4);
+
+ QByteArray &buffer = dev->buffer();
+ const int numBytes = glyphCount * sizeof(quint32);
+ qint64 pos = buffer.size();
+ buffer.resize(pos + numBytes);
+ qMemSet(buffer.data() + pos, 0xff, numBytes);
+ dev->seek(pos + numBytes);
+}
+
+void QPAGenerator::writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &data)
+{
+ writeUInt16(tag);
+ writeUInt16(0); // padding
+ const int padSize = ((data.size() + 3) / 4) * 4 - data.size();
+ writeUInt32(data.size() + padSize);
+ dev->write(data);
+ for (int i = 0; i < padSize; ++i)
+ writeUInt8(0);
+}
+
+void QPAGenerator::writeTaggedString(QFontEngineQPA::HeaderTag tag, const QByteArray &string)
+{
+ writeUInt16(tag);
+ writeUInt16(string.length());
+ dev->write(string);
+}
+
+void QPAGenerator::writeTaggedUInt32(QFontEngineQPA::HeaderTag tag, quint32 value)
+{
+ writeUInt16(tag);
+ writeUInt16(sizeof(value));
+ writeUInt32(value);
+}
+
+void QPAGenerator::writeTaggedUInt8(QFontEngineQPA::HeaderTag tag, quint8 value)
+{
+ writeUInt16(tag);
+ writeUInt16(sizeof(value));
+ writeUInt8(value);
+}
+
+void QPAGenerator::writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value)
+{
+ writeUInt16(tag);
+ writeUInt16(sizeof(quint32));
+ writeUInt32(value.value());
+}
+
+
+/*
+ Creates a new multi QPA engine.
+
+ This function takes ownership of the QFontEngine, increasing it's refcount.
+*/
+QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QStringList &fallbacks)
+ : QFontEngineMulti(fallbacks.size() + 1),
+ fallbackFamilies(fallbacks), script(_script)
+{
+ engines[0] = fe;
+ fe->ref.ref();
+ fontDef = engines[0]->fontDef;
+}
+
+void QFontEngineMultiQPA::loadEngine(int at)
+{
+ Q_ASSERT(at < engines.size());
+ Q_ASSERT(engines.at(at) == 0);
+
+ QFontDef request = fontDef;
+ request.styleStrategy |= QFont::NoFontMerging;
+ request.family = fallbackFamilies.at(at-1);
+ engines[at] = QFontDatabase::findFont(script,
+ /*fontprivate*/0,
+ request);
+ Q_ASSERT(engines[at]);
+ engines[at]->ref.ref();
+ engines[at]->fontDef = request;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpa_p.h
new file mode 100644
index 0000000000..467fca617e
--- /dev/null
+++ b/src/gui/text/qfontengine_qpa_p.h
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFONTENGINE_QPA_P_H
+#define QFONTENGINE_QPA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <QtCore/qconfig.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qendian.h>
+#include <QtCore/QBuffer>
+
+#include "qfontengine_p.h"
+
+#include <QtCore/QFile>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QFontEngine;
+class QFreetypeFace;
+class QBuffer;
+
+class Q_GUI_EXPORT QFontEngineQPA : public QFontEngine
+{
+public:
+ // if you add new tags please make sure to update the tables in
+ // qpfutil.cpp and tools/makeqpf/qpf2.cpp
+ enum HeaderTag {
+ Tag_FontName, // 0 string
+ Tag_FileName, // 1 string
+ Tag_FileIndex, // 2 quint32
+ Tag_FontRevision, // 3 quint32
+ Tag_FreeText, // 4 string
+ Tag_Ascent, // 5 QFixed
+ Tag_Descent, // 6 QFixed
+ Tag_Leading, // 7 QFixed
+ Tag_XHeight, // 8 QFixed
+ Tag_AverageCharWidth, // 9 QFixed
+ Tag_MaxCharWidth, // 10 QFixed
+ Tag_LineThickness, // 11 QFixed
+ Tag_MinLeftBearing, // 12 QFixed
+ Tag_MinRightBearing, // 13 QFixed
+ Tag_UnderlinePosition, // 14 QFixed
+ Tag_GlyphFormat, // 15 quint8
+ Tag_PixelSize, // 16 quint8
+ Tag_Weight, // 17 quint8
+ Tag_Style, // 18 quint8
+ Tag_EndOfHeader, // 19 string
+ Tag_WritingSystems, // 20 bitfield
+
+ NumTags
+ };
+
+ enum TagType {
+ StringType,
+ FixedType,
+ UInt8Type,
+ UInt32Type,
+ BitFieldType
+ };
+
+ struct Tag
+ {
+ quint16 tag;
+ quint16 size;
+ };
+
+ enum GlyphFormat {
+ BitmapGlyphs = 1,
+ AlphamapGlyphs = 8
+ };
+
+ enum {
+ CurrentMajorVersion = 2,
+ CurrentMinorVersion = 0
+ };
+
+ // The CMap is identical to the TrueType CMap table format
+ // The GMap table is a normal array with the total number of
+ // covered glyphs in the TrueType font
+ enum BlockTag {
+ CMapBlock,
+ GMapBlock,
+ GlyphBlock
+ };
+
+ struct Q_PACKED Header
+ {
+ char magic[4]; // 'QPF2'
+ quint32 lock; // values: 0 = unlocked, 0xffffffff = read-only, otherwise qws client id of locking process
+ quint8 majorVersion;
+ quint8 minorVersion;
+ quint16 dataSize;
+ };
+
+ struct Q_PACKED Block
+ {
+ quint16 tag;
+ quint16 pad;
+ quint32 dataSize;
+ };
+
+ struct Q_PACKED Glyph
+ {
+ quint8 width;
+ quint8 height;
+ quint8 bytesPerLine;
+ qint8 x;
+ qint8 y;
+ qint8 advance;
+ };
+
+ QFontEngineQPA(const QFontDef &def, const QByteArray &data);
+ ~QFontEngineQPA();
+
+ FaceId faceId() const { return face_id; }
+ bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
+
+ bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
+ void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
+
+ void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags);
+ QImage alphaMapForGlyph(glyph_t t);
+
+ glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
+ glyph_metrics_t boundingBox(glyph_t glyph);
+
+ QFixed ascent() const;
+ QFixed descent() const;
+ QFixed leading() const;
+ qreal maxCharWidth() const;
+ qreal minLeftBearing() const;
+ qreal minRightBearing() const;
+ QFixed underlinePosition() const;
+ QFixed lineThickness() const;
+
+ Type type() const;
+
+ bool canRender(const QChar *string, int len);
+ inline const char *name() const { return "QPF2"; }
+
+ virtual int glyphCount() const { return glyphMapEntries; }
+
+ bool isValid() const;
+
+ const Glyph *findGlyph(glyph_t g) const;
+
+ static bool verifyHeader(const uchar *data, int size);
+ static QVariant extractHeaderField(const uchar *data, HeaderTag tag);
+
+private:
+
+ const uchar *fontData;
+ int dataSize;
+ const uchar *externalCMap;
+ quint32 cmapOffset;
+ int cmapSize;
+ quint32 glyphMapOffset;
+ quint32 glyphMapEntries;
+ quint32 glyphDataOffset;
+ quint32 glyphDataSize;
+ QString internalFileName;
+ QString encodedFileName;
+ bool readOnly;
+
+ FaceId face_id;
+ QByteArray freetypeCMapTable;
+ mutable bool kerning_pairs_loaded;
+};
+
+struct QPAGenerator
+{
+ QPAGenerator(QBuffer *device, QFontEngine *engine)
+ : dev(device), fe(engine) {}
+
+ void generate();
+ void writeHeader();
+ void writeGMap();
+ void writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &data);
+
+ void writeTaggedString(QFontEngineQPA::HeaderTag tag, const QByteArray &string);
+ void writeTaggedUInt32(QFontEngineQPA::HeaderTag tag, quint32 value);
+ void writeTaggedUInt8(QFontEngineQPA::HeaderTag tag, quint8 value);
+ void writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value);
+
+ void writeUInt16(quint16 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
+ void writeUInt32(quint32 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); }
+ void writeUInt8(quint8 value) { dev->write((const char *)&value, sizeof(value)); }
+ void writeInt8(qint8 value) { dev->write((const char *)&value, sizeof(value)); }
+
+ void align4() { while (dev->pos() & 3) { dev->putChar('\0'); } }
+
+ QBuffer *dev;
+ QFontEngine *fe;
+};
+
+class QFontEngineMultiQPA : public QFontEngineMulti
+{
+public:
+ QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks);
+
+ void loadEngine(int at);
+
+private:
+ QStringList fallbackFamilies;
+ int script;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFONTENGINE_QPA_P_H
diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp
new file mode 100644
index 0000000000..7bb1f9a1b5
--- /dev/null
+++ b/src/gui/text/qplatformfontdatabase_qpa.cpp
@@ -0,0 +1,195 @@
+#include "qplatformfontdatabase_qpa.h"
+#include <QtGui/private/qfontengine_p.h>
+#include <QtGui/private/qfontengine_qpa_p.h>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+
+QT_BEGIN_NAMESPACE
+
+extern void qt_registerFont(const QString &familyname, const QString &foundryname, int weight,
+ QFont::Style style, int stretch, bool antialiased,bool scalable, int pixelSize,
+ const QSupportedWritingSystems &writingSystems, void *hanlde);
+
+void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
+{
+ if (dataArray.size() == 0)
+ return;
+
+ const uchar *data = reinterpret_cast<const uchar *>(dataArray.constData());
+ if (QFontEngineQPA::verifyHeader(data, dataArray.size())) {
+ QString fontName = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_FontName).toString();
+ int pixelSize = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_PixelSize).toInt();
+ QVariant weight = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Weight);
+ QVariant style = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Style);
+ QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray();
+
+ if (!fontName.isEmpty() && pixelSize) {
+ int fontWeight = 50;
+ if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt)
+ fontWeight = weight.toInt();
+
+ QFont::Style fontStyle = static_cast<QFont::Style>(style.toInt());
+
+ QSupportedWritingSystems writingSystems;
+ for (int i = 0; i < writingSystemBits.count(); ++i) {
+ uchar currentByte = writingSystemBits.at(i);
+ for (int j = 0; j < 8; ++j) {
+ if (currentByte & 1)
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i * 8 + j));
+ currentByte >>= 1;
+ }
+ }
+
+ registerFont(fontName,QString(),fontWeight,fontStyle,100,true,false,pixelSize,writingSystems,handle);
+ }
+ } else {
+ qDebug() << "header verification of QPF2 font failed. maybe it is corrupt?";
+ }
+}
+
+void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, int weight,
+ QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize,
+ const QSupportedWritingSystems &writingSystems, void *usrPtr)
+{
+ if (scalable)
+ pixelSize = 0;
+ qt_registerFont(familyname,foundryname,weight,style,stretch,antialiased,scalable,pixelSize,writingSystems,usrPtr);
+}
+
+class QWritingSystemsPrivate
+{
+public:
+ QWritingSystemsPrivate()
+ : ref(1)
+ , vector(QFontDatabase::WritingSystemsCount,false)
+ {
+ }
+
+ QWritingSystemsPrivate(const QWritingSystemsPrivate *other)
+ : ref(1)
+ , vector(other->vector)
+ {
+ }
+
+ QAtomicInt ref;
+ QVector<bool> vector;
+};
+
+QSupportedWritingSystems::QSupportedWritingSystems()
+{
+ d = new QWritingSystemsPrivate;
+}
+
+QSupportedWritingSystems::QSupportedWritingSystems(const QSupportedWritingSystems &other)
+{
+ d = other.d;
+ d->ref.ref();
+}
+
+QSupportedWritingSystems &QSupportedWritingSystems::operator=(const QSupportedWritingSystems &other)
+{
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
+ return *this;
+}
+
+QSupportedWritingSystems::~QSupportedWritingSystems()
+{
+ if (!d->ref.deref())
+ delete d;
+}
+
+void QSupportedWritingSystems::detach()
+{
+ if (d->ref != 1) {
+ QWritingSystemsPrivate *newd = new QWritingSystemsPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+void QSupportedWritingSystems::setSupported(QFontDatabase::WritingSystem writingSystem, bool support)
+{
+ detach();
+ d->vector[writingSystem] = support;
+}
+
+bool QSupportedWritingSystems::supported(QFontDatabase::WritingSystem writingSystem) const
+{
+ return d->vector.at(writingSystem);
+}
+
+void QPlatformFontDatabase::populateFontDatabase()
+{
+ QString fontpath = fontDir();
+
+ if(!QFile::exists(fontpath)) {
+ qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qPrintable(fontpath));
+ }
+
+ QDir dir(fontpath);
+ dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
+ dir.refresh();
+ for (int i = 0; i < int(dir.count()); ++i) {
+ const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));
+ QFile file(QString::fromLocal8Bit(fileName));
+ if (file.open(QFile::ReadOnly)) {
+ const QByteArray fileData = file.readAll();
+ QByteArray *fileDataPtr = new QByteArray(fileData);
+ registerQPF2Font(fileData, fileDataPtr);
+ }
+ }
+}
+
+QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
+{
+ Q_UNUSED(script);
+ Q_UNUSED(handle);
+ QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
+ QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
+ qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
+ return engine;
+}
+
+QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ return QStringList();
+}
+
+void QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ Q_UNUSED(fontData);
+ Q_UNUSED(fileName);
+
+ qWarning("This plugin does not support application fonts");
+}
+
+void QPlatformFontDatabase::releaseHandle(void *handle)
+{
+ QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
+ delete fileDataPtr;
+}
+
+QString QPlatformFontDatabase::fontDir() const
+{
+ QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR"));
+ if (fontpath.isEmpty()) {
+#ifndef QT_NO_SETTINGS
+ fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath);
+ fontpath += QLatin1String("/fonts");
+#endif
+ }
+
+ return fontpath;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h
new file mode 100644
index 0000000000..a34033f4a5
--- /dev/null
+++ b/src/gui/text/qplatformfontdatabase_qpa.h
@@ -0,0 +1,65 @@
+#ifndef QPLATFORMFONTDATABASE_QPA_H
+#define QPLATFORMFONTDATABASE_QPA_H
+
+#include <QtCore/qconfig.h>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QList>
+#include <QtGui/QFontDatabase>
+#include <QtGui/private/qfont_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QWritingSystemsPrivate;
+
+class Q_GUI_EXPORT QSupportedWritingSystems
+{
+public:
+
+ QSupportedWritingSystems();
+ QSupportedWritingSystems(const QSupportedWritingSystems &other);
+ QSupportedWritingSystems &operator=(const QSupportedWritingSystems &other);
+ ~QSupportedWritingSystems();
+
+ void setSupported(QFontDatabase::WritingSystem, bool supported = true);
+ bool supported(QFontDatabase::WritingSystem) const;
+
+private:
+ void detach();
+
+ QWritingSystemsPrivate *d;
+
+ friend Q_GUI_EXPORT bool operator==(const QSupportedWritingSystems &, const QSupportedWritingSystems &);
+ friend Q_GUI_EXPORT bool operator!=(const QSupportedWritingSystems &, const QSupportedWritingSystems &);
+};
+
+Q_GUI_EXPORT bool operator==(const QSupportedWritingSystems &, const QSupportedWritingSystems &);
+Q_GUI_EXPORT bool operator!=(const QSupportedWritingSystems &, const QSupportedWritingSystems &);
+
+class QFontRequestPrivate;
+
+class Q_GUI_EXPORT QPlatformFontDatabase
+{
+public:
+ virtual void populateFontDatabase();
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const;
+ virtual void addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ virtual void releaseHandle(void *handle);
+
+ virtual QString fontDir() const;
+
+ //callback
+ static void registerQPF2Font(const QByteArray &dataArray, void *handle);
+ static void registerFont(const QString &familyname, const QString &foundryname, int weight,
+ QFont::Style style, int stetch, bool antialiased, bool scalable, int pixelSize,
+ const QSupportedWritingSystems &writingSystems, void *handle);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPLATFORMFONTDATABASE_QPA_H
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 1040ad81a8..8721d80625 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -25,7 +25,7 @@ HEADERS += \
text/qabstracttextdocumentlayout.h \
text/qtextdocumentlayout_p.h \
text/qtextcursor.h \
- text/qtextcursor_p.h \
+ text/qtextcursor_p.h \
text/qtextdocumentfragment.h \
text/qtextdocumentfragment_p.h \
text/qtextimagehandler_p.h \
@@ -39,7 +39,7 @@ HEADERS += \
text/qzipwriter_p.h \
text/qtextodfwriter_p.h \
text/qstatictext_p.h \
- text/qstatictext.h
+ text/qstatictext.h
SOURCES += \
text/qfont.cpp \
@@ -69,7 +69,7 @@ SOURCES += \
text/qcssparser.cpp \
text/qzip.cpp \
text/qtextodfwriter.cpp \
- text/qstatictext.cpp
+ text/qstatictext.cpp
win32 {
SOURCES += \
@@ -112,15 +112,15 @@ embedded {
qpa {
SOURCES += \
- text/qfont_qws.cpp \
- text/qfontengine_ft.cpp \
- text/qfontengine_qpf.cpp \
- text/qabstractfontengine_qws.cpp
+ text/qfont_qpa.cpp \
+ text/qfontengine_qpa.cpp \
+ text/qplatformfontdatabase_qpa.cpp
+
HEADERS += \
- text/qfontengine_ft_p.h \
- text/qabstractfontengine_qws.h \
- text/qabstractfontengine_p.h
+ text/qplatformfontdatabase_qpa.h
+
DEFINES += QT_NO_FONTCONFIG
+ DEFINES += QT_NO_FREETYPE
}
symbian {
@@ -142,6 +142,7 @@ symbian {
}
}
+!qpa {
contains(QT_CONFIG, freetype) {
SOURCES += \
../3rdparty/freetype/src/base/ftbase.c \
@@ -215,6 +216,7 @@ contains(QT_CONFIG, freetype) {
contains(QT_CONFIG, fontconfig) {
CONFIG += opentype
}
+}#!qpa
DEFINES += QT_NO_OPENTYPE
INCLUDEPATH += ../3rdparty/harfbuzz/src
diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro
index f81ec31158..48128fb90a 100644
--- a/src/plugins/platforms/directfb/directfb.pro
+++ b/src/plugins/platforms/directfb/directfb.pro
@@ -27,5 +27,7 @@ HEADERS = qdirectfbintegration.h \
qdirectfbinput.h \
qdirectfbcursor.h \
qdirectfbwindow.h
+
+include(../fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
index b19a1d9eab..64b98dbd41 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -46,6 +46,8 @@
#include "qdirectfbcursor.h"
#include "qdirectfbwindow.h"
+#include "qgenericunixfontdatabase.h"
+
#include <private/qwindowsurface_raster_p.h>
#include <private/qpixmap_raster_p.h>
@@ -80,6 +82,7 @@ QDirectFbScreen::~QDirectFbScreen()
}
QDirectFbIntegration::QDirectFbIntegration()
+ : mFontDb(new QGenericUnixFontDatabase())
{
const QStringList args = QCoreApplication::arguments();
int argc = args.size();
@@ -133,9 +136,9 @@ QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId w
return new QDirectFbWindowSurface(widget,winId);
}
-QBlittable *QDirectFbIntegration::createBlittable(const QSize &size) const
+QPlatformFontDatabase *QDirectFbIntegration::fontDatabase() const
{
- return new QDirectFbBlitter(size);
+ return mFontDb;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
index 27847e24c0..d2d83676c5 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.h
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -87,14 +87,16 @@ public:
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
- QBlittable *createBlittable(const QSize &size) const;
QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformFontDatabase *fontDatabase() const;
+
private:
QList<QPlatformScreen *> mScreens;
QDirectFbInput *mInput;
QThread *mInputRunner;
+ QPlatformFontDatabase *mFontDb;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro
index 5d1318aa50..7ad8fd985b 100644
--- a/src/plugins/platforms/eglfs/eglfs.pro
+++ b/src/plugins/platforms/eglfs/eglfs.pro
@@ -25,5 +25,7 @@ HEADERS = qeglfsintegration.h \
qeglfswindowsurface.h \
qeglfsscreen.h
+include(../fontdatabases/genericunix/genericunix.pri)
+
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 2b673aec21..07605ec81d 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -48,11 +48,14 @@
#include <QtGui/QPlatformWindowFormat>
#include <QtOpenGL/private/qpixmapdata_gl_p.h>
+#include "qgenericunixfontdatabase.h"
+
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
+ mFontDb(new QGenericUnixFontDatabase())
{
m_primaryScreen = new QEglFSScreen(EGL_DEFAULT_DISPLAY);
@@ -90,4 +93,9 @@ QWindowSurface *QEglFSIntegration::createWindowSurface(QWidget *widget, WId winI
return new QEglFSWindowSurface(m_primaryScreen,widget);
}
+QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index f15b6b2ed3..0342539bb5 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -62,7 +62,10 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformFontDatabase *fontDatabase() const;
+
private:
+ QPlatformFontDatabase *mFontDb;
QList<QPlatformScreen *> mScreens;
QEglFSScreen *m_primaryScreen;
};
diff --git a/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri b/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
new file mode 100644
index 0000000000..21aedba6ed
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/basicunix.pri
@@ -0,0 +1,82 @@
+DEFINES += QT_NO_FONTCONFIG
+HEADERS += \
+ $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
+
+SOURCES += \
+ $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp \
+ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
+
+INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
+
+INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/basicunix
+
+CONFIG += opentype
+
+contains(QT_CONFIG, freetype) {
+ SOURCES += \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbase.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbbox.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftdebug.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftglyph.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftinit.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftmm.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/fttype1.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsynth.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftbitmap.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/bdf/bdf.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cache/ftcache.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cff/cff.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/cid/type1cid.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/gzip/ftgzip.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pcf/pcf.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pfr/pfr.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psaux/psaux.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/pshinter/pshinter.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/psnames/psmodule.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/raster/raster.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/sfnt/sfnt.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/smooth/smooth.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/truetype/truetype.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type1/type1.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/type42/type42.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/winfonts/winfnt.c \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/lzw/ftlzw.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvalid.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvbase.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgdef.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvjstf.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvcommn.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgpos.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvgsub.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/otvalid/otvmod.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afangles.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afglobal.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/aflatin.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afmodule.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afdummy.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afhints.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/afloader.c\
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/autofit/autofit.c
+
+ symbian {
+ SOURCES += \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src/base/ftsystem.c
+ } else {
+ SOURCES += \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix/ftsystem.c
+ INCLUDEPATH += \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/builds/unix
+ }
+
+ INCLUDEPATH += \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/src \
+ $$QT_SOURCE_TREE/src/3rdparty/freetype/include
+
+ DEFINES += FT2_BUILD_LIBRARY FT_CONFIG_OPTION_SYSTEM_ZLIB
+ } else:contains(QT_CONFIG, system-freetype) {
+ # pull in the proper freetype2 include directory
+ include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
+ LIBS_PRIVATE += -lfreetype
+ }
+
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
new file mode 100644
index 0000000000..5b8ca63a9e
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.cpp
@@ -0,0 +1,281 @@
+#include "qbasicunixfontdatabase.h"
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/QPlatformScreen>
+
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+
+#undef QT_NO_FREETYPE
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
+ // Any,
+ { 127, 127 },
+ // Latin,
+ { 0, 127 },
+ // Greek,
+ { 7, 127 },
+ // Cyrillic,
+ { 9, 127 },
+ // Armenian,
+ { 10, 127 },
+ // Hebrew,
+ { 11, 127 },
+ // Arabic,
+ { 13, 127 },
+ // Syriac,
+ { 71, 127 },
+ //Thaana,
+ { 72, 127 },
+ //Devanagari,
+ { 15, 127 },
+ //Bengali,
+ { 16, 127 },
+ //Gurmukhi,
+ { 17, 127 },
+ //Gujarati,
+ { 18, 127 },
+ //Oriya,
+ { 19, 127 },
+ //Tamil,
+ { 20, 127 },
+ //Telugu,
+ { 21, 127 },
+ //Kannada,
+ { 22, 127 },
+ //Malayalam,
+ { 23, 127 },
+ //Sinhala,
+ { 73, 127 },
+ //Thai,
+ { 24, 127 },
+ //Lao,
+ { 25, 127 },
+ //Tibetan,
+ { 70, 127 },
+ //Myanmar,
+ { 74, 127 },
+ // Georgian,
+ { 26, 127 },
+ // Khmer,
+ { 80, 127 },
+ // SimplifiedChinese,
+ { 126, 127 },
+ // TraditionalChinese,
+ { 126, 127 },
+ // Japanese,
+ { 126, 127 },
+ // Korean,
+ { 56, 127 },
+ // Vietnamese,
+ { 0, 127 }, // same as latin1
+ // Other,
+ { 126, 127 },
+ // Ogham,
+ { 78, 127 },
+ // Runic,
+ { 79, 127 },
+ // Nko,
+ { 14, 127 },
+};
+
+static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
+{
+ QSupportedWritingSystems writingSystems;
+ bool hasScript = false;
+
+ int i;
+ for(i = 0; i < QFontDatabase::WritingSystemsCount; i++) {
+ int bit = requiredUnicodeBits[i][0];
+ int index = bit/32;
+ int flag = 1 << (bit&31);
+ if (bit != 126 && unicodeRange[index] & flag) {
+ bit = requiredUnicodeBits[i][1];
+ index = bit/32;
+
+ flag = 1 << (bit&31);
+ if (bit == 127 || unicodeRange[index] & flag) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ hasScript = true;
+ // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
+ }
+ }
+ }
+ if(codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
+ hasScript = true;
+ //qDebug("font %s supports Simplified Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::TraditionalChinese);
+ hasScript = true;
+ //qDebug("font %s supports Traditional Chinese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << JapaneseCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Japanese);
+ hasScript = true;
+ //qDebug("font %s supports Japanese", familyName.latin1());
+ }
+ if(codePageRange[0] & (1 << KoreanCsbBit)) {
+ writingSystems.setSupported(QFontDatabase::Korean);
+ hasScript = true;
+ //qDebug("font %s supports Korean", familyName.latin1());
+ }
+ if (!hasScript)
+ writingSystems.setSupported(QFontDatabase::Symbol);
+
+ return writingSystems;
+}
+
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+void QBasicUnixFontDatabase::populateFontDatabase()
+{
+ QPlatformFontDatabase::populateFontDatabase();
+ QString fontpath = fontDir();
+
+ if(!QFile::exists(fontpath)) {
+ qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
+ qPrintable(fontpath));
+ }
+
+ QDir dir(fontpath);
+ dir.setNameFilters(QStringList() << QLatin1String("*.ttf")
+ << QLatin1String("*.ttc") << QLatin1String("*.pfa")
+ << QLatin1String("*.pfb"));
+ dir.refresh();
+ for (int i = 0; i < int(dir.count()); ++i) {
+ const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
+// qDebug() << "looking at" << file;
+ addTTFile(QByteArray(), file);
+ }
+}
+
+QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr)
+{
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+ engine = new QFontEngineFT(fontDef);
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const
+{
+ Q_UNUSED(family);
+ Q_UNUSED(style);
+ Q_UNUSED(script);
+ return QStringList();
+}
+
+void QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
+{
+ addTTFile(fontData,fileName.toLocal8Bit());
+}
+
+void QBasicUnixFontDatabase::releaseHandle(void *handle)
+{
+ FontFile *file = static_cast<FontFile *>(handle);
+ delete file;
+}
+
+void QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
+{
+ 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.constData(), 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;
+
+ QFont::Style style = QFont::StyleNormal;
+ if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+ style = QFont::StyleItalic;
+
+ if (face->style_flags & FT_STYLE_FLAG_BOLD)
+ weight = QFont::Bold;
+
+ QSupportedWritingSystems 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.setSupported(QFontDatabase::Symbol);
+ break;
+ }
+ }
+
+ 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);
+ }
+
+ QString family = QString::fromAscii(face->family_name);
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = file;
+ fontFile->indexValue = index;
+
+ registerFont(family,"",weight,style,100,true,true,0,writingSystems,fontFile);
+
+ FT_Done_Face(face);
+ ++index;
+ } while (index < numFaces);
+}
diff --git a/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
new file mode 100644
index 0000000000..401a4aa857
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/basicunix/qbasicunixfontdatabase.h
@@ -0,0 +1,26 @@
+#ifndef QBASICUNIXFONTDATABASE_H
+#define QBASICUNIXFONTDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include <QtCore/QByteArray>
+#include <QtCore/QString>
+
+struct FontFile
+{
+ QString fileName;
+ int indexValue;
+};
+
+class QBasicUnixFontDatabase : public QPlatformFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const;
+ void addApplicationFont(const QByteArray &fontData, const QString &fileName);
+ void releaseHandle(void *handle);
+
+ static void addTTFile(const QByteArray &fontData, const QByteArray &file);
+};
+
+#endif // QBASICUNIXFONTDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri b/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
new file mode 100644
index 0000000000..19c74ed089
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/fontconfig.pri
@@ -0,0 +1,12 @@
+include(../basicunix/basicunix.pri)
+
+HEADERS += \
+ $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
+
+SOURCES += \
+ $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+
+INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/fontconfig
+LIBS_PRIVATE += -lfontconfig
+
+
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
new file mode 100644
index 0000000000..562cb2d532
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -0,0 +1,528 @@
+#include "qfontconfigdatabase.h"
+
+#include <QtCore/QList>
+#include <QtGui/private/qfont_p.h>
+
+#include <QtCore/QElapsedTimer>
+
+#include <QtGui/private/qapplication_p.h>
+#include <QtGui/QPlatformScreen>
+
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <QtGui/private/qfontengine_p.h>
+
+
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+
+#include <fontconfig/fontconfig.h>
+
+#define SimplifiedChineseCsbBit 18
+#define TraditionalChineseCsbBit 20
+#define JapaneseCsbBit 17
+#define KoreanCsbBit 21
+
+static inline bool requiresOpenType(int writingSystem)
+{
+ return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
+ || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
+}
+static inline bool scriptRequiresOpenType(int script)
+{
+ return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
+ || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
+}
+
+static int getFCWeight(int fc_weight)
+{
+ int qtweight = QFont::Black;
+ if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_MEDIUM) / 2)
+ qtweight = QFont::Light;
+ else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_DEMIBOLD) / 2)
+ qtweight = QFont::Normal;
+ else if (fc_weight <= (FC_WEIGHT_DEMIBOLD + FC_WEIGHT_BOLD) / 2)
+ qtweight = QFont::DemiBold;
+ else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
+ qtweight = QFont::Bold;
+
+ return qtweight;
+}
+
+static const char *specialLanguages[] = {
+ "en", // Common
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "ko", // Hangul
+ "", // Ogham
+ "", // Runic
+ "km", // Khmer
+ "" // N'Ko
+};
+enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
+
+static const ushort specialChars[] = {
+ 0, // English
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Hangul
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0, // Khmer
+ 0x7ca // N'Ko
+};
+enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
+
+// this could become a list of all languages used for each writing
+// system, instead of using the single most common language.
+static const char *languageForWritingSystem[] = {
+ 0, // Any
+ "en", // Latin
+ "el", // Greek
+ "ru", // Cyrillic
+ "hy", // Armenian
+ "he", // Hebrew
+ "ar", // Arabic
+ "syr", // Syriac
+ "div", // Thaana
+ "hi", // Devanagari
+ "bn", // Bengali
+ "pa", // Gurmukhi
+ "gu", // Gujarati
+ "or", // Oriya
+ "ta", // Tamil
+ "te", // Telugu
+ "kn", // Kannada
+ "ml", // Malayalam
+ "si", // Sinhala
+ "th", // Thai
+ "lo", // Lao
+ "bo", // Tibetan
+ "my", // Myanmar
+ "ka", // Georgian
+ "km", // Khmer
+ "zh-cn", // SimplifiedChinese
+ "zh-tw", // TraditionalChinese
+ "ja", // Japanese
+ "ko", // Korean
+ "vi", // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ 0 // N'Ko
+};
+enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
+
+// Unfortunately FontConfig doesn't know about some languages. We have to test these through the
+// charset. The lists below contain the systems where we need to do this.
+static const ushort sampleCharForWritingSystem[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ 0, // Syriac
+ 0, // Thaana
+ 0, // Devanagari
+ 0, // Bengali
+ 0, // Gurmukhi
+ 0, // Gujarati
+ 0, // Oriya
+ 0, // Tamil
+ 0xc15, // Telugu
+ 0xc95, // Kannada
+ 0xd15, // Malayalam
+ 0xd9a, // Sinhala
+ 0, // Thai
+ 0, // Lao
+ 0, // Tibetan
+ 0x1000, // Myanmar
+ 0, // Georgian
+ 0, // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0x1681, // Ogham
+ 0x16a0, // Runic
+ 0x7ca // N'Ko
+};
+enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
+
+// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
+// open type tables for is directly. Do this so we don't pick some strange
+// pseudo unicode font
+static const char *openType[] = {
+ 0, // Any
+ 0, // Latin
+ 0, // Greek
+ 0, // Cyrillic
+ 0, // Armenian
+ 0, // Hebrew
+ 0, // Arabic
+ "syrc", // Syriac
+ "thaa", // Thaana
+ "deva", // Devanagari
+ "beng", // Bengali
+ "guru", // Gurmukhi
+ "gurj", // Gujarati
+ "orya", // Oriya
+ "taml", // Tamil
+ "telu", // Telugu
+ "knda", // Kannada
+ "mlym", // Malayalam
+ "sinh", // Sinhala
+ 0, // Thai
+ 0, // Lao
+ "tibt", // Tibetan
+ "mymr", // Myanmar
+ 0, // Georgian
+ "khmr", // Khmer
+ 0, // SimplifiedChinese
+ 0, // TraditionalChinese
+ 0, // Japanese
+ 0, // Korean
+ 0, // Vietnamese
+ 0, // Symbol
+ 0, // Ogham
+ 0, // Runic
+ "nko " // N'Ko
+};
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcFontSet *fonts;
+
+ QString familyName;
+ FcChar8 *value = 0;
+ int weight_value;
+ int slant_value;
+ int spacing_value;
+ FcChar8 *file_value;
+ int indexValue;
+ FcChar8 *foundry_value;
+ FcBool scalable;
+ FcBool antialias;
+
+ {
+ FcObjectSet *os = FcObjectSetCreate();
+ FcPattern *pattern = FcPatternCreate();
+ const char *properties [] = {
+ FC_FAMILY, FC_WEIGHT, FC_SLANT,
+ FC_SPACING, FC_FILE, FC_INDEX,
+ FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
+ FC_WIDTH,
+#if FC_VERSION >= 20297
+ FC_CAPABILITY,
+#endif
+ (const char *)0
+ };
+ const char **p = properties;
+ while (*p) {
+ FcObjectSetAdd(os, *p);
+ ++p;
+ }
+ fonts = FcFontList(0, pattern, os);
+ FcObjectSetDestroy(os);
+ FcPatternDestroy(pattern);
+ }
+
+ for (int i = 0; i < fonts->nfont; i++) {
+ if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ familyName = QString::fromUtf8((const char *)value);
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_MEDIUM;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_MEDIUM;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ for (int i = 1; i < LanguageCount; ++i) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[i];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang)
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+ FcCharSet *cs = 0;
+ res = FcPatternGetCharSet(fonts->fonts[i], FC_CHARSET, 0, &cs);
+ if (res == FcResultMatch) {
+ // some languages are not supported by FontConfig, we rather check the
+ // charset to detect these
+ for (int i = 1; i < SampleCharCount; ++i) {
+ if (!sampleCharForWritingSystem[i])
+ continue;
+ if (FcCharSetHasChar(cs, sampleCharForWritingSystem[i]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(i));
+ }
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < LanguageCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ int weight = getFCWeight(weight_value);
+
+ double pixel_size = 0;
+ if (!scalable) {
+ int width = 100;
+ FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
+ FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
+ }
+
+ QPlatformFontDatabase::registerFont(familyName,QLatin1String((const char *)foundry_value),weight,style,100,antialias,scalable,pixel_size,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+ }
+
+ FcFontSetDestroy (fonts);
+
+ struct FcDefaultFont {
+ const char *qtname;
+ const char *rawname;
+ bool fixed;
+ };
+ const FcDefaultFont defaults[] = {
+ { "Serif", "serif", false },
+ { "Sans Serif", "sans-serif", false },
+ { "Monospace", "monospace", true },
+ { 0, 0, false }
+ };
+ const FcDefaultFont *f = defaults;
+ // aliases only make sense for 'common', not for any of the specials
+ QSupportedWritingSystems ws;
+ ws.setSupported(QFontDatabase::Latin);
+
+ while (f->qtname) {
+ registerFont(f->qtname,"",50,QFont::StyleNormal,100,true,true,0,ws,0);
+ registerFont(f->qtname,"",50,QFont::StyleItalic,100,true,true,0,ws,0);
+ registerFont(f->qtname,"",50,QFont::StyleOblique,100,true,true,0,ws,0);
+ ++f;
+ }
+
+ const FcDefaultFont *s = defaults;
+ QFont font("Sans Serif");
+ font.setPointSize(9);
+ QApplication::setFont(font);
+}
+
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QUnicodeTables::Script script, void *usrPtr)
+{
+ QFontDef fontDef = f;
+
+ QFontEngineFT *engine;
+ FontFile *fontfile = static_cast<FontFile *> (usrPtr);
+ QFontEngine::FaceId fid;
+ fid.filename = fontfile->fileName.toLocal8Bit();
+ fid.index = fontfile->indexValue;
+
+ //try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+
+ engine = new QFontEngineFT(fontDef);
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = fontDef.family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+
+ value.u.s = (const FcChar8 *)fid.filename.data();
+ FcPatternAdd(pattern,FC_FILE,value,true);
+
+ value.type = FcTypeInteger;
+ value.u.i = fid.index;
+ FcPatternAdd(pattern,FC_INDEX,value,true);
+
+ QFontEngineFT::HintStyle default_hint_style;
+
+ if (FcConfigSubstitute(0,pattern,FcMatchPattern)) {
+
+ //hinting
+ int hint_style = 0;
+ if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ hint_style = QFontEngineFT::HintFull;
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ default_hint_style = QFontEngineFT::HintNone;
+ break;
+ case FC_HINT_SLIGHT:
+ default_hint_style = QFontEngineFT::HintLight;
+ break;
+ case FC_HINT_MEDIUM:
+ default_hint_style = QFontEngineFT::HintMedium;
+ break;
+ default:
+ default_hint_style = QFontEngineFT::HintFull;
+ break;
+ }
+ }
+
+ engine->setDefaultHintStyle(default_hint_style);
+ if (!engine->init(fid,antialias,format)) {
+ delete engine;
+ engine = 0;
+ return engine;
+ }
+ if (engine->invalid()) {
+ delete engine;
+ engine = 0;
+ } else if (scriptRequiresOpenType(script)) {
+ HB_Face hbFace = engine->harfbuzzFace();
+ if (!hbFace || !hbFace->supported_scripts[script]) {
+ delete engine;
+ engine = 0;
+ }
+ }
+
+ return engine;
+}
+
+QStringList QFontconfigDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const
+{
+ QStringList fallbackFamilies;
+ FcPattern *pattern = FcPatternCreate();
+ if (!pattern)
+ return fallbackFamilies;
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+ int slant_value = FC_SLANT_ROMAN;
+ if (style == QFont::StyleItalic)
+ slant_value = FC_SLANT_ITALIC;
+ else if (style == QFont::StyleOblique)
+ slant_value = FC_SLANT_OBLIQUE;
+ FcPatternAddInteger(pattern, FC_SLANT, slant_value);
+
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
+ Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ FcLangSet *ls = FcLangSetCreate();
+ FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
+ FcPatternAddLangSet(pattern, FC_LANG, ls);
+ FcLangSetDestroy(ls);
+ }
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcConfigSubstitute(0, pattern, FcMatchFont);
+
+ FcResult result = FcResultMatch;
+ FcFontSet *fontSet = FcFontSort(0,pattern,FcFalse,0,&result);
+
+ if (fontSet && result == FcResultMatch)
+ {
+ for (int i = 0; i < fontSet->nfont; i++) {
+ FcChar8 *value = 0;
+ if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
+ continue;
+ // capitalize(value);
+ QString familyName = QString::fromUtf8((const char *)value);
+ if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive)) {
+ fallbackFamilies << familyName;
+ }
+
+ }
+ }
+// qDebug() << "fallbackFamilies for:" << family << fallbackFamilies;
+
+ return fallbackFamilies;
+}
diff --git a/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
new file mode 100644
index 0000000000..5945b6eb80
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/fontconfig/qfontconfigdatabase.h
@@ -0,0 +1,15 @@
+#ifndef QFONTCONFIGDATABASE_H
+#define QFONTCONFIGDATABASE_H
+
+#include <QPlatformFontDatabase>
+#include "qbasicunixfontdatabase.h"
+
+class QFontconfigDatabase : public QBasicUnixFontDatabase
+{
+public:
+ void populateFontDatabase();
+ QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle);
+ QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QUnicodeTables::Script &script) const;
+};
+
+#endif // QFONTCONFIGDATABASE_H
diff --git a/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
new file mode 100644
index 0000000000..dbcfbce384
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/genericunix/genericunix.pri
@@ -0,0 +1,10 @@
+contains(QT_CONFIG, fontconfig) {
+ include(../fontconfig/fontconfig.pri)
+ DEFINES += Q_FONTCONFIGDATABASE
+} else {
+ include(../basicunix/basicunix.pri)
+}
+
+INCLUDEPATH += $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix
+HEADERS += \
+ $$QT_SOURCE_TREE/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
diff --git a/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h b/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
new file mode 100644
index 0000000000..ec083f8155
--- /dev/null
+++ b/src/plugins/platforms/fontdatabases/genericunix/qgenericunixfontdatabase.h
@@ -0,0 +1,12 @@
+#ifndef QGENERICUNIXFONTDATABASE_H
+#define QGENERICUNIXFONTDATABASE_H
+
+#ifdef Q_FONTCONFIGDATABASE
+#include "qfontconfigdatabase.h"
+typedef QFontconfigDatabase QGenericUnixFontDatabase;
+#else
+#include "qbasicunixfontdatabase.h"
+typedef QBasicUnixFontDatabase QGenericUnixFontDatabase;
+#endif //Q_FONTCONFIGDATABASE
+
+#endif // QGENERICUNIXFONTDATABASE_H
diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
index 8d4b6d7c00..216b899fdb 100644
--- a/src/plugins/platforms/linuxfb/linuxfb.pro
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -7,6 +7,7 @@ SOURCES = main.cpp qlinuxfbintegration.cpp
HEADERS = qlinuxfbintegration.h
include(../fb_base/fb_base.pri)
+include(../fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 437af81aa0..aa1d4019a5 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -41,6 +41,7 @@
#include "qlinuxfbintegration.h"
#include "../fb_base/fb_base.h"
+#include "qgenericunixfontdatabase.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#include <qimage.h>
@@ -156,6 +157,7 @@ void QLinuxFbIntegrationPrivate::closeTty()
}
QLinuxFbIntegration::QLinuxFbIntegration()
+ :fontDb(new QGenericUnixFontDatabase())
{
d_ptr = new QLinuxFbIntegrationPrivate();
@@ -799,6 +801,11 @@ QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWidget *widget, WId
return w;
}
+QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
+{
+ return fontDb;
+}
+
QLinuxFbScreen::QLinuxFbScreen(uchar * d, int w,
int h, int lstep, QImage::Format screenFormat) : compositePainter(0)
{
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index dc61df5c8d..a5d7abd49b 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -82,6 +82,8 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformFontDatabase *fontDatabase() const;
+
private:
QLinuxFbScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
@@ -122,6 +124,7 @@ private:
void setPixelFormat(struct fb_var_screeninfo);
void createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo);
void blank(bool on);
+ QPlatformFontDatabase *fontDb;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index b68230c60d..3446e81a31 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -5,7 +5,15 @@ contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl) {
SUBDIRS += minimal
-#this don't work. but leave it for now
-qpa:x11 {
+contains(QT_CONFIG, mitshm) {
SUBDIRS += testlite
}
+
+linux {
+ SUBDIRS += linuxfb
+}
+
+unix {
+ SUBDIRS += vnc \
+ qvfb
+}
diff --git a/src/plugins/platforms/qvfb/qvfb.pro b/src/plugins/platforms/qvfb/qvfb.pro
index a560755ac6..d2b332a6d5 100644
--- a/src/plugins/platforms/qvfb/qvfb.pro
+++ b/src/plugins/platforms/qvfb/qvfb.pro
@@ -7,5 +7,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
SOURCES = main.cpp qvfbintegration.cpp qvfbwindowsurface.cpp
HEADERS = qvfbintegration.h qvfbwindowsurface.h
+include(../fontdatabases/genericunix/genericunix.pri)
+
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.cpp b/src/plugins/platforms/qvfb/qvfbintegration.cpp
index a50763a962..0cc3938d17 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.cpp
+++ b/src/plugins/platforms/qvfb/qvfbintegration.cpp
@@ -62,6 +62,8 @@
#include <QApplication>
#include <QWindowSystemInterface>
+#include "qgenericunixfontdatabase.h"
+
QT_BEGIN_NAMESPACE
@@ -409,6 +411,7 @@ QImage *QVFbScreen::screenImage()
}
QVFbIntegration::QVFbIntegration(const QStringList &paramList)
+ : mFontDb(new QGenericUnixFontDatabase())
{
int displayId = 0;
if (paramList.length() > 0)
@@ -435,6 +438,11 @@ QPlatformWindow *QVFbIntegration::createPlatformWindow(QWidget *widget, WId) con
return new QVFbWindow(mPrimaryScreen, widget);
}
+QPlatformFontDatabase *QVFbIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
QT_END_NAMESPACE
#include "qvfbintegration.moc"
diff --git a/src/plugins/platforms/qvfb/qvfbintegration.h b/src/plugins/platforms/qvfb/qvfbintegration.h
index e46e0dadeb..198a45cb27 100644
--- a/src/plugins/platforms/qvfb/qvfbintegration.h
+++ b/src/plugins/platforms/qvfb/qvfbintegration.h
@@ -84,9 +84,12 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformFontDatabase *fontDatabase() const;
+
private:
QVFbScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
+ QPlatformFontDatabase *mFontDb;
};
diff --git a/src/plugins/platforms/testlite/qtestliteintegration.cpp b/src/plugins/platforms/testlite/qtestliteintegration.cpp
index a8e0fa73df..68e9051118 100644
--- a/src/plugins/platforms/testlite/qtestliteintegration.cpp
+++ b/src/plugins/platforms/testlite/qtestliteintegration.cpp
@@ -49,6 +49,7 @@
#include <QPlatformCursor>
#include "qtestlitewindow.h"
+#include "qgenericunixfontdatabase.h"
#ifndef QT_NO_OPENGL
#include <GL/glx.h>
@@ -84,8 +85,8 @@ public:
QTestLiteIntegration::QTestLiteIntegration(bool useOpenGL)
: mUseOpenGL(useOpenGL)
+ , mFontDb(new QGenericUnixFontDatabase())
{
-
xd = new MyDisplay;
mPrimaryScreen = new QTestLiteScreen();
@@ -136,6 +137,11 @@ QPixmap QTestLiteIntegration::grabWindow(WId window, int x, int y, int width, in
return QPixmap::fromImage(img);
}
+QPlatformFontDatabase *QTestLiteIntegration::fontDatabase() const
+{
+ return mFontDb;
+}
+
bool QTestLiteIntegration::hasOpenGL() const
{
#ifndef QT_NO_OPENGL
diff --git a/src/plugins/platforms/testlite/qtestliteintegration.h b/src/plugins/platforms/testlite/qtestliteintegration.h
index ac10841cbb..8286ef01d8 100644
--- a/src/plugins/platforms/testlite/qtestliteintegration.h
+++ b/src/plugins/platforms/testlite/qtestliteintegration.h
@@ -84,6 +84,8 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ QPlatformFontDatabase *fontDatabase() const;
+
bool hasOpenGL() const;
MyDisplay *xd;
@@ -92,6 +94,7 @@ private:
bool mUseOpenGL;
QTestLiteScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
+ QPlatformFontDatabase *mFontDb;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp
index 1f477dbdb0..1de4b9db54 100644
--- a/src/plugins/platforms/testlite/qtestlitewindow.cpp
+++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp
@@ -622,7 +622,7 @@ void QTestLiteWindow::handleKeyEvent(QEvent::Type type, void *ev)
int qtcode = chars.toUpper()[0]; //Not exactly right...
if (modifiers & Qt::ControlModifier && qtcode < ' ')
qtcode = chars[0] + '@';
- QWindowSystemInterface::handleKeyEvent(widget(), e->time, type, qtcode, modifiers, QString::fromLatin1(chars));
+ QWindowSystemInterface::handleKeyEvent(0, e->time, type, qtcode, modifiers, QString::fromLatin1(chars));
} else {
qWarning() << "unknown X keycode" << hex << e->keycode << keySym;
}
@@ -647,9 +647,9 @@ WId QTestLiteWindow::winId() const
void QTestLiteWindow::setParent(const QPlatformWindow *window)
{
- QPoint point = widget()->mapTo(widget()->nativeParentWidget(),QPoint());
- XReparentWindow(xd->display,x_window,window->winId(),point.x(),point.y());
- XMapWindow(xd->display, x_window);
+ QPoint point = widget()->mapTo(widget()->nativeParentWidget(),QPoint());
+ XReparentWindow(xd->display,x_window,window->winId(),point.x(),point.y());
+ XMapWindow(xd->display, x_window);
}
void QTestLiteWindow::raise()
@@ -1441,7 +1441,7 @@ bool MyDisplay::handleEvent(XEvent *xe)
xw->handleMouseEvent(QEvent::MouseMove, &xe->xbutton);
break;
- case XKeyPress:
+ case XKeyPress:
xw->handleKeyEvent(QEvent::KeyPress, &xe->xkey);
break;
diff --git a/src/plugins/platforms/testlite/testlite.pro b/src/plugins/platforms/testlite/testlite.pro
index 0a5ebb23ae..05bd384a1d 100644
--- a/src/plugins/platforms/testlite/testlite.pro
+++ b/src/plugins/platforms/testlite/testlite.pro
@@ -1,18 +1,29 @@
-TARGET = qtestlitegraphicssystem
-include(../../qpluginbase.pri)
+TARGET = qtestlite
+include(../../qpluginbase.pri)
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-SOURCES = main.cpp qtestliteintegration.cpp qtestlitewindowsurface.cpp qtestlitewindow.cpp
-HEADERS = qtestliteintegration.h qtestlitewindowsurface.h qtestlitewindow.h
+SOURCES = \
+ main.cpp \
+ qtestliteintegration.cpp \
+ qtestlitewindowsurface.cpp \
+ qtestlitewindow.cpp
+
+HEADERS = \
+ qtestliteintegration.h \
+ qtestlitewindowsurface.h \
+ qtestlitewindow.h
+
LIBS += -lX11 -lXext
+include (../fontdatabases/genericunix/genericunix.pri)
+
contains(QT_CONFIG, opengl) {
QT += opengl
HEADERS += qglxintegration.h
SOURCES += qglxintegration.cpp
}
-target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
+target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index 331c16a090..b36ff333c5 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -49,6 +49,7 @@
#include <QtGui/QPainter>
#include <QtCore/QTimer>
+#include "qgenericunixfontdatabase.h"
QVNCScreen::QVNCScreen(QRect screenSize, int screenId)
: QFbScreen::QFbScreen()
@@ -100,7 +101,7 @@ static void usage()
}
QVNCIntegration::QVNCIntegration(const QStringList& paramList)
- : virtualDesktop(false)
+ : virtualDesktop(false), fontDb(new QGenericUnixFontDatabase())
{
int sizeX = defaultWidth();
int sizeY = defaultHeight();
@@ -234,3 +235,8 @@ void QVNCIntegration::moveToScreen(QWidget *window, int screen)
window->platformWindow()->setGeometry(window->geometry()); // this should be unified elsewhere
newScreen->addWindow(static_cast<QFbWindow *>(window->platformWindow()));
}
+
+QPlatformFontDatabase *QVNCIntegration::fontDatabase() const
+{
+ return fontDb;
+}
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index 241993d207..dfc0e6bde9 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -45,6 +45,7 @@
#include "qvnccursor.h"
#include "../fb_base/fb_base.h"
#include <QPlatformIntegration>
+#include "qgenericunixfontdatabase.h"
QT_BEGIN_NAMESPACE
@@ -91,10 +92,13 @@ public:
bool isVirtualDesktop() { return virtualDesktop; }
void moveToScreen(QWidget *window, int screen);
+ QPlatformFontDatabase *fontDatabase() const;
+
private:
QVNCScreen *mPrimaryScreen;
QList<QPlatformScreen *> mScreens;
bool virtualDesktop;
+ QPlatformFontDatabase *fontDb;
};
diff --git a/src/plugins/platforms/vnc/vnc.pro b/src/plugins/platforms/vnc/vnc.pro
index 65824a2613..6c448f5fba 100644
--- a/src/plugins/platforms/vnc/vnc.pro
+++ b/src/plugins/platforms/vnc/vnc.pro
@@ -13,6 +13,7 @@ HEADERS += qvnccursor.h
SOURCES += qvnccursor.cpp
include(../fb_base/fb_base.pri)
+include(../fontdatabases/genericunix/genericunix.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms