summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorAlexis Menard <alexis.menard@trolltech.com>2011-06-22 15:00:09 (GMT)
committerAlexis Menard <alexis.menard@trolltech.com>2011-06-22 15:00:09 (GMT)
commit1b46b28ddac18fd0f5edc250218dfb15ac05e652 (patch)
tree57b0fe3414941d5deda54a7b658c7b3d2b0f2268 /src/gui
parent20ec7b41ac600fe670c3c8e6305cc12b10440c30 (diff)
parente4cce8849bf45be9a111072e3fca7bdf67364e8a (diff)
downloadQt-1b46b28ddac18fd0f5edc250218dfb15ac05e652.zip
Qt-1b46b28ddac18fd0f5edc250218dfb15ac05e652.tar.gz
Qt-1b46b28ddac18fd0f5edc250218dfb15ac05e652.tar.bz2
Merge branch '4.8' of git://gitorious.org/qt/qt into 4.8
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp131
-rw-r--r--src/gui/accessible/qaccessiblewidget.cpp11
-rw-r--r--src/gui/dialogs/dialogs.pri6
-rw-r--r--src/gui/dialogs/qfiledialog_symbian.cpp6
-rw-r--r--src/gui/egl/qegl_p.h10
-rw-r--r--src/gui/embedded/qkbd_qws.cpp2
-rw-r--r--src/gui/embedded/qkbdum_qws.cpp2
-rw-r--r--src/gui/embedded/qlock.cpp142
-rw-r--r--src/gui/embedded/qmousepc_qws.cpp2
-rw-r--r--src/gui/embedded/qscreenlinuxfb_qws.cpp5
-rw-r--r--src/gui/embedded/qwindowsystem_qws.cpp26
-rw-r--r--src/gui/embedded/qwslock.cpp185
-rw-r--r--src/gui/embedded/qwslock_p.h14
-rw-r--r--src/gui/embedded/qwssharedmemory.cpp120
-rw-r--r--src/gui/embedded/qwssharedmemory_p.h34
-rw-r--r--src/gui/embedded/qwssignalhandler.cpp52
-rw-r--r--src/gui/embedded/qwssignalhandler_p.h22
-rw-r--r--src/gui/graphicsview/qgraphicslayout.cpp6
-rw-r--r--src/gui/image/qimage.cpp7
-rw-r--r--src/gui/image/qpixmap_mac.cpp2
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp46
-rw-r--r--src/gui/itemviews/qtableview.cpp2
-rw-r--r--src/gui/kernel/qactiongroup.cpp4
-rw-r--r--src/gui/kernel/qapplication_mac.mm3
-rw-r--r--src/gui/kernel/qapplication_qpa.cpp19
-rw-r--r--src/gui/kernel/qapplication_qws.cpp29
-rw-r--r--src/gui/kernel/qapplication_s60.cpp34
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm2
-rw-r--r--src/gui/kernel/qdesktopwidget.qdoc10
-rw-r--r--src/gui/kernel/qevent.cpp6
-rw-r--r--src/gui/kernel/qeventdispatcher_s60.cpp66
-rw-r--r--src/gui/kernel/qeventdispatcher_s60_p.h27
-rw-r--r--src/gui/kernel/qgenericplugin_qpa.cpp2
-rw-r--r--src/gui/kernel/qgenericpluginfactory_qpa.cpp3
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.cpp2
-rw-r--r--src/gui/kernel/qplatformclipboard_qpa.h2
-rw-r--r--src/gui/kernel/qplatformcursor_qpa.cpp89
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp6
-rw-r--r--src/gui/kernel/qplatformintegration_qpa.cpp16
-rw-r--r--src/gui/kernel/qplatformscreen_qpa.cpp23
-rw-r--r--src/gui/kernel/qplatformwindowformat_qpa.cpp24
-rw-r--r--src/gui/kernel/qsessionmanager_qws.cpp3
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp12
-rw-r--r--src/gui/kernel/qsoftkeymanager_common_p.h2
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp4
-rw-r--r--src/gui/kernel/qwidget_qpa.cpp33
-rw-r--r--src/gui/painting/painting.pri4
-rw-r--r--src/gui/painting/qbrush.cpp18
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp1010
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h152
-rw-r--r--src/gui/painting/qgraphicssystemex_symbian.cpp36
-rw-r--r--src/gui/painting/qgraphicssystemex_symbian_p.h3
-rw-r--r--src/gui/painting/qoutlinemapper.cpp9
-rw-r--r--src/gui/painting/qoutlinemapper_p.h8
-rw-r--r--src/gui/painting/qpaintengine.cpp1
-rw-r--r--src/gui/painting/qpaintengine_mac_p.h2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp1484
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h6
-rw-r--r--src/gui/painting/qpaintengineex.cpp47
-rw-r--r--src/gui/painting/qpaintengineex_p.h3
-rw-r--r--src/gui/painting/qpainter.cpp63
-rw-r--r--src/gui/painting/qpainter_p.h2
-rw-r--r--src/gui/painting/qrasterizer.cpp4
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp16
-rw-r--r--src/gui/painting/qunifiedtoolbarsurface_mac.cpp6
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp72
-rw-r--r--src/gui/styles/qs60style.cpp280
-rw-r--r--src/gui/styles/qs60style_feedbackinterface_p.h50
-rw-r--r--src/gui/styles/qs60style_p.h3
-rw-r--r--src/gui/styles/qs60style_s60.cpp54
-rw-r--r--src/gui/styles/qs60style_simulated.cpp19
-rw-r--r--src/gui/text/qfont.cpp50
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/text/qfont_p.h1
-rw-r--r--src/gui/text/qfontdatabase.cpp4
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp142
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp3
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp63
-rw-r--r--src/gui/text/qfontengine_coretext.mm42
-rw-r--r--src/gui/text/qfontengine_coretext_p.h4
-rw-r--r--src/gui/text/qfontengine_ft.cpp8
-rw-r--r--src/gui/text/qfontengine_x11.cpp2
-rw-r--r--src/gui/text/qfontinfo.h1
-rw-r--r--src/gui/text/qfontmetrics.cpp6
-rw-r--r--src/gui/text/qglyphrun.cpp108
-rw-r--r--src/gui/text/qglyphrun.h4
-rw-r--r--src/gui/text/qglyphrun_p.h19
-rw-r--r--src/gui/text/qplatformfontdatabase_qpa.cpp64
-rw-r--r--src/gui/text/qrawfont.cpp69
-rw-r--r--src/gui/text/qrawfont.h1
-rw-r--r--src/gui/text/qrawfont_ft.cpp6
-rw-r--r--src/gui/text/qtextdocument.cpp4
-rw-r--r--src/gui/text/qtextengine.cpp71
-rw-r--r--src/gui/text/qtextengine_p.h2
-rw-r--r--src/gui/text/qtextformat.cpp61
-rw-r--r--src/gui/text/qtextlayout.cpp40
-rw-r--r--src/gui/text/qtextodfwriter.cpp1
-rw-r--r--src/gui/util/qdesktopservices_s60.cpp37
-rw-r--r--src/gui/util/util.pri6
-rw-r--r--src/gui/widgets/qlineedit.cpp7
-rw-r--r--src/gui/widgets/qmdiarea.cpp2
-rw-r--r--src/gui/widgets/qtabwidget.cpp2
103 files changed, 2865 insertions, 2578 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 00427eb..337bb99 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -212,42 +212,101 @@ QT_BEGIN_NAMESPACE
This enum type defines accessible event types.
- \value AcceleratorChanged
- \value Alert A system alert (e.g., a message from a QMessageBox)
- \value ContextHelpEnd Context help (QWhatsThis) for an object is finished.
- \value ContextHelpStart Context help (QWhatsThis) for an object is initiated.
- \value DefaultActionChanged The default QAccessible::Action for the accessible object changed
- \value DescriptionChanged The objects QAccessible::Description changed.
- \value DialogEnd A dialog (QDialog) is been hidden
- \value DialogStart A dialog (QDialog) has been set visible.
- \value DragDropEnd A Drag & Drop operation is about to finished.
- \value DragDropStart A Drag & Drop operation is about to be initiated.
- \value Focus An object has gained keyboard focus.
- \value ForegroundChanged A window has been activated (i.e., a new window has gained focus on the desktop)
- \value HelpChanged The QAccessible::Help text property of an object has changed
- \value LocationChanged An objects location on the screen changed
- \value MenuCommand A menu item is triggered.
- \value MenuEnd A menu has been closed (Qt uses PopupMenuEnd for all menus)
- \value MenuStart A menu has been opened on the menubar (Qt uses PopupMenuStart for all menus)
- \value NameChanged The QAccessible::Name property of an object has changed
- \value ObjectCreated A new object is created.
- \value ObjectDestroyed An object is deleted.
- \value ObjectHide An object is hidden (i.e., with QWidget::hide()). Any children the object that is hidden has do not send this event.
- It is not send when an object is hidden as it is being obcured by others.
- \value ObjectReorder A layout or item view has added, removed, or moved an object (Qt does not use this event).
- \value ObjectShow An object is displayed (i.e., with QWidget::show()).
- \value ParentChanged An objects parent object changed.
- \value PopupMenuEnd A popup menu has closed.
- \value PopupMenuStart A popupmenu has opened.
- \value ScrollingEnd A scrollbar scroll operation has ended (the mouse has released the slider handle)
- \value ScrollingStart A scrollbar scroll operation is about to start (i.e., the mouse has pressed on the slider handle)
- \value Selection The selection has changed in a menu or item view.
- \value SelectionAdd An item has been added to the selection in an item view.
- \value SelectionRemove An item has been removed from an item view selection.
- \value SelectionWithin Several changes to a selection has occurred in an item view.
- \value SoundPlayed A sound has been played by an object
- \value StateChanged The QAccessible::State of an object has changed.
- \value ValueChanged The QAccessible::Value of an object has changed.
+ \value AcceleratorChanged The keyboard accelerator for an action has been changed.
+ \value ActionChanged An action has been changed.
+ \value ActiveDescendantChanged
+ \value Alert A system alert (e.g., a message from a QMessageBox)
+ \value AttributeChanged
+ \value ContextHelpEnd Context help (QWhatsThis) for an object is finished.
+ \value ContextHelpStart Context help (QWhatsThis) for an object is initiated.
+ \value DefaultActionChanged The default QAccessible::Action for the accessible
+ object has changed.
+ \value DescriptionChanged The object's QAccessible::Description changed.
+ \value DialogEnd A dialog (QDialog) has been hidden
+ \value DialogStart A dialog (QDialog) has been set visible.
+ \value DocumentContentChanged The contents of a text document have changed.
+ \value DocumentLoadComplete A document has been loaded.
+ \value DocumentLoadStopped A document load has been stopped.
+ \value DocumentReload A document reload has been initiated.
+ \value DragDropEnd A drag and drop operation is about to finished.
+ \value DragDropStart A drag and drop operation is about to be initiated.
+ \value Focus An object has gained keyboard focus.
+ \value ForegroundChanged A window has been activated (i.e., a new window has
+ gained focus on the desktop).
+ \value HelpChanged The QAccessible::Help text property of an object has
+ changed.
+ \value HyperlinkEndIndexChanged The end position of the display text for a hypertext
+ link has changed.
+ \value HyperlinkNumberOfAnchorsChanged The number of anchors in a hypertext link has changed,
+ perhaps because the display text has been split to
+ provide more than one link.
+ \value HyperlinkSelectedLinkChanged The link for the selected hypertext link has changed.
+ \value HyperlinkStartIndexChanged The start position of the display text for a hypertext
+ link has changed.
+ \value HypertextChanged The display text for a hypertext link has changed.
+ \value HypertextLinkActivated A hypertext link has been activated, perhaps by being
+ clicked or via a key press.
+ \value HypertextLinkSelected A hypertext link has been selected.
+ \value HypertextNLinksChanged
+ \value LocationChanged An object's location on the screen has changed.
+ \value MenuCommand A menu item is triggered.
+ \value MenuEnd A menu has been closed (Qt uses PopupMenuEnd for all
+ menus).
+ \value MenuStart A menu has been opened on the menubar (Qt uses
+ PopupMenuStart for all menus).
+ \value NameChanged The QAccessible::Name property of an object has changed.
+ \value ObjectAttributeChanged
+ \value ObjectCreated A new object is created.
+ \value ObjectDestroyed An object is deleted.
+ \value ObjectHide An object is hidden; for example, with QWidget::hide().
+ Any children the object that is hidden has do not send
+ this event. It is not sent when an object is hidden as
+ it is being obcured by others.
+ \value ObjectReorder A layout or item view has added, removed, or moved an
+ object (Qt does not use this event).
+ \value ObjectShow An object is displayed; for example, with
+ QWidget::show().
+ \value PageChanged
+ \value ParentChanged An object's parent object changed.
+ \value PopupMenuEnd A pop-up menu has closed.
+ \value PopupMenuStart A pop-up menu has opened.
+ \value ScrollingEnd A scrollbar scroll operation has ended (the mouse has
+ released the slider handle).
+ \value ScrollingStart A scrollbar scroll operation is about to start; this may
+ be caused by a mouse press on the slider handle, for
+ example.
+ \value SectionChanged
+ \value SelectionAdd An item has been added to the selection in an item view.
+ \value SelectionRemove An item has been removed from an item view selection.
+ \value Selection The selection has changed in a menu or item view.
+ \value SelectionWithin Several changes to a selection has occurred in an item
+ view.
+ \value SoundPlayed A sound has been played by an object
+ \value StateChanged The QAccessible::State of an object has changed.
+ \value TableCaptionChanged A table caption has been changed.
+ \value TableColumnDescriptionChanged The description of a table column, typically found in
+ the column's header, has been changed.
+ \value TableColumnHeaderChanged A table column header has been changed.
+ \value TableModelChanged The model providing data for a table has been changed.
+ \value TableRowDescriptionChanged The description of a table row, typically found in the
+ row's header, has been changed.
+ \value TableRowHeaderChanged A table row header has been changed.
+ \value TableSummaryChanged The summary of a table has been changed.
+ \value TextAttributeChanged
+ \value TextCaretMoved The caret has moved in an editable widget.
+ The caret represents the cursor position in an editable
+ widget with the input focus.
+ \value TextColumnChanged A text column has been changed.
+ \value TextInserted Text has been inserted into an editable widget.
+ \value TextRemoved Text has been removed from an editable widget.
+ \value TextSelectionChanged The selected text has changed in an editable widget.
+ \value TextUpdated The text has been update in an editable widget.
+ \value ValueChanged The QAccessible::Value of an object has changed.
+ \value VisibleDataChanged
+
+ The values for this enum are defined to be the same as those defined in the
+ \l{AccessibleEventID.idl File Reference}{IAccessible2} and
+ \l{Microsoft Active Accessibility Event Constants}{MSAA} specifications.
*/
/*!
diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp
index 60ed48f..6a7d7e9 100644
--- a/src/gui/accessible/qaccessiblewidget.cpp
+++ b/src/gui/accessible/qaccessiblewidget.cpp
@@ -704,13 +704,16 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry,
int sibCount = pIface->childCount();
QAccessibleInterface *candidate = 0;
for (int i = 0; i < sibCount && entry; ++i) {
- pIface->navigate(Child, i+1, &candidate);
- Q_ASSERT(candidate);
- if (candidate->relationTo(0, this, 0) & Label)
+ const int childId = pIface->navigate(Child, i+1, &candidate);
+ Q_ASSERT(childId >= 0);
+ if (childId > 0)
+ candidate = pIface;
+ if (candidate->relationTo(childId, this, 0) & Label)
--entry;
if (!entry)
break;
- delete candidate;
+ if (candidate != pIface)
+ delete candidate;
candidate = 0;
}
if (!candidate) {
diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri
index 6ba707c..1dddb44 100644
--- a/src/gui/dialogs/dialogs.pri
+++ b/src/gui/dialogs/dialogs.pri
@@ -109,7 +109,11 @@ SOURCES += \
dialogs/qprintpreviewdialog.cpp
symbian:contains(QT_CONFIG, s60) {
- LIBS += -lCommonDialogs
+ contains(CONFIG, is_using_gnupoc) {
+ LIBS += -lcommondialogs
+ } else {
+ LIBS += -lCommonDialogs
+ }
SOURCES += dialogs/qfiledialog_symbian.cpp \
dialogs/qcolordialog_symbian.cpp
}
diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp
index a4a7a22..16ef5b6 100644
--- a/src/gui/dialogs/qfiledialog_symbian.cpp
+++ b/src/gui/dialogs/qfiledialog_symbian.cpp
@@ -44,7 +44,7 @@
#ifndef QT_NO_FILEDIALOG
#include <private/qfiledialog_p.h>
-#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3)
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
#include <driveinfo.h>
#include <AknCommonDialogsDynMem.h>
#include <CAknMemorySelectionDialogMultiDrive.h>
@@ -58,7 +58,7 @@ extern QStringList qt_make_filter_list(const QString &filter); // defined in qfi
extern QStringList qt_clean_filter_list(const QString &filter); // defined in qfiledialog.cpp
enum DialogMode { DialogOpen, DialogSave, DialogFolder };
-#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3)
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
class CExtensionFilter : public MAknFileFilter
{
public:
@@ -104,7 +104,7 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st
const QString filter, DialogMode dialogMode)
{
QString selection;
-#if defined(Q_WS_S60) && defined(SYMBIAN_VERSION_SYMBIAN3)
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
TFileName startFolder;
if (!startDirectory.isEmpty()) {
QString dir = QDir::toNativeSeparators(QFileDialogPrivate::workingDirectory(startDirectory));
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index 9b0d82e..15e7cab 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -165,13 +165,21 @@ typedef int EGLImageKHR;
typedef void *EGLImageKHR;
#endif
+#if !defined(EGL_NO_IMAGE_KHR)
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
+#endif
+#if !defined(EGL_IMAGE_PRESERVED_KHR)
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif
+#if !defined(EGL_KHR_image_base)
#define EGL_KHR_image_base
#endif
+#endif
-#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap)
+#if !defined(EGL_KHR_image)
#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#endif
+#if !defined(EGL_KHR_image_pixmap)
#define EGL_KHR_image_pixmap
#endif
diff --git a/src/gui/embedded/qkbd_qws.cpp b/src/gui/embedded/qkbd_qws.cpp
index 77ae47b..5edc4d9 100644
--- a/src/gui/embedded/qkbd_qws.cpp
+++ b/src/gui/embedded/qkbd_qws.cpp
@@ -225,7 +225,7 @@ bool QWSKbPrivate::loadKeymap(const QString &file)
ds >> qmap_magic >> qmap_version >> qmap_keymap_size >> qmap_keycompose_size;
if (ds.status() != QDataStream::Ok || qmap_magic != QWSKeyboard::FileMagic || qmap_version != 1 || qmap_keymap_size == 0) {
- qWarning("'%s' is ot a valid.qmap keymap file.", qPrintable(file));
+ qWarning("'%s' is not a valid .qmap keymap file.", qPrintable(file));
return false;
}
diff --git a/src/gui/embedded/qkbdum_qws.cpp b/src/gui/embedded/qkbdum_qws.cpp
index 4fbe03e..97561b5 100644
--- a/src/gui/embedded/qkbdum_qws.cpp
+++ b/src/gui/embedded/qkbdum_qws.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qkbdum_qws.h"
-#include "qvfbhdr.h"
#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_UM)
@@ -55,6 +54,7 @@
#include <qwindowsystem_qws.h>
#include <qsocketnotifier.h>
#include "qplatformdefs.h"
+#include "qvfbhdr.h"
QT_BEGIN_NAMESPACE
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
index bb442e4..ac15431 100644
--- a/src/gui/embedded/qlock.cpp
+++ b/src/gui/embedded/qlock.cpp
@@ -99,7 +99,6 @@ QT_END_NAMESPACE
#endif
#include <string.h>
#include <errno.h>
-#include <qdebug.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -138,8 +137,6 @@ public:
*/
/*!
- \fn QLock::QLock(const QString &filename, char id, bool create)
-
Creates a lock. \a filename is the file path of the Unix-domain
socket the \l{Qt for Embedded Linux} client is using. \a id is the name of the
particular lock to be created on that socket. If \a create is true
@@ -147,76 +144,79 @@ public:
create is false the lock should exist already (as the Qt for Embedded Linux
client expects).
*/
-
QLock::QLock(const QString &filename, char id, bool create)
{
data = new QLockData;
data->count = 0;
#ifdef Q_NO_SEMAPHORE
- data->file = QString(filename+id).toLocal8Bit().constData();
- for(int x = 0; x < 2; x++) {
- data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
- if(data->id != -1 || !create) {
+ data->file = filename.toLocal8Bit() + id;
+ for (int x = 0; x < 2; ++x) {
+ data->id = QT_OPEN(data->file.constData(), O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
+ if (data->id != -1 || !create) {
data->owned = x;
break;
}
}
#else
key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
- data->id = semget(semkey,0,0);
+ data->id = semget(semkey, 0, 0);
data->owned = create;
if (create) {
- qt_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);
+ semctl(data->id, 0, IPC_RMID, arg);
+ data->id = semget(semkey, 1, IPC_CREAT | 0600);
arg.val = MAX_LOCKS;
- semctl(data->id,0,SETVAL,arg);
-
- QWSSignalHandler::instance()->addSemaphore(data->id);
+ semctl(data->id, 0, SETVAL, arg);
}
#endif
- if (data->id == -1) {
- int eno = errno;
- qWarning("Cannot %s semaphore %s '%c'", (create ? "create" : "get"),
- qPrintable(filename), id);
- qDebug() << "Error" << eno << strerror(eno);
+ if (!isValid()) {
+ qWarning("QLock::QLock: Cannot %s semaphore %s '%c' (%d, %s)",
+ (create ? "create" : "get"), qPrintable(filename), id,
+ errno, strerror(errno));
}
+
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addLock(this);
+#endif
}
/*!
- \fn QLock::~QLock()
-
Destroys a lock
*/
-
QLock::~QLock()
{
- if (locked())
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->removeLock(this);
+#endif
+
+ while (locked())
unlock();
#ifdef Q_NO_SEMAPHORE
- if(isValid()) {
+ if (isValid())
QT_CLOSE(data->id);
- if(data->owned)
- unlink(data->file);
- }
+#endif
+ if (data->owned) {
+#ifdef Q_NO_SEMAPHORE
+ unlink(data->file.constData());
#else
- if(data->owned)
- QWSSignalHandler::instance()->removeSemaphore(data->id);
+ qt_semun semval;
+ semval.val = 0;
+ semctl(data->id, 0, IPC_RMID, semval);
#endif
+ }
delete data;
+ data = 0;
}
/*!
- \fn bool QLock::isValid() const
-
Returns true if the lock constructor was successful; returns false if
the lock could not be created or was not available to connect to.
*/
-
bool QLock::isValid() const
{
- return (data->id != -1);
+ return data && data->id != -1;
}
/*!
@@ -230,96 +230,72 @@ bool QLock::isValid() const
will only be unlocked after a corresponding number of unlock()
calls.
*/
-
void QLock::lock(Type t)
{
if (!data->count) {
+ type = t;
+
+ int rv;
#ifdef Q_NO_SEMAPHORE
- int op = LOCK_SH;
- if(t == Write)
- op = LOCK_EX;
- for(int rv=1; rv;) {
- rv = flock(data->id, op);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
+ int op = type == Write ? LOCK_EX : LOCK_SH;
+
+ EINTR_LOOP(rv, flock(data->id, op));
#else
sembuf sops;
sops.sem_num = 0;
+ sops.sem_op = type == Write ? -MAX_LOCKS : -1;
sops.sem_flg = SEM_UNDO;
- if (t == Write) {
- sops.sem_op = -MAX_LOCKS;
- type = Write;
- } else {
- sops.sem_op = -1;
- type = Read;
- }
-
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
+ EINTR_LOOP(rv, semop(data->id, &sops, 1));
#endif
+ if (rv == -1) {
+ qDebug("QLock::lock(): %s", strerror(errno));
+ return;
+ }
+ } else if (type == Read && t == Write) {
+ qDebug("QLock::lock(): Attempt to lock for write while locked for read");
}
data->count++;
}
/*!
- \fn void QLock::unlock()
-
Unlocks the semaphore. If other processes were blocking waiting to
lock() the semaphore, one of them will wake up and succeed in
- lock()ing.
+ locking.
*/
-
void QLock::unlock()
{
- if(data->count) {
+ if (data->count) {
data->count--;
- if(!data->count) {
+ if (!data->count) {
+ int rv;
#ifdef Q_NO_SEMAPHORE
- for(int rv=1; rv;) {
- rv = flock(data->id, LOCK_UN);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop lock failure %s",strerror(errno));
- }
+ EINTR_LOOP(rv, flock(data->id, LOCK_UN));
#else
sembuf sops;
sops.sem_num = 0;
- sops.sem_op = 1;
+ sops.sem_op = type == Write ? MAX_LOCKS : 1;
sops.sem_flg = SEM_UNDO;
- if (type == Write)
- sops.sem_op = MAX_LOCKS;
- int rv;
- do {
- rv = semop(data->id,&sops,1);
- if (rv == -1 && errno != EINTR)
- qDebug("Semop unlock failure %s",strerror(errno));
- } while (rv == -1 && errno == EINTR);
+ EINTR_LOOP(rv, semop(data->id, &sops, 1));
#endif
+ if (rv == -1)
+ qDebug("QLock::unlock(): %s", strerror(errno));
}
} else {
- qDebug("Unlock without corresponding lock");
+ qDebug("QLock::unlock(): Unlock without corresponding lock");
}
}
/*!
- \fn bool QLock::locked() const
-
Returns true if the lock is currently held by the current process;
otherwise returns false.
*/
-
bool QLock::locked() const
{
- return (data->count > 0);
+ return isValid() && data->count > 0;
}
QT_END_NAMESPACE
#endif // QT_NO_QWS_MULTIPROCESS
-
diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp
index 5d3b182..c22cab9 100644
--- a/src/gui/embedded/qmousepc_qws.cpp
+++ b/src/gui/embedded/qmousepc_qws.cpp
@@ -261,7 +261,7 @@ public:
usleep(50000);
QT_WRITE(fd,"@EeI!",5);
usleep(10000);
- static const char ibuf[] = { 246, 244 };
+ static const unsigned char ibuf[] = { 246, 244 };
QT_WRITE(fd,ibuf,1);
QT_WRITE(fd,ibuf+1,1);
if (tcflush(fd,TCIOFLUSH) == -1) {
diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp
index 67c8a31..4b41b5b 100644
--- a/src/gui/embedded/qscreenlinuxfb_qws.cpp
+++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp
@@ -110,7 +110,9 @@ QLinuxFbScreenPrivate::QLinuxFbScreenPrivate()
#endif
ttyfd(-1), oldKdMode(KD_TEXT)
{
+#ifndef QT_NO_QWS_SIGNALHANDLER
QWSSignalHandler::instance()->addObject(this);
+#endif
}
QLinuxFbScreenPrivate::~QLinuxFbScreenPrivate()
@@ -263,6 +265,9 @@ QLinuxFbScreen::QLinuxFbScreen(int display_id)
QLinuxFbScreen::~QLinuxFbScreen()
{
+#ifdef QT_NO_QWS_SIGNALHANDLER
+ delete d_ptr;
+#endif
}
/*!
diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp
index 0e4e27c..36802a8 100644
--- a/src/gui/embedded/qwindowsystem_qws.cpp
+++ b/src/gui/embedded/qwindowsystem_qws.cpp
@@ -2494,7 +2494,7 @@ QWSWindow *QWSServer::windowAt(const QPoint& pos)
}
#ifndef QT_NO_QWS_KEYBOARD
-static int keyUnicode(int keycode)
+static inline int keyUnicode(int keycode)
{
int code = 0xffff;
@@ -2550,18 +2550,16 @@ void QWSServer::sendKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers mod
void QWSServerPrivate::sendKeyEventUnfiltered(int unicode, int keycode, Qt::KeyboardModifiers modifiers,
bool isPress, bool autoRepeat)
{
+ QWSWindow *win = keyboardGrabber ? keyboardGrabber : qwsServerPrivate->focusw;
- QWSKeyEvent event;
- QWSWindow *win = keyboardGrabber ? keyboardGrabber :
- qwsServerPrivate->focusw;
-
- event.simpleData.window = win ? win->winId() : 0;
-
- event.simpleData.unicode =
#ifndef QT_NO_QWS_KEYBOARD
- unicode < 0 ? keyUnicode(keycode) :
+ if (unicode < 0)
+ unicode = keyUnicode(keycode);
#endif
- unicode;
+
+ QWSKeyEvent event;
+ event.simpleData.window = win ? win->winId() : 0;
+ event.simpleData.unicode = unicode;
event.simpleData.keycode = keycode;
event.simpleData.modifiers = modifiers;
event.simpleData.is_press = isPress;
@@ -4127,11 +4125,11 @@ void QWSServer::processKeyEvent(int unicode, int keycode, Qt::KeyboardModifiers
#endif
// If we press a key and it's going to be blocked, wake up the screen
- if ( block && isPress )
- qwsServerPrivate->_q_screenSaverWake();
-
- if ( block )
+ if (block) {
+ if (isPress)
+ qwsServerPrivate->_q_screenSaverWake();
return;
+ }
if (keyFilters) {
for (int i = 0; i < keyFilters->size(); ++i) {
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
index 0d65b61..c14f50b 100644
--- a/src/gui/embedded/qwslock.cpp
+++ b/src/gui/embedded/qwslock.cpp
@@ -45,8 +45,6 @@
#include "qwssignalhandler_p.h"
-#include <qglobal.h>
-#include <qdebug.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -68,164 +66,141 @@ QT_BEGIN_NAMESPACE
#error QWSLock currently requires semaphores
#endif
-QWSLock::QWSLock()
+QWSLock::QWSLock(int id) : semId(id)
{
- semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
+ static unsigned short initialValues[3] = { 1, 1, 0 };
- if (semId == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to create semaphore");
- }
- QWSSignalHandler::instance()->addSemaphore(semId);
-
- qt_semun semval;
- semval.val = 1;
-
- if (semctl(semId, BackingStore, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize backingstore semaphore");
- }
- lockCount[BackingStore] = 0;
-
- if (semctl(semId, Communication, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize communication semaphore");
- }
- lockCount[Communication] = 0;
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addWSLock(this);
+#endif
- semval.val = 0;
- if (semctl(semId, RegionEvent, SETVAL, semval) == -1) {
- perror("QWSLock::QWSLock");
- qFatal("Unable to initialize region event semaphore");
+ if (semId == -1) {
+ semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
+ if (semId == -1) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to create semaphore");
+ }
+
+ qt_semun semval;
+ semval.array = initialValues;
+ if (semctl(semId, 0, SETALL, semval) == -1) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to initialize semaphores");
+ }
}
-}
-QWSLock::QWSLock(int id)
-{
- semId = id;
- QWSSignalHandler::instance()->addSemaphore(semId);
lockCount[0] = lockCount[1] = 0;
}
QWSLock::~QWSLock()
{
- if (semId == -1)
- return;
- QWSSignalHandler::instance()->removeSemaphore(semId);
-}
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->removeWSLock(this);
+#endif
-static bool forceLock(int semId, int semNum, int)
-{
- int ret;
- do {
- sembuf sops = { semNum, -1, 0 };
-
- // As the BackingStore lock is a mutex, and only one process may own
- // the lock, it's safe to use SEM_UNDO. On the other hand, the
- // Communication lock is locked by the client but unlocked by the
- // server and therefore can't use SEM_UNDO.
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::lock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+ if (semId != -1) {
+ qt_semun semval;
+ semval.val = 0;
+ semctl(semId, 0, IPC_RMID, semval);
+ semId = -1;
+ }
}
-static bool up(int semId, int semNum)
+bool QWSLock::up(unsigned short semNum)
{
int ret;
- do {
- sembuf sops = { semNum, 1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::up: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+
+ sembuf sops = { semNum, 1, 0 };
+ // As the BackingStore lock is a mutex, and only one process may own
+ // the lock, it's safe to use SEM_UNDO. On the other hand, the
+ // Communication lock is locked by the client but unlocked by the
+ // server and therefore can't use SEM_UNDO.
+ if (semNum == BackingStore)
+ sops.sem_flg |= SEM_UNDO;
+
+ EINTR_LOOP(ret, semop(semId, &sops, 1));
+ if (ret == -1) {
+ qDebug("QWSLock::up(): %s", strerror(errno));
+ return false;
+ }
+
+ return true;
}
-static bool down(int semId, int semNum)
+bool QWSLock::down(unsigned short semNum, int)
{
int ret;
- do {
- sembuf sops = { semNum, -1, 0 };
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::down: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
- return (ret != -1);
+
+ sembuf sops = { semNum, -1, 0 };
+ // As the BackingStore lock is a mutex, and only one process may own
+ // the lock, it's safe to use SEM_UNDO. On the other hand, the
+ // Communication lock is locked by the client but unlocked by the
+ // server and therefore can't use SEM_UNDO.
+ if (semNum == BackingStore)
+ sops.sem_flg |= SEM_UNDO;
+
+ EINTR_LOOP(ret, semop(semId, &sops, 1));
+ if (ret == -1) {
+ qDebug("QWSLock::down(): %s", strerror(errno));
+ return false;
+ }
+
+ return true;
}
-static int getValue(int semId, int semNum)
+int QWSLock::getValue(unsigned short semNum) const
{
- int ret;
- do {
- ret = semctl(semId, semNum, GETVAL, 0);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::getValue: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
-
+ int ret = semctl(semId, semNum, GETVAL, 0);
+ if (ret == -1)
+ qDebug("QWSLock::getValue(): %s", strerror(errno));
return ret;
}
bool QWSLock::lock(LockType type, int timeout)
{
if (type == RegionEvent)
- return up(semId, RegionEvent);
+ return up(type);
- if (hasLock(type)) {
+ if (lockCount[type] > 0) {
++lockCount[type];
return true;
}
- if (!forceLock(semId, type, timeout))
- return false;
- ++lockCount[type];
- return true;
+ if (down(type, timeout)) {
+ ++lockCount[type];
+ return true;
+ }
+
+ return false;
}
bool QWSLock::hasLock(LockType type)
{
if (type == RegionEvent)
- return (getValue(semId, RegionEvent) == 0);
+ return getValue(type) == 0;
- return (lockCount[type] > 0);
+ return lockCount[type] > 0;
}
void QWSLock::unlock(LockType type)
{
if (type == RegionEvent) {
- down(semId, RegionEvent);
+ down(type, -1);
return;
}
- if (hasLock(type)) {
+ if (lockCount[type] > 0) {
--lockCount[type];
- if (hasLock(type))
+ if (lockCount[type] > 0)
return;
}
- const int semNum = type;
- int ret;
- do {
- sembuf sops = {semNum, 1, 0};
- if (semNum == QWSLock::BackingStore)
- sops.sem_flg |= SEM_UNDO;
-
- ret = semop(semId, &sops, 1);
- if (ret == -1 && errno != EINTR)
- qDebug("QWSLock::unlock: %s", strerror(errno));
- } while (ret == -1 && errno == EINTR);
+ up(type);
}
bool QWSLock::wait(LockType type, int timeout)
{
- bool ok = forceLock(semId, type, timeout);
+ bool ok = down(type, timeout);
if (ok)
unlock(type);
return ok;
diff --git a/src/gui/embedded/qwslock_p.h b/src/gui/embedded/qwslock_p.h
index 9a7f279..d020b22 100644
--- a/src/gui/embedded/qwslock_p.h
+++ b/src/gui/embedded/qwslock_p.h
@@ -55,17 +55,16 @@
#include <qglobal.h>
-QT_BEGIN_NAMESPACE
-
#ifndef QT_NO_QWS_MULTIPROCESS
+QT_BEGIN_NAMESPACE
+
class QWSLock
{
public:
enum LockType { BackingStore, Communication, RegionEvent };
- QWSLock();
- QWSLock(int lockId);
+ QWSLock(int lockId = -1);
~QWSLock();
bool lock(LockType type, int timeout = -1);
@@ -75,11 +74,16 @@ public:
int id() const { return semId; }
private:
+ bool up(unsigned short semNum);
+ bool down(unsigned short semNum, int timeout);
+ int getValue(unsigned short semNum) const;
+
int semId;
int lockCount[2];
};
-
QT_END_NAMESPACE
+
#endif // QT_NO_QWS_MULTIPROCESS
+
#endif // QWSLOCK_P_H
diff --git a/src/gui/embedded/qwssharedmemory.cpp b/src/gui/embedded/qwssharedmemory.cpp
index 66bedee..a677626 100644
--- a/src/gui/embedded/qwssharedmemory.cpp
+++ b/src/gui/embedded/qwssharedmemory.cpp
@@ -43,51 +43,51 @@
#if !defined(QT_NO_QWS_MULTIPROCESS)
+#include <sys/types.h>
+#include <sys/ipc.h>
#include <sys/shm.h>
+//#define QT_SHM_DEBUG
+
QT_BEGIN_NAMESPACE
QWSSharedMemory::QWSSharedMemory()
- : shmBase(0), shmSize(0), character(0), shmId(-1), key(-1)
+ : shmId(-1), shmBase(0), shmSize(0)
{
}
-
QWSSharedMemory::~QWSSharedMemory()
{
detach();
}
-/*
- man page says:
- On Linux, it is possible to attach a shared memory segment even if it
- is already marked to be deleted. However, POSIX.1-2001 does not spec-
- ify this behaviour and many other implementations do not support it.
-*/
-
bool QWSSharedMemory::create(int size)
{
if (shmId != -1)
detach();
- shmId = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
+ shmId = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600);
if (shmId == -1) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create allocating shared memory");
+ perror("QWSSharedMemory::create():");
qWarning("Error allocating shared memory of size %d", size);
#endif
return false;
}
- shmBase = shmat(shmId,0,0);
+ shmBase = shmat(shmId, 0, 0);
+ // On Linux, it is possible to attach a shared memory segment even if it
+ // is already marked to be deleted. However, POSIX.1-2001 does not specify
+ // this behaviour and many other implementations do not support it.
shmctl(shmId, IPC_RMID, 0);
- if (shmBase == (void*)-1) {
+ if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::create attaching to shared memory");
+ perror("QWSSharedMemory::create():");
qWarning("Error attaching to shared memory id %d", shmId);
#endif
- shmBase = 0;
+ detach();
return false;
}
+
return true;
}
@@ -95,91 +95,49 @@ bool QWSSharedMemory::attach(int id)
{
if (shmId == id)
return id != -1;
- if (shmId != -1)
- detach();
- shmBase = shmat(id,0,0);
- if (shmBase == (void*)-1) {
+ detach();
+
+ if (id == -1)
+ return false;
+
+ shmId = id;
+ shmBase = shmat(shmId, 0, 0);
+ if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
- perror("QWSSharedMemory::attach attaching to shared memory");
- qWarning("Error attaching to shared memory 0x%x of size %d",
- id, size());
+ perror("QWSSharedMemory::attach():");
+ qWarning("Error attaching to shared memory id %d", shmId);
#endif
- shmBase = 0;
+ detach();
return false;
}
- shmId = id;
+
return true;
}
-
-void QWSSharedMemory::detach ()
+void QWSSharedMemory::detach()
{
- if (!shmBase)
- return;
- shmdt (shmBase);
+ if (shmBase && shmBase != (void*)-1)
+ shmdt(shmBase);
shmBase = 0;
shmSize = 0;
shmId = -1;
}
-void QWSSharedMemory::setPermissions (mode_t mode)
+int QWSSharedMemory::size() const
{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- shm.shm_perm.mode = mode;
- shmctl (shmId, IPC_SET, &shm);
-}
-
-int QWSSharedMemory::size () const
-{
- struct shmid_ds shm;
- shmctl (shmId, IPC_STAT, &shm);
- return shm.shm_segsz;
-}
+ if (shmId == -1)
+ return 0;
+ if (!shmSize) {
+ struct shmid_ds shm;
+ shmctl(shmId, IPC_STAT, &shm);
+ const_cast<QWSSharedMemory *>(this)->shmSize = shm.shm_segsz;
+ }
-// old API
-
-
-
-QWSSharedMemory::QWSSharedMemory (int size, const QString &filename, char c)
-{
- shmSize = size;
- shmFile = filename;
- shmBase = 0;
- shmId = -1;
- character = c;
- key = ftok (shmFile.toLatin1().constData(), c);
-}
-
-
-
-bool QWSSharedMemory::create ()
-{
- shmId = shmget (key, shmSize, IPC_CREAT | 0666);
- return (shmId != -1);
-}
-
-void QWSSharedMemory::destroy ()
-{
- if (shmId != -1)
- shmctl(shmId, IPC_RMID, 0);
-}
-
-bool QWSSharedMemory::attach ()
-{
- if (shmId == -1)
- shmId = shmget (key, shmSize, 0);
-
- shmBase = shmat (shmId, 0, 0);
- if ((long)shmBase == -1)
- shmBase = 0;
-
- return (long)shmBase != 0;
+ return shmSize;
}
-
QT_END_NAMESPACE
#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssharedmemory_p.h b/src/gui/embedded/qwssharedmemory_p.h
index 31e69c4..f3ce241 100644
--- a/src/gui/embedded/qwssharedmemory_p.h
+++ b/src/gui/embedded/qwssharedmemory_p.h
@@ -53,49 +53,31 @@
// We mean it.
//
-#include "qplatformdefs.h"
-#include "QtCore/qstring.h"
+#include <qplatformdefs.h>
QT_BEGIN_NAMESPACE
#if !defined(QT_NO_QWS_MULTIPROCESS)
-class QWSSharedMemory {
+class QWSSharedMemory
+{
public:
-
QWSSharedMemory();
~QWSSharedMemory();
- void setPermissions(mode_t mode);
- int size() const;
- void *address() { return shmBase; }
-
- int id() const { return shmId; }
-
- void detach();
-
bool create(int size);
bool attach(int id);
+ void detach();
- //bool create(int size, const QString &filename, char c = 'Q');
- //bool attach(const QString &filename, char c = 'Q');
-// old API
-
- QWSSharedMemory(int, const QString &, char c = 'Q');
- void * base() { return address(); }
-
- bool create();
- void destroy();
+ int id() const { return shmId; }
- bool attach();
+ void *address() const { return shmBase; }
+ int size() const;
private:
+ int shmId;
void *shmBase;
int shmSize;
- QString shmFile;
- char character;
- int shmId;
- key_t key;
};
#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/embedded/qwssignalhandler.cpp b/src/gui/embedded/qwssignalhandler.cpp
index 730dbae..b13a57d 100644
--- a/src/gui/embedded/qwssignalhandler.cpp
+++ b/src/gui/embedded/qwssignalhandler.cpp
@@ -43,13 +43,10 @@
#ifndef QT_NO_QWS_SIGNALHANDLER
-#include <sys/types.h>
-#ifndef QT_NO_QWS_MULTIPROCESS
-# include <sys/ipc.h>
-# include <sys/sem.h>
+#include "qlock_p.h"
+#include "qwslock_p.h"
-# include <private/qcore_unix_p.h>
-#endif
+#include <sys/types.h>
#include <signal.h>
QT_BEGIN_NAMESPACE
@@ -87,42 +84,33 @@ QWSSignalHandler::QWSSignalHandler()
QWSSignalHandler::~QWSSignalHandler()
{
-#ifndef QT_NO_QWS_MULTIPROCESS
- while (!semaphores.isEmpty())
- removeSemaphore(semaphores.last());
-#endif
+ clear();
}
-#ifndef QT_NO_QWS_MULTIPROCESS
-void QWSSignalHandler::removeSemaphore(int semno)
+void QWSSignalHandler::clear()
{
- const int index = semaphores.lastIndexOf(semno);
- if (index != -1) {
- qt_semun semval;
- semval.val = 0;
- semctl(semaphores.at(index), 0, IPC_RMID, semval);
- semaphores.remove(index);
- }
+#if !defined(QT_NO_QWS_MULTIPROCESS)
+ // it is safe to call d-tors directly here since, on normal exit,
+ // lists should be empty; otherwise, we don't care about semi-alive objects
+ // and the only important thing here is to unregister the system semaphores.
+ while (!locks.isEmpty())
+ locks.takeLast()->~QLock();
+ while (!wslocks.isEmpty())
+ wslocks.takeLast()->~QWSLock();
+#endif
+ objects.clear();
}
-#endif // QT_NO_QWS_MULTIPROCESS
void QWSSignalHandler::handleSignal(int signum)
{
QWSSignalHandler *h = instance();
-
- signal(signum, h->oldHandlers[signum]);
-
-#ifndef QT_NO_QWS_MULTIPROCESS
- qt_semun semval;
- semval.val = 0;
- for (int i = 0; i < h->semaphores.size(); ++i)
- semctl(h->semaphores.at(i), 0, IPC_RMID, semval);
-#endif
-
- h->objects.clear();
+ if (h) {
+ signal(signum, h->oldHandlers[signum]);
+ h->clear();
+ }
raise(signum);
}
QT_END_NAMESPACE
-#endif // QT_QWS_NO_SIGNALHANDLER
+#endif // QT_NO_QWS_SIGNALHANDLER
diff --git a/src/gui/embedded/qwssignalhandler_p.h b/src/gui/embedded/qwssignalhandler_p.h
index dda9c76..217eda1 100644
--- a/src/gui/embedded/qwssignalhandler_p.h
+++ b/src/gui/embedded/qwssignalhandler_p.h
@@ -57,14 +57,17 @@
#ifndef QT_NO_QWS_SIGNALHANDLER
-#include <QtCore/qmap.h>
-#include <QtCore/qvector.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
#include <QtCore/qobjectcleanuphandler.h>
QT_BEGIN_NAMESPACE
typedef void (*qt_sighandler_t)(int);
+class QLock;
+class QWSLock;
+
class QWSSignalHandlerPrivate;
class Q_GUI_EXPORT QWSSignalHandler
@@ -75,17 +78,24 @@ public:
~QWSSignalHandler();
#ifndef QT_NO_QWS_MULTIPROCESS
- inline void addSemaphore(int semno) { semaphores.append(semno); }
- void removeSemaphore(int semno);
+ inline void addLock(QLock *lock) { locks.append(lock); }
+ inline void removeLock(QLock *lock) { locks.removeOne(lock); }
+ inline void addWSLock(QWSLock *wslock) { wslocks.append(wslock); }
+ inline void removeWSLock(QWSLock *wslock) { wslocks.removeOne(wslock); }
#endif
inline void addObject(QObject *object) { (void)objects.add(object); }
private:
QWSSignalHandler();
+
+ void clear();
+
static void handleSignal(int signal);
- QMap<int, qt_sighandler_t> oldHandlers;
+
+ QHash<int, qt_sighandler_t> oldHandlers;
#ifndef QT_NO_QWS_MULTIPROCESS
- QVector<int> semaphores;
+ QList<QLock *> locks;
+ QList<QWSLock *> wslocks;
#endif
QObjectCleanupHandler objects;
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp
index cd6416c..76d2d04 100644
--- a/src/gui/graphicsview/qgraphicslayout.cpp
+++ b/src/gui/graphicsview/qgraphicslayout.cpp
@@ -478,7 +478,7 @@ static bool g_instantInvalidatePropagation = false;
/*!
\internal
\since 4.8
- \see instantInvalidatePropagation
+ \sa instantInvalidatePropagation()
Calling this function with \a enable set to true will enable a feature that
makes propagation of invalidation up to ancestor layout items to be done in
@@ -489,7 +489,7 @@ static bool g_instantInvalidatePropagation = false;
invalid (not activated). This is the recommended behaviour.
If not set it will also propagate up the parentLayoutItem() hierarchy, but
- it will stop at the \i first \i widget it encounters, and post a layout
+ it will stop at the \e{first widget} it encounters, and post a layout
request to the widget. When the layout request is consumed, this might
cause it to continue propagation up to the parentLayoutItem() of the
widget. It will continue in this fashion until it has reached a widget with
@@ -508,7 +508,7 @@ void QGraphicsLayout::setInstantInvalidatePropagation(bool enable)
/*!
\internal
\since 4.8
- \see setInstantInvalidatePropagation
+ \sa setInstantInvalidatePropagation()
returns true if the complete widget/layout hierarchy is rearranged in one go.
*/
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 61a228d..14322dc 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -2008,10 +2008,11 @@ void QImage::fill(uint pixel)
/*!
\fn void QImage::fill(Qt::GlobalColor color)
-
\overload
-
\since 4.8
+
+ Fills the image with the given \a color, described as a standard global
+ color.
*/
void QImage::fill(Qt::GlobalColor color)
@@ -2022,7 +2023,7 @@ void QImage::fill(Qt::GlobalColor color)
/*!
- \fn void QImage::fill(Qt::GlobalColor color)
+ \fn void QImage::fill(const QColor &color)
\overload
diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp
index cb30161..bdf1f90 100644
--- a/src/gui/image/qpixmap_mac.cpp
+++ b/src/gui/image/qpixmap_mac.cpp
@@ -648,7 +648,7 @@ void QMacPixmapData::macCreatePixels()
}
if (pixels)
- memcpy(base_pixels, pixels, pixelsSize);
+ memcpy(base_pixels, pixels, qMin(pixelsSize, (uint) numBytes));
pixels = base_pixels;
pixelsSize = numBytes;
}
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 433c0e9..5d3d8d9 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -159,6 +159,7 @@ private:
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
QBasicTimer m_tempPreeditStringTimeout;
bool m_hasTempPreeditString;
+ QString m_cachedPreeditString;
int m_splitViewResizeBy;
Qt::WindowStates m_splitViewPreviousWindowStates;
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index daa448b..ebf0ff8 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -141,6 +141,16 @@ QCoeFepInputContext::~QCoeFepInputContext()
void QCoeFepInputContext::reset()
{
+ Qt::InputMethodHints currentHints = Qt::ImhNone;
+ if (focusWidget()) {
+ QWidget *proxy = focusWidget()->focusProxy();
+ currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints();
+ }
+ // Store a copy of preedit text, if prediction is active and input context is reseted.
+ // This is to ensure that we can replace preedit string after losing focus to FEP manager's
+ // internal sub-windows.
+ if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText))
+ m_cachedPreeditString = m_preeditString;
commitCurrentString(true);
}
@@ -175,6 +185,8 @@ void QCoeFepInputContext::setFocusWidget(QWidget *w)
void QCoeFepInputContext::widgetDestroyed(QWidget *w)
{
+ m_cachedPreeditString.clear();
+
// Make sure that the input capabilities of whatever new widget got focused are queried.
CCoeControl *ctrl = w->effectiveWinId();
if (ctrl->IsFocused()) {
@@ -353,6 +365,11 @@ bool QCoeFepInputContext::symbianFilterEvent(QWidget *keyWidget, const QSymbianE
}
}
+ if (event->type() == QSymbianEvent::ResourceChangeEvent
+ && event->resourceChangeType() == KEikMessageFadeAllWindows) {
+ reset();
+ }
+
return false;
}
@@ -826,13 +843,6 @@ void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attri
}
}
- if (attributes->size() == oldSize) {
- // S60 didn't provide any format, so let's give our own instead.
- attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
- 0,
- m_preeditString.size(),
- standardFormat(PreeditFormat)));
- }
}
void QCoeFepInputContext::queueInputCapabilitiesChanged()
@@ -862,6 +872,8 @@ void QCoeFepInputContext::ensureInputCapabilitiesChanged()
void QCoeFepInputContext::translateInputWidget()
{
QGraphicsView *gv = qobject_cast<QGraphicsView *>(S60->splitViewLastWidget);
+ if (!gv)
+ return;
QRect splitViewRect = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
QRectF cursor = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
@@ -909,6 +921,8 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
if (!w)
return;
+ m_cachedPreeditString.clear();
+
commitTemporaryPreeditString();
QList<QInputMethodEvent::Attribute> attributes;
@@ -965,7 +979,10 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
QVariant()));
QString newPreeditString = qt_TDesC2QString(aNewInlineText);
QInputMethodEvent event(newPreeditString, attributes);
- if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
+ if (!m_cachedPreeditString.isEmpty()) {
+ event.setCommitString(QLatin1String(""), -m_cachedPreeditString.length(), m_cachedPreeditString.length());
+ m_cachedPreeditString.clear();
+ } else if (newPreeditString.isEmpty() && m_preeditString.isEmpty()) {
// In Symbian world this means "erase last character".
event.setCommitString(QLatin1String(""), -1, 1);
}
@@ -1155,7 +1172,18 @@ void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction)
m_hasTempPreeditString = false;
- if (cancelFepTransaction) {
+ //Only cancel FEP transactions with prediction, when there is still active window.
+ Qt::InputMethodHints currentHints = Qt::ImhNone;
+ if (focusWidget()) {
+ if (focusWidget()->focusProxy())
+ currentHints = focusWidget()->focusProxy()->inputMethodHints();
+ else
+ currentHints = focusWidget()->inputMethodHints();
+ }
+ bool predictive = !(currentHints & Qt::ImhNoPredictiveText);
+ bool widgetAndWindowAvailable = QApplication::activeWindow() && focusWidget();
+
+ if (cancelFepTransaction && ((predictive && widgetAndWindowAvailable) || !predictive)) {
CCoeFep* fep = CCoeEnv::Static()->Fep();
if (fep)
fep->CancelTransaction();
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 52fbfa5..617409f 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -1102,7 +1102,7 @@ void QTableView::setRootIndex(const QModelIndex &index)
}
/*!
- \reimp
+ \internal
*/
void QTableView::doItemsLayout()
{
diff --git a/src/gui/kernel/qactiongroup.cpp b/src/gui/kernel/qactiongroup.cpp
index 8029dfb..cbab6aa 100644
--- a/src/gui/kernel/qactiongroup.cpp
+++ b/src/gui/kernel/qactiongroup.cpp
@@ -108,8 +108,8 @@ void QActionGroupPrivate::_q_actionHovered()
\ingroup mainwindow-classes
- In some situations it is useful to group actions together. For
- example, if you have a \gui{Left Align} action, a \gui{Right
+ In some situations it is useful to group QAction objects together.
+ For example, if you have a \gui{Left Align} action, a \gui{Right
Align} action, a \gui{Justify} action, and a \gui{Center} action,
only one of these actions should be active at any one time. One
simple way of achieving this is to group the actions together in
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index eb0fd8d..343b68f 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -715,6 +715,7 @@ void qt_event_request_showsheet(QWidget *w)
{
Q_ASSERT(qt_mac_is_macsheet(w));
#ifdef QT_MAC_USE_COCOA
+ w->repaint();
[NSApp beginSheet:qt_mac_window_for(w) modalForWindow:qt_mac_window_for(w->parentWidget())
modalDelegate:nil didEndSelector:nil contextInfo:0];
#else
@@ -2623,8 +2624,6 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap
Return true if you want to stop the event from being processed.
Return false for normal event dispatching. The default
implementation returns false.
-
- \sa macEventFilter(void *nsevent)
*/
bool QApplication::macEventFilter(EventHandlerCallRef, EventRef)
{
diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp
index 98359e4..b23c15c 100644
--- a/src/gui/kernel/qapplication_qpa.cpp
+++ b/src/gui/kernel/qapplication_qpa.cpp
@@ -444,6 +444,9 @@ void QApplication::alert(QWidget *, int)
{
}
+/*!
+ \internal
+*/
QPlatformNativeInterface *QApplication::platformNativeInterface()
{
QPlatformIntegration *pi = QApplicationPrivate::platformIntegration();
@@ -612,6 +615,9 @@ void QApplication::setMainWidget(QWidget *mainWidget)
void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
{
+ if (!e->widget)
+ return;
+
// qDebug() << "handleMouseEvent" << tlw << ev.pos() << ev.globalPos() << hex << ev.buttons();
static QWeakPointer<QWidget> implicit_mouse_grabber;
@@ -768,6 +774,10 @@ void QApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mouse
void QApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
{
+
+ if (!e->widget)
+ return;
+
// QPoint localPoint = ev.pos();
QPoint globalPoint = e->globalPos;
// bool trustLocalPoint = !!tlw; //is there something the local point can be local to?
@@ -842,12 +852,18 @@ void QApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEven
void QApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
{
+ if (!e->enter)
+ return;
+
QApplicationPrivate::dispatchEnterLeave(e->enter.data(),0);
qt_last_mouse_receiver = e->enter.data();
}
void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
{
+ if (!e->leave)
+ return;
+
QApplicationPrivate::dispatchEnterLeave(0,qt_last_mouse_receiver);
if (e->leave.data() && !e->leave.data()->isAncestorOf(qt_last_mouse_receiver)) //(???) this should not happen
@@ -858,6 +874,9 @@ void QApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::Leave
void QApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
{
+ if (!e->activated)
+ return;
+
QApplication::setActiveWindow(e->activated.data());
}
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 14f7790..abee361 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -112,19 +112,6 @@
#include <qvfbhdr.h>
-#ifndef QT_NO_QWS_MULTIPROCESS
-#ifdef QT_NO_QSHM
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#ifndef Q_OS_DARWIN
-# include <sys/sem.h>
-#endif
-#include <sys/socket.h>
-#else
-#include "private/qwssharedmemory_p.h"
-#endif
-#endif
-
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DIRECTPAINTER
@@ -230,7 +217,7 @@ QString qws_dataDir()
qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData());
#endif
- result.append("/");
+ result.append(QLatin1Char('/'));
return result;
}
@@ -2197,6 +2184,11 @@ void qt_init(QApplicationPrivate *priv, int type)
qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
const char *display = ::getenv("QWS_DISPLAY");
+
+#ifdef QT_QWS_DEFAULT_DRIVER_NAME
+ if (!display) display = QT_QWS_DEFAULT_DRIVER_NAME;
+#endif
+
if (display)
qws_display_spec = display; // since we setenv later!
@@ -3565,13 +3557,8 @@ bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab i
QEvent::KeyPress : QEvent::KeyRelease;
bool autor = event->simpleData.is_auto_repeat;
QString text;
- char ascii = 0;
- if (event->simpleData.unicode) {
- QChar ch(event->simpleData.unicode);
- if (ch.unicode() != 0xffff)
- text += ch;
- ascii = ch.toLatin1();
- }
+ if (event->simpleData.unicode && event->simpleData.unicode != 0xffff)
+ text += QChar(event->simpleData.unicode);
code = event->simpleData.keycode;
#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index e9d58c7..31d02d4 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -74,6 +74,7 @@
# include <centralrepository.h>
# include "qs60mainappui.h"
# include "qinputcontext.h"
+# include <private/qgraphicssystemex_symbian_p.h>
#endif
#if defined(Q_WS_S60)
@@ -1694,7 +1695,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
if (commandLine) {
// After this construction, CEikonEnv will be available from CEikonEnv::Static().
// (much like our qApp).
- QtEikonEnv* coe = new QtEikonEnv;
+ CEikonEnv* coe = new CEikonEnv;
//not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there.
TRAPD(err, coe->ConstructAppFromCommandLineL(factory, *commandLine));
if(err != KErrNone) {
@@ -1850,26 +1851,12 @@ void qt_init(QApplicationPrivate * /* priv */, int)
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = true;
- const TUid KIvePropertyCat = {0x2726beef};
- enum TIvePropertyChipType {
- EVCBCM2727B1 = 0x00000000,
- EVCBCM2763A0 = 0x04000100,
- EVCBCM2763B0 = 0x04000102,
- EVCBCM2763C0 = 0x04000103,
- EVCBCM2763C1 = 0x04000104,
- EVCBCMUnknown = 0x7fffffff
- };
-
- TInt chipType = EVCBCMUnknown;
- if (RProperty::Get(KIvePropertyCat, 0 /*chip type*/, chipType) == KErrNone) {
- if (chipType == EVCBCM2727B1) {
- // We have only 32MB GPU memory. Use raster surfaces
- // for transparent TLWs.
- QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
- }
- } else {
+ if (QSymbianGraphicsSystemEx::hasBCM2727()) {
+ // We have only 32MB GPU memory. Use raster surfaces
+ // for transparent TLWs.
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
}
+
if (QApplicationPrivate::graphics_system_name == QLatin1String("raster"))
QApplicationPrivate::instance()->useTranslucentEGLSurfaces = false;
#else
@@ -2027,7 +2014,7 @@ void QApplicationPrivate::openPopup(QWidget *popup)
QApplicationPrivate::popupWidgets->append(popup);
// Cancel focus widget pointer capture and long tap timer
- if (QApplication::focusWidget()) {
+ if (QApplication::focusWidget() && QApplication::focusWidget()->effectiveWinId()) {
static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
QApplication::focusWidget()->effectiveWinId()->SetPointerCapture(false);
}
@@ -2278,6 +2265,7 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
#if defined(Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS)
case EEventDisplayChanged:
#endif
+ {
if (callSymbianEventFilters(symbianEvent))
return 1;
if (S60)
@@ -2289,6 +2277,12 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
QResizeEvent e(qt_desktopWidget->size(), oldSize);
QApplication::sendEvent(qt_desktopWidget, &e);
}
+ // Close non-native QMenus (that should act like context menus, i.e. close
+ // automatically when the orientation changes).
+ QMenu *activeMenu = qobject_cast<QMenu *>(QApplication::activePopupWidget());
+ if (activeMenu)
+ activeMenu->close();
+ }
return 0; // Propagate to CONE
case EEventWindowVisibilityChanged:
if (controlInMap) {
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 13ff85b..e32fdeb 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -320,7 +320,7 @@ static int qCocoaViewCount = 0;
}
- CGContextFlush(context);
+ CGContextSynchronize(context);
qt_mac_release_graphics_context(context);
return;
}
diff --git a/src/gui/kernel/qdesktopwidget.qdoc b/src/gui/kernel/qdesktopwidget.qdoc
index f71155e..b93bcb3 100644
--- a/src/gui/kernel/qdesktopwidget.qdoc
+++ b/src/gui/kernel/qdesktopwidget.qdoc
@@ -151,6 +151,11 @@
on Mac OS X, or the task bar on Windows). The default screen is used if
\a screen is -1.
+ \note In Symbian devices the available geometry reported by QDesktopWidget is
+ not guaranteed to be correct at the time the geometry change resize event
+ is passed to widgets. The correct way to listen for available geometry changes
+ is to connect to the workAreaResized() signal of QDesktopWidget.
+
\sa screenNumber(), screenGeometry()
*/
@@ -179,6 +184,11 @@
Returns the geometry of the screen with index \a screen. The default
screen is used if \a screen is -1.
+ \note In Symbian devices the screen geometry reported by QDesktopWidget is
+ not guaranteed to be correct at the time the geometry change resize event
+ is passed to widgets. The correct way to listen for screen geometry changes
+ is to connect to the resized() signal of QDesktopWidget.
+
\sa screenNumber()
*/
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index bdd2fe4..de2d87e 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3103,10 +3103,10 @@ QUrl QFileOpenEvent::url() const
}
/*!
- \fn bool openFile(QFile &file, QIODevice::OpenMode flags) const
+ \fn bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const
- Opens a QFile on the file referenced by this event.
- Returns true if successful; otherwise returns false.
+ Opens a QFile on the \a file referenced by this event in the mode specified
+ by \a flags. Returns true if successful; otherwise returns false.
This is necessary as some files cannot be opened by name, but require specific
information stored in this event.
diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/gui/kernel/qeventdispatcher_s60.cpp
index 3f20c08..d5a2761 100644
--- a/src/gui/kernel/qeventdispatcher_s60.cpp
+++ b/src/gui/kernel/qeventdispatcher_s60.cpp
@@ -45,62 +45,6 @@
QT_BEGIN_NAMESPACE
-QtEikonEnv::QtEikonEnv()
- : m_lastIterationCount(0)
- , m_savedStatusCode(KRequestPending)
- , m_hasAlreadyRun(false)
-{
-}
-
-QtEikonEnv::~QtEikonEnv()
-{
-}
-
-void QtEikonEnv::RunL()
-{
- QEventDispatcherS60 *dispatcher = qobject_cast<QEventDispatcherS60 *>(QAbstractEventDispatcher::instance());
- if (!dispatcher) {
- CEikonEnv::RunL();
- return;
- }
-
- if (m_lastIterationCount != dispatcher->iterationCount()) {
- m_hasAlreadyRun = false;
- m_lastIterationCount = dispatcher->iterationCount();
- }
-
- if (m_hasAlreadyRun) {
- // Fool the active scheduler into believing we are still waiting for events.
- // The window server thinks we are not, however.
- m_savedStatusCode = iStatus.Int();
- iStatus = KRequestPending;
- SetActive();
- dispatcher->queueDeferredActiveObjectsCompletion();
- } else {
- m_hasAlreadyRun = true;
- CEikonEnv::RunL();
- }
-}
-
-void QtEikonEnv::DoCancel()
-{
- complete();
-
- CEikonEnv::DoCancel();
-}
-
-void QtEikonEnv::complete()
-{
- if (m_hasAlreadyRun) {
- if (m_savedStatusCode != KRequestPending) {
- TRequestStatus *status = &iStatus;
- QEventDispatcherSymbian::RequestComplete(status, m_savedStatusCode);
- m_savedStatusCode = KRequestPending;
- }
- m_hasAlreadyRun = false;
- }
-}
-
QEventDispatcherS60::QEventDispatcherS60(QObject *parent)
: QEventDispatcherSymbian(parent),
m_noInputEvents(false)
@@ -183,14 +127,4 @@ void QEventDispatcherS60::removeInputEventsForWidget(QObject *object)
}
}
-// reimpl
-void QEventDispatcherS60::reactivateDeferredActiveObjects()
-{
- if (S60->qtOwnsS60Environment) {
- static_cast<QtEikonEnv *>(CCoeEnv::Static())->complete();
- }
-
- QEventDispatcherSymbian::reactivateDeferredActiveObjects();
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qeventdispatcher_s60_p.h b/src/gui/kernel/qeventdispatcher_s60_p.h
index 49ec568..c7cf2b2 100644
--- a/src/gui/kernel/qeventdispatcher_s60_p.h
+++ b/src/gui/kernel/qeventdispatcher_s60_p.h
@@ -62,31 +62,6 @@ QT_BEGIN_NAMESPACE
class QEventDispatcherS60;
-class QtEikonEnv : public CEikonEnv
-{
-public:
- QtEikonEnv();
- ~QtEikonEnv();
-
- // from CActive.
- void RunL();
- void DoCancel();
-
- void complete();
-
-private:
- // Workaround for a BC break from S60 3.2 -> 5.0, where the CEikonEnv override was removed.
- // To avoid linking to that when we build against 3.2, define an empty body here.
- // Reserved_*() have been verified to be empty in the S60 code.
- void Reserved_1() {}
- void Reserved_2() {}
-
-private:
- int m_lastIterationCount;
- TInt m_savedStatusCode;
- bool m_hasAlreadyRun;
-};
-
class Q_GUI_EXPORT QEventDispatcherS60 : public QEventDispatcherSymbian
{
Q_OBJECT
@@ -102,8 +77,6 @@ public:
void saveInputEvent(QSymbianControl *control, QWidget *widget, QInputEvent *event);
- void reactivateDeferredActiveObjects();
-
private:
bool sendDeferredInputEvents();
diff --git a/src/gui/kernel/qgenericplugin_qpa.cpp b/src/gui/kernel/qgenericplugin_qpa.cpp
index ca2fe7a..e7b65b7 100644
--- a/src/gui/kernel/qgenericplugin_qpa.cpp
+++ b/src/gui/kernel/qgenericplugin_qpa.cpp
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
\brief The QGenericPlugin class is an abstract base class for
window-system related plugins in Qt QPA.
- Note that this class is only available in \l{Qt QPA}.
+ Note that this class is only available in Qt QPA.
A mouse plugin can be created by subclassing
QGenericPlugin and reimplementing the pure virtual keys() and
diff --git a/src/gui/kernel/qgenericpluginfactory_qpa.cpp b/src/gui/kernel/qgenericpluginfactory_qpa.cpp
index 8db22fb..fb6a0d8 100644
--- a/src/gui/kernel/qgenericpluginfactory_qpa.cpp
+++ b/src/gui/kernel/qgenericpluginfactory_qpa.cpp
@@ -65,8 +65,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
\brief The QGenericPluginFactory class creates window-system
related plugin drivers in Qt QPA.
- Note that this class is only available in \l{Qt QPA}.
-
+ Note that this class is only available in Qt QPA.
\sa QGenericPlugin
*/
diff --git a/src/gui/kernel/qplatformclipboard_qpa.cpp b/src/gui/kernel/qplatformclipboard_qpa.cpp
index 7905185..f8e4b62 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.cpp
+++ b/src/gui/kernel/qplatformclipboard_qpa.cpp
@@ -83,7 +83,7 @@ QPlatformClipboard::~QPlatformClipboard()
}
-const QMimeData *QPlatformClipboard::mimeData(QClipboard::Mode mode) const
+QMimeData *QPlatformClipboard::mimeData(QClipboard::Mode mode)
{
//we know its clipboard
Q_UNUSED(mode);
diff --git a/src/gui/kernel/qplatformclipboard_qpa.h b/src/gui/kernel/qplatformclipboard_qpa.h
index 41aa951..6a40fbc 100644
--- a/src/gui/kernel/qplatformclipboard_qpa.h
+++ b/src/gui/kernel/qplatformclipboard_qpa.h
@@ -59,7 +59,7 @@ class Q_GUI_EXPORT QPlatformClipboard
public:
virtual ~QPlatformClipboard();
- virtual const QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard ) const;
+ virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
virtual bool supportsMode(QClipboard::Mode mode) const;
void emitChanged(QClipboard::Mode mode);
diff --git a/src/gui/kernel/qplatformcursor_qpa.cpp b/src/gui/kernel/qplatformcursor_qpa.cpp
index e612e2d..0695486 100644
--- a/src/gui/kernel/qplatformcursor_qpa.cpp
+++ b/src/gui/kernel/qplatformcursor_qpa.cpp
@@ -52,48 +52,46 @@ QT_BEGIN_NAMESPACE
QList <QWeakPointer<QPlatformCursor> > QPlatformCursorPrivate::instances;
/*!
- \class QGraphicsSystemCursor
+ \class QPlatformCursor
- \brief The QGraphicsSystemCursor class provides information about
+ \brief The QPlatformCursor class provides information about
pointer device events (movement, buttons), and requests to change
the currently displayed cursor.
- Note that QGraphicsSystemCursor does not include any graphics for
+ Note that QPlatformCursor does not include any graphics for
display. An application that sets a QCursor may provide its own
graphics.
- \sa QGraphicsSystemCursorImage
+ \sa QPlatformCursorImage
*/
/*!
- \fn virtual void QGraphicsSystemCursor::pointerEvent(const QMouseEvent & event)
+ \fn virtual void QPlatformCursor::pointerEvent(const QMouseEvent & event)
This method is called by Qt whenever a QMouseEvent is generated by the
underlying pointer input. \a event is a reference to the QMouseEvent in
question. A default do-nothing implementation is provided.
-
- \sa QApplicationPrivate::handleMouseEvent()
*/
/*!
- \fn virtual void QGraphicsSystemCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
+ \fn virtual void QPlatformCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
\brief This method is called by Qt whenever the cursor graphic should be changed.
- Implementation of this method is mandatory for a subclass of QGraphicsSystemCursor.
+ Implementation of this method is mandatory for a subclass of QPlatformCursor.
\a widgetCursor is a pointer to the QCursor that should be displayed.
\a widget is a pointer to the widget currently displayed at QCursor::pos(). Note
that this may be 0 if the current position is not occupied by a displayed widget.
- \sa QApplicationPrivate::handleMouseEvent(), QCursor::pos()
+ \sa QCursor::pos()
*/
/*!
- \fn QGraphicsSystemCursor::QGraphicsSystemCursor()
+ \fn QPlatformCursor::QPlatformCursor(QPlatformScreen *screen)
- \brief Constructs a QGraphicsSystemCursor
+ Constructs a QPlatformCursor for the given \a screen.
*/
QPlatformCursor::QPlatformCursor(QPlatformScreen *scr )
: screen(scr)
@@ -106,12 +104,12 @@ QPlatformCursor::QPlatformCursor(QPlatformScreen *scr )
// from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp
/*!
- \class QGraphicsSystemCursorImage
+ \class QPlatformCursorImage
- \brief The QGraphicsSystemCursorImage class provides a set of graphics
+ \brief The QPlatformCursorImage class provides a set of graphics
intended to be used as cursors.
- \sa QGraphicsSystemCursor
+ \sa QPlatformCursor
*/
static QPlatformCursorImage *systemCursorTable[Qt::LastCursor+1];
@@ -502,7 +500,7 @@ void QPlatformCursorImage::createSystemCursor(int id)
}
/*!
- \fn void QGraphicsSystemCursorImage::set(Qt::CursorShape id)
+ \fn void QPlatformCursorImage::set(Qt::CursorShape id)
\brief Calling this method sets the cursor image to the specified shape
@@ -531,15 +529,8 @@ void QPlatformCursorImage::set(Qt::CursorShape id)
}
/*!
- \fn void QGraphicsSystemCursorImage::set(const QImage * image, int hx, int hy)
-
- \brief Set the cursor image to the specified QImage, with the hotsport at (hx, hy)
-
- \a image A pointer to a QImage
-
- \a hx The x coordinate of the cursor's hotspot
-
- \a hy the y coordinate of the cursor's hotspot
+ Sets the cursor image to the given \a image, with the hotspot at the
+ point specified by (\a hx, \a hy).
*/
void QPlatformCursorImage::set(const QImage &image, int hx, int hy)
@@ -550,22 +541,19 @@ void QPlatformCursorImage::set(const QImage &image, int hx, int hy)
}
/*!
- \fn void QGraphicsSystemCursorImage::set(const uchar *data, const uchar *mask, int width, int height, int hx, int hy)
-
- \brief set the cursor image to the graphic represented by the combination of data, mask,
- width, and height
-
- \a data The pixel data of the graphic
-
- \a mask Mask data for the graphic. pixels in data with a corresponding mask bit of 0 are not drawn
+ \fn void QPlatformCursorImage::set(const uchar *data, const uchar *mask, int width, int height, int hx, int hy)
- \a width The width of the graphic in pixels
+ Sets the cursor image to the graphic represented by the combination of
+ \a data and \a mask, with dimensions given by \a width and \a height and a
+ hotspot at the point specified by (\a hx, \a hy).
- \a height The height of the graphic in pixels
+ The image data specified by \a data must be supplied in the format
+ described by QImage::Format_Indexed8.
- \a hx The X hotspot of the cursor graphic
-
- \a hy The Y hotspot of the cursor graphic
+ The corresponding mask data specified by \a mask must be supplied in a
+ character array containing packed 1 bit per pixel format data, with any
+ padding bits at the end of the array. Bits of value 0 represent transparent
+ pixels in the image data.
*/
void QPlatformCursorImage::set(const uchar *data, const uchar *mask,
int width, int height, int hx, int hy)
@@ -625,34 +613,23 @@ void QPlatformCursorImage::set(const uchar *data, const uchar *mask,
}
/*!
- \fn QGraphicsSystemCursorImage::QGraphicsSystemCursorImage(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY)
-
- \brief set the cursor image to the graphic represented by the combination of data, mask,
- width, and height
-
- \a data The pixel data of the graphic
-
- \a mask Mask data for the graphic. pixels in data with a corresponding mask bit of 0 are not drawn
-
- \a width The width of the graphic in pixels
-
- \a height The height of the graphic in pixels
-
- \a hotX The X hotspot of the cursor graphic
+ \fn QPlatformCursorImage::QPlatformCursorImage(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY)
- \a hotY The Y hotspot of the cursor graphic
+ Sets the cursor image to the graphic represented by the combination of
+ \a data and \a mask, with dimensions given by \a width and \a height and a
+ hotspot at the point specified by (\a hotX, \a hotY).
- \sa set
+ \sa set()
*/
/*!
- \fn QImage *QGraphicsSystemCursorImage::image()
+ \fn QImage *QPlatformCursorImage::image()
\brief Return the cursor graphic as a pointer to a QImage
*/
/*!
- \fn QPoint QGraphicsSystemCursorImage::hotspot()
+ \fn QPoint QPlatformCursorImage::hotspot()
\brief Return the cursor's hotspot
*/
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
index 8daa5d4..5c56efb 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ b/src/gui/kernel/qplatformglcontext_qpa.cpp
@@ -191,17 +191,17 @@ void QPlatformGLContext::deleteQGLContext()
which maps to the QPlatformGLContext.
*/
-/*! \fn void swapBuffers()
+/*! \fn void QPlatformGLContext::swapBuffers()
Reimplement in subclass to native swap buffers calls
*/
-/*! getProcAddress(const QString& procName)
+/*! \fn void *QPlatformGLContext::getProcAddress(const QString &procName)
Reimplement in subclass to native getProcAddr calls.
Note: its convenient to use qPrintable(const QString &str) to get the const char * pointer
*/
-/*! platformWindowFormat() const
+/*! \fn QPlatformWindowFormat QPlatformGLContext::platformWindowFormat() const
QWidget has the function qplatformWindowFormat(). That function is for the application
programmer to request the format of the window and the context that he wants.
diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp
index 972fb0a..29287fe 100644
--- a/src/gui/kernel/qplatformintegration_qpa.cpp
+++ b/src/gui/kernel/qplatformintegration_qpa.cpp
@@ -132,20 +132,20 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
the recommended approach for making new platform plugin is to copy an existing plugin inside
the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree.
- The minimal platformintegration is the smallest platform integration it is possible to make,
+ The minimal platform integration is the smallest platform integration it is possible to make,
which makes it an ideal starting point for new plugins. For a slightly more advanced plugin,
consider reviewing the directfb plugin, or the testlite plugin.
*/
/*!
- \fn QPixmapData *createPixmapData(QPixmapData::PixelType type) const
+ \fn QPixmapData *QPlatformIntegration::createPixmapData(QPixmapData::PixelType type) const
Factory function for QPixmapData. PixelType can be either PixmapType or BitmapType.
\sa QPixmapData
*/
/*!
- \fn QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const
+ \fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWidget *widget, WId winId = 0) const
Factory function for QPlatformWindow. The widget parameter is a pointer to the top level
widget(tlw) which the QPlatformWindow is suppose to be created for. The WId handle is actually
@@ -162,7 +162,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/
/*!
- \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const
+ \fn QWindowSurface *QPlatformIntegration::createWindowSurface(QWidget *widget, WId winId) const
Factory function for QWindowSurface. The QWidget parameter is a pointer to the
top level widget(tlw) the window surface is created for. A QPlatformWindow is always created
@@ -175,7 +175,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/
/*!
- \fn void moveToScreen(QWidget *window, int screen)
+ \fn void QPlatformIntegration::moveToScreen(QWidget *window, int screen)
This function is called when a QWidget is displayed on screen, or the QWidget is to be
displayed on a new screen. The QWidget parameter is a pointer to the top level widget and
@@ -187,14 +187,14 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/
/*!
- \fn QList<QPlatformScreen *> screens() const
+ \fn QList<QPlatformScreen *> QPlatformIntegration::screens() const
Accessor function to a list of all the screens on the current system. The screen with the
index == 0 is the default/main screen.
*/
/*!
- \fn bool isVirtualDesktop()
+ \fn bool QPlatformIntegration::isVirtualDesktop()
Returns if the current windowing system configuration defines all the screens to be one
desktop(virtual desktop), or if each screen is a desktop of its own.
@@ -203,7 +203,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/
/*!
- \fn QPixmap grabWindow(WId window, int x, int y, int width, int height) const
+ \fn QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
This function is called when Qt needs to be able to grab the content of a window.
diff --git a/src/gui/kernel/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp
index 87e40e4..2a1e7e4 100644
--- a/src/gui/kernel/qplatformscreen_qpa.cpp
+++ b/src/gui/kernel/qplatformscreen_qpa.cpp
@@ -66,12 +66,15 @@ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const
return 0;
}
-/*! \fn physicalSize() const
- Reimplement in subclass to return the physical size of the screen. This function is used by
- QFont to convert point sizes to pixel sizes.
-
- Default implementation takes the pixel size of the screen, considers a dpi of 100 and returns
- the calculated (and probably wrong) physical size
+/*!
+ Reimplement this function in subclass to return the physical size of the
+ screen. This function is used by QFont to convert point sizes to pixel
+ sizes.
+
+ The default implementation takes the pixel size of the screen, considers a
+ resolution of 100 dots per inch, and returns the calculated physical size.
+ A device with a screen that has different resolutions will need to be
+ supported by a suitable reimplementation of this function.
*/
QSize QPlatformScreen::physicalSize() const
{
@@ -110,20 +113,20 @@ QPlatformScreen * QPlatformScreen::platformScreenForWidget(const QWidget *widget
QPlatformScreen is also used by the public api QDesktopWidget for information about the desktop.
*/
-/*! \fn geometry() const
+/*! \fn QRect QPlatformScreen::geometry() const = 0
Reimplement in subclass to return the pixel geometry of the screen
*/
-/*! \fn availableGeometry() const
+/*! \fn QRect QPlatformScreen::availableGeometry() const
Reimplement in subclass to return the pixel geometry of the available space
This normally is the desktop screen minus the task manager, global menubar etc.
*/
-/*! \fn depth() const
+/*! \fn int QPlatformScreen::depth() const = 0
Reimplement in subclass to return current depth of the screen
*/
-/*! \fn format() const
+/*! \fn QImage::Format QPlatformScreen::format() const = 0
Reimplement in subclass to return the image format which corresponds to the screen format
*/
diff --git a/src/gui/kernel/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp
index e89b458..482ae68 100644
--- a/src/gui/kernel/qplatformwindowformat_qpa.cpp
+++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp
@@ -122,8 +122,6 @@ public:
\i \link setStencil() Stencil buffer.\endlink
\i \link setStereo() Stereo buffers.\endlink
\i \link setDirectRendering() Direct rendering.\endlink
- \i \link setOverlay() Presence of an overlay.\endlink
- \i \link setPlane() Plane of an overlay.\endlink
\i \link setSampleBuffers() Multisample buffers.\endlink
\endlist
@@ -168,7 +166,7 @@ public:
United States and other countries.
\endlegalese
- \sa QPlatformContext, QWidget
+ \sa QPlatformGLContext, QWidget
*/
/*!
@@ -182,8 +180,6 @@ public:
\i \link setStencil() Stencil buffer:\endlink Enabled.
\i \link setStereo() Stereo:\endlink Disabled.
\i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setOverlay() Overlay:\endlink Disabled.
- \i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
\i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
\endlist
*/
@@ -207,14 +203,10 @@ QPlatformWindowFormat::QPlatformWindowFormat()
\snippet doc/src/snippets/code/src_opengl_qgl.cpp 3
Note that there are QGL::FormatOption values to turn format settings
- both on and off, e.g. QGL::DepthBuffer and QGL::NoDepthBuffer,
+ both on and off; e.g., QGL::DepthBuffer and QGL::NoDepthBuffer,
QGL::DirectRendering and QGL::IndirectRendering, etc.
- The \a plane parameter defaults to 0 and is the plane which this
- format should be associated with. Not all OpenGL implementations
- supports overlay/underlay rendering planes.
-
- \sa defaultFormat(), setOption(), setPlane()
+ \sa defaultFormat(), setOption()
*/
QPlatformWindowFormat::QPlatformWindowFormat(QPlatformWindowFormat::FormatOptions options)
@@ -619,8 +611,6 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const
Otherwise returns false.
WindowSurface is enabled by default.
-
- \sa setOverlay()
*/
/*!
@@ -628,9 +618,7 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const
otherwise the QWidget will only have a QPlatformWindow.
- This is useful for ie. QGLWidget where the QPlatformGLContext controls the surface.
-
- \sa hasOverlay()
+ This is useful for QGLWidget where the QPlatformGLContext controls the surface.
*/
void QPlatformWindowFormat::setWindowSurface(bool enable)
@@ -894,7 +882,7 @@ void QPlatformWindowFormat::setDefaultFormat(const QPlatformWindowFormat &f)
}
-/*!
+/*
Returns the default QPlatformWindowFormat for overlay contexts.
The default overlay format is:
@@ -907,9 +895,7 @@ void QPlatformWindowFormat::setDefaultFormat(const QPlatformWindowFormat &f)
\i \link setStencil() Stencil buffer:\endlink Disabled.
\i \link setStereo() Stereo:\endlink Disabled.
\i \link setDirectRendering() Direct rendering:\endlink Enabled.
- \i \link setOverlay() Overlay:\endlink Disabled.
\i \link setSampleBuffers() Multisample buffers:\endlink Disabled.
- \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
\endlist
\sa setDefaultFormat()
diff --git a/src/gui/kernel/qsessionmanager_qws.cpp b/src/gui/kernel/qsessionmanager_qws.cpp
index efe688e..e437635 100644
--- a/src/gui/kernel/qsessionmanager_qws.cpp
+++ b/src/gui/kernel/qsessionmanager_qws.cpp
@@ -43,6 +43,9 @@
#ifndef QT_NO_SESSIONMANAGER
+#include <qapplication.h>
+#include <private/qobject_p.h>
+
QT_BEGIN_NAMESPACE
class QSessionManagerPrivate : public QObjectPrivate
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index 7d7c56f..a866da3 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -48,9 +48,6 @@
#ifdef Q_WS_S60
#include "private/qsoftkeymanager_s60_p.h"
-#endif
-
-#ifdef SYMBIAN_VERSION_SYMBIAN3
#include "private/qt_s60_p.h"
#endif
@@ -105,7 +102,7 @@ QSoftKeyManager::QSoftKeyManager() :
QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *actionWidget)
{
QAction *action = new QAction(standardSoftKeyText(standardKey), actionWidget);
-#ifdef SYMBIAN_VERSION_SYMBIAN3
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
int key = 0;
switch (standardKey) {
case OkSoftKey:
@@ -171,7 +168,7 @@ void QSoftKeyManager::cleanupHash(QObject *obj)
Q_D(QSoftKeyManager);
QAction *action = qobject_cast<QAction*>(obj);
d->keyedActions.remove(action);
-#ifdef SYMBIAN_VERSION_SYMBIAN3
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
d->softKeyCommandActions.remove(action);
#endif
}
@@ -193,6 +190,11 @@ void QSoftKeyManager::sendKeyEvent()
void QSoftKeyManager::updateSoftKeys()
{
+#ifdef Q_WS_S60
+ // Do not adjust softkeys if application is not the topmost one
+ if (S60->wsSession().GetFocusWindowGroup() != S60->windowGroup().WindowGroupId())
+ return;
+#endif
QSoftKeyManager::instance()->d_func()->pendingUpdate = true;
QEvent *event = new QEvent(QEvent::UpdateSoftKeys);
QApplication::postEvent(QSoftKeyManager::instance(), event);
diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h
index bf4c747..5b76e60 100644
--- a/src/gui/kernel/qsoftkeymanager_common_p.h
+++ b/src/gui/kernel/qsoftkeymanager_common_p.h
@@ -72,7 +72,7 @@ protected:
QMultiHash<int, QAction*> requestedSoftKeyActions;
QWidget *initialSoftKeySource;
bool pendingUpdate;
-#ifdef SYMBIAN_VERSION_SYMBIAN3
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
QHash<QAction*, int> softKeyCommandActions;
#endif
};
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
index ab71064..acdb0e5 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -113,7 +113,7 @@ void QSoftKeyManagerPrivateS60::ensureCbaVisibilityAndResponsiviness(CEikButtonG
void QSoftKeyManagerPrivateS60::clearSoftkeys(CEikButtonGroupContainer &cba)
{
-#ifdef SYMBIAN_VERSION_SYMBIAN3
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
QT_TRAP_THROWING(
//EAknSoftkeyEmpty is used, because using -1 adds softkeys without actions on Symbian3
cba.SetCommandL(0, EAknSoftkeyEmpty, KNullDesC);
@@ -297,7 +297,7 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba,
QString text = softkeyText(*action);
TPtrC nativeText = qt_QString2TPtrC(text);
int command = S60_COMMAND_START + position;
-#ifdef SYMBIAN_VERSION_SYMBIAN3
+#if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4)
if (softKeyCommandActions.contains(action))
command = softKeyCommandActions.value(action);
#endif
diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp
index a9bfba6..56c3010 100644
--- a/src/gui/kernel/qwidget_qpa.cpp
+++ b/src/gui/kernel/qwidget_qpa.cpp
@@ -129,6 +129,11 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
+ d->aboutToDestroy();
+ if (!isWindow() && parentWidget())
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ d->deactivateWidgetCleanup();
+
if ((windowType() == Qt::Popup))
qApp->d_func()->closePopup(this);
@@ -136,6 +141,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (this == QApplicationPrivate::active_window)
QApplication::setActiveWindow(0);
+ setAttribute(Qt::WA_WState_Created, false);
+
if (windowType() != Qt::Desktop) {
if (destroySubWindows) {
QObjectList childList(children());
@@ -155,6 +162,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
d->hide_sys();
}
}
+
+ d->setWinId(0);
}
}
@@ -412,6 +421,7 @@ void QWidgetPrivate::hide_sys()
{
Q_Q(QWidget);
q->setAttribute(Qt::WA_Mapped, false);
+ deactivateWidgetCleanup();
if (!q->isWindow()) {
QWidget *p = q->parentWidget();
if (p &&p->isVisible()) {
@@ -681,8 +691,10 @@ int QWidget::metric(PaintDeviceMetric m) const
/*!
\preliminary
- Sets the window to be the \a window specified.
- The QWidget takes ownership of the \a surface.
+ Sets the window to be the platform \a window specified.
+
+ The widget takes ownership of the \a window. Any platform window
+ previously set on the widget will be destroyed.
*/
void QWidget::setPlatformWindow(QPlatformWindow *window)
{
@@ -711,6 +723,9 @@ QPlatformWindow *QWidget::platformWindow() const
return 0;
}
+/*!
+ Sets the platform window format for the widget to the \a format specified.
+*/
void QWidget::setPlatformWindowFormat(const QPlatformWindowFormat &format)
{
if (isWindow() || testAttribute(Qt::WA_NativeWindow)) {
@@ -727,16 +742,26 @@ void QWidget::setPlatformWindowFormat(const QPlatformWindowFormat &format)
}
}
+/*!
+ Returns the platform window format for the widget.
+*/
QPlatformWindowFormat QWidget::platformWindowFormat() const
{
Q_D(const QWidget);
+ QPlatformWindowFormat format;
+
QTLWExtra *extra = d->maybeTopData();
if (extra){
- return extra->platformWindowFormat;
+ format = extra->platformWindowFormat;
} else {
- return QPlatformWindowFormat::defaultFormat();
+ format = QPlatformWindowFormat::defaultFormat();
}
+
+ if (testAttribute(Qt::WA_TranslucentBackground))
+ format.setAlpha(true);
+
+ return format;
}
void QWidgetPrivate::createSysExtra()
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index f1496b1..d5ae364 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -6,6 +6,7 @@ HEADERS += \
painting/qcolor.h \
painting/qcolor_p.h \
painting/qcolormap.h \
+ painting/qcosmeticstroker_p.h \
painting/qdrawutil.h \
painting/qemulationpaintengine_p.h \
painting/qgraphicssystem_p.h \
@@ -15,7 +16,7 @@ HEADERS += \
painting/qoutlinemapper_p.h \
painting/qpaintdevice.h \
painting/qpaintengine.h \
- painting/qpaintengine_p.h \
+ painting/qpaintengine_p.h \
painting/qpaintengine_alpha_p.h \
painting/qpaintengine_preview_p.h \
painting/qpaintengineex_p.h \
@@ -54,6 +55,7 @@ SOURCES += \
painting/qbrush.cpp \
painting/qcolor.cpp \
painting/qcolor_p.cpp \
+ painting/qcosmeticstroker.cpp \
painting/qcssutil.cpp \
painting/qdrawutil.cpp \
painting/qemulationpaintengine.cpp \
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 5d8f43b..79c4c4e 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -1826,9 +1826,9 @@ static QPointF qt_radial_gradient_adapt_focal_point(const QPointF &center,
radius and \a focalPoint.
\note If the given focal point is outside the circle defined by the
- center (\a cx, \a cy) and the \a radius it will be re-adjusted to
- the intersection between the line from the center to the focal point
- and the circle.
+ \a center point and \a radius, it will be re-adjusted to lie at a point on
+ the circle where it intersects with the line from \a center to
+ \a focalPoint.
\sa QGradient::setColorAt(), QGradient::setStops()
*/
@@ -1947,11 +1947,9 @@ QRadialGradient::QRadialGradient(const QPointF &center, qreal centerRadius, cons
/*!
\since 4.8
- Constructs an extended radial gradient with the given \a center, \a
- centerRadius, \a focalPoint, and \a focalRadius.
- Constructs a radial gradient with the given center (\a cx, \a cy),
- center radius \a centerRadius, focal point (\a fx, \a fy), and
- focal radius \a focalRadius.
+ Constructs an extended radial gradient with the given center
+ (\a cx, \a cy), center radius, \a centerRadius, focal point, (\a fx, \a fy),
+ and focal radius \a focalRadius.
*/
QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
{
@@ -2049,7 +2047,7 @@ qreal QRadialGradient::centerRadius() const
return m_data.radial.cradius;
}
-/*
+/*!
\since 4.8
Sets the center radius of this radial gradient in logical coordinates
@@ -2080,7 +2078,7 @@ qreal QRadialGradient::focalRadius() const
return u.f;
}
-/*
+/*!
\since 4.8
Sets the focal radius of this radial gradient in logical coordinates
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
new file mode 100644
index 0000000..cdc0978
--- /dev/null
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -0,0 +1,1010 @@
+/****************************************************************************
+**
+** 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 "qcosmeticstroker_p.h"
+#include "private/qpainterpath_p.h"
+#include <qdebug.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+#if 0
+inline QString capString(int caps)
+{
+ QString str;
+ if (caps & QCosmeticStroker::CapBegin) {
+ str += "CapBegin ";
+ }
+ if (caps & QCosmeticStroker::CapEnd) {
+ str += "CapEnd ";
+ }
+ return str;
+}
+#endif
+
+#define toF26Dot6(x) ((int)((x)*64.))
+
+static inline uint sourceOver(uint d, uint color)
+{
+ return color + BYTE_MUL(d, qAlpha(~color));
+}
+
+inline static int F16Dot16FixedDiv(int x, int y)
+{
+ if (qAbs(x) > 0x7fff)
+ return (((qlonglong)x) << 16) / y;
+ return (x << 16) / y;
+}
+
+typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);
+
+namespace {
+
+struct Dasher {
+ QCosmeticStroker *stroker;
+ int *pattern;
+ int offset;
+ int dashIndex;
+ int dashOn;
+
+ Dasher(QCosmeticStroker *s, bool reverse, int start, int stop)
+ : stroker(s)
+ {
+ int delta = stop - start;
+ if (reverse) {
+ pattern = stroker->reversePattern;
+ offset = stroker->patternLength - stroker->patternOffset - delta - ((start & 63) - 32);
+ dashOn = 0;
+ } else {
+ pattern = stroker->pattern;
+ offset = stroker->patternOffset - ((start & 63) - 32);
+ dashOn = 1;
+ }
+ offset %= stroker->patternLength;
+ if (offset < 0)
+ offset += stroker->patternLength;
+
+ dashIndex = 0;
+ while (offset>= pattern[dashIndex])
+ ++dashIndex;
+
+// qDebug() << " dasher" << offset/64. << reverse << dashIndex;
+ stroker->patternOffset += delta;
+ stroker->patternOffset %= stroker->patternLength;
+ }
+
+ bool on() const {
+ return (dashIndex + dashOn) & 1;
+ }
+ void adjust() {
+ offset += 64;
+ if (offset >= pattern[dashIndex]) {
+ ++dashIndex;
+ dashIndex %= stroker->patternSize;
+ }
+ offset %= stroker->patternLength;
+// qDebug() << "dasher.adjust" << offset/64. << dashIndex;
+ }
+};
+
+struct NoDasher {
+ NoDasher(QCosmeticStroker *, bool, int, int) {}
+ bool on() const { return true; }
+ void adjust(int = 0) {}
+};
+
+};
+
+template<DrawPixel drawPixel, class Dasher>
+static void drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+template<DrawPixel drawPixel, class Dasher>
+static void drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+
+inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage)
+{
+ const QRect &cl = stroker->clip;
+ if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
+ return;
+
+ int lastx = stroker->spans[stroker->current_span-1].x + stroker->spans[stroker->current_span-1].len ;
+ int lasty = stroker->spans[stroker->current_span-1].y;
+
+ if (stroker->current_span == QCosmeticStroker::NSPANS || y < lasty || (y == lasty && x < lastx)) {
+ stroker->blend(stroker->current_span, stroker->spans, &stroker->state->penData);
+ stroker->current_span = 0;
+ }
+
+ stroker->spans[stroker->current_span].x = ushort(x);
+ stroker->spans[stroker->current_span].len = 1;
+ stroker->spans[stroker->current_span].y = y;
+ stroker->spans[stroker->current_span].coverage = coverage*stroker->opacity >> 8;
+ ++stroker->current_span;
+}
+
+inline void drawPixelARGB32(QCosmeticStroker *stroker, int x, int y, int coverage)
+{
+ const QRect &cl = stroker->clip;
+ if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
+ return;
+
+ int offset = x + stroker->ppl*y;
+ uint c = BYTE_MUL(stroker->color, coverage);
+ stroker->pixels[offset] = sourceOver(stroker->pixels[offset], c);
+}
+
+inline void drawPixelARGB32Opaque(QCosmeticStroker *stroker, int x, int y, int)
+{
+ const QRect &cl = stroker->clip;
+ if (x < cl.x() || x > cl.right() || y < cl.y() || y > cl.bottom())
+ return;
+
+ int offset = x + stroker->ppl*y;
+ stroker->pixels[offset] = sourceOver(stroker->pixels[offset], stroker->color);
+}
+
+enum StrokeSelection {
+ Aliased = 0,
+ AntiAliased = 1,
+ Solid = 0,
+ Dashed = 2,
+ RegularDraw = 0,
+ FastDraw = 4
+};
+
+static StrokeLine strokeLine(int strokeSelection)
+{
+ StrokeLine stroke;
+
+ switch (strokeSelection) {
+ case Aliased|Solid|RegularDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixel, NoDasher>;
+ break;
+ case Aliased|Solid|FastDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixelARGB32Opaque, NoDasher>;
+ break;
+ case Aliased|Dashed|RegularDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixel, Dasher>;
+ break;
+ case Aliased|Dashed|FastDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLine)<drawPixelARGB32Opaque, Dasher>;
+ break;
+ case AntiAliased|Solid|RegularDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixel, NoDasher>;
+ break;
+ case AntiAliased|Solid|FastDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixelARGB32, NoDasher>;
+ break;
+ case AntiAliased|Dashed|RegularDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixel, Dasher>;
+ break;
+ case AntiAliased|Dashed|FastDraw:
+ stroke = &QT_PREPEND_NAMESPACE(drawLineAA)<drawPixelARGB32, Dasher>;
+ break;
+ default:
+ Q_ASSERT(false);
+ stroke = 0;
+ }
+ return stroke;
+}
+
+void QCosmeticStroker::setup()
+{
+ blend = state->penData.blend;
+ if (state->clip && state->clip->enabled && state->clip->hasRectClip && !state->clip->clipRect.isEmpty()) {
+ clip &= state->clip->clipRect;
+ blend = state->penData.unclipped_blend;
+ }
+
+ int strokeSelection = 0;
+ if (blend == state->penData.unclipped_blend
+ && state->penData.type == QSpanData::Solid
+ && (state->penData.rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
+ || state->penData.rasterBuffer->format == QImage::Format_RGB32)
+ && state->compositionMode() == QPainter::CompositionMode_SourceOver)
+ strokeSelection |= FastDraw;
+
+ if (state->renderHints & QPainter::Antialiasing)
+ strokeSelection |= AntiAliased;
+
+ const QVector<qreal> &penPattern = state->lastPen.dashPattern();
+ if (penPattern.isEmpty()) {
+ Q_ASSERT(!pattern && !reversePattern);
+ pattern = 0;
+ reversePattern = 0;
+ patternLength = 0;
+ patternSize = 0;
+ } else {
+ pattern = (int *)malloc(penPattern.size()*sizeof(int));
+ reversePattern = (int *)malloc(penPattern.size()*sizeof(int));
+ patternSize = penPattern.size();
+
+ patternLength = 0;
+ for (int i = 0; i < patternSize; ++i) {
+ patternLength += (int) qMax(1. , penPattern.at(i)*64.);
+ pattern[i] = patternLength;
+ }
+ patternLength = 0;
+ for (int i = 0; i < patternSize; ++i) {
+ patternLength += (int) qMax(1., penPattern.at(patternSize - 1 - i)*64.);
+ reversePattern[i] = patternLength;
+ }
+ strokeSelection |= Dashed;
+// qDebug() << "setup: size=" << patternSize << "length=" << patternLength/64.;
+ }
+
+ stroke = strokeLine(strokeSelection);
+
+ qreal width = state->lastPen.widthF();
+ if (width == 0)
+ opacity = 256;
+ else if (state->lastPen.isCosmetic())
+ opacity = (int) 256*width;
+ else
+ opacity = (int) 256*width*state->txscale;
+ opacity = qBound(0, opacity, 256);
+
+ drawCaps = state->lastPen.capStyle() != Qt::FlatCap;
+
+ if (strokeSelection & FastDraw) {
+ color = INTERPOLATE_PIXEL_256(state->penData.solid.color, opacity, 0, 0);
+ QRasterBuffer *buffer = state->penData.rasterBuffer;
+ pixels = (uint *)buffer->buffer();
+ ppl = buffer->bytesPerLine()>>2;
+ }
+
+ // setup FP clip bounds
+ xmin = clip.left() - 1;
+ xmax = clip.right() + 2;
+ ymin = clip.top() - 1;
+ ymax = clip.bottom() + 2;
+
+ lastPixel.x = -1;
+}
+
+// returns true if the whole line gets clipped away
+bool QCosmeticStroker::clipLine(qreal &x1, qreal &y1, qreal &x2, qreal &y2)
+{
+ // basic/rough clipping is done in floating point coordinates to avoid
+ // integer overflow problems.
+ if (x1 < xmin) {
+ if (x2 <= xmin)
+ goto clipped;
+ y1 += (y2 - y1)/(x2 - x1) * (xmin - x1);
+ x1 = xmin;
+ } else if (x1 > xmax) {
+ if (x2 >= xmax)
+ goto clipped;
+ y1 += (y2 - y1)/(x2 - x1) * (xmax - x1);
+ x1 = xmax;
+ }
+ if (x2 < xmin) {
+ lastPixel.x = -1;
+ y2 += (y2 - y1)/(x2 - x1) * (xmin - x2);
+ x2 = xmin;
+ } else if (x2 > xmax) {
+ lastPixel.x = -1;
+ y2 += (y2 - y1)/(x2 - x1) * (xmax - x2);
+ x2 = xmax;
+ }
+
+ if (y1 < ymin) {
+ if (y2 <= ymin)
+ goto clipped;
+ x1 += (x2 - x1)/(y2 - y1) * (ymin - y1);
+ y1 = ymin;
+ } else if (y1 > ymax) {
+ if (y2 >= ymax)
+ goto clipped;
+ x1 += (x2 - x1)/(y2 - y1) * (ymax - y1);
+ y1 = ymax;
+ }
+ if (y2 < ymin) {
+ lastPixel.x = -1;
+ x2 += (x2 - x1)/(y2 - y1) * (ymin - y2);
+ y2 = ymin;
+ } else if (y2 > ymax) {
+ lastPixel.x = -1;
+ x2 += (x2 - x1)/(y2 - y1) * (ymax - y2);
+ y2 = ymax;
+ }
+
+ return false;
+
+ clipped:
+ lastPixel.x = -1;
+ return true;
+}
+
+
+void QCosmeticStroker::drawLine(const QPointF &p1, const QPointF &p2)
+{
+ QPointF start = p1 * state->matrix;
+ QPointF end = p2 * state->matrix;
+
+ patternOffset = state->lastPen.dashOffset()*64;
+ lastPixel.x = -1;
+
+ stroke(this, start.x(), start.y(), end.x(), end.y(), drawCaps ? CapBegin|CapEnd : 0);
+
+ blend(current_span, spans, &state->penData);
+ current_span = 0;
+}
+
+void QCosmeticStroker::drawPoints(const QPoint *points, int num)
+{
+ const QPoint *end = points + num;
+ while (points < end) {
+ QPointF p = QPointF(*points) * state->matrix;
+ drawPixel(this, qRound(p.x()), qRound(p.y()), 255);
+ ++points;
+ }
+
+ blend(current_span, spans, &state->penData);
+ current_span = 0;
+}
+
+void QCosmeticStroker::drawPoints(const QPointF *points, int num)
+{
+ const QPointF *end = points + num;
+ while (points < end) {
+ QPointF p = (*points) * state->matrix;
+ drawPixel(this, qRound(p.x()), qRound(p.y()), 255);
+ ++points;
+ }
+
+ blend(current_span, spans, &state->penData);
+ current_span = 0;
+}
+
+void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal ry2)
+{
+ // this is basically the same code as used in the aliased stroke method,
+ // but it only determines the direction and last point of a line
+ //
+ // This is being used to have proper dropout control for closed contours
+ // by calculating the direction and last pixel of the last segment in the contour.
+ // the info is then used to perform dropout control when drawing the first line segment
+ // of the contour
+ lastPixel.x = -1;
+ lastPixel.y = -1;
+
+ if (clipLine(rx1, ry1, rx2, ry2))
+ return;
+
+ const int half = 32;
+ int x1 = toF26Dot6(rx1) + half;
+ int y1 = toF26Dot6(ry1) + half;
+ int x2 = toF26Dot6(rx2) + half;
+ int y2 = toF26Dot6(ry2) + half;
+
+ int dx = qAbs(x2 - x1);
+ int dy = qAbs(y2 - y1);
+
+ if (dx < dy) {
+ // vertical
+ bool swapped = false;
+ if (y1 > y2) {
+ swapped = true;
+ qSwap(y1, y2);
+ qSwap(x1, x2);
+ --x1; --x2; --y1; --y2;
+ }
+ int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
+ int x = x1 << 10;
+
+ int y = (y1+32) >> 6;
+ int ys = (y2+32) >> 6;
+
+ if (y != ys) {
+ x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
+
+ if (swapped) {
+ lastPixel.x = x >> 16;
+ lastPixel.y = y;
+ lastDir = QCosmeticStroker::BottomToTop;
+ } else {
+ lastPixel.x = (x + (ys - y - 1)*xinc) >> 16;
+ lastPixel.y = ys - 1;
+ lastDir = QCosmeticStroker::TopToBottom;
+ }
+ lastAxisAligned = qAbs(xinc) < (1 << 14);
+ }
+ } else {
+ // horizontal
+ if (!dx)
+ return;
+
+ bool swapped = false;
+ if (x1 > x2) {
+ swapped = true;
+ qSwap(x1, x2);
+ qSwap(y1, y2);
+ --x1; --x2; --y1; --y2;
+ }
+ int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
+ int y = y1 << 10;
+
+ int x = (x1+32) >> 6;
+ int xs = (x2+32) >> 6;
+
+ if (x != xs) {
+ y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
+
+ if (swapped) {
+ lastPixel.x = x;
+ lastPixel.y = y >> 16;
+ lastDir = QCosmeticStroker::RightToLeft;
+ } else {
+ lastPixel.x = xs - 1;
+ lastPixel.y = (y + (xs - x - 1)*yinc) >> 16;
+ lastDir = QCosmeticStroker::LeftToRight;
+ }
+ lastAxisAligned = qAbs(yinc) < (1 << 14);
+ }
+ }
+// qDebug() << " moveTo: setting last pixel to x/y dir" << lastPixel.x << lastPixel.y << lastDir;
+}
+
+static inline const QPainterPath::ElementType *subPath(const QPainterPath::ElementType *t, const QPainterPath::ElementType *end,
+ const qreal *points, bool *closed)
+{
+ const QPainterPath::ElementType *start = t;
+ ++t;
+
+ // find out if the subpath is closed
+ while (t < end) {
+ if (*t == QPainterPath::MoveToElement)
+ break;
+ ++t;
+ }
+
+ int offset = t - start - 1;
+// qDebug() << "subpath" << offset << points[0] << points[1] << points[2*offset] << points[2*offset+1];
+ *closed = (points[0] == points[2*offset] && points[1] == points[2*offset + 1]);
+
+ return t;
+}
+
+void QCosmeticStroker::drawPath(const QVectorPath &path)
+{
+// qDebug() << ">>>> drawpath" << path.convertToPainterPath()
+// << "antialiasing:" << (bool)(state->renderHints & QPainter::Antialiasing) << " implicit close:" << path.hasImplicitClose();
+ if (path.isEmpty())
+ return;
+
+ const qreal *points = path.points();
+ const QPainterPath::ElementType *type = path.elements();
+
+ if (type) {
+ const QPainterPath::ElementType *end = type + path.elementCount();
+
+ while (type < end) {
+ Q_ASSERT(type == path.elements() || *type == QPainterPath::MoveToElement);
+
+ QPointF p = QPointF(points[0], points[1]) * state->matrix;
+ QPointF movedTo = p;
+ patternOffset = state->lastPen.dashOffset()*64;
+ lastPixel.x = -1;
+
+ bool closed;
+ const QPainterPath::ElementType *e = subPath(type, end, points, &closed);
+ if (closed) {
+ const qreal *p = points + 2*(e-type);
+ QPointF p1 = QPointF(p[-4], p[-3]) * state->matrix;
+ QPointF p2 = QPointF(p[-2], p[-1]) * state->matrix;
+ calculateLastPoint(p1.x(), p1.y(), p2.x(), p2.y());
+ }
+ int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
+// qDebug() << "closed =" << closed << capString(caps);
+
+ points += 2;
+ ++type;
+
+ while (type < e) {
+ QPointF p2 = QPointF(points[0], points[1]) * state->matrix;
+ switch (*type) {
+ case QPainterPath::MoveToElement:
+ Q_ASSERT(!"Logic error");
+ break;
+
+ case QPainterPath::LineToElement:
+ if (!closed && drawCaps && type == e - 1)
+ caps |= CapEnd;
+ stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
+ p = p2;
+ points += 2;
+ ++type;
+ break;
+
+ case QPainterPath::CurveToElement: {
+ if (!closed && drawCaps && type == e - 3)
+ caps |= CapEnd;
+ QPointF p3 = QPointF(points[2], points[3]) * state->matrix;
+ QPointF p4 = QPointF(points[4], points[5]) * state->matrix;
+ renderCubic(p, p2, p3, p4, caps);
+ p = p4;
+ type += 3;
+ points += 6;
+ break;
+ }
+ case QPainterPath::CurveToDataElement:
+ Q_ASSERT(!"QPainterPath::toSubpathPolygons(), bad element type");
+ break;
+ }
+ caps = NoCaps;
+ }
+ }
+ } else { // !type, simple polygon
+ QPointF p = QPointF(points[0], points[1]) * state->matrix;
+ QPointF movedTo = p;
+ patternOffset = state->lastPen.dashOffset()*64;
+ lastPixel.x = -1;
+
+ const qreal *end = points + 2*path.elementCount();
+ // handle closed path case
+ bool closed = path.hasImplicitClose() || (points[0] == end[-2] && points[1] == end[-1]);
+ int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
+ if (closed) {
+ QPointF p2 = QPointF(end[-2], end[-1]) * state->matrix;
+ calculateLastPoint(p2.x(), p2.y(), p.x(), p.y());
+ }
+
+ points += 2;
+ while (points < end) {
+ QPointF p2 = QPointF(points[0], points[1]) * state->matrix;
+
+ if (!closed && drawCaps && points == end - 2)
+ caps |= CapEnd;
+
+ stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
+
+ p = p2;
+ points += 2;
+ caps = NoCaps;
+ }
+ if (path.hasImplicitClose())
+ stroke(this, p.x(), p.y(), movedTo.x(), movedTo.y(), NoCaps);
+ }
+
+
+ blend(current_span, spans, &state->penData);
+ current_span = 0;
+}
+
+void QCosmeticStroker::renderCubic(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, int caps)
+{
+// qDebug() << ">>>> renderCubic" << p1 << p2 << p3 << p4 << capString(caps);
+ const int maxSubDivisions = 6;
+ PointF points[3*maxSubDivisions + 4];
+
+ points[3].x = p1.x();
+ points[3].y = p1.y();
+ points[2].x = p2.x();
+ points[2].y = p2.y();
+ points[1].x = p3.x();
+ points[1].y = p3.y();
+ points[0].x = p4.x();
+ points[0].y = p4.y();
+
+ PointF *p = points;
+ int level = maxSubDivisions;
+
+ renderCubicSubdivision(p, level, caps);
+}
+
+static void splitCubic(QCosmeticStroker::PointF *points)
+{
+ const qreal half = .5;
+ qreal a, b, c, d;
+
+ points[6].x = points[3].x;
+ c = points[1].x;
+ d = points[2].x;
+ points[1].x = a = ( points[0].x + c ) * half;
+ points[5].x = b = ( points[3].x + d ) * half;
+ c = ( c + d ) * half;
+ points[2].x = a = ( a + c ) * half;
+ points[4].x = b = ( b + c ) * half;
+ points[3].x = ( a + b ) * half;
+
+ points[6].y = points[3].y;
+ c = points[1].y;
+ d = points[2].y;
+ points[1].y = a = ( points[0].y + c ) * half;
+ points[5].y = b = ( points[3].y + d ) * half;
+ c = ( c + d ) * half;
+ points[2].y = a = ( a + c ) * half;
+ points[4].y = b = ( b + c ) * half;
+ points[3].y = ( a + b ) * half;
+}
+
+void QCosmeticStroker::renderCubicSubdivision(QCosmeticStroker::PointF *points, int level, int caps)
+{
+ if (level) {
+ qreal dx = points[3].x - points[0].x;
+ qreal dy = points[3].y - points[0].y;
+ qreal len = ((qreal).25) * (qAbs(dx) + qAbs(dy));
+
+ if (qAbs(dx * (points[0].y - points[2].y) - dy * (points[0].x - points[2].x)) >= len ||
+ qAbs(dx * (points[0].y - points[1].y) - dy * (points[0].x - points[1].x)) >= len) {
+ splitCubic(points);
+
+ --level;
+ renderCubicSubdivision(points + 3, level, caps & CapBegin);
+ renderCubicSubdivision(points, level, caps & CapEnd);
+ return;
+ }
+ }
+
+ stroke(this, points[3].x, points[3].y, points[0].x, points[0].y, caps);
+}
+
+static inline int swapCaps(int caps)
+{
+ return ((caps & QCosmeticStroker::CapBegin) << 1) |
+ ((caps & QCosmeticStroker::CapEnd) >> 1);
+}
+
+// adjust line by half a pixel
+static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc)
+{
+ if (caps & QCosmeticStroker::CapBegin) {
+ x1 -= 32;
+ y -= yinc >> 1;
+ }
+ if (caps & QCosmeticStroker::CapEnd) {
+ x2 += 32;
+ }
+}
+
+/*
+ The hard part about this is dropout control and avoiding douple drawing of points when
+ the drawing shifts from horizontal to vertical or back.
+ */
+template<DrawPixel drawPixel, class Dasher>
+static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
+{
+ if (stroker->clipLine(rx1, ry1, rx2, ry2))
+ return;
+
+ static const int half = 32;
+ int x1 = toF26Dot6(rx1) + half;
+ int y1 = toF26Dot6(ry1) + half;
+ int x2 = toF26Dot6(rx2) + half;
+ int y2 = toF26Dot6(ry2) + half;
+
+ int dx = qAbs(x2 - x1);
+ int dy = qAbs(y2 - y1);
+
+ QCosmeticStroker::Point last = stroker->lastPixel;
+
+// qDebug() << "stroke" << x1/64. << y1/64. << x2/64. << y2/64. << capString(caps);
+
+ if (dx < dy) {
+ // vertical
+
+ bool swapped = false;
+ if (y1 > y2) {
+ swapped = true;
+ qSwap(y1, y2);
+ qSwap(x1, x2);
+ caps = swapCaps(caps);
+ --x1; --x2; --y1; --y2;
+ }
+ int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
+ int x = x1 << 10;
+
+ capAdjust(caps, y1, y2, x, xinc);
+
+ int y = (y1+32) >> 6;
+ int ys = (y2+32) >> 6;
+
+ if (y != ys) {
+ x += ( ((((y << 6) + 32 - y1))) * xinc ) >> 6;
+
+ // calculate first and last pixel and perform dropout control
+ QCosmeticStroker::Direction dir = QCosmeticStroker::TopToBottom;
+ QCosmeticStroker::Point first;
+ first.x = x >> 16;
+ first.y = y;
+ last.x = (x + (ys - y - 1)*xinc) >> 16;
+ last.y = ys - 1;
+ if (swapped) {
+ qSwap(first, last);
+ dir = QCosmeticStroker::BottomToTop;
+ }
+ bool axisAligned = qAbs(xinc) < (1 << 14);
+ if (stroker->lastPixel.x >= 0) {
+ if (first.x == stroker->lastPixel.x &&
+ first.y == stroker->lastPixel.y) {
+ // remove duplicated pixel
+ if (swapped) {
+ --ys;
+ } else {
+ ++y;
+ x += xinc;
+ }
+ } else if (stroker->lastDir != dir &&
+ (((axisAligned && stroker->lastAxisAligned) &&
+ stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) ||
+ (qAbs(stroker->lastPixel.x - first.x) > 1 &&
+ qAbs(stroker->lastPixel.y - first.y) > 1))) {
+ // have a missing pixel, insert it
+ if (swapped) {
+ ++ys;
+ } else {
+ --y;
+ x -= xinc;
+ }
+ }
+ }
+ stroker->lastDir = dir;
+ stroker->lastAxisAligned = axisAligned;
+
+ Dasher dasher(stroker, swapped, y << 6, ys << 6);
+
+ do {
+ if (dasher.on())
+ drawPixel(stroker, x >> 16, y, 255);
+ dasher.adjust();
+ x += xinc;
+ } while (++y < ys);
+ }
+ } else {
+ // horizontal
+ if (!dx)
+ return;
+
+ bool swapped = false;
+ if (x1 > x2) {
+ swapped = true;
+ qSwap(x1, x2);
+ qSwap(y1, y2);
+ caps = swapCaps(caps);
+ --x1; --x2; --y1; --y2;
+ }
+ int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
+ int y = y1 << 10;
+
+ capAdjust(caps, x1, x2, y, yinc);
+
+ int x = (x1+32) >> 6;
+ int xs = (x2+32) >> 6;
+
+
+ if (x != xs) {
+ y += ( ((((x << 6) + 32 - x1))) * yinc ) >> 6;
+
+ // calculate first and last pixel to perform dropout control
+ QCosmeticStroker::Direction dir = QCosmeticStroker::LeftToRight;
+ QCosmeticStroker::Point first;
+ first.x = x;
+ first.y = y >> 16;
+ last.x = xs - 1;
+ last.y = (y + (xs - x - 1)*yinc) >> 16;
+ if (swapped) {
+ qSwap(first, last);
+ dir = QCosmeticStroker::RightToLeft;
+ }
+ bool axisAligned = qAbs(yinc) < (1 << 14);
+ if (stroker->lastPixel.x >= 0) {
+ if (first.x == stroker->lastPixel.x && first.y == stroker->lastPixel.y) {
+ // remove duplicated pixel
+ if (swapped) {
+ --xs;
+ } else {
+ ++x;
+ y += yinc;
+ }
+ } else if (stroker->lastDir != dir &&
+ (((axisAligned && stroker->lastAxisAligned) &&
+ stroker->lastPixel.x != first.x && stroker->lastPixel.y != first.y) ||
+ (qAbs(stroker->lastPixel.x - first.x) > 1 &&
+ qAbs(stroker->lastPixel.y - first.y) > 1))) {
+ // have a missing pixel, insert it
+ if (swapped) {
+ ++xs;
+ } else {
+ --x;
+ y -= yinc;
+ }
+ }
+ }
+ stroker->lastDir = dir;
+ stroker->lastAxisAligned = axisAligned;
+
+ Dasher dasher(stroker, swapped, x << 6, xs << 6);
+
+ do {
+ if (dasher.on())
+ drawPixel(stroker, x, y >> 16, 255);
+ dasher.adjust();
+ y += yinc;
+ } while (++x < xs);
+ }
+ }
+ stroker->lastPixel = last;
+}
+
+
+template<DrawPixel drawPixel, class Dasher>
+static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
+{
+ if (stroker->clipLine(rx1, ry1, rx2, ry2))
+ return;
+
+ int x1 = toF26Dot6(rx1);
+ int y1 = toF26Dot6(ry1);
+ int x2 = toF26Dot6(rx2);
+ int y2 = toF26Dot6(ry2);
+
+ int dx = x2 - x1;
+ int dy = y2 - y1;
+
+ if (qAbs(dx) < qAbs(dy)) {
+ // vertical
+
+ int xinc = F16Dot16FixedDiv(dx, dy);
+
+ bool swapped = false;
+ if (y1 > y2) {
+ qSwap(y1, y2);
+ qSwap(x1, x2);
+ swapped = true;
+ caps = swapCaps(caps);
+ }
+
+ int x = (x1 - 32) << 10;
+ x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
+
+ capAdjust(caps, y1, y2, x, xinc);
+
+ Dasher dasher(stroker, swapped, y1, y2);
+
+ int y = y1 >> 6;
+ int ys = y2 >> 6;
+
+ int alphaStart, alphaEnd;
+ if (y == ys) {
+ alphaStart = y2 - y1;
+ Q_ASSERT(alphaStart >= 0 && alphaStart < 64);
+ alphaEnd = 0;
+ } else {
+ alphaStart = 64 - (y1 & 63);
+ alphaEnd = (y2 & 63);
+ }
+// qDebug() << "vertical" << x1/64. << y1/64. << x2/64. << y2/64.;
+// qDebug() << " x=" << x << "dx=" << dx << "xi=" << (x>>16) << "xsi=" << ((x+(ys-y)*dx)>>16) << "y=" << y << "ys=" << ys;
+
+ // draw first pixel
+ if (dasher.on()) {
+ uint alpha = (quint8)(x >> 8);
+ drawPixel(stroker, x>>16, y, (255-alpha) * alphaStart >> 6);
+ drawPixel(stroker, (x>>16) + 1, y, alpha * alphaStart >> 6);
+ }
+ dasher.adjust();
+ x += xinc;
+ ++y;
+ if (y < ys) {
+ do {
+ if (dasher.on()) {
+ uint alpha = (quint8)(x >> 8);
+ drawPixel(stroker, x>>16, y, (255-alpha));
+ drawPixel(stroker, (x>>16) + 1, y, alpha);
+ }
+ dasher.adjust();
+ x += xinc;
+ } while (++y < ys);
+ }
+ // draw last pixel
+ if (alphaEnd && dasher.on()) {
+ uint alpha = (quint8)(x >> 8);
+ drawPixel(stroker, x>>16, y, (255-alpha) * alphaEnd >> 6);
+ drawPixel(stroker, (x>>16) + 1, y, alpha * alphaEnd >> 6);
+ }
+ } else {
+ // horizontal
+ if (!dx)
+ return;
+
+ int yinc = F16Dot16FixedDiv(dy, dx);
+
+ bool swapped = false;
+ if (x1 > x2) {
+ qSwap(x1, x2);
+ qSwap(y1, y2);
+ swapped = true;
+ caps = swapCaps(caps);
+ }
+
+ int y = (y1 - 32) << 10;
+ y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
+
+ capAdjust(caps, x1, x2, y, yinc);
+
+ Dasher dasher(stroker, swapped, x1, x2);
+
+ int x = x1 >> 6;
+ int xs = x2 >> 6;
+
+// qDebug() << "horizontal" << x1/64. << y1/64. << x2/64. << y2/64.;
+// qDebug() << " y=" << y << "dy=" << dy << "x=" << x << "xs=" << xs << "yi=" << (y>>16) << "ysi=" << ((y+(xs-x)*dy)>>16);
+ int alphaStart, alphaEnd;
+ if (x == xs) {
+ alphaStart = x2 - x1;
+ Q_ASSERT(alphaStart >= 0 && alphaStart < 64);
+ alphaEnd = 0;
+ } else {
+ alphaStart = 64 - (x1 & 63);
+ alphaEnd = (x2 & 63);
+ }
+
+ // draw first pixel
+ if (dasher.on()) {
+ uint alpha = (quint8)(y >> 8);
+ drawPixel(stroker, x, y>>16, (255-alpha) * alphaStart >> 6);
+ drawPixel(stroker, x, (y>>16) + 1, alpha * alphaStart >> 6);
+ }
+ dasher.adjust();
+ y += yinc;
+ ++x;
+ // draw line
+ if (x < xs) {
+ do {
+ if (dasher.on()) {
+ uint alpha = (quint8)(y >> 8);
+ drawPixel(stroker, x, y>>16, (255-alpha));
+ drawPixel(stroker, x, (y>>16) + 1, alpha);
+ }
+ dasher.adjust();
+ y += yinc;
+ } while (++x < xs);
+ }
+ // draw last pixel
+ if (alphaEnd && dasher.on()) {
+ uint alpha = (quint8)(y >> 8);
+ drawPixel(stroker, x, y>>16, (255-alpha) * alphaEnd >> 6);
+ drawPixel(stroker, x, (y>>16) + 1, alpha * alphaEnd >> 6);
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
new file mode 100644
index 0000000..0aa71fc
--- /dev/null
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** 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 QCOSMETICSTROKER_P_H
+#define QCOSMETICSTROKER_P_H
+
+#include <private/qdrawhelper_p.h>
+#include <private/qvectorpath_p.h>
+#include <private/qpaintengine_raster_p.h>
+#include <qpen.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QCosmeticStroker;
+
+
+typedef void (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+
+class QCosmeticStroker
+{
+public:
+ struct Point {
+ int x;
+ int y;
+ };
+ struct PointF {
+ qreal x;
+ qreal y;
+ };
+
+ enum Caps {
+ NoCaps = 0,
+ CapBegin = 0x1,
+ CapEnd = 0x2,
+ };
+
+ // used to avoid drop outs or duplicated points
+ enum Direction {
+ TopToBottom,
+ BottomToTop,
+ LeftToRight,
+ RightToLeft
+ };
+
+ QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr)
+ : state(s),
+ clip(dr),
+ pattern(0),
+ reversePattern(0),
+ patternSize(0),
+ patternLength(0),
+ patternOffset(0),
+ current_span(0),
+ lastDir(LeftToRight),
+ lastAxisAligned(false)
+ { setup(); }
+ ~QCosmeticStroker() { free(pattern); free(reversePattern); }
+ void drawLine(const QPointF &p1, const QPointF &p2);
+ void drawPath(const QVectorPath &path);
+ void drawPoints(const QPoint *points, int num);
+ void drawPoints(const QPointF *points, int num);
+
+
+ QRasterPaintEngineState *state;
+ QRect clip;
+ // clip bounds in real
+ qreal xmin, xmax;
+ qreal ymin, ymax;
+
+ StrokeLine stroke;
+ bool drawCaps;
+
+ int *pattern;
+ int *reversePattern;
+ int patternSize;
+ int patternLength;
+ int patternOffset;
+
+ enum { NSPANS = 255 };
+ QT_FT_Span spans[NSPANS];
+ int current_span;
+ ProcessSpans blend;
+
+ int opacity;
+
+ uint color;
+ uint *pixels;
+ int ppl;
+
+ Direction lastDir;
+ Point lastPixel;
+ bool lastAxisAligned;
+
+private:
+ void setup();
+
+ void renderCubic(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4, int caps);
+ void renderCubicSubdivision(PointF *points, int level, int caps);
+ // used for closed subpaths
+ void calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal ry2);
+
+public:
+ bool clipLine(qreal &x1, qreal &y1, qreal &x2, qreal &y2);
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QCOSMETICLINE_H
diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp
index b53353b..4469704 100644
--- a/src/gui/painting/qgraphicssystemex_symbian.cpp
+++ b/src/gui/painting/qgraphicssystemex_symbian.cpp
@@ -44,10 +44,39 @@
#include "private/qbackingstore_p.h"
#include "private/qapplication_p.h"
-#include <QDebug>
+#include <e32property.h>
QT_BEGIN_NAMESPACE
+static bool bcm2727Initialized = false;
+static bool bcm2727 = false;
+
+bool QSymbianGraphicsSystemEx::hasBCM2727()
+{
+ if (bcm2727Initialized)
+ return bcm2727;
+
+ const TUid KIvePropertyCat = {0x2726beef};
+ enum TIvePropertyChipType {
+ EVCBCM2727B1 = 0x00000000,
+ EVCBCM2763A0 = 0x04000100,
+ EVCBCM2763B0 = 0x04000102,
+ EVCBCM2763C0 = 0x04000103,
+ EVCBCM2763C1 = 0x04000104,
+ EVCBCMUnknown = 0x7fffffff
+ };
+
+ TInt chipType = EVCBCMUnknown;
+ if (RProperty::Get(KIvePropertyCat, 0, chipType) == KErrNone) {
+ if (chipType == EVCBCM2727B1)
+ bcm2727 = true;
+ }
+
+ bcm2727Initialized = true;
+
+ return bcm2727;
+}
+
void QSymbianGraphicsSystemEx::releaseCachedGpuResources()
{
// Do nothing here
@@ -64,11 +93,6 @@ void QSymbianGraphicsSystemEx::releaseAllGpuResources()
}
}
-bool QSymbianGraphicsSystemEx::hasBCM2727()
-{
- return !QApplicationPrivate::instance()->useTranslucentEGLSurfaces;
-}
-
void QSymbianGraphicsSystemEx::forceToRaster(QWidget *window)
{
if (window && window->isWindow()) {
diff --git a/src/gui/painting/qgraphicssystemex_symbian_p.h b/src/gui/painting/qgraphicssystemex_symbian_p.h
index c1d1bdf..1f2a7c6 100644
--- a/src/gui/painting/qgraphicssystemex_symbian_p.h
+++ b/src/gui/painting/qgraphicssystemex_symbian_p.h
@@ -62,9 +62,10 @@ class QWidget;
class Q_GUI_EXPORT QSymbianGraphicsSystemEx : public QGraphicsSystemEx
{
public:
+ static bool hasBCM2727();
+
virtual void releaseCachedGpuResources();
virtual void releaseAllGpuResources();
- virtual bool hasBCM2727();
virtual void forceToRaster(QWidget *window);
};
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp
index 7c17c1b..8b607b2 100644
--- a/src/gui/painting/qoutlinemapper.cpp
+++ b/src/gui/painting/qoutlinemapper.cpp
@@ -47,6 +47,8 @@
QT_BEGIN_NAMESPACE
+static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
+
#define qreal_to_fixed_26_6(f) (int(f * 64))
@@ -214,6 +216,13 @@ void QOutlineMapper::endOutline()
elements = m_elements_dev.data();
}
+ if (m_round_coords) {
+ // round coordinates to match outlines drawn with drawLine_midpoint_i
+ for (int i = 0; i < m_elements.size(); ++i)
+ elements[i] = QPointF(qFloor(elements[i].x() + aliasedCoordinateDelta),
+ qFloor(elements[i].y() + aliasedCoordinateDelta));
+ }
+
controlPointRect = boundingRect(elements, element_count);
#ifdef QT_DEBUG_CONVERT
diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h
index 1432d6f..388858c 100644
--- a/src/gui/painting/qoutlinemapper_p.h
+++ b/src/gui/painting/qoutlinemapper_p.h
@@ -95,7 +95,8 @@ public:
m_tags(0),
m_contours(0),
m_polygon_dev(0),
- m_in_clip_elements(false)
+ m_in_clip_elements(false),
+ m_round_coords(false)
{
}
@@ -201,6 +202,8 @@ public:
QT_FT_Outline *convertPath(const QPainterPath &path);
QT_FT_Outline *convertPath(const QVectorPath &path);
+ void setCoordinateRounding(bool coordinateRounding) { m_round_coords = coordinateRounding; }
+
inline QPainterPath::ElementType *elementTypes() const { return m_element_types.size() == 0 ? 0 : m_element_types.data(); }
public:
@@ -234,6 +237,9 @@ public:
bool m_valid;
bool m_in_clip_elements;
+
+private:
+ bool m_round_coords;
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index 9562d83..c46513a 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -387,6 +387,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw
\value MaxUser Last user type ID
\value OpenGL2
\value PaintBuffer
+ \value Blitter
*/
/*!
diff --git a/src/gui/painting/qpaintengine_mac_p.h b/src/gui/painting/qpaintengine_mac_p.h
index c87501e..2434011 100644
--- a/src/gui/painting/qpaintengine_mac_p.h
+++ b/src/gui/painting/qpaintengine_mac_p.h
@@ -121,6 +121,8 @@ public:
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
{ QPaintEngine::drawPolygon(points, pointCount, mode); }
+ bool supportsTransformations(qreal, const QTransform &) const { return true; };
+
protected:
friend class QMacPrintEngine;
friend class QMacPrintEnginePrivate;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 5ce94f8..30553b5 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -69,6 +69,7 @@
// #include <private/qrasterizer_p.h>
#include <private/qimage_p.h>
#include <private/qstatictext_p.h>
+#include <private/qcosmeticstroker_p.h>
#include "qmemrotate_p.h"
#include "qpaintengine_raster_p.h"
@@ -126,6 +127,9 @@ void dumpClip(int width, int height, const QClipData *clip);
// 4 pixels.
#define int_dim(pos, dim) (int(pos+dim) - int(pos))
+// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
+static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
+
#ifdef Q_WS_WIN
extern bool qt_cleartype_enabled;
#endif
@@ -156,16 +160,6 @@ enum LineDrawMode {
LineDrawIncludeLastPixel
};
-static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans span_func, QSpanData *data,
- LineDrawMode style, const QIntRect &rect);
-static void drawLine_midpoint_dashed_i(int x1, int y1, int x2, int y2,
- QPen *pen, ProcessSpans span_func, QSpanData *data,
- LineDrawMode style, const QIntRect &devRect,
- int *patternOffset);
-// static void drawLine_midpoint_f(qreal x1, qreal y1, qreal x2, qreal y2,
-// ProcessSpans span_func, QSpanData *data,
-// LineDrawMode style, const QRect &devRect);
-
static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip,
ProcessSpans pen_func, ProcessSpans brush_func,
QSpanData *pen_data, QSpanData *brush_data);
@@ -789,14 +783,12 @@ void QRasterPaintEngine::updatePen(const QPen &pen)
s->stroker = 0;
}
+ ensureState(); // needed because of tx_noshear...
s->flags.fast_pen = pen_style > Qt::NoPen
- && s->penData.blend
- && !s->flags.antialiased
- && (penWidth == 0 || (penWidth <= 1
- && (s->matrix.type() <= QTransform::TxTranslate
- || pen.isCosmetic())));
+ && s->penData.blend
+ && ((pen.isCosmetic() && penWidth <= 1)
+ || (s->flags.tx_noshear && penWidth * s->txscale <= 1));
- ensureState(); // needed because of tx_noshear...
s->flags.non_complex_pen = qpen_capStyle(s->lastPen) <= Qt::SquareCap && s->flags.tx_noshear;
s->strokeFlags = 0;
@@ -1513,6 +1505,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
qDebug(" - QRasterPaintEngine::drawRect(), rectCount=%d", rectCount);
#endif
Q_D(QRasterPaintEngine);
+ ensureState();
QRasterPaintEngineState *s = state();
// Fill
@@ -1541,32 +1534,14 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
ensurePen();
if (s->penData.blend) {
- if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) {
- const QRect *r = rects;
- const QRect *lastRect = rects + rectCount;
- while (r < lastRect) {
- int left = r->x();
- int right = r->x() + r->width();
- int top = r->y();
- int bottom = r->y() + r->height();
-
-#ifdef Q_WS_MAC
- int pts[] = { top, left,
- top, right,
- bottom, right,
- bottom, left };
-#else
- int pts[] = { left, top,
- right, top,
- right, bottom,
- left, bottom };
-#endif
-
- strokePolygonCosmetic((QPoint *) pts, 4, WindingMode);
- ++r;
+ QRectVectorPath path;
+ if (s->flags.fast_pen) {
+ QCosmeticStroker stroker(s, d->deviceRect);
+ for (int i = 0; i < rectCount; ++i) {
+ path.set(rects[i]);
+ stroker.drawPath(path);
}
} else {
- QRectVectorPath path;
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
stroke(path, s->pen);
@@ -1581,13 +1556,13 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
{
#ifdef QT_DEBUG_DRAW
- qDebug(" - QRasterPaintEngine::drawRect(), rectCount=%d", rectCount);
+ qDebug(" - QRasterPaintEngine::drawRect(QRectF*), rectCount=%d", rectCount);
#endif
#ifdef QT_FAST_SPANS
Q_D(QRasterPaintEngine);
+ ensureState();
QRasterPaintEngineState *s = state();
- ensureState();
if (s->flags.tx_noshear) {
ensureBrush();
@@ -1605,59 +1580,17 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
ensurePen();
if (s->penData.blend) {
- qreal width = s->pen.isCosmetic()
- ? (s->lastPen.widthF() == 0 ? 1 : s->lastPen.widthF())
- : s->lastPen.widthF() * s->txscale;
-
- if (s->flags.fast_pen && s->lastPen.brush().isOpaque()) {
- for (int i = 0; i < rectCount; ++i) {
- const QRectF &r = rects[i];
- qreal left = r.x();
- qreal right = r.x() + r.width();
- qreal top = r.y();
- qreal bottom = r.y() + r.height();
- qreal pts[] = { left, top,
- right, top,
- right, bottom,
- left, bottom };
- strokePolygonCosmetic((QPointF *) pts, 4, WindingMode);
- }
- } else if (width <= 1 && qpen_style(s->lastPen) == Qt::SolidLine) {
- d->initializeRasterizer(&s->penData);
-
+ QRectVectorPath path;
+ if (s->flags.fast_pen) {
+ QCosmeticStroker stroker(s, d->deviceRect);
for (int i = 0; i < rectCount; ++i) {
- const QRectF &rect = rects[i].normalized();
- if (rect.isEmpty()) {
- qreal pts[] = { rect.left(), rect.top(), rect.right(), rect.bottom() };
- QVectorPath vp(pts, 2, 0, QVectorPath::LinesHint);
- QPaintEngineEx::stroke(vp, s->lastPen);
- } else {
- const QPointF tl = s->matrix.map(rect.topLeft());
- const QPointF tr = s->matrix.map(rect.topRight());
- const QPointF bl = s->matrix.map(rect.bottomLeft());
- const QPointF br = s->matrix.map(rect.bottomRight());
- const qreal w = width / (rect.width() * s->txscale);
- const qreal h = width / (rect.height() * s->txscale);
- d->rasterizer->rasterizeLine(tl, tr, w); // top
- d->rasterizer->rasterizeLine(bl, br, w); // bottom
- d->rasterizer->rasterizeLine(bl, tl, h); // left
- d->rasterizer->rasterizeLine(br, tr, h); // right
- }
+ path.set(rects[i]);
+ stroker.drawPath(path);
}
} else {
for (int i = 0; i < rectCount; ++i) {
- const QRectF &r = rects[i];
- qreal left = r.x();
- qreal right = r.x() + r.width();
- qreal top = r.y();
- qreal bottom = r.y() + r.height();
- qreal pts[] = { left, top,
- right, top,
- right, bottom,
- left, bottom,
- left, top };
- QVectorPath vp(pts, 5, 0, QVectorPath::RectangleHint);
- QPaintEngineEx::stroke(vp, s->lastPen);
+ path.set(rects[i]);
+ QPaintEngineEx::stroke(path, s->lastPen);
}
}
}
@@ -1674,36 +1607,16 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
*/
void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
{
+ Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
+
ensurePen(pen);
if (!s->penData.blend)
return;
- if (s->flags.fast_pen && !path.isCurved()
- && s->lastPen.brush().isOpaque()) {
- int count = path.elementCount();
- QPointF *points = (QPointF *) path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (types) {
- int first = 0;
- int last;
- while (first < count) {
- while (first < count && types[first] != QPainterPath::MoveToElement) ++first;
- last = first + 1;
- while (last < count && types[last] == QPainterPath::LineToElement) ++last;
- strokePolygonCosmetic(points + first, last - first,
- path.hasImplicitClose() && last == count // only close last one..
- ? WindingMode
- : PolylineMode);
- first = last;
- }
- } else {
- strokePolygonCosmetic(points, count,
- path.hasImplicitClose()
- ? WindingMode
- : PolylineMode);
- }
-
+ if (s->flags.fast_pen) {
+ QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
qreal width = s->lastPen.isCosmetic()
? (qpen_widthf(s->lastPen) == 0 ? 1 : qpen_widthf(s->lastPen))
@@ -1760,10 +1673,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
static inline QRect toNormalizedFillRect(const QRectF &rect)
{
- int x1 = qRound(rect.x());
- int y1 = qRound(rect.y());
- int x2 = qRound(rect.right());
- int y2 = qRound(rect.bottom());
+ int x1 = qRound(rect.x() + aliasedCoordinateDelta);
+ int y1 = qRound(rect.y() + aliasedCoordinateDelta);
+ int x2 = qRound(rect.right() + aliasedCoordinateDelta);
+ int y2 = qRound(rect.bottom() + aliasedCoordinateDelta);
if (x2 < x1)
qSwap(x1, x2);
@@ -1818,26 +1731,6 @@ void QRasterPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
}
}
- if (path.shape() == QVectorPath::EllipseHint) {
- if (!s->flags.antialiased && s->matrix.type() <= QTransform::TxScale) {
- const qreal *p = path.points();
- QPointF tl = QPointF(p[0], p[1]) * s->matrix;
- QPointF br = QPointF(p[4], p[5]) * s->matrix;
- QRectF r = s->matrix.mapRect(QRectF(tl, br));
-
- ProcessSpans penBlend = d->getPenFunc(r, &s->penData);
- ProcessSpans brushBlend = d->getBrushFunc(r, &s->brushData);
- const QRect brect = QRect(int(r.x()), int(r.y()),
- int_dim(r.x(), r.width()),
- int_dim(r.y(), r.height()));
- if (brect == r) {
- drawEllipse_midpoint_i(brect, d->deviceRect, penBlend, brushBlend,
- &s->penData, &s->brushData);
- return;
- }
- }
- }
-
// ### Optimize for non transformed ellipses and rectangles...
QRectF cpRect = path.controlPointRect();
const QRect deviceRect = s->matrix.mapRect(cpRect).toRect();
@@ -2032,6 +1925,7 @@ void QRasterPaintEngine::fillPolygon(const QPointF *points, int pointCount, Poly
*/
void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
+ Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
#ifdef QT_DEBUG_DRAW
@@ -2048,20 +1942,23 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
}
ensurePen();
- ensureBrush();
if (mode != PolylineMode) {
// Do the fill...
+ ensureBrush();
if (s->brushData.blend) {
+ d->outlineMapper->setCoordinateRounding(s->penData.blend && s->flags.fast_pen && s->lastPen.brush().isOpaque());
fillPolygon(points, pointCount, mode);
+ d->outlineMapper->setCoordinateRounding(false);
}
}
// Do the outline...
if (s->penData.blend) {
- if (s->flags.fast_pen && s->lastPen.brush().isOpaque())
- strokePolygonCosmetic(points, pointCount, mode);
- else {
- QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
+ QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
+ if (s->flags.fast_pen) {
+ QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.drawPath(vp);
+ } else {
QPaintEngineEx::stroke(vp, s->lastPen);
}
}
@@ -2090,13 +1987,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
return;
}
- ensureState();
ensurePen();
- if (!(s->flags.int_xform && s->flags.fast_pen && (!s->penData.blend || s->pen.brush().isOpaque()))) {
- // this calls the float version
- QPaintEngineEx::drawPolygon(points, pointCount, mode);
- return;
- }
// Do the fill
if (mode != PolylineMode) {
@@ -2104,6 +1995,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
if (s->brushData.blend) {
// Compose polygon fill..,
ensureOutlineMapper();
+ d->outlineMapper->setCoordinateRounding(s->penData.blend != 0);
d->outlineMapper->beginOutline(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);
d->outlineMapper->moveTo(*points);
const QPoint *p = points;
@@ -2117,235 +2009,30 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
ProcessSpans brushBlend = d->getBrushFunc(d->outlineMapper->controlPointRect,
&s->brushData);
d->rasterize(d->outlineMapper->outline(), brushBlend, &s->brushData, d->rasterBuffer.data());
+ d->outlineMapper->setCoordinateRounding(false);
}
}
// Do the outline...
if (s->penData.blend) {
- if (s->flags.fast_pen && s->lastPen.brush().isOpaque())
- strokePolygonCosmetic(points, pointCount, mode);
- else {
- int count = pointCount * 2;
- QVarLengthArray<qreal> fpoints(count);
-#ifdef Q_WS_MAC
- for (int i=0; i<count; i+=2) {
- fpoints[i] = ((int *) points)[i+1];
- fpoints[i+1] = ((int *) points)[i];
- }
-#else
- for (int i=0; i<count; ++i)
- fpoints[i] = ((int *) points)[i];
-#endif
- QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
- QPaintEngineEx::stroke(vp, s->lastPen);
+ int count = pointCount * 2;
+ QVarLengthArray<qreal> fpoints(count);
+ #ifdef Q_WS_MAC
+ for (int i=0; i<count; i+=2) {
+ fpoints[i] = ((int *) points)[i+1];
+ fpoints[i+1] = ((int *) points)[i];
}
- }
-}
-
-/*!
- \internal
-*/
-void QRasterPaintEngine::strokePolygonCosmetic(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- Q_ASSERT(s->penData.blend);
- Q_ASSERT(s->flags.fast_pen);
-
- bool needs_closing = mode != PolylineMode && points[0] != points[pointCount-1];
-
- // Use fast path for 0 width / trivial pens.
- QIntRect devRect;
- devRect.set(d->deviceRect);
-
- LineDrawMode mode_for_last = (s->lastPen.capStyle() != Qt::FlatCap
- ? LineDrawIncludeLastPixel
- : LineDrawNormal);
- int dashOffset = int(s->lastPen.dashOffset());
-
- // Draw all the line segments.
- for (int i=1; i<pointCount; ++i) {
-
- QPointF lp1 = points[i-1] * s->matrix;
- QPointF lp2 = points[i] * s->matrix;
-
- const QRectF brect(lp1, lp2);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine) {
- drawLine_midpoint_i(qFloor(lp1.x()), qFloor(lp1.y()),
- qFloor(lp2.x()), qFloor(lp2.y()),
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect);
+ #else
+ for (int i=0; i<count; ++i)
+ fpoints[i] = ((int *) points)[i];
+ #endif
+ QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
+
+ if (s->flags.fast_pen) {
+ QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.drawPath(vp);
} else {
- drawLine_midpoint_dashed_i(qFloor(lp1.x()), qFloor(lp1.y()),
- qFloor(lp2.x()), qFloor(lp2.y()),
- &s->lastPen,
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect, &dashOffset);
- }
- }
-
- // Polygons are implicitly closed.
- if (needs_closing) {
- QPointF lp1 = points[pointCount-1] * s->matrix;
- QPointF lp2 = points[0] * s->matrix;
-
- const QRectF brect(lp1, lp2);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine) {
- drawLine_midpoint_i(qFloor(lp1.x()), qFloor(lp1.y()),
- qFloor(lp2.x()), qFloor(lp2.y()),
- penBlend, &s->penData,
- LineDrawIncludeLastPixel,
- devRect);
- } else {
- drawLine_midpoint_dashed_i(qFloor(lp1.x()), qFloor(lp1.y()),
- qFloor(lp2.x()), qFloor(lp2.y()),
- &s->lastPen,
- penBlend, &s->penData,
- LineDrawIncludeLastPixel,
- devRect, &dashOffset);
- }
- }
-
-}
-
-/*!
- \internal
-*/
-void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QRasterPaintEngine);
- QRasterPaintEngineState *s = state();
-
- // We assert here because this function is called from drawRects
- // and drawPolygon and they already do ensurePen(), so we skip that
- // here to avoid duplicate checks..
- Q_ASSERT(s->penData.blend);
-
- bool needs_closing = mode != PolylineMode && points[0] != points[pointCount-1];
-
- QIntRect devRect;
- devRect.set(d->deviceRect);
-
- LineDrawMode mode_for_last = (s->lastPen.capStyle() != Qt::FlatCap
- ? LineDrawIncludeLastPixel
- : LineDrawNormal);
-
- int m11 = int(s->matrix.m11());
- int m22 = int(s->matrix.m22());
- int dx = int(s->matrix.dx());
- int dy = int(s->matrix.dy());
- int m13 = int(s->matrix.m13());
- int m23 = int(s->matrix.m23());
- bool affine = !m13 && !m23;
-
- int dashOffset = int(s->lastPen.dashOffset());
-
- if (affine) {
- // Draw all the line segments.
- for (int i=1; i<pointCount; ++i) {
- const QPoint lp1 = points[i-1] * s->matrix;
- const QPoint lp2 = points[i] * s->matrix;
- const QRect brect(lp1, lp2);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
-
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(lp1.x(), lp1.y(),
- lp2.x(), lp2.y(),
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect);
- else
- drawLine_midpoint_dashed_i(lp1.x(), lp1.y(),
- lp2.x(), lp2.y(),
- &s->lastPen,
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect, &dashOffset);
-
- }
-
- // Polygons are implicitly closed.
- if (needs_closing) {
- const QPoint lp1 = points[pointCount - 1] * s->matrix;
- const QPoint lp2 = points[0] * s->matrix;
- const QRect brect(lp1, lp2);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
-
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(lp1.x(), lp1.y(),
- lp2.x(), lp2.y(),
- penBlend, &s->penData, LineDrawIncludeLastPixel,
- devRect);
- else
- drawLine_midpoint_dashed_i(lp1.x(), lp1.y(),
- lp2.x(), lp2.y(),
- &s->lastPen,
- penBlend, &s->penData, LineDrawIncludeLastPixel,
- devRect, &dashOffset);
- }
- } else {
- // Draw all the line segments.
- for (int i=1; i<pointCount; ++i) {
- int x1 = points[i-1].x() * m11 + dx;
- int y1 = points[i-1].y() * m22 + dy;
- qreal w = m13*points[i-1].x() + m23*points[i-1].y() + 1.;
- w = 1/w;
- x1 = int(x1*w);
- y1 = int(y1*w);
- int x2 = points[i].x() * m11 + dx;
- int y2 = points[i].y() * m22 + dy;
- w = m13*points[i].x() + m23*points[i].y() + 1.;
- w = 1/w;
- x2 = int(x2*w);
- y2 = int(y2*w);
-
- const QRect brect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(x1, y1, x2, y2,
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect);
- else
- drawLine_midpoint_dashed_i(x1, y1, x2, y2,
- &s->lastPen,
- penBlend, &s->penData,
- i == pointCount - 1 ? mode_for_last : LineDrawIncludeLastPixel,
- devRect, &dashOffset);
-
- }
-
- int x1 = points[pointCount-1].x() * m11 + dx;
- int y1 = points[pointCount-1].y() * m22 + dy;
- qreal w = m13*points[pointCount-1].x() + m23*points[pointCount-1].y() + 1.;
- w = 1/w;
- x1 = int(x1*w);
- y1 = int(y1*w);
- int x2 = points[0].x() * m11 + dx;
- int y2 = points[0].y() * m22 + dy;
- w = m13*points[0].x() + m23*points[0].y() + 1.;
- w = 1/w;
- x2 = int(x2 * w);
- y2 = int(y2 * w);
- // Polygons are implicitly closed.
-
- if (needs_closing) {
- const QRect brect(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(x1, y1, x2, y2,
- penBlend, &s->penData, LineDrawIncludeLastPixel,
- devRect);
- else
- drawLine_midpoint_dashed_i(x1, y1, x2, y2,
- &s->lastPen,
- penBlend, &s->penData, LineDrawIncludeLastPixel,
- devRect, &dashOffset);
+ QPaintEngineEx::stroke(vp, s->lastPen);
}
}
}
@@ -2579,7 +2266,10 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
int sr_b = qCeil(sr.bottom()) - 1;
if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
+ // as fillRect will apply the aliased coordinate delta we need to
+ // subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
+ s->matrix = s->matrix * QTransform::fromTranslate(-aliasedCoordinateDelta, -aliasedCoordinateDelta);
// Do whatever fillRect() does, but without premultiplying the color if it's already premultiplied.
QRgb color = img.pixel(sr_l, sr_t);
@@ -2723,9 +2413,11 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
d->initializeRasterizer(&d->image_filler_xform);
d->rasterizer->setAntialiased(s->flags.antialiased);
+ const QPointF offs = s->flags.antialiased ? QPointF() : QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
+
const QRectF &rect = r.normalized();
- const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f);
- const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f);
+ const QPointF a = s->matrix.map((rect.topLeft() + rect.bottomLeft()) * 0.5f) - offs;
+ const QPointF b = s->matrix.map((rect.topRight() + rect.bottomRight()) * 0.5f) - offs;
if (s->flags.tx_noshear)
d->rasterizer->rasterizeLine(a, b, rect.height() / rect.width());
@@ -2734,12 +2426,13 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
return;
}
#endif
+ const qreal offs = s->flags.antialiased ? qreal(0) : aliasedCoordinateDelta;
QPainterPath path;
path.addRect(r);
QTransform m = s->matrix;
s->matrix = QTransform(m.m11(), m.m12(), m.m13(),
m.m21(), m.m22(), m.m23(),
- m.m31(), m.m32(), m.m33());
+ m.m31() - offs, m.m32() - offs, m.m33());
fillPath(path, &d->image_filler_xform);
s->matrix = m;
} else {
@@ -3167,7 +2860,15 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
} else
#endif
{
- QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType;
+ QFontEngineGlyphCache::Type glyphType;
+ if (fontEngine->glyphFormat >= 0) {
+ glyphType = QFontEngineGlyphCache::Type(fontEngine->glyphFormat);
+ } else if (s->matrix.type() > QTransform::TxTranslate
+ && d->glyphCacheType == QFontEngineGlyphCache::Raster_RGBMask) {
+ glyphType = QFontEngineGlyphCache::Raster_A8;
+ } else {
+ glyphType = d->glyphCacheType;
+ }
QImageTextureGlyphCache *cache =
static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix));
@@ -3191,6 +2892,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
rightShift = 3; // divide by 8
int margin = cache->glyphMargin();
+ const QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
const uchar *bits = image.bits();
for (int i=0; i<numGlyphs; ++i) {
@@ -3201,7 +2903,7 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
continue;
int x = qFloor(positions[i].x) + c.baseLineX - margin;
- int y = qFloor(positions[i].y) - c.baseLineY - margin;
+ int y = qFloor(positions[i].y + offs) - c.baseLineY - margin;
// printf("drawing [%d %d %d %d] baseline [%d %d], glyph: %d, to: %d %d, pos: %d %d\n",
// c.x, c.y,
@@ -3239,13 +2941,15 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti)
fe->setFontScale(matrix.m11());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
+ const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta);
+
for (int i=0; i<glyphs.size(); ++i) {
TOpenFontCharMetrics tmetrics;
const TUint8 *glyphBitmapBytes;
TSize glyphBitmapSize;
fe->getCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize);
- const int x = qFloor(positions[i].x + tmetrics.HorizBearingX());
- const int y = qFloor(positions[i].y - tmetrics.HorizBearingY());
+ const int x = qFloor(positions[i].x + tmetrics.HorizBearingX() + aliasDelta);
+ const int y = qFloor(positions[i].y - tmetrics.HorizBearingY() + aliasDelta);
alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight);
}
@@ -3346,19 +3050,6 @@ QRasterPaintEnginePrivate::getBrushFunc(const QRectF &rect,
}
inline ProcessSpans
-QRasterPaintEnginePrivate::getPenFunc(const QRect &rect,
- const QSpanData *data) const
-{
- Q_Q(const QRasterPaintEngine);
- const QRasterPaintEngineState *s = q->state();
-
- if (!s->flags.fast_pen && s->matrix.type() > QTransform::TxTranslate)
- return data->blend;
- const int penWidth = s->flags.fast_pen ? 1 : qCeil(s->pen.widthF());
- return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend;
-}
-
-inline ProcessSpans
QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect,
const QSpanData *data) const
{
@@ -3379,8 +3070,13 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
ensurePen();
ensureState();
- drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
- textItem->fontEngine());
+ QFontEngine *fontEngine = textItem->fontEngine();
+ if (!supportsTransformations(fontEngine)) {
+ drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
+ fontEngine);
+ } else {
+ QPaintEngineEx::drawStaticTextItem(textItem);
+ }
}
/*!
@@ -3403,36 +3099,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
#if defined (Q_WS_WIN) || defined(Q_WS_MAC)
- bool drawCached = true;
-
- if (s->matrix.type() >= QTransform::TxProject)
- drawCached = false;
-
- // don't try to cache huge fonts
- const qreal pixelSize = ti.fontEngine->fontDef.pixelSize;
- if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64)
- drawCached = false;
-
- // ### Remove the TestFontEngine and Box engine crap, in these
- // ### cases we should delegate painting to the font engine
- // ### directly...
-
-#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
- QFontEngine::Type fontEngineType = ti.fontEngine->type();
- // qDebug() << "type" << fontEngineType << s->matrix.type();
- if ((fontEngineType == QFontEngine::Win && !((QFontEngineWin *) ti.fontEngine)->ttf && s->matrix.type() > QTransform::TxTranslate)
- || (s->matrix.type() <= QTransform::TxTranslate
- && (fontEngineType == QFontEngine::TestFontEngine
- || fontEngineType == QFontEngine::Box))) {
- drawCached = false;
- }
-#else
- if (s->matrix.type() > QTransform::TxTranslate)
- drawCached = false;
-#endif
- if (drawCached) {
- QRasterPaintEngineState *s = state();
-
+ if (!supportsTransformations(ti.fontEngine)) {
QVarLengthArray<QFixedPoint> positions;
QVarLengthArray<glyph_t> glyphs;
@@ -3467,7 +3134,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
|| (fontEngine->type() == QFontEngine::Proxy
&& !(static_cast<QProxyFontEngine *>(fontEngine)->drawAsOutline()))
)) {
- fontEngine->draw(this, qFloor(p.x()), qFloor(p.y()), ti);
+ fontEngine->draw(this, qFloor(p.x() + aliasedCoordinateDelta), qFloor(p.y() + aliasedCoordinateDelta), ti);
return;
}
#endif // Q_WS_QWS
@@ -3490,6 +3157,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
for(int i = 0; i < glyphs.size(); i++) {
QImage img = fontEngine->alphaMapForGlyph(glyphs[i]);
glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]);
+ // ### hm, perhaps an QFixed offs = QFixed::fromReal(aliasedCoordinateDelta) is needed here?
alphaPenBlt(img.bits(), img.bytesPerLine(), img.depth(),
qRound(positions[i].x + metrics.x),
qRound(positions[i].y + metrics.y),
@@ -3544,48 +3212,16 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
QRasterPaintEngineState *s = state();
ensurePen();
- qreal pw = s->lastPen.widthF();
- if (!s->flags.fast_pen && (s->matrix.type() > QTransform::TxTranslate || pw > 1)) {
- QPaintEngineEx::drawPoints(points, pointCount);
-
- } else {
- if (!s->penData.blend)
- return;
-
- QVarLengthArray<QT_FT_Span, 4096> array(pointCount);
- QT_FT_Span span = { 0, 1, 0, 255 };
- const QPointF *end = points + pointCount;
- qreal trans_x, trans_y;
- int x, y;
- int left = d->deviceRect.x();
- int right = left + d->deviceRect.width();
- int top = d->deviceRect.y();
- int bottom = top + d->deviceRect.height();
- int count = 0;
- while (points < end) {
- s->matrix.map(points->x(), points->y(), &trans_x, &trans_y);
- x = qFloor(trans_x);
- y = qFloor(trans_y);
- if (x >= left && x < right && y >= top && y < bottom) {
- if (count > 0) {
- const QT_FT_Span &last = array[count - 1];
- // spans must be sorted on y (primary) and x (secondary)
- if (y < last.y || (y == last.y && x < last.x)) {
- s->penData.blend(count, array.constData(), &s->penData);
- count = 0;
- }
- }
-
- span.x = x;
- span.y = y;
- array[count++] = span;
- }
- ++points;
- }
+ if (!s->penData.blend)
+ return;
- if (count > 0)
- s->penData.blend(count, array.constData(), &s->penData);
+ if (!s->flags.fast_pen) {
+ QPaintEngineEx::drawPoints(points, pointCount);
+ return;
}
+
+ QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.drawPoints(points, pointCount);
}
@@ -3595,48 +3231,16 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
QRasterPaintEngineState *s = state();
ensurePen();
- double pw = s->lastPen.widthF();
- if (!s->flags.fast_pen && (s->matrix.type() > QTransform::TxTranslate || pw > 1)) {
- QPaintEngineEx::drawPoints(points, pointCount);
-
- } else {
- if (!s->penData.blend)
- return;
-
- QVarLengthArray<QT_FT_Span, 4096> array(pointCount);
- QT_FT_Span span = { 0, 1, 0, 255 };
- const QPoint *end = points + pointCount;
- qreal trans_x, trans_y;
- int x, y;
- int left = d->deviceRect.x();
- int right = left + d->deviceRect.width();
- int top = d->deviceRect.y();
- int bottom = top + d->deviceRect.height();
- int count = 0;
- while (points < end) {
- s->matrix.map(points->x(), points->y(), &trans_x, &trans_y);
- x = qFloor(trans_x);
- y = qFloor(trans_y);
- if (x >= left && x < right && y >= top && y < bottom) {
- if (count > 0) {
- const QT_FT_Span &last = array[count - 1];
- // spans must be sorted on y (primary) and x (secondary)
- if (y < last.y || (y == last.y && x < last.x)) {
- s->penData.blend(count, array.constData(), &s->penData);
- count = 0;
- }
- }
-
- span.x = x;
- span.y = y;
- array[count++] = span;
- }
- ++points;
- }
+ if (!s->penData.blend)
+ return;
- if (count > 0)
- s->penData.blend(count, array.constData(), &s->penData);
+ if (!s->flags.fast_pen) {
+ QPaintEngineEx::drawPoints(points, pointCount);
+ return;
}
+
+ QCosmeticStroker stroker(s, d->deviceRect);
+ stroker.drawPoints(points, pointCount);
}
/*!
@@ -3645,59 +3249,22 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
{
#ifdef QT_DEBUG_DRAW
- qDebug() << " - QRasterPaintEngine::drawLine()";
+ qDebug() << " - QRasterPaintEngine::drawLines(QLine*)" << lineCount;
#endif
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
ensurePen();
+ if (!s->penData.blend)
+ return;
+
if (s->flags.fast_pen) {
- QIntRect bounds; bounds.set(d->deviceRect);
- LineDrawMode mode = s->lastPen.capStyle() == Qt::FlatCap
- ? LineDrawNormal
- : LineDrawIncludeLastPixel;
-
- int m11 = int(s->matrix.m11());
- int m22 = int(s->matrix.m22());
- int dx = qFloor(s->matrix.dx());
- int dy = qFloor(s->matrix.dy());
+ QCosmeticStroker stroker(s, d->deviceRect);
for (int i=0; i<lineCount; ++i) {
- int dashOffset = int(s->lastPen.dashOffset());
- if (s->flags.int_xform) {
- const QLine &l = lines[i];
- int x1 = l.x1() * m11 + dx;
- int y1 = l.y1() * m22 + dy;
- int x2 = l.x2() * m11 + dx;
- int y2 = l.y2() * m22 + dy;
-
- const QRect brect(QPoint(x1, y1), QPoint(x2, y2));
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(x1, y1, x2, y2,
- penBlend, &s->penData, mode, bounds);
- else
- drawLine_midpoint_dashed_i(x1, y1, x2, y2,
- &s->lastPen, penBlend,
- &s->penData, mode, bounds,
- &dashOffset);
- } else {
- QLineF line = lines[i] * s->matrix;
- const QRectF brect(QPointF(line.x1(), line.y1()),
- QPointF(line.x2(), line.y2()));
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(int(line.x1()), int(line.y1()),
- int(line.x2()), int(line.y2()),
- penBlend, &s->penData, mode, bounds);
- else
- drawLine_midpoint_dashed_i(int(line.x1()), int(line.y1()),
- int(line.x2()), int(line.y2()),
- &s->lastPen, penBlend,
- &s->penData, mode, bounds,
- &dashOffset);
- }
+ const QLine &l = lines[i];
+ stroker.drawLine(l.p1(), l.p2());
}
- } else if (s->penData.blend) {
+ } else {
QPaintEngineEx::drawLines(lines, lineCount);
}
}
@@ -3754,7 +3321,7 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line,
void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
#ifdef QT_DEBUG_DRAW
- qDebug() << " - QRasterPaintEngine::drawLine()";
+ qDebug() << " - QRasterPaintEngine::drawLines(QLineF *)" << lineCount;
#endif
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
@@ -3763,28 +3330,10 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (!s->penData.blend)
return;
if (s->flags.fast_pen) {
- QIntRect bounds;
- bounds.set(d->deviceRect);
- LineDrawMode mode = s->lastPen.capStyle() == Qt::FlatCap
- ? LineDrawNormal
- : LineDrawIncludeLastPixel;
-
+ QCosmeticStroker stroker(s, d->deviceRect);
for (int i=0; i<lineCount; ++i) {
- int dashOffset = int(s->lastPen.dashOffset());
- QLineF line = lines[i] * s->matrix;
- const QRectF brect(QPointF(line.x1(), line.y1()),
- QPointF(line.x2(), line.y2()));
- ProcessSpans penBlend = d->getPenFunc(brect, &s->penData);
- if (qpen_style(s->lastPen) == Qt::SolidLine)
- drawLine_midpoint_i(int(line.x1()), int(line.y1()),
- int(line.x2()), int(line.y2()),
- penBlend, &s->penData, mode, bounds);
- else
- drawLine_midpoint_dashed_i(int(line.x1()), int(line.y1()),
- int(line.x2()), int(line.y2()),
- &s->lastPen,
- penBlend, &s->penData, mode,
- bounds, &dashOffset);
+ QLineF line = lines[i];
+ stroker.drawLine(line.p1(), line.p2());
}
} else {
QPaintEngineEx::drawLines(lines, lineCount);
@@ -3802,7 +3351,8 @@ void QRasterPaintEngine::drawEllipse(const QRectF &rect)
ensurePen();
if (((qpen_style(s->lastPen) == Qt::SolidLine && s->flags.fast_pen)
- || (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased))
+ || (qpen_style(s->lastPen) == Qt::NoPen))
+ && !s->flags.antialiased
&& qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT
&& !rect.isEmpty()
&& s->matrix.type() <= QTransform::TxScale) // no shear
@@ -3870,6 +3420,37 @@ void QRasterPaintEngine::releaseDC(HDC) const
#endif
+bool QRasterPaintEngine::supportsTransformations(const QFontEngine *fontEngine) const
+{
+ const QTransform &m = state()->matrix;
+#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
+ QFontEngine::Type fontEngineType = fontEngine->type();
+ if ((fontEngineType == QFontEngine::Win && !((QFontEngineWin *) fontEngine)->ttf && m.type() > QTransform::TxTranslate)
+ || (m.type() <= QTransform::TxTranslate
+ && (fontEngineType == QFontEngine::TestFontEngine
+ || fontEngineType == QFontEngine::Box))) {
+ return true;
+ }
+#endif
+ return supportsTransformations(fontEngine->fontDef.pixelSize, m);
+}
+
+bool QRasterPaintEngine::supportsTransformations(qreal pixelSize, const QTransform &m) const
+{
+#if defined(Q_WS_MAC)
+ // Mac font engines don't support scaling and rotation
+ if (m.type() > QTransform::TxTranslate)
+#else
+ if (m.type() >= QTransform::TxProject)
+#endif
+ return true;
+
+ if (pixelSize * pixelSize * qAbs(m.determinant()) >= 64 * 64)
+ return true;
+
+ return false;
+}
+
/*!
\internal
*/
@@ -4821,7 +4402,7 @@ static void qt_span_fill_clipped(int spanCount, const QSpan *spans, void *userDa
while (spans < end) {
QSpan *clipped = cspans;
spans = qt_intersect_spans(fillData->clip, &currentClip, spans, end, &clipped, NSPANS);
-// qDebug() << "processed " << processed << "clipped" << clipped-cspans
+// qDebug() << "processed " << spanCount - (end - spans) << "clipped" << clipped-cspans
// << "span:" << cspans->x << cspans->y << cspans->len << spans->coverage;
if (clipped - cspans)
@@ -5473,759 +5054,6 @@ void QSpanData::initTexture(const QImage *image, int alpha, QTextureData::Type _
adjustSpanMethods();
}
-#ifdef Q_WS_WIN
-
-
-#endif
-
-
-/*!
- \internal
-
- Draws a line using the floating point midpoint algorithm. The line
- \a line is already in device coords at this point.
-*/
-
-static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans span_func, QSpanData *data,
- LineDrawMode style, const QIntRect &devRect)
-{
-#ifdef QT_DEBUG_DRAW
- qDebug() << " - drawLine_midpoint_i" << QLine(QPoint(x1, y1), QPoint(x2, y2));
-#endif
-
- int x, y;
- int dx, dy, d, incrE, incrNE;
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- const int NSPANS = 256;
- QT_FT_Span spans[NSPANS];
- int current = 0;
- bool ordered = true;
-
- if (dy == 0) {
- // specialcase horizontal lines
- if (y1 >= devRect.y1 && y1 < devRect.y2) {
- int start = qMax(devRect.x1, qMin(x1, x2));
- int stop = qMax(x1, x2) + 1;
- int stop_clipped = qMin(devRect.x2, stop);
- int len = stop_clipped - start;
- if (style == LineDrawNormal && stop == stop_clipped)
- len--;
- if (len > 0) {
- spans[0].x = ushort(start);
- spans[0].len = ushort(len);
- spans[0].y = y1;
- spans[0].coverage = 255;
- span_func(1, spans, data);
- }
- }
- return;
- } else if (dx == 0) {
- // specialcase vertical lines
- if (x1 >= devRect.x1 && x1 < devRect.x2) {
- int start = qMax(devRect.y1, qMin(y1, y2));
- int stop = qMax(y1, y2) + 1;
- int stop_clipped = qMin(devRect.y2, stop);
- int len = stop_clipped - start;
- if (style == LineDrawNormal && stop == stop_clipped)
- len--;
- // hw: create spans directly instead to possibly avoid clipping
- if (len > 0)
- fillRect_normalized(QRect(x1, start, 1, len).normalized(), data, 0);
- }
- return;
- }
-
-
- if (qAbs(dx) >= qAbs(dy)) { /* if x is the major axis: */
-
- if (x2 < x1) { /* if coordinates are out of order */
- qt_swap_int(x1, x2);
- dx = -dx;
-
- qt_swap_int(y1, y2);
- dy = -dy;
- }
-
- int x_lower_limit = - 128;
- if (x1 < x_lower_limit) {
- int cy = dy * (x_lower_limit - x1) / dx + y1;
- drawLine_midpoint_i(x_lower_limit, cy, x2, y2, span_func, data, style, devRect);
- return;
- }
-
- if (style == LineDrawNormal)
- --x2;
-
- // In the loops below we increment before call the span function so
- // we need to stop one pixel before
- x2 = qMin(x2, devRect.x2 - 1);
-
- // completely clipped, so abort
- if (x2 <= x1) {
- return;
- }
-
- int x = x1;
- int y = y1;
-
- if (y2 <= y1)
- ordered = false;
-
- {
- const int index = (ordered ? current : NSPANS - 1 - current);
- spans[index].coverage = 255;
- spans[index].x = x;
- spans[index].y = y;
-
- if (x >= devRect.x1 && y >= devRect.y1 && y < devRect.y2)
- spans[index].len = 1;
- else
- spans[index].len = 0;
- }
-
- if (y2 > y1) { // 315 -> 360 and 135 -> 180 (unit circle degrees)
- y2 = qMin(y2, devRect.y2 - 1);
-
- incrE = dy * 2;
- d = incrE - dx;
- incrNE = (dy - dx) * 2;
-
- if (y > y2)
- goto flush_and_return;
-
- while (x < x2) {
- ++x;
- if (d > 0) {
- if (spans[current].len > 0)
- ++current;
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
-
- ++y;
- d += incrNE;
- if (y > y2)
- goto flush_and_return;
-
- spans[current].len = 0;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- } else {
- d += incrE;
- if (x == devRect.x1)
- spans[current].x = devRect.x1;
- }
-
- if (x < devRect.x1 || y < devRect.y1)
- continue;
-
- Q_ASSERT(x<devRect.x2);
- Q_ASSERT(y<devRect.y2);
- Q_ASSERT(spans[current].y == y);
- spans[current].len++;
- }
- if (spans[current].len > 0) {
- ++current;
- }
- } else { // 0-45 and 180->225 (unit circle degrees)
-
- y1 = qMin(y1, devRect.y2 - 1);
-
- incrE = dy * 2;
- d = incrE + dx;
- incrNE = (dy + dx) * 2;
-
- if (y < devRect.y1)
- goto flush_and_return;
-
- while (x < x2) {
- ++x;
- if (d < 0) {
- if (spans[NSPANS - 1 - current].len > 0)
- ++current;
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
-
- --y;
- d += incrNE;
- if (y < devRect.y1)
- goto flush_and_return;
-
- const int index = NSPANS - 1 - current;
- spans[index].len = 0;
- spans[index].coverage = 255;
- spans[index].x = x;
- spans[index].y = y;
- } else {
- d += incrE;
- if (x == devRect.x1)
- spans[NSPANS - 1 - current].x = devRect.x1;
- }
-
- if (x < devRect.x1 || y > y1)
- continue;
-
- Q_ASSERT(x<devRect.x2 && y<devRect.y2);
- Q_ASSERT(spans[NSPANS - 1 - current].y == y);
- spans[NSPANS - 1 - current].len++;
- }
- if (spans[NSPANS - 1 - current].len > 0) {
- ++current;
- }
- }
-
- } else {
-
- // if y is the major axis:
-
- if (y2 < y1) { /* if coordinates are out of order */
- qt_swap_int(y1, y2);
- dy = -dy;
-
- qt_swap_int(x1, x2);
- dx = -dx;
- }
-
- int y_lower_limit = - 128;
- if (y1 < y_lower_limit) {
- int cx = dx * (y_lower_limit - y1) / dy + x1;
- drawLine_midpoint_i(cx, y_lower_limit, x2, y2, span_func, data, style, devRect);
- return;
- }
-
- if (style == LineDrawNormal)
- --y2;
-
- // In the loops below we increment before call the span function so
- // we need to stop one pixel before
- y2 = qMin(y2, devRect.y2 - 1);
-
- // completely clipped, so abort
- if (y2 <= y1) {
- return;
- }
-
- x = x1;
- y = y1;
-
- if (x>=devRect.x1 && y>=devRect.y1 && x < devRect.x2) {
- Q_ASSERT(x >= devRect.x1 && y >= devRect.y1 && x < devRect.x2 && y < devRect.y2);
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
-
- if (x2 > x1) { // 90 -> 135 and 270 -> 315 (unit circle degrees)
- x2 = qMin(x2, devRect.x2 - 1);
- incrE = dx * 2;
- d = incrE - dy;
- incrNE = (dx - dy) * 2;
-
- if (x > x2)
- goto flush_and_return;
-
- while (y < y2) {
- if (d > 0) {
- ++x;
- d += incrNE;
- if (x > x2)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++y;
- if (x < devRect.x1 || y < devRect.y1)
- continue;
- Q_ASSERT(x<devRect.x2 && y<devRect.y2);
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- } else { // 45 -> 90 and 225 -> 270 (unit circle degrees)
- x1 = qMin(x1, devRect.x2 - 1);
- incrE = dx * 2;
- d = incrE + dy;
- incrNE = (dx + dy) * 2;
-
- if (x < devRect.x1)
- goto flush_and_return;
-
- while (y < y2) {
- if (d < 0) {
- --x;
- d += incrNE;
- if (x < devRect.x1)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++y;
- if (y < devRect.y1 || x > x1)
- continue;
- Q_ASSERT(x>=devRect.x1 && x<devRect.x2 && y>=devRect.y1 && y<devRect.y2);
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- }
- }
-flush_and_return:
- if (current > 0)
- span_func(current, ordered ? spans : spans + (NSPANS - current), data);
-}
-
-static void offset_pattern(int offset, bool *inDash, int *dashIndex, int *currentOffset, const QVarLengthArray<qreal> &pattern)
-{
- while (offset--) {
- if (--*currentOffset == 0) {
- *inDash = !*inDash;
- *dashIndex = ((*dashIndex + 1) % pattern.size());
- *currentOffset = int(pattern[*dashIndex]);
- }
- }
-}
-
-static void drawLine_midpoint_dashed_i(int x1, int y1, int x2, int y2,
- QPen *pen,
- ProcessSpans span_func, QSpanData *data,
- LineDrawMode style, const QIntRect &devRect,
- int *patternOffset)
-{
-#ifdef QT_DEBUG_DRAW
- qDebug() << " - drawLine_midpoint_dashed_i" << x1 << y1 << x2 << y2 << *patternOffset;
-#endif
-
- int x, y;
- int dx, dy, d, incrE, incrNE;
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- Q_ASSERT(*patternOffset >= 0);
-
- const QVector<qreal> penPattern = pen->dashPattern();
- QVarLengthArray<qreal> pattern(penPattern.size());
-
- int patternLength = 0;
- for (int i = 0; i < penPattern.size(); ++i)
- patternLength += qMax<qreal>(1.0, (penPattern.at(i)));
-
- // pattern must be reversed if coordinates are out of order
- int reverseLength = -1;
- if (dy == 0 && x1 > x2)
- reverseLength = x1 - x2;
- else if (dx == 0 && y1 > y2)
- reverseLength = y1 - y2;
- else if (qAbs(dx) >= qAbs(dy) && x2 < x1) // x major axis
- reverseLength = qAbs(dx);
- else if (qAbs(dy) >= qAbs(dx) && y2 < y1) // y major axis
- reverseLength = qAbs(dy);
-
- const bool reversed = (reverseLength > -1);
- if (reversed) { // reverse pattern
- for (int i = 0; i < penPattern.size(); ++i)
- pattern[penPattern.size() - 1 - i] = qMax<qreal>(1.0, penPattern.at(i));
-
- *patternOffset = (patternLength - 1 - *patternOffset);
- *patternOffset += patternLength - (reverseLength % patternLength);
- *patternOffset = *patternOffset % patternLength;
- } else {
- for (int i = 0; i < penPattern.size(); ++i)
- pattern[i] = qMax<qreal>(1.0, penPattern.at(i));
- }
-
- int dashIndex = 0;
- bool inDash = !reversed;
- int currPattern = int(pattern[dashIndex]);
-
- // adjust pattern for offset
- offset_pattern(*patternOffset, &inDash, &dashIndex, &currPattern, pattern);
-
- const int NSPANS = 256;
- QT_FT_Span spans[NSPANS];
- int current = 0;
- bool ordered = true;
-
- if (dy == 0) {
- // specialcase horizontal lines
- if (y1 >= devRect.y1 && y1 < devRect.y2) {
- int start_unclipped = qMin(x1, x2);
- int start = qMax(devRect.x1, start_unclipped);
- int stop = qMax(x1, x2) + 1;
- int stop_clipped = qMin(devRect.x2, stop);
- int len = stop_clipped - start;
- if (style == LineDrawNormal && stop == stop_clipped)
- len--;
-
- // adjust pattern for starting offset
- offset_pattern(start - start_unclipped, &inDash, &dashIndex, &currPattern, pattern);
-
- if (len > 0) {
- int x = start;
- while (x < stop_clipped) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- const int dash = qMin(currPattern, stop_clipped - x);
- if (inDash) {
- spans[current].x = ushort(x);
- spans[current].len = ushort(dash);
- spans[current].y = y1;
- spans[current].coverage = 255;
- ++current;
- }
- if (dash < currPattern) {
- currPattern -= dash;
- } else {
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- inDash = !inDash;
- }
- x += dash;
- }
- }
- }
- goto flush_and_return;
- } else if (dx == 0) {
- if (x1 >= devRect.x1 && x1 < devRect.x2) {
- int start_unclipped = qMin(y1, y2);
- int start = qMax(devRect.y1, start_unclipped);
- int stop = qMax(y1, y2) + 1;
- int stop_clipped = qMin(devRect.y2, stop);
- if (style == LineDrawNormal && stop == stop_clipped)
- --stop;
- else
- stop = stop_clipped;
-
- // adjust pattern for starting offset
- offset_pattern(start - start_unclipped, &inDash, &dashIndex, &currPattern, pattern);
-
- // loop over dashes
- int y = start;
- while (y < stop) {
- const int dash = qMin(currPattern, stop - y);
- if (inDash) {
- for (int i = 0; i < dash; ++i) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].x = x1;
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].y = ushort(y + i);
- ++current;
- }
- }
- if (dash < currPattern) {
- currPattern -= dash;
- } else {
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- inDash = !inDash;
- }
- y += dash;
- }
- }
- goto flush_and_return;
- }
-
- if (qAbs(dx) >= qAbs(dy)) { /* if x is the major axis: */
-
- if (x2 < x1) { /* if coordinates are out of order */
- qt_swap_int(x1, x2);
- dx = -dx;
-
- qt_swap_int(y1, y2);
- dy = -dy;
- }
-
- if (style == LineDrawNormal)
- --x2;
-
- // In the loops below we increment before call the span function so
- // we need to stop one pixel before
- x2 = qMin(x2, devRect.x2 - 1);
-
- // completely clipped, so abort
- if (x2 <= x1)
- goto flush_and_return;
-
- int x = x1;
- int y = y1;
-
- if (x >= devRect.x1 && y >= devRect.y1 && y < devRect.y2) {
- Q_ASSERT(x < devRect.x2);
- if (inDash) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
-
- if (y2 > y1) { // 315 -> 360 and 135 -> 180 (unit circle degrees)
- y2 = qMin(y2, devRect.y2 - 1);
-
- incrE = dy * 2;
- d = incrE - dx;
- incrNE = (dy - dx) * 2;
-
- if (y > y2)
- goto flush_and_return;
-
- while (x < x2) {
- if (d > 0) {
- ++y;
- d += incrNE;
- if (y > y2)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++x;
-
- const bool skip = x < devRect.x1 || y < devRect.y1;
- Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2));
- if (inDash && !skip) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
- } else { // 0-45 and 180->225 (unit circle degrees)
- y1 = qMin(y1, devRect.y2 - 1);
-
- incrE = dy * 2;
- d = incrE + dx;
- incrNE = (dy + dx) * 2;
-
- if (y < devRect.y1)
- goto flush_and_return;
-
- while (x < x2) {
- if (d < 0) {
- if (current > 0) {
- span_func(current, spans, data);
- current = 0;
- }
-
- --y;
- d += incrNE;
- if (y < devRect.y1)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++x;
-
- const bool skip = x < devRect.x1 || y > y1;
- Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2));
- if (inDash && !skip) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
- }
- } else {
-
- // if y is the major axis:
-
- if (y2 < y1) { /* if coordinates are out of order */
- qt_swap_int(y1, y2);
- dy = -dy;
-
- qt_swap_int(x1, x2);
- dx = -dx;
- }
-
- if (style == LineDrawNormal)
- --y2;
-
- // In the loops below we increment before call the span function so
- // we need to stop one pixel before
- y2 = qMin(y2, devRect.y2 - 1);
-
- // completely clipped, so abort
- if (y2 <= y1)
- goto flush_and_return;
-
- x = x1;
- y = y1;
-
- if (x>=devRect.x1 && y>=devRect.y1 && x < devRect.x2) {
- Q_ASSERT(x < devRect.x2);
- if (inDash) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
-
- if (x2 > x1) { // 90 -> 135 and 270 -> 315 (unit circle degrees)
- x2 = qMin(x2, devRect.x2 - 1);
- incrE = dx * 2;
- d = incrE - dy;
- incrNE = (dx - dy) * 2;
-
- if (x > x2)
- goto flush_and_return;
-
- while (y < y2) {
- if (d > 0) {
- ++x;
- d += incrNE;
- if (x > x2)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++y;
- const bool skip = x < devRect.x1 || y < devRect.y1;
- Q_ASSERT(skip || (x < devRect.x2 && y < devRect.y2));
- if (inDash && !skip) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
- } else { // 45 -> 90 and 225 -> 270 (unit circle degrees)
- x1 = qMin(x1, devRect.x2 - 1);
- incrE = dx * 2;
- d = incrE + dy;
- incrNE = (dx + dy) * 2;
-
- if (x < devRect.x1)
- goto flush_and_return;
-
- while (y < y2) {
- if (d < 0) {
- --x;
- d += incrNE;
- if (x < devRect.x1)
- goto flush_and_return;
- } else {
- d += incrE;
- }
- ++y;
- const bool skip = y < devRect.y1 || x > x1;
- Q_ASSERT(skip || (x >= devRect.x1 && x < devRect.x2 && y < devRect.y2));
- if (inDash && !skip) {
- if (current == NSPANS) {
- span_func(NSPANS, spans, data);
- current = 0;
- }
- spans[current].len = 1;
- spans[current].coverage = 255;
- spans[current].x = x;
- spans[current].y = y;
- ++current;
- }
- if (--currPattern <= 0) {
- inDash = !inDash;
- dashIndex = (dashIndex + 1) % pattern.size();
- currPattern = int(pattern[dashIndex]);
- }
- }
- }
- }
-flush_and_return:
- if (current > 0)
- span_func(current, ordered ? spans : spans + (NSPANS - current), data);
-
- // adjust offset
- if (reversed) {
- *patternOffset = (patternLength - 1 - *patternOffset);
- } else {
- *patternOffset = 0;
- for (int i = 0; i <= dashIndex; ++i)
- *patternOffset += int(pattern[i]);
- *patternOffset += patternLength - currPattern - 1;
- *patternOffset = (*patternOffset % patternLength);
- }
-}
-
/*!
\internal
\a x and \a y is relative to the midpoint of \a rect.
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 8859df0..8774fda 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -196,9 +196,6 @@ public:
void stroke(const QVectorPath &path, const QPen &pen);
void fill(const QVectorPath &path, const QBrush &brush);
- void strokePolygonCosmetic(const QPoint *pts, int pointCount, PolygonDrawMode mode);
- void strokePolygonCosmetic(const QPointF *pt, int pointCount, PolygonDrawMode mode);
-
void clip(const QVectorPath &path, Qt::ClipOperation op);
void clip(const QRect &rect, Qt::ClipOperation op);
void clip(const QRegion &region, Qt::ClipOperation op);
@@ -249,6 +246,8 @@ public:
virtual void drawBufferSpan(const uint *buffer, int bufsize,
int x, int y, int length, uint const_alpha);
#endif
+ bool supportsTransformations(const QFontEngine *fontEngine) const;
+ bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
protected:
QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
@@ -328,7 +327,6 @@ public:
bool isUnclipped_normalized(const QRect &rect) const;
bool isUnclipped(const QRect &rect, int penWidth) const;
bool isUnclipped(const QRectF &rect, int penWidth) const;
- ProcessSpans getPenFunc(const QRect &rect, const QSpanData *data) const;
ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 30cf206..8510416 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -44,6 +44,8 @@
#include "qstroker_p.h"
#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qstatictext_p.h>
#include <qvarlengtharray.h>
#include <qdebug.h>
@@ -831,7 +833,7 @@ void QPaintEngineEx::drawEllipse(const QRectF &r)
int point_count = 0;
x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count);
- QVectorPath vp((qreal *) pts, point_count, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
+ QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
draw(vp);
}
@@ -1057,5 +1059,48 @@ Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path)
return p;
}
+void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem)
+{
+ QPainterPath path;
+#ifndef Q_WS_MAC
+ path.setFillRule(Qt::WindingFill);
+#endif
+
+ if (staticTextItem->numGlyphs == 0)
+ return;
+
+ QFontEngine *fontEngine = staticTextItem->fontEngine();
+ fontEngine->addGlyphsToPath(staticTextItem->glyphs, staticTextItem->glyphPositions,
+ staticTextItem->numGlyphs, &path, 0);
+ if (!path.isEmpty()) {
+ QPainterState *s = state();
+ QPainter::RenderHints oldHints = s->renderHints;
+ bool changedHints = false;
+ if (bool(oldHints & QPainter::TextAntialiasing)
+ && !bool(fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
+ && !bool(oldHints & QPainter::Antialiasing)) {
+ s->renderHints |= QPainter::Antialiasing;
+ renderHintsChanged();
+ changedHints = true;
+ }
+
+ fill(qtVectorPathForPath(path), staticTextItem->color);
+
+ if (changedHints) {
+ s->renderHints = oldHints;
+ renderHintsChanged();
+ }
+ }
+}
+
+bool QPaintEngineEx::supportsTransformations(qreal pixelSize, const QTransform &m) const
+{
+ Q_UNUSED(pixelSize);
+
+ if (!m.isAffine())
+ return true;
+
+ return false;
+}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 9730033..c605685 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -202,7 +202,7 @@ public:
virtual void updateState(const QPaintEngineState &state);
- virtual void drawStaticTextItem(QStaticTextItem *) = 0;
+ virtual void drawStaticTextItem(QStaticTextItem *);
virtual void setState(QPainterState *s);
inline QPainterState *state() { return static_cast<QPainterState *>(QPaintEngine::state); }
@@ -227,6 +227,7 @@ public:
IsEmulationEngine = 0x02 // If set, this object is a QEmulationEngine.
};
virtual uint flags() const {return 0;}
+ virtual bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
protected:
QPaintEngineEx(QPaintEngineExPrivate &data);
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 17b7451..5a566d1 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -152,14 +152,6 @@ static inline uint line_emulation(uint emulation)
| QPaintEngine_OpaqueBackground);
}
-static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
-{
- return type == QPaintEngine::OpenGL2
- || type == QPaintEngine::OpenVG
- || type == QPaintEngine::OpenGL
- || type == QPaintEngine::CoreGraphics;
-}
-
#ifndef QT_NO_DEBUG
static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
{
@@ -2868,6 +2860,9 @@ void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
return;
}
+ if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
+ op = Qt::ReplaceClip;
+
d->state->clipRegion = rect;
d->state->clipOperation = op;
if (op == Qt::NoClip || op == Qt::ReplaceClip)
@@ -2923,6 +2918,9 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
return;
}
+ if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
+ op = Qt::ReplaceClip;
+
d->state->clipRegion = r;
d->state->clipOperation = op;
if (op == Qt::NoClip || op == Qt::ReplaceClip)
@@ -3328,6 +3326,9 @@ void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
return;
}
+ if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
+ op = Qt::ReplaceClip;
+
d->state->clipPath = path;
d->state->clipOperation = op;
if (op == Qt::NoClip || op == Qt::ReplaceClip)
@@ -5809,35 +5810,37 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
if (!font.isValid())
return;
- QVector<quint32> glyphIndexes = glyphRun.glyphIndexes();
- QVector<QPointF> glyphPositions = glyphRun.positions();
+ QGlyphRunPrivate *glyphRun_d = QGlyphRunPrivate::get(glyphRun);
- int count = qMin(glyphIndexes.size(), glyphPositions.size());
- QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
+ const quint32 *glyphIndexes = glyphRun_d->glyphIndexData;
+ const QPointF *glyphPositions = glyphRun_d->glyphPositionData;
- bool paintEngineSupportsTransformations =
- d->extended != 0
- ? qt_paintengine_supports_transformations(d->extended->type())
- : qt_paintengine_supports_transformations(d->engine->type());
+ int count = qMin(glyphRun_d->glyphIndexDataSize, glyphRun_d->glyphPositionDataSize);
+ QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
- // If the matrix is not affine, the paint engine will fall back to
- // drawing the glyphs as paths, which in turn means we should not
- // preprocess the glyph positions
- if (!d->state->matrix.isAffine())
- paintEngineSupportsTransformations = true;
+ QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+ bool supportsTransformations;
+ if (d->extended != 0) {
+ supportsTransformations = d->extended->supportsTransformations(fontD->fontEngine->fontDef.pixelSize,
+ d->state->matrix);
+ } else {
+ supportsTransformations = d->engine->type() == QPaintEngine::CoreGraphics
+ || d->state->matrix.isAffine();
+ }
for (int i=0; i<count; ++i) {
- QPointF processedPosition = position + glyphPositions.at(i);
- if (!paintEngineSupportsTransformations)
+ QPointF processedPosition = position + glyphPositions[i];
+ if (!supportsTransformations)
processedPosition = d->state->transform().map(processedPosition);
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
- d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphRun.overline(),
+ d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(),
glyphRun.underline(), glyphRun.strikeOut());
}
-void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount,
+void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
+ int glyphCount,
const QRawFont &font, bool overline, bool underline,
bool strikeOut)
{
@@ -6004,11 +6007,12 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
return;
}
- bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type());
- if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
+ bool supportsTransformations = d->extended->supportsTransformations(staticText_d->font.pixelSize(),
+ d->state->matrix);
+ if (supportsTransformations && !staticText_d->untransformedCoordinates) {
staticText_d->untransformedCoordinates = true;
staticText_d->needsRelayout = true;
- } else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) {
+ } else if (!supportsTransformations && staticText_d->untransformedCoordinates) {
staticText_d->untransformedCoordinates = false;
staticText_d->needsRelayout = true;
}
@@ -6468,8 +6472,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
const qreal underlineOffset = fe->underlinePosition().toReal();
// deliberately ceil the offset to avoid the underline coming too close to
// the text above it.
- const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
- const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta;
+ const qreal underlinePos = pos.y() + qCeil(underlineOffset);
if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 35cdf86..79d4b4b 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -232,7 +232,7 @@ public:
void drawOpaqueBackground(const QPainterPath &path, DrawOperation operation);
#if !defined(QT_NO_RAWFONT)
- void drawGlyphs(quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
+ void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
const QRawFont &font, bool overline = false, bool underline = false,
bool strikeOut = false);
#endif
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index 6c5edbc..1d3f581 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -62,8 +62,8 @@ typedef int Q16Dot16;
#define SPAN_BUFFER_SIZE 256
-#define COORD_ROUNDING 0 // 0: round up, 1: round down
-#define COORD_OFFSET 0 // 26.6, 32 is half a pixel
+#define COORD_ROUNDING 1 // 0: round up, 1: round down
+#define COORD_OFFSET 32 // 26.6, 32 is half a pixel
static inline QT_FT_Vector PointToVector(const QPointF &p)
{
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 53fefa4..fdba9c9 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -296,14 +296,10 @@ void QTextureGlyphCache::fillInPendingGlyphs()
QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const
{
#if defined(Q_WS_X11)
- if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) {
+ if (m_type != Raster_RGBMask && m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) {
QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None;
QImage::Format imageFormat = QImage::Format_Invalid;
switch (m_type) {
- case Raster_RGBMask:
- format = QFontEngineFT::Format_A32;
- imageFormat = QImage::Format_RGB32;
- break;
case Raster_A8:
format = QFontEngineFT::Format_A8;
imageFormat = QImage::Format_Indexed8;
@@ -312,6 +308,10 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition
format = QFontEngineFT::Format_Mono;
imageFormat = QImage::Format_Mono;
break;
+ case Raster_RGBMask:
+ // impossible condition (see the if-clause above)
+ // this option is here only to silence a compiler warning
+ break;
};
QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine);
@@ -367,7 +367,9 @@ void QImageTextureGlyphCache::createTextureData(int width, int height)
int QImageTextureGlyphCache::glyphMargin() const
{
-#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) || defined(Q_WS_X11)
+#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA))
+ return 1;
+#elif defined(Q_WS_X11)
return 0;
#else
return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0;
@@ -386,7 +388,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
}
#endif
- if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
+ if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()),
qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(),
m_image.format());
diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
index aecbf2b..1eb5e61 100644
--- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
+++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp
@@ -171,10 +171,8 @@ void QUnifiedToolbarSurface::flush(QWidget *widget)
if (!d->image)
return;
- if (widget->d_func()->flushRequested) {
- // We call display: directly to avoid flickering in the toolbar.
- qt_mac_display(widget);
- }
+ if (widget->d_func()->flushRequested)
+ qt_mac_setNeedsDisplay(widget);
}
void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget)
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
index c52f864..7e8cf9b 100644
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ b/src/gui/painting/qwindowsurface_qws.cpp
@@ -806,6 +806,10 @@ QWSMemorySurface::QWSMemorySurface(QWidget *w)
QWSMemorySurface::~QWSMemorySurface()
{
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (memlock != QWSDisplay::Data::getClientLock())
+ delete memlock;
+#endif
}
@@ -852,9 +856,9 @@ void QWSMemorySurface::setLock(int lockId)
{
if (memlock && memlock->id() == lockId)
return;
- delete memlock;
+ if (memlock != QWSDisplay::Data::getClientLock())
+ delete memlock;
memlock = (lockId == -1 ? 0 : new QWSLock(lockId));
- return;
}
#endif // QT_NO_QWS_MULTIPROCESS
@@ -946,37 +950,39 @@ void QWSLocalMemSurface::setGeometry(const QRect &rect)
}
uchar *deleteLater = 0;
- // In case of a Hide event we need to delete the memory after sending the
- // event to the server in order to let the server animate the event.
- if (size.isEmpty()) {
- deleteLater = mem;
- mem = 0;
- }
if (img.size() != size) {
- delete[] mem;
if (size.isEmpty()) {
+ if (memsize) {
+ // In case of a Hide event we need to delete the memory after sending the
+ // event to the server in order to let the server animate the event.
+ deleteLater = mem;
+ memsize = 0;
+ }
mem = 0;
img = QImage();
} else {
const QImage::Format format = preferredImageFormat(win);
const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
- const int memsize = bpl * size.height();
- mem = new uchar[memsize];
+ const int imagesize = bpl * size.height();
+ if (memsize < imagesize) {
+ delete[] mem;
+ memsize = imagesize;
+ mem = new uchar[memsize];
+ }
img = QImage(mem, size.width(), size.height(), bpl, format);
setImageMetrics(img, win);
}
}
QWSWindowSurface::setGeometry(rect);
+
delete[] deleteLater;
}
QByteArray QWSLocalMemSurface::permanentState() const
{
- QByteArray array;
- array.resize(sizeof(uchar*) + 3 * sizeof(int) +
- sizeof(SurfaceFlags));
+ QByteArray array(sizeof(uchar*) + 3 * sizeof(int) + sizeof(SurfaceFlags), Qt::Uninitialized);
char *ptr = array.data();
@@ -997,6 +1003,11 @@ QByteArray QWSLocalMemSurface::permanentState() const
void QWSLocalMemSurface::setPermanentState(const QByteArray &data)
{
+ if (memsize) {
+ delete[] mem;
+ memsize = 0;
+ }
+
int width;
int height;
QImage::Format format;
@@ -1023,6 +1034,10 @@ void QWSLocalMemSurface::setPermanentState(const QByteArray &data)
void QWSLocalMemSurface::releaseSurface()
{
+ if (memsize) {
+ delete[] mem;
+ memsize = 0;
+ }
mem = 0;
img = QImage();
}
@@ -1064,17 +1079,15 @@ bool QWSSharedMemSurface::setMemory(int memId)
void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id)
{
QWSMemorySurface::setDirectRegion(r, id);
- if(mem.address())
+ if (mem.address())
*(uint *)mem.address() = id;
}
const QRegion QWSSharedMemSurface::directRegion() const
{
- QWSSharedMemory *cmem = const_cast<QWSSharedMemory *>(&mem);
- if (cmem->address() && ((int*)cmem->address())[0] == directRegionId())
+ if (mem.address() && *(uint *)mem.address() == uint(directRegionId())
return QWSMemorySurface::directRegion();
- else
- return QRegion();
+ return QRegion();
}
#endif
@@ -1117,8 +1130,6 @@ void QWSSharedMemSurface::setGeometry(const QRect &rect)
mem.detach();
img = QImage();
} else {
- mem.detach();
-
QWidget *win = window();
const QImage::Format format = preferredImageFormat(win);
const int bpl = nextMulOf4(bytesPerPixel(format) * size.width());
@@ -1127,9 +1138,12 @@ void QWSSharedMemSurface::setGeometry(const QRect &rect)
#else
const int imagesize = bpl * size.height();
#endif
- if (!mem.create(imagesize)) {
- perror("QWSSharedMemSurface::setGeometry allocating shared memory");
- qFatal("Error creating shared memory of size %d", imagesize);
+ if (mem.size() < imagesize) {
+ mem.detach();
+ if (!mem.create(imagesize)) {
+ perror("QWSSharedMemSurface::setGeometry allocating shared memory");
+ qFatal("Error creating shared memory of size %d", imagesize);
+ }
}
#ifdef QT_QWS_CLIENTBLIT
*((uint *)mem.address()) = 0;
@@ -1147,8 +1161,7 @@ void QWSSharedMemSurface::setGeometry(const QRect &rect)
QByteArray QWSSharedMemSurface::permanentState() const
{
- QByteArray array;
- array.resize(6 * sizeof(int));
+ QByteArray array(6 * sizeof(int), Qt::Uninitialized);
int *ptr = reinterpret_cast<int*>(array.data());
@@ -1222,8 +1235,8 @@ bool QWSOnScreenSurface::isValid() const
QByteArray QWSOnScreenSurface::permanentState() const
{
- QByteArray array;
- array.resize(sizeof(int));
+ QByteArray array(sizeof(int), Qt::Uninitialized);
+
int *ptr = reinterpret_cast<int*>(array.data());
ptr[0] = QApplication::desktop()->screenNumber(window());
return array;
@@ -1263,8 +1276,7 @@ QWSYellowSurface::~QWSYellowSurface()
QByteArray QWSYellowSurface::permanentState() const
{
- QByteArray array;
- array.resize(2 * sizeof(int));
+ QByteArray array(2 * sizeof(int), Qt::Uninitialized);
int *ptr = reinterpret_cast<int*>(array.data());
ptr[0] = surfaceSize.width();
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 634cf00..219b963 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -91,11 +91,8 @@ static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,19,"QVGA Landscape"},
-{320,240,1,19,"QVGA Portrait"},
{360,640,1,19,"NHD Landscape"},
{640,360,1,19,"NHD Portrait"},
-{352,800,1,12,"E90 Landscape"},
{480,640,1,19,"VGA Landscape"}
// *** End of generated data ***
};
@@ -104,11 +101,8 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106},
-{5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106},
{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135},
-{7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106},
{9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184}
// *** End of generated data ***
};
@@ -532,29 +526,14 @@ void QS60StylePrivate::setCurrentLayout(int index)
void QS60StylePrivate::drawPart(QS60StyleEnums::SkinParts skinPart,
QPainter *painter, const QRect &rect, SkinElementFlags flags)
{
- static const bool doCache =
-#if defined(Q_WS_S60)
- // Freezes on 3.1. Anyways, caching is only really needed on touch UI
- !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
-#else
- true;
-#endif
-
- const QPixmap skinPartPixMap((doCache ? cachedPart : part)(skinPart, rect.size(), painter, flags));
+ const QPixmap skinPartPixMap((cachedPart)(skinPart, rect.size(), painter, flags));
if (!skinPartPixMap.isNull())
painter->drawPixmap(rect.topLeft(), skinPartPixMap);
}
void QS60StylePrivate::drawFrame(SkinFrameElements frameElement, QPainter *painter, const QRect &rect, SkinElementFlags flags)
{
- static const bool doCache =
-#if defined(Q_WS_S60)
- // Freezes on 3.1. Anyways, caching is only really needed on touch UI
- !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
-#else
- true;
-#endif
- const QPixmap frameElementPixMap((doCache ? cachedFrame : frame)(frameElement, rect.size(), flags));
+ const QPixmap frameElementPixMap((cachedFrame)(frameElement, rect.size(), flags));
if (!frameElementPixMap.isNull())
painter->drawPixmap(rect.topLeft(), frameElementPixMap);
}
@@ -1040,23 +1019,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
drawPrimitive(PE_FrameFocusRect, optionSlider, painter, widget);*/
//Groove graphics
- if (QS60StylePrivate::hasSliderGrooveGraphic()) {
- const QS60StylePrivate::SkinElements grooveElement = horizontal ?
- QS60StylePrivate::SE_SliderGrooveHorizontal :
- QS60StylePrivate::SE_SliderGrooveVertical;
- QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
- } else {
- const QPoint sliderGrooveCenter = sliderGroove.center();
- const bool horizontal = optionSlider->orientation == Qt::Horizontal;
- painter->save();
- if (widget)
- painter->setPen(widget->palette().windowText().color());
- if (horizontal)
- painter->drawLine(0, sliderGrooveCenter.y(), sliderGroove.right(), sliderGrooveCenter.y());
- else
- painter->drawLine(sliderGrooveCenter.x(), 0, sliderGrooveCenter.x(), sliderGroove.bottom());
- painter->restore();
- }
+ const QS60StylePrivate::SkinElements grooveElement = horizontal ?
+ QS60StylePrivate::SE_SliderGrooveHorizontal :
+ QS60StylePrivate::SE_SliderGrooveVertical;
+ QS60StylePrivate::drawSkinElement(grooveElement, painter, sliderGroove, flags);
//Handle graphics
const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget);
@@ -1155,11 +1121,10 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom
case Qt::UpArrow:
pe = PE_IndicatorArrowUp;
break;
- case Qt::DownArrow:
+ default:
pe = PE_IndicatorArrowDown;
break;
- default:
- break; }
+ }
toolButton.rect = button;
drawPrimitive(pe, &toolButton, painter, widget);
}
@@ -1333,8 +1298,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
const bool isDisabled = !(option->state & State_Enabled);
const bool isFlat = button->features & QStyleOptionButton::Flat;
- QS60StyleEnums::SkinParts skinPart;
- QS60StylePrivate::SkinElements skinElement;
+ QS60StyleEnums::SkinParts skinPart = QS60StyleEnums::SP_QsnFrButtonCenterInactive;
+ QS60StylePrivate::SkinElements skinElement = QS60StylePrivate::SE_ButtonInactive;
if (!isDisabled) {
const bool isPressed = (option->state & State_Sunken) ||
(option->state & State_On);
@@ -1345,11 +1310,6 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
skinElement =
isPressed ? QS60StylePrivate::SE_ButtonPressed : QS60StylePrivate::SE_ButtonNormal;
}
- } else {
- if (isFlat)
- skinPart =QS60StyleEnums::SP_QsnFrButtonCenterInactive;
- else
- skinElement = QS60StylePrivate::SE_ButtonInactive;
}
if (isFlat)
QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
@@ -1485,26 +1445,14 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
checkMarkOption.rect = selectionRect;
// Draw selection mark.
if (isSelected && selectItems) {
- proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
// @todo: this should happen in the rect retrievel i.e. subElementRect()
if (textRect.right() > selectionRect.left())
textRect.setRight(selectionRect.left());
} else if (voptAdj.features & QStyleOptionViewItemV2::HasCheckIndicator) {
checkMarkOption.state = checkMarkOption.state & ~State_HasFocus;
- switch (vopt->checkState) {
- case Qt::Unchecked:
- checkMarkOption.state |= State_Off;
- break;
- case Qt::PartiallyChecked:
- checkMarkOption.state |= State_NoChange;
- break;
- case Qt::Checked:
- checkMarkOption.state |= State_On;
- break;
- }
- drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
}
+ proxy()->drawPrimitive(PE_IndicatorViewItemCheck, &checkMarkOption, painter, widget);
}
// draw the text
@@ -1837,7 +1785,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget);
//draw icon and/or checkState
- QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize),
+ QPixmap pix = menuItem->icon.pixmap(iconRect.width(),
enabled ? QIcon::Normal : QIcon::Disabled);
const bool itemWithIcon = !pix.isNull();
if (itemWithIcon) {
@@ -1985,36 +1933,31 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
if (!tbWidget || (widget && qobject_cast<QToolBar *>(widget->parentWidget())))
break;
- // Normally in S60 5.0+ there is no background for toolbar, but in some cases with versatile QToolBar,
+ // Normally in S60 there is no background for toolbar, but in some cases with versatile QToolBar,
// it looks a bit strange. So, lets fillRect with Button.
- if (!QS60StylePrivate::isToolBarBackground()) {
- QList<QAction *> actions = tbWidget->actions();
- bool justToolButtonsInToolBar = true;
- for (int i = 0; i < actions.size(); ++i) {
- QWidget *childWidget = tbWidget->widgetForAction(actions.at(i));
- const QToolButton *button = qobject_cast<const QToolButton *>(childWidget);
- if (!button){
- justToolButtonsInToolBar = false;
- }
- }
-
- // Draw frame background
- // for vertical toolbars with text only and
- // for toolbars with extension buttons and
- // for toolbars with widgets in them.
- if (!justToolButtonsInToolBar ||
- (tbWidget &&
- (tbWidget->orientation() == Qt::Vertical) &&
- (tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly))) {
- painter->save();
- if (widget)
- painter->setBrush(widget->palette().button());
- painter->setOpacity(0.3);
- painter->fillRect(toolBar->rect, painter->brush());
- painter->restore();
- }
- } else {
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ToolBar, painter, toolBar->rect, flags);
+ QList<QAction *> actions = tbWidget->actions();
+ bool justToolButtonsInToolBar = true;
+ for (int i = 0; i < actions.size(); ++i) {
+ QWidget *childWidget = tbWidget->widgetForAction(actions.at(i));
+ const QToolButton *button = qobject_cast<const QToolButton *>(childWidget);
+ if (!button)
+ justToolButtonsInToolBar = false;
+ }
+
+ // Draw frame background
+ // for vertical toolbars with text only and
+ // for toolbars with extension buttons and
+ // for toolbars with widgets in them.
+ if (!justToolButtonsInToolBar
+ || (tbWidget
+ && tbWidget->orientation() == Qt::Vertical
+ && tbWidget->toolButtonStyle() == Qt::ToolButtonTextOnly)) {
+ painter->save();
+ if (widget)
+ painter->setBrush(widget->palette().button());
+ painter->setOpacity(0.3);
+ painter->fillRect(toolBar->rect, painter->brush());
+ painter->restore();
}
}
break;
@@ -2159,12 +2102,28 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
#ifndef QT_NO_ITEMVIEWS
if (const QAbstractItemView *itemView = (qobject_cast<const QAbstractItemView *>(widget))) {
if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) {
+ QStyleOptionViewItemV4 voptAdj = *vopt;
const bool checkBoxVisible = vopt->features & QStyleOptionViewItemV2::HasCheckIndicator;
const bool singleSelection = itemView->selectionMode() ==
QAbstractItemView::SingleSelection || itemView->selectionMode() == QAbstractItemView::NoSelection;
// draw either checkbox at the beginning
if (checkBoxVisible && singleSelection) {
- drawPrimitive(PE_IndicatorCheckBox, option, painter, widget);
+ if (vopt->features & QStyleOptionViewItemV2::HasCheckIndicator) {
+ switch (vopt->checkState) {
+ case Qt::Unchecked:
+ voptAdj.state |= State_Off;
+ break;
+ case Qt::PartiallyChecked:
+ voptAdj.state |= State_NoChange;
+ break;
+ case Qt::Checked:
+ voptAdj.state |= State_On;
+ break;
+ default:
+ break;
+ }
+ }
+ drawPrimitive(PE_IndicatorCheckBox, &voptAdj, painter, widget);
// ... or normal "tick" selection at the end.
} else if (option->state & State_Selected) {
QRect tickRect = option->rect;
@@ -2226,21 +2185,16 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
break;
#ifndef QT_NO_TOOLBUTTON
case PE_IndicatorArrowDown:
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafScrollArrowDown, painter, option->rect, flags);
+ break;
case PE_IndicatorArrowLeft:
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafScrollArrowLeft, painter, option->rect, flags);
+ break;
case PE_IndicatorArrowRight:
- case PE_IndicatorArrowUp: {
- QS60StyleEnums::SkinParts skinPart;
- if (element==PE_IndicatorArrowDown)
- skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowDown;
- else if (element==PE_IndicatorArrowLeft)
- skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowLeft;
- else if (element==PE_IndicatorArrowRight)
- skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowRight;
- else if (element==PE_IndicatorArrowUp)
- skinPart = QS60StyleEnums::SP_QgnGrafScrollArrowUp;
-
- QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, flags);
- }
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafScrollArrowRight, painter, option->rect, flags);
+ break;
+ case PE_IndicatorArrowUp:
+ QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnGrafScrollArrowUp, painter, option->rect, flags);
break;
#endif //QT_NO_TOOLBUTTON
#ifndef QT_NO_SPINBOX
@@ -2427,52 +2381,46 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_IndicatorBranch:
#if defined(Q_WS_S60)
- // 3.1 AVKON UI does not have tree view component, use common style for drawing there
- if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1) {
-#else
- if (true) {
-#endif
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- } else {
- if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(option)) {
- const bool rightLine = option->state & State_Item;
- const bool downLine = option->state & State_Sibling;
- const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
- QS60StylePrivate::SkinElementFlags adjustedFlags = flags;
-
- QS60StyleEnums::SkinParts skinPart;
- bool drawSkinPart = false;
- if (rightLine && downLine && upLine) {
- skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
- drawSkinPart = true;
- } else if (rightLine && upLine) {
- skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
- drawSkinPart = true;
- } else if (upLine && downLine) {
- skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
- drawSkinPart = true;
- }
+ if (const QStyleOptionViewItemV2 *vopt = qstyleoption_cast<const QStyleOptionViewItemV2 *>(option)) {
+ const bool rightLine = option->state & State_Item;
+ const bool downLine = option->state & State_Sibling;
+ const bool upLine = option->state & (State_Open | State_Children | State_Item | State_Sibling);
+ QS60StylePrivate::SkinElementFlags adjustedFlags = flags;
- if (option->direction == Qt::RightToLeft)
- adjustedFlags |= QS60StylePrivate::SF_Mirrored_X_Axis;
-
- if (drawSkinPart)
- QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, adjustedFlags);
-
- if (option->state & State_Children) {
- QS60StyleEnums::SkinParts skinPart =
- (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
- const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
- const int minDimension = qMin(option->rect.width(), option->rect.height());
- const int magicTweak = (option->direction == Qt::RightToLeft) ? -3 : 3; //@todo: magic
- //The branch indicator icon in S60 is supposed to be superimposed on top of branch lines.
- QRect iconRect(QPoint(option->rect.left() + magicTweak, selectionRect.top() + 1), QSize(minDimension, minDimension));
- if (!QS60StylePrivate::isTouchSupported())
- iconRect.translate(0, -4); //@todo: magic
- QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, adjustedFlags);
- }
+ QS60StyleEnums::SkinParts skinPart;
+ bool drawSkinPart = false;
+ if (rightLine && downLine && upLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineBranch;
+ drawSkinPart = true;
+ } else if (rightLine && upLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineEnd;
+ drawSkinPart = true;
+ } else if (upLine && downLine) {
+ skinPart = QS60StyleEnums::SP_QgnIndiHlLineStraight;
+ drawSkinPart = true;
+ }
+
+ if (option->direction == Qt::RightToLeft)
+ adjustedFlags |= QS60StylePrivate::SF_Mirrored_X_Axis;
+
+ if (drawSkinPart)
+ QS60StylePrivate::drawSkinPart(skinPart, painter, option->rect, adjustedFlags);
+
+ if (option->state & State_Children) {
+ QS60StyleEnums::SkinParts skinPart =
+ (option->state & State_Open) ? QS60StyleEnums::SP_QgnIndiHlColSuper : QS60StyleEnums::SP_QgnIndiHlExpSuper;
+ const QRect selectionRect = subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
+ const int minDimension = qMin(option->rect.width(), option->rect.height());
+ const int magicTweak = (option->direction == Qt::RightToLeft) ? -3 : 3;
+ //The branch indicator icon in S60 is supposed to be superimposed on top of branch lines.
+ QRect iconRect(QPoint(option->rect.left() + magicTweak, selectionRect.top() + 1), QSize(minDimension, minDimension));
+ iconRect.translate(0, -4);
+ QS60StylePrivate::drawSkinPart(skinPart, painter, iconRect, adjustedFlags);
}
}
+#else
+ QCommonStyle::drawPrimitive(element, option, painter, widget);
+#endif
break;
case PE_PanelItemViewRow: // ### Qt 5: remove
#ifndef QT_NO_ITEMVIEWS
@@ -2494,10 +2442,7 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti
case PE_PanelScrollAreaCorner:
break;
case PE_IndicatorItemViewItemDrop:
- if (QS60StylePrivate::isTouchSupported())
- QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DropArea, painter, option->rect, flags);
- else
- commonStyleDraws = true;
+ QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_DropArea, painter, option->rect, flags);
break;
// todo: items are below with #ifdefs "just in case". in final version, remove all non-required cases
case PE_FrameLineEdit:
@@ -2673,13 +2618,11 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
}
}
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
- if (QS60StylePrivate::isTouchSupported()) {
- //Make itemview easier to use in touch devices
- sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
- //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
- if (ct == CT_MenuItem)
- sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values
- }
+ //Make itemview easier to use in touch devices
+ sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin));
+ //QCommonStyle does not adjust height with horizontal margin, it only adjusts width
+ if (ct == CT_MenuItem)
+ sz.setHeight(sz.height() - 8); //QCommonstyle adds 8 to height that this style handles through PM values
break;
#ifndef QT_NO_COMBOBOX
case CT_ComboBox: {
@@ -3313,8 +3256,7 @@ void QS60Style::polish(QApplication *application)
QCommonStyle::polish(qApp);
d->m_originalPalette = application->palette();
d->setThemePalette(application);
- if (QS60StylePrivate::isTouchSupported())
- qApp->installEventFilter(this);
+ qApp->installEventFilter(this);
}
/*!
@@ -3329,8 +3271,7 @@ void QS60Style::unpolish(QApplication *application)
const QPalette newPalette = QApplication::style()->standardPalette();
QApplication::setPalette(newPalette);
QApplicationPrivate::setSystemPalette(d->m_originalPalette);
- if (QS60StylePrivate::isTouchSupported())
- qApp->removeEventFilter(this);
+ qApp->removeEventFilter(this);
}
/*!
@@ -3341,11 +3282,10 @@ bool QS60Style::event(QEvent *e)
#ifdef QT_KEYPAD_NAVIGATION
Q_D(QS60Style);
const QEvent::Type eventType = e->type();
- if ((eventType == QEvent::FocusIn ||
- eventType == QEvent::FocusOut ||
- eventType == QEvent::EnterEditFocus ||
- eventType == QEvent::LeaveEditFocus) &&
- QS60StylePrivate::isTouchSupported())
+ if (eventType == QEvent::FocusIn
+ || eventType == QEvent::FocusOut
+ || eventType == QEvent::EnterEditFocus
+ || eventType == QEvent::LeaveEditFocus)
return false;
#endif
diff --git a/src/gui/styles/qs60style_feedbackinterface_p.h b/src/gui/styles/qs60style_feedbackinterface_p.h
new file mode 100644
index 0000000..81fcdc3
--- /dev/null
+++ b/src/gui/styles/qs60style_feedbackinterface_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QObject>
+
+class TactileFeedbackInterface : public QObject
+{
+ public:
+ virtual void touchFeedback(QEvent *event, const QWidget *widget) = 0;
+};
+
+Q_DECLARE_INTERFACE(TactileFeedbackInterface, "com.trolltech.Qt.TactileFeedbackInterface/1.0")
diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h
index ee981c0..1cf069b 100644
--- a/src/gui/styles/qs60style_p.h
+++ b/src/gui/styles/qs60style_p.h
@@ -516,9 +516,6 @@ public:
void setBackgroundTexture(QApplication *application) const;
static void deleteBackground();
- static bool isTouchSupported();
- static bool isToolBarBackground();
- static bool hasSliderGrooveGraphic();
static bool isSingleClickUi();
static bool isWidgetPressed(const QWidget *widget);
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index f272ff4..58d70a4 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -579,7 +579,6 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
const TAknsItemID skinId = m_partMap[stylepartIndex].skinID;
TInt fallbackGraphicID = -1;
- HBufC* iconFile = HBufC::NewLC( KMaxFileName );
fallbackInfo(stylepart, fallbackGraphicID);
TAknsItemID colorGroup = KAknsIIDQsnIconColors;
@@ -613,7 +612,7 @@ QPixmap QS60StyleModeSpecifics::colorSkinnedGraphicsLX(
defaultColor);
QPixmap result = fromFbsBitmap(icon, iconMask, flags, targetSize);
- CleanupStack::PopAndDestroy(3); //icon, iconMask, iconFile
+ CleanupStack::PopAndDestroy(2); //icon, iconMask
return result;
}
@@ -693,21 +692,6 @@ QPixmap QS60StyleModeSpecifics::fromFbsBitmap(CFbsBitmap *icon, CFbsBitmap *mask
return pixmap;
}
-bool QS60StylePrivate::isTouchSupported()
-{
- return bool(AknLayoutUtils::PenEnabled());
-}
-
-bool QS60StylePrivate::isToolBarBackground()
-{
- return (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2);
-}
-
-bool QS60StylePrivate::hasSliderGrooveGraphic()
-{
- return QSysInfo::s60Version() != QSysInfo::SV_S60_3_1;
-}
-
bool QS60StylePrivate::isSingleClickUi()
{
return (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0);
@@ -1068,20 +1052,8 @@ void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameEleme
switch(frameElement) {
case QS60StylePrivate::SF_ToolTip:
- if (QSysInfo::s60Version() != QSysInfo::SV_S60_3_1) {
- centerId.Set(EAknsMajorGeneric, 0x19c2);
- frameId.Set(EAknsMajorSkin, 0x5300);
- } else {
- centerId.Set(KAknsIIDQsnFrPopupCenter);
- frameId.iMinor = centerId.iMinor - 9;
- }
- break;
- case QS60StylePrivate::SF_ToolBar:
- if (QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version() == QSysInfo::SV_S60_3_2) {
- centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
- frameId.Set(KAknsIIDQsnFrPopupSub);
- }
+ centerId.Set(EAknsMajorGeneric, 0x19c2);
+ frameId.Set(EAknsMajorSkin, 0x5300);
break;
case QS60StylePrivate::SF_PopupBackground:
centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
@@ -1223,10 +1195,7 @@ void QS60StylePrivate::setActiveLayout()
//not found, lets try with either of dimensions
if (activeLayoutIndex==-1){
- const QSysInfo::S60Version currentRelease = QSysInfo::s60Version();
const bool landscape = screenHeight < screenWidth;
-
- activeLayoutIndex = (currentRelease == QSysInfo::SV_S60_3_1 || currentRelease == QSysInfo::SV_S60_3_2) ? 0 : 2;
activeLayoutIndex += (!landscape) ? 1 : 0;
}
@@ -1282,9 +1251,7 @@ bool QS60StyleModeSpecifics::disabledPartGraphic(QS60StyleEnums::SkinParts &part
case QS60StyleEnums::SP_QsnFrButtonSideLInactive:
case QS60StyleEnums::SP_QsnFrButtonSideRInactive:
case QS60StyleEnums::SP_QsnFrButtonCenterInactive:
- if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
- disabledGraphic = true;
+ disabledGraphic = true;
break;
default:
break;
@@ -1300,9 +1267,7 @@ bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameEle
switch(frame){
// inactive button graphics are available from 5.0 onwards
case QS60StylePrivate::SF_ButtonInactive:
- if (!(QSysInfo::s60Version()==QSysInfo::SV_S60_3_1 ||
- QSysInfo::s60Version()==QSysInfo::SV_S60_3_2))
- disabledGraphic = true;
+ disabledGraphic = true;
break;
default:
break;
@@ -1313,9 +1278,6 @@ bool QS60StyleModeSpecifics::disabledFrameGraphic(QS60StylePrivate::SkinFrameEle
QPixmap QS60StyleModeSpecifics::generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part,
const QSize &size, QS60StylePrivate::SkinElementFlags flags)
{
- if (!QS60StylePrivate::isTouchSupported())
- return QPixmap();
-
QS60StyleEnums::SkinParts updatedPart = part;
switch(part){
// AVKON UI has a abnormal handling for scrollbar graphics. It is possible that the root
@@ -1541,7 +1503,7 @@ QVariant QS60StyleModeSpecifics::themeDefinition(
//Animation definitions
case QS60StyleEnums::TD_AnimationData:
{
- CAknsBmpAnimItemData *animationData;
+ CAknsBmpAnimItemData *animationData = 0;
TAknsItemID animationSkinId = partSpecificThemeId(part);
QList<QVariant> list;
@@ -1557,9 +1519,6 @@ QVariant QS60StyleModeSpecifics::themeDefinition(
QS60StyleEnums::AnimationMode playMode;
switch(animationData->PlayMode()) {
- case CBitmapAnimClientData::EPlay:
- playMode = QS60StyleEnums::AM_PlayOnce;
- break;
case CBitmapAnimClientData::ECycle:
playMode = QS60StyleEnums::AM_Looping;
break;
@@ -1567,6 +1526,7 @@ QVariant QS60StyleModeSpecifics::themeDefinition(
playMode = QS60StyleEnums::AM_Bounce;
break;
default:
+ playMode = QS60StyleEnums::AM_PlayOnce;
break;
}
list.append(QVariant((int)playMode));
diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp
index ca02cdf..d0789a8 100644
--- a/src/gui/styles/qs60style_simulated.cpp
+++ b/src/gui/styles/qs60style_simulated.cpp
@@ -318,25 +318,6 @@ QPixmap QS60StylePrivate::backgroundTexture(bool /*skipCreation*/)
return *m_background;
}
-bool QS60StylePrivate::isTouchSupported()
-{
-#ifdef QT_KEYPAD_NAVIGATION
- return !QApplication::keypadNavigationEnabled();
-#else
- return true;
-#endif
-}
-
-bool QS60StylePrivate::isToolBarBackground()
-{
- return true;
-}
-
-bool QS60StylePrivate::hasSliderGrooveGraphic()
-{
- return false;
-}
-
bool QS60StylePrivate::isSingleClickUi()
{
return false;
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 90dd029..d4c81b9 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -348,6 +348,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::FamilyResolved))
request.family = other->request.family;
+ if (! (mask & QFont::StyleNameResolved))
+ request.styleName = other->request.styleName;
+
if (! (mask & QFont::SizeResolved)) {
request.pointSize = other->request.pointSize;
request.pixelSize = other->request.pixelSize;
@@ -897,6 +900,38 @@ void QFont::setFamily(const QString &family)
}
/*!
+ \since 4.8
+
+ Returns the requested font style name, it will be used to match the
+ font with irregular styles (that can't be normalized in other style
+ properties). It depends on system font support, thus only works for
+ Mac OS X and X11 so far. On Windows irregular styles will be added
+ as separate font families so there is no need for this.
+
+ \sa setFamily() setStyle()
+*/
+QString QFont::styleName() const
+{
+ return d->request.styleName;
+}
+
+/*!
+ \since 4.8
+
+ Sets the style name of the font. When set, other style properties
+ like \a style() and \a weight() will be ignored for font matching.
+
+ \sa styleName()
+*/
+void QFont::setStyleName(const QString &styleName)
+{
+ detach();
+
+ d->request.styleName = styleName;
+ resolve_mask |= QFont::StyleNameResolved;
+}
+
+/*!
Returns the point size of the font. Returns -1 if the font size
was specified in pixels.
@@ -2509,6 +2544,21 @@ QString QFontInfo::family() const
}
/*!
+ \since 4.8
+
+ Returns the style name of the matched window system font on
+ system that supports it.
+
+ \sa QFont::styleName()
+*/
+QString QFontInfo::styleName() const
+{
+ QFontEngine *engine = d->engineForScript(QUnicodeTables::Common);
+ Q_ASSERT(engine != 0);
+ return engine->fontDef.styleName;
+}
+
+/*!
Returns the point size of the matched window system font.
\sa pointSizeF() QFont::pointSize()
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 7636ecf..14f290c 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -156,7 +156,8 @@ public:
LetterSpacingResolved = 0x2000,
WordSpacingResolved = 0x4000,
HintingPreferenceResolved = 0x8000,
- AllPropertiesResolved = 0xffff
+ StyleNameResolved = 0x10000,
+ AllPropertiesResolved = 0x1ffff
};
QFont();
@@ -168,6 +169,9 @@ public:
QString family() const;
void setFamily(const QString &);
+ QString styleName() const;
+ void setStyleName(const QString &);
+
int pointSize() const;
void setPointSize(int);
qreal pointSizeF() const;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d36518e..8eeae6f 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -80,6 +80,7 @@ struct QFontDef
}
QString family;
+ QString styleName;
#ifdef Q_WS_X11
QString addStyle;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 7a8a912..98186df 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -879,10 +879,10 @@ QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteA
TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
if (os2) {
quint32 unicodeRange[4] = {
- os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
+ static_cast<quint32>(os2->ulUnicodeRange1), static_cast<quint32>(os2->ulUnicodeRange2), static_cast<quint32>(os2->ulUnicodeRange3), static_cast<quint32>(os2->ulUnicodeRange4)
};
quint32 codePageRange[2] = {
- os2->ulCodePageRange1, os2->ulCodePageRange2
+ static_cast<quint32>(os2->ulCodePageRange1), static_cast<quint32>(os2->ulCodePageRange2)
};
writingSystems = qt_determine_writing_systems_from_truetype_bits(unicodeRange, codePageRange);
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index 6fdaf06..724dbf6 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -249,6 +249,63 @@ static inline float weightToFloat(unsigned int weight)
return (weight - 50) / 100.0;
}
+static QFontEngine *loadFromDatabase(const QFontDef &req, const QFontPrivate *d)
+{
+#if defined(QT_MAC_USE_COCOA)
+ QCFString fontName = NULL;
+#else
+ ATSFontFamilyRef familyRef = 0;
+ ATSFontRef fontRef = 0;
+#endif
+
+ QStringList family_list = familyList(req);
+
+ const char *stylehint = styleHint(req);
+ if (stylehint)
+ family_list << QLatin1String(stylehint);
+
+ // add QFont::defaultFamily() to the list, for compatibility with previous versions
+ family_list << QApplication::font().defaultFamily();
+
+ QMutexLocker locker(fontDatabaseMutex());
+ QFontDatabasePrivate *db = privateDb();
+ if (!db->count)
+ initializeDb();
+ for (int i = 0; i < family_list.size(); ++i) {
+ for (int k = 0; k < db->count; ++k) {
+ if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
+ QByteArray family_name = db->families[k]->name.toUtf8();
+#if defined(QT_MAC_USE_COCOA)
+ QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
+ if (ctFont) {
+ fontName = CTFontCopyFullName(ctFont);
+ goto found;
+ }
+#else
+ familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
+ if (familyRef) {
+ fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
+ goto found;
+ }
+#endif
+ }
+ }
+ }
+found:
+#ifdef QT_MAC_USE_COCOA
+ if (fontName)
+ return new QCoreTextFontEngineMulti(fontName, req, d->kerning);
+#else
+ if (familyRef) {
+ QCFString actualName;
+ if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
+ req.family = actualName;
+ return new QFontEngineMacMulti(familyRef, req, fontDef, d->kerning);
+ }
+#endif
+ return NULL;
+}
+
void QFontDatabase::load(const QFontPrivate *d, int script)
{
// sanity checks
@@ -289,69 +346,38 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
return; // the font info and fontdef should already be filled
}
- //find the font
- QStringList family_list = familyList(req);
-
- const char *stylehint = styleHint(req);
- if (stylehint)
- family_list << QLatin1String(stylehint);
-
- // add QFont::defaultFamily() to the list, for compatibility with
- // previous versions
- family_list << QApplication::font().defaultFamily();
-
+ QFontEngine *engine = NULL;
#if defined(QT_MAC_USE_COCOA)
- QCFString fontName = NULL, familyName = NULL;
-#else
- ATSFontFamilyRef familyRef = 0;
- ATSFontRef fontRef = 0;
-#endif
-
- QMutexLocker locker(fontDatabaseMutex());
- QFontDatabasePrivate *db = privateDb();
- if (!db->count)
- initializeDb();
- for(int i = 0; i < family_list.size(); ++i) {
- for (int k = 0; k < db->count; ++k) {
- if (db->families[k]->name.compare(family_list.at(i), Qt::CaseInsensitive) == 0) {
- QByteArray family_name = db->families[k]->name.toUtf8();
-#if defined(QT_MAC_USE_COCOA)
- QCFType<CTFontRef> ctFont = CTFontCreateWithName(QCFString(db->families[k]->name), 12, NULL);
- if (ctFont) {
- fontName = CTFontCopyFullName(ctFont);
- familyName = CTFontCopyFamilyName(ctFont);
- goto FamilyFound;
- }
-#else
- familyRef = ATSFontFamilyFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- if (familyRef) {
- fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
- goto FamilyFound;
- }
-#endif
+ // Shortcut to get the font directly without going through the font database
+ if (!req.family.isEmpty() && !req.styleName.isEmpty()) {
+ QCFString expectedFamily = QCFString(req.family);
+ QCFString expectedStyle = QCFString(req.styleName);
+
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, expectedFamily);
+ CFDictionaryAddValue(attributes, kCTFontStyleNameAttribute, expectedStyle);
+
+ QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ CGAffineTransform transform = qt_transform_from_fontdef(req);
+ QCFType<CTFontRef> ctFont = CTFontCreateWithFontDescriptor(descriptor, req.pixelSize, &transform);
+ if (ctFont) {
+ QCFString familyName = CTFontCopyFamilyName(ctFont);
+ // Only accept the font if the family name is exactly the same as we specified
+ if (CFEqual(expectedFamily, familyName)) {
+ engine = new QCoreTextFontEngineMulti(ctFont, req, d->kerning);
}
}
}
-FamilyFound:
- //fill in the engine's font definition
- QFontDef fontDef = d->request; //copy..
- if(fontDef.pointSize < 0)
- fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi);
- else
- fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi);
-
-#ifdef QT_MAC_USE_COCOA
- fontDef.family = familyName;
- QFontEngine *engine = new QCoreTextFontEngineMulti(fontName, fontDef, d->kerning);
-#else
- QCFString actualName;
- if (ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr)
- fontDef.family = actualName;
- QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning);
#endif
- d->engineData->engine = engine;
- engine->ref.ref(); //a ref for the engineData->engine
- QFontCache::instance()->insertEngine(key, engine);
+ if (!engine)
+ engine = loadFromDatabase(req, d);
+
+ if (engine) {
+ d->engineData->engine = engine;
+ engine->ref.ref();
+ QFontCache::instance()->insertEngine(key, engine);
+ }
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp
index c5a04f1..c83e929 100644
--- a/src/gui/text/qfontdatabase_qws.cpp
+++ b/src/gui/text/qfontdatabase_qws.cpp
@@ -759,9 +759,6 @@ bool QFontDatabase::supportsThreadedFontRendering()
return true;
}
-/*!
- \internal
-*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
const QFontDef &request)
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index 8a13d91..754334c 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -1452,6 +1452,35 @@ static const char *styleHint(const QFontDef &request)
void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontDef &request)
{
+ double size_value = qMax(qreal(1.), request.pixelSize);
+ FcPatternDel(pattern, FC_PIXEL_SIZE);
+ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
+
+ if (X11->display && QX11Info::appDepth(screen) <= 8) {
+ FcPatternDel(pattern, FC_ANTIALIAS);
+ // can't do antialiasing on 8bpp
+ FcPatternAddBool(pattern, FC_ANTIALIAS, false);
+ } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
+ FcPatternDel(pattern, FC_ANTIALIAS);
+ FcPatternAddBool(pattern, FC_ANTIALIAS,
+ !(request.styleStrategy & QFont::NoAntialias));
+ }
+
+ if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
+ Q_ASSERT(script < QUnicodeTables::ScriptCount);
+ FcLangSet *ls = FcLangSetCreate();
+ FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
+ FcPatternDel(pattern, FC_LANG);
+ FcPatternAddLangSet(pattern, FC_LANG, ls);
+ FcLangSetDestroy(ls);
+ }
+
+ if (!request.styleName.isEmpty()) {
+ QByteArray cs = request.styleName.toUtf8();
+ FcPatternAddString(pattern, FC_STYLE, (const FcChar8 *) cs.constData());
+ return;
+ }
+
int weight_value = FC_WEIGHT_BLACK;
if (request.weight == 0)
weight_value = FC_WEIGHT_MEDIUM;
@@ -1474,34 +1503,11 @@ void qt_addPatternProps(FcPattern *pattern, int screen, int script, const QFontD
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, slant_value);
- double size_value = qMax(qreal(1.), request.pixelSize);
- FcPatternDel(pattern, FC_PIXEL_SIZE);
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
-
int stretch = request.stretch;
if (!stretch)
stretch = 100;
FcPatternDel(pattern, FC_WIDTH);
FcPatternAddInteger(pattern, FC_WIDTH, stretch);
-
- if (X11->display && QX11Info::appDepth(screen) <= 8) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- // can't do antialiasing on 8bpp
- FcPatternAddBool(pattern, FC_ANTIALIAS, false);
- } else if (request.styleStrategy & (QFont::PreferAntialias|QFont::NoAntialias)) {
- FcPatternDel(pattern, FC_ANTIALIAS);
- FcPatternAddBool(pattern, FC_ANTIALIAS,
- !(request.styleStrategy & QFont::NoAntialias));
- }
-
- if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
- Q_ASSERT(script < QUnicodeTables::ScriptCount);
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternDel(pattern, FC_LANG);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- }
}
static bool preferScalable(const QFontDef &request)
@@ -1996,6 +2002,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QFontCache::instance()->insertEngine(key, fe);
}
+// Needed for fontconfig version < 2.2.97
+#ifndef FC_FAMILYLANG
+#define FC_FAMILYLANG "familylang"
+#endif
+
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
#if defined(QT_NO_FONTCONFIG)
@@ -2044,7 +2055,8 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
return;
FcPatternDel(pattern, FC_FILE);
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *)fnt->fileName.toUtf8().constData());
+ QByteArray cs = fnt->fileName.toUtf8();
+ FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
FcChar8 *fam = 0, *familylang = 0;
int i, n = 0;
@@ -2130,7 +2142,8 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
if (!pattern)
return family;
- FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) family.toUtf8().data());
+ QByteArray cs = family.toUtf8();
+ FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
FcConfigSubstitute(0, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm
index 24bd750..64b8682 100644
--- a/src/gui/text/qfontengine_coretext.mm
+++ b/src/gui/text/qfontengine_coretext.mm
@@ -100,7 +100,12 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const
QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform);
- ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits);
+ ctfont = NULL;
+ // There is a side effect in Core Text: if we apply 0 as symbolic traits to a font in normal weight,
+ // we will get the light version of that font (while the way supposed to work doesn't:
+ // setting kCTFontWeightTrait to some value between -1.0 to 0.0 has no effect on font selection)
+ if (fontDef.weight != QFont::Normal || symbolicTraits)
+ ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits);
// CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
// not exist for the given font. (for example italic)
@@ -111,17 +116,11 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const
init(kerning);
}
-QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning)
+QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CTFontRef ctFontRef, 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);
+ ctfont = (CTFontRef) CFRetain(ctFontRef);
init(kerning);
}
@@ -144,6 +143,9 @@ void QCoreTextFontEngineMulti::init(bool kerning)
}
QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef);
+ fontDef.family = fe->fontDef.family;
+ fontDef.styleName = fe->fontDef.styleName;
+ transform = fe->transform;
fe->ref.ref();
engines.append(fe);
}
@@ -400,7 +402,7 @@ void QCoreTextFontEngineMulti::loadEngine(int)
extern int qt_antialiasing_threshold; // from qapplication.cpp
-static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef)
+CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)
{
CGAffineTransform transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100)
@@ -411,7 +413,7 @@ static inline CGAffineTransform transformFromFontDef(const QFontDef &fontDef)
QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
{
fontDef = def;
- transform = transformFromFontDef(fontDef);
+ transform = qt_transform_from_fontdef(fontDef);
ctfont = font;
CFRetain(ctfont);
cgFont = CTFontCopyGraphicsFont(font, NULL);
@@ -421,7 +423,7 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def)
{
fontDef = def;
- transform = transformFromFontDef(fontDef);
+ transform = qt_transform_from_fontdef(fontDef);
cgFont = font;
// Keep reference count balanced
CFRetain(cgFont);
@@ -459,6 +461,9 @@ void QCoreTextFontEngine::init()
QCFString family = CTFontCopyFamilyName(ctfont);
fontDef.family = family;
+ QCFString styleName = (CFStringRef) CTFontCopyAttribute(ctfont, kCTFontStyleNameAttribute);
+ fontDef.styleName = styleName;
+
synthesisFlags = 0;
CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
if (traits & kCTFontItalicTrait)
@@ -725,10 +730,10 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
}
}
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int /*margin*/, bool aa)
+QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool aa)
{
const glyph_metrics_t br = boundingBox(glyph);
- QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32);
+ QImage im(qRound(br.width) + margin * 2, qRound(br.height) + margin * 2, QImage::Format_RGB32);
im.fill(0);
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
@@ -740,9 +745,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
8, im.bytesPerLine(), colorspace,
cgflags);
CGContextSetFontSize(ctx, fontDef.pixelSize);
- CGContextSetShouldAntialias(ctx, aa ||
- (fontDef.pointSize > qt_antialiasing_threshold
- && !(fontDef.styleStrategy & QFont::NoAntialias)));
+ CGContextSetShouldAntialias(ctx, (aa || fontDef.pointSize > qt_antialiasing_threshold)
+ && !(fontDef.styleStrategy & QFont::NoAntialias));
CGContextSetShouldSmoothFonts(ctx, aa);
CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
@@ -760,8 +764,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition
CGContextSetFont(ctx, cgFont);
- qreal pos_x = -br.x.toReal() + subPixelPosition.toReal();
- qreal pos_y = im.height() + br.y.toReal() - 1;
+ qreal pos_x = -br.x.toReal() + subPixelPosition.toReal() + margin;
+ qreal pos_y = im.height() + br.y.toReal() - margin;
CGContextSetTextPosition(ctx, pos_x, pos_y);
CGSize advance;
diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h
index 98d3b50..3ca8a0a 100644
--- a/src/gui/text/qfontengine_coretext_p.h
+++ b/src/gui/text/qfontengine_coretext_p.h
@@ -113,7 +113,7 @@ class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
- QCoreTextFontEngineMulti(CGFontRef cgFontRef, const QFontDef &fontDef, bool kerning);
+ QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
@@ -141,6 +141,8 @@ private:
friend class QFontDialogPrivate;
};
+CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
+
#endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
#endif // QFONTENGINE_CORETEXT_P_H
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index f514942..9a5d9d6 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -758,6 +758,8 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
}
#endif
+ fontDef.styleName = QString::fromUtf8(face->style_name);
+
unlockFace();
fsType = freetype->fsType();
@@ -795,7 +797,7 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
if (set && set->outline_drawing)
load_flags = FT_LOAD_NO_BITMAP;
- if (default_hint_style == HintNone || (flags & HB_ShaperFlag_UseDesignMetrics))
+ if (default_hint_style == HintNone || (flags & HB_ShaperFlag_UseDesignMetrics) || set->outline_drawing)
load_flags |= FT_LOAD_NO_HINTING;
else
load_flags |= load_target;
@@ -1751,7 +1753,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
} else {
glyphSet = &defaultGlyphSet;
}
- bool needsDelete = false;
Glyph * g = glyphSet->getGlyph(glyph);
if (!g || g->format != format) {
face = lockFace();
@@ -1759,7 +1760,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
FT_Matrix_Multiply(&glyphSet->transformationMatrix, &m);
freetype->matrix = m;
g = loadGlyph(glyphSet, glyph, subPixelPosition, format);
- needsDelete = true;
}
if (g) {
@@ -1768,8 +1768,6 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
overall.width = g->width;
overall.height = g->height;
overall.xoff = g->advance;
- if (needsDelete)
- delete g;
} else {
int left = FLOOR(face->glyph->metrics.horiBearingX);
int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index 0997048..e3bfa5d 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -1205,7 +1205,9 @@ QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const
delete fe;
return 0;
} else {
+#ifndef QT_NO_XRENDER
fe->xglyph_format = xglyph_format;
+#endif
return fe;
}
}
diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h
index 1238cba..37a724e 100644
--- a/src/gui/text/qfontinfo.h
+++ b/src/gui/text/qfontinfo.h
@@ -61,6 +61,7 @@ public:
QFontInfo &operator=(const QFontInfo &);
QString family() const;
+ QString styleName() const;
int pixelSize() const;
int pointSize() const;
qreal pointSizeF() const;
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 195bd78..9e1646f 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -1329,8 +1329,10 @@ bool QFontMetricsF::inFont(QChar ch) const
}
/*!
- Returns true if the character encoded in UCS-4/UTF-32 is a valid
- character in the font; otherwise returns false.
+ \fn bool QFontMetricsF::inFontUcs4(uint ch) const
+
+ Returns true if the character given by \a ch, encoded in UCS-4/UTF-32,
+ is a valid character in the font; otherwise returns false.
*/
bool QFontMetricsF::inFontUcs4(uint ucs4) const
{
diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp
index 05e3b6b..2865d91 100644
--- a/src/gui/text/qglyphrun.cpp
+++ b/src/gui/text/qglyphrun.cpp
@@ -132,13 +132,27 @@ QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other)
*/
bool QGlyphRun::operator==(const QGlyphRun &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->rawFont == other.d->rawFont));
+ if (d == other.d)
+ return true;
+
+ if ((d->glyphIndexDataSize != other.d->glyphIndexDataSize)
+ || (d->glyphPositionDataSize != other.d->glyphPositionDataSize)) {
+ return false;
+ }
+
+ for (int i=0; i<qMax(d->glyphIndexDataSize, d->glyphPositionDataSize); ++i) {
+ if (i < d->glyphIndexDataSize && d->glyphIndexData[i] != other.d->glyphIndexData[i])
+ return false;
+
+ if (i < d->glyphPositionDataSize && d->glyphPositionData[i] != other.d->glyphPositionData[i])
+ return false;
+ }
+
+
+ return (d->overline == other.d->overline
+ && d->underline == other.d->underline
+ && d->strikeOut == other.d->strikeOut
+ && d->rawFont == other.d->rawFont);
}
/*!
@@ -151,36 +165,6 @@ bool QGlyphRun::operator!=(const QGlyphRun &other) const
}
/*!
- \internal
-
- Adds together the lists of glyph indexes and positions in \a other and this QGlyphRun
- object and returns the result. The font in the returned QGlyphRun will be the same as in
- this QGlyphRun object.
-*/
-QGlyphRun QGlyphRun::operator+(const QGlyphRun &other) const
-{
- QGlyphRun ret(*this);
- ret += other;
- return ret;
-}
-
-/*!
- \internal
-
- Appends the glyph indexes and positions in \a other to this QGlyphRun object and returns
- a reference to the current object.
-*/
-QGlyphRun &QGlyphRun::operator+=(const QGlyphRun &other)
-{
- detach();
-
- d->glyphIndexes += other.d->glyphIndexes;
- d->glyphPositions += other.d->glyphPositions;
-
- return *this;
-}
-
-/*!
Returns the font selected for this QGlyphRun object.
\sa setRawFont()
@@ -208,7 +192,13 @@ void QGlyphRun::setRawFont(const QRawFont &rawFont)
*/
QVector<quint32> QGlyphRun::glyphIndexes() const
{
- return d->glyphIndexes;
+ if (d->glyphIndexes.constData() == d->glyphIndexData) {
+ return d->glyphIndexes;
+ } else {
+ QVector<quint32> indexes(d->glyphIndexDataSize);
+ qMemCopy(indexes.data(), d->glyphIndexData, d->glyphIndexDataSize * sizeof(quint32));
+ return indexes;
+ }
}
/*!
@@ -218,7 +208,9 @@ QVector<quint32> QGlyphRun::glyphIndexes() const
void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes)
{
detach();
- d->glyphIndexes = glyphIndexes;
+ d->glyphIndexes = glyphIndexes; // Keep a reference to the QVector to avoid copying
+ d->glyphIndexData = glyphIndexes.constData();
+ d->glyphIndexDataSize = glyphIndexes.size();
}
/*!
@@ -226,7 +218,14 @@ void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes)
*/
QVector<QPointF> QGlyphRun::positions() const
{
- return d->glyphPositions;
+ if (d->glyphPositions.constData() == d->glyphPositionData) {
+ return d->glyphPositions;
+ } else {
+ QVector<QPointF> glyphPositions(d->glyphPositionDataSize);
+ qMemCopy(glyphPositions.data(), d->glyphPositionData,
+ d->glyphPositionDataSize * sizeof(QPointF));
+ return glyphPositions;
+ }
}
/*!
@@ -236,7 +235,9 @@ QVector<QPointF> QGlyphRun::positions() const
void QGlyphRun::setPositions(const QVector<QPointF> &positions)
{
detach();
- d->glyphPositions = positions;
+ d->glyphPositions = positions; // Keep a reference to the vector to avoid copying
+ d->glyphPositionData = positions.constData();
+ d->glyphPositionDataSize = positions.size();
}
/*!
@@ -245,12 +246,33 @@ void QGlyphRun::setPositions(const QVector<QPointF> &positions)
void QGlyphRun::clear()
{
detach();
- d->glyphPositions = QVector<QPointF>();
- d->glyphIndexes = QVector<quint32>();
d->rawFont = QRawFont();
d->strikeOut = false;
d->overline = false;
d->underline = false;
+
+ setPositions(QVector<QPointF>());
+ setGlyphIndexes(QVector<quint32>());
+}
+
+/*!
+ Sets the glyph indexes and positions of this QGlyphRun to use the first \a size
+ elements in the arrays \a glyphIndexArray and \a glyphPositionArray. The data is
+ \e not copied. The caller must guarantee that the arrays are not deleted as long
+ as this QGlyphRun and any copies of it exists.
+
+ \sa setGlyphIndexes(), setPositions()
+*/
+void QGlyphRun::setRawData(const quint32 *glyphIndexArray, const QPointF *glyphPositionArray,
+ int size)
+{
+ detach();
+ d->glyphIndexes.clear();
+ d->glyphPositions.clear();
+
+ d->glyphIndexData = glyphIndexArray;
+ d->glyphPositionData = glyphPositionArray;
+ d->glyphIndexDataSize = d->glyphPositionDataSize = size;
}
/*!
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index e43f1ef..cf407a8 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -66,6 +66,10 @@ public:
QRawFont rawFont() const;
void setRawFont(const QRawFont &rawFont);
+ void setRawData(const quint32 *glyphIndexArray,
+ const QPointF *glyphPositionArray,
+ int size);
+
QVector<quint32> glyphIndexes() const;
void setGlyphIndexes(const QVector<quint32> &glyphIndexes);
diff --git a/src/gui/text/qglyphrun_p.h b/src/gui/text/qglyphrun_p.h
index 533679d..a7745e6 100644
--- a/src/gui/text/qglyphrun_p.h
+++ b/src/gui/text/qglyphrun_p.h
@@ -71,6 +71,10 @@ public:
: overline(false)
, underline(false)
, strikeOut(false)
+ , glyphIndexData(glyphIndexes.constData())
+ , glyphIndexDataSize(0)
+ , glyphPositionData(glyphPositions.constData())
+ , glyphPositionDataSize(0)
{
}
@@ -82,6 +86,10 @@ public:
, overline(other.overline)
, underline(other.underline)
, strikeOut(other.strikeOut)
+ , glyphIndexData(other.glyphIndexData)
+ , glyphIndexDataSize(other.glyphIndexDataSize)
+ , glyphPositionData(other.glyphPositionData)
+ , glyphPositionDataSize(other.glyphPositionDataSize)
{
}
@@ -92,6 +100,17 @@ public:
uint overline : 1;
uint underline : 1;
uint strikeOut : 1;
+
+ const quint32 *glyphIndexData;
+ int glyphIndexDataSize;
+
+ const QPointF *glyphPositionData;
+ int glyphPositionDataSize;
+
+ static QGlyphRunPrivate *get(const QGlyphRun &glyphRun)
+ {
+ return glyphRun.d.data();
+ }
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp
index 6071c55..7e829db 100644
--- a/src/gui/text/qplatformfontdatabase_qpa.cpp
+++ b/src/gui/text/qplatformfontdatabase_qpa.cpp
@@ -51,6 +51,13 @@ extern void qt_registerFont(const QString &familyname, const QString &foundrynam
QFont::Style style, int stretch, bool antialiased,bool scalable, int pixelSize,
const QSupportedWritingSystems &writingSystems, void *hanlde);
+/*!
+ \fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *)
+
+ Registers the pre-rendered QPF2 font contained in the given \a dataArray.
+
+ \sa registerFont()
+*/
void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
{
if (dataArray.size() == 0)
@@ -88,6 +95,32 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *
}
}
+/*!
+ \fn void QPlatformFontDatabase::registerFont(const QString &familyName,
+ const QString &foundryName, QFont::Weight weight, QFont::Style style,
+ QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize,
+ const QSupportedWritingSystems &writingSystems, void *usrPtr)
+
+ Registers a font with the given set of attributes describing the font's
+ foundry, family name, style and stretch information, pixel size, and
+ supported writing systems. Additional information about whether the font
+ can be scaled and antialiased can also be provided.
+
+ The foundry name and font family are described by \a foundryName and
+ \a familyName. The font weight (light, normal, bold, etc.), style (normal,
+ oblique, italic) and stretch information (condensed, expanded, unstretched,
+ etc.) are specified by \a weight, \a style and \a stretch.
+
+ Some fonts can be antialiased and scaled; \a scalable and \a antialiased
+ can be set to true for fonts with these attributes. The intended pixel
+ size of non-scalable fonts is specified by \a pixelSize; this value will be
+ ignored for scalable fonts.
+
+ The writing systems supported by the font are specified by the
+ \a writingSystems argument.
+
+ \sa registerQPF2Font()
+*/
void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight,
QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize,
const QSupportedWritingSystems &writingSystems, void *usrPtr)
@@ -206,7 +239,8 @@ void QPlatformFontDatabase::populateFontDatabase()
}
/*!
-
+ Returns the font engine that can be used to render the font described by
+ the font definition, \a fontDef, in the specified \a script.
*/
QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
{
@@ -229,7 +263,8 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal
}
/*!
-
+ Returns a list of alternative fonts for the specified \a family and
+ \a style and \a script using the \a styleHint given.
*/
QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const
{
@@ -241,8 +276,13 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, cons
}
/*!
- Adds an application font. Returns a list of family names, or an empty list if the font could
- not be added
+ Adds an application font described by the font contained supplied \a fontData
+ or using the font contained in the file referenced by \a fileName. Returns
+ a list of family names, or an empty list if the font could not be added.
+
+ \note The default implementation of this function does not add an application
+ font. Subclasses should reimplement this function to perform the necessary
+ loading and registration of fonts.
*/
QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
@@ -280,21 +320,23 @@ QString QPlatformFontDatabase::fontDir() const
/*!
\class QPlatformFontDatabase
- \brief The QPlatformFontDatabase makes it possible to customize how fonts are picked up, and
- and how they are rendered
+ \brief The QPlatformFontDatabase class makes it possible to customize how fonts
+ are discovered and how they are rendered
\ingroup painting
QPlatformFontDatabase is the superclass which is intended to let platform implementations use
native font handling.
- Qt has its internal fontdatabase which it uses to pick up available fonts. To be able
- to populate this database subclass this class, and reimplement populateFontDatabase().
+ Qt has its internal font database which it uses to discover available fonts on the
+ user's system. To be able to populate this database subclass this class, and
+ reimplement populateFontDatabase().
- Use the function registerFont to populate the internal fontdatabase.
+ Use the function registerFont() to populate the internal font database.
- Sometimes a specified font does not have the required glyphs, then the fallbackForFamily
- function is called.
+ Sometimes a specified font does not have the required glyphs; in such a case, the
+ fallbackForFamily() function is called automatically to find alternative font
+ families that can supply alternatives to the missing glyphs.
\sa QSupportedWritingSystems
*/
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 843deb0..ec5cc18 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -87,16 +87,16 @@ QT_BEGIN_NAMESPACE
QRawFont can be constructed in a number of ways:
\list
- \o \l It can be constructed by calling QTextLayout::glyphRuns() or QTextFragment::glyphRuns().
- The returned QGlyphRun 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.
+ \o 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 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 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
@@ -132,8 +132,9 @@ QRawFont::QRawFont()
}
/*!
- 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.
+ Constructs a QRawFont representing the font contained in the file referenced
+ by \a fileName for the size (in pixels) given by \a pixelSize, and using the
+ hinting preference specified by \a hintingPreference.
\note The referenced file must contain a TrueType or OpenType font.
*/
@@ -146,7 +147,9 @@ QRawFont::QRawFont(const QString &fileName,
}
/*!
- Constructs a QRawFont representing the font contained in \a fontData.
+ Constructs a QRawFont representing the font contained in the supplied
+ \a fontData for the size (in pixels) given by \a pixelSize, and using the
+ hinting preference specified by \a hintingPreference.
\note The data must contain a TrueType or OpenType font.
*/
@@ -192,7 +195,9 @@ bool QRawFont::isValid() const
}
/*!
- Replaces the current QRawFont with the contents of the file references by \a fileName.
+ Replaces the current QRawFont with the contents of the file referenced
+ by \a fileName for the size (in pixels) given by \a pixelSize, and using the
+ hinting preference specified by \a hintingPreference.
The file must reference a TrueType or OpenType font.
@@ -208,7 +213,9 @@ void QRawFont::loadFromFile(const QString &fileName,
}
/*!
- Replaces the current QRawFont with the contents of \a fontData.
+ Replaces the current QRawFont with the font contained in the supplied
+ \a fontData for the size (in pixels) given by \a pixelSize, and using the
+ hinting preference specified by \a hintingPreference.
The \a fontData must contain a TrueType or OpenType font.
@@ -226,8 +233,9 @@ void QRawFont::loadFromData(const QByteArray &fontData,
}
/*!
- 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.
+ This function returns a rasterized image of the glyph at the given
+ \a glyphIndex in the underlying font, using the \a transform specified.
+ If the QRawFont is not valid, this function 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
@@ -396,6 +404,19 @@ QString QRawFont::familyName() const
}
/*!
+ Returns the style name of this QRawFont.
+
+ \sa QFont::styleName()
+*/
+QString QRawFont::styleName() const
+{
+ if (!isValid())
+ return QString();
+
+ return d->fontEngine->fontDef.styleName;
+}
+
+/*!
Returns the style of this QRawFont.
\sa QFont::style()
@@ -422,11 +443,15 @@ int QRawFont::weight() const
}
/*!
- 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::glyphRuns() to get the set of glyph index list and QRawFont pairs.
+ Converts the string of unicode points given by \a text to glyph indexes
+ using the CMAP table in the underlying font, and returns a vector containing
+ the result.
+
+ 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, then call QTextLayout::glyphs()
+ to get the set of glyph index list and QRawFont pairs.
\sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns()
*/
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index da56d3d..99e0837 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -84,6 +84,7 @@ public:
bool operator==(const QRawFont &other) const;
QString familyName() const;
+ QString styleName() const;
QFont::Style style() const;
int weight() const;
diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp
index e8c10a5..db60459 100644
--- a/src/gui/text/qrawfont_ft.cpp
+++ b/src/gui/text/qrawfont_ft.cpp
@@ -46,7 +46,7 @@
#include "qrawfont_p.h"
#include "qfontengine_ft_p.h"
-#if defined(Q_WS_X11)
+#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
# include "qfontengine_x11_p.h"
#endif
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
class QFontEngineFTRawFont
-#if defined(Q_WS_X11)
+#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
: public QFontEngineX11FT
#else
: public QFontEngineFT
@@ -63,7 +63,7 @@ class QFontEngineFTRawFont
{
public:
QFontEngineFTRawFont(const QFontDef &fontDef)
-#if defined(Q_WS_X11)
+#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
: QFontEngineX11FT(fontDef)
#else
: QFontEngineFT(fontDef)
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index fe3c993..41b6fe2 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -600,7 +600,7 @@ Qt::CursorMoveStyle QTextDocument::defaultCursorMoveStyle() const
/*!
\since 4.8
- Set the default cursor movement style.
+ Sets the default cursor movement style to the given \a style.
*/
void QTextDocument::setDefaultCursorMoveStyle(Qt::CursorMoveStyle style)
{
@@ -2553,7 +2553,7 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block)
const bool emptyBlock = block.begin().atEnd();
if (emptyBlock) {
- html += QLatin1String("-qt-paragraph-type:empty;");
+ html += QLatin1String("-qt-paragraph-type:empty; height:1em;");
}
emitMargins(QString::number(format.topMargin()),
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index b43c8f4..e8e6c98 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -856,7 +856,7 @@ void QTextEngine::shapeLine(const QScriptLine &line)
}
}
-#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC)
+#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) && defined(Q_WS_MAC)
static bool enableHarfBuzz()
{
static enum { Yes, No, Unknown } status = Unknown;
@@ -2825,6 +2825,75 @@ QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, in
return 0;
}
+// Scan in logClusters[from..to-1] for glyph_pos
+int QTextEngine::getClusterLength(unsigned short *logClusters,
+ const HB_CharAttributes *attributes,
+ int from, int to, int glyph_pos, int *start)
+{
+ int clusterLength = 0;
+ for (int i = from; i < to; i++) {
+ if (logClusters[i] == glyph_pos && attributes[i].charStop) {
+ if (*start < 0)
+ *start = i;
+ clusterLength++;
+ }
+ else if (clusterLength)
+ break;
+ }
+ return clusterLength;
+}
+
+int QTextEngine::positionInLigature(const QScriptItem *si, int end,
+ QFixed x, QFixed edge, int glyph_pos,
+ bool cursorOnCharacter)
+{
+ unsigned short *logClusters = this->logClusters(si);
+ int clusterStart = -1;
+ int clusterLength = 0;
+
+ if (si->analysis.script != QUnicodeTables::Common &&
+ si->analysis.script != QUnicodeTables::Greek) {
+ if (glyph_pos == -1)
+ return si->position + end;
+ else {
+ int i;
+ for (i = 0; i < end; i++)
+ if (logClusters[i] == glyph_pos)
+ break;
+ return si->position + i;
+ }
+ }
+
+ if (glyph_pos == -1 && end > 0)
+ glyph_pos = logClusters[end - 1];
+ else {
+ if (x <= edge)
+ glyph_pos--;
+ }
+
+ const HB_CharAttributes *attrs = attributes();
+ clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart);
+
+ if (clusterLength) {
+ const QGlyphLayout &glyphs = shapedGlyphs(si);
+ QFixed glyphWidth = glyphs.effectiveAdvance(glyph_pos);
+ // the approximate width of each individual element of the ligature
+ QFixed perItemWidth = glyphWidth / clusterLength;
+ QFixed left = x > edge ? edge : edge - glyphWidth;
+ int n = ((x - left) / perItemWidth).floor().toInt();
+ QFixed dist = x - left - n * perItemWidth;
+ int closestItem = dist > (perItemWidth / 2) ? n + 1 : n;
+ if (cursorOnCharacter && closestItem > 0)
+ closestItem--;
+ int pos = si->position + clusterStart + closestItem;
+ // Jump to the next charStop
+ while (!attrs[pos].charStop && pos < end)
+ pos++;
+ return pos;
+ }
+ return si->position + end;
+}
+
int QTextEngine::previousLogicalPosition(int oldPos) const
{
const HB_CharAttributes *attrs = attributes();
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index ed24d59..055974a 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -620,6 +620,7 @@ public:
QFixed leadingSpaceWidth(const QScriptLine &line);
QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos);
+ int positionInLigature(const QScriptItem *si, int end, QFixed x, QFixed edge, int glyph_pos, bool cursorOnCharacter);
int previousLogicalPosition(int oldPos) const;
int nextLogicalPosition(int oldPos) const;
int lineNumberForTextPosition(int pos);
@@ -642,6 +643,7 @@ private:
void resolveAdditionalFormats() const;
int endOfLine(int lineNum);
int beginningOfLine(int lineNum);
+ int getClusterLength(unsigned short *logClusters, const HB_CharAttributes *attributes, int from, int to, int glyph_pos, int *start);
};
class QStackTextEngine : public QTextEngine {
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index a699568..833414f 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -571,6 +571,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value FontStyleHint Corresponds to the QFont::StyleHint property
\value FontStyleStrategy Corresponds to the QFont::StyleStrategy property
\value FontKerning Specifies whether the font has kerning turned on.
+ \value FontHintingPreference Controls the use of hinting according to values
+ of the QFont::HintingPreference enum.
\omitvalue FirstFontProperty
\omitvalue LastFontProperty
@@ -588,8 +590,13 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
List properties
- \value ListStyle
- \value ListIndent
+ \value ListStyle Specifies the style used for the items in a list,
+ described by values of the QTextListFormat::Style enum.
+ \value ListIndent Specifies the amount of indentation used for a list.
+ \value ListNumberPrefix Defines the text which is prepended to item numbers in
+ numeric lists.
+ \value ListNumberSuffix Defines the text which is appended to item numbers in
+ numeric lists.
Table and frame properties
@@ -1263,16 +1270,18 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const
\value AlignNormal Adjacent characters are positioned in the standard
way for text in the writing system in use.
- \value AlignSuperScript Characters are placed above the baseline for
+ \value AlignSuperScript Characters are placed above the base line for
normal text.
- \value AlignSubScript Characters are placed below the baseline for
+ \value AlignSubScript Characters are placed below the base line for
normal text.
- \value AlignMiddle The center of the object is vertically aligned with the base line.
- Currently, this is only implemented for inline objects.
+ \value AlignMiddle The center of the object is vertically aligned with the
+ base line. Currently, this is only implemented for
+ inline objects.
\value AlignBottom The bottom edge of the object is vertically aligned with
the base line.
\value AlignTop The top edge of the object is vertically aligned with
the base line.
+ \value AlignBaseline The base lines of the characters are aligned.
*/
/*!
@@ -2136,8 +2145,9 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
\fn void QTextBlockFormat::setLineHeight(qreal height, int heightType)
\since 4.8
- This sets the line height for the paragraph to the value in height
- which is dependant on heightType, described by the LineHeightTypes enum.
+ Sets the line height for the paragraph to the value given by \a height
+ which is dependent on \a heightType in the way described by the
+ LineHeightTypes enum.
\sa LineHeightTypes, lineHeight(), lineHeightType()
*/
@@ -2147,11 +2157,16 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
\fn qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling) const
\since 4.8
- This returns what the height of the lines in the paragraph will be depending
- on the given height of the script line and the scaling. The value that is returned
- is also dependant on the given LineHeightType of the paragraph as well as the LineHeight
- setting that has been set for the paragraph. The scaling is needed for the heights
- that include a fixed number of pixels, to scale them appropriately for printing.
+ Returns the height of the lines in the paragraph based on the height of the
+ script line given by \a scriptLineHeight and the specified \a scaling
+ factor.
+
+ The value that is returned is also dependent on the given LineHeightType of
+ the paragraph as well as the LineHeight setting that has been set for the
+ paragraph.
+
+ The scaling is needed for heights that include a fixed number of pixels, to
+ scale them appropriately for printing.
\sa LineHeightTypes, setLineHeight(), lineHeightType()
*/
@@ -2237,6 +2252,13 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
numbering scheme used for items in the list. Note that lists that use the
decimal numbering scheme begin counting at 1 rather than 0.
+ Style properties can be set to further configure the appearance of list
+ items; for example, the ListNumberPrefix and ListNumberSuffix properties
+ can be used to customize the numbers used in an ordered list so that they
+ appear as (1), (2), (3), etc.:
+
+ \snippet doc/src/snippets/textdocument-listitemstyles/mainwindow.cpp add a styled, ordered list
+
\sa QTextList
*/
@@ -2328,8 +2350,11 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt)
\fn void QTextListFormat::setNumberPrefix(const QString &numberPrefix)
\since 4.8
- Sets the list format's number prefix. This can be used with all
- sorted list types. It does not have any effect on unsorted list types.
+ Sets the list format's number prefix to the string specified by
+ \a numberPrefix. This can be used with all sorted list types. It does not
+ have any effect on unsorted list types.
+
+ The default prefix is an empty string.
\sa numberPrefix()
*/
@@ -2347,8 +2372,10 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt)
\fn void QTextListFormat::setNumberSuffix(const QString &numberSuffix)
\since 4.8
- Sets the list format's number suffix. This can be used with all
- sorted list types. It does not have any effect on unsorted list types.
+ Sets the list format's number suffix to the string specified by
+ \a numberSuffix. This can be used with all sorted list types. It does not
+ have any effect on unsorted list types.
+
The default suffix is ".".
\sa numberSuffix()
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 988ae93..c1bc846 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -584,7 +584,7 @@ bool QTextLayout::cacheEnabled() const
this option is for widgets like QLineEdit or custom widgets without
a QTextDocument. Default value is Qt::LogicalMoveStyle.
- \sa setCursorMoveStyle()
+ \sa cursorMoveStyle()
*/
void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style)
{
@@ -2233,10 +2233,20 @@ QList<QGlyphRun> QTextLine::glyphs(int from, int length) const
glyphIndexes.setRawFont(font);
QPair<QFontEngine *, int> key(fontEngine, int(flags));
- if (!glyphsHash.contains(key))
+ if (!glyphsHash.contains(key)) {
glyphsHash.insert(key, glyphIndexes);
- else
- glyphsHash[key] += glyphIndexes;
+ } else {
+ QGlyphRun &glyphRun = glyphsHash[key];
+
+ QVector<quint32> indexes = glyphRun.glyphIndexes();
+ QVector<QPointF> positions = glyphRun.positions();
+
+ indexes += glyphIndexes.glyphIndexes();
+ positions += glyphIndexes.positions();
+
+ glyphRun.setGlyphIndexes(indexes);
+ glyphRun.setPositions(positions);
+ }
}
}
@@ -2559,8 +2569,8 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
} else {
bool rtl = eng->isRightToLeft();
bool visual = eng->visualCursorMovement();
+ int end = qMin(lineEnd, si->position + l) - si->position;
if (reverse) {
- int end = qMin(lineEnd, si->position + l) - si->position;
int glyph_end = end == l ? si->num_glyphs : logClusters[end];
int glyph_start = glyph_pos;
if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
@@ -2576,7 +2586,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
for (int i = glyph_start; i <= glyph_end; i++)
x += glyphs.effectiveAdvance(i);
}
- x += eng->offsetInLigature(si, pos, line.length, glyph_pos);
+ x += eng->offsetInLigature(si, pos, end, glyph_pos);
}
*cursorPos = pos + si->position;
@@ -2691,6 +2701,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
}
int glyph_pos = -1;
+ QFixed edge;
// has to be inside run
if (cpos == QTextLine::CursorOnCharacter) {
if (si.analysis.bidiLevel % 2) {
@@ -2701,6 +2712,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
if (pos < x)
break;
glyph_pos = gs;
+ edge = pos;
break;
}
pos -= glyphs.effectiveAdvance(gs);
@@ -2713,6 +2725,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
if (pos > x)
break;
glyph_pos = gs;
+ edge = pos;
}
pos += glyphs.effectiveAdvance(gs);
++gs;
@@ -2726,6 +2739,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
+ edge = pos;
dist = qAbs(x-pos);
}
pos -= glyphs.effectiveAdvance(gs);
@@ -2735,6 +2749,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
while (ge >= gs) {
if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = ge;
+ edge = pos;
dist = qAbs(x-pos);
}
pos += glyphs.effectiveAdvance(ge);
@@ -2746,6 +2761,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
while (gs <= ge) {
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
+ edge = pos;
dist = qAbs(x-pos);
}
pos += glyphs.effectiveAdvance(gs);
@@ -2757,6 +2773,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
pos += glyphs.effectiveAdvance(gs);
if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
glyph_pos = gs;
+ edge = pos;
dist = qAbs(x-pos);
}
++gs;
@@ -2773,16 +2790,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
if (rtl && nchars > 0)
return insertionPoints[lastLine ? nchars : nchars - 1];
}
- return si.position + end;
+ return eng->positionInLigature(&si, end, x, pos, -1,
+ cpos == QTextLine::CursorOnCharacter);
}
}
Q_ASSERT(glyph_pos != -1);
- int j;
- for (j = 0; j < eng->length(item); ++j)
- if (logClusters[j] == glyph_pos)
- break;
-// qDebug("at pos %d (in run: %d)", si.position + j, j);
- return si.position + j;
+ return eng->positionInLigature(&si, end, x, edge, glyph_pos,
+ cpos == QTextLine::CursorOnCharacter);
}
}
// right of last item
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 1619c9c..2addc0f 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -591,6 +591,7 @@ void QTextOdfWriter::writeCharacterFormat(QXmlStreamWriter &writer, QTextCharFor
QString value;
switch (format.verticalAlignment()) {
case QTextCharFormat::AlignMiddle:
+ case QTextCharFormat::AlignBaseline:
case QTextCharFormat::AlignNormal: value = QString::fromLatin1("0%"); break;
case QTextCharFormat::AlignSuperScript: value = QString::fromLatin1("super"); break;
case QTextCharFormat::AlignSubScript: value = QString::fromLatin1("sub"); break;
diff --git a/src/gui/util/qdesktopservices_s60.cpp b/src/gui/util/qdesktopservices_s60.cpp
index 97d1226..8c243ed 100644
--- a/src/gui/util/qdesktopservices_s60.cpp
+++ b/src/gui/util/qdesktopservices_s60.cpp
@@ -70,6 +70,10 @@
#include <schemehandler.h>
#endif
+#ifdef Q_WS_S60
+#include <CDirectoryLocalizer.h> // CDirectoryLocalizer
+#endif
+
QT_BEGIN_NAMESPACE
_LIT(KCacheSubDir, "Cache\\");
@@ -444,18 +448,31 @@ static QString defaultLocalizedDirectoryName(QString&)
QString QDesktopServices::displayName(StandardLocation type)
{
- static LocalizerFunc ptrLocalizerFunc = NULL;
-
- if (!ptrLocalizerFunc) {
- ptrLocalizerFunc = reinterpret_cast<LocalizerFunc>
- (qt_resolveS60PluginFunc(S60Plugin_LocalizedDirectoryName));
- if (!ptrLocalizerFunc)
- ptrLocalizerFunc = &defaultLocalizedDirectoryName;
- }
+ QString ret;
+#ifdef Q_WS_S60
QString rawPath = storageLocation(type);
- return ptrLocalizerFunc(rawPath);
-}
+ TRAPD(err,
+ QT_TRYCATCH_LEAVING(
+ CDirectoryLocalizer* localizer = CDirectoryLocalizer::NewL();
+ CleanupStack::PushL(localizer);
+ localizer->SetFullPath(qt_QString2TPtrC(QDir::toNativeSeparators(rawPath)));
+ if (localizer->IsLocalized()) {
+ TPtrC locName(localizer->LocalizedName());
+ ret = qt_TDesC2QString(locName);
+ }
+ CleanupStack::PopAndDestroy(localizer);
+ )
+ )
+
+ if (err != KErrNone)
+ ret = QString();
+#else
+ qWarning("QDesktopServices::displayName() not implemented for this platform version");
+#endif
+
+ return ret;
+}
QT_END_NAMESPACE
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index f125f82..7395604 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -56,4 +56,10 @@ symbian {
} else {
DEFINES += USE_SCHEMEHANDLER
}
+
+ contains(CONFIG, is_using_gnupoc) {
+ LIBS += -ldirectorylocalizer
+ } else {
+ LIBS += -lDirectoryLocalizer
+ }
}
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 8a93c28..2d63f63 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -1127,12 +1127,19 @@ void QLineEdit::setDragEnabled(bool b)
behavior applies.
*/
+/*!
+ Returns the movement style for the cursor in the line edit.
+*/
Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const
{
Q_D(const QLineEdit);
return d->control->cursorMoveStyle();
}
+/*!
+ Sets the movement style for the cursor in the line edit to the given
+ \a style.
+*/
void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style)
{
Q_D(QLineEdit);
diff --git a/src/gui/widgets/qmdiarea.cpp b/src/gui/widgets/qmdiarea.cpp
index fde683d..2fe9706 100644
--- a/src/gui/widgets/qmdiarea.cpp
+++ b/src/gui/widgets/qmdiarea.cpp
@@ -2176,7 +2176,7 @@ void QMdiArea::setTabsClosable(bool closable)
Tabs are not movable by default.
- \sa QTabBar::tabsMovable, setViewMode()
+ \sa QTabBar::movable, setViewMode()
*/
bool QMdiArea::tabsMovable() const
{
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp
index ade798f..c6551e5 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/gui/widgets/qtabwidget.cpp
@@ -883,7 +883,7 @@ QSize QTabWidget::minimumSizeHint() const
.expandedTo(QApplication::globalStrut());
}
-/*
+/*!
\reimp
*/
int QTabWidget::heightForWidth(int width) const