summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorSami Lempinen <sami.lempinen@nokia.com>2011-04-28 08:10:57 (GMT)
committerSami Lempinen <sami.lempinen@nokia.com>2011-04-28 08:10:57 (GMT)
commit95de3f34d9dba4cd95f1f3d32b35c4a4d97e70d9 (patch)
tree7be35a9028b5c83b792190fb954127e9f558baf5 /src/gui
parent9d6530b9774de482b0b3a29720f7f756e986f5c7 (diff)
parent8e615d9b07f6146b5cb6b56c4cd2e32376a8b429 (diff)
downloadQt-95de3f34d9dba4cd95f1f3d32b35c4a4d97e70d9.zip
Qt-95de3f34d9dba4cd95f1f3d32b35c4a4d97e70d9.tar.gz
Qt-95de3f34d9dba4cd95f1f3d32b35c4a4d97e70d9.tar.bz2
Merge remote-tracking branch 'qt/4.8'
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/egl/qegl_symbian.cpp11
-rw-r--r--src/gui/embedded/qlock.cpp33
-rw-r--r--src/gui/embedded/qwslock.cpp13
-rw-r--r--src/gui/embedded/qwssignalhandler.cpp16
-rw-r--r--src/gui/gui.pro8
-rw-r--r--src/gui/image/qpixmapcache.cpp4
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp67
-rw-r--r--src/gui/kernel/kernel.pri5
-rw-r--r--src/gui/kernel/qapplication.cpp17
-rw-r--r--src/gui/kernel/qapplication.h6
-rw-r--r--src/gui/kernel/qapplication_qpa.cpp19
-rw-r--r--src/gui/kernel/qapplication_s60.cpp189
-rw-r--r--src/gui/kernel/qapplication_x11.cpp9
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp18
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h5
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp10
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.h4
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.cpp13
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.h11
-rw-r--r--src/gui/kernel/qsessionmanager_qpa.cpp172
-rw-r--r--src/gui/kernel/qt_s60_p.h71
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_s60.cpp2
-rw-r--r--src/gui/kernel/qwidget_x11.cpp40
-rw-r--r--src/gui/painting/qcolormap_qpa.cpp2
-rw-r--r--src/gui/painting/qpaintbuffer.cpp23
-rw-r--r--src/gui/painting/qpainter.cpp76
-rw-r--r--src/gui/painting/qpainter.h2
-rw-r--r--src/gui/painting/qpainter_p.h10
-rw-r--r--src/gui/painting/qpainterpath.cpp4
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp43
-rw-r--r--src/gui/styles/qs60style.cpp55
-rw-r--r--src/gui/styles/qs60style_s60.cpp44
-rw-r--r--src/gui/styles/qstylehelper_p.h1
-rw-r--r--src/gui/text/qfont.cpp26
-rw-r--r--src/gui/text/qfont_win.cpp17
-rw-r--r--src/gui/text/qfontdatabase.cpp27
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp7
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp2
-rw-r--r--src/gui/text/qfontdatabase_win.cpp90
-rw-r--r--src/gui/text/qfontengine.cpp18
-rw-r--r--src/gui/text/qfontengine_coretext.mm316
-rw-r--r--src/gui/text/qfontengine_coretext_p.h27
-rw-r--r--src/gui/text/qfontengine_ft.cpp162
-rw-r--r--src/gui/text/qfontengine_ft_p.h15
-rw-r--r--src/gui/text/qfontengine_mac.mm21
-rw-r--r--src/gui/text/qfontengine_mac_p.h2
-rw-r--r--src/gui/text/qfontengine_p.h5
-rw-r--r--src/gui/text/qfontengine_x11_p.h1
-rw-r--r--src/gui/text/qfontenginedirectwrite.cpp54
-rw-r--r--src/gui/text/qfontenginedirectwrite_p.h11
-rw-r--r--src/gui/text/qfragmentmap_p.h5
-rw-r--r--src/gui/text/qglyphs.cpp97
-rw-r--r--src/gui/text/qglyphs.h19
-rw-r--r--src/gui/text/qglyphs_p.h25
-rw-r--r--src/gui/text/qrawfont.cpp612
-rw-r--r--src/gui/text/qrawfont.h140
-rw-r--r--src/gui/text/qrawfont_ft.cpp189
-rw-r--r--src/gui/text/qrawfont_mac.cpp105
-rw-r--r--src/gui/text/qrawfont_p.h132
-rw-r--r--src/gui/text/qrawfont_win.cpp750
-rw-r--r--src/gui/text/qtextcontrol.cpp19
-rw-r--r--src/gui/text/qtextdocument_p.cpp17
-rw-r--r--src/gui/text/qtextlayout.cpp58
-rw-r--r--src/gui/text/qtextlayout.h5
-rw-r--r--src/gui/text/qtextobject.cpp7
-rw-r--r--src/gui/text/qtextobject.h4
-rw-r--r--src/gui/text/qzip.cpp2
-rw-r--r--src/gui/text/qzipwriter_p.h2
-rw-r--r--src/gui/text/text.pri22
-rw-r--r--src/gui/util/qcompleter.cpp2
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp2
-rw-r--r--src/gui/util/qscroller.cpp24
-rw-r--r--src/gui/util/qscroller_p.h4
-rw-r--r--src/gui/widgets/qlinecontrol.cpp12
75 files changed, 3378 insertions, 682 deletions
diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp
index 6533d11..fabf9d1 100644
--- a/src/gui/egl/qegl_symbian.cpp
+++ b/src/gui/egl/qegl_symbian.cpp
@@ -42,6 +42,7 @@
#include <QtGui/qpaintdevice.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qwidget.h>
+#include <QtGui/private/qapplication_p.h>
#include "qegl_p.h"
#include "qeglcontext_p.h"
@@ -73,10 +74,14 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
return;
int devType = dev->devType();
- if (devType == QInternal::Image)
+ if (devType == QInternal::Image) {
setPixelFormat(static_cast<QImage *>(dev)->format());
- else
- setPixelFormat(QImage::Format_RGB32);
+ } else {
+ QImage::Format format = QImage::Format_RGB32;
+ if (QApplicationPrivate::instance() && QApplicationPrivate::instance()->useTranslucentEGLSurfaces)
+ format = QImage::Format_ARGB32_Premultiplied;
+ setPixelFormat(format);
+ }
}
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
index b169a9b..d429b93 100644
--- a/src/gui/embedded/qlock.cpp
+++ b/src/gui/embedded/qlock.cpp
@@ -82,38 +82,27 @@ QT_END_NAMESPACE
#else // QT_NO_QWS_MULTIPROCESS
+#if defined(Q_OS_DARWIN)
+# define Q_NO_SEMAPHORE
+#endif
+
#include "qwssignalhandler_p.h"
#include <unistd.h>
#include <sys/types.h>
-#if defined(Q_OS_DARWIN)
-# define Q_NO_SEMAPHORE
-# include <sys/stat.h>
-# include <sys/file.h>
-#else // Q_OS_DARWIN
-# include <sys/sem.h>
-# if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) && !defined(QT_LINUXBASE)) \
- || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) \
- || defined(Q_OS_BSDI)
- /* union semun is defined by including <sys/sem.h> */
-# else
-/* according to X/OPEN we have to define it ourselves */
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
- unsigned short *array; /* array for GETALL, SETALL */
-};
-# endif
-#endif // Q_OS_DARWIN
#include <sys/ipc.h>
+#if defined(Q_NO_SEMAPHORE)
+# include <sys/stat.h>
+# include <sys/file.h>
+#else
+# include <sys/sem.h>
+#endif
#include <string.h>
#include <errno.h>
#include <qdebug.h>
-#include <signal.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
-
QT_BEGIN_NAMESPACE
#define MAX_LOCKS 200 // maximum simultaneous read locks
@@ -177,7 +166,7 @@ QLock::QLock(const QString &filename, char id, bool create)
data->id = semget(semkey,0,0);
data->owned = create;
if (create) {
- semun arg; arg.val = 0;
+ qt_semun arg; arg.val = 0;
if (data->id != -1)
semctl(data->id,0,IPC_RMID,arg);
data->id = semget(semkey,1,IPC_CREAT|0600);
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
index 5841841..324d813 100644
--- a/src/gui/embedded/qwslock.cpp
+++ b/src/gui/embedded/qwslock.cpp
@@ -60,21 +60,14 @@
#endif
#include <unistd.h>
+#include <private/qcore_unix_p.h>
+
QT_BEGIN_NAMESPACE
#ifdef QT_NO_SEMAPHORE
#error QWSLock currently requires semaphores
#endif
-#ifndef Q_OS_BSD4
-union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- struct seminfo *__buf;
-};
-#endif
-
QWSLock::QWSLock()
{
semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
@@ -85,7 +78,7 @@ QWSLock::QWSLock()
}
QWSSignalHandler::instance()->addSemaphore(semId);
- semun semval;
+ qt_semun semval;
semval.val = 1;
if (semctl(semId, BackingStore, SETVAL, semval) == -1) {
diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp
index 49b7e94..cc18beb 100644
--- a/src/gui/embedded/qwssignalhandler.cpp
+++ b/src/gui/embedded/qwssignalhandler.cpp
@@ -47,21 +47,13 @@
#ifndef QT_NO_QWS_MULTIPROCESS
# include <sys/ipc.h>
# include <sys/sem.h>
+
+# include <private/qcore_unix_p.h>
#endif
#include <signal.h>
QT_BEGIN_NAMESPACE
-#ifndef Q_OS_BSD4
-union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- struct seminfo *__buf;
-};
-#endif
-
-
class QWSSignalHandlerPrivate : public QWSSignalHandler
{
public:
@@ -106,7 +98,7 @@ void QWSSignalHandler::removeSemaphore(int semno)
{
const int index = semaphores.lastIndexOf(semno);
if (index != -1) {
- semun semval;
+ qt_semun semval;
semval.val = 0;
semctl(semaphores.at(index), 0, IPC_RMID, semval);
semaphores.remove(index);
@@ -121,7 +113,7 @@ void QWSSignalHandler::handleSignal(int signum)
signal(signum, h->oldHandlers[signum]);
#ifndef QT_NO_QWS_MULTIPROCESS
- semun semval;
+ qt_semun semval;
semval.val = 0;
for (int i = 0; i < h->semaphores.size(); ++i)
semctl(h->semaphores.at(i), 0, IPC_RMID, semval);
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index fda76a2..8f72fea 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -55,11 +55,9 @@ DEFINES += Q_INTERNAL_QAPP_SRC
symbian {
TARGET.UID3=0x2001B2DD
- symbian-abld|symbian-sbsv2 {
- # ro-section in gui can exceed default allocated space, so move rw-section a little further
- QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
- QMAKE_LFLAGS.GCCE += -Tdata 0xC00000
- }
+ # ro-section in gui can exceed default allocated space, so move rw-section a little further
+ QMAKE_LFLAGS.ARMCC += --rw-base 0x800000
+ QMAKE_LFLAGS.GCCE += -Tdata 0x800000
}
neon:*-g++* {
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index 41fc6e9..ae772d8 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -91,9 +91,7 @@ QT_BEGIN_NAMESPACE
\sa QCache, QPixmap
*/
-#if defined(Q_OS_SYMBIAN)
-static int cache_limit = 1024; // 1048 KB cache limit for symbian
-#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE)
+#if defined(Q_WS_QWS) || defined(Q_WS_WINCE)
static int cache_limit = 2048; // 2048 KB cache limit for embedded
#else
static int cache_limit = 10240; // 10 MB cache limit for desktop
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 3b5290c..06dc25c 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -77,6 +77,15 @@ QT_BEGIN_NAMESPACE
Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
{
S60->partial_keyboard = enable;
+
+ QInputContext *ic = 0;
+ if (QApplication::focusWidget()) {
+ ic = QApplication::focusWidget()->inputContext();
+ } else if (qApp && qApp->inputContext()) {
+ ic = qApp->inputContext();
+ }
+ if (ic)
+ ic->update();
}
QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
@@ -108,7 +117,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState->SetDefaultCase( EAknEditorTextCase );
m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
- m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
+ m_fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
}
QCoeFepInputContext::~QCoeFepInputContext()
@@ -231,7 +240,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
// It ignores the mouse event, so we need to commit and send a selection event (which will get triggered
// after the commit)
if (!m_preeditString.isEmpty()) {
- commitCurrentString(false);
+ commitCurrentString(true);
int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt();
@@ -246,9 +255,13 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
// fall through intended
case QEvent::KeyRelease:
const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ //If proxy exists, always use hints from proxy.
+ QWidget *proxy = focusWidget()->focusProxy();
+ Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints();
+
switch (keyEvent->key()) {
case Qt::Key_F20:
- Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints());
+ Q_ASSERT(m_lastImHints == currentHints);
if (m_lastImHints & Qt::ImhHiddenText) {
// Special case in Symbian. On editors with secret text, F20 is for some reason
// considered to be a backspace.
@@ -278,7 +291,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
}
if (keyEvent->type() == QEvent::KeyPress
- && focusWidget()->inputMethodHints() & Qt::ImhHiddenText
+ && currentHints & Qt::ImhHiddenText
&& !keyEvent->text().isEmpty()) {
// Send some temporary preedit text in order to make text visible for a moment.
m_preeditString = keyEvent->text();
@@ -410,12 +423,14 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
windowToMove->setUpdatesEnabled(false);
if (!alwaysResize) {
- if (gv->scene() && gv->scene()->focusItem()) {
- // Check if the widget contains cursorPositionChanged signal and disconnect from it.
- QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
- if (index != -1)
- disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ if (gv->scene()) {
+ if (gv->scene()->focusItem()) {
+ // Check if the widget contains cursorPositionChanged signal and disconnect from it.
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1)
+ disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ }
QGraphicsItem *rootItem = 0;
foreach (QGraphicsItem *item, gv->scene()->items()) {
@@ -529,28 +544,32 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
// and greatly reduces event passing in orientation switch cases,
// as the statuspane size is not changing.
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(false);
+
if (!(windowToMove->windowState() & Qt::WindowFullScreen)) {
windowToMove->setWindowState(
(windowToMove->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowFullScreen);
}
if (alwaysResize) {
- windowToMove->setUpdatesEnabled(false);
- if (!moveWithinVisibleArea)
+ if (!moveWithinVisibleArea) {
m_splitViewResizeBy = widget->height();
-
- windowTop = widget->geometry().top();
- widget->resize(widget->width(), splitViewRect.height() - windowTop);
+ windowTop = widget->geometry().top();
+ widget->resize(widget->width(), splitViewRect.height() - windowTop);
+ }
if (gv->scene()) {
const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
gv->ensureVisible(microFocusRect);
}
- windowToMove->setUpdatesEnabled(true);
} else {
translateInputWidget();
}
+ if (alwaysResize)
+ windowToMove->setUpdatesEnabled(true);
+
widget->setAttribute(Qt::WA_Resized, userResize); //not a user resize
}
@@ -573,7 +592,21 @@ void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities)
{
QWidget *w = focusWidget();
if (w) {
- Qt::InputMethodHints hints = w->inputMethodHints();
+ QWidget *proxy = w->focusProxy();
+ Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints();
+
+ // Since splitview support works like an input method hint, yet it is private flag,
+ // we need to update its state separately.
+ if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
+ TInt currentFlags = m_fepState->Flags();
+ if (S60->partial_keyboard)
+ currentFlags |= QT_EAknEditorFlagEnablePartialScreen;
+ else
+ currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen;
+ if (currentFlags != m_fepState->Flags())
+ m_fepState->SetFlags(currentFlags);
+ }
+
if (hints != m_lastImHints) {
m_lastImHints = hints;
applyHints(hints);
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 32fa3d3..3c57368 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -108,6 +108,8 @@ win32 {
}
symbian {
+ exists($${EPOCROOT}epoc32/include/platform/mw/akntranseffect.h): DEFINES += QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
+
SOURCES += \
kernel/qapplication_s60.cpp \
kernel/qeventdispatcher_s60.cpp \
@@ -248,7 +250,8 @@ qpa {
kernel/qplatformglcontext_qpa.cpp \
kernel/qplatformcursor_qpa.cpp \
kernel/qplatformclipboard_qpa.cpp \
- kernel/qplatformnativeinterface_qpa.cpp
+ kernel/qplatformnativeinterface_qpa.cpp \
+ kernel/qsessionmanager_qpa.cpp
contains(QT_CONFIG, glib) {
SOURCES += \
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index e91fe04..4096bf3 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -128,6 +128,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
//#define ALIEN_DEBUG
+#if defined(Q_OS_SYMBIAN)
+#include "qt_s60_p.h"
+#endif
+
static void initResources()
{
#if defined(Q_WS_WINCE)
@@ -2438,6 +2442,11 @@ bool QApplication::event(QEvent *e)
{
Q_D(QApplication);
if(e->type() == QEvent::Close) {
+#if defined(Q_OS_SYMBIAN)
+ // In order to have proper application-exit effects on Symbian, certain
+ // native APIs have to be called _before_ closing/destroying the widgets.
+ bool effectStarted = qt_beginFullScreenEffect();
+#endif
QCloseEvent *ce = static_cast<QCloseEvent*>(e);
ce->accept();
closeAllWindows();
@@ -2451,8 +2460,14 @@ bool QApplication::event(QEvent *e)
break;
}
}
- if(ce->isAccepted())
+ if (ce->isAccepted()) {
return true;
+ } else {
+#if defined(Q_OS_SYMBIAN)
+ if (effectStarted)
+ qt_abortFullScreenEffect();
+#endif
+ }
} else if(e->type() == QEvent::LanguageChange) {
#ifndef QT_NO_TRANSLATION
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index aa62518..fb61d36 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -79,6 +79,8 @@ template <typename T> class QList;
class QLocale;
#if defined(Q_WS_QWS)
class QDecoration;
+#elif defined(Q_WS_QPA)
+class QPlatformNativeInterface;
#endif
#if defined(Q_OS_SYMBIAN)
class QSymbianEvent;
@@ -254,6 +256,10 @@ public:
#endif
#endif
+#if defined(Q_WS_QPA)
+ static QPlatformNativeInterface *platformNativeInterface();
+#endif
+
#if defined(Q_WS_WIN)
void winFocus(QWidget *, bool);
diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp
index cb5439c..b754cf7 100644
--- a/src/gui/kernel/qapplication_qpa.cpp
+++ b/src/gui/kernel/qapplication_qpa.cpp
@@ -444,6 +444,12 @@ void QApplication::alert(QWidget *, int)
{
}
+QPlatformNativeInterface *QApplication::platformNativeInterface()
+{
+ QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
+ return pi->nativeInterface();
+}
+
static void init_platform(const QString &name, const QString &platformPluginPath)
{
QApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
@@ -514,7 +520,14 @@ void qt_init(QApplicationPrivate *priv, int type)
QList<QByteArray> pluginList;
QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
- QString platformName = QLatin1String(qgetenv("QT_QPA_PLATFORM"));
+ QByteArray platformName;
+#ifdef QT_QPA_DEFAULT_PLATFORM_NAME
+ platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
+#endif
+ QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
+ if (!platformNameEnv.isEmpty()) {
+ platformName = platformNameEnv;
+ }
// Get command line params
@@ -533,7 +546,7 @@ void qt_init(QApplicationPrivate *priv, int type)
platformPluginPath = QLatin1String(argv[i]);
} else if (arg == "-platform") {
if (++i < argc)
- platformName = QLatin1String(argv[i]);
+ platformName = argv[i];
} else if (arg == "-plugin") {
if (++i < argc)
pluginList << argv[i];
@@ -554,7 +567,7 @@ void qt_init(QApplicationPrivate *priv, int type)
}
#endif
- init_platform(platformName, platformPluginPath);
+ init_platform(QLatin1String(platformName), platformPluginPath);
init_plugins(pluginList);
QColormap::initialize();
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 937f485..2221500 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -215,6 +215,12 @@ void QS60Data::controlVisibilityChanged(CCoeControl *control, bool visible)
widget->repaint();
}
} else {
+ // In certain special scenarios we may get an ENotVisible event
+ // without a previous EPartiallyVisible. The backingstore must
+ // still be destroyed, hence the registerWidget() call below.
+ if (backingStore.data() && widget->internalWinId()
+ && qt_widget_private(widget)->maybeBackingStore() == backingStore.data())
+ backingStore.registerWidget(widget);
backingStore.unregisterWidget(widget);
// In order to ensure that any resources used by the window surface
// are immediately freed, we flush the WSERV command buffer.
@@ -459,6 +465,7 @@ QSymbianControl::QSymbianControl(QWidget *w)
, m_ignoreFocusChanged(0)
, m_symbianPopupIsOpen(0)
, m_inExternalScreenOverride(false)
+ , m_lastStatusPaneVisibility(0)
{
}
@@ -545,11 +552,52 @@ void QSymbianControl::setWidget(QWidget *w)
{
qwidget = w;
}
+
+QPoint QSymbianControl::translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const
+{
+ QPoint pos(pointerEventPos.iX, pointerEventPos.iY);
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QSize wsize = qwidget->size();
+ TSize size = Size();
+ if (size.iWidth == wsize.height() && size.iHeight == wsize.width()) {
+ qreal x = pos.x();
+ qreal y = pos.y();
+ pos.setX(size.iHeight - y);
+ pos.setY(x);
+ }
+ }
+ return pos;
+}
+
+TRect QSymbianControl::translateRectForFixedNativeOrientation(const TRect &controlRect) const
+{
+ TRect rect = controlRect;
+ if (qwidget->d_func()->fixNativeOrientationCalled) {
+ QPoint a = translatePointForFixedNativeOrientation(rect.iTl);
+ QPoint b = translatePointForFixedNativeOrientation(rect.iBr);
+ if (a.x() < b.x()) {
+ rect.iTl.iX = a.x();
+ rect.iBr.iX = b.x();
+ } else {
+ rect.iTl.iX = b.x();
+ rect.iBr.iX = a.x();
+ }
+ if (a.y() < b.y()) {
+ rect.iTl.iY = a.y();
+ rect.iBr.iY = b.y();
+ } else {
+ rect.iTl.iY = b.y();
+ rect.iBr.iY = a.y();
+ }
+ }
+ return rect;
+}
+
void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation )
{
QWidget *alienWidget;
- QPoint widgetPos = QPoint(aPenEventLocation.iX, aPenEventLocation.iY);
- QPoint globalPos = QPoint(aPenEventScreenLocation.iX,aPenEventScreenLocation.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(aPenEventLocation);
+ QPoint globalPos = translatePointForFixedNativeOrientation(aPenEventScreenLocation);
alienWidget = qwidget->childAt(widgetPos);
if (!alienWidget)
alienWidget = qwidget;
@@ -564,7 +612,7 @@ void QSymbianControl::HandleLongTapEventL( const TPoint& aPenEventLocation, cons
void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent *event)
{
QApplicationPrivate *d = QApplicationPrivate::instance();
- QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
+ QPointF screenPos = qwidget->mapToGlobal(translatePointForFixedNativeOrientation(event->iPosition));
qreal pressure;
if(d->pressureSupported
&& event->Pressure() > 0) //workaround for misconfigured HAL
@@ -665,7 +713,7 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
mapS60MouseEventTypeToQt(&type, &button, &pEvent);
Qt::KeyboardModifiers modifiers = mapToQtModifiers(pEvent.iModifiers);
- QPoint widgetPos = QPoint(pEvent.iPosition.iX, pEvent.iPosition.iY);
+ QPoint widgetPos = translatePointForFixedNativeOrientation(pEvent.iPosition);
TPoint controlScreenPos = PositionRelativeToScreen();
QPoint globalPos = QPoint(controlScreenPos.iX, controlScreenPos.iY) + widgetPos;
S60->lastCursorPos = globalPos;
@@ -1131,6 +1179,9 @@ void QSymbianControl::Draw(const TRect& controlRect) const
Q_ASSERT(window);
QTLWExtra *topExtra = window->d_func()->maybeTopData();
Q_ASSERT(topExtra);
+
+ TRect wcontrolRect = translateRectForFixedNativeOrientation(controlRect);
+
if (!topExtra->inExpose) {
topExtra->inExpose = true;
if (!qwidget->isWindow()) {
@@ -1141,7 +1192,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
gc.SetBrushColor(TRgb(0, 0, 0, 0));
gc.Clear(controlRect);
}
- QRect exposeRect = qt_TRect2QRect(controlRect);
+ QRect exposeRect = qt_TRect2QRect(wcontrolRect);
qwidget->d_func()->syncBackingStore(exposeRect);
topExtra->inExpose = false;
}
@@ -1154,7 +1205,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
const bool sendNativePaintEvents = qwidget->d_func()->extraData()->receiveNativePaintEvents;
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
QMetaObject::invokeMethod(qwidget, "beginNativePaintEvent", Qt::DirectConnection, Q_ARG(QRect, r));
}
@@ -1209,7 +1260,7 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
if (sendNativePaintEvents) {
- const QRect r = qt_TRect2QRect(controlRect);
+ const QRect r = qt_TRect2QRect(wcontrolRect);
// The draw ops aren't actually sent to WSERV until the graphics
// context is deactivated, which happens in the function calling
// this one. We therefore delay the delivery of endNativePaintEvent,
@@ -1222,14 +1273,45 @@ void QSymbianControl::Draw(const TRect& controlRect) const
}
}
+void QSymbianControl::qwidgetResize_helper(const QSize &newSize)
+{
+ QRect cr = qwidget->geometry();
+ QSize oldSize(cr.size());
+ cr.setSize(newSize);
+ qwidget->data->crect = cr;
+ if (qwidget->isVisible()) {
+ QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
+ bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = true;
+ QResizeEvent e(newSize, oldSize);
+ qt_sendSpontaneousEvent(qwidget, &e);
+ if (!qwidget->testAttribute(Qt::WA_StaticContents))
+ qwidget->d_func()->syncBackingStore();
+ if (!slowResize && tlwExtra)
+ tlwExtra->inTopLevelResize = false;
+ } else {
+ if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
+ QResizeEvent *e = new QResizeEvent(newSize, oldSize);
+ QApplication::postEvent(qwidget, e);
+ }
+ }
+}
+
void QSymbianControl::SizeChanged()
{
CCoeControl::SizeChanged();
+ // When FixNativeOrientation had been called, the RWindow/CCoeControl size
+ // and the surface/QWidget size have nothing to do with each other.
+ if (qwidget->d_func()->fixNativeOrientationCalled)
+ return;
+
QSize oldSize = qwidget->size();
QSize newSize(Size().iWidth, Size().iHeight);
if (oldSize != newSize) {
+ // Enforce the proper size for fullscreen widgets on the secondary screen.
const bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
const int screenNumber = S60->screenNumberForWidget(qwidget);
if (!m_inExternalScreenOverride && isFullscreen && screenNumber > 0) {
@@ -1242,26 +1324,8 @@ void QSymbianControl::SizeChanged()
return;
}
}
- QRect cr = qwidget->geometry();
- cr.setSize(newSize);
- qwidget->data->crect = cr;
- if (qwidget->isVisible()) {
- QTLWExtra *tlwExtra = qwidget->d_func()->maybeTopData();
- bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = true;
- QResizeEvent e(newSize, oldSize);
- qt_sendSpontaneousEvent(qwidget, &e);
- if (!qwidget->testAttribute(Qt::WA_StaticContents))
- qwidget->d_func()->syncBackingStore();
- if (!slowResize && tlwExtra)
- tlwExtra->inTopLevelResize = false;
- } else {
- if (!qwidget->testAttribute(Qt::WA_PendingResizeEvent)) {
- QResizeEvent *e = new QResizeEvent(newSize, oldSize);
- QApplication::postEvent(qwidget, e);
- }
- }
+
+ qwidgetResize_helper(newSize);
}
m_inExternalScreenOverride = false;
@@ -1427,7 +1491,13 @@ void QSymbianControl::HandleResourceChange(int resourceType)
}
break;
case KInternalStatusPaneChange:
- handleClientAreaChange();
+ // When status pane is not visible, only handle client area change if status pane was
+ // previously visible, as size changes to hidden status pane should not affect
+ // client area.
+ if (S60->statusPane() && (S60->statusPane()->IsVisible() || m_lastStatusPaneVisibility)) {
+ m_lastStatusPaneVisibility = S60->statusPane()->IsVisible();
+ handleClientAreaChange();
+ }
if (IsFocused() && IsVisible()) {
qwidget->d_func()->setWindowIcon_sys(true);
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
@@ -1441,8 +1511,10 @@ void QSymbianControl::HandleResourceChange(int resourceType)
{
handleClientAreaChange();
// Send resize event to trigger desktopwidget workAreaResized signal
- QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
- QApplication::sendEvent(qt_desktopWidget, &e);
+ if (qt_desktopWidget) {
+ QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
+ QApplication::sendEvent(qt_desktopWidget, &e);
+ }
break;
}
#endif
@@ -1504,29 +1576,49 @@ bool QSymbianControl::isControlActive()
void QSymbianControl::ensureFixNativeOrientation()
{
#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION)
- // Call FixNativeOrientation() for fullscreen QDeclarativeViews that
- // have a locked orientation matching the native orientation of the device.
- // This avoids unnecessary window rotation on wserv level.
- if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop
- || !qwidget->inherits("QDeclarativeView")
- || S60->screenNumberForWidget(qwidget) > 0)
+ if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop)
+ return;
+ if (S60->screenNumberForWidget(qwidget) > 0)
return;
- const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled;
- const bool matchesNative = qwidget->testAttribute(
- S60->nativeOrientationIsPortrait ? Qt::WA_LockPortraitOrientation
- : Qt::WA_LockLandscapeOrientation);
- if (isFullScreen && matchesNative) {
- if (!isFixed) {
- Window().FixNativeOrientation();
- qwidget->d_func()->fixNativeOrientationCalled = true;
+ const bool isFixEnabled = qwidget->testAttribute(Qt::WA_SymbianNoSystemRotation);
+ const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen);
+ if (isFullScreen && isFixEnabled) {
+ const bool surfaceBasedGs =
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
+ || QApplicationPrivate::graphics_system_name == QLatin1String("opengl");
+ if (!surfaceBasedGs)
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ if (!isFixed && surfaceBasedGs) {
+ if (Window().FixNativeOrientation() == KErrNone) {
+ qwidget->d_func()->fixNativeOrientationCalled = true;
+ // The EGL window surface is now fixed to the native orientation
+ // of the device, no matter what size we pass when creating it.
+ // Enforce the same size for the QWidget too. For the underlying
+ // CCoeControl and RWindow it is up to the system to resize them
+ // when the standard auto-rotation mechanism is in use, we must not
+ // change that behavior by forcing any size for those. In practice
+ // this means that the QWidget and the underlying native control
+ // dimensions will be out of sync when FixNativeOrientation was
+ // called and the device is turned to the non-native (typically
+ // landscape) orientation. The pointer event handling and certain
+ // functions like Draw() will need to compensate for this.
+ QSize newSize(S60->nativeScreenWidthInPixels, S60->nativeScreenHeightInPixels);
+ if (qwidget->size() != newSize)
+ qwidgetResize_helper(newSize);
+ } else {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ }
}
} else if (isFixed) {
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
qwidget->d_func()->fixNativeOrientationCalled = false;
qwidget->hide();
qwidget->d_func()->create_sys(0, false, true);
qwidget->show();
}
+#else
+ qwidget->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
#endif
}
@@ -1738,9 +1830,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
systemFont.setFamily(systemFont.defaultFamily());
QApplicationPrivate::setSystemFont(systemFont);
-#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
QObject::connect(qApp, SIGNAL(aboutToQuit()), qApp, SLOT(_q_aboutToQuit()));
-#endif
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
@@ -1765,6 +1855,8 @@ void qt_init(QApplicationPrivate * /* priv */, int)
} else {
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
}
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
+ QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
#else
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
#endif
@@ -1836,6 +1928,9 @@ void qt_cleanup()
S60->setButtonGroupContainer(0);
#endif
+ // Call EndFullScreen() to prevent confusing the system effect state machine.
+ qt_endFullScreenEffect();
+
if (S60->qtOwnsS60Environment) {
// Restore the S60 framework trap handler. See qt_init().
User::SetTrapHandler(S60->s60InstalledTrapHandler);
@@ -2581,6 +2676,8 @@ void QApplication::restoreOverrideCursor()
void QApplicationPrivate::_q_aboutToQuit()
{
+ qt_beginFullScreenEffect();
+
#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
// Send the shutdown tfx command
S60->wsSession().SendEffectCommand(ETfxCmdAppShutDown);
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 31f70c7..20542ea 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -2281,6 +2281,13 @@ void qt_init(QApplicationPrivate *priv, int,
// Attempt to determine the current running X11 Desktop Enviornment
// Use dbus if/when we can, but fall back to using windowManagerName() for now
+#ifndef QT_NO_XFIXES
+ if (X11->ptrXFixesSelectSelectionInput)
+ X11->ptrXFixesSelectSelectionInput(X11->display, QX11Info::appRootWindow(), ATOM(_NET_WM_CM_S0),
+ XFixesSetSelectionOwnerNotifyMask
+ | XFixesSelectionWindowDestroyNotifyMask
+ | XFixesSelectionClientCloseNotifyMask);
+#endif // QT_NO_XFIXES
X11->compositingManagerRunning = XGetSelectionOwner(X11->display,
ATOM(_NET_WM_CM_S0));
X11->desktopEnvironment = DE_UNKNOWN;
@@ -3216,6 +3223,8 @@ int QApplication::x11ProcessEvent(XEvent* event)
XFixesSelectionNotifyEvent *req =
reinterpret_cast<XFixesSelectionNotifyEvent *>(event);
X11->time = req->selection_timestamp;
+ if (req->selection == ATOM(_NET_WM_CM_S0))
+ X11->compositingManagerRunning = req->owner;
}
#endif
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
index 86740e8..1810532 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ b/src/gui/kernel/qplatformglcontext_qpa.cpp
@@ -125,24 +125,6 @@ QPlatformGLContext::~QPlatformGLContext()
}
-
-/*!
- Makes it possible to set the context which can be the default for making new contexts.
-*/
-void QPlatformGLContext::setDefaultSharedContext(QPlatformGLContext *sharedContext)
-{
- QPlatformGLContextPrivate::staticSharedContext = sharedContext;
-}
-
-/*!
- Default shared context is intended to be a globally awailable pointer to a context which can
- be used for sharing resources when creating new contexts. Its default value is 0;
-*/
-QPlatformGLContext *QPlatformGLContext::defaultSharedContext()
-{
- return QPlatformGLContextPrivate::staticSharedContext;
-}
-
/*!
Reimplement in subclass to do makeCurrent on native GL context
*/
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
index a680c85..28923a9 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ b/src/gui/kernel/qplatformglcontext_qpa.h
@@ -69,13 +69,10 @@ public:
virtual QPlatformWindowFormat platformWindowFormat() const = 0;
const static QPlatformGLContext *currentContext();
- static QPlatformGLContext *defaultSharedContext();
protected:
-
- static void setDefaultSharedContext(QPlatformGLContext *sharedContext);
-
QScopedPointer<QPlatformGLContextPrivate> d_ptr;
+
private:
//hack to make it work with QGLContext::CurrentContext
friend class QGLContext;
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index c45a953..d559c53 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -69,16 +69,6 @@ QPlatformEventLoopIntegration *QPlatformIntegration::createEventLoopIntegration(
}
/*!
- Returns whether the given platform integration supports OpenGL.
-
- Default implementation returns false,
-*/
-bool QPlatformIntegration::hasOpenGL() const
-{
- return false;
-}
-
-/*!
Accessor for the platform integrations fontdatabase.
Default implementation returns a default QPlatformFontDatabase.
diff --git a/src/gui/kernel/qplatformintegration_qpa.h b/src/gui/kernel/qplatformintegration_qpa.h
index 0aacefa..d06272c 100644
--- a/src/gui/kernel/qplatformintegration_qpa.h
+++ b/src/gui/kernel/qplatformintegration_qpa.h
@@ -67,6 +67,7 @@ class Q_GUI_EXPORT QPlatformIntegration
public:
enum Capability {
ThreadedPixmaps = 1,
+ OpenGL = 2
};
virtual ~QPlatformIntegration() { }
@@ -95,9 +96,6 @@ public:
// the gui thread. All of the functions in QWindowSystemInterface are thread safe.
virtual QPlatformEventLoopIntegration *createEventLoopIntegration() const;
-//jl:XXX should it be hasGLContext and do we need it at all?
- virtual bool hasOpenGL() const;
-
// Access native handles. The window handle is already available from Wid;
virtual QPlatformNativeInterface *nativeInterface() const;
};
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp
index ddc6239..c165c85 100644
--- a/src/gui/kernel/qplatformwindowformat_qpa.cpp
+++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp
@@ -53,7 +53,7 @@ public:
, opts(QPlatformWindowFormat::DoubleBuffer | QPlatformWindowFormat::DepthBuffer
| QPlatformWindowFormat::Rgba | QPlatformWindowFormat::DirectRendering
| QPlatformWindowFormat::StencilBuffer | QPlatformWindowFormat::DeprecatedFunctions
- | QPlatformWindowFormat::UseDefaultSharedContext | QPlatformWindowFormat::HasWindowSurface)
+ | QPlatformWindowFormat::HasWindowSurface)
, depthSize(-1)
, accumSize(-1)
, stencilSize(-1)
@@ -525,16 +525,6 @@ void QPlatformWindowFormat::setSampleBuffers(bool enable)
setOption(enable ? QPlatformWindowFormat::SampleBuffers : QPlatformWindowFormat::NoSampleBuffers);
}
-void QPlatformWindowFormat::setUseDefaultSharedContext(bool enable)
-{
- if (enable) {
- setOption(QPlatformWindowFormat::UseDefaultSharedContext);
- d->sharedContext = 0;
- } else {
- setOption(QPlatformWindowFormat::NoDefaultSharedContext);
- }
-}
-
/*!
Returns the number of samples per pixel when multisampling is
enabled. By default, the highest number of samples that is
@@ -613,7 +603,6 @@ QPlatformWindowFormat::WindowApi QPlatformWindowFormat::windowApi() const
void QPlatformWindowFormat::setSharedContext(QPlatformGLContext *context)
{
- setUseDefaultSharedContext(false);
d->sharedContext = context;
}
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.h b/src/gui/kernel/qplatformwindowformat_qpa.h
index fa01a8a..ba21ba4 100644
--- a/src/gui/kernel/qplatformwindowformat_qpa.h
+++ b/src/gui/kernel/qplatformwindowformat_qpa.h
@@ -66,8 +66,7 @@ public:
HasOverlay = 0x0100,
SampleBuffers = 0x0200,
DeprecatedFunctions = 0x0400,
- UseDefaultSharedContext = 0x0800,
- HasWindowSurface = 0x1000,
+ HasWindowSurface = 0x0800,
SingleBuffer = DoubleBuffer << 16,
NoDepthBuffer = DepthBuffer << 16,
ColorIndex = Rgba << 16,
@@ -79,7 +78,6 @@ public:
NoOverlay = HasOverlay << 16,
NoSampleBuffers = SampleBuffers << 16,
NoDeprecatedFunctions = DeprecatedFunctions << 16,
- NoDefaultSharedContext = UseDefaultSharedContext << 16,
NoWindowSurface = HasWindowSurface << 16
};
@@ -149,8 +147,6 @@ public:
void setStereo(bool enable);
bool directRendering() const;
void setDirectRendering(bool enable);
- bool useDefaultSharedContext() const;
- void setUseDefaultSharedContext(bool enable);
bool hasWindowSurface() const;
void setWindowSurface(bool enable);
@@ -231,11 +227,6 @@ inline bool QPlatformWindowFormat::sampleBuffers() const
return testOption(QPlatformWindowFormat::SampleBuffers);
}
-inline bool QPlatformWindowFormat::useDefaultSharedContext() const
-{
- return testOption(QPlatformWindowFormat::UseDefaultSharedContext);
-}
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/gui/kernel/qsessionmanager_qpa.cpp b/src/gui/kernel/qsessionmanager_qpa.cpp
new file mode 100644
index 0000000..ef532d7
--- /dev/null
+++ b/src/gui/kernel/qsessionmanager_qpa.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 <qsessionmanager.h>
+
+#include <private/qobject_p.h>
+#ifndef QT_NO_SESSIONMANAGER
+
+QT_BEGIN_NAMESPACE
+
+class QSessionManagerPrivate : public QObjectPrivate
+{
+public:
+ QSessionManagerPrivate(QSessionManager *m, const QString &id,
+ const QString &key);
+
+ QStringList restartCommand;
+ QStringList discardCommand;
+ const QString sessionId;
+ const QString sessionKey;
+ QSessionManager::RestartHint restartHint;
+};
+
+QSessionManagerPrivate::QSessionManagerPrivate(QSessionManager*,
+ const QString &id,
+ const QString &key)
+ : QObjectPrivate(), sessionId(id), sessionKey(key)
+{
+}
+
+QSessionManager::QSessionManager(QApplication *app, QString &id, QString &key)
+ : QObject(*(new QSessionManagerPrivate(this, id, key)), app)
+{
+ Q_D(QSessionManager);
+ d->restartHint = RestartIfRunning;
+}
+
+QSessionManager::~QSessionManager()
+{
+}
+
+QString QSessionManager::sessionId() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionId;
+}
+
+QString QSessionManager::sessionKey() const
+{
+ Q_D(const QSessionManager);
+ return d->sessionKey;
+}
+
+
+bool QSessionManager::allowsInteraction()
+{
+ return false;
+}
+
+bool QSessionManager::allowsErrorInteraction()
+{
+ return false;
+}
+
+void QSessionManager::release()
+{
+}
+
+void QSessionManager::cancel()
+{
+}
+
+void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
+{
+ Q_D(QSessionManager);
+ d->restartHint = hint;
+}
+
+QSessionManager::RestartHint QSessionManager::restartHint() const
+{
+ Q_D(const QSessionManager);
+ return d->restartHint;
+}
+
+void QSessionManager::setRestartCommand(const QStringList &command)
+{
+ Q_D(QSessionManager);
+ d->restartCommand = command;
+}
+
+QStringList QSessionManager::restartCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->restartCommand;
+}
+
+void QSessionManager::setDiscardCommand(const QStringList &command)
+{
+ Q_D(QSessionManager);
+ d->discardCommand = command;
+}
+
+QStringList QSessionManager::discardCommand() const
+{
+ Q_D(const QSessionManager);
+ return d->discardCommand;
+}
+
+void QSessionManager::setManagerProperty(const QString &name,
+ const QString &value)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+
+void QSessionManager::setManagerProperty(const QString &name,
+ const QStringList &value)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+
+bool QSessionManager::isPhase2() const
+{
+ return false;
+}
+
+void QSessionManager::requestPhase2()
+{
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_SESSIONMANAGER
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 288ee99..02977ce 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -77,6 +77,10 @@
#include <akncontext.h> // CAknContextPane
#include <eikspane.h> // CEikStatusPane
#include <AknPopupFader.h> // MAknFadedComponent and TAknPopupFader
+#include <gfxtranseffect/gfxtranseffect.h> // BeginFullScreen
+#ifdef QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H
+#include <akntranseffect.h> // BeginFullScreen
+#endif
#endif
QT_BEGIN_NAMESPACE
@@ -85,6 +89,9 @@ QT_BEGIN_NAMESPACE
// system events seems to start with 0x10
const TInt KInternalStatusPaneChange = 0x50000000;
+// For BeginFullScreen().
+const TUint KQtAppExitFlag = 0x400;
+
static const int qt_symbian_max_screens = 4;
//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2
@@ -199,7 +206,11 @@ public:
int screenWidthInTwipsForScreen[qt_symbian_max_screens];
int screenHeightInTwipsForScreen[qt_symbian_max_screens];
- bool nativeOrientationIsPortrait;
+ int nativeScreenWidthInPixels;
+ int nativeScreenHeightInPixels;
+
+ int beginFullScreenCalled : 1;
+ int endFullScreenCalled : 1;
};
Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data();
@@ -245,6 +256,8 @@ public:
bool isControlActive();
void ensureFixNativeOrientation();
+ QPoint translatePointForFixedNativeOrientation(const TPoint &pointerEventPos) const;
+ TRect translateRectForFixedNativeOrientation(const TRect &controlRect) const;
#ifdef Q_WS_S60
void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
@@ -264,6 +277,9 @@ protected:
void PositionChanged();
void FocusChanged(TDrawNow aDrawNow);
+protected:
+ void qwidgetResize_helper(const QSize &newSize);
+
private:
void HandlePointerEvent(const TPointerEvent& aPointerEvent);
TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType);
@@ -303,6 +319,7 @@ private:
#endif
bool m_inExternalScreenOverride : 1;
+ bool m_lastStatusPaneVisibility : 1;
};
inline QS60Data::QS60Data()
@@ -335,6 +352,8 @@ inline QS60Data::QS60Data()
#ifdef Q_OS_SYMBIAN
,s60InstalledTrapHandler(0)
#endif
+ ,beginFullScreenCalled(0),
+ endFullScreenCalled(0)
{
}
@@ -370,18 +389,15 @@ inline void QS60Data::updateScreenSize()
// Look for a screen mode with rotation 0
// in order to decide what the native orientation is.
- int nativeScreenWidthInPixels = 0;
- int nativeScreenHeightInPixels = 0;
for (mode = 0; mode < screenModeCount; ++mode) {
TPixelsAndRotation sizeAndRotation;
dev->GetScreenModeSizeAndRotation(mode, sizeAndRotation);
if (sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal) {
- nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth;
- nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight;
+ S60->nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth;
+ S60->nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight;
break;
}
}
- S60->nativeOrientationIsPortrait = nativeScreenWidthInPixels <= nativeScreenHeightInPixels;
}
inline RWsSession& QS60Data::wsSession()
@@ -587,6 +603,49 @@ void qt_symbian_set_cursor_visible(bool visible);
bool qt_symbian_is_cursor_visible();
#endif
+static inline bool qt_beginFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ // Only for post-S^3. On earlier versions the system transition effects
+ // may not be able to capture the non-Avkon content, leading to confusing
+ // looking effects, so just skip the whole thing.
+ if (S60->beginFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return false;
+ S60->beginFullScreenCalled = true;
+ // For Avkon apps the app-exit effect is triggered from CAknAppUi::PrepareToExit().
+ // That is good for Avkon apps, but in case of Qt the RWindows are destroyed earlier.
+ // Therefore we call BeginFullScreen() ourselves.
+ GfxTransEffect::BeginFullScreen(AknTransEffect::EApplicationExit,
+ TRect(0, 0, 0, 0),
+ AknTransEffect::EParameterType,
+ AknTransEffect::GfxTransParam(S60->uid,
+ AknTransEffect::TParameter::EAvkonCheck | KQtAppExitFlag));
+ return true;
+#else
+ return false;
+#endif
+}
+
+static inline void qt_abortFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ if (!S60->beginFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return;
+ GfxTransEffect::AbortFullScreen();
+ S60->beginFullScreenCalled = S60->endFullScreenCalled = false;
+#endif
+}
+
+static inline void qt_endFullScreenEffect()
+{
+#if defined(Q_WS_S60) && defined(QT_SYMBIAN_HAVE_AKNTRANSEFFECT_H)
+ if (S60->endFullScreenCalled || QSysInfo::s60Version() <= QSysInfo::SV_S60_5_2)
+ return;
+ S60->endFullScreenCalled = true;
+ GfxTransEffect::EndFullScreen();
+#endif
+}
+
QT_END_NAMESPACE
#endif // QT_S60_P_H
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index f5a9e27..354f05b 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2885,7 +2885,7 @@ void QWidgetPrivate::setSubWindowStacking(bool set)
if ([pwin isVisible]
&& (ptype == Qt::Window || ptype == Qt::Dialog)
&& ![qwin parentWindow]
- && (!use_behaviour_qt473 && parent->windowModality() == Qt::ApplicationModal)) {
+ && (use_behaviour_qt473 || parent->windowModality() == Qt::ApplicationModal)) {
NSInteger level = [qwin level];
[pwin addChildWindow:qwin ordered:NSWindowAbove];
if ([qwin level] < level)
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index 96b0776..12bcc4b 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -851,6 +851,8 @@ void QWidgetPrivate::s60UpdateIsOpaque()
// recreate backing store to get translucent surface (raster surface).
extra->topextra->backingStore.create(q);
extra->topextra->backingStore.registerWidget(q);
+ // FixNativeOrientation() will not work without an EGL surface.
+ q->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
}
}
} else if (extra->topextra->nativeWindowTransparencyEnabled) {
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index c6753fc..5ece7d6 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -1333,12 +1333,40 @@ QPoint QWidgetPrivate::mapFromGlobal(const QPoint &pos) const
QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
Q_D(const QWidget);
+ QPoint offset = data->crect.topLeft();
+ const QWidget *w = this;
+ const QWidget *p = w->parentWidget();
+ while (!w->isWindow() && p) {
+ w = p;
+ p = p->parentWidget();
+ offset += w->data->crect.topLeft();
+ }
+
+ const QWidgetPrivate *wd = w->d_func();
+ QTLWExtra *tlw = wd->topData();
+ if (!tlw->embedded)
+ return pos + offset;
+
return d->mapToGlobal(pos);
}
QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
Q_D(const QWidget);
+ QPoint offset = data->crect.topLeft();
+ const QWidget *w = this;
+ const QWidget *p = w->parentWidget();
+ while (!w->isWindow() && p) {
+ w = p;
+ p = p->parentWidget();
+ offset += w->data->crect.topLeft();
+ }
+
+ const QWidgetPrivate *wd = w->d_func();
+ QTLWExtra *tlw = wd->topData();
+ if (!tlw->embedded)
+ return pos - offset;
+
return d->mapFromGlobal(pos);
}
@@ -1352,9 +1380,15 @@ void QWidgetPrivate::updateSystemBackground()
if (brush.style() == Qt::NoBrush
|| q->testAttribute(Qt::WA_NoSystemBackground)
|| q->testAttribute(Qt::WA_UpdatesDisabled)
- || type == Qt::Popup || type == Qt::ToolTip
- )
- XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+ || type == Qt::Popup || type == Qt::ToolTip) {
+ if (QX11Info::isCompositingManagerRunning()
+ && q->testAttribute(Qt::WA_TranslucentBackground)
+ && !(q->parent()))
+ XSetWindowBackground(X11->display, q->internalWinId(),
+ QColormap::instance(xinfo.screen()).pixel(Qt::transparent));
+ else
+ XSetWindowBackgroundPixmap(X11->display, q->internalWinId(), XNone);
+ }
else if (brush.style() == Qt::SolidPattern && brush.isOpaque())
XSetWindowBackground(X11->display, q->internalWinId(),
QColormap::instance(xinfo.screen()).pixel(brush.color()));
diff --git a/src/gui/painting/qcolormap_qpa.cpp b/src/gui/painting/qcolormap_qpa.cpp
index 1f4fea8..f66607b 100644
--- a/src/gui/painting/qcolormap_qpa.cpp
+++ b/src/gui/painting/qcolormap_qpa.cpp
@@ -70,7 +70,7 @@ void QColormap::initialize()
QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
QList<QPlatformScreen*> screens = pi->screens();
- screenMap->depth = screens[0]->depth();
+ screenMap->depth = screens.at(0)->depth();
if (screenMap->depth < 8) {
screenMap->mode = QColormap::Indexed;
screenMap->numcolors = 256;
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index dd4b3db..7870def 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -47,6 +47,7 @@
#include <private/qimage_p.h>
#include <qstatictext.h>
#include <private/qstatictext_p.h>
+#include <private/qrawfont_p.h>
#include <QDebug>
@@ -1754,26 +1755,38 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
painter->setClipRegion(region, Qt::ClipOperation(cmd.extra));
break; }
+#if !defined(QT_NO_RAWFONT)
case QPaintBufferPrivate::Cmd_DrawStaticText: {
QVariantList variants(d->variants.at(cmd.offset).value<QVariantList>());
QFont font = variants.at(0).value<QFont>();
- QVector<quint32> glyphs;
+ QVector<quint32> glyphIndexes;
QVector<QPointF> positions;
for (int i=0; i<(variants.size() - 1) / 2; ++i) {
- glyphs.append(variants.at(i*2 + 1).toUInt());
+ glyphIndexes.append(variants.at(i*2 + 1).toUInt());
positions.append(variants.at(i*2 + 2).toPointF());
}
painter->setFont(font);
- qt_draw_glyphs(painter, glyphs.constData(), positions.constData(), glyphs.size());
-
- break;
+ QRawFont rawFont;
+ QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont);
+ QFontPrivate *fontD = QFontPrivate::get(font);
+ rawFontD->fontEngine = fontD->engineForScript(QUnicodeTables::Common);
+ rawFontD->fontEngine->ref.ref();
+
+ QGlyphs glyphs;
+ glyphs.setFont(rawFont);
+ glyphs.setGlyphIndexes(glyphIndexes);
+ glyphs.setPositions(positions);
+
+ painter->drawGlyphs(QPointF(), glyphs);
+ break;
}
+#endif
case QPaintBufferPrivate::Cmd_DrawText: {
QPointF pos(d->floats.at(cmd.extra), d->floats.at(cmd.extra+1));
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 50d65e6..9fafba5 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -75,6 +75,7 @@
#include <private/qstatictext_p.h>
#include <private/qglyphs_p.h>
#include <private/qstylehelper_p.h>
+#include <private/qrawfont_p.h>
QT_BEGIN_NAMESPACE
@@ -97,10 +98,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
-static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat);
+Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat);
static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
@@ -5790,12 +5791,14 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR
\sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes()
*/
+#if !defined(QT_NO_RAWFONT)
void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
{
Q_D(QPainter);
- QFont oldFont = d->state->font;
- d->state->font = glyphs.font();
+ QRawFont font = glyphs.font();
+ if (!font.isValid())
+ return;
QVector<quint32> glyphIndexes = glyphs.glyphIndexes();
QVector<QPointF> glyphPositions = glyphs.positions();
@@ -5814,39 +5817,20 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
- d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count);
-
- d->state->font = oldFont;
+ d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphs.overline(),
+ glyphs.underline(), glyphs.strikeOut());
}
-void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray,
- int glyphCount)
-{
- QVarLengthArray<QFixedPoint, 128> positions(glyphCount);
- for (int i=0; i<glyphCount; ++i)
- positions[i] = QFixedPoint::fromPointF(positionArray[i]);
-
- QPainterPrivate *painter_d = QPainterPrivate::get(painter);
- painter_d->drawGlyphs(const_cast<quint32 *>(glyphArray), positions.data(), glyphCount);
-}
-
-void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount)
+void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount,
+ const QRawFont &font, bool overline, bool underline,
+ bool strikeOut)
{
Q_Q(QPainter);
updateState(state);
- QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common);
-
- while (fontEngine->type() == QFontEngine::Multi) {
- // Pick engine based on first glyph in array if we are using a multi engine.
- // (all glyphs must be for same font)
- int engineIdx = 0;
- if (glyphCount > 0)
- engineIdx = glyphArray[0] >> 24;
-
- fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
- }
+ QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+ QFontEngine *fontEngine = fontD->fontEngine;
QFixed leftMost;
QFixed rightMost;
@@ -5881,7 +5865,6 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
extended->drawStaticTextItem(&staticTextItem);
} else {
QTextItemInt textItem;
- textItem.f = &state->font;
textItem.fontEngine = fontEngine;
QVarLengthArray<QFixed, 128> advances(glyphCount);
@@ -5903,20 +5886,21 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
}
QTextItemInt::RenderFlags flags;
- if (state->font.underline())
+ if (underline)
flags |= QTextItemInt::Underline;
- if (state->font.overline())
+ if (overline)
flags |= QTextItemInt::Overline;
- if (state->font.strikeOut())
+ if (strikeOut)
flags |= QTextItemInt::StrikeOut;
drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
fontEngine,
- (state->font.underline()
- ? QTextCharFormat::SingleUnderline
- : QTextCharFormat::NoUnderline),
+ (underline
+ ? QTextCharFormat::SingleUnderline
+ : QTextCharFormat::NoUnderline),
flags, width.toReal(), QTextCharFormat());
}
+#endif // QT_NO_RAWFONT
/*!
@@ -6076,9 +6060,9 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
}
d->extended->drawStaticTextItem(item);
- drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions,
- item->numGlyphs, item->fontEngine(), staticText_d->font,
- QTextCharFormat());
+ qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
+ item->numGlyphs, item->fontEngine(), staticText_d->font,
+ QTextCharFormat());
}
if (currentColor != oldPen.color())
setPen(oldPen);
@@ -6523,10 +6507,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setBrush(oldBrush);
}
-static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat)
+Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
+ const QFixedPoint *positions, int glyphCount,
+ QFontEngine *fontEngine, const QFont &font,
+ const QTextCharFormat &charFormat)
{
if (!(font.underline() || font.strikeOut() || font.overline()))
return;
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index ae2fdf2..4b2c447 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -399,7 +399,9 @@ public:
void setLayoutDirection(Qt::LayoutDirection direction);
Qt::LayoutDirection layoutDirection() const;
+#if !defined(QT_NO_RAWFONT)
void drawGlyphs(const QPointF &position, const QGlyphs &glyphs);
+#endif
void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText);
inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText);
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 26d8fc3..205c10a 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -184,6 +184,7 @@ struct QPainterDummyState
QTransform transform;
};
+class QRawFont;
class QPainterPrivate
{
Q_DECLARE_PUBLIC(QPainter)
@@ -229,7 +230,12 @@ public:
void draw_helper(const QPainterPath &path, DrawOperation operation = StrokeAndFillDraw);
void drawStretchedGradient(const QPainterPath &path, DrawOperation operation);
void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
- void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount);
+
+#if !defined(QT_NO_RAWFONT)
+ void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
+ const QRawFont &font, bool overline = false, bool underline = false,
+ bool strikeOut = false);
+#endif
void updateMatrix();
void updateInvMatrix();
@@ -259,8 +265,6 @@ public:
};
Q_GUI_EXPORT void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation);
-Q_GUI_EXPORT void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray,
- const QPointF *positionArray, int glyphCount);
QString qt_generate_brush_key(const QBrush &brush);
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 2058040..27aed32 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1904,7 +1904,7 @@ static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1,
if (y >= bounds.top() && y < bounds.bottom()
&& bounds.right() >= x1 && bounds.left() < x2) {
const qreal lower_bound = qreal(.01);
- if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound)
+ if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
return true;
QBezier first_half, second_half;
@@ -1923,7 +1923,7 @@ static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qr
if (x >= bounds.left() && x < bounds.right()
&& bounds.bottom() >= y1 && bounds.top() < y2) {
const qreal lower_bound = qreal(.01);
- if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound)
+ if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
return true;
QBezier first_half, second_half;
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index 8a2a88b..cc5fe10 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -68,9 +68,6 @@
#include <qlibrary.h>
#include <private/qstylehelper_p.h>
-#define CL_MAX(a,b) (a)>(b) ? (a):(b) // ### qMin/qMax does not work for vc6
-#define CL_MIN(a,b) (a)<(b) ? (a):(b) // remove this when it is working
-
QT_BEGIN_NAMESPACE
using namespace QStyleHelper;
@@ -533,8 +530,8 @@ static void qt_cleanlooks_draw_mdibutton(QPainter *painter, const QStyleOptionTi
{
QColor dark;
dark.setHsv(option->palette.button().color().hue(),
- CL_MIN(255, (int)(option->palette.button().color().saturation()*1.9)),
- CL_MIN(255, (int)(option->palette.button().color().value()*0.7)));
+ qMin(255, (int)(option->palette.button().color().saturation()*1.9)),
+ qMin(255, (int)(option->palette.button().color().value()*0.7)));
QColor highlight = option->palette.highlight().color();
@@ -691,11 +688,11 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem,
QColor darkOutline;
QColor dark;
darkOutline.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*3.0)),
- CL_MIN(255, (int)(button.value()*0.6)));
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
dark.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*1.9)),
- CL_MIN(255, (int)(button.value()*0.7)));
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
QColor tabFrameColor = mergedColors(option->palette.background().color(),
dark.lighter(135), 60);
@@ -1117,8 +1114,8 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem,
QColor gradientMidColor = option->palette.button().color();
QColor gradientStopColor;
gradientStopColor.setHsv(buttonColor.hue(),
- CL_MIN(255, (int)(buttonColor.saturation()*1.9)),
- CL_MIN(255, (int)(buttonColor.value()*0.96)));
+ qMin(255, (int)(buttonColor.saturation()*1.9)),
+ qMin(255, (int)(buttonColor.value()*0.96)));
QRect gradRect = rect.adjusted(1, 2, -1, -2);
// gradient fill
@@ -1384,12 +1381,12 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o
QColor button = option->palette.button().color();
QColor dark;
dark.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*1.9)),
- CL_MIN(255, (int)(button.value()*0.7)));
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
QColor darkOutline;
darkOutline.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*2.0)),
- CL_MIN(255, (int)(button.value()*0.6)));
+ qMin(255, (int)(button.saturation()*2.0)),
+ qMin(255, (int)(button.value()*0.6)));
QRect rect = option->rect;
QColor shadow = mergedColors(option->palette.background().color().darker(120),
dark.lighter(130), 60);
@@ -1662,8 +1659,8 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o
QColor gradientStopColor;
QColor gradientStartColor = option->palette.button().color();
gradientStopColor.setHsv(gradientStartColor.hue(),
- CL_MIN(255, (int)(gradientStartColor.saturation()*2)),
- CL_MIN(255, (int)(gradientStartColor.value()*0.96)));
+ qMin(255, (int)(gradientStartColor.saturation()*2)),
+ qMin(255, (int)(gradientStartColor.value()*0.96)));
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
if (option->palette.background().gradient()) {
gradient.setStops(option->palette.background().gradient()->stops());
@@ -2425,14 +2422,14 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp
QColor grooveColor;
QColor darkOutline;
dark.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*1.9)),
- CL_MIN(255, (int)(button.value()*0.7)));
+ qMin(255, (int)(button.saturation()*1.9)),
+ qMin(255, (int)(button.value()*0.7)));
grooveColor.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*2.6)),
- CL_MIN(255, (int)(button.value()*0.9)));
+ qMin(255, (int)(button.saturation()*2.6)),
+ qMin(255, (int)(button.value()*0.9)));
darkOutline.setHsv(button.hue(),
- CL_MIN(255, (int)(button.saturation()*3.0)),
- CL_MIN(255, (int)(button.value()*0.6)));
+ qMin(255, (int)(button.saturation()*3.0)),
+ qMin(255, (int)(button.value()*0.6)));
QColor alphaCornerColor;
if (widget) {
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 680e007..fa6eeb7 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -72,6 +72,7 @@
#include "qcheckbox.h"
#include "qdesktopwidget.h"
#include "qprogressbar.h"
+#include "qlabel.h"
#include "private/qtoolbarextension_p.h"
#include "private/qcombobox_p.h"
@@ -681,6 +682,13 @@ void QS60StylePrivate::setThemePalette(QWidget *widget)
if (header->viewport())
header->viewport()->setPalette(widgetPalette);
QApplication::setPalette(widgetPalette, "QHeaderView");
+ } else if (qobject_cast<QLabel *>(widget)) {
+ if (widget->window() && widget->window()->windowType() == Qt::Dialog) {
+ QPalette widgetPalette = widget->palette();
+ widgetPalette.setColor(QPalette::WindowText,
+ s60Color(QS60StyleEnums::CL_QsnTextColors, 19, 0));
+ widget->setPalette(widgetPalette);
+ }
}
}
@@ -955,6 +963,17 @@ bool QS60StylePrivate::isWidgetPressed(const QWidget *widget)
return (widget && widget == m_pressedWidget);
}
+// Generates 1*1 white pixmap as a placeholder for real texture.
+// The actual theme texture is drawn in qt_s60_fill_background().
+QPixmap QS60StylePrivate::placeHolderTexture()
+{
+ if (!m_placeHolderTexture) {
+ m_placeHolderTexture = new QPixmap(1,1);
+ m_placeHolderTexture->fill(Qt::green);
+ }
+ return *m_placeHolderTexture;
+}
+
/*!
\class QS60Style
\brief The QS60Style class provides a look and feel suitable for applications on S60.
@@ -1540,8 +1559,10 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
skinElement==QS60StylePrivate::SE_TabBarTabWestActive) {
const int borderThickness =
QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- const int tabOverlap =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
+
const bool usesScrollButtons =
(widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
const int roomForScrollButton =
@@ -1580,9 +1601,11 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QStyleOptionTabV3 optionTab = *tab;
QRect tr = optionTab.rect;
const bool directionMirrored = (optionTab.direction == Qt::RightToLeft);
- const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
- const int tabOverlap =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
const bool usesScrollButtons =
(widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
const int roomForScrollButton =
@@ -2531,6 +2554,11 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
//without having to define custom pixel metric
metricValue *= 2;
+#if defined(Q_WS_S60)
+ if (metric == PM_TabBarTabOverlap && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_2))
+ metricValue = 0;
+#endif
+
return metricValue;
}
@@ -2645,8 +2673,6 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
}
}
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
- //native items have small empty areas at the beginning and end of menu item
- sz.setWidth(sz.width() + 2 * pixelMetric(PM_MenuHMargin) + 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth));
if (QS60StylePrivate::isTouchSupported()) {
//Make itemview easier to use in touch devices
sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
@@ -3005,10 +3031,11 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
ret = QCommonStyle::subElementRect(element, opt, widget);
if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
- const int tabOverlapNoBorder =
- QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap);
- const int tabOverlap =
- tabOverlapNoBorder - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ const int borderThickness =
+ QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
+ int tabOverlap = pixelMetric(PM_TabBarTabOverlap);
+ if (tabOverlap > borderThickness)
+ tabOverlap -= borderThickness;
const QTabWidget *tab = qobject_cast<const QTabWidget *>(widget);
int gain = (tab) ? tabOverlap * tab->count() : 0;
switch (twf->shape) {
@@ -3026,7 +3053,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
if ((ret.right() + gain) > widget->rect().right())
gain = widget->rect().right() - ret.right();
ret.adjust(0, 0, gain, 0);
- }
+ }
}
break;
}
@@ -3114,7 +3141,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
}
break;
case SE_ItemViewItemCheckIndicator:
- if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(opt)) {
+ if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(opt)) {
const QAbstractItemView *listItem = qobject_cast<const QAbstractItemView *>(widget);
const bool singleSelection = listItem &&
@@ -3122,7 +3149,7 @@ QRect QS60Style::subElementRect(SubElement element, const QStyleOption *opt, con
listItem->selectionMode() == QAbstractItemView::NoSelection);
const bool checkBoxOnly = (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) &&
listItem &&
- singleSelection;
+ singleSelection && vopt->text.isEmpty() && vopt->icon.isNull();
// Selection check mark rect.
const int indicatorWidth = QS60StylePrivate::pixelMetric(PM_IndicatorWidth);
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 6b79874..1e374cb 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -89,17 +89,25 @@ enum TSupportRelease {
ES60_5_0 = 0x0004,
ES60_5_1 = 0x0008,
ES60_5_2 = 0x0010,
+ ES60_5_3 = 0x0020,
ES60_3_X = ES60_3_1 | ES60_3_2,
// Releases before Symbian Foundation
ES60_PreSF = ES60_3_1 | ES60_3_2 | ES60_5_0,
+ // Releases before the S60 5.2
+ ES60_Pre52 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1,
+ // Releases before S60 5.3
+ ES60_Pre53 = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2,
// Add all new releases here
- ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2
+ ES60_All = ES60_3_1 | ES60_3_2 | ES60_5_0 | ES60_5_1 | ES60_5_2 | ES60_5_3
};
typedef struct {
- const TAknsItemID &skinID;
- TDrawType drawType;
- int supportInfo;
+ const TAknsItemID &skinID; // Determines default theme graphics ID.
+ TDrawType drawType; // Determines which native drawing routine is used to draw this item.
+ int supportInfo; // Defines the S60 versions that use the default graphics.
+ // These two, define new graphics that are used in releases other than partMapEntry.supportInfo defined releases.
+ // In general, these are given in numeric form to allow style compilation in earlier
+ // native releases that do not contain the new graphics.
int newMajorSkinId;
int newMinorSkinId;
} partMapEntry;
@@ -188,12 +196,14 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
/* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1},
/* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1},
/* SP_QgnGrafScrollArrowUp */ {KAknsIIDQgnGrafScrollArrowUp, EDrawGulIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_All, -1,-1},
- /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_All, -1,-1},
+
+ // In S60 5.3 there is a new tab graphic
+ /* SP_QgnGrafTabActiveL */ {KAknsIIDQgnGrafTabActiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2219}, //KAknsIIDQtgFrTabActiveNormalL
+ /* SP_QgnGrafTabActiveM */ {KAknsIIDQgnGrafTabActiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221b}, //KAknsIIDQtgFrTabActiveNormalC
+ /* SP_QgnGrafTabActiveR */ {KAknsIIDQgnGrafTabActiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x221a}, //KAknsIIDQtgFrTabActiveNormalR
+ /* SP_QgnGrafTabPassiveL */ {KAknsIIDQgnGrafTabPassiveL, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2221}, //KAknsIIDQtgFrTabPassiveNormalL
+ /* SP_QgnGrafTabPassiveM */ {KAknsIIDQgnGrafTabPassiveM, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2223}, //KAknsIIDQtgFrTabPassiveNormalC
+ /* SP_QgnGrafTabPassiveR */ {KAknsIIDQgnGrafTabPassiveR, EDrawIcon, ES60_Pre53, EAknsMajorSkin, 0x2222}, //KAknsIIDQtgFrTabPassiveNormalR
// In 3.1 there is no slider groove.
/* SP_QgnGrafNsliderEndLeft */ {KAknsIIDNone, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19cf /* KAknsIIDQgnGrafNsliderEndLeft */},
@@ -1132,7 +1142,8 @@ bool QS60StyleModeSpecifics::checkSupport(const int supportedRelease)
(currentRelease == QSysInfo::SV_S60_3_2 && supportedRelease & ES60_3_2) ||
(currentRelease == QSysInfo::SV_S60_5_0 && supportedRelease & ES60_5_0) ||
(currentRelease == QSysInfo::SV_S60_5_1 && supportedRelease & ES60_5_1) ||
- (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2));
+ (currentRelease == QSysInfo::SV_S60_5_2 && supportedRelease & ES60_5_2) ||
+ (currentRelease == QSysInfo::SV_S60_5_3 && supportedRelease & ES60_5_3) );
}
TAknsItemID QS60StyleModeSpecifics::partSpecificThemeId(int part)
@@ -1421,17 +1432,6 @@ QPixmap QS60StylePrivate::backgroundTexture(bool skipCreation)
return *m_background;
}
-// Generates 1*1 white pixmap as a placeholder for real texture.
-// The actual theme texture is drawn in qt_s60_fill_background().
-QPixmap QS60StylePrivate::placeHolderTexture()
-{
- if (!m_placeHolderTexture) {
- m_placeHolderTexture = new QPixmap(1,1);
- m_placeHolderTexture->fill(Qt::white);
- }
- return *m_placeHolderTexture;
-}
-
QSize QS60StylePrivate::screenSize()
{
return QSize(S60->screenWidthInPixels, S60->screenHeightInPixels);
diff --git a/src/gui/styles/qstylehelper_p.h b/src/gui/styles/qstylehelper_p.h
index 559f7f7..27587e3 100644
--- a/src/gui/styles/qstylehelper_p.h
+++ b/src/gui/styles/qstylehelper_p.h
@@ -110,6 +110,7 @@ template <typename T>
enum { ExactSize = true };
static int size(const HexString<T> &) { return sizeof(T) * 2; }
static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
+ typedef QString ConvertTo;
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index f77e237..b8cfb1f 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -282,27 +282,16 @@ QFontPrivate::~QFontPrivate()
scFont = 0;
}
-#if !defined(Q_WS_MAC)
extern QMutex *qt_fontdatabase_mutex();
-QFontEngine *QFontPrivate::engineForScript(int script) const
-{
- QMutexLocker locker(qt_fontdatabase_mutex());
- if (script >= QUnicodeTables::Inherited)
- script = QUnicodeTables::Common;
- if (engineData && engineData->fontCache != QFontCache::instance()) {
- // throw out engineData that came from a different thread
- engineData->ref.deref();
- engineData = 0;
- }
- if (!engineData || !engineData->engines[script])
- QFontDatabase::load(this, script);
- return engineData->engines[script];
-}
+#if !defined(Q_WS_MAC)
+#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engines[script]
#else
+#define QT_FONT_ENGINE_FROM_DATA(data, script) data->engine
+#endif
+
QFontEngine *QFontPrivate::engineForScript(int script) const
{
- extern QMutex *qt_fontdatabase_mutex();
QMutexLocker locker(qt_fontdatabase_mutex());
if (script >= QUnicodeTables::Inherited)
script = QUnicodeTables::Common;
@@ -311,11 +300,10 @@ QFontEngine *QFontPrivate::engineForScript(int script) const
engineData->ref.deref();
engineData = 0;
}
- if (!engineData || !engineData->engine)
+ if (!engineData || !QT_FONT_ENGINE_FROM_DATA(engineData, script))
QFontDatabase::load(this, script);
- return engineData->engine;
+ return QT_FONT_ENGINE_FROM_DATA(engineData, script);
}
-#endif
void QFontPrivate::alterCharForCapitalization(QChar &c) const {
switch (capital) {
diff --git a/src/gui/text/qfont_win.cpp b/src/gui/text/qfont_win.cpp
index 7d710ea..3ef761b 100644
--- a/src/gui/text/qfont_win.cpp
+++ b/src/gui/text/qfont_win.cpp
@@ -58,6 +58,7 @@
QT_BEGIN_NAMESPACE
extern HDC shared_dc(); // common dc for all fonts
+extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
// ### maybe move to qapplication_win
QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
@@ -65,20 +66,8 @@ QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
QString family = QString::fromWCharArray(lf.lfFaceName);
QFont qf(family);
qf.setItalic(lf.lfItalic);
- if (lf.lfWeight != FW_DONTCARE) {
- int weight;
- if (lf.lfWeight < 400)
- weight = QFont::Light;
- else if (lf.lfWeight < 600)
- weight = QFont::Normal;
- else if (lf.lfWeight < 700)
- weight = QFont::DemiBold;
- else if (lf.lfWeight < 800)
- weight = QFont::Bold;
- else
- weight = QFont::Black;
- qf.setWeight(weight);
- }
+ if (lf.lfWeight != FW_DONTCARE)
+ qf.setWeight(weightFromInteger(lf.lfWeight));
int lfh = qAbs(lf.lfHeight);
qf.setPointSizeF(lfh * 72.0 / GetDeviceCaps(shared_dc(),LOGPIXELSY));
qf.setUnderline(false);
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 94f21b8..36b0ea9 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -136,6 +136,21 @@ static int getFontWeight(const QString &weightString)
return (int) QFont::Normal;
}
+// convert 0 ~ 1000 integer to QFont::Weight
+QFont::Weight weightFromInteger(int weight)
+{
+ if (weight < 400)
+ return QFont::Light;
+ else if (weight < 600)
+ return QFont::Normal;
+ else if (weight < 700)
+ return QFont::DemiBold;
+ else if (weight < 800)
+ return QFont::Bold;
+ else
+ return QFont::Black;
+}
+
struct QtFontEncoding
{
signed int encoding : 16;
@@ -497,8 +512,6 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
// ### copied to tools/makeqpf/qpf2.cpp
-#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_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] = {
// Any,
@@ -576,7 +589,7 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
#define JapaneseCsbBit 17
#define KoreanCsbBit 21
-static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
+QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2])
{
QList<QFontDatabase::WritingSystem> writingSystems;
bool hasScript = false;
@@ -623,7 +636,6 @@ static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBi
return writingSystems;
}
-#endif
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
// class with virtual destructor, derived in qfontdatabase_s60.cpp
@@ -873,7 +885,7 @@ QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteA
os2->ulCodePageRange1, os2->ulCodePageRange2
};
- writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
//for (int i = 0; i < writingSystems.count(); ++i)
// qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i));
}
@@ -936,6 +948,11 @@ static const int scriptForWritingSystem[] = {
QUnicodeTables::Nko // Nko
};
+int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
+{
+ return scriptForWritingSystem[writingSystem];
+}
+
#if defined Q_WS_QWS || (defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)) || defined(Q_WS_WIN)
static inline bool requiresOpenType(int writingSystem)
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index ad2c1b2..5ba236b 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -72,7 +72,7 @@ static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont)
qFromBigEndian<quint32>(os2Table.data() + 54)
};
quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78), qFromBigEndian<quint32>(os2Table.data() + 82) };
- QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
#if 0
QCFString name;
ATSFontGetName(atsFont, kATSOptionFlagsDefault, &name);
@@ -244,6 +244,11 @@ static const char *styleHint(const QFontDef &request)
return stylehint;
}
+static inline float weightToFloat(unsigned int weight)
+{
+ return (weight - 50) / 100.0;
+}
+
void QFontDatabase::load(const QFontPrivate *d, int script)
{
// sanity checks
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index 3c7255b..3ab1ac8 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -529,7 +529,7 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex,
qFromBigEndian<quint32>(ulCodePageRange + 4)
};
const QList<QFontDatabase::WritingSystem> writingSystems =
- determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
foreach (const QFontDatabase::WritingSystem system, writingSystems)
family->writingSystems[system] = QtFontFamily::Supported;
return true;
diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp
index 8279195..05b7509 100644
--- a/src/gui/text/qfontdatabase_win.cpp
+++ b/src/gui/text/qfontdatabase_win.cpp
@@ -242,6 +242,8 @@ error:
return i18n_name;
}
+extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
+
static
void addFontToDatabase(QString familyName, const QString &scriptName,
TEXTMETRIC *textmetric,
@@ -274,16 +276,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) {
QtFontStyle::Key styleKey;
styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
- if (weight < 400)
- styleKey.weight = QFont::Light;
- else if (weight < 600)
- styleKey.weight = QFont::Normal;
- else if (weight < 700)
- styleKey.weight = QFont::DemiBold;
- else if (weight < 800)
- styleKey.weight = QFont::Bold;
- else
- styleKey.weight = QFont::Black;
+ styleKey.weight = weightFromInteger(weight);
QtFontFamily *family = privateDb()->family(familyName, true);
@@ -340,7 +333,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
quint32 codePageRange[2] = {
signature->fsCsb[0], signature->fsCsb[1]
};
- QList<QFontDatabase::WritingSystem> systems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ QList<QFontDatabase::WritingSystem> systems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
for (int i = 0; i < systems.count(); ++i) {
QFontDatabase::WritingSystem writingSystem = systems.at(i);
@@ -530,26 +523,26 @@ static inline void load(const QString &family = QString(), int = -1)
-static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, const QFontPrivate *fp)
+static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, HDC fontHdc, int dpi)
{
fe->fontDef = request; // most settings are equal
- HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fp->hdc) ? fp->hdc : shared_dc();
+ HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fontHdc) ? fontHdc : shared_dc();
SelectObject(dc, fe->hfont);
wchar_t n[64];
GetTextFace(dc, 64, n);
fe->fontDef.family = QString::fromWCharArray(n);
fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
if (fe->fontDef.pointSize < 0) {
- fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi;
+ fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi;
} else if (fe->fontDef.pixelSize == -1) {
- fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * fp->dpi / 72.);
+ fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.);
}
}
#if !defined(QT_NO_DIRECTWRITE)
static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request,
- const QFontPrivate *fp, IDWriteFont *font)
+ int dpi, IDWriteFont *font)
{
fe->fontDef = request;
@@ -601,9 +594,9 @@ static void initFontInfo(QFontEngineDirectWrite *fe, const QFontDef &request,
qErrnoWarning(hr, "initFontInfo: Failed to get family name");
if (fe->fontDef.pointSize < 0)
- fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi;
+ fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / dpi;
else if (fe->fontDef.pixelSize == -1)
- fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * fp->dpi / 72.);
+ fe->fontDef.pixelSize = qRound(fe->fontDef.pointSize * dpi / 72.);
}
#endif
@@ -679,20 +672,21 @@ static inline HFONT systemFont()
#define DEFAULT_GUI_FONT 17
#endif
-static
-QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &request, const QtFontDesc *desc,
- const QStringList &family_list)
+static QFontEngine *loadEngine(int script, const QFontDef &request,
+ HDC fontHdc, int dpi, bool rawMode,
+ const QtFontDesc *desc,
+ const QStringList &family_list)
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
- bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fp->hdc;
+ bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc;
HDC hdc = shared_dc();
- QString font_name = desc->family->name;
+ QString font_name = desc != 0 ? desc->family->name : request.family;
if (useDevice) {
- hdc = fp->hdc;
+ hdc = fontHdc;
font_name = request.family;
}
@@ -710,9 +704,9 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
bool useDirectWrite = false;
#endif
- if (fp->rawMode) { // will choose a stock font
+ if (rawMode) { // will choose a stock font
int f, deffnt = SYSTEM_FONT;
- QString fam = desc->family->name.toLower();
+ QString fam = desc != 0 ? desc->family->name.toLower() : request.family.toLower();
if (fam == QLatin1String("default"))
f = deffnt;
else if (fam == QLatin1String("system"))
@@ -766,11 +760,11 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
- if (desc->style->key.weight == 50)
+ if (desc == 0 || desc->style->key.weight == 50)
lf.lfWeight = FW_DONTCARE;
else
lf.lfWeight = (desc->style->key.weight*900)/99;
- lf.lfItalic = (desc->style->key.style != QFont::StyleNormal);
+ lf.lfItalic = (desc != 0 && desc->style->key.style != QFont::StyleNormal);
lf.lfCharSet = DEFAULT_CHARSET;
int strat = OUT_DEFAULT_PRECIS;
@@ -901,9 +895,11 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
&lf,
&directWriteFont);
if (FAILED(hr)) {
+#ifndef QT_NO_DEBUG
qErrnoWarning("QFontEngine::loadEngine: CreateFontFromLOGFONT failed "
"for %ls (0x%lx)",
lf.lfFaceName, hr);
+#endif
} else {
DeleteObject(hfont);
useDirectWrite = true;
@@ -933,22 +929,27 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
}
}
- initFontInfo(few, request, fp);
+ initFontInfo(few, request, fontHdc, dpi);
fe = few;
}
#if !defined(QT_NO_DIRECTWRITE)
else {
QFontDatabasePrivate *db = privateDb();
- QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(font_name,
- db->directWriteFactory,
- db->directWriteGdiInterop,
- directWriteFont,
- request.pixelSize);
- initFontInfo(fedw, request, fp, directWriteFont);
+ IDWriteFontFace *directWriteFontFace = NULL;
+ HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace);
+ if (SUCCEEDED(hr)) {
+ QFontEngineDirectWrite *fedw = new QFontEngineDirectWrite(db->directWriteFactory,
+ directWriteFontFace,
+ request.pixelSize);
+
+ initFontInfo(fedw, request, dpi, directWriteFont);
- fe = fedw;
+ fe = fedw;
+ } else {
+ qErrnoWarning(hr, "QFontEngine::loadEngine: CreateFontFace failed");
+ }
}
if (directWriteFont != 0)
@@ -957,6 +958,7 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
if(script == QUnicodeTables::Common
&& !(request.styleStrategy & QFont::NoFontMerging)
+ && desc != 0
&& !(desc->family->writingSystems[QFontDatabase::Symbol] & QtFontFamily::Supported)) {
if(!tryFonts) {
LANGID lid = GetUserDefaultLangID();
@@ -993,6 +995,20 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ
return fe;
}
+QFontEngine *qt_load_font_engine_win(const QFontDef &request)
+{
+ // From qfont.cpp
+ extern int qt_defaultDpi();
+
+ QFontCache::Key key(request, QUnicodeTables::Common);
+ QFontEngine *fe = QFontCache::instance()->findEngine(key);
+ if (fe != 0)
+ return fe;
+ else
+ return loadEngine(QUnicodeTables::Common, request, 0, qt_defaultDpi(), false, 0,
+ QStringList());
+}
+
const char *styleHint(const QFontDef &request)
{
const char *stylehint = 0;
@@ -1053,7 +1069,7 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r
}
if (!desc.family)
break;
- fe = loadEngine(script, d, req, &desc, family_list);
+ fe = loadEngine(script, req, d->hdc, d->dpi, d->rawMode, &desc, family_list);
if (!fe)
blacklistedFamilies.append(desc.familyIndex);
}
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 3adf4eb..2f76cc6 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -237,24 +237,6 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix
return metrics;
}
-QFont QFontEngine::createExplicitFont() const
-{
- return createExplicitFontWithName(fontDef.family);
-}
-
-QFont QFontEngine::createExplicitFontWithName(const QString &familyName) const
-{
- QFont font(familyName);
- font.setStyleStrategy(QFont::NoFontMerging);
- font.setWeight(fontDef.weight);
- font.setItalic(fontDef.style == QFont::StyleItalic);
- if (fontDef.pointSize < 0)
- font.setPixelSize(fontDef.pixelSize);
- else
- font.setPointSizeF(fontDef.pointSize);
- return font;
-}
-
QFixed QFontEngine::xHeight() const
{
QGlyphLayoutArray<8> glyphs;
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm
index 4d9192e..20b3730 100644
--- a/src/gui/text/qfontengine_coretext.mm
+++ b/src/gui/text/qfontengine_coretext.mm
@@ -52,6 +52,31 @@ QT_BEGIN_NAMESPACE
static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
+static void loadAdvancesForGlyphs(CTFontRef ctfont,
+ QVarLengthArray<CGGlyph> &cgGlyphs,
+ QGlyphLayout *glyphs, int len,
+ QTextEngine::ShaperFlags flags,
+ const QFontDef &fontDef)
+{
+ Q_UNUSED(flags);
+ QVarLengthArray<CGSize> advances(len);
+ CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len);
+
+ for (int i = 0; i < len; ++i) {
+ if (glyphs->glyphs[i] & 0xff000000)
+ continue;
+ glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
+ glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
+ }
+
+ if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ for (int i = 0; i < len; ++i) {
+ glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances_y[i] = glyphs->advances_y[i].round();
+ }
+ }
+}
+
QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
@@ -83,7 +108,31 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const
ctfont = baseFont;
CFRetain(ctfont);
}
+ init(kerning);
+}
+
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning)
+ : QFontEngineMulti(0)
+{
+ this->fontDef = fontDef;
+
+ transform = CGAffineTransformIdentity;
+ if (fontDef.stretch != 100) {
+ transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
+ }
+
+ ctfont = CTFontCreateWithGraphicsFont(cgFontRef, fontDef.pixelSize, &transform, NULL);
+ init(kerning);
+}
+
+QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti()
+{
+ CFRelease(ctfont);
+}
+void QCoreTextFontEngineMulti::init(bool kerning)
+{
+ Q_ASSERT(ctfont != NULL);
attributeDict = CFDictionaryCreateMutable(0, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
@@ -94,26 +143,20 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const
CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern);
}
- QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this);
+ QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef);
fe->ref.ref();
engines.append(fe);
-
-}
-
-QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti()
-{
- CFRelease(ctfont);
}
-uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const
+uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
{
for (int i = 0; i < engines.count(); ++i) {
- if (CFEqual(engineAt(i)->ctfont, id))
+ if (CFEqual(engineAt(i)->ctfont, font))
return i;
}
QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
- QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that);
+ QCoreTextFontEngine *fe = new QCoreTextFontEngine(font, fontDef);
fe->ref.ref();
that->engines.append(fe);
return engines.count() - 1;
@@ -317,72 +360,45 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
if (flags & QTextEngine::GlyphIndicesOnly)
return true;
- QVarLengthArray<CGSize> advances(len);
- CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, cgGlyphs.data(), advances.data(), len);
-
- for (int i = 0; i < len; ++i) {
- if (glyphs->glyphs[i] & 0xff000000)
- continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
- }
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < len; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
- }
-
+ loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef);
return true;
}
-void QCoreTextFontEngineMulti::recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const
-{
-}
-void QCoreTextFontEngineMulti::doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const
-{
-}
-
void QCoreTextFontEngineMulti::loadEngine(int)
{
// Do nothing
Q_ASSERT(false);
}
+extern int qt_antialiasing_threshold; // from qapplication.cpp
+static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef)
+{
+ CGAffineTransform transform = CGAffineTransformIdentity;
+ if (fontDef.stretch != 100)
+ transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
+ return transform;
+}
-QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def,
- QCoreTextFontEngineMulti *multiEngine)
+QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
{
fontDef = def;
- parentEngine = multiEngine;
- synthesisFlags = 0;
+ transform = transformFromFontDef(fontDef);
ctfont = font;
CFRetain(ctfont);
- cgFont = CTFontCopyGraphicsFont(ctfont, NULL);
- CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
- if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) {
- synthesisFlags |= SynthesizedBold;
- }
-
- if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait)) {
- synthesisFlags |= SynthesizedItalic;
- }
- transform = CGAffineTransformIdentity;
- if (fontDef.stretch != 100) {
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- }
- QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
- if (os2Table.size() >= 10)
- fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
+ cgFont = CTFontCopyGraphicsFont(font, NULL);
+ init();
+}
- QSettings appleSettings(QLatin1String("apple.com"));
- QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
- if (appleValue.isValid())
- antialiasing_threshold = appleValue.toInt();
- else
- antialiasing_threshold = -1;
+QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def)
+{
+ fontDef = def;
+ transform = transformFromFontDef(fontDef);
+ cgFont = font;
+ // Keep reference count balanced
+ CFRetain(cgFont);
+ ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, NULL);
+ init();
}
QCoreTextFontEngine::~QCoreTextFontEngine()
@@ -391,9 +407,89 @@ QCoreTextFontEngine::~QCoreTextFontEngine()
CFRelease(ctfont);
}
-bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int *, QTextEngine::ShaperFlags) const
+extern QFont::Weight weightFromInteger(int weight); // qfontdatabase.cpp
+
+int getTraitValue(CFDictionaryRef allTraits, CFStringRef trait)
{
- return false;
+ if (CFDictionaryContainsKey(allTraits, trait)) {
+ CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait);
+ float v = 0;
+ CFNumberGetValue(traitNum, kCFNumberFloatType, &v);
+ // the value we get from CFNumberRef is from -1.0 to 1.0
+ int value = v * 500 + 500;
+ return value;
+ }
+
+ return 0;
+}
+
+void QCoreTextFontEngine::init()
+{
+ Q_ASSERT(ctfont != NULL);
+ Q_ASSERT(cgFont != NULL);
+
+ QCFString family = CTFontCopyFamilyName(ctfont);
+ fontDef.family = family;
+
+ synthesisFlags = 0;
+ CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
+ if (traits & kCTFontItalicTrait)
+ fontDef.style = QFont::StyleItalic;
+
+ CFDictionaryRef allTraits = CTFontCopyTraits(ctfont);
+ fontDef.weight = weightFromInteger(getTraitValue(allTraits, kCTFontWeightTrait));
+ int slant = getTraitValue(allTraits, kCTFontSlantTrait);
+ if (slant > 500 && !(traits & kCTFontItalicTrait))
+ fontDef.style = QFont::StyleOblique;
+ CFRelease(allTraits);
+
+ if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait))
+ synthesisFlags |= SynthesizedBold;
+ // XXX: we probably don't need to synthesis italic for oblique font
+ if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait))
+ synthesisFlags |= SynthesizedItalic;
+
+ avgCharWidth = 0;
+ QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
+ unsigned emSize = CTFontGetUnitsPerEm(ctfont);
+ if (os2Table.size() >= 10) {
+ fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
+ // qAbs is a workaround for weird fonts like Lucida Grande
+ qint16 width = qAbs(qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 2)));
+ avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize);
+ } else
+ avgCharWidth = QFontEngine::averageCharWidth();
+
+ ctMaxCharWidth = ctMinLeftBearing = ctMinRightBearing = 0;
+ QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));
+ if (hheaTable.size() >= 16) {
+ quint16 width = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 10));
+ ctMaxCharWidth = width * fontDef.pixelSize / emSize;
+ qint16 bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 12));
+ ctMinLeftBearing = bearing * fontDef.pixelSize / emSize;
+ bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 14));
+ ctMinRightBearing = bearing * fontDef.pixelSize / emSize;
+ }
+}
+
+bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
+ int *nglyphs, QTextEngine::ShaperFlags flags) const
+{
+ *nglyphs = len;
+ QCFType<CFStringRef> cfstring;
+
+ QVarLengthArray<CGGlyph> cgGlyphs(len);
+ CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
+
+ for (int i = 0; i < len; ++i)
+ if (cgGlyphs[i])
+ glyphs->glyphs[i] = cgGlyphs[i];
+
+ if (flags & QTextEngine::GlyphIndicesOnly)
+ return true;
+
+ loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef);
+ return true;
}
glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
@@ -407,6 +503,7 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
}
return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
}
+
glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
{
glyph_metrics_t ret;
@@ -460,31 +557,29 @@ QFixed QCoreTextFontEngine::xHeight() const
? QFixed::fromReal(CTFontGetXHeight(ctfont)).round()
: QFixed::fromReal(CTFontGetXHeight(ctfont));
}
+
QFixed QCoreTextFontEngine::averageCharWidth() const
{
- // ### Need to implement properly and get the information from the OS/2 Table.
return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFontEngine::averageCharWidth().round()
- : QFontEngine::averageCharWidth();
+ ? avgCharWidth.round() : avgCharWidth;
}
qreal QCoreTextFontEngine::maxCharWidth() const
{
- // ### Max Help!
- return 0;
-
+ return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ ? qRound(ctMaxCharWidth) : ctMaxCharWidth;
}
+
qreal QCoreTextFontEngine::minLeftBearing() const
{
- // ### Min Help!
- return 0;
-
+ return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ ? qRound(ctMinLeftBearing) : ctMinLeftBearing;
}
+
qreal QCoreTextFontEngine::minRightBearing() const
{
- // ### Max Help! (even thought it's right)
- return 0;
-
+ return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
+ ? qRound(ctMinRightBearing) : ctMinLeftBearing;
}
void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
@@ -602,12 +697,6 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
-QFont QCoreTextFontEngine::createExplicitFont() const
-{
- QString familyName = QCFString::toQString(CTFontCopyFamilyName(ctfont));
- return createExplicitFontWithName(familyName);
-}
-
QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa)
{
const glyph_metrics_t br = boundingBox(glyph);
@@ -624,7 +713,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
cgflags);
CGContextSetFontSize(ctx, fontDef.pixelSize);
CGContextSetShouldAntialias(ctx, aa ||
- (fontDef.pointSize > antialiasing_threshold
+ (fontDef.pointSize > qt_antialiasing_threshold
&& !(fontDef.styleStrategy & QFont::NoAntialias)));
CGContextSetShouldSmoothFonts(ctx, aa);
CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
@@ -696,12 +785,19 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo
return im;
}
-void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
+void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
{
- Q_ASSERT(false);
- Q_UNUSED(numGlyphs);
- Q_UNUSED(glyphs);
- Q_UNUSED(flags);
+ int i, numGlyphs = glyphs->numGlyphs;
+ QVarLengthArray<CGGlyph> cgGlyphs(numGlyphs);
+
+ for (i = 0; i < numGlyphs; ++i) {
+ if (glyphs->glyphs[i] & 0xff000000)
+ cgGlyphs[i] = 0;
+ else
+ cgGlyphs[i] = glyphs->glyphs[i];
+ }
+
+ loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, numGlyphs, flags, fontDef);
}
QFontEngine::FaceId QCoreTextFontEngine::faceId() const
@@ -711,36 +807,36 @@ QFontEngine::FaceId QCoreTextFontEngine::faceId() const
bool QCoreTextFontEngine::canRender(const QChar *string, int len)
{
- QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont,
- QCFType<CFStringRef>(CFStringCreateWithCharactersNoCopy(0,
- reinterpret_cast<const UniChar *>(string),
- len, kCFAllocatorNull)),
- CFRangeMake(0, len));
- return retFont != 0;
- return false;
-}
-
- bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
- {
- QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
- if (!table || !length)
- return false;
- CFIndex tableLength = CFDataGetLength(table);
- int availableLength = *length;
- *length = tableLength;
- if (buffer) {
- if (tableLength > availableLength)
- return false;
- CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
- }
- return true;
- }
+ QVarLengthArray<CGGlyph> cgGlyphs(len);
+ return CTFontGetGlyphsForCharacters(ctfont, (const UniChar *) string, cgGlyphs.data(), len);
+}
+
+bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+{
+ QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
+ if (!table || !length)
+ return false;
+ CFIndex tableLength = CFDataGetLength(table);
+ int availableLength = *length;
+ *length = tableLength;
+ if (buffer) {
+ if (tableLength > availableLength)
+ return false;
+ CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
+ }
+ return true;
+}
void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *)
{
// ###
}
+QFixed QCoreTextFontEngine::emSquareSize() const
+{
+ return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont)));
+}
+
QT_END_NAMESPACE
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
index 7d17aef..1503c3f 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/gui/text/qfontengine_coretext_p.h
@@ -46,15 +46,17 @@
#if !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+class QRawFontPrivate;
class QCoreTextFontEngineMulti;
class QCoreTextFontEngine : public QFontEngine
{
public:
- QCoreTextFontEngine(CTFontRef font, const QFontDef &def,
- QCoreTextFontEngineMulti *multiEngine = 0);
+ QCoreTextFontEngine(CTFontRef font, const QFontDef &def);
+ QCoreTextFontEngine(CGFontRef font, const QFontDef &def);
~QCoreTextFontEngine();
+
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
- virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const;
+ virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
virtual glyph_metrics_t boundingBox(glyph_t glyph);
@@ -87,23 +89,29 @@ public:
virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, int margin, const QTransform &t);
virtual qreal minRightBearing() const;
virtual qreal minLeftBearing() const;
- virtual QFont createExplicitFont() const;
+ virtual QFixed emSquareSize() const;
private:
+ friend class QRawFontPrivate;
+
+ void init();
QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool colorful);
CTFontRef ctfont;
CGFontRef cgFont;
- QCoreTextFontEngineMulti *parentEngine;
int synthesisFlags;
CGAffineTransform transform;
+ QFixed avgCharWidth;
+ qreal ctMaxCharWidth;
+ qreal ctMinLeftBearing;
+ qreal ctMinRightBearing;
friend class QCoreTextFontEngineMulti;
- int antialiasing_threshold;
};
class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
+ QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
@@ -112,19 +120,16 @@ public:
QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes) const;
-
- virtual void recalcAdvances(int , QGlyphLayout *, QTextEngine::ShaperFlags) const;
- virtual void doKerning(int , QGlyphLayout *, QTextEngine::ShaperFlags) const;
-
virtual const char *name() const { return "CoreText"; }
protected:
virtual void loadEngine(int at);
private:
+ void init(bool kerning);
inline const QCoreTextFontEngine *engineAt(int i) const
{ return static_cast<const QCoreTextFontEngine *>(engines.at(i)); }
- uint fontIndexForFont(CTFontRef id) const;
+ uint fontIndexForFont(CTFontRef font) const;
CTFontRef ctfont;
mutable QCFType<CFMutableDictionaryRef> attributeDict;
CGAffineTransform transform;
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index ffdaaa7..8f2da9b 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -200,9 +200,10 @@ HB_Error QFreetypeFace::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p
* Returns the freetype face or 0 in case of an empty file or any other problems
* (like not being able to open the file)
*/
-QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id)
+QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
+ const QByteArray &fontData)
{
- if (face_id.filename.isEmpty())
+ if (face_id.filename.isEmpty() && fontData.isEmpty())
return 0;
QtFreetypeData *freetypeData = qt_getFreetypeData();
@@ -215,21 +216,25 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id)
} else {
QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace);
FT_Face face;
- QFile file(QString::fromUtf8(face_id.filename));
- if (face_id.filename.startsWith(":qmemoryfonts/")) {
- // from qfontdatabase.cpp
- extern QByteArray qt_fontdata_from_index(int);
- QByteArray idx = face_id.filename;
- idx.remove(0, 14); // remove ':qmemoryfonts/'
- bool ok = false;
- newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
- if (!ok)
- newFreetype->fontData = QByteArray();
- } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
- if (!file.open(QIODevice::ReadOnly)) {
- return 0;
+ if (!face_id.filename.isEmpty()) {
+ QFile file(QString::fromUtf8(face_id.filename));
+ if (face_id.filename.startsWith(":qmemoryfonts/")) {
+ // from qfontdatabase.cpp
+ extern QByteArray qt_fontdata_from_index(int);
+ QByteArray idx = face_id.filename;
+ idx.remove(0, 14); // remove ':qmemoryfonts/'
+ bool ok = false;
+ newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
+ if (!ok)
+ newFreetype->fontData = QByteArray();
+ } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
+ if (!file.open(QIODevice::ReadOnly)) {
+ return 0;
+ }
+ newFreetype->fontData = file.readAll();
}
- newFreetype->fontData = file.readAll();
+ } else {
+ newFreetype->fontData = fontData;
}
if (!newFreetype->fontData.isEmpty()) {
if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
@@ -651,8 +656,21 @@ void QFontEngineFT::freeGlyphSets()
freeServerGlyphSet(transformedGlyphSets.at(i).id);
}
-bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format)
+bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
+ const QByteArray &fontData)
{
+ return init(faceId, antialias, format, QFreetypeFace::getFace(faceId, fontData));
+}
+
+bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
+ QFreetypeFace *freetypeFace)
+{
+ freetype = freetypeFace;
+ if (!freetype) {
+ xsize = 0;
+ ysize = 0;
+ return false;
+ }
defaultFormat = format;
this->antialias = antialias;
@@ -664,12 +682,6 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format)
glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
face_id = faceId;
- freetype = QFreetypeFace::getFace(face_id);
- if (!freetype) {
- xsize = 0;
- ysize = 0;
- return false;
- }
symbol = freetype->symbol_map != 0;
PS_FontInfoRec psrec;
@@ -791,6 +803,106 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
return load_flags;
}
+QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const
+{
+ Glyph *g = set->getGlyph(glyph);
+ if (g && g->format == format)
+ return g;
+
+ bool hsubpixel = false;
+ int vfactor = 1;
+ int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);
+
+ // apply our matrix to this, but note that the metrics will not be affected by this.
+ FT_Face face = lockFace();
+ FT_Matrix matrix = this->matrix;
+ FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
+ FT_Set_Transform(face, &matrix, 0);
+ freetype->matrix = matrix;
+
+ bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0;
+ if (transform)
+ load_flags |= FT_LOAD_NO_BITMAP;
+
+ FT_Error err = FT_Load_Glyph(face, glyph, load_flags);
+ if (err && (load_flags & FT_LOAD_NO_BITMAP)) {
+ load_flags &= ~FT_LOAD_NO_BITMAP;
+ err = FT_Load_Glyph(face, glyph, load_flags);
+ }
+ if (err == FT_Err_Too_Few_Arguments) {
+ // this is an error in the bytecode interpreter, just try to run without it
+ load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ err = FT_Load_Glyph(face, glyph, load_flags);
+ }
+ if (err != FT_Err_Ok)
+ qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
+
+ unlockFace();
+ if (set->outline_drawing)
+ return 0;
+
+ if (!g) {
+ g = new Glyph;
+ g->uploadedToServer = false;
+ g->data = 0;
+ }
+
+ FT_GlyphSlot slot = face->glyph;
+ if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot);
+ int left = slot->metrics.horiBearingX;
+ int right = slot->metrics.horiBearingX + slot->metrics.width;
+ int top = slot->metrics.horiBearingY;
+ int bottom = slot->metrics.horiBearingY - slot->metrics.height;
+ if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { // freetype doesn't apply the transformation on the metrics
+ int l, r, t, b;
+ FT_Vector vector;
+ vector.x = left;
+ vector.y = top;
+ FT_Vector_Transform(&vector, &matrix);
+ l = r = vector.x;
+ t = b = vector.y;
+ vector.x = right;
+ vector.y = top;
+ FT_Vector_Transform(&vector, &matrix);
+ if (l > vector.x) l = vector.x;
+ if (r < vector.x) r = vector.x;
+ if (t < vector.y) t = vector.y;
+ if (b > vector.y) b = vector.y;
+ vector.x = right;
+ vector.y = bottom;
+ FT_Vector_Transform(&vector, &matrix);
+ if (l > vector.x) l = vector.x;
+ if (r < vector.x) r = vector.x;
+ if (t < vector.y) t = vector.y;
+ if (b > vector.y) b = vector.y;
+ vector.x = left;
+ vector.y = bottom;
+ FT_Vector_Transform(&vector, &matrix);
+ if (l > vector.x) l = vector.x;
+ if (r < vector.x) r = vector.x;
+ if (t < vector.y) t = vector.y;
+ if (b > vector.y) b = vector.y;
+ left = l;
+ right = r;
+ top = t;
+ bottom = b;
+ }
+ left = FLOOR(left);
+ right = CEIL(right);
+ bottom = FLOOR(bottom);
+ top = CEIL(top);
+
+ g->linearAdvance = face->glyph->linearHoriAdvance >> 10;
+ g->width = TRUNC(right-left);
+ g->height = TRUNC(top-bottom);
+ g->x = TRUNC(left);
+ g->y = TRUNC(top);
+ g->advance = TRUNC(ROUND(face->glyph->advance.x));
+ g->format = Format_None;
+
+ return g;
+}
+
QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
QFixed subPixelPosition,
GlyphFormat format,
@@ -1511,7 +1623,7 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
mtx->lock();
}
- if (FcCharSetHasChar(freetype->charset, uc)) {
+ if (freetype->charset != 0 && FcCharSetHasChar(freetype->charset, uc)) {
#else
if (false) {
#endif
@@ -1546,7 +1658,7 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
mtx->lock();
}
- if (FcCharSetHasChar(freetype->charset, uc))
+ if (freetype->charset == 0 || FcCharSetHasChar(freetype->charset, uc))
#endif
{
redo:
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 451d26e..887efed 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -74,6 +74,8 @@
QT_BEGIN_NAMESPACE
+class QFontEngineFTRawFont;
+
/*
* This struct represents one font file on disk (like Arial.ttf) and is shared between all the font engines
* that show this font file (at different pixel sizes).
@@ -84,7 +86,8 @@ struct QFreetypeFace
QFontEngine::Properties properties() const;
bool getSfntTable(uint tag, uchar *buffer, uint *length) const;
- static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id);
+ static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id,
+ const QByteArray &fontData = QByteArray());
void release(const QFontEngine::FaceId &face_id);
// locks the struct for usage. Any read/write operations require locking.
@@ -119,6 +122,7 @@ struct QFreetypeFace
static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false);
private:
+ friend class QFontEngineFTRawFont;
friend class QScopedPointerDeleter<QFreetypeFace>;
QFreetypeFace() : _lock(QMutex::Recursive) {}
~QFreetypeFace() {}
@@ -300,7 +304,10 @@ private:
QFontEngineFT(const QFontDef &fd);
virtual ~QFontEngineFT();
- bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None);
+ bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None,
+ const QByteArray &fontData = QByteArray());
+ bool init(FaceId faceId, bool antialias, GlyphFormat format,
+ QFreetypeFace *freetypeFace);
virtual HB_Error getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
@@ -312,6 +319,7 @@ private:
};
void setDefaultHintStyle(HintStyle style);
+ HintStyle defaultHintStyle() const { return default_hint_style; }
protected:
void freeGlyphSets();
@@ -335,6 +343,9 @@ protected:
bool embeddedbitmap;
private:
+ friend class QFontEngineFTRawFont;
+
+ QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const;
int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
GlyphFormat defaultFormat;
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 7751bbe..673a7c8 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -922,27 +922,6 @@ static void addGlyphsToPathHelper(ATSUStyle style, glyph_t *glyphs, QFixedPoint
DisposeATSCubicClosePathUPP(closePath);
}
-QFont QFontEngineMac::createExplicitFont() const
-{
- FMFont fmFont = FMGetFontFromATSFontRef(fontID);
-
- FMFontFamily fmFamily;
- FMFontStyle fmStyle;
- QString familyName;
- if (!FMGetFontFamilyInstanceFromFont(fmFont, &fmFamily, &fmStyle)) {
- ATSFontFamilyRef familyRef = FMGetATSFontFamilyRefFromFontFamily(fmFamily);
- QCFString cfFamilyName;;
- ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &cfFamilyName);
- familyName = cfFamilyName;
- } else {
- QCFString cfFontName;
- ATSFontGetName(fontID, kATSOptionFlagsDefault, &cfFontName);
- familyName = cfFontName;
- }
-
- return createExplicitFontWithName(familyName);
-}
-
void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path,
QTextItem::RenderFlags)
{
diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h
index 6967348..385fa83 100644
--- a/src/gui/text/qfontengine_mac_p.h
+++ b/src/gui/text/qfontengine_mac_p.h
@@ -66,8 +66,6 @@ public:
virtual qreal maxCharWidth() const;
virtual QFixed averageCharWidth() const;
- virtual QFont createExplicitFont() const;
-
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
QPainterPath *path, QTextItem::RenderFlags);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 7b29993..5b39fd3 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -185,9 +185,6 @@ public:
virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags);
- /* Creates a QFont object to represent this particular QFontEngine */
- virtual QFont createExplicitFont() const;
-
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags,
QVarLengthArray<glyph_t> &glyphs_out, QVarLengthArray<QFixedPoint> &positions);
@@ -276,7 +273,6 @@ public:
int glyphFormat;
protected:
- QFont createExplicitFontWithName(const QString &familyName) const;
static const QVector<QRgb> &grayPalette();
QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false);
@@ -431,6 +427,7 @@ public:
protected:
friend class QPSPrintEnginePrivate;
friend class QPSPrintEngineFontMulti;
+ friend class QRawFont;
virtual void loadEngine(int at) = 0;
QVector<QFontEngine *> engines;
};
diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h
index 2a4a9cd..ad68fac 100644
--- a/src/gui/text/qfontengine_x11_p.h
+++ b/src/gui/text/qfontengine_x11_p.h
@@ -157,6 +157,7 @@ private:
class Q_GUI_EXPORT QFontEngineX11FT : public QFontEngineFT
{
public:
+ explicit QFontEngineX11FT(const QFontDef &fontDef) : QFontEngineFT(fontDef) {}
explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen);
~QFontEngineX11FT();
diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp
index af5bab2..f0a3644 100644
--- a/src/gui/text/qfontenginedirectwrite.cpp
+++ b/src/gui/text/qfontenginedirectwrite.cpp
@@ -170,17 +170,12 @@ namespace {
}
-QFontEngineDirectWrite::QFontEngineDirectWrite(const QString &name,
- IDWriteFactory *directWriteFactory,
- IDWriteGdiInterop *directWriteGdiInterop,
- IDWriteFont *directWriteFont,
+QFontEngineDirectWrite::QFontEngineDirectWrite(IDWriteFactory *directWriteFactory,
+ IDWriteFontFace *directWriteFontFace,
qreal pixelSize)
- : m_name(name)
- , m_directWriteFont(directWriteFont)
- , m_directWriteFontFace(0)
+ : m_directWriteFontFace(directWriteFontFace)
, m_directWriteFactory(directWriteFactory)
, m_directWriteBitmapRenderTarget(0)
- , m_directWriteGdiInterop(directWriteGdiInterop)
, m_lineThickness(-1)
, m_unitsPerEm(-1)
, m_ascent(-1)
@@ -188,24 +183,17 @@ QFontEngineDirectWrite::QFontEngineDirectWrite(const QString &name,
, m_xHeight(-1)
, m_lineGap(-1)
{
- m_directWriteFont->AddRef();
m_directWriteFactory->AddRef();
- m_directWriteGdiInterop->AddRef();
+ m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
-
- HRESULT hr = m_directWriteFont->CreateFontFace(&m_directWriteFontFace);
- if (FAILED(hr))
- qErrnoWarning("QFontEngineDirectWrite: CreateFontFace failed");
-
collectMetrics();
}
QFontEngineDirectWrite::~QFontEngineDirectWrite()
{
- m_directWriteFont->Release();
m_directWriteFactory->Release();
- m_directWriteGdiInterop->Release();
+ m_directWriteFontFace->Release();
if (m_directWriteBitmapRenderTarget != 0)
m_directWriteBitmapRenderTarget->Release();
@@ -213,10 +201,10 @@ QFontEngineDirectWrite::~QFontEngineDirectWrite()
void QFontEngineDirectWrite::collectMetrics()
{
- if (m_directWriteFont != 0) {
+ if (m_directWriteFontFace != 0) {
DWRITE_FONT_METRICS metrics;
- m_directWriteFont->GetMetrics(&metrics);
+ m_directWriteFontFace->GetMetrics(&metrics);
m_unitsPerEm = metrics.designUnitsPerEm;
m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
@@ -616,19 +604,25 @@ const char *QFontEngineDirectWrite::name() const
bool QFontEngineDirectWrite::canRender(const QChar *string, int len)
{
- for (int i=0; i<len; ++i) {
- BOOL exists;
- UINT32 codePoint = getChar(string, i, len);
- HRESULT hr = m_directWriteFont->HasCharacter(codePoint, &exists);
- if (FAILED(hr)) {
- qErrnoWarning("QFontEngineDirectWrite::canRender: HasCharacter failed");
- return false;
- } else if (!exists) {
- return false;
+ QVarLengthArray<UINT32> codePoints(len);
+ int actualLength = 0;
+ for (int i=0; i<len; ++i, actualLength++)
+ codePoints[actualLength] = getChar(string, i, len);
+
+ QVarLengthArray<UINT16> glyphIndices(actualLength);
+ HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength,
+ glyphIndices.data());
+ if (FAILED(hr)) {
+ qErrnoWarning(hr, "QFontEngineDirectWrite::canRender: GetGlyphIndices failed");
+ return false;
+ } else {
+ for (int i=0; i<glyphIndices.size(); ++i) {
+ if (glyphIndices.at(i) == 0)
+ return false;
}
- }
- return true;
+ return true;
+ }
}
QFontEngine::Type QFontEngineDirectWrite::type() const
diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h
index 80f90b8..c440a6c 100644
--- a/src/gui/text/qfontenginedirectwrite_p.h
+++ b/src/gui/text/qfontenginedirectwrite_p.h
@@ -69,10 +69,8 @@ class QFontEngineDirectWrite : public QFontEngine
{
Q_OBJECT
public:
- explicit QFontEngineDirectWrite(const QString &name,
- IDWriteFactory *directWriteFactory,
- IDWriteGdiInterop *directWriteGdiInterop,
- IDWriteFont *directWriteFont,
+ explicit QFontEngineDirectWrite(IDWriteFactory *directWriteFactory,
+ IDWriteFontFace *directWriteFontFace,
qreal pixelSize);
~QFontEngineDirectWrite();
@@ -107,15 +105,14 @@ public:
Type type() const;
private:
+ friend class QRawFontPrivate;
+
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
- QString m_name;
- IDWriteFont *m_directWriteFont;
IDWriteFontFace *m_directWriteFontFace;
IDWriteFactory *m_directWriteFactory;
IDWriteBitmapRenderTarget *m_directWriteBitmapRenderTarget;
- IDWriteGdiInterop *m_directWriteGdiInterop;
QFixed m_lineThickness;
int m_unitsPerEm;
diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h
index 501bfff..4057142 100644
--- a/src/gui/text/qfragmentmap_p.h
+++ b/src/gui/text/qfragmentmap_p.h
@@ -195,6 +195,10 @@ public:
head->root = new_root;
}
+ inline bool isValid(uint n) const {
+ return n > 0 && n != head->freelist;
+ }
+
union {
Header *head;
Fragment *fragments;
@@ -854,6 +858,7 @@ public:
return data.fragment(index);
}
inline uint position(uint node, uint field = 0) const { return data.position(node, field); }
+ inline bool isValid(uint n) const { return data.isValid(n); }
inline uint next(uint n) const { return data.next(n); }
inline uint previous(uint n) const { return data.previous(n); }
inline uint size(uint node, uint field = 0) const { return data.size(node, field); }
diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp
index affa08a..b8a418d 100644
--- a/src/gui/text/qglyphs.cpp
+++ b/src/gui/text/qglyphs.cpp
@@ -39,6 +39,10 @@
**
****************************************************************************/
+#include "qglobal.h"
+
+#if !defined(QT_NO_RAWFONT)
+
#include "qglyphs.h"
#include "qglyphs_p.h"
@@ -69,8 +73,14 @@ QT_BEGIN_NAMESPACE
It is the user's responsibility to ensure that the selected font actually contains the
provided glyph indexes.
- QTextLayout::glyphs() can be used to convert unicode encoded text into a list of QGlyphs
- objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
+ QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text
+ into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs.
+
+ \note Please note that QRawFont is considered local to the thread in which it is constructed,
+ which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is
+ moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different
+ thread than the current, it will not be possible to draw the glyphs using a QPainter, as the
+ QRawFont is considered invalid and inaccessible in this case.
*/
@@ -124,6 +134,9 @@ bool QGlyphs::operator==(const QGlyphs &other) const
return ((d == other.d)
|| (d->glyphIndexes == other.d->glyphIndexes
&& d->glyphPositions == other.d->glyphPositions
+ && d->overline == other.d->overline
+ && d->underline == other.d->underline
+ && d->strikeOut == other.d->strikeOut
&& d->font == other.d->font));
}
@@ -171,18 +184,17 @@ QGlyphs &QGlyphs::operator+=(const QGlyphs &other)
\sa setFont()
*/
-QFont QGlyphs::font() const
+QRawFont QGlyphs::font() const
{
return d->font;
}
/*!
- Sets the font in which to look up the glyph indexes to \a font. This must be an explicitly
- resolvable font which defines glyphs for the specified glyph indexes.
+ Sets the font in which to look up the glyph indexes to \a font.
\sa font(), setGlyphIndexes()
*/
-void QGlyphs::setFont(const QFont &font)
+void QGlyphs::setFont(const QRawFont &font)
{
detach();
d->font = font;
@@ -234,7 +246,78 @@ void QGlyphs::clear()
detach();
d->glyphPositions = QVector<QPointF>();
d->glyphIndexes = QVector<quint32>();
- d->font = QFont();
+ d->font = QRawFont();
+ d->strikeOut = false;
+ d->overline = false;
+ d->underline = false;
+}
+
+/*!
+ Returns true if this QGlyphs should be painted with an overline decoration.
+
+ \sa setOverline()
+*/
+bool QGlyphs::overline() const
+{
+ return d->overline;
+}
+
+/*!
+ Indicates that this QGlyphs should be painted with an overline decoration if \a overline is true.
+ Otherwise the QGlyphs should be painted with no overline decoration.
+
+ \sa overline()
+*/
+void QGlyphs::setOverline(bool overline)
+{
+ detach();
+ d->overline = overline;
+}
+
+/*!
+ Returns true if this QGlyphs should be painted with an underline decoration.
+
+ \sa setUnderline()
+*/
+bool QGlyphs::underline() const
+{
+ return d->underline;
+}
+
+/*!
+ Indicates that this QGlyphs should be painted with an underline decoration if \a underline is
+ true. Otherwise the QGlyphs should be painted with no underline decoration.
+
+ \sa underline()
+*/
+void QGlyphs::setUnderline(bool underline)
+{
+ detach();
+ d->underline = underline;
+}
+
+/*!
+ Returns true if this QGlyphs should be painted with a strike out decoration.
+
+ \sa setStrikeOut()
+*/
+bool QGlyphs::strikeOut() const
+{
+ return d->strikeOut;
+}
+
+/*!
+ Indicates that this QGlyphs should be painted with an strike out decoration if \a strikeOut is
+ true. Otherwise the QGlyphs should be painted with no strike out decoration.
+
+ \sa strikeOut()
+*/
+void QGlyphs::setStrikeOut(bool strikeOut)
+{
+ detach();
+ d->strikeOut = strikeOut;
}
QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphs.h
index 5f37136..4d7dcaf 100644
--- a/src/gui/text/qglyphs.h
+++ b/src/gui/text/qglyphs.h
@@ -45,7 +45,9 @@
#include <QtCore/qsharedpointer.h>
#include <QtCore/qvector.h>
#include <QtCore/qpoint.h>
-#include <QtGui/qfont.h>
+#include <QtGui/qrawfont.h>
+
+#if !defined(QT_NO_RAWFONT)
QT_BEGIN_HEADER
@@ -61,8 +63,8 @@ public:
QGlyphs(const QGlyphs &other);
~QGlyphs();
- QFont font() const;
- void setFont(const QFont &font);
+ QRawFont font() const;
+ void setFont(const QRawFont &font);
QVector<quint32> glyphIndexes() const;
void setGlyphIndexes(const QVector<quint32> &glyphIndexes);
@@ -76,6 +78,15 @@ public:
bool operator==(const QGlyphs &other) const;
bool operator!=(const QGlyphs &other) const;
+ void setOverline(bool overline);
+ bool overline() const;
+
+ void setUnderline(bool underline);
+ bool underline() const;
+
+ void setStrikeOut(bool strikeOut);
+ bool strikeOut() const;
+
private:
friend class QGlyphsPrivate;
friend class QTextLine;
@@ -85,12 +96,12 @@ private:
void detach();
QExplicitlySharedDataPointer<QGlyphsPrivate> d;
-
};
QT_END_NAMESPACE
QT_END_HEADER
+#endif // QT_NO_RAWFONT
#endif // QGLYPHS_H
diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphs_p.h
index c632e2f..944f777 100644
--- a/src/gui/text/qglyphs_p.h
+++ b/src/gui/text/qglyphs_p.h
@@ -53,8 +53,12 @@
// We mean it.
//
-#include <qfont.h>
#include "qglyphs.h"
+#include "qrawfont.h"
+
+#include <qfont.h>
+
+#if !defined(QT_NO_RAWFONT)
QT_BEGIN_HEADER
@@ -64,17 +68,30 @@ class QGlyphsPrivate: public QSharedData
{
public:
QGlyphsPrivate()
+ : overline(false)
+ , underline(false)
+ , strikeOut(false)
{
}
QGlyphsPrivate(const QGlyphsPrivate &other)
- : QSharedData(other), glyphIndexes(other.glyphIndexes), glyphPositions(other.glyphPositions), font(other.font)
+ : QSharedData(other)
+ , glyphIndexes(other.glyphIndexes)
+ , glyphPositions(other.glyphPositions)
+ , font(other.font)
+ , overline(other.overline)
+ , underline(other.underline)
+ , strikeOut(other.strikeOut)
{
}
QVector<quint32> glyphIndexes;
QVector<QPointF> glyphPositions;
- QFont font;
+ QRawFont font;
+
+ uint overline : 1;
+ uint underline : 1;
+ uint strikeOut : 1;
};
QT_END_NAMESPACE
@@ -82,3 +99,5 @@ QT_END_NAMESPACE
QT_END_HEADER
#endif // QGLYPHS_P_H
+
+#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
new file mode 100644
index 0000000..4a715c2
--- /dev/null
+++ b/src/gui/text/qrawfont.cpp
@@ -0,0 +1,612 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "qglobal.h"
+
+#if !defined(QT_NO_RAWFONT)
+
+#include "qrawfont.h"
+#include "qrawfont_p.h"
+
+#include <QtCore/qthread.h>
+#include <QtCore/qendian.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QRawFont
+ \brief The QRawFont class provides access to a single physical instance of a font.
+ \since 4.8
+
+ \ingroup text
+ \mainclass
+
+ \note QRawFont is a low level class. For most purposes QFont is a more appropriate class.
+
+ Most commonly, when presenting text in a user interface, the exact fonts used
+ to render the characters is to some extent unknown. This can be the case for several
+ reasons: For instance, the actual, physical fonts present on the target system could be
+ unexpected to the developers, or the text could contain user selected styles, sizes or
+ writing systems that are not supported by font chosen in the code.
+
+ Therefore, Qt's QFont class really represents a query for fonts. When text is interpreted,
+ Qt will do its best to match the text to the query, but depending on the support, different
+ fonts can be used behind the scenes.
+
+ For most use cases, this is both expected and necessary, as it minimizes the possibility of
+ text in the user interface being undisplayable. In some cases, however, more direct control
+ over the process might be useful. It is for these use cases the QRawFont class exists.
+
+ A QRawFont object represents a single, physical instance of a given font in a given pixel size.
+ I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a
+ user specified pixel size to convert metrics into logical pixel units. In can be used in
+ combination with the QGlyphs class to draw specific glyph indexes at specific positions, and
+ also have accessors to some relevant data in the physical font.
+
+ QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows
+ platforms, FreeType on Symbian and Linux platforms and CoreText on Mac OS X. For other
+ font back-ends, the APIs will be disabled.
+
+ QRawFont can be constructed in a number of ways:
+ \list
+ \o \l It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The
+ returned QGlyphs objects will contain QRawFont objects which represent the actual fonts
+ used to render each portion of the text.
+ \o \l It can be constructed by passing a QFont object to QRawFont::fromFont(). The function
+ will return a QRawFont object representing the font that will be selected as response to
+ the QFont query and the selected writing system.
+ \o \l It can be constructed by passing a file name or QByteArray directly to the QRawFont
+ constructor, or by calling loadFromFile() or loadFromData(). In this case, the
+ font will not be registered in QFontDatabase, and it will not be available as part of
+ regular font selection.
+ \endlist
+
+ QRawFont is considered local to the thread in which it is constructed (either using a
+ constructor, or by calling loadFromData() or loadFromFile()). The QRawFont cannot be moved to a
+ different thread, but will have to be recreated in the thread in question.
+
+ \note For the requirement of caching glyph indexes and font selections for static text to avoid
+ reshaping and relayouting in the inner loop of an application, a better choice is the QStaticText
+ class, since it optimizes the memory cost of the cache and also provides the possibility of paint
+ engine specific caches for an additional speed-up.
+*/
+
+/*!
+ \enum QRawFont::AntialiasingType
+
+ This enum represents the different ways a glyph can be rasterized in the function
+ alphaMapForGlyph().
+
+ \value PixelAntialiasing Will rasterize by measuring the coverage of the shape on whole pixels.
+ The returned image contains the alpha values of each pixel based on the coverage of
+ the glyph shape.
+ \value SubPixelAntialiasing Will rasterize by measuring the coverage of each subpixel,
+ returning a separate alpha value for each of the red, green and blue components of
+ each pixel.
+*/
+
+/*!
+ Constructs an invalid QRawFont.
+*/
+QRawFont::QRawFont()
+ : d(new QRawFontPrivate)
+{
+}
+
+/*!
+ Constructs a QRawFont representing the font contained in the file referenced by \a fileName,
+ with \a pixelSize size in pixels, and the selected \a hintingPreference.
+
+ \note The referenced file must contain a TrueType or OpenType font.
+*/
+QRawFont::QRawFont(const QString &fileName,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+ : d(new QRawFontPrivate)
+{
+ loadFromFile(fileName, pixelSize, hintingPreference);
+}
+
+/*!
+ Constructs a QRawFont representing the font contained in \a fontData.
+
+ \note The data must contain a TrueType or OpenType font.
+*/
+QRawFont::QRawFont(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+ : d(new QRawFontPrivate)
+{
+ loadFromData(fontData, pixelSize, hintingPreference);
+}
+
+/*!
+ Creates a QRawFont which is a copy of \a other.
+*/
+QRawFont::QRawFont(const QRawFont &other)
+{
+ d = other.d;
+}
+
+/*!
+ Destroys the QRawFont
+*/
+QRawFont::~QRawFont()
+{
+}
+
+/*!
+ Assigns \a other to this QRawFont.
+*/
+QRawFont &QRawFont::operator=(const QRawFont &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns true if the QRawFont is valid and false otherwise.
+*/
+bool QRawFont::isValid() const
+{
+ Q_ASSERT(d->thread == 0 || d->thread == QThread::currentThread());
+ return d->fontEngine != 0;
+}
+
+/*!
+ Replaces the current QRawFont with the contents of the file references by \a fileName.
+
+ The file must reference a TrueType or OpenType font.
+
+ \sa loadFromData()
+*/
+void QRawFont::loadFromFile(const QString &fileName,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly))
+ loadFromData(file.readAll(), pixelSize, hintingPreference);
+}
+
+/*!
+ Replaces the current QRawFont with the contents of \a fontData.
+
+ The \a fontData must contain a TrueType or OpenType font.
+
+ \sa loadFromFile()
+*/
+void QRawFont::loadFromData(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ detach();
+ d->cleanUp();
+ d->hintingPreference = hintingPreference;
+ d->thread = QThread::currentThread();
+ d->platformLoadFromData(fontData, pixelSize, hintingPreference);
+}
+
+/*!
+ This function returns a rasterized image of the glyph at a given \a glyphIndex in the underlying
+ font, if the QRawFont is valid, otherwise it will return an invalid QImage.
+
+ If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be
+ in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of
+ the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of
+ QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization.
+
+ \sa pathForGlyph(), QPainter::drawGlyphs()
+*/
+QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType,
+ const QTransform &transform) const
+{
+ if (!isValid())
+ return QImage();
+
+ if (antialiasingType == SubPixelAntialiasing)
+ return d->fontEngine->alphaRGBMapForGlyph(glyphIndex, QFixed(), 0, transform);
+ else
+ return d->fontEngine->alphaMapForGlyph(glyphIndex, QFixed(), transform);
+}
+
+/*!
+ This function returns the shape of the glyph at a given \a glyphIndex in the underlying font
+ if the QRawFont is valid. Otherwise, it returns an empty QPainterPath.
+
+ The returned glyph will always be unhinted.
+
+ \sa alphaMapForGlyph(), QPainterPath::addText()
+*/
+QPainterPath QRawFont::pathForGlyph(quint32 glyphIndex) const
+{
+ if (!isValid())
+ return QPainterPath();
+
+ QFixedPoint position;
+ QPainterPath path;
+ d->fontEngine->addGlyphsToPath(&glyphIndex, &position, 1, &path, 0);
+ return path;
+}
+
+/*!
+ Returns true if this QRawFont is equal to \a other. Otherwise, returns false.
+*/
+bool QRawFont::operator==(const QRawFont &other) const
+{
+ return d->fontEngine == other.d->fontEngine;
+}
+
+/*!
+ Returns the ascent of this QRawFont in pixel units.
+
+ \sa QFontMetricsF::ascent()
+*/
+qreal QRawFont::ascent() const
+{
+ if (!isValid())
+ return 0.0;
+
+ return d->fontEngine->ascent().toReal();
+}
+
+/*!
+ Returns the descent of this QRawFont in pixel units.
+
+ \sa QFontMetricsF::descent()
+*/
+qreal QRawFont::descent() const
+{
+ if (!isValid())
+ return 0.0;
+
+ return d->fontEngine->descent().toReal();
+}
+
+/*!
+ Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are
+ rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert
+ internal metrics from design units to logical pixel units.
+
+ \sa setPixelSize()
+*/
+int QRawFont::pixelSize() const
+{
+ if (!isValid())
+ return -1;
+
+ return d->fontEngine->fontDef.pixelSize;
+}
+
+/*!
+ Returns the number of design units define the width and height of the em square
+ for this QRawFont. This value is used together with the pixel size when converting design metrics
+ to pixel units, as the internal metrics are specified in design units and the pixel size gives
+ the size of 1 em in pixels.
+
+ \sa pixelSize(), setPixelSize()
+*/
+qreal QRawFont::unitsPerEm() const
+{
+ if (!isValid())
+ return 0.0;
+
+ return d->fontEngine->emSquareSize().toReal();
+}
+
+/*!
+ Returns the family name of this QRawFont.
+*/
+QString QRawFont::familyName() const
+{
+ if (!isValid())
+ return QString();
+
+ return d->fontEngine->fontDef.family;
+}
+
+/*!
+ Returns the style of this QRawFont.
+
+ \sa QFont::style()
+*/
+QFont::Style QRawFont::style() const
+{
+ if (!isValid())
+ return QFont::StyleNormal;
+
+ return QFont::Style(d->fontEngine->fontDef.style);
+}
+
+/*!
+ Returns the weight of this QRawFont.
+
+ \sa QFont::weight()
+*/
+int QRawFont::weight() const
+{
+ if (!isValid())
+ return -1;
+
+ return int(d->fontEngine->fontDef.weight);
+}
+
+/*!
+ Converts a string of unicode points to glyph indexes using the CMAP table in the
+ underlying font. Note that in cases where there are other tables in the font that affect the
+ shaping of the text, the returned glyph indexes will not correctly represent the rendering
+ of the text. To get the correctly shaped text, you can use QTextLayout to lay out and shape the
+ text, and then call QTextLayout::glyphs() to get the set of glyph index list and QRawFont pairs.
+
+ \sa advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs()
+*/
+QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
+{
+ if (!isValid())
+ return QVector<quint32>();
+
+ int nglyphs = text.size();
+ QVarLengthGlyphLayoutArray glyphs(nglyphs);
+ if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs,
+ QTextEngine::GlyphIndicesOnly)) {
+ glyphs.resize(nglyphs);
+ if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs,
+ QTextEngine::GlyphIndicesOnly)) {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
+ return QVector<quint32>();
+ }
+ }
+
+ QVector<quint32> glyphIndexes;
+ for (int i=0; i<nglyphs; ++i)
+ glyphIndexes.append(glyphs.glyphs[i]);
+
+ return glyphIndexes;
+}
+
+/*!
+ Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances
+ give the distance from the position of a given glyph to where the next glyph should be drawn
+ to make it appear as if the two glyphs are unspaced.
+
+ \sa QTextLine::horizontalAdvance(), QFontMetricsF::width()
+*/
+QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const
+{
+ if (!isValid())
+ return QVector<QPointF>();
+
+ int numGlyphs = glyphIndexes.size();
+ QVarLengthGlyphLayoutArray glyphs(numGlyphs);
+ qMemCopy(glyphs.glyphs, glyphIndexes.data(), numGlyphs * sizeof(quint32));
+
+ d->fontEngine->recalcAdvances(&glyphs, 0);
+
+ QVector<QPointF> advances;
+ for (int i=0; i<numGlyphs; ++i)
+ advances.append(QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()));
+
+ return advances;
+}
+
+/*!
+ Returns the hinting preference used to construct this QRawFont.
+
+ \sa QFont::hintingPreference()
+*/
+QFont::HintingPreference QRawFont::hintingPreference() const
+{
+ if (!isValid())
+ return QFont::PreferDefaultHinting;
+
+ return d->hintingPreference;
+}
+
+/*!
+ Retrieves the sfnt table named \a tagName from the underlying physical font, or an empty
+ byte array if no such table was found. The returned font table's byte order is Big Endian, like
+ the sfnt format specifies. The \a tagName must be four characters long and should be formatted
+ in the default endianness of the current platform.
+*/
+QByteArray QRawFont::fontTable(const char *tagName) const
+{
+ if (!isValid())
+ return QByteArray();
+
+ const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName);
+ return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
+}
+
+// From qfontdatabase.cpp
+extern QList<QFontDatabase::WritingSystem> qt_determine_writing_systems_from_truetype_bits(quint32 unicodeRange[4], quint32 codePageRange[2]);
+
+/*!
+ Returns a list of writing systems supported by the font according to designer supplied
+ information in the font file. Please note that this does not guarantee support for a
+ specific unicode point in the font. You can use the supportsCharacter() to check support
+ for a single, specific character.
+
+ \note The list is determined based on the unicode ranges and codepage ranges set in the font's
+ OS/2 table and requires such a table to be present in the underlying font file.
+
+ \sa supportsCharacter()
+*/
+QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const
+{
+ if (isValid()) {
+ QByteArray os2Table = fontTable("OS/2");
+ if (!os2Table.isEmpty() && os2Table.size() > 86) {
+ char *data = os2Table.data();
+ quint32 *bigEndianUnicodeRanges = reinterpret_cast<quint32 *>(data + 42);
+ quint32 *bigEndianCodepageRanges = reinterpret_cast<quint32 *>(data + 78);
+
+ quint32 unicodeRanges[4];
+ quint32 codepageRanges[2];
+
+ for (int i=0; i<4; ++i) {
+ if (i < 2)
+ codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]);
+ unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]);
+ }
+
+ return qt_determine_writing_systems_from_truetype_bits(unicodeRanges, codepageRanges);
+ }
+ }
+
+ return QList<QFontDatabase::WritingSystem>();
+}
+
+/*!
+ Returns true if the font has a glyph that corresponds to the given \a character.
+
+ \sa supportedWritingSystems()
+*/
+bool QRawFont::supportsCharacter(const QChar &character) const
+{
+ if (!isValid())
+ return false;
+
+ return d->fontEngine->canRender(&character, 1);
+}
+
+/*!
+ Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4.
+
+ \sa supportedWritingSystems()
+*/
+bool QRawFont::supportsCharacter(quint32 ucs4) const
+{
+ if (!isValid())
+ return false;
+
+ QString str = QString::fromUcs4(&ucs4, 1);
+ return d->fontEngine->canRender(str.constData(), str.size());
+}
+
+// qfontdatabase.cpp
+extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
+
+/*!
+ Fetches the physical representation based on a \a font query. The physical font returned is
+ the font that will be preferred by Qt in order to display text in the selected \a writingSystem.
+*/
+QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
+{
+#if defined(Q_WS_MAC)
+ QTextLayout layout(QFontDatabase::writingSystemSample(writingSystem), font);
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
+ QList<QGlyphs> list = layout.glyphs();
+ if (list.size()) {
+ // Pick the one matches the family name we originally requested,
+ // if none of them match, just pick the first one
+ for (int i = 0; i < list.size(); i++) {
+ QGlyphs glyphs = list.at(i);
+ QRawFont rawfont = glyphs.font();
+ if (rawfont.familyName() == font.family())
+ return rawfont;
+ }
+ return list.at(0).font();
+ }
+ return QRawFont();
+#else
+ QFontPrivate *font_d = QFontPrivate::get(font);
+ int script = qt_script_for_writing_system(writingSystem);
+ QFontEngine *fe = font_d->engineForScript(script);
+
+ if (fe != 0 && fe->type() == QFontEngine::Multi) {
+ QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
+ fe = multiEngine->engine(0);
+ if (fe == 0) {
+ multiEngine->loadEngine(0);
+ fe = multiEngine->engine(0);
+ }
+ }
+
+ if (fe != 0) {
+ QRawFont rawFont;
+ rawFont.d.data()->fontEngine = fe;
+ rawFont.d.data()->fontEngine->ref.ref();
+ rawFont.d.data()->hintingPreference = font.hintingPreference();
+ return rawFont;
+ } else {
+ return QRawFont();
+ }
+#endif
+}
+
+/*!
+ Sets the pixel size with which this font should be rendered to \a pixelSize.
+*/
+void QRawFont::setPixelSize(int pixelSize)
+{
+ detach();
+ d->platformSetPixelSize(pixelSize);
+}
+
+/*!
+ \internal
+*/
+void QRawFont::detach()
+{
+ if (d->ref != 1)
+ d.detach();
+}
+
+/*!
+ \internal
+*/
+void QRawFontPrivate::cleanUp()
+{
+ platformCleanUp();
+ if (fontEngine != 0) {
+ fontEngine->ref.deref();
+ if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
+ delete fontEngine;
+ fontEngine = 0;
+ }
+ hintingPreference = QFont::PreferDefaultHinting;
+}
+
+#endif // QT_NO_RAWFONT
+
+QT_END_NAMESPACE
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
new file mode 100644
index 0000000..96dc838
--- /dev/null
+++ b/src/gui/text/qrawfont.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QRAWFONT_H
+#define QRAWFONT_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qiodevice.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+#include <QtCore/qpoint.h>
+#include <QtGui/qfont.h>
+#include <QtGui/qtransform.h>
+#include <QtGui/qfontdatabase.h>
+
+#if !defined(QT_NO_RAWFONT)
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QRawFontPrivate;
+class Q_GUI_EXPORT QRawFont
+{
+public:
+ enum AntialiasingType {
+ PixelAntialiasing,
+ SubPixelAntialiasing
+ };
+
+ QRawFont();
+ QRawFont(const QString &fileName,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
+ QRawFont(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
+ QRawFont(const QRawFont &other);
+ ~QRawFont();
+
+ bool isValid() const;
+
+ QRawFont &operator=(const QRawFont &other);
+ bool operator==(const QRawFont &other) const;
+
+ QString familyName() const;
+
+ QFont::Style style() const;
+ int weight() const;
+
+ QVector<quint32> glyphIndexesForString(const QString &text) const;
+ QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const;
+
+ QImage alphaMapForGlyph(quint32 glyphIndex,
+ AntialiasingType antialiasingType = SubPixelAntialiasing,
+ const QTransform &transform = QTransform()) const;
+ QPainterPath pathForGlyph(quint32 glyphIndex) const;
+
+ void setPixelSize(int pixelSize);
+ int pixelSize() const;
+
+ QFont::HintingPreference hintingPreference() const;
+
+ qreal ascent() const;
+ qreal descent() const;
+
+ qreal unitsPerEm() const;
+
+ void loadFromFile(const QString &fileName,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference);
+
+ void loadFromData(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference);
+
+ bool supportsCharacter(quint32 ucs4) const;
+ bool supportsCharacter(const QChar &character) const;
+ QList<QFontDatabase::WritingSystem> supportedWritingSystems() const;
+
+ QByteArray fontTable(const char *tagName) const;
+
+ static QRawFont fromFont(const QFont &font,
+ QFontDatabase::WritingSystem writingSystem = QFontDatabase::Any);
+
+private:
+ friend class QRawFontPrivate;
+
+ void detach();
+
+ QExplicitlySharedDataPointer<QRawFontPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_RAWFONT
+
+#endif // QRAWFONT_H
diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp
new file mode 100644
index 0000000..eefbd92
--- /dev/null
+++ b/src/gui/text/qrawfont_ft.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 <QtCore/qglobal.h>
+
+#if !defined(QT_NO_RAWFONT)
+
+#include "qrawfont_p.h"
+#include "qfontengine_ft_p.h"
+
+#if defined(Q_WS_X11)
+# include "qfontengine_x11_p.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QFontEngineFTRawFont
+
+#if defined(Q_WS_X11)
+ : public QFontEngineX11FT
+#else
+ : public QFontEngineFT
+#endif
+
+{
+public:
+ QFontEngineFTRawFont(const QFontDef &fontDef)
+#if defined(Q_WS_X11)
+ : QFontEngineX11FT(fontDef)
+#else
+ : QFontEngineFT(fontDef)
+#endif
+ {
+ }
+
+ void updateFamilyNameAndStyle()
+ {
+ fontDef.family = QString::fromAscii(freetype->face->family_name);
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
+ fontDef.style = QFont::StyleItalic;
+
+ if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
+ fontDef.weight = QFont::Bold;
+ }
+
+ bool initFromData(const QByteArray &fontData)
+ {
+ FaceId faceId;
+ faceId.filename = "";
+ faceId.index = 0;
+
+ return init(faceId, true, Format_None, fontData);
+ }
+
+ bool initFromFontEngine(QFontEngine *oldFontEngine)
+ {
+ QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine);
+
+ // Increase the reference of this QFreetypeFace since one more QFontEngineFT
+ // will be using it
+ fe->freetype->ref.ref();
+ if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
+ return false;
+
+ default_load_flags = fe->default_load_flags;
+ default_hint_style = fe->default_hint_style;
+ antialias = fe->antialias;
+ transform = fe->transform;
+ embolden = fe->embolden;
+ subpixelType = fe->subpixelType;
+ lcdFilterType = fe->lcdFilterType;
+ canUploadGlyphsToServer = fe->canUploadGlyphsToServer;
+ embeddedbitmap = fe->embeddedbitmap;
+
+#if defined(Q_WS_X11)
+ xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format;
+#endif
+ return true;
+ }
+};
+
+
+void QRawFontPrivate::platformCleanUp()
+{
+ // Font engine handles all resources
+}
+
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ Q_ASSERT(fontEngine == 0);
+
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+
+ QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
+ if (!fe->initFromData(fontData)) {
+ delete fe;
+ return;
+ }
+
+ fe->updateFamilyNameAndStyle();
+
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintNone);
+ break;
+ case QFont::PreferFullHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintFull);
+ break;
+ case QFont::PreferVerticalHinting:
+ fe->setDefaultHintStyle(QFontEngineFT::HintLight);
+ break;
+ default:
+ // Leave it as it is
+ break;
+ }
+
+ fontEngine = fe;
+ fontEngine->ref.ref();
+}
+
+void QRawFontPrivate::platformSetPixelSize(int pixelSize)
+{
+ if (fontEngine == NULL)
+ return;
+
+ QFontEngine *oldFontEngine = fontEngine;
+
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+ QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef);
+ if (!fe->initFromFontEngine(oldFontEngine)) {
+ delete fe;
+ return;
+ }
+
+ fontEngine = fe;
+ fontEngine->fontDef = oldFontEngine->fontDef;
+ fontEngine->fontDef.pixelSize = pixelSize;
+ fontEngine->ref.ref();
+ Q_ASSERT(fontEngine != oldFontEngine);
+ oldFontEngine->ref.deref();
+ if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
+ delete oldFontEngine;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp
new file mode 100644
index 0000000..56005c6
--- /dev/null
+++ b/src/gui/text/qrawfont_mac.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 <QtCore/qglobal.h>
+
+#if !defined(QT_NO_RAWFONT)
+
+#include "qrawfont_p.h"
+#include "qfontengine_coretext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+void QRawFontPrivate::platformCleanUp()
+{
+}
+
+extern int qt_defaultDpi();
+
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ // Mac OS X ignores it
+ Q_UNUSED(hintingPreference);
+
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(NULL,
+ fontData.constData(), fontData.size(), NULL);
+
+ CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
+
+ if (cgFont == NULL) {
+ qWarning("QRawFont::platformLoadFromData: CGFontCreateWithDataProvider failed");
+ } else {
+ QFontDef def;
+ def.pixelSize = pixelSize;
+ def.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+ fontEngine = new QCoreTextFontEngine(cgFont, def);
+ CFRelease(cgFont);
+ fontEngine->ref.ref();
+ }
+}
+
+void QRawFontPrivate::platformSetPixelSize(int pixelSize)
+{
+ if (fontEngine == NULL)
+ return;
+
+ QFontEngine *oldFontEngine = fontEngine;
+
+ QFontDef fontDef = oldFontEngine->fontDef;
+ fontDef.pixelSize = pixelSize;
+ fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+
+ QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine);
+ Q_ASSERT(ctFontEngine->cgFont);
+
+ fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef);
+ fontEngine->ref.ref();
+ Q_ASSERT(fontEngine != oldFontEngine);
+ oldFontEngine->ref.deref();
+ if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
+ delete oldFontEngine;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
new file mode 100644
index 0000000..f9a9ab5
--- /dev/null
+++ b/src/gui/text/qrawfont_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QRAWFONTPRIVATE_P_H
+#define QRAWFONTPRIVATE_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 "qrawfont.h"
+#include "qfontengine_p.h"
+#include <QtCore/qthreadstorage.h>
+
+#if !defined(QT_NO_RAWFONT)
+
+QT_BEGIN_NAMESPACE
+
+namespace { class CustomFontFileLoader; }
+class Q_AUTOTEST_EXPORT QRawFontPrivate
+{
+public:
+ QRawFontPrivate()
+ : fontEngine(0)
+ , hintingPreference(QFont::PreferDefaultHinting)
+ , thread(0)
+#if defined(Q_WS_WIN)
+ , fontHandle(NULL)
+ , ptrAddFontMemResourceEx(NULL)
+ , ptrRemoveFontMemResourceEx(NULL)
+#endif
+ {}
+
+ QRawFontPrivate(const QRawFontPrivate &other)
+ : hintingPreference(other.hintingPreference)
+ , thread(other.thread)
+#if defined(Q_WS_WIN)
+ , fontHandle(NULL)
+ , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx)
+ , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx)
+ , uniqueFamilyName(other.uniqueFamilyName)
+#endif
+ {
+ fontEngine = other.fontEngine;
+ if (fontEngine != 0)
+ fontEngine->ref.ref();
+ }
+
+ ~QRawFontPrivate()
+ {
+ Q_ASSERT(ref == 0);
+ cleanUp();
+ }
+
+ void cleanUp();
+ void platformCleanUp();
+ void platformLoadFromData(const QByteArray &fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference);
+ void platformSetPixelSize(int pixelSize);
+
+ static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
+
+ QFontEngine *fontEngine;
+ QFont::HintingPreference hintingPreference;
+ QThread *thread;
+ QAtomicInt ref;
+
+#if defined(Q_WS_WIN)
+ HANDLE fontHandle;
+
+ typedef HANDLE (WINAPI *PtrAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
+ typedef BOOL (WINAPI *PtrRemoveFontMemResourceEx)(HANDLE);
+
+ PtrAddFontMemResourceEx ptrAddFontMemResourceEx;
+ PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx;
+
+ QString uniqueFamilyName;
+
+#endif // Q_WS_WIN
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
+
+#endif // QRAWFONTPRIVATE_P_H
diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp
new file mode 100644
index 0000000..fb5c6f4
--- /dev/null
+++ b/src/gui/text/qrawfont_win.cpp
@@ -0,0 +1,750 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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 "qrawfont_p.h"
+#include <private/qsystemlibrary_p.h>
+
+#if !defined(QT_NO_DIRECTWRITE)
+# include "qfontenginedirectwrite_p.h"
+# include <dwrite.h>
+#endif
+
+#if !defined(QT_NO_RAWFONT)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+
+ template<typename T>
+ struct BigEndian
+ {
+ quint8 data[sizeof(T)];
+
+ operator T() const
+ {
+ T littleEndian = 0;
+ for (int i=0; i<sizeof(T); ++i) {
+ littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8);
+ }
+
+ return littleEndian;
+ }
+
+ BigEndian<T> &operator=(const T &t)
+ {
+ for (int i=0; i<sizeof(T); ++i) {
+ data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff);
+ }
+
+ return *this;
+ }
+ };
+
+# pragma pack(1)
+
+ // Common structure for all formats of the "name" table
+ struct NameTable
+ {
+ BigEndian<quint16> format;
+ BigEndian<quint16> count;
+ BigEndian<quint16> stringOffset;
+ };
+
+ struct NameRecord
+ {
+ BigEndian<quint16> platformID;
+ BigEndian<quint16> encodingID;
+ BigEndian<quint16> languageID;
+ BigEndian<quint16> nameID;
+ BigEndian<quint16> length;
+ BigEndian<quint16> offset;
+ };
+
+ struct OffsetSubTable
+ {
+ BigEndian<quint32> scalerType;
+ BigEndian<quint16> numTables;
+ BigEndian<quint16> searchRange;
+ BigEndian<quint16> entrySelector;
+ BigEndian<quint16> rangeShift;
+ };
+
+ struct TableDirectory
+ {
+ BigEndian<quint32> identifier;
+ BigEndian<quint32> checkSum;
+ BigEndian<quint32> offset;
+ BigEndian<quint32> length;
+ };
+
+ struct OS2Table
+ {
+ BigEndian<quint16> version;
+ BigEndian<qint16> avgCharWidth;
+ BigEndian<quint16> weightClass;
+ BigEndian<quint16> widthClass;
+ BigEndian<quint16> type;
+ BigEndian<qint16> subscriptXSize;
+ BigEndian<qint16> subscriptYSize;
+ BigEndian<qint16> subscriptXOffset;
+ BigEndian<qint16> subscriptYOffset;
+ BigEndian<qint16> superscriptXSize;
+ BigEndian<qint16> superscriptYSize;
+ BigEndian<qint16> superscriptXOffset;
+ BigEndian<qint16> superscriptYOffset;
+ BigEndian<qint16> strikeOutSize;
+ BigEndian<qint16> strikeOutPosition;
+ BigEndian<qint16> familyClass;
+ quint8 panose[10];
+ BigEndian<quint32> unicodeRanges[4];
+ quint8 vendorID[4];
+ BigEndian<quint16> selection;
+ BigEndian<quint16> firstCharIndex;
+ BigEndian<quint16> lastCharIndex;
+ BigEndian<qint16> typoAscender;
+ BigEndian<qint16> typoDescender;
+ BigEndian<qint16> typoLineGap;
+ BigEndian<quint16> winAscent;
+ BigEndian<quint16> winDescent;
+ BigEndian<quint32> codepageRanges[2];
+ BigEndian<qint16> height;
+ BigEndian<qint16> capHeight;
+ BigEndian<quint16> defaultChar;
+ BigEndian<quint16> breakChar;
+ BigEndian<quint16> maxContext;
+ };
+
+# pragma pack()
+
+ class EmbeddedFont
+ {
+ public:
+ EmbeddedFont(const QByteArray &fontData);
+
+ QString changeFamilyName(const QString &newFamilyName);
+ QByteArray data() const { return m_fontData; }
+ TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
+ QString familyName(TableDirectory *nameTableDirectory = 0);
+
+ private:
+ QByteArray m_fontData;
+ };
+
+ EmbeddedFont::EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData)
+ {
+ }
+
+ TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
+ {
+ Q_ASSERT(tagName.size() == 4);
+
+ const BigEndian<quint32> *tagIdPtr =
+ reinterpret_cast<const BigEndian<quint32> *>(tagName.constData());
+ quint32 tagId = *tagIdPtr;
+
+ OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
+ TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
+
+ TableDirectory *nameTableDirectoryEntry = 0;
+ for (int i=0; i<offsetSubTable->numTables; ++i, ++tableDirectory) {
+ if (tableDirectory->identifier == tagId) {
+ nameTableDirectoryEntry = tableDirectory;
+ break;
+ }
+ }
+
+ return nameTableDirectoryEntry;
+ }
+
+ QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
+ {
+ QString name;
+
+ if (nameTableDirectoryEntry == 0)
+ nameTableDirectoryEntry = tableDirectoryEntry("name");
+
+ if (nameTableDirectoryEntry != 0) {
+ NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data()
+ + nameTableDirectoryEntry->offset);
+ NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
+ for (int i=0; i<nameTable->count; ++i, ++nameRecord) {
+ if (nameRecord->nameID == 1
+ && nameRecord->platformID == 3 // Windows
+ && nameRecord->languageID == 0x0409) { // US English
+ const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
+ + nameTable->stringOffset
+ + nameRecord->offset;
+
+ const BigEndian<quint16> *s = reinterpret_cast<const BigEndian<quint16> *>(ptr);
+ for (int j=0; j<nameRecord->length / sizeof(quint16); ++j)
+ name += QChar(s[j]);
+
+ break;
+ }
+ }
+ }
+
+ return name;
+ }
+
+ QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
+ {
+ TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
+ if (nameTableDirectoryEntry == 0)
+ return QString();
+
+ QString oldFamilyName = familyName(nameTableDirectoryEntry);
+
+ // Reserve size for name table header, five required name records and string
+ const int requiredRecordCount = 5;
+ quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
+
+ int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
+ int newFamilyNameSize = newFamilyName.size() * sizeof(quint16);
+
+ const QString regularString = QString::fromLatin1("Regular");
+ int regularStringSize = regularString.size() * sizeof(quint16);
+
+ // Align table size of table to 32 bits (pad with 0)
+ int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
+
+ QByteArray newNameTable(fullSize, char(0));
+
+ {
+ NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
+ nameTable->count = requiredRecordCount;
+ nameTable->stringOffset = sizeOfHeader;
+
+ NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
+ for (int i=0; i<requiredRecordCount; ++i, nameRecord++) {
+ nameRecord->nameID = nameIds[i];
+ nameRecord->encodingID = 1;
+ nameRecord->languageID = 0x0409;
+ nameRecord->platformID = 3;
+ nameRecord->length = newFamilyNameSize;
+
+ // Special case for sub-family
+ if (nameIds[i] == 4) {
+ nameRecord->offset = newFamilyNameSize;
+ nameRecord->length = regularStringSize;
+ }
+ }
+
+ // nameRecord now points to string data
+ BigEndian<quint16> *stringStorage = reinterpret_cast<BigEndian<quint16> *>(nameRecord);
+ const quint16 *sourceString = newFamilyName.utf16();
+ for (int i=0; i<newFamilyName.size(); ++i)
+ stringStorage[i] = sourceString[i];
+ stringStorage += newFamilyName.size();
+
+ sourceString = regularString.utf16();
+ for (int i=0; i<regularString.size(); ++i)
+ stringStorage[i] = sourceString[i];
+ }
+
+ quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
+ quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
+
+ quint32 checkSum = 0;
+ while (p < tableEnd)
+ checkSum += *(p++);
+
+ nameTableDirectoryEntry->checkSum = checkSum;
+ nameTableDirectoryEntry->offset = m_fontData.size();
+ nameTableDirectoryEntry->length = fullSize;
+
+ m_fontData.append(newNameTable);
+
+ return oldFamilyName;
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+
+ class DirectWriteFontFileStream: public IDWriteFontFileStream
+ {
+ public:
+ DirectWriteFontFileStream(const QByteArray &fontData)
+ : m_fontData(fontData)
+ , m_referenceCount(0)
+ {
+ }
+
+ ~DirectWriteFontFileStream()
+ {
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
+ UINT64 fragmentSize, OUT void **fragmentContext);
+ void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
+ HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
+ HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
+
+ private:
+ QByteArray m_fontData;
+ ULONG m_referenceCount;
+ };
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
+ {
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
+ *object = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
+ {
+ return InterlockedIncrement(&m_referenceCount);
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
+ {
+ ULONG newCount = InterlockedDecrement(&m_referenceCount);
+ if (newCount == 0)
+ delete this;
+ return newCount;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
+ const void **fragmentStart,
+ UINT64 fileOffset,
+ UINT64 fragmentSize,
+ OUT void **fragmentContext)
+ {
+ *fragmentContext = NULL;
+ if (fragmentSize + fileOffset <= m_fontData.size()) {
+ *fragmentStart = m_fontData.data() + fileOffset;
+ return S_OK;
+ } else {
+ *fragmentStart = NULL;
+ return E_FAIL;
+ }
+ }
+
+ void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
+ {
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
+ {
+ *fileSize = m_fontData.size();
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
+ {
+ *lastWriteTime = 0;
+ return E_NOTIMPL;
+ }
+
+ class DirectWriteFontFileLoader: public IDWriteFontFileLoader
+ {
+ public:
+ DirectWriteFontFileLoader() : m_referenceCount(0) {}
+
+ ~DirectWriteFontFileLoader()
+ {
+ }
+
+ inline void addKey(const void *key, const QByteArray &fontData)
+ {
+ Q_ASSERT(!m_fontDatas.contains(key));
+ m_fontDatas.insert(key, fontData);
+ }
+
+ inline void removeKey(const void *key)
+ {
+ m_fontDatas.remove(key);
+ }
+
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ OUT IDWriteFontFileStream **fontFileStream);
+
+ private:
+ ULONG m_referenceCount;
+ QHash<const void *, QByteArray> m_fontDatas;
+ };
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
+ void **object)
+ {
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
+ *object = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *object = NULL;
+ return E_NOINTERFACE;
+ }
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
+ {
+ return InterlockedIncrement(&m_referenceCount);
+ }
+
+ ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
+ {
+ ULONG newCount = InterlockedDecrement(&m_referenceCount);
+ if (newCount == 0)
+ delete this;
+ return newCount;
+ }
+
+ HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
+ void const *fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ IDWriteFontFileStream **fontFileStream)
+ {
+ Q_UNUSED(fontFileReferenceKeySize);
+
+ if (fontFileReferenceKeySize != sizeof(const void *)) {
+ qWarning("DirectWriteFontFileLoader::CreateStreamFromKey: Wrong key size");
+ return E_FAIL;
+ }
+
+ const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
+ *fontFileStream = NULL;
+ if (!m_fontDatas.contains(key))
+ return E_FAIL;
+
+ QByteArray fontData = m_fontDatas.value(key);
+ DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
+ stream->AddRef();
+ *fontFileStream = stream;
+
+ return S_OK;
+ }
+
+ class CustomFontFileLoader
+ {
+ public:
+ CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0)
+ {
+ HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown **>(&m_directWriteFactory));
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "CustomFontFileLoader::CustomFontFileLoader: "
+ "DWriteCreateFactory failed.");
+ } else {
+ m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
+ m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
+ }
+ }
+
+ ~CustomFontFileLoader()
+ {
+ if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0)
+ m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
+
+ if (m_directWriteFactory != 0)
+ m_directWriteFactory->Release();
+ }
+
+ void addKey(const void *key, const QByteArray &fontData)
+ {
+ if (m_directWriteFontFileLoader != 0)
+ m_directWriteFontFileLoader->addKey(key, fontData);
+ }
+
+ void removeKey(const void *key)
+ {
+ if (m_directWriteFontFileLoader != 0)
+ m_directWriteFontFileLoader->removeKey(key);
+ }
+
+ IDWriteFontFileLoader *loader() const
+ {
+ return m_directWriteFontFileLoader;
+ }
+
+ private:
+ IDWriteFactory *m_directWriteFactory;
+ DirectWriteFontFileLoader *m_directWriteFontFileLoader;
+ };
+
+#endif
+
+} // Anonymous namespace
+
+
+// From qfontdatabase_win.cpp
+extern QFontEngine *qt_load_font_engine_win(const QFontDef &request);
+// From qfontdatabase.cpp
+extern QFont::Weight weightFromInteger(int weight);
+
+void QRawFontPrivate::platformCleanUp()
+{
+ if (fontHandle != NULL) {
+ if (ptrRemoveFontMemResourceEx == NULL) {
+ void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
+ ptrRemoveFontMemResourceEx =
+ reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
+ }
+
+ if (ptrRemoveFontMemResourceEx == NULL) {
+ qWarning("QRawFont::platformCleanUp: Can't find RemoveFontMemResourceEx in gdi32");
+ fontHandle = NULL;
+ } else {
+ ptrRemoveFontMemResourceEx(fontHandle);
+ fontHandle = NULL;
+ }
+ }
+}
+
+void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
+ int pixelSize,
+ QFont::HintingPreference hintingPreference)
+{
+ QByteArray fontData(_fontData);
+ EmbeddedFont font(fontData);
+
+#if !defined(QT_NO_DIRECTWRITE)
+ if (hintingPreference == QFont::PreferDefaultHinting
+ || hintingPreference == QFont::PreferFullHinting)
+#endif
+ {
+ GUID guid;
+ CoCreateGuid(&guid);
+
+ uniqueFamilyName = QString::fromLatin1("f")
+ + QString::number(guid.Data1, 36) + QLatin1Char('-')
+ + QString::number(guid.Data2, 36) + QLatin1Char('-')
+ + QString::number(guid.Data3, 36) + QLatin1Char('-')
+ + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36);
+
+ QString actualFontName = font.changeFamilyName(uniqueFamilyName);
+ if (actualFontName.isEmpty()) {
+ qWarning("QRawFont::platformLoadFromData: Can't change family name of font");
+ return;
+ }
+
+ if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) {
+ void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
+ ptrRemoveFontMemResourceEx =
+ reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
+
+ func = QSystemLibrary::resolve(QLatin1String("gdi32"), "AddFontMemResourceEx");
+ ptrAddFontMemResourceEx =
+ reinterpret_cast<QRawFontPrivate::PtrAddFontMemResourceEx>(func);
+ }
+
+ Q_ASSERT(fontHandle == NULL);
+ if (ptrAddFontMemResourceEx != NULL && ptrRemoveFontMemResourceEx != NULL) {
+ DWORD count = 0;
+ fontData = font.data();
+ fontHandle = ptrAddFontMemResourceEx(fontData.data(), fontData.size(), 0, &count);
+
+ if (count == 0 && fontHandle != NULL) {
+ ptrRemoveFontMemResourceEx(fontHandle);
+ fontHandle = NULL;
+ }
+ }
+
+ if (fontHandle == NULL) {
+ qWarning("QRawFont::platformLoadFromData: AddFontMemResourceEx failed");
+ } else {
+ QFontDef request;
+ request.family = uniqueFamilyName;
+ request.pixelSize = pixelSize;
+ request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch;
+ request.hintingPreference = hintingPreference;
+
+ fontEngine = qt_load_font_engine_win(request);
+ if (request.family != fontEngine->fontDef.family) {
+ qWarning("QRawFont::platformLoadFromData: Failed to load font. "
+ "Got fallback instead: %s", qPrintable(fontEngine->fontDef.family));
+ if (fontEngine->cache_count == 0 && fontEngine->ref == 0)
+ delete fontEngine;
+ fontEngine = 0;
+ } else {
+ Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0);
+
+ // Override the generated font name
+ fontEngine->fontDef.family = actualFontName;
+ fontEngine->ref.ref();
+ }
+ }
+ }
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ CustomFontFileLoader fontFileLoader;
+ fontFileLoader.addKey(this, fontData);
+
+ IDWriteFactory *factory = NULL;
+ HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(IDWriteFactory),
+ reinterpret_cast<IUnknown **>(&factory));
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "QRawFont::platformLoadFromData: DWriteCreateFactory failed");
+ return;
+ }
+
+ IDWriteFontFile *fontFile = NULL;
+ void *key = this;
+
+ hres = factory->CreateCustomFontFileReference(&key, sizeof(void *),
+ fontFileLoader.loader(), &fontFile);
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "QRawFont::platformLoadFromData: "
+ "CreateCustomFontFileReference failed");
+ factory->Release();
+ return;
+ }
+
+ BOOL isSupportedFontType;
+ DWRITE_FONT_FILE_TYPE fontFileType;
+ DWRITE_FONT_FACE_TYPE fontFaceType;
+ UINT32 numberOfFaces;
+ fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
+ if (!isSupportedFontType) {
+ fontFile->Release();
+ factory->Release();
+ return;
+ }
+
+ IDWriteFontFace *directWriteFontFace = NULL;
+ hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE,
+ &directWriteFontFace);
+ if (FAILED(hres)) {
+ qErrnoWarning(hres, "QRawFont::platformLoadFromData: CreateFontFace failed");
+ fontFile->Release();
+ factory->Release();
+ return;
+ }
+
+ fontFile->Release();
+
+ fontEngine = new QFontEngineDirectWrite(factory, directWriteFontFace, pixelSize);
+
+ // Get font family from font data
+ fontEngine->fontDef.family = font.familyName();
+ fontEngine->ref.ref();
+
+ directWriteFontFace->Release();
+ factory->Release();
+ }
+#endif
+
+ // Get style and weight info
+ if (fontEngine != 0) {
+ TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2");
+ if (os2TableEntry != 0) {
+ const OS2Table *os2Table =
+ reinterpret_cast<const OS2Table *>(fontData.constData()
+ + os2TableEntry->offset);
+
+ bool italic = os2Table->selection & 1;
+ bool oblique = os2Table->selection & 128;
+
+ if (italic)
+ fontEngine->fontDef.style = QFont::StyleItalic;
+ else if (oblique)
+ fontEngine->fontDef.style = QFont::StyleOblique;
+ else
+ fontEngine->fontDef.style = QFont::StyleNormal;
+
+ fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass);
+ }
+ }
+}
+
+void QRawFontPrivate::platformSetPixelSize(int pixelSize)
+{
+ if (fontEngine == NULL)
+ return;
+
+ QFontEngine *oldFontEngine = fontEngine;
+
+#if !defined(QT_NO_DIRECTWRITE)
+ if (fontEngine->type() == QFontEngine::Win)
+#endif
+
+ {
+ QFontDef request = fontEngine->fontDef;
+ QString actualFontName = request.family;
+ if (!uniqueFamilyName.isEmpty())
+ request.family = uniqueFamilyName;
+ request.pixelSize = pixelSize;
+
+ fontEngine = qt_load_font_engine_win(request);
+ if (fontEngine != NULL) {
+ fontEngine->fontDef.family = actualFontName;
+ fontEngine->ref.ref();
+ }
+ }
+
+#if !defined(QT_NO_DIRECTWRITE)
+ else {
+ QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine);
+ fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory,
+ dWriteFE->m_directWriteFontFace,
+ pixelSize);
+
+ fontEngine->fontDef = dWriteFE->fontDef;
+ fontEngine->fontDef.pixelSize = pixelSize;
+ fontEngine->ref.ref();
+ }
+#endif
+
+ Q_ASSERT(fontEngine != oldFontEngine);
+ oldFontEngine->ref.deref();
+ if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0)
+ delete oldFontEngine;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_RAWFONT
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 66ce64b..4396730 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1519,7 +1519,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con
const QTextCursor oldSelection = cursor;
const int oldCursorPos = cursor.position();
- mousePressed = true;
+ mousePressed = (interactionFlags & Qt::TextSelectableByMouse);
#ifndef QT_NO_DRAGANDDROP
mightStartDrag = false;
#endif
@@ -1608,13 +1608,11 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
if (!(buttons & Qt::LeftButton))
return;
- const bool selectable = interactionFlags & Qt::TextSelectableByMouse;
const bool editable = interactionFlags & Qt::TextEditable;
- if (!selectable && !editable)
- return;
-
if (!(mousePressed
+ || editable
+ || mightStartDrag
|| selectedWordOnDoubleClick.hasSelection()
|| selectedBlockOnTrippleClick.hasSelection()))
return;
@@ -1628,7 +1626,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons
return;
}
- if (!selectable)
+ if (!mousePressed)
return;
const qreal mouseX = qreal(mousePos.x());
@@ -1696,10 +1694,8 @@ void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, c
if (mousePressed) {
mousePressed = false;
#ifndef QT_NO_CLIPBOARD
- if (interactionFlags & Qt::TextSelectableByMouse) {
- setClipboardSelection();
- selectionChanged(true);
- }
+ setClipboardSelection();
+ selectionChanged(true);
} else if (button == Qt::MidButton
&& (interactionFlags & Qt::TextEditable)
&& QApplication::clipboard()->supportsSelection()) {
@@ -1951,6 +1947,7 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
if (isGettingInput)
layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
QList<QTextLayout::FormatRange> overrides;
+ const int oldPreeditCursor = preeditCursor;
preeditCursor = e->preeditString().length();
hideCursor = false;
for (int i = 0; i < e->attributes().size(); ++i) {
@@ -1973,6 +1970,8 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
cursor.endEditBlock();
if (cursor.d)
cursor.d->setX();
+ if (oldPreeditCursor != preeditCursor)
+ emit q->microFocusChanged();
}
QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 2172f74..a997720 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -1406,11 +1406,18 @@ void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format)
static QTextFrame *findChildFrame(QTextFrame *f, int pos)
{
- // ##### use binary search
- QList<QTextFrame *> children = f->childFrames();
- for (int i = 0; i < children.size(); ++i) {
- QTextFrame *c = children.at(i);
- if (pos >= c->firstPosition() && pos <= c->lastPosition())
+ /* Binary search for frame at pos */
+ const QList<QTextFrame *> children = f->childFrames();
+ int first = 0;
+ int last = children.size() - 1;
+ while (first <= last) {
+ int mid = (first + last) / 2;
+ QTextFrame *c = children.at(mid);
+ if (pos > c->lastPosition())
+ first = mid + 1;
+ else if (pos < c->firstPosition())
+ last = mid - 1;
+ else
return c;
}
return 0;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index afe6949..93f71d3 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -54,12 +54,18 @@
#include "qpainterpath.h"
#include "qglyphs.h"
#include "qglyphs_p.h"
+#include "qrawfont.h"
+#include "qrawfont_p.h"
#include <limits.h>
#include <qdebug.h>
#include "qfontengine_p.h"
+#if !defined(QT_NO_FREETYPE)
+# include "qfontengine_ft_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)
@@ -1158,6 +1164,7 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
\sa draw(), QPainter::drawGlyphs()
*/
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> QTextLayout::glyphs() const
{
QList<QGlyphs> glyphs;
@@ -1166,6 +1173,7 @@ QList<QGlyphs> QTextLayout::glyphs() const
return glyphs;
}
+#endif // QT_NO_RAWFONT
/*!
Draws the whole layout on the painter \a p at the position specified by \a pos.
@@ -2257,6 +2265,7 @@ namespace {
\sa QTextLayout::glyphs()
*/
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> QTextLine::glyphs(int from, int length) const
{
const QScriptLine &line = eng->lines[i];
@@ -2331,7 +2340,35 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
QFontEngine *fontEngine = keys.at(i);
// Make a font for this particular engine
- QFont font = fontEngine->createExplicitFont();
+ QRawFont font;
+ QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+ fontD->fontEngine = fontEngine;
+ fontD->fontEngine->ref.ref();
+
+#if defined(Q_WS_WIN)
+ if (fontEngine->supportsSubPixelPositions())
+ fontD->hintingPreference = QFont::PreferVerticalHinting;
+ else
+ fontD->hintingPreference = QFont::PreferFullHinting;
+#elif defined(Q_WS_MAC)
+ fontD->hintingPreference = QFont::PreferNoHinting;
+#elif !defined(QT_NO_FREETYPE)
+ if (fontEngine->type() == QFontEngine::Freetype) {
+ QFontEngineFT *freeTypeEngine = static_cast<QFontEngineFT *>(fontEngine);
+ switch (freeTypeEngine->defaultHintStyle()) {
+ case QFontEngineFT::HintNone:
+ fontD->hintingPreference = QFont::PreferNoHinting;
+ break;
+ case QFontEngineFT::HintLight:
+ fontD->hintingPreference = QFont::PreferVerticalHinting;
+ break;
+ case QFontEngineFT::HintMedium:
+ case QFontEngineFT::HintFull:
+ fontD->hintingPreference = QFont::PreferFullHinting;
+ break;
+ };
+ }
+#endif
QList<GlyphInfo> glyphLayouts = glyphLayoutHash.values(fontEngine);
for (int j=0; j<glyphLayouts.size(); ++j) {
@@ -2339,10 +2376,6 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
const QGlyphLayout &glyphLayout = glyphLayouts.at(j).glyphLayout;
const QTextItem::RenderFlags &flags = glyphLayouts.at(j).flags;
- font.setOverline(flags.testFlag(QTextItem::Overline));
- font.setUnderline(flags.testFlag(QTextItem::Underline));
- font.setStrikeOut(flags.testFlag(QTextItem::StrikeOut));
-
QVarLengthArray<glyph_t> glyphsArray;
QVarLengthArray<QFixedPoint> positionsArray;
@@ -2361,19 +2394,22 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const
glyphIndexes.setGlyphIndexes(glyphs);
glyphIndexes.setPositions(positions);
- QPair<QFontEngine *, int> key(fontEngine, int(flags));
+ glyphIndexes.setOverline(flags.testFlag(QTextItem::Overline));
+ glyphIndexes.setUnderline(flags.testFlag(QTextItem::Underline));
+ glyphIndexes.setStrikeOut(flags.testFlag(QTextItem::StrikeOut));
+ glyphIndexes.setFont(font);
+ QPair<QFontEngine *, int> key(fontEngine, int(flags));
if (!glyphsHash.contains(key))
- glyphsHash.insert(key, QGlyphs());
-
- QGlyphs &target = glyphsHash[key];
- target += glyphIndexes;
- target.setFont(font);
+ glyphsHash.insert(key, glyphIndexes);
+ else
+ glyphsHash[key] += glyphIndexes;
}
}
return glyphsHash.values();
}
+#endif // QT_NO_RAWFONT
/*!
\fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 0f64c33..9dd8ebd 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -167,7 +167,9 @@ public:
qreal minimumWidth() const;
qreal maximumWidth() const;
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> glyphs() const;
+#endif
QTextEngine *engine() const { return d; }
void setFlags(int flags);
@@ -239,7 +241,10 @@ public:
private:
QTextLine(int line, QTextEngine *e) : i(line), eng(e) {}
void layout_helper(int numGlyphs);
+
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> glyphs(int from, int length) const;
+#endif
friend class QTextLayout;
friend class QTextFragment;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index 0081550..5c1c8b9 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -891,6 +891,11 @@ QTextBlockUserData::~QTextBlockUserData()
Returns true if this text block is valid; otherwise returns false.
*/
+bool QTextBlock::isValid() const
+{
+ return p != 0 && p->blockMap().isValid(n);
+}
+
/*!
\fn QTextBlock &QTextBlock::operator=(const QTextBlock &other)
@@ -1661,6 +1666,7 @@ QTextBlock::iterator &QTextBlock::iterator::operator--()
\sa QGlyphs, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphs()
*/
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> QTextFragment::glyphs() const
{
if (!p || !n)
@@ -1684,6 +1690,7 @@ QList<QGlyphs> QTextFragment::glyphs() const
return ret;
}
+#endif // QT_NO_RAWFONT
/*!
Returns the position of this text fragment in the document.
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index fface3f..ad8e657 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -205,7 +205,7 @@ public:
inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {}
inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; }
- inline bool isValid() const { return p != 0 && n != 0; }
+ bool isValid() const;
inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; }
inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; }
@@ -316,7 +316,9 @@ public:
int charFormatIndex() const;
QString text() const;
+#if !defined(QT_NO_RAWFONT)
QList<QGlyphs> glyphs() const;
+#endif
private:
const QTextDocumentPrivate *p;
diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp
index 0f7edae..9f21886 100644
--- a/src/gui/text/qzip.cpp
+++ b/src/gui/text/qzip.cpp
@@ -572,7 +572,7 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
"directory",
"file ",
"symlink " };
- ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? (" -> " + contents).constData() : "");
+ ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : "");
#endif
if (! (device->isOpen() || device->open(QIODevice::WriteOnly))) {
diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h
index 0ee445e..153ef19 100644
--- a/src/gui/text/qzipwriter_p.h
+++ b/src/gui/text/qzipwriter_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QZipWriterPrivate;
-class Q_AUTOTEST_EXPORT QZipWriter
+class Q_GUI_EXPORT QZipWriter
{
public:
QZipWriter(const QString &fileName, QIODevice::OpenMode mode = (QIODevice::WriteOnly | QIODevice::Truncate) );
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 7fb2783..df9398c 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -41,7 +41,9 @@ HEADERS += \
text/qstatictext_p.h \
text/qstatictext.h \
text/qglyphs.h \
- text/qglyphs_p.h
+ text/qglyphs_p.h \
+ text/qrawfont.h \
+ text/qrawfont_p.h
SOURCES += \
text/qfont.cpp \
@@ -72,12 +74,14 @@ SOURCES += \
text/qzip.cpp \
text/qtextodfwriter.cpp \
text/qstatictext.cpp \
- text/qglyphs.cpp
+ text/qglyphs.cpp \
+ text/qrawfont.cpp
win32 {
SOURCES += \
text/qfont_win.cpp \
- text/qfontengine_win.cpp
+ text/qfontengine_win.cpp \
+ text/qrawfont_win.cpp
HEADERS += text/qfontengine_win_p.h
}
@@ -95,7 +99,8 @@ unix:x11 {
SOURCES += \
text/qfont_x11.cpp \
text/qfontengine_x11.cpp \
- text/qfontengine_ft.cpp
+ text/qfontengine_ft.cpp \
+ text/qrawfont_ft.cpp
}
!embedded:!qpa:!x11:mac {
@@ -104,7 +109,8 @@ unix:x11 {
OBJECTIVE_HEADERS += \
text/qfontengine_coretext_p.h
SOURCES += \
- text/qfont_mac.cpp
+ text/qfont_mac.cpp \
+ text/qrawfont_mac.cpp
OBJECTIVE_SOURCES += \
text/qfontengine_coretext.mm \
text/qfontengine_mac.mm
@@ -116,7 +122,8 @@ embedded {
text/qfontengine_qws.cpp \
text/qfontengine_ft.cpp \
text/qfontengine_qpf.cpp \
- text/qabstractfontengine_qws.cpp
+ text/qabstractfontengine_qws.cpp \
+ text/qrawfont_ft.cpp
HEADERS += \
text/qfontengine_ft_p.h \
text/qfontengine_qpf_p.h \
@@ -143,7 +150,8 @@ symbian {
text/qfont_s60.cpp
contains(QT_CONFIG, freetype) {
SOURCES += \
- text/qfontengine_ft.cpp
+ text/qfontengine_ft.cpp \
+ text/qrawfont_ft.cpp
HEADERS += \
text/qfontengine_ft_p.h
DEFINES += \
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
index 27684bf..0cb3bbd 100644
--- a/src/gui/util/qcompleter.cpp
+++ b/src/gui/util/qcompleter.cpp
@@ -926,7 +926,7 @@ void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
// If we hide the popup because there was no match because the model was not loaded yet,
// we re-start the completion when we get the results
if (hiddenBecauseNoMatch
- && prefix.startsWith(path) && prefix != (path + '/')
+ && prefix.startsWith(path) && prefix != (path + QLatin1Char('/'))
&& widget) {
q->complete();
}
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 96860df..8caeb74 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -314,7 +314,7 @@ static bool handleUrl(const QUrl &url)
if (!url.isValid())
return false;
- QString urlString(url.toString());
+ QString urlString(url.toEncoded());
TPtrC urlPtr(qt_QString2TPtrC(urlString));
TRAPD( err, handleUrlL(urlPtr));
return err ? false : true;
diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp
index 9c2d24d..db128c1 100644
--- a/src/gui/util/qscroller.cpp
+++ b/src/gui/util/qscroller.cpp
@@ -279,9 +279,11 @@ private:
\sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties
*/
+typedef QMap<QObject *, QScroller *> ScrollerHash;
+typedef QSet<QScroller *> ScrollerSet;
-QMap<QObject *, QScroller *> QScrollerPrivate::allScrollers;
-QSet<QScroller *> QScrollerPrivate::activeScrollers;
+Q_GLOBAL_STATIC(ScrollerHash, qt_allScrollers)
+Q_GLOBAL_STATIC(ScrollerSet, qt_activeScrollers)
/*!
Returns \c true if a QScroller object was already created for \a target; \c false otherwise.
@@ -290,7 +292,7 @@ QSet<QScroller *> QScrollerPrivate::activeScrollers;
*/
bool QScroller::hasScroller(QObject *target)
{
- return (QScrollerPrivate::allScrollers.value(target));
+ return (qt_allScrollers()->value(target));
}
/*!
@@ -308,11 +310,11 @@ QScroller *QScroller::scroller(QObject *target)
return 0;
}
- if (QScrollerPrivate::allScrollers.contains(target))
- return QScrollerPrivate::allScrollers.value(target);
+ if (qt_allScrollers()->contains(target))
+ return qt_allScrollers()->value(target);
QScroller *s = new QScroller(target);
- QScrollerPrivate::allScrollers.insert(target, s);
+ qt_allScrollers()->insert(target, s);
return s;
}
@@ -332,7 +334,7 @@ const QScroller *QScroller::scroller(const QObject *target)
*/
QList<QScroller *> QScroller::activeScrollers()
{
- return QScrollerPrivate::activeScrollers.toList();
+ return qt_activeScrollers()->toList();
}
/*!
@@ -508,8 +510,8 @@ QScroller::~QScroller()
// do not delete the recognizer. The QGestureManager is doing this.
d->recognizer = 0;
#endif
- QScrollerPrivate::allScrollers.remove(d->target);
- QScrollerPrivate::activeScrollers.remove(this);
+ qt_allScrollers()->remove(d->target);
+ qt_activeScrollers()->remove(this);
delete d_ptr;
}
@@ -1754,9 +1756,9 @@ void QScrollerPrivate::setState(QScroller::State newstate)
firstScroll = true;
}
if (state == QScroller::Dragging || state == QScroller::Scrolling)
- activeScrollers.insert(q);
+ qt_activeScrollers()->insert(q);
else
- activeScrollers.remove(q);
+ qt_activeScrollers()->remove(q);
emit q->stateChanged(state);
}
diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h
index 8c5f2e7..c119615 100644
--- a/src/gui/util/qscroller_p.h
+++ b/src/gui/util/qscroller_p.h
@@ -148,10 +148,6 @@ public slots:
void targetDestroyed();
public:
- // static
- static QMap<QObject *, QScroller *> allScrollers;
- static QSet<QScroller *> activeScrollers;
-
// non static
QObject *target;
QScrollerProperties properties;
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 3eac64a..289faa9 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -254,12 +254,20 @@ void QLineControl::setSelection(int start, int length)
m_selstart = start;
m_selend = qMin(start + length, (int)m_text.length());
m_cursor = m_selend;
- } else {
+ } else if (length < 0){
if (start == m_selend && start + length == m_selstart)
return;
m_selstart = qMax(start + length, 0);
m_selend = start;
m_cursor = m_selstart;
+ } else if (m_selstart != m_selend) {
+ m_selstart = 0;
+ m_selend = 0;
+ m_cursor = start;
+ } else {
+ m_cursor = start;
+ emitCursorPositionChanged();
+ return;
}
emit selectionChanged();
emitCursorPositionChanged();
@@ -435,7 +443,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
removeSelectedText();
}
if (!event->commitString().isEmpty()) {
- insert(event->commitString());
+ internalInsert(event->commitString());
cursorPositionChanged = true;
}