summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qfiledialog.cpp263
-rw-r--r--src/gui/dialogs/qfilesystemmodel_p.h18
-rw-r--r--src/gui/dialogs/qfontdialog_mac.mm67
-rw-r--r--src/gui/dialogs/qsidebar.cpp4
-rw-r--r--src/gui/embedded/qscreentransformed_qws.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp41
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp4
-rw-r--r--src/gui/image/qpixmap.cpp14
-rw-r--r--src/gui/image/qpixmap.h2
-rw-r--r--src/gui/image/qpixmap_raster.cpp9
-rw-r--r--src/gui/image/qpixmap_raster_p.h7
-rw-r--r--src/gui/image/qpixmapcache.cpp5
-rw-r--r--src/gui/itemviews/qsortfilterproxymodel.cpp51
-rw-r--r--src/gui/kernel/kernel.pri2
-rw-r--r--src/gui/kernel/qaction.cpp47
-rw-r--r--src/gui/kernel/qaction_p.h1
-rw-r--r--src/gui/kernel/qapplication.cpp19
-rw-r--r--src/gui/kernel/qapplication_win.cpp3
-rw-r--r--src/gui/kernel/qapplication_x11.cpp24
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm76
-rw-r--r--src/gui/kernel/qshortcut.cpp20
-rw-r--r--src/gui/kernel/qshortcutmap.cpp9
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm12
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h1
-rw-r--r--src/gui/kernel/qwidget.cpp37
-rw-r--r--src/gui/kernel/qwidget_mac.mm88
-rw-r--r--src/gui/kernel/qwidget_p.h7
-rw-r--r--src/gui/kernel/qwidget_win.cpp47
-rw-r--r--src/gui/mac/images/leopard-unified-toolbar-on.pngbin0 -> 356 bytes
-rw-r--r--src/gui/mac/macresources.qrc (renamed from src/gui/mac/maccursors.qrc)3
-rw-r--r--src/gui/painting/painting.pri10
-rw-r--r--src/gui/painting/qbackingstore.cpp11
-rw-r--r--src/gui/painting/qmemrotate.cpp1
-rw-r--r--src/gui/painting/qmemrotate_p.h1
-rw-r--r--src/gui/painting/qpaintengine.cpp4
-rw-r--r--src/gui/painting/qpaintengine_d3d.cpp4576
-rw-r--r--src/gui/painting/qpaintengine_d3d.fx608
-rw-r--r--src/gui/painting/qpaintengine_d3d.qrc5
-rw-r--r--src/gui/painting/qpaintengine_d3d_p.h120
-rw-r--r--src/gui/painting/qpaintengine_p.h12
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp14
-rw-r--r--src/gui/painting/qpainter.cpp6
-rw-r--r--src/gui/painting/qprintengine_win.cpp2
-rw-r--r--src/gui/painting/qprinter.cpp14
-rw-r--r--src/gui/painting/qwindowsurface_d3d.cpp169
-rw-r--r--src/gui/painting/qwindowsurface_d3d_p.h84
-rw-r--r--src/gui/styles/gtksymbols.cpp4
-rw-r--r--src/gui/styles/qcommonstyle.cpp4
-rw-r--r--src/gui/styles/qgtkstyle.cpp5
-rw-r--r--src/gui/styles/qmacstyle_mac.mm50
-rw-r--r--src/gui/styles/qstylehelper.cpp70
-rw-r--r--src/gui/styles/qstylehelper_p.h4
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp51
-rw-r--r--src/gui/styles/qstylesheetstyle_p.h2
-rw-r--r--src/gui/widgets/qlabel.cpp22
-rw-r--r--src/gui/widgets/qlineedit.cpp2
-rw-r--r--src/gui/widgets/qmainwindowlayout_mac.mm4
-rw-r--r--src/gui/widgets/qtabbar.cpp4
59 files changed, 621 insertions, 6124 deletions
diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp
index d786f3e..073c25b 100644
--- a/src/gui/dialogs/qfiledialog.cpp
+++ b/src/gui/dialogs/qfiledialog.cpp
@@ -1538,52 +1538,51 @@ extern QString qt_win_get_existing_directory(const QFileDialogArgs &args);
#endif
/*!
- This is a convenience static function that returns an existing file
- selected by the user. If the user presses Cancel, it returns a null
- string.
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user presses Cancel, it returns a null string.
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8
- The function creates a modal file dialog with the given \a parent widget.
- If the parent is not 0, the dialog will be shown centered over the
- parent widget.
+ The function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
- The file dialog's working directory will be set to \a dir. If \a
- dir includes a file name, the file will be selected. Only files
- that match the given \a filter are shown. The filter selected is
- set to \a selectedFilter. The parameters \a dir, \a
- selectedFilter, and \a filter may be empty strings. If you want
- multiple filters, separate them with ';;', for example:
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. Only files that match the
+ given \a filter are shown. The filter selected is set to \a selectedFilter.
+ The parameters \a dir, \a selectedFilter, and \a filter may be empty
+ strings. If you want multiple filters, separate them with ';;', for
+ example:
- \code
+ \code
"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
+ \endcode
- The \a options argument holds various
- options about how to run the dialog, see the QFileDialog::Option enum for
- more information on the flags you can pass.
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
- The dialog's caption is set to \a caption. If \a caption is not
- specified then a default caption will be used.
+ The dialog's caption is set to \a caption. If \a caption is not specified
+ then a default caption will be used.
- Under Windows and Mac OS X, this static function will use the native
- file dialog and not a QFileDialog.
+ On Windows and Mac OS X, this static function will use the native file
+ dialog and not a QFileDialog.
- Note that on Windows the dialog will spin a blocking modal event loop
- that will not dispatch any QTimers, and if parent is not 0 then it will
- position the dialog just under the parent's title bar.
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
- Under Unix/X11, the normal behavior of the file dialog is to resolve
- and follow symlinks. For example, if \c{/usr/tmp} is a symlink to
- \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after
- entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks,
- the file dialog will treat symlinks as regular directories.
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks, the file dialog will treat
+ symlinks as regular directories.
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QFileDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QFileDialog constructors.
- \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
+ \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
*/
QString QFileDialog::getOpenFileName(QWidget *parent,
const QString &caption,
@@ -1626,54 +1625,53 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
}
/*!
- This is a convenience static function that will return one or more
- existing files selected by the user.
+ This is a convenience static function that will return one or more existing
+ files selected by the user.
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9
- This function creates a modal file dialog with the given \a parent
- widget. If the parent is not 0, the dialog will be shown centered
- over the parent widget.
+ This function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
- The file dialog's working directory will be set to \a dir. If \a
- dir includes a file name, the file will be selected. The filter
- is set to \a filter so that only those files which match the filter
- are shown. The filter selected is set to \a selectedFilter. The parameters
- \a dir, \a selectedFilter and \a filter may be empty strings. If you
- need multiple filters, separate them with ';;', for instance:
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. The filter is set to
+ \a filter so that only those files which match the filter are shown. The
+ filter selected is set to \a selectedFilter. The parameters \a dir,
+ \a selectedFilter and \a filter may be empty strings. If you need multiple
+ filters, separate them with ';;', for instance:
- \code
+ \code
"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
+ \endcode
- The dialog's caption is set to \a caption. If \a caption is not
- specified then a default caption will be used.
+ The dialog's caption is set to \a caption. If \a caption is not specified
+ then a default caption will be used.
- Under Windows and Mac OS X, this static function will use the native
- file dialog and not a QFileDialog. On Mac OS X, the \a dir argument
- is ignored, the native dialog always displays the last visited directory.
+ On Windows and Mac OS X, this static function will use the native file
+ dialog and not a QFileDialog.
- Note that on Windows the dialog will spin a blocking modal event loop
- that will not dispatch any QTimers, and if parent is not 0 then it will
- position the dialog just under the parent's title bar.
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
- Under Unix/X11, the normal behavior of the file dialog is to resolve
- and follow symlinks. For example, if \c{/usr/tmp} is a symlink to
- \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after
- entering \c{/usr/tmp}. The \a options argument holds various
- options about how to run the dialog, see the QFileDialog::Option enum for
- more information on the flags you can pass.
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}.
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
- Note that if you want to iterate over the list of files, you should
- iterate over a copy. For example:
+ \note If you want to iterate over the list of files, you should iterate
+ over a copy. For example:
\snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 10
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QFileDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QFileDialog constructors.
- \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
+ \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
*/
QStringList QFileDialog::getOpenFileNames(QWidget *parent,
const QString &caption,
@@ -1717,54 +1715,54 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
}
/*!
- This is a convenience static function that will return a file name
- selected by the user. The file does not have to exist.
+ This is a convenience static function that will return a file name selected
+ by the user. The file does not have to exist.
- It creates a modal file dialog with the given \a parent widget. If the
- parent is not 0, the dialog will be shown centered over the parent
- widget.
+ It creates a modal file dialog with the given \a parent widget. If
+ \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11
- The file dialog's working directory will be set to \a dir. If \a
- dir includes a file name, the file will be selected. Only files that
- match the \a filter are shown. The filter selected is set to
- \a selectedFilter. The parameters \a dir, \a selectedFilter, and
- \a filter may be empty strings. Multiple filters are separated with ';;'.
- For instance:
+ The file dialog's working directory will be set to \a dir. If \a dir
+ includes a file name, the file will be selected. Only files that match the
+ \a filter are shown. The filter selected is set to \a selectedFilter. The
+ parameters \a dir, \a selectedFilter, and \a filter may be empty strings.
+ Multiple filters are separated with ';;'. For instance:
- \code
+ \code
"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
- \endcode
+ \endcode
- The \a options argument holds various
- options about how to run the dialog, see the QFileDialog::Option enum for
- more information on the flags you can pass.
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass.
- The default filter can be chosen by setting \a selectedFilter to the desired value.
+ The default filter can be chosen by setting \a selectedFilter to the
+ desired value.
- The dialog's caption is set to \a caption. If \a caption is not
- specified then a default caption will be used.
+ The dialog's caption is set to \a caption. If \a caption is not specified,
+ a default caption will be used.
- Under Windows and Mac OS X, this static function will use the native
- file dialog and not a QFileDialog.
+ On Windows and Mac OS X, this static function will use the native file
+ dialog and not a QFileDialog.
- Note that on Windows the dialog will spin a blocking modal event loop
- that will not dispatch any QTimers, and if parent is not 0 then it will
- position the dialog just under the parent's title bar.
- On Mac OS X, the filter argument is ignored.
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar. On Mac OS X, with its native file
+ dialog, the filter argument is ignored.
- Under Unix/X11, the normal behavior of the file dialog is to resolve
- and follow symlinks. For example, if \c{/usr/tmp} is a symlink to
- \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after
- entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks,
- the file dialog will treat symlinks as regular directories.
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks the file dialog will treat symlinks
+ as regular directories.
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QFileDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QFileDialog constructors.
- \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
+ \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
*/
QString QFileDialog::getSaveFileName(QWidget *parent,
const QString &caption,
@@ -1810,46 +1808,43 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
}
/*!
- This is a convenience static function that will return an existing
- directory selected by the user.
+ This is a convenience static function that will return an existing
+ directory selected by the user.
- \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12
+ \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12
- This function creates a modal file dialog with the given \a parent
- widget. If the parent is not 0, the dialog will be shown centered over
- the parent widget.
+ This function creates a modal file dialog with the given \a parent widget.
+ If \a parent is not 0, the dialog will be shown centered over the parent
+ widget.
- The dialog's working directory is set to \a dir, and the caption is
- set to \a caption. Either of these may be an empty string in which case
- the current directory and a default caption will be used
- respectively.
+ The dialog's working directory is set to \a dir, and the caption is set to
+ \a caption. Either of these may be an empty string in which case the
+ current directory and a default caption will be used respectively.
- The \a options argument holds various
- options about how to run the dialog, see the QFileDialog::Option enum for
- more information on the flags you can pass. Note that \l{QFileDialog::}{ShowDirsOnly}
- must be set to ensure a native file dialog.
+ The \a options argument holds various options about how to run the dialog,
+ see the QFileDialog::Option enum for more information on the flags you can
+ pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must
+ be set.
- Under Windows and Mac OS X, this static function will use the native
- file dialog and not a QFileDialog. On Mac OS X, the \a dir argument
- is ignored, the native dialog always displays the last visited directory.
- On Windows CE, if the device has no native file dialog, a QFileDialog
- will be used.
+ On Windows and Mac OS X, this static function will use the native file
+ dialog and not a QFileDialog. On Windows CE, if the device has no native
+ file dialog, a QFileDialog will be used.
- Under Unix/X11, the normal behavior of the file dialog is to resolve
- and follow symlinks. For example, if \c{/usr/tmp} is a symlink to
- \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after
- entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks,
- the file dialog will treat symlinks as regular directories.
+ On Unix/X11, the normal behavior of the file dialog is to resolve and
+ follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp},
+ the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If
+ \a options includes DontResolveSymlinks, the file dialog will treat
+ symlinks as regular directories.
- Note that on Windows the dialog will spin a blocking modal event loop
- that will not dispatch any QTimers, and if parent is not 0 then it will
- position the dialog just under the parent's title bar.
+ On Windows the dialog will spin a blocking modal event loop that will not
+ dispatch any QTimers, and if \a parent is not 0 then it will position the
+ dialog just below the parent's title bar.
- \warning Do not delete \a parent during the execution of the dialog.
- If you want to do this, you should create the dialog
- yourself using one of the QFileDialog constructors.
+ \warning Do not delete \a parent during the execution of the dialog. If you
+ want to do this, you should create the dialog yourself using one of the
+ QFileDialog constructors.
- \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
+ \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
*/
QString QFileDialog::getExistingDirectory(QWidget *parent,
const QString &caption,
diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h
index 0a1265a..61e8b4c 100644
--- a/src/gui/dialogs/qfilesystemmodel_p.h
+++ b/src/gui/dialogs/qfilesystemmodel_p.h
@@ -164,9 +164,12 @@ public:
QHash<QString, QFileSystemNode *>::const_iterator iterator;
for(iterator = children.constBegin() ; iterator != children.constEnd() ; ++iterator) {
//On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/)
- if (!path.isEmpty())
- iterator.value()->updateIcon(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName);
- else
+ if (!path.isEmpty()) {
+ if (path.endsWith(QLatin1Char('/')))
+ iterator.value()->updateIcon(iconProvider, path + iterator.value()->fileName);
+ else
+ iterator.value()->updateIcon(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName);
+ } else
iterator.value()->updateIcon(iconProvider, iterator.value()->fileName);
}
}
@@ -177,9 +180,12 @@ public:
QHash<QString, QFileSystemNode *>::const_iterator iterator;
for(iterator = children.constBegin() ; iterator != children.constEnd() ; ++iterator) {
//On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/)
- if (!path.isEmpty())
- iterator.value()->retranslateStrings(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName);
- else
+ if (!path.isEmpty()) {
+ if (path.endsWith(QLatin1Char('/')))
+ iterator.value()->retranslateStrings(iconProvider, path + iterator.value()->fileName);
+ else
+ iterator.value()->retranslateStrings(iconProvider, path + QLatin1Char('/') + iterator.value()->fileName);
+ } else
iterator.value()->retranslateStrings(iconProvider, iterator.value()->fileName);
}
}
diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm
index 42be3be..50917a1 100644
--- a/src/gui/dialogs/qfontdialog_mac.mm
+++ b/src/gui/dialogs/qfontdialog_mac.mm
@@ -87,7 +87,6 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
NSButton *mOkButton;
NSButton *mCancelButton;
QFontDialogPrivate *mPriv;
- NSFont *mCocoaFont;
QFont *mQtFont;
BOOL mPanelHackedWithButtons;
CGFloat mDialogExtraWidth;
@@ -119,6 +118,29 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
- (void)cleanUpAfterMyself;
@end
+static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont)
+{
+ QFont newFont;
+ if (cocoaFont) {
+ int pSize = qRound([cocoaFont pointSize]);
+ QString family(QCFString::toQString(reinterpret_cast<CFStringRef>([cocoaFont familyName])));
+ QString typeface(QCFString::toQString(reinterpret_cast<CFStringRef>([cocoaFont fontName])));
+// qDebug() << "original family" << family << "typeface" << typeface << "psize" << pSize;
+ int hyphenPos = typeface.indexOf(QLatin1Char('-'));
+ if (hyphenPos != -1) {
+ typeface.remove(0, hyphenPos + 1);
+ } else {
+ typeface = QLatin1String("Normal");
+ }
+// qDebug() << " massaged family" << family << "typeface" << typeface << "psize" << pSize;
+ newFont = QFontDatabase().font(family, typeface, pSize);
+ newFont.setUnderline(resolveFont.underline());
+ newFont.setStrikeOut(resolveFont.strikeOut());
+
+ }
+ return newFont;
+}
+
@implementation QCocoaFontPanelDelegate
- (id)initWithFontPanel:(NSFontPanel *)panel
stolenContentView:(NSView *)stolenContentView
@@ -134,7 +156,6 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
mOkButton = okButton;
mCancelButton = cancelButton;
mPriv = priv;
- mCocoaFont = 0;
mPanelHackedWithButtons = (okButton != 0);
mDialogExtraWidth = extraWidth;
mDialogExtraHeight = extraHeight;
@@ -155,42 +176,14 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
- (void)dealloc
{
- if (mCocoaFont)
- [mCocoaFont release];
delete mQtFont;
[super dealloc];
}
- (void)changeFont:(id)sender
{
- Q_UNUSED(sender);
-
- QFont newFont;
-
- if (mCocoaFont)
- [mCocoaFont autorelease];
NSFont *dummyFont = [NSFont userFontOfSize:12.0];
- mCocoaFont = [sender convertFont:dummyFont];
- if (mCocoaFont) {
- [mCocoaFont retain];
-
- int pSize = qRound([mCocoaFont pointSize]);
- QString family(QCFString::toQString(reinterpret_cast<CFStringRef>([mCocoaFont familyName])));
- QString typeface(QCFString::toQString(reinterpret_cast<CFStringRef>([mCocoaFont fontName])));
-// qDebug() << "original family" << family << "typeface" << typeface << "psize" << pSize;
- int hyphenPos = typeface.indexOf(QLatin1Char('-'));
- if (hyphenPos != -1) {
- typeface.remove(0, hyphenPos + 1);
- } else {
- typeface = QLatin1String("Normal");
- }
-// qDebug() << " massaged family" << family << "typeface" << typeface << "psize" << pSize;
- newFont = QFontDatabase().font(family, typeface, pSize);
- newFont.setUnderline(mQtFont->underline());
- newFont.setStrikeOut(mQtFont->strikeOut());
- }
-
- [self setQtFont:newFont];
+ [self setQtFont:qfontForCocoaFont([sender convertFont:dummyFont], *mQtFont)];
if (mPriv)
mPriv->updateSampleFont(*mQtFont);
}
@@ -317,6 +310,9 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
- (void)onOkClicked
{
Q_ASSERT(mPanelHackedWithButtons);
+ NSFontManager *fontManager = [NSFontManager sharedFontManager];
+ [self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]],
+ *mQtFont)];
[[mStolenContentView window] close];
[self finishOffWithCode:NSOKButton];
}
@@ -374,16 +370,7 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin
mModalSession = 0;
}
- // temporary hack to work around bug in deleteLater() in Qt/Mac Cocoa
-#if 1
- bool deleteDialog = mPriv->fontDialog()->testAttribute(Qt::WA_DeleteOnClose);
- mPriv->fontDialog()->setAttribute(Qt::WA_DeleteOnClose, false);
-#endif
mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
-#if 1
- if (deleteDialog)
- delete mPriv->fontDialog();
-#endif
} else {
[NSApp stopModalWithCode:code];
}
diff --git a/src/gui/dialogs/qsidebar.cpp b/src/gui/dialogs/qsidebar.cpp
index bfdb37e..26108d7 100644
--- a/src/gui/dialogs/qsidebar.cpp
+++ b/src/gui/dialogs/qsidebar.cpp
@@ -248,7 +248,11 @@ void QUrlModel::addUrls(const QList<QUrl> &list, int row, bool move)
if (!url.isValid() || url.scheme() != QLatin1String("file"))
continue;
for (int j = 0; move && j < rowCount(); ++j) {
+#if defined(Q_OS_WIN)
+ if (index(j, 0).data(UrlRole).toUrl().toLocalFile().toLower() == url.toLocalFile().toLower()) {
+#else
if (index(j, 0).data(UrlRole) == url) {
+#endif
removeRow(j);
if (j <= row)
row--;
diff --git a/src/gui/embedded/qscreentransformed_qws.cpp b/src/gui/embedded/qscreentransformed_qws.cpp
index f988789..46ac1d1 100644
--- a/src/gui/embedded/qscreentransformed_qws.cpp
+++ b/src/gui/embedded/qscreentransformed_qws.cpp
@@ -410,7 +410,9 @@ void QTransformedScreen::blit(const QImage &image, const QPoint &topLeft,
#endif
#ifdef QT_QWS_DEPTH_8
case 8:
- if (image.depth() == 16)
+ if (image.format() == QImage::Format_RGB444)
+ SET_BLIT_FUNC(quint8, qrgb444, trans, func);
+ else if (image.depth() == 16)
SET_BLIT_FUNC(quint8, quint16, trans, func);
else
SET_BLIT_FUNC(quint8, quint32, trans, func);
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 7971711..92be62f 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -885,6 +885,38 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, bool de
/*!
\internal
+ Returns the bounding rect of this item's children (excluding itself).
+*/
+void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rect)
+{
+ for (int i = 0; i < children.size(); ++i) {
+ QGraphicsItem *child = children.at(i);
+ QGraphicsItemPrivate *childd = child->d_ptr;
+ bool hasX = childd->hasTransform;
+ bool hasPos = !childd->pos.isNull();
+ if (hasPos || hasX) {
+ QTransform matrix;
+ if (hasX)
+ matrix = child->transform();
+ if (hasPos) {
+ const QPointF &p = childd->pos;
+ matrix *= QTransform::fromTranslate(p.x(), p.y());
+ }
+ matrix *= *x;
+ *rect |= matrix.mapRect(child->boundingRect());
+ if (!childd->children.isEmpty())
+ childd->childrenBoundingRectHelper(&matrix, rect);
+ } else {
+ *rect |= x->mapRect(child->boundingRect());
+ if (!childd->children.isEmpty())
+ childd->childrenBoundingRectHelper(x, rect);
+ }
+ }
+}
+
+/*!
+ \internal
+
Empty all cached pixmaps from the pixmap cache.
*/
void QGraphicsItemCache::purge()
@@ -3255,13 +3287,8 @@ void QGraphicsItem::setZValue(qreal z)
QRectF QGraphicsItem::childrenBoundingRect() const
{
QRectF childRect;
- foreach (QGraphicsItem *child, children()) {
- QPointF childPos = child->pos();
- QTransform matrix = child->transform();
- if (!childPos.isNull())
- matrix *= QTransform::fromTranslate(childPos.x(), childPos.y());
- childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect());
- }
+ QTransform x;
+ d_ptr->childrenBoundingRectHelper(&x, &childRect);
return childRect;
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index fb0bd2d..bcbd737 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -187,6 +187,7 @@ public:
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
void setParentItemHelper(QGraphicsItem *parent, bool deleting);
+ void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
virtual void resolveFont(uint inheritedMask)
{
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index a9d585c..7720a10 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2809,9 +2809,7 @@ void QGraphicsView::setupViewport(QWidget *widget)
const bool isGLWidget = widget->inherits("QGLWidget");
- d->accelerateScrolling = !(isGLWidget
- || widget->testAttribute(Qt::WA_MSWindowsUseDirect3D)
- || qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault));
+ d->accelerateScrolling = !(isGLWidget);
widget->setFocusPolicy(Qt::StrongFocus);
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 3b82da8..f495b31 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1359,14 +1359,6 @@ bool QPixmap::isDetached() const
void QPixmap::deref()
{
if (data && !data->ref.deref()) { // Destroy image if last ref
-#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
- if (data->classId() == QPixmapData::RasterClass) {
- QRasterPixmapData *rData = static_cast<QRasterPixmapData*>(data);
- if (rData->texture)
- rData->texture->Release();
- rData->texture = 0;
- }
-#endif
if (data->is_cached && qt_pixmap_cleanup_hook_64)
qt_pixmap_cleanup_hook_64(cacheKey());
delete data;
@@ -1938,12 +1930,6 @@ void QPixmap::detach()
if (id == QPixmapData::RasterClass) {
QRasterPixmapData *rasterData = static_cast<QRasterPixmapData*>(data);
rasterData->image.detach();
-#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECT3D)
- if (rasterData->texture) {
- rasterData->texture->Release();
- rasterData->texture = 0;
- }
-#endif
}
if (data->is_cached && qt_pixmap_cleanup_hook_64 && data->ref == 1)
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index cd3b465..a5609e4 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -254,8 +254,6 @@ private:
friend class QWidgetPrivate;
friend class QRasterPaintEngine;
friend class QRasterBuffer;
- friend class QDirect3DPaintEngine;
- friend class QDirect3DPaintEnginePrivate;
friend class QDetachedPixmap;
#if !defined(QT_NO_DATASTREAM)
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPixmap &);
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 145b02a..b5556cd 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -50,12 +50,6 @@
#include <private/qwidget_p.h>
#include <private/qdrawhelper_p.h>
-#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
-#include <private/qpaintengine_d3d_p.h>
-#include <d3d9.h>
-extern QDirect3DPaintEngine *qt_d3dEngine();
-#endif
-
QT_BEGIN_NAMESPACE
const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
@@ -63,9 +57,6 @@ const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08,
QRasterPixmapData::QRasterPixmapData(PixelType type)
: QPixmapData(type, RasterClass)
-#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECT3D)
- , texture(0)
-#endif
{
}
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index 48d5cf8..9d3bf72 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -58,9 +58,6 @@
#ifdef Q_WS_WIN
# include "qt_windows.h"
-# ifndef QT_NO_DIRECT3D
-# include <d3d9.h>
-# endif
#endif
QT_BEGIN_NAMESPACE
@@ -88,10 +85,6 @@ protected:
int metric(QPaintDevice::PaintDeviceMetric metric) const;
private:
-#if defined(Q_WS_WIN) && !defined(QT_NO_DIRECT3D)
- friend class QDirect3DPaintEnginePrivate;
- IDirect3DTexture9 *texture;
-#endif
friend class QPixmap;
friend class QBitmap;
friend class QDetachedPixmap;
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index eedb6a3..458d6b9 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -187,6 +187,11 @@ bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost)
cacheKeys.insert(key, cacheKey);
return true;
}
+ qint64 oldCacheKey = cacheKeys.value(key, -1);
+ //If for the same key we add already a pixmap we should delete it
+ if (oldCacheKey != -1)
+ QCache<qint64, QDetachedPixmap>::remove(oldCacheKey);
+
bool success = QCache<qint64, QDetachedPixmap>::insert(cacheKey, new QDetachedPixmap(pixmap), cost);
if (success) {
cacheKeys.insert(key, cacheKey);
diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp
index 91431c4..fee19c9 100644
--- a/src/gui/itemviews/qsortfilterproxymodel.cpp
+++ b/src/gui/itemviews/qsortfilterproxymodel.cpp
@@ -56,6 +56,15 @@ QT_BEGIN_NAMESPACE
typedef QList<QPair<QModelIndex, QPersistentModelIndex> > QModelIndexPairList;
+static inline QSet<int> qVectorToSet(const QVector<int> &vector)
+{
+ QSet<int> set;
+ set.reserve(vector.size());
+ for(int i=0; i < vector.size(); ++i)
+ set << vector.at(i);
+ return set;
+}
+
class QSortFilterProxyModelLessThan
{
public:
@@ -223,8 +232,8 @@ public:
QModelIndexPairList store_persistent_indexes();
void update_persistent_indexes(const QModelIndexPairList &source_indexes);
- void filter_changed();
- void handle_filter_changed(
+ void filter_changed(const QModelIndex &source_parent = QModelIndex());
+ QSet<int> handle_filter_changed(
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
const QModelIndex &source_parent, Qt::Orientation orient);
@@ -928,27 +937,39 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes(
q->changePersistentIndexList(from, to);
}
+
/*!
\internal
Updates the proxy model (adds/removes rows) based on the
new filter.
*/
-void QSortFilterProxyModelPrivate::filter_changed()
+void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_parent)
{
- QMap<QModelIndex, Mapping *>::const_iterator it;
- for (it = source_index_mapping.constBegin(); it != source_index_mapping.constEnd(); ++it) {
- QModelIndex source_parent = it.key();
- Mapping *m = it.value();
- handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical);
- handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal);
+ IndexMap::const_iterator it = source_index_mapping.constFind(source_parent);
+ if (it == source_index_mapping.constEnd())
+ return;
+ Mapping *m = it.value();
+ QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical);
+ QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal);
+ QVector<QModelIndex>::iterator it2 = m->mapped_children.end();
+ while (it2 != m->mapped_children.begin()) {
+ --it2;
+ const QModelIndex source_child_index = *it2;
+ if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) {
+ it2 = m->mapped_children.erase(it2);
+ remove_from_mapping(source_child_index);
+ } else {
+ filter_changed(source_child_index);
+ }
}
}
/*!
\internal
+ returns the removed items indexes
*/
-void QSortFilterProxyModelPrivate::handle_filter_changed(
+QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed(
QVector<int> &source_to_proxy, QVector<int> &proxy_to_source,
const QModelIndex &source_parent, Qt::Orientation orient)
{
@@ -985,6 +1006,7 @@ void QSortFilterProxyModelPrivate::handle_filter_changed(
insert_source_items(source_to_proxy, proxy_to_source,
source_items_insert, source_parent, orient);
}
+ return qVectorToSet(source_items_remove);
}
void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &source_top_left,
@@ -1035,15 +1057,14 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
if (!source_rows_remove.isEmpty()) {
remove_source_items(m->proxy_rows, m->source_rows,
source_rows_remove, source_parent, Qt::Vertical);
- QSet<int> source_rows_remove_set = source_rows_remove.toList().toSet();
- QVector<QModelIndex>::iterator it = m->mapped_children.begin();
- while (it != m->mapped_children.end()) {
+ QSet<int> source_rows_remove_set = qVectorToSet(source_rows_remove);
+ QVector<QModelIndex>::iterator it = m->mapped_children.end();
+ while (it != m->mapped_children.begin()) {
+ --it;
const QModelIndex source_child_index = *it;
if (source_rows_remove_set.contains(source_child_index.row())) {
it = m->mapped_children.erase(it);
remove_from_mapping(source_child_index);
- } else {
- ++it;
}
}
}
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index cb2b014..a1b982a 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -193,7 +193,7 @@ embedded {
MENU_NIB.path = Resources
MENU_NIB.version = Versions
QMAKE_BUNDLE_DATA += MENU_NIB
- RESOURCES += mac/maccursors.qrc
+ RESOURCES += mac/macresources.qrc
LIBS += -framework AppKit
}
diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp
index 921be22..c6addc1 100644
--- a/src/gui/kernel/qaction.cpp
+++ b/src/gui/kernel/qaction.cpp
@@ -136,27 +136,25 @@ void QActionPrivate::redoGrab(QShortcutMap &map)
void QActionPrivate::redoGrabAlternate(QShortcutMap &map)
{
Q_Q(QAction);
- for (int i = 0; i < alternateShortcutIds.size(); ++i)
- if (int id = alternateShortcutIds.at(i))
+ foreach (int id, alternateShortcutIds)
+ if (id)
map.removeShortcut(id, q);
alternateShortcutIds.clear();
if (alternateShortcuts.isEmpty())
return;
- for (int i = 0; i < alternateShortcuts.size(); ++i) {
- const QKeySequence &alternate = alternateShortcuts.at(i);
+ foreach (const QKeySequence& alternate, alternateShortcuts) {
if (!alternate.isEmpty())
alternateShortcutIds.append(map.addShortcut(q, alternate, shortcutContext));
else
alternateShortcutIds.append(0);
}
-
if (!enabled) {
- for (int i = 0; i < alternateShortcutIds.size(); ++i)
- map.setShortcutEnabled(false, alternateShortcutIds.at(i), q);
+ foreach (int id, alternateShortcutIds)
+ map.setShortcutEnabled(false, id, q);
}
if (!autorepeat) {
- for (int i = 0; i < alternateShortcutIds.size(); ++i)
- map.setShortcutAutoRepeat(false, alternateShortcutIds.at(i), q);
+ foreach (int id, alternateShortcutIds)
+ map.setShortcutAutoRepeat(false, id, q);
}
}
@@ -165,26 +163,10 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
Q_Q(QAction);
if (shortcutId)
map.setShortcutEnabled(enable, shortcutId, q);
- for (int i = 0; i < alternateShortcutIds.size(); ++i)
- if (int id = alternateShortcutIds.at(i))
+ foreach (int id, alternateShortcutIds)
+ if (id)
map.setShortcutEnabled(enable, id, q);
}
-
-void QActionPrivate::removeAll(QShortcutMap &map)
-{
- Q_Q(QAction);
- if (shortcutId) {
- map.removeShortcut(shortcutId, q);
- shortcutId = 0;
- }
-
- for (int i = 0; i < alternateShortcutIds.size(); ++i)
- if (int id = alternateShortcutIds.at(i))
- map.removeShortcut(id, q);
-
- alternateShortcutIds.clear();
-}
-
#endif // QT_NO_SHORTCUT
@@ -633,8 +615,8 @@ QAction::~QAction()
#ifndef QT_NO_SHORTCUT
if (d->shortcutId && qApp) {
qApp->d_func()->shortcutMap.removeShortcut(d->shortcutId, this);
- for (int i = 0; i < d->alternateShortcutIds.size(); ++i)
- qApp->d_func()->shortcutMap.removeShortcut(d->alternateShortcutIds.at(i), this);
+ foreach (int id, d->alternateShortcutIds)
+ qApp->d_func()->shortcutMap.removeShortcut(id, this);
}
#endif
}
@@ -1067,12 +1049,7 @@ void QAction::setVisible(bool b)
d->visible = b;
d->enabled = b && !d->forceDisabled && (!d->group || d->group->isEnabled()) ;
#ifndef QT_NO_SHORTCUT
- if (b) {
- d->redoGrab(qApp->d_func()->shortcutMap);
- d->redoGrabAlternate(qApp->d_func()->shortcutMap);
- } else {
- d->removeAll(qApp->d_func()->shortcutMap);
- }
+ d->setShortcutEnabled(d->enabled, qApp->d_func()->shortcutMap);
#endif
d->sendDataChanged();
}
diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h
index a5b3731..0617ef5 100644
--- a/src/gui/kernel/qaction_p.h
+++ b/src/gui/kernel/qaction_p.h
@@ -111,7 +111,6 @@ public:
void redoGrab(QShortcutMap &map);
void redoGrabAlternate(QShortcutMap &map);
void setShortcutEnabled(bool enable, QShortcutMap &map);
- void removeAll(QShortcutMap &map);
static QShortcutMap *globalMap;
#endif // QT_NO_SHORTCUT
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index fd189c7..34c135c 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -107,9 +107,6 @@ static void initResources()
Q_INIT_RESOURCE(qstyle);
#endif
-#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
- Q_INIT_RESOURCE(qpaintengine_d3d);
-#endif
Q_INIT_RESOURCE(qmessagebox);
#if !defined(QT_NO_PRINTDIALOG)
Q_INIT_RESOURCE(qprintdialog);
@@ -620,13 +617,6 @@ void QApplicationPrivate::process_cmdline()
and QPixmaps. Available options are \c{raster} and \c{opengl}.
\endlist
- The Windows version of Qt supports an additional command line option, if
- Direct3D support has been compiled into Qt:
- \list
- \o -direct3d will make the Direct3D paint engine the default widget
- paint engine in Qt. \bold {This functionality is experimental.}
- \endlist
-
The X11 version of Qt supports some traditional X11 command line options:
\list
\o -display \e display, sets the X display (default is $DISPLAY).
@@ -832,12 +822,13 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv,
#endif // Q_WS_X11
+extern void qInitDrawhelperAsm();
/*!
+ \fn void QApplicationPrivate::initialize()
+
Initializes the QApplication object, called from the constructors.
*/
-extern void qInitDrawhelperAsm();
-
void QApplicationPrivate::initialize()
{
QWidgetPrivate::mapper = new QWidgetMapper;
@@ -2106,8 +2097,8 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
if (that)
QApplication::sendEvent(that->style(), &in);
}
+ emit qApp->focusChanged(prev, focus_widget);
}
- emit qApp->focusChanged(prev, focus_widget);
}
}
@@ -3504,7 +3495,7 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
It is necessary to call this function to start event handling. The main
event loop receives events from the window system and dispatches these to
the application widgets.
-
+
Generally, no user interaction can take place before calling exec(). As a
special case, modal widgets like QMessageBox can be used before calling
exec(), because modal widgets call exec() to start a local event loop.
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 2f2fc2c..c1cb7e2 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -745,9 +745,6 @@ void qt_init(QApplicationPrivate *priv, int)
appNoGrab = !appNoGrab;
else
#endif // QT_DEBUG
- if (qstrcmp(argv[i], "-direct3d") == 0)
- QApplication::setAttribute(Qt::AA_MSWindowsUseDirect3DByDefault);
- else
argv[j++] = argv[i];
}
if(j < priv->argc) {
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 366e576..d7ca2f4 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -402,7 +402,7 @@ extern bool qt_xdnd_dragging;
// gui or non-gui from qapplication.cpp
extern bool qt_is_gui_used;
-/*!
+/*!
\internal
Try to resolve a \a symbol from \a library with the version specified
by \a vernum.
@@ -840,7 +840,7 @@ bool QApplicationPrivate::x11_apply_settings()
}
int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
-
+
if (!appFont) {
QFont font(QApplication::font());
QString fontDescription;
@@ -1583,6 +1583,7 @@ static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0;
static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0;
static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0;
static PtrWacomConfigTerm ptrWacomConfigTerm = 0;
+Q_GLOBAL_STATIC(QByteArray, wacomDeviceName)
#endif
#endif
@@ -1952,11 +1953,17 @@ void qt_init(QApplicationPrivate *priv, int,
{
QString displayName = QLatin1String(XDisplayName(NULL));
- // apparently MITSHM only works for local displays, so do a quick check here
- // to determine whether the display is local or not (not 100 % accurate)
+ // MITSHM only works for local displays, so do a quick check here
+ // to determine whether the display is local or not (not 100 % accurate).
+ // BGR server layouts are not supported either, since it requires the raster
+ // engine to work on a QImage with BGR layout.
bool local = displayName.isEmpty() || displayName.lastIndexOf(QLatin1Char(':')) == 0;
- if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0))
- X11->use_mitshm = mitshm_pixmaps;
+ if (local && (qgetenv("QT_X11_NO_MITSHM").toInt() == 0)) {
+ Visual *defaultVisual = DefaultVisual(X11->display, DefaultScreen(X11->display));
+ X11->use_mitshm = mitshm_pixmaps && (defaultVisual->red_mask == 0xff0000
+ && defaultVisual->green_mask == 0xff00
+ && defaultVisual->blue_mask == 0xff);
+ }
}
#endif // QT_NO_MITSHM
@@ -2377,6 +2384,8 @@ void qt_init(QApplicationPrivate *priv, int,
#else
if (devs->type == ATOM(XWacomStylus)) {
deviceType = QTabletEvent::Stylus;
+ if (wacomDeviceName()->isEmpty())
+ wacomDeviceName()->append(devs->name);
gotStylus = true;
} else if (devs->type == ATOM(XWacomEraser)) {
deviceType = QTabletEvent::XFreeEraser;
@@ -4511,8 +4520,7 @@ void fetchWacomToolId(int &deviceType, qint64 &serialId)
WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0);
if (config == 0)
return;
- const char *name = "stylus"; // TODO get this from the X config instead (users may have called it differently)
- WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, name);
+ WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData());
if (device == 0)
return;
unsigned keys[1];
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index dcb3564..cf66605 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -293,9 +293,18 @@ extern "C" {
QPoint posDrag(localPoint.x, localPoint.y);
NSDragOperation nsActions = [sender draggingSourceOperationMask];
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
+ QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ if ([sender draggingSource] != nil) {
+ // modifier flags might have changed, update it here since we don't send any input events.
+ QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
+ modifiers = QApplication::keyboardModifiers();
+ } else {
+ // when the source is from another application the above technique will not work.
+ modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
+ }
// send the drag enter event to the widget.
- QDragEnterEvent qDEEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragEnterEvent qDEEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
QApplication::sendEvent(qwidget, &qDEEvent);
if (!qDEEvent.isAccepted()) {
// widget is not interested in this drag, so ignore this drop data.
@@ -303,24 +312,23 @@ extern "C" {
return NSDragOperationNone;
} else {
// send a drag move event immediately after a drag enter event (as per documentation).
- QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(qDEEvent.dropAction());
qDMEvent.accept(); // accept by default, since enter event was accepted.
QApplication::sendEvent(qwidget, &qDMEvent);
if (!qDMEvent.isAccepted() || qDMEvent.dropAction() == Qt::IgnoreAction) {
// since we accepted the drag enter event, the widget expects
// future drage move events.
- // ### check if we need to treat this like the drag enter event.
+ // ### check if we need to treat this like the drag enter event.
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDEEvent.dropAction());
} else {
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
- }
+ }
QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
- return nsActions;
+ return nsActions;
}
}
-
+
- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
{
// drag enter event was rejected, so ignore the move event.
@@ -338,11 +346,19 @@ extern "C" {
// send drag move event to the widget
QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+ if ([sender draggingSource] != nil) {
+ // modifier flags might have changed, update it here since we don't send any input events.
+ QApplicationPrivate::modifier_buttons = qt_cocoaModifiers2QtModifiers([[NSApp currentEvent] modifierFlags]);
+ modifiers = QApplication::keyboardModifiers();
+ } else {
+ // when the source is from another application the above technique will not work.
+ modifiers = qt_cocoaDragOperation2QtModifiers(nsActions);
+ }
QMimeData *mimeData = dropData;
if (QDragManager::self()->source())
mimeData = QDragManager::self()->dragPrivate()->data;
- QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData,
- QApplication::mouseButtons(), QApplication::keyboardModifiers());
+ QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
qDMEvent.accept();
QApplication::sendEvent(qwidget, &qDMEvent);
@@ -371,12 +387,12 @@ extern "C" {
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
[self addDropData:sender];
-
+
NSPoint windowPoint = [sender draggingLocation];
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
QPoint posDrop(localPoint.x, localPoint.y);
-
+
NSDragOperation nsActions = [sender draggingSourceOperationMask];
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations(nsActions);
QMimeData *mimeData = dropData;
@@ -388,6 +404,8 @@ extern "C" {
if (QDragManager::self()->object)
QDragManager::self()->dragPrivate()->target = qwidget;
QApplication::sendEvent(qwidget, &de);
+ if (QDragManager::self()->object)
+ QDragManager::self()->dragPrivate()->executed_action = de.dropAction();
if (!de.isAccepted())
return NO;
else
@@ -419,10 +437,9 @@ extern "C" {
- (void) setFrameSize:(NSSize)newSize
{
[super setFrameSize:newSize];
-
+
// A change in size has required the view to be invalidated.
- if ([self inLiveResize])
- {
+ if ([self inLiveResize]) {
NSRect rects[4];
NSInteger count;
[self getRectsExposedDuringLiveResize:rects count:&count];
@@ -430,9 +447,7 @@ extern "C" {
{
[self setNeedsDisplayInRect:rects[count]];
}
- }
- else
- {
+ } else {
[self setNeedsDisplay:YES];
}
}
@@ -567,7 +582,7 @@ extern "C" {
if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) {
QApplication::sendEvent(qwidget, &enterEvent);
qt_mouseover = qwidget;
-
+
// Update cursor and dispatch hover events.
qt_mac_update_cursor_at_global_pos(flipPoint(globalPoint).toPoint());
if (qwidget->testAttribute(Qt::WA_Hover) &&
@@ -622,7 +637,7 @@ extern "C" {
[viewsToLookAt addObject:qt_mac_nativeview_for(parentWidget)];
parentWidget = parentWidget->parentWidget();
}
-
+
// Now walk through the subviews of each view and determine which subview should
// get the event. We look through all the subviews at a given level with
// the assumption that the last item to be found the candidate has a higher z-order.
@@ -758,7 +773,7 @@ extern "C" {
if (currentIManager && [currentIManager wantsToHandleMouseEvents]) {
[currentIManager handleMouseEvent:theEvent];
}
-
+
NSPoint windowPoint = [theEvent locationInWindow];
NSPoint globalPoint = [[theEvent window] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
@@ -767,7 +782,7 @@ extern "C" {
Qt::MouseButton buttons = cocoaButton2QtButton([theEvent buttonNumber]);
bool wheelOK = false;
Qt::KeyboardModifiers keyMods = qt_cocoaModifiers2QtModifiers([theEvent modifierFlags]);
-
+
// Mouse wheel deltas seem to tick in at increments of 0.1. Qt widgets
// expect the delta to be a multiple of 120.
const int ScrollFactor = 10 * 120;
@@ -789,7 +804,7 @@ extern "C" {
wheelOK = qwe2.isAccepted();
}
}
-
+
if (deltaY) {
QWheelEvent qwe(qlocal, qglobal, deltaY, buttons, keyMods, Qt::Vertical);
qt_sendSpontaneousEvent(qwidget, &qwe);
@@ -802,7 +817,7 @@ extern "C" {
wheelOK = qwe2.isAccepted();
}
}
-
+
if (deltaZ) {
// Qt doesn't explicitly support wheels with a Z component. In a misguided attempt to
// try to be ahead of the pack, I'm adding this extra value.
@@ -891,6 +906,11 @@ extern "C" {
Q_UNUSED(anImage);
Q_UNUSED(aPoint);
qMacDnDParams()->performedAction = operation;
+ if (QDragManager::self()->object
+ && QDragManager::self()->dragPrivate()->executed_action != Qt::ActionMask) {
+ qMacDnDParams()->performedAction =
+ qt_mac_mapDropAction(QDragManager::self()->dragPrivate()->executed_action);
+ }
}
- (QWidget *)qt_qwidget
@@ -1214,13 +1234,13 @@ Qt::DropAction QDragManager::drag(QDrag *o)
so we just bail early to prevent it */
if(!(GetCurrentEventButtonState() & kEventMouseButtonPrimary))
return Qt::IgnoreAction;
-
+
if(object) {
dragPrivate()->source->removeEventFilter(this);
cancel();
beingCancelled = false;
}
-
+
object = o;
dragPrivate()->target = 0;
@@ -1232,7 +1252,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND);
dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray());
dragBoard.setMimeData(dragPrivate()->data);
-
+
// create the image
QPoint hotspot;
QPixmap pix = dragPrivate()->pixmap;
@@ -1278,6 +1298,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
NSSize mouseOffset = {0.0, 0.0};
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
NSPoint windowPoint = [dndParams->theEvent locationInWindow];
+ dragPrivate()->executed_action = Qt::ActionMask;
// do the drag
[dndParams->view retain];
[dndParams->view dragImage:image
@@ -1289,6 +1310,7 @@ Qt::DropAction QDragManager::drag(QDrag *o)
slideBack:YES];
[dndParams->view release];
[image release];
+ dragPrivate()->executed_action = Qt::IgnoreAction;
object = 0;
Qt::DropAction performedAction(qt_mac_mapNSDragOperation(dndParams->performedAction));
// do post drag processing, if required.
diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp
index f3c93c6..50b6e59 100644
--- a/src/gui/kernel/qshortcut.cpp
+++ b/src/gui/kernel/qshortcut.cpp
@@ -385,21 +385,19 @@ bool QShortcut::event(QEvent *e)
{
Q_D(QShortcut);
bool handled = false;
- if (e->type() == QEvent::Shortcut) {
+ if (d->sc_enabled && e->type() == QEvent::Shortcut) {
QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
- if (d->sc_enabled) {
#ifndef QT_NO_WHATSTHIS
- if (QWhatsThis::inWhatsThisMode()) {
- QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
- handled = true;
- } else
+ if (QWhatsThis::inWhatsThisMode()) {
+ QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
+ handled = true;
+ } else
#endif
- if (se->isAmbiguous())
- emit activatedAmbiguously();
- else
- emit activated();
- }
+ if (se->isAmbiguous())
+ emit activatedAmbiguously();
+ else
+ emit activated();
handled = true;
}
}
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 9766a69..ed9654b 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -370,8 +370,9 @@ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
default:
break;
}
-
- return true;
+ // If nextState is QKeySequence::ExactMatch && identicals.count == 0
+ // we've only found disabled shortcuts
+ return identicalMatches > 0 || result == QKeySequence::PartialMatch;
}
/*! \internal
@@ -493,7 +494,9 @@ QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e)
// We don't need partials, if we have identicals
if (d->identicals.size())
break;
- partialFound = true;
+ // We only care about enabled partials, so we don't consume
+ // key events when all partials are disabled!
+ partialFound |= (*it).enabled;
}
}
++it;
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 52e76d8..f000292 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -515,6 +515,18 @@ Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags)
return qtMods;
}
+Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations)
+{
+ Qt::KeyboardModifiers qtMods =Qt::NoModifier;
+ if (dragOperations & NSDragOperationLink)
+ qtMods |= Qt::MetaModifier;
+ if (dragOperations & NSDragOperationGeneric)
+ qtMods |= Qt::ControlModifier;
+ if (dragOperations & NSDragOperationCopy)
+ qtMods |= Qt::AltModifier;
+ return qtMods;
+}
+
static inline QEvent::Type cocoaEvent2QtEvent(NSUInteger eventType)
{
// Handle the trivial cases that can be determined from the type.
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index ef55aa4..63a301c 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -141,6 +141,7 @@ inline QApplication *qAppInstance() { return static_cast<QApplication *>(QCoreAp
struct ::TabletProximityRec;
void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec);
Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags);
+Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations);
inline int flipYCoordinate(int y)
{
return QApplication::desktop()->screenGeometry(0).height() - y;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 9f5f18d..9f0d2a4 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -183,6 +183,7 @@ QWidgetPrivate::QWidgetPrivate(int version) :
,inDirtyList(0)
,isScrolled(0)
,isMoved(0)
+ ,usesDoubleBufferedGLContext(0)
#ifdef Q_WS_WIN
,noPaintOnScreen(0)
#endif
@@ -2132,6 +2133,10 @@ QWidget *QWidget::find(WId id)
If a widget is non-native (alien) and winId() is invoked on it, that widget
will be provided a native handle.
+ On Mac OS X, the type returned depends on which framework Qt was linked
+ against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt
+ is using Cocoa, {WId} is a pointer to an NSView.
+
\note We recommend that you do not store this value as it is likely to
change at run-time.
@@ -4714,10 +4719,13 @@ void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
if (redirected) {
target = redirected;
offset -= redirectionOffset;
- if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
- const QRegion redirectedSystemClip = redirected->paintEngine()->systemClip();
- if (!redirectedSystemClip.isEmpty())
- paintRegion &= redirectedSystemClip.translated(-offset);
+ }
+
+ if (!inRenderWithPainter) { // Clip handled by shared painter (in qpainter.cpp).
+ if (QPaintEngine *targetEngine = target->paintEngine()) {
+ const QRegion targetSystemClip = targetEngine->systemClip();
+ if (!targetSystemClip.isEmpty())
+ paintRegion &= targetSystemClip.translated(-offset);
}
}
@@ -9792,27 +9800,6 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
QEvent e(QEvent::MouseTrackingChange);
QApplication::sendEvent(this, &e);
break; }
-#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
- case Qt::WA_MSWindowsUseDirect3D:
- if (!qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault)) {
- if (on) {
- if (!d->extra)
- d->createExtra();
- d->extra->had_auto_fill_bg = d->extra->autoFillBackground;
- d->extra->had_no_system_bg = testAttribute(Qt::WA_NoSystemBackground);
- d->extra->had_paint_on_screen = testAttribute(Qt::WA_PaintOnScreen);
- // enforce the opaque widget state D3D needs
- d->extra->autoFillBackground = true;
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_NoSystemBackground);
- } else if (d->extra) {
- d->extra->autoFillBackground = d->extra->had_auto_fill_bg;
- setAttribute(Qt::WA_PaintOnScreen, d->extra->had_paint_on_screen);
- setAttribute(Qt::WA_NoSystemBackground, d->extra->had_no_system_bg);
- }
- }
- break;
-#endif
case Qt::WA_NativeWindow: {
QInputContext *ic = 0;
if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) {
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 013fc1e..0f74c32 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -3995,6 +3995,33 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
}
}
+void QWidgetPrivate::applyMaxAndMinSizeConstraints(int &w, int &h)
+{
+ if (QWExtra *extra = extraData()) {
+ w = qMin(w, extra->maxw);
+ h = qMin(h, extra->maxh);
+ w = qMax(w, extra->minw);
+ h = qMax(h, extra->minh);
+
+ // Deal with size increment
+ if (QTLWExtra *top = topData()) {
+ if(top->incw) {
+ w = w/top->incw;
+ w *= top->incw;
+ }
+ if(top->inch) {
+ h = h/top->inch;
+ h *= top->inch;
+ }
+ }
+ }
+
+ if (isRealWindow()) {
+ w = qMax(0, w);
+ h = qMax(0, h);
+ }
+}
+
void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
{
Q_Q(QWidget);
@@ -4005,7 +4032,9 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
QMacCocoaAutoReleasePool pool;
bool realWindow = isRealWindow();
+
if (realWindow && !(w == 0 && h == 0) && !q->testAttribute(Qt::WA_DontShowOnScreen)) {
+ applyMaxAndMinSizeConstraints(w, h);
topData()->isSetGeometry = 1;
topData()->isMove = isMove;
#ifndef QT_MAC_USE_COCOA
@@ -4031,10 +4060,26 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
{
Q_Q(QWidget);
bool realWindow = isRealWindow();
- if(QWExtra *extra = extraData()) { // any size restrictions?
- if(realWindow) {
+
+ QPoint oldp = q->pos();
+ QSize olds = q->size();
+ const bool isResize = (olds != QSize(w, h));
+
+ if (!realWindow && !isResize && QPoint(x, y) == oldp)
+ return;
+
+ if (isResize)
+ data.window_state = data.window_state & ~Qt::WindowMaximized;
+
+ const bool visible = q->isVisible();
+ data.crect = QRect(x, y, w, h);
+
+ if (realWindow) {
+ if (QWExtra *extra = extraData()) {
+ applyMaxAndMinSizeConstraints(w, h);
qt_mac_update_sizer(q);
- if(q->windowFlags() & Qt::WindowMaximizeButtonHint) {
+
+ if (q->windowFlags() & Qt::WindowMaximizeButtonHint) {
#ifndef QT_MAC_USE_COCOA
OSWindowRef window = qt_mac_window_for(q);
if(extra->maxw && extra->maxh && extra->maxw == extra->minw
@@ -4045,43 +4090,8 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
}
#endif
}
- }
-
- w = qMin(w,extra->maxw);
- h = qMin(h,extra->maxh);
- w = qMax(w,extra->minw);
- h = qMax(h,extra->minh);
-
- // Deal with size increment
- if(QTLWExtra *top = topData()) {
- if(top->incw) {
- w = w/top->incw;
- w *= top->incw;
- }
- if(top->inch) {
- h = h/top->inch;
- h *= top->inch;
- }
- }
- }
-
- if (realWindow) {
- w = qMax(0, w);
- h = qMax(0, h);
- }
-
- QPoint oldp = q->pos();
- QSize olds = q->size();
- const bool isResize = (olds != QSize(w, h));
- if(!realWindow && !isResize && QPoint(x, y) == oldp)
- return;
- if(isResize && q->isMaximized())
- data.window_state = data.window_state & ~Qt::WindowMaximized;
- const bool visible = q->isVisible();
- data.crect = QRect(x, y, w, h);
- if(realWindow) {
- if(QWExtra *extra = extraData()) { //set constraints
+ // Update max and min constraints:
const float max_f(20000);
#ifndef QT_MAC_USE_COCOA
#define SF(x) ((x > max_f) ? max_f : x)
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 9e93f66..8731551 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -177,11 +177,6 @@ struct QWExtra {
//bit flags at the end to improve packing
#if defined(Q_WS_WIN)
uint shown_mode : 8; // widget show mode
-#ifndef QT_NO_DIRECT3D
- uint had_paint_on_screen : 1;
- uint had_no_system_bg : 1;
- uint had_auto_fill_bg : 1;
-#endif
#endif
#if defined(Q_WS_X11)
uint compress_events : 1;
@@ -257,6 +252,7 @@ public:
void macUpdateIsOpaque();
void setEnabled_helper_sys(bool enable);
bool isRealWindow() const;
+ void applyMaxAndMinSizeConstraints(int &w, int &h);
#endif
void raise_sys();
@@ -535,6 +531,7 @@ public:
uint inDirtyList : 1;
uint isScrolled : 1;
uint isMoved : 1;
+ uint usesDoubleBufferedGLContext : 1;
#ifdef Q_WS_WIN
uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index ffbb341..7374994 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -56,12 +56,6 @@
#include "private/qbackingstore_p.h"
#include "private/qwindowsurface_raster_p.h"
-#ifndef QT_NO_DIRECT3D
-#include "private/qpaintengine_d3d_p.h"
-#include "private/qwindowsurface_d3d_p.h"
-#endif
-
-
#include <qdebug.h>
#include <private/qapplication_p.h>
@@ -1716,11 +1710,6 @@ void QWidgetPrivate::createSysExtra()
#ifndef QT_NO_DRAGANDDROP
extra->dropTarget = 0;
#endif
-#ifndef QT_NO_DIRECT3D
- extra->had_auto_fill_bg = 0;
- extra->had_paint_on_screen = 0;
- extra->had_no_system_bg = 0;
-#endif
}
void QWidgetPrivate::deleteSysExtra()
@@ -1931,22 +1920,6 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level)
// };
// Q_GLOBAL_STATIC(QGlobalRasterPaintEngine, globalRasterPaintEngine)
-#ifndef QT_NO_DIRECT3D
-static void cleanup_d3d_engine();
-Q_GLOBAL_STATIC_WITH_INITIALIZER(QDirect3DPaintEngine, _qt_d3dEngine,
- {
- qAddPostRoutine(cleanup_d3d_engine);
- })
-static void cleanup_d3d_engine()
-{
- _qt_d3dEngine()->cleanup();
-}
-QDirect3DPaintEngine* qt_d3dEngine()
-{
- return _qt_d3dEngine();
-}
-#endif
-
#ifndef QT_NO_DIRECTDRAW
static uchar *qt_primary_surface_bits;
@@ -2059,19 +2032,6 @@ void qt_win_initialize_directdraw() { }
QPaintEngine *QWidget::paintEngine() const
{
-#ifndef QT_NO_DIRECT3D
- if ((qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault)
- || testAttribute(Qt::WA_MSWindowsUseDirect3D))
- && qt_d3dEngine()->hasDirect3DSupport())
- {
- QDirect3DPaintEngine *engine = qt_d3dEngine();
- if (qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault))
- engine->setFlushOnEnd(false);
- else
- engine->setFlushOnEnd(true);
- return engine;
- }
-#endif
#ifndef QT_NO_DIRECTDRAW
QOnScreenRasterPaintEngine *pe = onScreenPaintEngine();
pe->widget = this;
@@ -2100,13 +2060,6 @@ QPaintEngine *QWidget::paintEngine() const
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys()
{
Q_Q(QWidget);
-#ifndef QT_NO_DIRECT3D
- extern QDirect3DPaintEngine *qt_d3dEngine();
- if (qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault) && (q->windowOpacity() == 1.0f)
- && qt_d3dEngine()->hasDirect3DSupport()) {
- return new QD3DWindowSurface(q);
- }
-#endif
return new QRasterWindowSurface(q);
}
diff --git a/src/gui/mac/images/leopard-unified-toolbar-on.png b/src/gui/mac/images/leopard-unified-toolbar-on.png
new file mode 100644
index 0000000..6716597
--- /dev/null
+++ b/src/gui/mac/images/leopard-unified-toolbar-on.png
Binary files differ
diff --git a/src/gui/mac/maccursors.qrc b/src/gui/mac/macresources.qrc
index d80a63b..9696002 100644
--- a/src/gui/mac/maccursors.qrc
+++ b/src/gui/mac/macresources.qrc
@@ -6,4 +6,7 @@
<file>images/waitcursor.png</file>
<file>images/pluscursor.png</file>
</qresource>
+<qresource prefix="/trolltech/mac/style">
+<file>images/leopard-unified-toolbar-on.png</file>
+</qresource>
</RCC>
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 528559c..34d1779 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -103,12 +103,6 @@ win32 {
painting/qprinterinfo_win.cpp \
painting/qregion_win.cpp
!win32-borland:!wince*:LIBS += -lmsimg32
- contains(QT_CONFIG, direct3d) {
- HEADERS += painting/qpaintengine_d3d_p.h
- SOURCES += painting/qpaintengine_d3d.cpp
- RESOURCES += painting/qpaintengine_d3d.qrc
- LIBS += -ldxguid
- }
}
embedded {
@@ -362,8 +356,4 @@ embedded {
SOURCES += painting/qwindowsurface_qws.cpp
}
-win32:contains(QT_CONFIG, direct3d) {
- HEADERS += painting/qwindowsurface_d3d_p.h
- SOURCES += painting/qwindowsurface_d3d.cpp
-}
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index fbac811a..34df6c9 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -1517,13 +1517,20 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn)
extra->staticContentsSize = data.crect.size();
}
+ QPaintEngine *engine = q->paintEngine();
+ // QGLWidget does not support partial updates if:
+ // 1) The context is double buffered
+ // 2) The context is single buffered and auto-fill background is enabled.
+ const bool noPartialUpdateSupport = (engine && engine->type() == QPaintEngine::OpenGL)
+ && (usesDoubleBufferedGLContext || q->autoFillBackground());
+ QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn);
+
#ifdef Q_WS_MAC
// No difference between update() and repaint() on the Mac.
- update_sys(rgn);
+ update_sys(toBePainted);
return;
#endif
- QRegion toBePainted(rgn);
toBePainted &= clipRect();
clipToEffectiveMask(toBePainted);
if (toBePainted.isEmpty())
diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp
index 7ad0e42..4058143 100644
--- a/src/gui/painting/qmemrotate.cpp
+++ b/src/gui/painting/qmemrotate.cpp
@@ -537,6 +537,7 @@ QT_IMPL_MEMROTATE(quint32, quint24)
QT_IMPL_MEMROTATE(quint32, quint18)
QT_IMPL_MEMROTATE(quint32, quint8)
QT_IMPL_MEMROTATE(quint16, quint8)
+QT_IMPL_MEMROTATE(qrgb444, quint8)
QT_IMPL_MEMROTATE(quint8, quint8)
#ifdef QT_QWS_DEPTH_GENERIC
QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
diff --git a/src/gui/painting/qmemrotate_p.h b/src/gui/painting/qmemrotate_p.h
index bd6006b..c1eb93e 100644
--- a/src/gui/painting/qmemrotate_p.h
+++ b/src/gui/painting/qmemrotate_p.h
@@ -90,6 +90,7 @@ QT_DECL_MEMROTATE(quint32, quint24);
QT_DECL_MEMROTATE(quint32, quint18);
QT_DECL_MEMROTATE(quint32, quint8);
QT_DECL_MEMROTATE(quint16, quint8);
+QT_DECL_MEMROTATE(qrgb444, quint8);
QT_DECL_MEMROTATE(quint8, quint8);
#ifdef QT_QWS_DEPTH_GENERIC
QT_DECL_MEMROTATE(quint32, qrgb_generic16);
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index ad09060..7de1ec4 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -949,8 +949,8 @@ void QPaintEngine::setSystemClip(const QRegion &region)
Q_D(QPaintEngine);
d->systemClip = region;
// Be backward compatible and only call d->systemStateChanged()
- // if we currently have a system transform set.
- if (d->hasSystemTransform) {
+ // if we currently have a system transform/viewport set.
+ if (d->hasSystemTransform || d->hasSystemViewport) {
d->transformSystemClip();
d->systemStateChanged();
}
diff --git a/src/gui/painting/qpaintengine_d3d.cpp b/src/gui/painting/qpaintengine_d3d.cpp
deleted file mode 100644
index 9a7638b..0000000
--- a/src/gui/painting/qpaintengine_d3d.cpp
+++ /dev/null
@@ -1,4576 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include "qpaintengine_d3d_p.h"
-
-#include "private/qdrawhelper_p.h"
-#include "private/qfont_p.h"
-#include "private/qfontengine_p.h"
-#include "private/qpaintengine_p.h"
-#include "private/qtessellator_p.h"
-#include <private/qbezier_p.h>
-#include <private/qpainter_p.h>
-#include <private/qpixmap_raster_p.h>
-#include <private/qpolygonclipper_p.h>
-#include <qbuffer.h>
-#include <qcache.h>
-#include <qdir.h>
-#include <qfileinfo.h>
-#include <qlibrary.h>
-#include <qlibraryinfo.h>
-#include <qmath.h>
-#include <qpaintdevice.h>
-#include <qpixmapcache.h>
-
-#include <qwidget.h>
-#include <d3d9.h>
-#include <d3dx9.h>
-
-#include <mmintrin.h>
-#include <xmmintrin.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef M_PI
- #define M_PI 3.14159265358979323846
-#endif
-
-#define QD3D_MASK_MARGIN 1
-#define QD3D_BATCH_SIZE 256
-
-// for the ClearType detection stuff..
-#ifndef SPI_GETFONTSMOOTHINGTYPE
-#define SPI_GETFONTSMOOTHINGTYPE 0x200A
-#endif
-
-#ifndef FE_FONTSMOOTHINGCLEARTYPE
-#define FE_FONTSMOOTHINGCLEARTYPE 0x0002
-#endif
-
-//#include <performance.h>
-#define PM_INIT
-#define PM_MEASURE(A)
-#define PM_DISPLAY
-
-//debugging
-//#define QT_DEBUG_VERTEXBUFFER_ACCESS
-//#define QT_DEBUG_D3D
-//#define QT_DEBUG_D3D_CALLS
-
-#define QD3D_SET_MARK(output) \
- D3DPERF_SetMarker(0, QString(output).utf16());
-
-#define QT_VERTEX_RESET_LIMIT 24576
-#define QT_VERTEX_BUF_SIZE 32768
-#define QD3DFVF_CSVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEXCOORDSIZE4(1))
-
-// this is a different usage of the effect framework than intended,
-// but it's convenient for us to use (See effect file)
-#define PASS_STENCIL_ODDEVEN 0
-#define PASS_STENCIL_WINDING 1
-#define PASS_STENCIL_DRAW 2
-#define PASS_STENCIL_DRAW_DIRECT 3
-#define PASS_STENCIL_CLIP 4
-#define PASS_STENCIL_NOSTENCILCHECK 5
-#define PASS_STENCIL_NOSTENCILCHECK_DIRECT 6
-#define PASS_TEXT 7
-#define PASS_CLEARTYPE_TEXT 8
-#define PASS_ALIASED_LINES 9
-#define PASS_ALIASED_LINES_DIRECT 10
-
-#define PASS_AA_CREATEMASK 0
-#define PASS_AA_DRAW 1
-#define PASS_AA_DRAW_DIRECT 2
-
-#define D3D_STAGE_COUNT 2
-#define D3D_RENDER_STATES 210
-#define D3D_TEXTURE_STATES 33
-#define D3D_SAMPLE_STATES 14
-
-
-typedef HRESULT (APIENTRY *PFND3DXCREATEBUFFER)(DWORD, LPD3DXBUFFER *);
-typedef HRESULT (APIENTRY *PFND3DXCREATEEFFECT)(LPDIRECT3DDEVICE9, LPCVOID, UINT, CONST D3DXMACRO *,
- LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL,
- LPD3DXEFFECT *, LPD3DXBUFFER *);
-typedef D3DXMATRIX *(APIENTRY *PFND3DXMATRIXORTHOOFFCENTERLH)(D3DMATRIX *, FLOAT, FLOAT,
- FLOAT, FLOAT, FLOAT, FLOAT);
-typedef IDirect3D9 *(APIENTRY *PFNDIRECT3DCREATE9)(uint);
-
-static PFNDIRECT3DCREATE9 pDirect3DCreate9 = 0;
-static PFND3DXCREATEBUFFER pD3DXCreateBuffer = 0;
-static PFND3DXCREATEEFFECT pD3DXCreateEffect = 0;
-static PFND3DXMATRIXORTHOOFFCENTERLH pD3DXMatrixOrthoOffCenterLH = 0;
-
-
-class QD3DSurfaceManager : public QObject {
- Q_OBJECT
-
-public:
- enum QD3DSurfaceManagerStatus {
- NoStatus = 0,
- NeedsResetting = 0x01,
- MaxSizeChanged = 0x02
- };
-
- QD3DSurfaceManager();
- ~QD3DSurfaceManager();
-
- void init(LPDIRECT3D9 object);
-
- void setPaintDevice(QPaintDevice *pd);
-
- int status() const;
- void reset();
-
- LPDIRECT3DSURFACE9 renderTarget();
-
- LPDIRECT3DSURFACE9 surface(QPaintDevice *pd);
- LPDIRECT3DSWAPCHAIN9 swapChain(QPaintDevice *pd);
- void releasePaintDevice(QPaintDevice *pd);
-
- LPDIRECT3DDEVICE9 device();
- void cleanup();
-
- QSize maxSize() const;
-
-private:
- struct D3DSwapChain {
- QSize size;
- LPDIRECT3DSWAPCHAIN9 swapchain;
- LPDIRECT3DSURFACE9 surface;
- };
-
- void updateMaxSize();
- void initPresentParameters(D3DPRESENT_PARAMETERS *params);
- D3DSwapChain *createSwapChain(QWidget *w);
-
- QSize m_max_size;
- int m_status;
- QMap<QPaintDevice *, D3DSwapChain *> m_swapchains;
-
- LPDIRECT3DDEVICE9 m_device;
- QPaintDevice *m_pd;
- HWND m_dummy;
- D3DSwapChain *m_current;
-
-private Q_SLOTS:
- void cleanupPaintDevice(QObject *);
-};
-
-struct vertex {
- D3DVECTOR pos;
- DWORD color;
- FLOAT s0, t0, r0, q0;
- FLOAT s1, t1, r1, q1;
-};
-
-struct QD3DMaskPosition {
- int x, y, channel;
-};
-
-
-struct QD3DBatchItem {
- enum QD3DBatchInfo {
- BI_WINDING = 0x0001,
- BI_AA = 0x0002,
- BI_BRECT = 0x0004,
- BI_MASKFULL = 0x0008,
- BI_TEXT = 0x0010,
- BI_MASK = 0x0020,
- BI_CLIP = 0x0040,
- BI_SCISSOR = 0x0080,
-
- BI_PIXMAP = 0x0100,
- BI_IMAGE = 0x0200,
- BI_COMPLEXBRUSH = 0x0400,
-
- BI_CLEARCLIP = 0x0800, // clip nothing (filling the clip mask with 0)
- BI_TRANSFORM = 0x1000,
- BI_MASKSCISSOR = 0x2000,
- BI_FASTLINE = 0x4000,
- BI_COSMETICPEN = 0x8000
- };
-
- int m_info;
-
- int m_count;
- int m_offset;
-
- QD3DMaskPosition m_maskpos;
- qreal m_xoffset;
- qreal m_yoffset;
- qreal m_opacity;
-
- QPixmap m_pixmap;
- QRectF m_brect;
- QBrush m_brush;
-
- IDirect3DTexture9 *m_texture;
-
- qreal m_width;
- qreal m_distance;
-
- QTransform m_matrix;
- QPainter::CompositionMode m_cmode;
-
- QVector<int> m_pointstops;
-};
-
-struct QD3DBatch {
- int m_item_index;
- QD3DBatchItem items[QD3D_BATCH_SIZE];
-};
-
-class QD3DStateManager;
-class QD3DFontCache;
-class QD3DDrawHelper;
-class QD3DGradientCache;
-
-class QDirect3DPaintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QDirect3DPaintEngine)
-
-public:
- enum RenderTechnique {
- RT_NoTechnique,
- RT_Antialiased,
- RT_Aliased,
- };
-
- QDirect3DPaintEnginePrivate()
- : m_d3d_object(0)
- , m_d3d_device(0)
- , m_txop(QTransform::TxNone)
- , m_effect(0)
- , m_flush_on_end(0)
- { init(); }
-
- ~QDirect3DPaintEnginePrivate();
-
- bool init();
- void initDevice();
-
- inline QD3DBatchItem *nextBatchItem();
-
- QPolygonF brushCoordinates(const QRectF &r, bool stroke, qreal *fp) const;
- void fillAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform);
- void fillAntialiasedPath(const QPainterPath &path, const QRectF &brect,
- const QTransform &txform, bool stroke);
- void fillPath(const QPainterPath &path, QRectF brect);
-
- void strokePath(const QPainterPath &path, QRectF brect, bool simple = false);
- QPainterPath strokePathFastPen(const QPainterPath &path);
- void strokeAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform);
-
- void flushBatch();
- int flushAntialiased(int offset);
- void flushAliased(QD3DBatchItem *item, int offset);
- void flushText(QD3DBatchItem *item, int offset);
- void flushLines(QD3DBatchItem *item, int offset);
-
- void updateTransform(const QTransform &matrix);
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &pen);
- void updateClipRegion(const QRegion &clipregion, Qt::ClipOperation op = Qt::ReplaceClip);
- void updateClipPath(const QPainterPath &clipregion, Qt::ClipOperation op = Qt::ReplaceClip);
- void updateFont(const QFont &font);
-
- void setRenderTechnique(RenderTechnique technique);
-
- QPointF transformPoint(const QPointF &p, qreal *w) const;
-
- bool prepareBatch(QD3DBatchItem *item, int offset);
- void prepareItem(QD3DBatchItem *item);
- void cleanupItem(QD3DBatchItem *item);
- void setCompositionMode(QPainter::CompositionMode mode);
-
- void verifyTexture(const QPixmap &pixmap);
-
- bool isFastRect(const QRectF &rect);
-
- void releaseDC();
-
- void cleanup();
- bool testCaps();
-
- QPixmap getPattern(Qt::BrushStyle style) const;
-
- // clipping
- QPainterPath m_sysclip_path;
- QPainterPath m_clip_path;
- QRegion m_sysclip_region;
- QRegion m_clip_region;
-
- qreal m_opacity;
- D3DCOLOR m_opacity_color;
-
- int m_current_state;
-
- ID3DXEffect* m_effect;
-
- RenderTechnique m_current_technique;
-
- QTransform m_matrix;
- qreal m_inv_scale;
-
- QPen m_pen;
- Qt::BrushStyle m_pen_brush_style;
- QTransform m_inv_pen_matrix;
- D3DCOLOR m_pen_color;
- qreal m_pen_width;
-
- QBrush m_brush;
- Qt::BrushStyle m_brush_style;
- QTransform m_inv_brush_matrix;
- D3DCOLOR m_brush_color;
- QTransform m_brush_origin;
-
- uint m_clipping_enabled : 1;
- uint m_has_complex_clipping : 1;
- uint m_cleartype_text: 1;
- uint m_has_pen : 1;
- uint m_has_cosmetic_pen : 1;
- uint m_has_brush : 1;
- uint m_has_fast_pen : 1;
- uint m_has_aa_fast_pen : 1;
- uint m_flush_on_end : 1;
- uint m_supports_d3d : 1;
-
- QTransform::TransformationType m_txop;
-
- QPainter::CompositionMode m_cmode;
-
- QD3DSurfaceManager m_surface_manager;
- QSize m_surface_size;
-
- LPDIRECT3D9 m_d3d_object;
- LPDIRECT3DDEVICE9 m_d3d_device;
- IDirect3DSurface9 *m_current_surface;
- bool m_in_scene;
-
- QD3DGradientCache *m_gradient_cache;
- QD3DDrawHelper *m_draw_helper;
- QD3DBatch m_batch;
- QD3DStateManager *m_statemanager;
-
- HDC m_dc;
- IDirect3DSurface9 *m_dcsurface;
-
- QMap<Qt::BrushStyle, QPixmap> m_patterns;
-};
-
-
-class QD3DStateManager : public ID3DXEffectStateManager {
-public:
- QD3DStateManager(LPDIRECT3DDEVICE9 pDevice, ID3DXEffect *effect);
- void reset();
-
- inline void startStateBlock();
- inline void endStateBlock();
-
- inline void setCosmeticPen(bool enabled);
- inline void setBrushMode(int mode);
- inline void setTexture(LPDIRECT3DBASETEXTURE9 pTexture);
- inline void setTexture(LPDIRECT3DBASETEXTURE9 pTexture, QGradient::Spread spread);
- inline void setTransformation(const QTransform *matrix = 0);
- inline void setProjection(const D3DXMATRIX *pMatrix);
- inline void setMaskChannel(int channel);
- inline void setMaskOffset(qreal x, qreal y);
- inline void setFocalDistance(const qreal &fd);
-
- inline void beginPass(int pass);
- inline void endPass();
-
- STDMETHOD(QueryInterface)(REFIID iid, LPVOID *ppv);
- STDMETHOD_(ULONG, AddRef)();
- STDMETHOD_(ULONG, Release)();
-
- STDMETHOD(SetTransform)(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix);
- STDMETHOD(SetMaterial)(CONST D3DMATERIAL9 *pMaterial);
- STDMETHOD(SetLight)(DWORD Index, CONST D3DLIGHT9 *pLight);
- STDMETHOD(LightEnable)(DWORD Index, BOOL Enable);
- STDMETHOD(SetRenderState)(D3DRENDERSTATETYPE State, DWORD Value);
- STDMETHOD(SetTexture)(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture);
- STDMETHOD(SetTextureStageState)(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
- STDMETHOD(SetSamplerState)(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
- STDMETHOD(SetNPatchMode)(FLOAT NumSegments);
- STDMETHOD(SetFVF)(DWORD FVF);
- STDMETHOD(SetVertexShader)(LPDIRECT3DVERTEXSHADER9 pShader);
- STDMETHOD(SetVertexShaderConstantF)(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount);
- STDMETHOD(SetVertexShaderConstantI)(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount);
- STDMETHOD(SetVertexShaderConstantB)(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount);
- STDMETHOD(SetPixelShader)(LPDIRECT3DPIXELSHADER9 pShader);
- STDMETHOD(SetPixelShaderConstantF)(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount);
- STDMETHOD(SetPixelShaderConstantI)(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount);
- STDMETHOD(SetPixelShaderConstantB)(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount);
-private:
- LPDIRECT3DVERTEXSHADER9 m_vertexshader;
- LPDIRECT3DPIXELSHADER9 m_pixelshader;
-
- LPDIRECT3DBASETEXTURE9 m_textures[D3D_STAGE_COUNT];
- DWORD m_texturestates[D3D_STAGE_COUNT][D3D_TEXTURE_STATES];
- DWORD m_samplerstates[D3D_STAGE_COUNT][D3D_SAMPLE_STATES];
- DWORD m_renderstate[D3D_RENDER_STATES];
-
- qreal m_radgradfd;
-
- bool m_cosmetic_pen;
- int m_pass;
- int m_maskchannel;
- int m_brushmode;
- LPDIRECT3DBASETEXTURE9 m_texture;
- D3DXMATRIX m_projection;
-
- D3DXMATRIX m_d3dIdentityMatrix;
- bool m_isIdentity;
- QTransform m_transformation;
-
- LPDIRECT3DDEVICE9 m_pDevice;
- ID3DXEffect *m_effect;
-
- LONG m_refs;
- bool m_changed;
- qreal m_xoffset, m_yoffset;
- static int m_mask_channels[4][4];
-};
-
-//
-// font cache stuff
-//
-
-struct QD3DGlyphCoord {
- // stores the offset and size of a glyph texture
- qreal x;
- qreal y;
- qreal width;
- qreal height;
- qreal log_width;
- qreal log_height;
- QFixed x_offset;
- QFixed y_offset;
-};
-
-struct QD3DFontTexture {
- int x_offset; // current glyph offset within the texture
- int y_offset;
- int width;
- int height;
- IDirect3DTexture9 *texture;
-};
-
-typedef QHash<glyph_t, QD3DGlyphCoord*> QD3DGlyphHash;
-typedef QHash<QFontEngine*, QD3DGlyphHash*> QD3DFontGlyphHash;
-typedef QHash<quint64, QD3DFontTexture*> QD3DFontTexHash;
-
-class QD3DGlyphCache : public QObject
-{
- Q_OBJECT
-public:
- QD3DGlyphCache()
- : QObject(0)
- , current_cache(0) {}
- ~QD3DGlyphCache();
- QD3DGlyphCoord *lookup(QFontEngine *, glyph_t);
- void cacheGlyphs(QDirect3DPaintEngine *, const QTextItemInt &, const QVarLengthArray<glyph_t> &,
- bool);
- void cleanCache();
- inline QD3DFontTexture *fontTexture(QFontEngine *engine) {
- return font_textures.constFind(reinterpret_cast<quint64>(engine)).value();
- }
-
-public slots:
- void fontEngineDestroyed(QObject *);
-
-private:
- QImage clearTypeGlyph(QFontEngine *, glyph_t glyph);
- QD3DGlyphHash *current_cache;
- QD3DFontTexHash font_textures;
- QD3DFontGlyphHash font_cache;
-};
-
-QD3DGlyphCache::~QD3DGlyphCache()
-{
-}
-
-QD3DGlyphCoord *QD3DGlyphCache::lookup(QFontEngine *, glyph_t g)
-{
- Q_ASSERT(current_cache != 0);
- QD3DGlyphHash::const_iterator it = current_cache->constFind(g);
- if (it == current_cache->constEnd())
- return 0;
- return it.value();
-}
-
-void QD3DGlyphCache::cleanCache()
-{
- QList<quint64> keys = font_textures.keys();
- for (int i=0; i<keys.size(); ++i)
- font_textures.value(keys.at(i))->texture->Release();
-
- qDeleteAll(font_textures);
- qDeleteAll(font_cache);
- font_textures.clear();
- font_cache.clear();
- current_cache = 0;
-}
-
-void QD3DGlyphCache::fontEngineDestroyed(QObject *object)
-{
-// qDebug() << "=> font engine destroyed: " << object;
- QFontEngine *engine = static_cast<QFontEngine *>(object);
-
- QD3DFontGlyphHash::iterator cache_it = font_cache.find(engine);
- if (cache_it != font_cache.end()) {
- QD3DGlyphHash *cache = font_cache.take(engine);
- delete cache;
- }
-
- quint64 font_key = reinterpret_cast<quint64>(engine);
- QD3DFontTexture *tex = font_textures.take(font_key);
- if (tex) {
- tex->texture->Release();
- delete tex;
- }
-}
-
-QImage QD3DGlyphCache::clearTypeGlyph(QFontEngine *engine, glyph_t glyph)
-{
- glyph_metrics_t gm = engine->boundingBox(glyph);
- int glyph_x = qFloor(gm.x.toReal());
- int glyph_y = qFloor(gm.y.toReal());
- int glyph_width = qCeil((gm.x + gm.width).toReal()) - glyph_x + 2;
- int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y + 2;
-
- if (glyph_width + glyph_x <= 0 || glyph_height <= 0)
- return QImage();
- QImage im(glyph_width + glyph_x, glyph_height, QImage::Format_ARGB32_Premultiplied);
- im.fill(0xff000000); // solid black
- QPainter p(&im);
-
- p.setPen(Qt::white);
- p.setBrush(Qt::NoBrush);
-
- QTextItemInt ti;
- ti.ascent = engine->ascent();
- ti.descent = engine->descent();
- ti.width = glyph_width;
- ti.fontEngine = engine;
-
- QGlyphLayoutArray<1> glyphLayout;
- ti.glyphs = glyphLayout;
- ti.glyphs.glyphs[0] = glyph;
- ti.glyphs.advances_x[0] = glyph_width;
- p.drawTextItem(QPointF(-glyph_x, -glyph_y), ti);
- p.end();
- return im;
-}
-
-#if 0
-static void dump_font_texture(QD3DFontTexture *tex)
-{
- QColor color(Qt::red);
- D3DLOCKED_RECT rect;
- if (FAILED(tex->texture->LockRect(0, &rect, 0, 0))) {
- qDebug() << "debug: unable to lock texture rect.";
- return;
- }
-
-// cleartype version
-// uint *tex_data = (uint *) rect.pBits;
-// QImage im(tex->width, tex->height, QImage::Format_ARGB32);
-// for (int y=0; y<tex->height; ++y) {
-// for (int x=0; x<tex->width; ++x) {
-// im.setPixel(x, y, ((*(tex_data+x+y*tex->width))));
-// }
-// }
- uchar *tex_data = (uchar *) rect.pBits;
- QImage im(rect.Pitch, tex->height, QImage::Format_ARGB32);
- for (int y=0; y<tex->height; ++y) {
- for (int x=0; x<rect.Pitch; ++x) {
- uchar val = ((*(tex_data+x+y*rect.Pitch)));
- im.setPixel(x, y, 0xff000000 | (val << 16) | (val << 8) | val);
- }
- }
- tex->texture->UnlockRect(0);
- static int i= 0;
- im.save(QString("tx%1.png").arg(i++));
-}
-#endif
-
-void QD3DGlyphCache::cacheGlyphs(QDirect3DPaintEngine *engine, const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs, bool clearType)
-{
- IDirect3DDevice9 *device = engine->d_func()->m_d3d_device;
- QD3DFontGlyphHash::const_iterator cache_it = font_cache.constFind(ti.fontEngine);
- QD3DGlyphHash *cache = 0;
- if (cache_it == font_cache.constEnd()) {
- cache = new QD3DGlyphHash;
- font_cache.insert(ti.fontEngine, cache);
- connect(ti.fontEngine, SIGNAL(destroyed(QObject *)), SLOT(fontEngineDestroyed(QObject *)));
- } else {
- cache = cache_it.value();
- }
-
- current_cache = cache;
-
- D3DFORMAT tex_format = clearType ? D3DFMT_A8R8G8B8 : D3DFMT_A8;
- quint64 font_key = reinterpret_cast<quint64>(ti.fontEngine);
- QD3DFontTexHash::const_iterator it = font_textures.constFind(font_key);
- QD3DFontTexture *font_tex = 0;
- if (it == font_textures.constEnd()) {
- // alloc a new texture, put it into the cache
- int tex_height = qCeil(ti.ascent.toReal() + ti.descent.toReal()) + 5;
- int tex_width = tex_height * 30; // ###
- IDirect3DTexture9 *tex;
- if (FAILED(device->CreateTexture(tex_width, tex_height, 1, 0,
- tex_format, D3DPOOL_MANAGED, &tex, NULL)))
- {
- qWarning("QD3DGlyphCache::cacheGlyphs(): can't allocate font texture (%dx%d).",
- tex_width, tex_height);
- return;
- } else {
-// qDebug() << "=> new font texture: " << QSize(tex_width,tex_height);
- font_tex = new QD3DFontTexture;
- font_tex->texture = tex;
- font_tex->x_offset = 0;
- font_tex->y_offset = 0;
- font_tex->width = tex_width;
- font_tex->height = tex_height;
- font_textures.insert(font_key, font_tex);
- }
- } else {
- font_tex = it.value();
- // make it current render target..
- }
-
- // cache each glyph
- for (int i=0; i<glyphs.size(); ++i) {
- QD3DGlyphHash::const_iterator it = cache->constFind(glyphs[i]);
- if (it == cache->constEnd()) {
- glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);
- int glyph_width = qCeil(metrics.width.toReal()) + 5;
- int glyph_height = qCeil(ti.ascent.toReal() + ti.descent.toReal()) + 5;
- if (font_tex->x_offset + glyph_width > font_tex->width) {
- // no room on the current line, start new glyph strip
- int strip_height = glyph_height;
- font_tex->x_offset = 0;
- font_tex->y_offset += strip_height;
- if (font_tex->y_offset >= font_tex->height) {
- // if no room in the current texture - realloc a larger texture
- int old_tex_height = font_tex->height;
- font_tex->height += strip_height;
-
- IDirect3DTexture9 *new_tex;
- if (FAILED(device->CreateTexture(font_tex->width, font_tex->height, 1, 0,
- tex_format, D3DPOOL_MANAGED, &new_tex, NULL)))
- {
- qWarning("QD3DGlyphCache(): can't re-allocate font texture.");
- return;
- } else {
-// qDebug() << " -> new glyph strip added:" << QSize(font_tex->width,font_tex->height);
-
- D3DLOCKED_RECT new_rect, old_rect;
- if (FAILED(font_tex->texture->LockRect(0, &old_rect, 0, D3DLOCK_READONLY))) {
- qDebug() << "QD3DGlyphCache: unable to lock texture rect.";
- return;
- }
- if (FAILED(new_tex->LockRect(0, &new_rect, 0, 0))) {
- qDebug() << "QD3DGlyphCache: unable to lock texture rect.";
- return;
- }
- memcpy(new_rect.pBits, old_rect.pBits, new_rect.Pitch * old_tex_height);
- font_tex->texture->UnlockRect(0);
- new_tex->UnlockRect(0);
- engine->d_func()->flushBatch();
- font_tex->texture->Release();
- font_tex->texture = new_tex;
- }
-
- // update the texture coords and the y offset for the existing glyphs in
- // the cache, because of the texture size change
- QD3DGlyphHash::iterator it = cache->begin();
- while (it != cache->end()) {
- it.value()->height = (it.value()->height * old_tex_height) / font_tex->height;
- it.value()->y = (it.value()->y * old_tex_height) / font_tex->height;
- ++it;
- }
- }
- }
- QD3DGlyphCoord *d3d_glyph = new QD3DGlyphCoord;
- d3d_glyph->x = qreal(font_tex->x_offset) / font_tex->width;
- d3d_glyph->y = qreal(font_tex->y_offset) / font_tex->height;
- d3d_glyph->width = qreal(glyph_width) / font_tex->width;
- d3d_glyph->height = qreal(glyph_height) / font_tex->height;
- d3d_glyph->log_width = d3d_glyph->width * font_tex->width;
- d3d_glyph->log_height = d3d_glyph->height * font_tex->height;
- d3d_glyph->x_offset = -metrics.x;
- d3d_glyph->y_offset = metrics.y;
-
- QImage glyph_im;
- if (clearType)
- glyph_im = clearTypeGlyph(ti.fontEngine, glyphs[i]);
- else
- glyph_im = ti.fontEngine->alphaMapForGlyph(glyphs[i]).convertToFormat(QImage::Format_Indexed8);
-
- // write glyph to texture
- D3DLOCKED_RECT rect;
- RECT glyph_rect = { font_tex->x_offset, font_tex->y_offset,
- font_tex->x_offset + glyph_im.width(),
- font_tex->y_offset + glyph_im.height() };
-
-// qDebug() << " > new glyph char added:" << QSize(glyph_im.width(), glyph_im.height());
- if (FAILED(font_tex->texture->LockRect(0, &rect, &glyph_rect, 0))) {
- qDebug() << "QD3DGlyphCache: unable to lock texture rect.";
- return;
- }
-
- // ### unify these loops
- if (clearType) {
- int ppl = rect.Pitch / 4;
- uint *tex_data = (uint *) rect.pBits;
- for (int y=0; y<glyph_im.height(); ++y) {
- uint *s = (uint *) glyph_im.scanLine(y);
- for (int x=0; x<glyph_im.width(); ++x) {
- tex_data[ppl*y + x] = *s;
- ++s;
- }
- }
- } else {
- int ppl = rect.Pitch;
- uchar *tex_data = (uchar *) rect.pBits;
- for (int y=0; y<glyph_im.height(); ++y) {
- uchar *s = (uchar *) glyph_im.scanLine(y);
- for (int x=0; x<glyph_im.width(); ++x) {
- tex_data[ppl*y + x] = *s;
- ++s;
- }
- }
- }
- font_tex->texture->UnlockRect(0);
-
- // debug
-// dump_font_texture(font_tex);
-
- if (font_tex->x_offset + glyph_width > font_tex->width) {
- font_tex->x_offset = 0;
- font_tex->y_offset += glyph_height;
- } else {
- font_tex->x_offset += glyph_width;
- }
-
- cache->insert(glyphs[i], d3d_glyph);
- }
- }
-}
-
-Q_GLOBAL_STATIC(QD3DGlyphCache, qd3d_glyph_cache)
-
-//
-// end font caching stuff
-//
-
-
-//
-// D3D image cache stuff
-//
-
-// ### keep the GL stuff in mind..
-typedef void (*_qt_image_cleanup_hook_64)(qint64);
-extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64;
-
-static void qd3d_image_cleanup(qint64 key);
-
-class QD3DImage
-{
-public:
- QD3DImage(IDirect3DDevice9 *device, const QImage &image);
- ~QD3DImage();
-
- IDirect3DTexture9 *texture;
-};
-
-static QList<IDirect3DTexture9 *> qd3d_release_list;
-
-QD3DImage::QD3DImage(IDirect3DDevice9 *device, const QImage &image)
-{
- texture = 0;
- Q_ASSERT(device);
- QImage im = image.convertToFormat(QImage::Format_ARGB32);
- if (FAILED(device->CreateTexture(im.width(), im.height(), 1, 0,
- D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, 0))) {
- qWarning("QD3DImage(): unable to create Direct3D texture.");
- return;
- }
-// qDebug(" -> created image texture: %p - 0x%08x%08x",texture,uint (image.cacheKey() >> 32),uint (image.cacheKey() & 0xffffffff));
- D3DLOCKED_RECT rect;
- if (FAILED(texture->LockRect(0, &rect, 0, 0))) {
- qDebug() << "QD3DImage: unable to lock texture rect.";
- return;
- }
- DWORD *dst = (DWORD *) rect.pBits;
- DWORD *src = (DWORD *) im.scanLine(0);
-
- Q_ASSERT((rect.Pitch/4) == (im.bytesPerLine()/4));
- memcpy(dst, src, rect.Pitch*im.height());
- texture->UnlockRect(0);
-}
-
-QD3DImage::~QD3DImage()
-{
- if (texture)
- qd3d_release_list.append(texture);
-}
-
-static int qd3d_cache_limit = 64*1024; // cache ~64 MB worth of textures
-typedef QCache<quint64, QD3DImage> QD3DImageCache;
-
-class QD3DImageManager
-{
-public:
- QD3DImageManager() {
- // ### GL does the same!
- qt_image_cleanup_hook_64 = qd3d_image_cleanup;
- cache.setMaxCost(qd3d_cache_limit);
- }
- ~QD3DImageManager() {
-// qDebug() << "unhooking d3d image cache";
- qt_image_cleanup_hook_64 = 0;
- cache.clear();
- }
-
- IDirect3DTexture9 *lookup(IDirect3DDevice9 *device, const QImage &image);
- void remove(quint64 key);
-
-private:
- QD3DImageCache cache;
-};
-
-IDirect3DTexture9 *QD3DImageManager::lookup(IDirect3DDevice9 *device, const QImage &image)
-{
- QD3DImage *tex_image = 0;
-
- tex_image = cache.object(image.cacheKey());
- if (!tex_image) {
- // to avoid cache thrashing we remove images from the cache
- // that have the same serial no as the cached image, since
- // that image is most likely destoyed already, and we got a
- // stale cache entry
- uint serial = (uint) (image.cacheKey() >> 32);
- QList<quint64> keys = cache.keys();
- for (int i=0; i<keys.size(); ++i) {
- if ((uint)(keys.at(i) >> 32) == serial) {
- cache.remove(keys.at(i));
- break;
- }
- }
-// qDebug(" => cached: %d, adding cache image: 0x%08x%08x",cache.size(), uint (image.cacheKey() >> 32),uint (image.cacheKey() & 0xffffffff));
- // add cache entry
- int cost = image.width()*image.height()*4/1024;
- if (cache.totalCost() + cost > cache.maxCost()) {
- // no room for new entries? kick out half the cached images
- int old_max_cost = cache.maxCost();
- cache.setMaxCost(old_max_cost/2);
- cache.setMaxCost(old_max_cost);
- }
- tex_image = new QD3DImage(device, image);
- cache.insert(image.cacheKey(), tex_image, cost);
-// qDebug() << "==> total cache cost: " << cache.totalCost() << cost;
- }
-
- return tex_image->texture;
-}
-
-void QD3DImageManager::remove(quint64 key)
-{
-// QList<quint64> keys = cache.keys();
-// if (keys.contains(key))
-// qDebug() << "entery removed from cache";
- cache.remove(key);
-}
-
-Q_GLOBAL_STATIC(QD3DImageManager, qd3d_image_cache)
-
-static void qd3d_image_cleanup(qint64 key)
-{
-// qDebug() << "qd3d_image_cleanup:";
-// qDebug(" => key: 0x%08x%08x", (uint) (key >> 32), (uint)(key & 0xffffffff));
- qd3d_image_cache()->remove(key);
-}
-
-//
-// end D3D image cache stuff
-//
-
-class QD3DDrawHelper : public QTessellator
-{
-public:
- QD3DDrawHelper(QDirect3DPaintEnginePrivate *pe);
- ~QD3DDrawHelper();
-
- bool needsFlushing() const;
- QD3DMaskPosition allocateMaskPosition(const QRectF &brect, bool *breakbatch);
-
- void setClipPath(const QPainterPath &path, QD3DBatchItem **item);
-
- void queueAntialiasedMask(const QPolygonF &poly, QD3DBatchItem **item, const QRectF &brect);
- QRectF queueAliasedMask(const QPainterPath &path, QD3DBatchItem **item, D3DCOLOR color);
-
- void queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color, const QPolygonF &trect);
- void queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color);
-
- void queueTextGlyph(const QRectF &rect, const qreal *tex_coords, QD3DBatchItem *item,
- D3DCOLOR color);
-
- void queueAntialiasedLines(const QPainterPath &path, QD3DBatchItem **item, const QRectF &brect);
- void queueAliasedLines(const QLineF *lines, int lineCount, QD3DBatchItem **item);
-
- int drawAntialiasedMask(int offset, int maxoffset);
- void drawAliasedMask(int offset);
- void drawAntialiasedBoundingRect(QD3DBatchItem *item);
- void drawAliasedBoundingRect(QD3DBatchItem *item);
- void drawTextItem(QD3DBatchItem *item);
- void drawAliasedLines(QD3DBatchItem *item);
-
- void setMaskSize(QSize size);
-
- void beforeReset();
- void afterReset();
-
- IDirect3DSurface9 *freeMaskSurface();
-
- inline void lockVertexBuffer();
- inline void unlockVertexBuffer();
-
- inline int index() { return m_index; }
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- enum VertexBufferAccess {
- CLEAR = 0x00,
- READ = 0x01,
- WRITE = 0x02
- };
- int accesscontrol[QT_VERTEX_BUF_SIZE];
-#endif
-
-private:
- void addTrap(const Trapezoid &trap);
- void tessellate(const QPolygonF &poly);
- inline void lineToStencil(qreal x, qreal y);
- inline void curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep);
- QRectF pathToVertexArrays(const QPainterPath &path);
- void resetMask();
-
- QDirect3DPaintEnginePrivate *m_pe;
-
- qreal m_xoffset, m_yoffset;
- int m_startindex;
- int m_index;
- int m_height, m_width;
- LPDIRECT3DVERTEXBUFFER9 m_d3dvbuff;
- vertex *m_vbuff;
- QD3DBatchItem *m_item;
- QRectF m_boundingRect;
-
- qreal max_x;
- qreal max_y;
- qreal min_x;
- qreal min_y;
- qreal firstx;
- qreal firsty;
-
- QPointF tess_lastpoint;
- int tess_index;
-
- bool m_locked;
- IDirect3DTexture9 *m_mask;
- IDirect3DSurface9 *m_maskSurface;
- IDirect3DSurface9 *m_depthStencilSurface;
-
- D3DCOLOR m_color;
- bool m_clearmask;
- bool m_isLine;
- bool m_firstPoint;
-
- QD3DMaskPosition m_mask_position;
- int m_mask_offsetX2;
- int m_mask_offsetY2;
-};
-
-QD3DStateManager::QD3DStateManager(LPDIRECT3DDEVICE9 pDevice, ID3DXEffect *effect)
- : m_pDevice(pDevice), m_effect(effect), m_refs(0)
-{
- if (FAILED(D3DXMatrixIdentity(&m_d3dIdentityMatrix))) {
- qWarning("QDirect3DPaintEngine: D3DXMatrixIdentity failed");
- }
- reset();
-}
-
-void QD3DStateManager::reset()
-{
- m_radgradfd = -1;
-
- m_cosmetic_pen = false;
- m_pass = -1;
- m_maskchannel = -1;
- m_brushmode = -1;
- m_texture = 0;
- m_xoffset = INT_MAX;
- m_yoffset = INT_MAX;
-
- m_vertexshader = 0;
- m_pixelshader = 0;
-
- m_isIdentity = true;
- m_transformation = QTransform();
- m_effect->SetMatrix("g_mTransformation", &m_d3dIdentityMatrix);
-
- ZeroMemory(&m_projection, sizeof(D3DMATRIX));
- ZeroMemory(m_textures, sizeof(LPDIRECT3DBASETEXTURE9) * D3D_STAGE_COUNT);
- FillMemory(m_samplerstates, sizeof(DWORD) * D3D_SAMPLE_STATES * D3D_STAGE_COUNT, 0xFFFFFFFE);
- FillMemory(m_texturestates, sizeof(DWORD) * D3D_TEXTURE_STATES * D3D_STAGE_COUNT, 0xFFFFFFFE);
- FillMemory(m_renderstate, sizeof(DWORD) * D3D_RENDER_STATES, 0xFFFFFFFE);
-}
-
-inline void QD3DStateManager::beginPass(int pass)
-{
- if (pass != m_pass) {
- if (m_pass != -1)
- m_effect->EndPass();
- m_effect->BeginPass(pass);
- m_pass = pass;
- }
-}
-
-inline void QD3DStateManager::endPass()
-{
- if (m_pass != -1) {
- m_pass = -1;
- m_effect->EndPass();
- }
-}
-
-inline void QD3DStateManager::startStateBlock() {
- m_changed = false;
-}
-
-inline void QD3DStateManager::setCosmeticPen(bool enabled)
-{
- if (enabled != m_cosmetic_pen) {
- m_effect->SetBool("g_mCosmeticPen", enabled);
- m_cosmetic_pen = enabled;
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setBrushMode(int mode)
-{
- if (mode != m_brushmode) {
- m_effect->SetInt("g_mBrushMode", mode);
- m_brushmode = mode;
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setTexture(LPDIRECT3DBASETEXTURE9 pTexture)
-{
- SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
- SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
-
- if (pTexture != m_texture) {
- m_texture = pTexture;
- m_effect->SetTexture("g_mTexture", pTexture);
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setTexture(LPDIRECT3DBASETEXTURE9 pTexture, QGradient::Spread spread)
-{
- switch(spread) {
- case QGradient::RepeatSpread:
- SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
- SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
- break;
- case QGradient::ReflectSpread:
- SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
- SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
- break;
- default:
- SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
- SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
- break;
- };
-
- if (pTexture != m_texture) {
- m_texture = pTexture;
- m_effect->SetTexture("g_mTexture", pTexture);
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setTransformation(const QTransform *matrix)
-{
- if (matrix) {
- if (*matrix != m_transformation) {
- D3DXMATRIX dxmatrix(matrix->m11(), matrix->m12(), 0, matrix->m13(),
- matrix->m21(), matrix->m22(), 0, matrix->m23(),
- 0, 0, 1, 0,
- matrix->dx(), matrix->dy(), 0, 1);
- m_effect->SetMatrix("g_mTransformation", &dxmatrix);
- m_transformation = *matrix;
- m_changed = true;
- m_isIdentity = false;
- }
- } else if (!m_isIdentity) {
- m_effect->SetMatrix("g_mTransformation", &m_d3dIdentityMatrix);
- m_transformation = QTransform();
- m_changed = true;
- m_isIdentity = true;
- }
-}
-
-inline void QD3DStateManager::setProjection(const D3DXMATRIX *pMatrix)
-{
- if (*pMatrix != m_projection) {
- m_effect->SetMatrix("g_mViewProjection", pMatrix);
- m_projection = *pMatrix;
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setFocalDistance(const qreal &fd)
-{
- if (fd != m_radgradfd) {
- m_effect->SetFloat("g_mFocalDist", fd);
- m_changed = true;
- m_radgradfd = fd;
- }
-}
-
-inline void QD3DStateManager::setMaskOffset(qreal x, qreal y)
-{
- if (x != m_xoffset || y != m_yoffset) {
- float offset[2] = {x, y};
- m_effect->SetFloatArray("g_mMaskOffset", offset, 2);
- m_xoffset = x;
- m_yoffset = y;
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::setMaskChannel(int channel)
-{
- if (m_maskchannel != channel) {
- m_effect->SetIntArray("g_mChannel", m_mask_channels[channel], 4);
- m_maskchannel = channel;
- m_changed = true;
- }
-}
-
-inline void QD3DStateManager::endStateBlock()
-{
- if (m_changed) {
- m_effect->CommitChanges();
- m_changed = false;
- }
-}
-
-STDMETHODIMP QD3DStateManager::QueryInterface(REFIID iid, LPVOID *ppv)
-{
- if(iid == IID_IUnknown || iid == IID_ID3DXEffectStateManager)
- {
- *ppv = this;
- ++m_refs;
- return NOERROR;
- }
- *ppv = NULL;
- return ResultFromScode(E_NOINTERFACE);
-}
-
-STDMETHODIMP_(ULONG) QD3DStateManager::AddRef(void)
-{
- return (ULONG)InterlockedIncrement( &m_refs );
-}
-
-
-STDMETHODIMP_(ULONG) QD3DStateManager::Release(void)
-{
- if( 0L == InterlockedDecrement( &m_refs ) ) {
- delete this;
- return 0L;
- }
-
- return m_refs;
-}
-STDMETHODIMP QD3DStateManager::SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix)
-{
- return m_pDevice->SetTransform(State, pMatrix);
-}
-
-STDMETHODIMP QD3DStateManager::SetMaterial(CONST D3DMATERIAL9 *pMaterial)
-{
- return m_pDevice->SetMaterial(pMaterial);
-}
-
-STDMETHODIMP QD3DStateManager::SetLight(DWORD Index, CONST D3DLIGHT9 *pLight)
-{
- return m_pDevice->SetLight(Index, pLight);
-}
-
-STDMETHODIMP QD3DStateManager::LightEnable(DWORD Index, BOOL Enable)
-{
- return m_pDevice->LightEnable(Index, Enable);
-}
-
-STDMETHODIMP QD3DStateManager::SetRenderState(D3DRENDERSTATETYPE State, DWORD Value)
-{
- if (State < D3D_RENDER_STATES) {
- if (m_renderstate[State] == Value)
- return S_OK;
- m_renderstate[State] = Value;
- }
- return m_pDevice->SetRenderState(State, Value);
-}
-
-STDMETHODIMP QD3DStateManager::SetTexture(DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture)
-{
- if (Stage < D3D_STAGE_COUNT) {
- if (m_textures[Stage] == pTexture)
- return S_OK;
- m_textures[Stage] = pTexture;
- }
- return m_pDevice->SetTexture(Stage, pTexture);
-}
-
-STDMETHODIMP QD3DStateManager::SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
-{
- if (Stage < D3D_STAGE_COUNT && Type < D3D_TEXTURE_STATES) {
- if (m_texturestates[Stage][Type] == Value)
- return S_OK;
- m_texturestates[Stage][Type] = Value;
- }
- return m_pDevice->SetTextureStageState(Stage, Type, Value);
-}
-
-STDMETHODIMP QD3DStateManager::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
-{
- if (Sampler < D3D_STAGE_COUNT && Type < D3D_SAMPLE_STATES) {
- if (m_samplerstates[Sampler][Type] == Value)
- return S_OK;
- m_samplerstates[Sampler][Type] = Value;
- }
- return m_pDevice->SetSamplerState(Sampler, Type, Value);
-}
-
-STDMETHODIMP QD3DStateManager::SetNPatchMode(FLOAT NumSegments)
-{
- return m_pDevice->SetNPatchMode(NumSegments);
-}
-
-STDMETHODIMP QD3DStateManager::SetFVF(DWORD FVF)
-{
- return m_pDevice->SetFVF(FVF);
-}
-
-STDMETHODIMP QD3DStateManager::SetVertexShader(LPDIRECT3DVERTEXSHADER9 pShader)
-{
- if (m_vertexshader == pShader)
- return S_OK;
- m_vertexshader = pShader;
- return m_pDevice->SetVertexShader(pShader);
-}
-
-STDMETHODIMP QD3DStateManager::SetVertexShaderConstantF(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetVertexShaderConstantF(RegisterIndex, pConstantData, RegisterCount);
-}
-
-STDMETHODIMP QD3DStateManager::SetVertexShaderConstantI(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetVertexShaderConstantI(RegisterIndex, pConstantData, RegisterCount);
-}
-
-STDMETHODIMP QD3DStateManager::SetVertexShaderConstantB(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetVertexShaderConstantB(RegisterIndex, pConstantData, RegisterCount);
-}
-
-STDMETHODIMP QD3DStateManager::SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader)
-{
- if (m_pixelshader == pShader)
- return S_OK;
- m_pixelshader = pShader;
- return m_pDevice->SetPixelShader(pShader);
-}
-
-STDMETHODIMP QD3DStateManager::SetPixelShaderConstantF(UINT RegisterIndex, CONST FLOAT *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetPixelShaderConstantF(RegisterIndex, pConstantData, RegisterCount);
-}
-
-STDMETHODIMP QD3DStateManager::SetPixelShaderConstantI(UINT RegisterIndex, CONST INT *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetPixelShaderConstantI(RegisterIndex, pConstantData, RegisterCount);
-}
-
-STDMETHODIMP QD3DStateManager::SetPixelShaderConstantB(UINT RegisterIndex, CONST BOOL *pConstantData, UINT RegisterCount)
-{
- return m_pDevice->SetPixelShaderConstantB(RegisterIndex, pConstantData, RegisterCount);
-}
-
-#define QD3D_GRADIENT_CACHE_SIZE 60
-#define QD3D_GRADIENT_PALETTE_SIZE 1024
-
-class QD3DGradientCache
-{
- struct CacheInfo
- {
- inline CacheInfo(QGradientStops s, qreal op) :
- stops(s), opacity(op) {}
-
- IDirect3DTexture9 *texture;
- QGradientStops stops;
- qreal opacity;
- };
-
- typedef QMultiHash<quint64, CacheInfo> QD3DGradientColorTableHash;
-
-public:
- QD3DGradientCache(LPDIRECT3DDEVICE9 device);
- ~QD3DGradientCache();
-
- inline IDirect3DTexture9 *getBuffer(const QGradientStops &stops, qreal opacity);
-
-protected:
- inline void generateGradientColorTable(const QGradientStops& s,
- uint *colorTable,
- int size, qreal opacity) const;
- IDirect3DTexture9 *addCacheElement(quint64 hash_val, const QGradientStops &stops, qreal opacity);
- void cleanCache();
-
- QD3DGradientColorTableHash cache;
- LPDIRECT3DDEVICE9 m_device;
-};
-
-QD3DGradientCache::QD3DGradientCache(LPDIRECT3DDEVICE9 device)
- : m_device(device)
-{
-
-}
-
-QD3DGradientCache::~QD3DGradientCache()
-{
- cleanCache();
-}
-
-inline IDirect3DTexture9 *QD3DGradientCache::getBuffer(const QGradientStops &stops, qreal opacity)
-{
- quint64 hash_val = 0;
-
- for (int i = 0; i < stops.size() && i <= 2; i++)
- hash_val += stops[i].second.rgba();
-
- QD3DGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
-
- if (it == cache.constEnd())
- return addCacheElement(hash_val, stops, opacity);
- else {
- do {
- const CacheInfo &cache_info = it.value();
- if (cache_info.stops == stops && cache_info.opacity == opacity) {
- return cache_info.texture;
- }
- ++it;
- } while (it != cache.constEnd() && it.key() == hash_val);
- // an exact match for these stops and opacity was not found, create new cache
- return addCacheElement(hash_val, stops, opacity);
- }
-}
-
-void QD3DGradientCache::generateGradientColorTable(const QGradientStops& s, uint *colorTable, int size, qreal opacity) const
-{
- int pos = 0;
- qreal fpos = 0.0;
- qreal incr = 1.0 / qreal(size);
- QVector<uint> colors(s.size());
-
- for (int i = 0; i < s.size(); ++i)
- colors[i] = s[i].second.rgba();
-
- uint alpha = qRound(opacity * 255);
- while (fpos < s.first().first) {
- colorTable[pos] = ARGB_COMBINE_ALPHA(colors[0], alpha);
- pos++;
- fpos += incr;
- }
-
- for (int i = 0; i < s.size() - 1; ++i) {
- qreal delta = 1/(s[i+1].first - s[i].first);
- while (fpos < s[i+1].first && pos < size) {
- int dist = int(256 * ((fpos - s[i].first) * delta));
- int idist = 256 - dist;
- uint current_color = ARGB_COMBINE_ALPHA(colors[i], alpha);
- uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
-#else
- uint c = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
- colorTable[pos] = ( (c << 24) & 0xff000000)
- | ((c >> 24) & 0x000000ff)
- | ((c << 8) & 0x00ff0000)
- | ((c >> 8) & 0x0000ff00);
-#endif // Q_BYTE_ORDER
- ++pos;
- fpos += incr;
- }
- }
- for (;pos < size; ++pos)
- colorTable[pos] = colors[s.size() - 1];
-}
-
-IDirect3DTexture9 *QD3DGradientCache::addCacheElement(quint64 hash_val, const QGradientStops &stops, qreal opacity)
-{
- if (cache.size() == QD3D_GRADIENT_CACHE_SIZE) {
- int elem_to_remove = qrand() % QD3D_GRADIENT_CACHE_SIZE;
- uint key = cache.keys()[elem_to_remove];
-
- // need to call release on each removed cache entry:
- QD3DGradientColorTableHash::const_iterator it = cache.constFind(key);
- do {
- it.value().texture->Release();
- } while (++it != cache.constEnd() && it.key() == key);
-
- cache.remove(key); // may remove more than 1, but OK
- }
-
- CacheInfo cache_entry(stops, opacity);
- uint buffer[QD3D_GRADIENT_PALETTE_SIZE];
- generateGradientColorTable(stops, buffer, QD3D_GRADIENT_PALETTE_SIZE, opacity);
-
- if (FAILED(m_device->CreateTexture(QD3D_GRADIENT_PALETTE_SIZE, 1, 1, 0,
- D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cache_entry.texture, 0))) {
- qWarning("QD3DGradientCache::addCacheElement(): unable to create Direct3D texture.");
- return 0;
- }
-
- D3DLOCKED_RECT rect;
- if (FAILED(cache_entry.texture->LockRect(0, &rect, 0, 0))) {
- qDebug() << "QD3DGradientCache::addCacheElement(): unable to lock texture rect.";
- return 0;
- }
- memcpy(rect.pBits, buffer, rect.Pitch);
- cache_entry.texture->UnlockRect(0);
-
- return cache.insert(hash_val, cache_entry).value().texture;
-}
-
-void QD3DGradientCache::cleanCache()
-{
- QD3DGradientColorTableHash::const_iterator it = cache.constBegin();
- for (; it != cache.constEnd(); ++it) {
- const CacheInfo &cache_info = it.value();
- cache_info.texture->Release();
- }
- cache.clear();
-}
-
-QD3DSurfaceManager::QD3DSurfaceManager() :
- m_status(NoStatus), m_dummy(0), m_device(0), m_pd(0), m_current(0)
-{
-
-}
-
-QD3DSurfaceManager::~QD3DSurfaceManager()
-{
-}
-
-void QD3DSurfaceManager::setPaintDevice(QPaintDevice *pd)
-{
- m_status = NoStatus;
- m_pd = pd;
- m_current = 0;
-
- if (m_device->TestCooperativeLevel() != D3D_OK) {
- m_status = NeedsResetting;
- return;
- }
-
- m_current = m_swapchains.value(pd, 0);
- QWidget *w = static_cast<QWidget*>(pd);
-
- if (m_current) {
- if (m_current->size != w->size()) {
- m_swapchains.remove(pd);
- m_current->surface->Release();
- m_current->swapchain->Release();
- delete m_current;
- m_current = 0;
- }
- }
-
- if (!m_current) {
- m_current = createSwapChain(w);
- updateMaxSize();
- }
-}
-
-int QD3DSurfaceManager::status() const
-{
- return m_status;
-}
-
-void QD3DSurfaceManager::reset()
-{
- QList<QPaintDevice *> pds = m_swapchains.keys();
-
- QMap<QPaintDevice *, D3DSwapChain *>::const_iterator i = m_swapchains.constBegin();
- while (i != m_swapchains.constEnd()) {
- i.value()->surface->Release();
- i.value()->swapchain->Release();
- ++i;
- }
- qDeleteAll(m_swapchains.values());
- m_swapchains.clear();
-
- D3DPRESENT_PARAMETERS params;
- initPresentParameters(&params);
- params.hDeviceWindow = m_dummy;
-
- HRESULT res = m_device->Reset(&params);
- if (FAILED(res)) {
- switch (res) {
- case D3DERR_DEVICELOST:
- qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_DEVICELOST)");
- break;
- case D3DERR_DRIVERINTERNALERROR:
- qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_DRIVERINTERNALERROR)");
- break;
- case D3DERR_OUTOFVIDEOMEMORY:
- qWarning("QDirect3DPaintEngine: Reset failed (D3DERR_OUTOFVIDEOMEMORY)");
- break;
- default:
- qWarning("QDirect3DPaintEngine: Reset failed");
- };
- }
-
- for (int i=0; i<pds.count(); ++i) {
- QWidget *w = static_cast<QWidget*>(pds.at(i));
- createSwapChain(w);
- }
-
- // reset the mask as well
- m_status = MaxSizeChanged;
-
- setPaintDevice(m_pd);
- updateMaxSize();
-}
-
-LPDIRECT3DSURFACE9 QD3DSurfaceManager::renderTarget()
-{
- return m_current ? m_current->surface : 0;
-}
-
-LPDIRECT3DSURFACE9 QD3DSurfaceManager::surface(QPaintDevice *pd)
-{
- D3DSwapChain *swapchain = m_swapchains.value(pd, 0);
- return swapchain ? swapchain->surface : 0;
-}
-
-LPDIRECT3DSWAPCHAIN9 QD3DSurfaceManager::swapChain(QPaintDevice *pd)
-{
- D3DSwapChain *swapchain = m_swapchains.value(pd, 0);
- return swapchain ? swapchain->swapchain : 0;
-}
-
-void QD3DSurfaceManager::releasePaintDevice(QPaintDevice *pd)
-{
- D3DSwapChain *swapchain = m_swapchains.take(pd);
-
- if (swapchain) {
- swapchain->surface->Release();
- swapchain->swapchain->Release();
- delete swapchain;
- if (swapchain == m_current)
- m_current = 0;
- }
-}
-
-LPDIRECT3DDEVICE9 QD3DSurfaceManager::device()
-{
- return m_device;
-}
-
-void QD3DSurfaceManager::cleanup()
-{
- QPixmapCache::clear();
- qd3d_glyph_cache()->cleanCache();
-
- // release doomed textures
- for (int k=0; k<qd3d_release_list.size(); ++k)
- qd3d_release_list.at(k)->Release();
- qd3d_release_list.clear();
-
- QMap<QPaintDevice *, D3DSwapChain *>::const_iterator i = m_swapchains.constBegin();
- while (i != m_swapchains.constEnd()) {
- i.value()->surface->Release();
- i.value()->swapchain->Release();
- ++i;
- }
- qDeleteAll(m_swapchains.values());
-
- if (m_device)
- m_device->Release();
-
- DestroyWindow(m_dummy);
- QString cname(QLatin1String("qt_d3d_dummy"));
- QT_WA({
- UnregisterClass((TCHAR*)cname.utf16(), (HINSTANCE)qWinAppInst());
- } , {
- UnregisterClassA(cname.toLatin1(), (HINSTANCE)qWinAppInst());
- });
-}
-
-QSize QD3DSurfaceManager::maxSize() const
-{
- return m_max_size;
-}
-
-extern "C" {
- LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
-};
-
-void QD3DSurfaceManager::init(LPDIRECT3D9 object)
-{
- QString cname(QLatin1String("qt_d3d_dummy"));
- uint style = CS_DBLCLKS | CS_SAVEBITS;
- ATOM atom;
- QT_WA({
- WNDCLASS wc;
- wc.style = style;
- wc.lpfnWndProc = (WNDPROC)QtWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = (HINSTANCE)qWinAppInst();
- wc.hIcon = 0;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = 0;
- wc.lpszClassName = (TCHAR*)cname.utf16();
- atom = RegisterClass(&wc);
- } , {
- WNDCLASSA wc;
- wc.style = style;
- wc.lpfnWndProc = (WNDPROC)QtWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = (HINSTANCE)qWinAppInst();
- wc.hIcon = 0;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = 0;
- QByteArray tempArray = cname.toLatin1();
- wc.lpszClassName = tempArray;
- atom = RegisterClassA(&wc);
- });
-
- QT_WA({
- const TCHAR *className = (TCHAR*)cname.utf16();
- m_dummy = CreateWindow(className, className, 0,
- 0, 0, 1, 1,
- 0, 0, qWinAppInst(), 0);
- } , {
- m_dummy = CreateWindowA(cname.toLatin1(), cname.toLatin1(), 0,
- 0, 0, 1, 1,
- 0, 0, qWinAppInst(), 0);
- });
-
- D3DPRESENT_PARAMETERS params;
- initPresentParameters(&params);
- params.hDeviceWindow = m_dummy;
-
- HRESULT res = object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 0,
- D3DCREATE_PUREDEVICE|D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_NOWINDOWCHANGES|D3DCREATE_FPU_PRESERVE,
- &params, &m_device);
-
- if (FAILED(res) || m_device == 0)
- qWarning("QDirect3DPaintEngine: failed to create Direct3D device (error=0x%x).", res);
-}
-
-void QD3DSurfaceManager::updateMaxSize()
-{
- int w = 0, h = 0;
- QMap<QPaintDevice *, D3DSwapChain *>::const_iterator i = m_swapchains.constBegin();
- while (i != m_swapchains.constEnd()) {
-
- int nw = i.key()->width();
- if (nw > w)
- w = nw;
-
- int nh = i.key()->height();
- if (nh > h)
- h = nh;
-
- ++i;
- }
-
- QSize newsize = QSize(w, h);
- if (newsize != m_max_size) {
- m_status |= MaxSizeChanged;
- m_max_size = newsize;
- }
-}
-
-void QD3DSurfaceManager::initPresentParameters(D3DPRESENT_PARAMETERS *params)
-{
- ZeroMemory(params, sizeof(D3DPRESENT_PARAMETERS));
- params->Windowed = true;
- params->SwapEffect = D3DSWAPEFFECT_COPY;
- params->BackBufferFormat = D3DFMT_UNKNOWN;
- params->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- params->Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
-}
-
-QD3DSurfaceManager::D3DSwapChain *QD3DSurfaceManager::createSwapChain(QWidget *w)
-{
- D3DPRESENT_PARAMETERS params;
- initPresentParameters(&params);
- params.hDeviceWindow = w->winId();
- D3DSwapChain *swapchain = new D3DSwapChain();
- swapchain->size = w->size();
- if (FAILED(m_device->CreateAdditionalSwapChain(&params, &swapchain->swapchain)))
- qWarning("QDirect3DPaintEngine: CreateAdditionalSwapChain failed");
- if (FAILED(swapchain->swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &swapchain->surface)))
- qWarning("QDirect3DPaintEngine: GetBackBuffer failed");
- m_swapchains.insert(w, swapchain);
- connect(w, SIGNAL(destroyed(QObject *)), SLOT(cleanupPaintDevice(QObject *)));
-
- // init with background color
- QColor bg = w->palette().color(QPalette::Background);
- m_device->ColorFill(swapchain->surface, 0, D3DCOLOR_ARGB(bg.alpha(), bg.red(),bg.green(),bg.blue()));
-
- return swapchain;
-}
-
-void QD3DSurfaceManager::cleanupPaintDevice(QObject *object)
-{
- QWidget *w = static_cast<QWidget *>(object);
- releasePaintDevice(w);
-}
-
-int QD3DStateManager::m_mask_channels[4][4] =
- {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
-
-QD3DDrawHelper::QD3DDrawHelper(QDirect3DPaintEnginePrivate *pe)
- : m_pe(pe), m_d3dvbuff(0), m_maskSurface(0), m_depthStencilSurface(0),
- m_locked(false), m_mask(0), m_startindex(0), m_index(0), m_vbuff(0), m_clearmask(true),
- m_isLine(false), m_firstPoint(true)
-{
- resetMask();
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- memset(accesscontrol, 0, QT_VERTEX_BUF_SIZE * sizeof(VertexBufferAccess));
-#endif
-
- // create vertex buffer
- afterReset();
-}
-
-QD3DDrawHelper::~QD3DDrawHelper()
-{
- if (m_maskSurface)
- m_maskSurface->Release();
-
- if (m_mask)
- m_mask->Release();
-
- if (m_depthStencilSurface)
- m_depthStencilSurface->Release();
-
- if (m_d3dvbuff)
- m_d3dvbuff->Release();
-}
-
-inline void QD3DDrawHelper::lockVertexBuffer()
-{
- if (!m_locked) {
- DWORD lockflags = D3DLOCK_NOOVERWRITE;
- if (m_startindex >= QT_VERTEX_RESET_LIMIT) {
- m_startindex = 0;
- m_index = 0;
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- for (int i=0; i<QT_VERTEX_BUF_SIZE; ++i) {
- if (accesscontrol[i] != (WRITE|READ) && accesscontrol[i] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- }
- memset(accesscontrol, 0, QT_VERTEX_BUF_SIZE * sizeof(VertexBufferAccess));
-#endif
-
- lockflags = D3DLOCK_DISCARD;
- }
-
- if (FAILED(m_d3dvbuff->Lock(0, 0, (void**)&m_vbuff, lockflags))) {
- qWarning() << "QDirect3DPaintEngine: unable to lock vertex buffer.";
- }
- m_locked = true;
- }
-}
-
-inline void QD3DDrawHelper::unlockVertexBuffer()
-{
- if (m_locked) {
- if (FAILED(m_d3dvbuff->Unlock())) {
- qWarning() << "QDirect3DPaintEngine: unable to unlock vertex buffer.";
- }
- m_locked = false;
- }
-}
-
-void QD3DDrawHelper::setClipPath(const QPainterPath &path, QD3DBatchItem **item)
-{
- lockVertexBuffer();
-
- m_item = *item;
- m_item->m_maskpos.x = m_item->m_maskpos.y = 0;
- m_item->m_maskpos.channel = 3;
- m_item->m_info |= QD3DBatchItem::BI_CLIP;
-
- bool winding = (path.fillRule() == Qt::WindingFill);
- if (winding)
- m_item->m_info |= QD3DBatchItem::BI_WINDING;
-
- if (!path.isEmpty()) {
- m_item->m_info |= QD3DBatchItem::BI_MASK;
- m_item->m_info &= ~QD3DBatchItem::BI_AA;
- m_color = 0;
- QRectF brect = pathToVertexArrays(path);
- queueRect(brect, m_item, 0);
- }
-
- *item = m_item;
-}
-
-
-
-void QD3DDrawHelper::queueAntialiasedMask(const QPolygonF &poly, QD3DBatchItem **item, const QRectF &brect)
-{
- lockVertexBuffer();
-
- m_item = *item;
- m_item->m_info |= QD3DBatchItem::BI_MASK;
- setWinding(m_item->m_info & QD3DBatchItem::BI_WINDING);
-
- int xoffset = m_item->m_maskpos.x;
- int yoffset = m_item->m_maskpos.y;
-
- int x = brect.left();
- int y = brect.top();
-
- m_item->m_xoffset = (xoffset - x) + 1;
- m_item->m_yoffset = (yoffset - y) + 1;
-
- m_boundingRect = brect;
- tessellate(poly);
-
- *item = m_item;
-}
-
-QRectF QD3DDrawHelper::queueAliasedMask(const QPainterPath &path, QD3DBatchItem **item, D3DCOLOR color)
-{
- lockVertexBuffer();
-
- m_color = color;
- m_item = *item;
- m_item->m_info |= QD3DBatchItem::BI_MASK;
-
- bool winding = (path.fillRule() == Qt::WindingFill);
- if (winding)
- m_item->m_info |= QD3DBatchItem::BI_WINDING;
-
- QRectF result = pathToVertexArrays(path);
- *item = m_item;
- return result;
-}
-
-// used for drawing aliased transformed rects directly
-// don't use for antialiased or masked drawing
-void QD3DDrawHelper::queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color, const QPolygonF &trect)
-{
- lockVertexBuffer();
-
- qreal zval = (item->m_info & QD3DBatchItem::BI_CLIP) ? 0.0f : 0.5f;
- item->m_info |= QD3DBatchItem::BI_BRECT;
-
- // if the item does not have a mask, the offset is different
- if (!(item->m_info & QD3DBatchItem::BI_MASK)) {
- item->m_offset = m_index;
- item->m_count = (item->m_info & QD3DBatchItem::BI_AA) ? 0 : -2;
- }
-
- qreal x1 = rect.left();
- qreal y1 = rect.top();
- qreal x2 = rect.right();
- qreal y2 = rect.bottom();
-
- QPointF tc = trect.at(0);
- vertex v1 = { {x1, y1, zval} , color,
- tc.x(), tc.y(), 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f };
-
- tc = trect.at(1);
- vertex v2 = { {x2, y1, zval} , color,
- tc.x(), tc.y(), 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
-
- tc = trect.at(2);
- vertex v3 = { {x2, y2, zval} , color,
- tc.x(), tc.y(), 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};;
-
- tc = trect.at(3);
- vertex v4 = { {x1, y2, zval} , color,
- tc.x(), tc.y(), 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- for (int i=m_index; i<(m_index + 4); ++i) {
- if ((m_index + 4) > QT_VERTEX_BUF_SIZE)
- qDebug() << "Vertex Buffer: Buffer overflow";
- if (accesscontrol[i] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[i] |= WRITE;
- }
-#endif
-
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
- m_vbuff[m_index++] = v4;
-
- m_startindex = m_index;
-}
-
-
-QD3DMaskPosition QD3DDrawHelper::allocateMaskPosition(const QRectF &brect, bool *breakbatch)
-{
- int w = brect.width();
- int h = brect.height();
-
- w += 3;
- h += 3;
-
- if (w > m_width)
- w = m_width;
- if (h > m_height)
- h = m_height;
-
- *breakbatch = false;
-
- if ((m_height - m_mask_offsetY2) >= h && (m_width - m_mask_position.x) >= w) {
- m_mask_position.y = m_mask_offsetY2;
- } else if ((m_width - m_mask_offsetX2) >= w) {
- m_mask_position.y = QD3D_MASK_MARGIN;
- m_mask_position.x = m_mask_offsetX2;
- } else if (m_mask_position.channel < 3) {
- ++m_mask_position.channel;
- m_mask_position.x = m_mask_position.y = QD3D_MASK_MARGIN;
- m_mask_offsetX2 = m_mask_offsetY2 = QD3D_MASK_MARGIN;
- } else {
- resetMask();
- *breakbatch = true;
- }
-
- int newoffset = m_mask_position.x + w;
- if (m_mask_offsetX2 < newoffset)
- m_mask_offsetX2 = newoffset;
- m_mask_offsetY2 = (m_mask_position.y + h);
-
- return m_mask_position;
-
-}
-
-void QD3DDrawHelper::queueRect(const QRectF &rect, QD3DBatchItem *item, D3DCOLOR color)
-{
- lockVertexBuffer();
-
- QRectF brect;
- item->m_info |= QD3DBatchItem::BI_BRECT;
- qreal zval = (item->m_info & QD3DBatchItem::BI_CLIP) ? 0.0f : 0.5f;
-
- if (item->m_info & QD3DBatchItem::BI_AA) {
- int xoffset = item->m_maskpos.x;
- int yoffset = item->m_maskpos.y;
-
- int x = rect.left();
- int y = rect.top();
-
- brect = QRectF(x, y, rect.width() + 1, rect.height() + 1);
-
- item->m_xoffset = (xoffset - x) + 1;
- item->m_yoffset = (yoffset - y) + 1;
-
- // if the item does not have a mask, the offset is different
- if (!(item->m_info & QD3DBatchItem::BI_MASK)) {
- item->m_offset = m_index;
- item->m_count = 0;
- }
- } else {
- brect = rect;
-
- if (!(item->m_info & QD3DBatchItem::BI_MASK)) {
- item->m_offset = m_index;
- item->m_count = -2;
- }
- }
-
- qreal left = brect.left();
- qreal right = brect.right();
- qreal top = brect.top();
- qreal bottom = brect.bottom();
-
- vertex v1 = { {left, bottom, zval}, color,
- 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f};
- vertex v2 = { {left, top, zval}, color,
- 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f};
- vertex v3 = { {right, top, zval}, color,
- 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f};
- vertex v4 = { {right, bottom, zval}, color,
- 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f};
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- for (int i=m_index; i<(m_index + 4); ++i) {
- if ((m_index + 4) > QT_VERTEX_BUF_SIZE)
- qDebug() << "Vertex Buffer: Buffer overflow";
- if (accesscontrol[i] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[i] |= WRITE;
- }
-#endif
-
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
- m_vbuff[m_index++] = v4;
-
- m_startindex = m_index;
-}
-
-void QD3DDrawHelper::queueAntialiasedLines(const QPainterPath &path, QD3DBatchItem **item, const QRectF &brect)
-{
- lockVertexBuffer();
-
- m_item = *item;
- m_item->m_info |= QD3DBatchItem::BI_MASK;
- setWinding(m_item->m_info & QD3DBatchItem::BI_WINDING);
-
- int xoffset = m_item->m_maskpos.x;
- int yoffset = m_item->m_maskpos.y;
- int x = brect.left();
- int y = brect.top();
-
- m_item->m_xoffset = (xoffset - x) + 1;
- m_item->m_yoffset = (yoffset - y) + 1;
-
- m_boundingRect = brect;
-
- m_xoffset = (x - xoffset) + 0.5f;
- m_yoffset = (y - yoffset) + 0.5f;
-
- QPointF last;
- for (int i = 0; i < path.elementCount(); ++i) {
- QPainterPath::Element element = path.elementAt(i);
-
- //Q_ASSERT(!element.isCurveTo());
-
- if (element.isLineTo())
- QTessellator::tessellateRect(last, element, m_item->m_width);
-
- last = element;
- }
-
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) / 3;
- m_startindex = m_index;
-
- *item = m_item;
-}
-
-void QD3DDrawHelper::queueAliasedLines(const QLineF *lines, int lineCount, QD3DBatchItem **item)
-{
- lockVertexBuffer();
-
- m_item = *item;
- m_item->m_info |= QD3DBatchItem::BI_FASTLINE;
-
- for (int i=0; i<lineCount; ++i) {
- const QLineF line = lines[i];
- qreal p1x = line.p1().x();
- qreal p1y = line.p1().y();
- qreal p2x = line.p2().x();
- qreal p2y = line.p2().y();
-
- vertex v1 = { {p1x, p1y, m_pe->m_pen_width} , m_pe->m_pen_color,
- -1.f, -1.f, p2x, p2y,
- 0.f, 0.f, 0.f, 0.f };
- vertex v2 = { {p1x, p1y, m_pe->m_pen_width} , m_pe->m_pen_color,
- 1.f, -1.f, p2x, p2y,
- 0.f, 0.f, 0.f, 0.f };
- vertex v3 = { {p1x, p1y, m_pe->m_pen_width} , m_pe->m_pen_color,
- 1.f, 1.f, p2x, p2y,
- 0.f, 0.f, 0.f, 0.f };
- vertex v4 = { {p1x, p1y, m_pe->m_pen_width} , m_pe->m_pen_color,
- -1.f, 1.f, p2x, p2y,
- 0.f, 0.f, 0.f, 0.f };
-
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
-
- if (m_index >= (QT_VERTEX_BUF_SIZE - 16)) {
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) / 2;
- m_startindex = m_index;
-
- QD3DBatchItem itemcopy = *m_item;
- m_item = m_pe->nextBatchItem();
- *m_item = itemcopy;
-
- lockVertexBuffer();
- }
- }
-
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) - 2;
- m_startindex = m_index;
-
- *item = m_item;
-}
-
-void QD3DDrawHelper::queueTextGlyph(const QRectF &rect, const qreal *tex_coords,
- QD3DBatchItem *item, D3DCOLOR color)
-{
- lockVertexBuffer();
-
- qreal x1 = rect.left();
- qreal y1 = rect.top();
- qreal x2 = rect.right();
- qreal y2 = rect.bottom();
-
- vertex v1 = { {x1, y1, 0.5f}, color,
- tex_coords[0], tex_coords[1], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
- vertex v2 = { {x2, y1, 0.5f}, color,
- tex_coords[2], tex_coords[1], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
- vertex v3 = { {x2, y2, 0.5f}, color,
- tex_coords[2], tex_coords[3], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
- vertex v4 = { {x1, y1, 0.5f}, color,
- tex_coords[0], tex_coords[1], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
- vertex v5 = { {x2, y2, 0.5f}, color,
- tex_coords[2], tex_coords[3], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
- vertex v6 = { {x1, y2, 0.5f}, color,
- tex_coords[0], tex_coords[3], 0.f, 0.f,
- 0.f , 0.f , 0.f, 0.f};
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- for (int i=m_index; i<(m_index + 6); ++i) {
- if ((m_index + 6) > QT_VERTEX_BUF_SIZE)
- qDebug() << "Vertex Buffer: Buffer overflow";
- if (accesscontrol[i] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[i] |= WRITE;
- }
-#endif
-
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v5;
- m_vbuff[m_index++] = v6;
-
- m_startindex = m_index;
- ++item->m_count;
-}
-
-bool QD3DDrawHelper::needsFlushing() const
-{
- return (m_pe->m_batch.m_item_index >= QD3D_BATCH_SIZE || m_startindex >= QT_VERTEX_RESET_LIMIT);
-}
-
-void QD3DDrawHelper::setMaskSize(QSize size)
-{
- m_width = size.width();
- m_height = size.height();
-
- if (m_maskSurface)
- m_maskSurface->Release();
-
- if (m_mask)
- m_mask->Release();
-
- if (FAILED(m_pe->m_d3d_device->CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET,
- D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_mask, NULL))) {
- qWarning() << "QDirect3DPaintEngine: CreateTexture() failed.";
- }
-
- if (m_depthStencilSurface)
- m_depthStencilSurface->Release();
-
- if (FAILED(m_pe->m_d3d_device->CreateDepthStencilSurface(m_width, m_height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0,
- TRUE, &m_depthStencilSurface, NULL))) {
- qWarning() << "QDirect3DPaintEngine: CreateDepthStencilSurface() failed.";
- }
-
- m_pe->m_d3d_device->SetDepthStencilSurface(m_depthStencilSurface);
- m_pe->m_d3d_device->Clear(0, 0, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0, 0.0f, 0);
-
- if (FAILED(m_mask->GetSurfaceLevel(0, &m_maskSurface))) {
- qWarning() << "QDirect3DPaintEngine: GetSurfaceLevel() failed.";
- }
-
- m_pe->m_d3d_device->ColorFill(m_maskSurface, 0, D3DCOLOR_ARGB(0,0,0,0));
- D3DXMATRIX projMatrix;
- pD3DXMatrixOrthoOffCenterLH(&projMatrix, 0, m_width, m_height, 0, 0, 1);
- m_pe->m_effect->SetMatrix("g_mMaskProjection", &projMatrix);
- m_pe->m_effect->SetTexture("g_mAAMask", m_mask);
-}
-
-void QD3DDrawHelper::beforeReset()
-{
- resetMask();
- m_clearmask = true;
-
- if (m_maskSurface) {
- m_maskSurface->Release();
- m_maskSurface = 0;
- }
-
- if (m_mask) {
- m_mask->Release();
- m_mask = 0;
- }
-
- if (m_depthStencilSurface) {
- m_depthStencilSurface->Release();
- m_depthStencilSurface = 0;
- }
-
- if (m_d3dvbuff)
- m_d3dvbuff->Release();
-}
-
-void QD3DDrawHelper::afterReset()
-{
- if (FAILED(m_pe->m_d3d_device->CreateVertexBuffer(QT_VERTEX_BUF_SIZE*sizeof(vertex), D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
- QD3DFVF_CSVERTEX,
- D3DPOOL_DEFAULT, &m_d3dvbuff, NULL))) {
- qWarning() << "QDirect3DPaintEngine: failed to create vertex buffer.";
- }
-
- m_pe->m_d3d_device->SetStreamSource(0, m_d3dvbuff, 0, sizeof(vertex));
- m_pe->m_d3d_device->SetFVF(QD3DFVF_CSVERTEX);
-
- m_startindex = 0;
- m_index = 0;
-}
-
-IDirect3DSurface9 *QD3DDrawHelper::freeMaskSurface()
-{
- // we need to make sure the mask is cleared when it's used for something else
- resetMask();
- m_clearmask = true;
-
- return m_maskSurface;
-}
-
-int QD3DDrawHelper::drawAntialiasedMask(int offset, int maxoffset)
-{
- int newoffset = offset;
- QD3DBatchItem *item = &(m_pe->m_batch.items[offset]);
-
- // set mask as render target
- if (FAILED(m_pe->m_d3d_device->SetRenderTarget(0, m_maskSurface)))
- qWarning() << "QDirect3DPaintEngine: SetRenderTarget failed!";
-
- if (m_clearmask) {
- m_pe->m_d3d_device->Clear(0, 0, D3DCLEAR_TARGET,D3DCOLOR_ARGB(0,0,0,0), 0, 0);
- m_clearmask = false;
- }
-
- // fill the mask
- m_pe->m_statemanager->beginPass(PASS_AA_CREATEMASK);
- for (; newoffset<maxoffset; ++newoffset) {
- item = &(m_pe->m_batch.items[newoffset]);
- if (!(item->m_info & QD3DBatchItem::BI_AA) || !(item->m_info & QD3DBatchItem::BI_MASK)) {
- break;
- } else if (item->m_info & QD3DBatchItem::BI_MASKFULL) {
- item->m_info &= ~QD3DBatchItem::BI_MASKFULL;
- m_clearmask = true;
- break;
- }
-
- m_pe->m_statemanager->startStateBlock();
- if (item->m_info & QD3DBatchItem::BI_MASKSCISSOR) {
- RECT rect;
- QRectF srect = item->m_brect.adjusted(item->m_xoffset, item->m_yoffset,
- item->m_xoffset, item->m_yoffset);
- rect.left = qMax(qRound(srect.left()), 0);
- rect.top = qMax(qRound(srect.top()), 0);
- rect.bottom = qMin(m_height, qRound(srect.bottom()));
- rect.right = qMin(m_width, qRound(srect.right()));
- m_pe->m_d3d_device->SetScissorRect(&rect);
- m_pe->m_statemanager->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
- }
- m_pe->m_statemanager->setMaskChannel(item->m_maskpos.channel);
- m_pe->m_statemanager->endStateBlock();
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- int vbstart = item->m_offset;
- for (int i=vbstart; i<(vbstart + (item->m_count * 3)); ++i) {
- if (accesscontrol[i] != WRITE)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[i] |= READ;
- }
-#endif
-
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, item->m_offset, item->m_count);
-
- if (item->m_info & QD3DBatchItem::BI_MASKSCISSOR) {
- m_pe->m_statemanager->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
- }
- }
- m_pe->m_statemanager->endPass();
-
- return newoffset;
-}
-
-void QD3DDrawHelper::drawAliasedMask(int offset)
-{
- QD3DBatchItem *item = &(m_pe->m_batch.items[offset]);
- if (item->m_info & QD3DBatchItem::BI_MASK) {
- m_pe->m_statemanager->beginPass( (item->m_info & QD3DBatchItem::BI_WINDING) ? PASS_STENCIL_WINDING : PASS_STENCIL_ODDEVEN );
- int prev_stop = 0;
- for (int i=0; i<item->m_pointstops.count(); ++i) {
- int stop = item->m_pointstops.at(i);
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- int vbstart = (item->m_offset + prev_stop);
- for (int j=vbstart; j<(vbstart+(stop - prev_stop)); ++j) {
- if (accesscontrol[j] != WRITE)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[j] |= READ;
- }
-#endif
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLEFAN, item->m_offset + prev_stop, (stop - prev_stop) - 2);
- prev_stop = stop;
- }
- m_pe->m_statemanager->endPass();
- }
-}
-
-void QD3DDrawHelper::drawTextItem(QD3DBatchItem *item)
-{
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- int vbstart = item->m_offset;
- for (int j=vbstart; j<(vbstart + ((item->m_count * 2) * 3)); ++j) {
- if (accesscontrol[j] != WRITE)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[j] |= READ;
- }
-#endif
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, item->m_offset, item->m_count*2);
-}
-
-void QD3DDrawHelper::drawAliasedLines(QD3DBatchItem *item)
-{
- m_pe->m_statemanager->setCosmeticPen(item->m_info & QD3DBatchItem::BI_COSMETICPEN);
- if (item->m_info & QD3DBatchItem::BI_TRANSFORM) {
- m_pe->m_statemanager->setTransformation(&item->m_matrix);
- } else {
- m_pe->m_statemanager->setTransformation();
- }
- int pass = (item->m_info & QD3DBatchItem::BI_MASK)
- ? PASS_ALIASED_LINES
- : PASS_ALIASED_LINES_DIRECT;
- m_pe->m_statemanager->beginPass(pass);
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLELIST, item->m_offset, (item->m_count + 2) / 3);
- m_pe->m_statemanager->endPass();
-}
-
-void QD3DDrawHelper::drawAntialiasedBoundingRect(QD3DBatchItem *item)
-{
- if (item->m_info & QD3DBatchItem::BI_SCISSOR) {
- RECT rect;
- rect.left = qMax(qRound(item->m_brect.left()), 0);
- rect.top = qMax(qRound(item->m_brect.top()), 0);
- rect.bottom = qMin(m_height, qRound(item->m_brect.bottom()));
- rect.right = qMin(m_width, qRound(item->m_brect.right()));
- m_pe->m_d3d_device->SetScissorRect(&rect);
- m_pe->m_statemanager->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
- }
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- int vbstart = item->m_offset + (item->m_count * 3);
- for (int j=vbstart; j<(vbstart + 4); ++j) {
- if (accesscontrol[j] != WRITE)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[j] |= READ;
- }
-#endif
-
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLEFAN, item->m_offset + (item->m_count * 3), 2);
-
- if (item->m_info & QD3DBatchItem::BI_SCISSOR) {
- m_pe->m_statemanager->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
- }
-}
-
-void QD3DDrawHelper::drawAliasedBoundingRect(QD3DBatchItem *item)
-{
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- int vbstart = (item->m_offset + item->m_count + 2);
- for (int j=vbstart; j<(vbstart + 4); ++j) {
- if (accesscontrol[j] != WRITE)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[j] |= READ;
- }
-#endif
-
- m_pe->m_d3d_device->DrawPrimitive(D3DPT_TRIANGLEFAN, item->m_offset + item->m_count + 2, 2);
-}
-
-void QD3DDrawHelper::addTrap(const Trapezoid &trap)
-{
- qreal topLeftY = Q27Dot5ToDouble(trap.topLeft->y) - m_yoffset;
- qreal topLeftX = Q27Dot5ToDouble(trap.topLeft->x) - m_xoffset;
- qreal topRightY = Q27Dot5ToDouble(trap.topRight->y) - m_yoffset;
- qreal topRightX = Q27Dot5ToDouble(trap.topRight->x) - m_xoffset;
- qreal top = Q27Dot5ToDouble(trap.top) - m_yoffset;
- qreal bottom = Q27Dot5ToDouble(trap.bottom) - m_yoffset;
-
- Q27Dot5 _h = trap.topLeft->y - trap.bottomLeft->y;
- Q27Dot5 _w = trap.topLeft->x - trap.bottomLeft->x;
- qreal _leftA = (qreal)_w/_h;
- qreal _leftB = topLeftX - _leftA * topLeftY;
-
- _h = trap.topRight->y - trap.bottomRight->y;
- _w = trap.topRight->x - trap.bottomRight->x;
- qreal _rightA = (qreal)_w/_h;
- qreal _rightB = topRightX - _rightA * topRightY;
-
- qreal invLeftA = qFuzzyIsNull(_leftA) ? 0.0 : 1.0 / _leftA;
- qreal invRightA = qFuzzyIsNull(_rightA) ? 0.0 : 1.0 / _rightA;
-
- vertex v1 = { {1.f, top - 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
- vertex v2 = { {0.f, top - 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
- vertex v3 = { {0.f, bottom + 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
-
- vertex v4 = { {1.f, top - 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
- vertex v5 = { {0.f, bottom + 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
- vertex v6 = { {1.f, bottom + 1.f, 0.5f}, 0.f,
- top, bottom, invLeftA, -invRightA,
- _leftA, _leftB, _rightA, _rightB};
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- for (int i=m_index; i<(m_index + 6); ++i) {
- if ((m_index + 6) > QT_VERTEX_BUF_SIZE)
- qDebug() << "Vertex Buffer: Buffer overflow";
- if (accesscontrol[i] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[i] |= WRITE;
- }
-#endif
-
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v5;
- m_vbuff[m_index++] = v6;
-
- // check if buffer is full
- if (m_index >= (QT_VERTEX_BUF_SIZE - 16)) {
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) / 3;
- m_startindex = m_index;
-
- QD3DBatchItem itemcopy = *m_item;
- m_item = m_pe->nextBatchItem();
- *m_item = itemcopy;
- m_item->m_info &= ~QD3DBatchItem::BI_MASKFULL;
-
- lockVertexBuffer();
- }
-}
-
-void QD3DDrawHelper::tessellate(const QPolygonF &poly) {
- int xoffset = m_item->m_maskpos.x;
- int yoffset = m_item->m_maskpos.y;
-
- int x = m_boundingRect.left();
- int y = m_boundingRect.top();
- m_xoffset = (x - xoffset) + 0.5f;
- m_yoffset = (y - yoffset) + 0.5f;
-
- QTessellator::tessellate(poly.data(), poly.count());
-
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) / 3;
- m_startindex = m_index;
-}
-
-inline void QD3DDrawHelper::lineToStencil(qreal x, qreal y)
-{
- QPointF lastPt = tess_lastpoint;
- tess_lastpoint = QPointF(x, y);
-
- if (m_isLine && m_firstPoint)
- return;
-
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- if (m_index > QT_VERTEX_BUF_SIZE)
- qDebug() << "Vertex Buffer: Buffer overflow";
- if (accesscontrol[m_index] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[m_index] |= WRITE;
-#endif
-
- vertex v;
- if (m_isLine) {
- vertex v1 = { {lastPt.x(), lastPt.y(), m_pe->m_pen_width }, m_color,
- -1.f, -1.f, x, y,
- 0.f, 0.f, 0.f, 0.f};
- vertex v2 = { {lastPt.x(), lastPt.y(), m_pe->m_pen_width }, m_color,
- 1.f, -1.f, x, y,
- 0.f, 0.f, 0.f, 0.f};
- vertex v3 = { {lastPt.x(), lastPt.y(), m_pe->m_pen_width }, m_color,
- 1.f, 1.f, x, y,
- 0.f, 0.f, 0.f, 0.f};
- vertex v4 = { {lastPt.x(), lastPt.y(), m_pe->m_pen_width }, m_color,
- -1.f, 1.f, x, y,
- 0.f, 0.f, 0.f, 0.f};
- m_vbuff[m_index++] = v1;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v4;
- m_vbuff[m_index++] = v2;
- m_vbuff[m_index++] = v3;
- } else {
- vertex v1 = { {x, y, 0.5f}, m_color,
- 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f};
- m_vbuff[m_index++] = v1;
- v = v1;
- }
- ++tess_index;
-
- // check if buffer is full
- if (m_index >= (QT_VERTEX_BUF_SIZE - 16)) {
- int firstindex = m_startindex;
- if (!m_item->m_pointstops.isEmpty())
- firstindex = m_item->m_pointstops.last();
-
- vertex first = m_vbuff[firstindex];
-
- // finish current polygon
- m_item->m_pointstops.append(tess_index);
- m_item->m_offset = m_startindex;
- m_startindex = m_index;
-
- // copy item
- QD3DBatchItem itemcopy = *m_item;
- m_item = m_pe->nextBatchItem();
- *m_item = itemcopy;
-
- // start new polygon
- lockVertexBuffer();
- m_item->m_pointstops.clear();
- if (!m_isLine) {
- tess_index = 2;
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- if (accesscontrol[m_index] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[m_index] |= WRITE;
-#endif
-
- m_vbuff[m_index++] = first;
-
-#ifdef QT_DEBUG_VERTEXBUFFER_ACCESS
- if (accesscontrol[m_index] != CLEAR)
- qDebug() << "Vertex Buffer: Access Error";
- accesscontrol[m_index] |= WRITE;
-#endif
-
- m_vbuff[m_index++] = v;
- } else {
- tess_index = 0;
- }
- }
-
- if (x > max_x)
- max_x = x;
- else if (x < min_x)
- min_x = x;
- if (y > max_y)
- max_y = y;
- else if (y < min_y)
- min_y = y;
-}
-
-inline void QD3DDrawHelper::curveToStencil(const QPointF &cp1, const QPointF &cp2,
- const QPointF &ep)
-{
- qreal inverseScale = 0.5f;
- qreal inverseScaleHalf = inverseScale / 2;
-
- QBezier beziers[32];
- beziers[0] = QBezier::fromPoints(tess_lastpoint, cp1, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- lineToStencil(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
-}
-
-QRectF QD3DDrawHelper::pathToVertexArrays(const QPainterPath &path)
-{
- m_isLine = (m_item->m_info & QD3DBatchItem::BI_FASTLINE);
- const QPainterPath::Element &first = path.elementAt(0);
- firstx = first.x;
- firsty = first.y;
- min_x = max_x = firstx;
- min_y = max_y = firsty;
-
- m_firstPoint = true;
- tess_index = 0;
- m_item->m_pointstops.clear();
- lineToStencil(firstx, firsty);
- m_firstPoint = false;
-
- for (int i=1; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- m_item->m_pointstops.append(tess_index);
- m_firstPoint = true;
- lineToStencil(e.x, e.y);
- m_firstPoint = false;
- break;
- case QPainterPath::LineToElement:
- lineToStencil(e.x, e.y);
- break;
- case QPainterPath::CurveToElement:
- curveToStencil(e, path.elementAt(i+1), path.elementAt(i+2));
- i+=2;
- break;
- default:
- break;
- }
- }
-
- if (!m_isLine)
- lineToStencil(firstx, firsty);
-
- m_item->m_pointstops.append(tess_index);
-
- m_item->m_offset = m_startindex;
- m_item->m_count = ( m_index - m_startindex ) - 2;
- m_startindex = m_index;
-
- QRectF result;
- result.setLeft(min_x);
- result.setRight(max_x);
- result.setTop(min_y);
- result.setBottom(max_y);
-
- if (m_isLine)
- result.adjust(0,0,1,1);
-
- return result;
-}
-
-void QD3DDrawHelper::resetMask()
-{
- m_mask_position.x = m_mask_position.y = QD3D_MASK_MARGIN;
- m_mask_position.channel = 0;
- m_mask_offsetX2 = m_mask_offsetY2 = QD3D_MASK_MARGIN;
-}
-
-
-static inline QPainterPath strokeForPath(const QPainterPath &path, const QPen &cpen) {
- QPainterPathStroker stroker;
- if (cpen.style() == Qt::CustomDashLine)
- stroker.setDashPattern(cpen.dashPattern());
- else
- stroker.setDashPattern(cpen.style());
-
- stroker.setCapStyle(cpen.capStyle());
- stroker.setJoinStyle(cpen.joinStyle());
- stroker.setMiterLimit(cpen.miterLimit());
- stroker.setWidth(cpen.widthF());
-
- QPainterPath stroke = stroker.createStroke(path);
- stroke.setFillRule(Qt::WindingFill);
- return stroke;
-}
-
-
-QDirect3DPaintEnginePrivate::~QDirect3DPaintEnginePrivate()
-{
-
-}
-
-void QDirect3DPaintEnginePrivate::updateClipPath(const QPainterPath &path, Qt::ClipOperation op)
-{
- //#### remove me
- QRegion r(path.toFillPolygon().toPolygon(), path.fillRule());
- updateClipRegion(r, op);
-
-/* if (m_draw_helper->needsFlushing())
- flushBatch();
-
- if (op == Qt::IntersectClip && !has_clipping)
- op = Qt::ReplaceClip;
-
- // switch to paths
- if (!m_has_complex_clipping) {
- m_clip_path = QPainterPath();
- m_clip_path.addRegion(m_clip_region);
- m_clip_region = QRegion();
- m_sysclip_path = QPainterPath();
- m_sysclip_path.addRegion(m_sysclip_region);
- m_sysclip_region = QRegion();
- m_has_complex_clipping = true;
- }
-
- QPainterPath cpath = m_matrix.map(path);
-
- QD3DBatchItem *item = &m_batch.items[m_batch.m_item_index++];
- item->m_info = QD3DBatchItem::BI_COMPLEXCLIP;
-
- switch (op) {
- case Qt::UniteClip:
- has_clipping = true;
- m_clip_path = m_clip_path.united(cpath);
- break;
- case Qt::ReplaceClip:
- has_clipping = true;
- m_clip_path = cpath;
- break;
- case Qt::NoClip:
- m_has_complex_clipping = false;
- has_clipping = false;
- item->m_info |= QD3DBatchItem::BI_CLEARCLIP;
- break;
- default: // intersect clip
- has_clipping = true;
- m_clip_path = m_clip_path.intersected(cpath);
- break;
- }
-
- if (!m_sysclip_path.isEmpty()) {
- item->m_info &= ~QD3DBatchItem::BI_CLEARCLIP;
- if (has_clipping)
- m_clip_path = m_clip_path.intersected(m_sysclip_path);
- else
- m_clip_path = m_sysclip_path;
- }
-
- // update the aliased clipping mask
- m_draw_helper->setClipPath(m_clip_path, item);
-
- // update the antialiased clipping mask
- if (m_draw_helper->needsFlushing())
- flushBatch();
-
- QD3DBatchItem *aaitem = &m_batch.items[m_batch.m_item_index++];
- aaitem->m_info = item->m_info|QD3DBatchItem::BI_AA;
- m_draw_helper->setClipPath(m_clip_path, aaitem); */
-}
-
-extern QPainterPath qt_regionToPath(const QRegion &region);
-
-void QDirect3DPaintEnginePrivate::updateClipRegion(const QRegion &clipregion, Qt::ClipOperation op)
-{
- if (m_draw_helper->needsFlushing())
- flushBatch();
- if (m_has_complex_clipping) {
- QPainterPath path = qt_regionToPath(clipregion);
- updateClipPath(path, op);
- return;
- }
-
- if (op == Qt::IntersectClip && m_clip_region.isEmpty())
- op = Qt::ReplaceClip;
-
- QRegion cregion = m_matrix.map(clipregion);
-
- QD3DBatchItem *item = nextBatchItem();
- item->m_info &= ~QD3DBatchItem::BI_AA;
-
- switch (op) {
- case Qt::UniteClip:
- m_clip_region = m_clip_region.united(cregion);
- break;
- case Qt::ReplaceClip:
- m_clip_region = cregion;
- break;
- case Qt::NoClip:
- m_clip_region = QRegion();
- item->m_info |= QD3DBatchItem::BI_CLEARCLIP;
- break;
- default: // intersect clip
- m_clip_region = m_clip_region.intersected(cregion);
- break;
- }
-
- QRegion crgn = m_clip_region;
- if (!m_sysclip_region.isEmpty()) {
- item->m_info &= ~QD3DBatchItem::BI_CLEARCLIP;
- if (!crgn.isEmpty())
- crgn = crgn.intersected(m_sysclip_region);
- else
- crgn = m_sysclip_region;
- }
-
- QPainterPath path = qt_regionToPath(crgn);
- m_draw_helper->setClipPath(path, &item);
-}
-
-void QDirect3DPaintEnginePrivate::updateFont(const QFont &)
-{
-}
-
-void QDirect3DPaintEnginePrivate::setRenderTechnique(RenderTechnique technique)
-{
- if (m_current_technique != technique) {
- if (m_current_technique != RT_NoTechnique)
- m_effect->End();
-
- if (technique == RT_Aliased) {
- m_effect->SetTechnique("Aliased");
- m_effect->Begin(0,D3DXFX_DONOTSAVESTATE);
- } else if (technique == RT_Antialiased) {
- m_effect->SetTechnique("Antialiased");
- m_effect->Begin(0,D3DXFX_DONOTSAVESTATE);
- }
- }
-
- m_current_technique = technique;
-}
-
-/*QPolygonF QDirect3DPaintEnginePrivate::transformedRect(const QRectF &brect) const
-{
- QPolygonF poly(brect);
- return m_matrix.map(poly);
-}
-
-QPolygonF QDirect3DPaintEnginePrivate::calcTextureCoords(const QPolygonF &trect) const
-{
- QPolygonF result(4);
- QRectF brect = trect.boundingRect();
- qreal angle = atan(trect.at(0).x() -
-}
-
-QPolygonF QDirect3DPaintEnginePrivate::offsetTextureCoords(const QRectF &brect, const QPolygonF &trect) const
-{
-
-}*/
-
-inline QD3DBatchItem *QDirect3DPaintEnginePrivate::nextBatchItem()
-{
- if (m_draw_helper->needsFlushing())
- flushBatch();
-
- QD3DBatchItem *item = &m_batch.items[m_batch.m_item_index++];
- item->m_info = m_current_state;
- item->m_cmode = m_cmode;
- return item;
-}
-
-qreal calculateAngle(qreal dx, qreal dy)
-{
- qreal angle;
-
- if (qFuzzyIsNull(dx)) {
- angle = (dy < 0) ? -M_PI/2 : M_PI/2;
- } else {
- angle = atanf(dy/dx);
- if (dx < 0)
- angle += M_PI;
- }
-
- return angle;
-}
-
-QPolygonF QDirect3DPaintEnginePrivate::brushCoordinates(const QRectF &r, bool stroke, qreal *fd) const
-{
- QBrush brush;
- QTransform matrix;
- Qt::BrushStyle style;
-
- if (stroke) {
- brush = m_pen.brush();
- matrix = m_inv_pen_matrix;
- style = m_pen_brush_style;
- } else {
- brush = m_brush;
- matrix = m_inv_brush_matrix;
- style = m_brush_style;
- }
-
- QPolygonF bpoly;
- switch(style) {
- case Qt::TexturePattern: {
- QTransform totxcoords;
- QRectF adj_brect = r.adjusted(-0.5f, -0.5f, -0.5f, -0.5f);
- totxcoords.scale(1.0f/brush.texture().width(),
- 1.0f/brush.texture().height());
- bpoly = matrix.map(QPolygonF(adj_brect));
- bpoly = totxcoords.map(bpoly);
- break; }
- case Qt::LinearGradientPattern: {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
- QPointF start = g->start();
- QPointF stop = g->finalStop();
- qreal dx = stop.x() - start.x();
- qreal dy = stop.y() - start.y();
- qreal length = sqrt(dx * dx + dy * dy);
- qreal angle = calculateAngle(dx, dy);
- QTransform totxcoords;
- QRectF adj_brect = r.adjusted(-0.5f, -0.5f, -0.5f, -0.5f);
- totxcoords.scale(1.0f/length, 1.0f/length);
- totxcoords.rotateRadians(-angle);
- totxcoords.translate(-start.x(), -start.y());
- bpoly = matrix.map(QPolygonF(adj_brect));
- bpoly = totxcoords.map(bpoly);
- break; }
- case Qt::ConicalGradientPattern: {
- const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
- QPointF center = g->center();
- qreal angle = g->angle();
- QTransform totxcoords;
- totxcoords.rotate(angle);
- totxcoords.translate(-center.x(), -center.y());
- bpoly = matrix.map(QPolygonF(r));
- bpoly = totxcoords.map(bpoly);
- break; }
- case Qt::RadialGradientPattern: {
- const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
- QPointF center = g->center();
- QPointF focalpoint = g->focalPoint();
- qreal dx = focalpoint.x() - center.x();
- qreal dy = focalpoint.y() - center.y();
- qreal radius = g->radius();
- *fd = sqrt(dx * dx + dy * dy) / radius;
- qreal angle = calculateAngle(dx, dy);
- QTransform totxcoords;
- totxcoords.scale(1.0f/radius, 1.0f/radius);
- totxcoords.rotateRadians(-angle);
- totxcoords.translate(-center.x(), -center.y());
- bpoly = matrix.map(QPolygonF(r));
- bpoly = totxcoords.map(bpoly);
- break; }
- default: {
- QTransform totxcoords;
- QRectF adj_brect = r.adjusted(-0.5f, -0.5f, -0.5f, -0.5f);
- QPixmap pat = getPattern(style);
- totxcoords.scale(1.0f/pat.width(),
- 1.0f/pat.height());
- bpoly = matrix.map(QPolygonF(adj_brect));
- bpoly = totxcoords.map(bpoly); }
- };
-
- return bpoly;
-}
-
-void QDirect3DPaintEnginePrivate::strokeAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform)
-{
- D3DCOLOR solid_color;
- QD3DBatchItem *item = nextBatchItem();
-
- if (!txform.isIdentity())
- path = txform.map(path);
-
- QRectF trect;
- QPolygonF txcoord;
-
- solid_color = m_pen_color;
- bool has_complex_brush = false;
- if (m_pen_brush_style != Qt::SolidPattern) {
- has_complex_brush = true;
- item->m_brush = m_pen.brush();
- item->m_info |= QD3DBatchItem::BI_COMPLEXBRUSH;
- item->m_opacity = m_opacity;
- }
-
- if (m_has_fast_pen) {
- item->m_info |= QD3DBatchItem::BI_FASTLINE;
- if (m_pen_brush_style == Qt::SolidPattern) {
- m_draw_helper->queueAliasedMask(path, &item, solid_color);
- item->m_info &= ~QD3DBatchItem::BI_MASK; // bypass stencil buffer
- return;
- }
- }
-
- QRectF txrect = m_draw_helper->queueAliasedMask(path, &item, 0);
-
- if (has_complex_brush) {
- trect = brect;
- txcoord = brushCoordinates(brect, true, &item->m_distance);
- item->m_info |= QD3DBatchItem::BI_TRANSFORM;
- item->m_matrix = m_matrix;
- } else {
- trect = txrect;
- static const QPolygonF empty_poly(4);
- txcoord = empty_poly;
- }
-
- m_draw_helper->queueRect(trect, item, solid_color, txcoord);
-}
-
-void QDirect3DPaintEnginePrivate::fillAliasedPath(QPainterPath path, const QRectF &brect, const QTransform &txform)
-{
- D3DCOLOR solid_color;
- QD3DBatchItem *item = nextBatchItem();
-
- if (!txform.isIdentity())
- path = txform.map(path);
-
- QRectF trect;
- QPolygonF txcoord;
-
- solid_color = m_brush_color;
- bool has_complex_brush = false;
- if (m_brush_style != Qt::SolidPattern) {
- has_complex_brush = true;
- item->m_brush = m_brush;
- item->m_info |= QD3DBatchItem::BI_COMPLEXBRUSH;
- item->m_opacity = m_opacity;
- }
-
- QRectF txrect = m_draw_helper->queueAliasedMask(path, &item, 0);
-
- if (has_complex_brush) {
- trect = brect;
- txcoord = brushCoordinates(brect, false, &item->m_distance);
- item->m_info |= QD3DBatchItem::BI_TRANSFORM;
- item->m_matrix = m_matrix;
- } else {
- trect = txrect;
- static const QPolygonF empty_poly(4);
- txcoord = empty_poly;
- }
-
- m_draw_helper->queueRect(trect, item, solid_color, txcoord);
-}
-
-void QDirect3DPaintEnginePrivate::fillAntialiasedPath(const QPainterPath &path, const QRectF &brect,
- const QTransform &txform, bool stroke)
-{
- D3DCOLOR solid_color;
- bool winding = (path.fillRule() == Qt::WindingFill);
- QPolygonF poly;
- QRectF txrect;
- QPainterPath tpath;
-
- if (m_has_aa_fast_pen && stroke) {
- tpath = txform.map(path);
- txrect = tpath.controlPointRect();
- txrect.adjust(-(m_pen_width/2),-(m_pen_width/2), m_pen_width, m_pen_width);
- } else {
- poly = path.toFillPolygon(txform);
- txrect = poly.boundingRect();
- }
-
- // brect = approx. bounding rect before transformation
- // txrect = exact bounding rect after transformation
- // trect = the rectangle to be drawn
- // txcoord = the texture coordinates
- // adj_txrect = adjusted rect to include aliased outline
-
- bool use_scissor = false;
- if (txrect.left() < 0) {
- txrect.adjust(-txrect.left(),0,0,0);
- use_scissor = true;
- }
- if (txrect.top() < 0) {
- txrect.adjust(0,-txrect.top(),0,0);
- use_scissor = true;
- }
-
- if (!txrect.isValid())
- return;
-
- QD3DBatchItem *item = nextBatchItem();
-
- QRectF adj_txrect = txrect.adjusted(-1,-1,1,1);
- QRectF trect;
- QPolygonF txcoord;
-
- bool has_complex_brush = false;
- if (stroke) {
- solid_color = m_pen_color;
- if (m_pen_brush_style != Qt::SolidPattern) {
- has_complex_brush = true;
- item->m_brush = m_pen.brush();
- }
- item->m_width = m_pen_width;
- } else {
- solid_color = m_brush_color;
- if (m_brush_style != Qt::SolidPattern) {
- has_complex_brush = true;
- item->m_brush = m_brush;
- }
- }
-
- qreal focaldist = 0;
- if (has_complex_brush) {
- trect = brect;
- txcoord = brushCoordinates(brect, stroke, &focaldist);
- } else {
- trect = adj_txrect;
- static const QPolygonF empty_poly(4);
- txcoord = empty_poly;
- }
-
- bool maskfull;
- item->m_maskpos = m_draw_helper->allocateMaskPosition(txrect, &maskfull);
- if (maskfull)
- item->m_info |= QD3DBatchItem::BI_MASKFULL;
- item->m_distance = focaldist;
-
- if (winding)
- item->m_info |= QD3DBatchItem::BI_WINDING;
-
- if (has_complex_brush) {
- item->m_info |= QD3DBatchItem::BI_SCISSOR|QD3DBatchItem::BI_COMPLEXBRUSH|
- QD3DBatchItem::BI_TRANSFORM;
- item->m_brect = adj_txrect;
- item->m_matrix = m_matrix;
- item->m_opacity = m_opacity;
- }
- if (use_scissor) {
- item->m_info |= QD3DBatchItem::BI_MASKSCISSOR;
- item->m_brect = adj_txrect;
- }
-
- if (m_has_aa_fast_pen && stroke) {
- m_draw_helper->queueAntialiasedLines(tpath, &item, txrect);
- } else {
- m_draw_helper->queueAntialiasedMask(poly, &item, txrect);
- }
-
- m_draw_helper->queueRect(trect, item, solid_color, txcoord);
-}
-
-QPainterPath QDirect3DPaintEnginePrivate::strokePathFastPen(const QPainterPath &path)
-{
- QPainterPath result;
- QBezier beziers[32];
- for (int i=0; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- result.moveTo(e.x, e.y);
- break;
- case QPainterPath::LineToElement:
- result.lineTo(e.x, e.y);
- break;
-
- case QPainterPath::CurveToElement:
- {
- QPointF sp = path.elementAt(i-1);
- QPointF cp2 = path.elementAt(i+1);
- QPointF ep = path.elementAt(i+2);
- i+=2;
-
- qreal inverseScaleHalf = m_inv_scale / 2;
- beziers[0] = QBezier::fromPoints(sp, e, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > m_inv_scale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2)
- - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3)
- - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- result.lineTo(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- } // case CurveToElement
- default:
- break;
- } // end of switch
- }
- return result;
-}
-
-void QDirect3DPaintEnginePrivate::strokePath(const QPainterPath &path, QRectF brect, bool simple)
-{
- QTransform txform;
- QPainterPath tpath;
-
- if (m_has_fast_pen || m_has_aa_fast_pen) {
- if (!simple)
- tpath = strokePathFastPen(path);
- else
- tpath = path; //already only lines
- } else {
- tpath = strokeForPath(path, m_pen);
- }
-
- if (tpath.isEmpty())
- return;
-
- //brect is null if the path is not transformed
- if (brect.isNull())
- txform = m_matrix;
-
- if (!brect.isNull()) {
- // brect is set when the path is transformed already,
- // this is the case when we have a cosmetic pen.
- brect.adjust(-(m_pen_width/2),-(m_pen_width/2), m_pen_width, m_pen_width);
- }
-
- if (brect.isNull())
- brect = tpath.controlPointRect();
- brect.adjust(-m_inv_scale,-m_inv_scale,m_inv_scale,m_inv_scale); //adjust for antialiasing
-
- if (m_current_state & QD3DBatchItem::BI_AA) {
- fillAntialiasedPath(tpath, brect, txform, true);
- } else {
- strokeAliasedPath(tpath, brect, txform);
- }
-}
-
-void QDirect3DPaintEnginePrivate::fillPath(const QPainterPath &path, QRectF brect)
-{
- QTransform txform;
-
- //brect is null if the path is not transformed
- if (brect.isNull())
- txform = m_matrix;
-
- if (brect.isNull())
- brect = path.controlPointRect();
- brect.adjust(-m_inv_scale,-m_inv_scale,m_inv_scale,m_inv_scale); //adjust for antialiasing
-
- if (m_current_state & QD3DBatchItem::BI_AA) {
- fillAntialiasedPath(path, brect, txform, false);
- } else {
- fillAliasedPath(path, brect, txform);
- }
-}
-
-
-bool QDirect3DPaintEnginePrivate::init()
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEnginePrivate::init()";
-#endif
-
- m_draw_helper = 0;
- m_gradient_cache = 0;
- m_dc = 0;
- m_dcsurface = 0;
-
- m_supports_d3d = false;
- m_current_state = 0;
- m_in_scene = false;
- m_has_fast_pen = false;
- m_has_aa_fast_pen = false;
- m_has_pen = false;
- m_has_brush = false;
- m_pen_color = 0;
- m_brush_color = 0;
- m_current_surface = 0;
- m_batch.m_item_index = 0;
- m_current_technique = RT_NoTechnique;
-
- if (!pDirect3DCreate9) {
- QLibrary d3d_lib(QLatin1String("d3d9.dll"));
- pDirect3DCreate9 = (PFNDIRECT3DCREATE9) d3d_lib.resolve("Direct3DCreate9");
- if (!pDirect3DCreate9) {
- qWarning("QDirect3DPaintEngine: failed to resolve symbols from d3d9.dll.\n"
- "Make sure you have the DirectX run-time installed.");
- return false;
- }
- }
-
- if (!pD3DXCreateBuffer || !pD3DXCreateEffect || !pD3DXMatrixOrthoOffCenterLH) {
- QLibrary d3dx_lib(QLatin1String("d3dx9_32.dll"));
- pD3DXCreateBuffer = (PFND3DXCREATEBUFFER) d3dx_lib.resolve("D3DXCreateBuffer");
- pD3DXCreateEffect = (PFND3DXCREATEEFFECT) d3dx_lib.resolve("D3DXCreateEffect");
- pD3DXMatrixOrthoOffCenterLH = (PFND3DXMATRIXORTHOOFFCENTERLH)
- d3dx_lib.resolve("D3DXMatrixOrthoOffCenterLH");
- if (!(pD3DXCreateBuffer && pD3DXCreateEffect && pD3DXMatrixOrthoOffCenterLH)) {
- qWarning("QDirect3DPaintEngine: failed to resolve symbols from d3dx9_32.dll.\n"
- "Make sure you have the DirectX run-time installed.");
- return false;
- }
- }
-
- if (!m_d3d_object) {
- m_d3d_object = pDirect3DCreate9(D3D_SDK_VERSION);
- if (!m_d3d_object) {
- qWarning("QDirect3DPaintEngine: failed to create Direct3D object.\n"
- "Direct3D support in Qt will be disabled.");
- return false;
- }
- }
-
- m_supports_d3d = testCaps();
- if (!m_supports_d3d)
- return false;
-
- m_surface_manager.init(m_d3d_object);
- m_d3d_device = m_surface_manager.device();
-
- if (!m_d3d_device)
- return false;
-
- /* load shaders */
- QFile file(QLatin1String(":/qpaintengine_d3d.fx"));
- QByteArray fxFile;
- if (file.open(QFile::ReadOnly))
- fxFile = file.readAll();
-
- if (fxFile.size() > 0) {
- LPD3DXBUFFER compout;
- pD3DXCreateBuffer(4096, &compout);
- DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE|D3DXFX_DONOTSAVESTATE|D3DXSHADER_OPTIMIZATION_LEVEL3;
- if(FAILED(pD3DXCreateEffect(m_d3d_device, fxFile.constData(), fxFile.size(),
- NULL, NULL, dwShaderFlags, NULL, &m_effect, &compout))) {
- qWarning("QDirect3DPaintEngine: failed to compile effect file");
- if (compout)
- qWarning((char *)compout->GetBufferPointer());
- m_supports_d3d = false;
- return false;
- }
- if (m_effect) {
- m_statemanager = new QD3DStateManager(m_d3d_device, m_effect);
- m_effect->SetStateManager(m_statemanager);
- m_draw_helper = new QD3DDrawHelper(this);
- initDevice();
- m_gradient_cache = new QD3DGradientCache(m_d3d_device);
- }
- } else {
- return false;
- }
-
- return true;
-}
-
-QPixmap QDirect3DPaintEnginePrivate::getPattern(Qt::BrushStyle style) const
-{
- if (!m_patterns.contains(style)) {
- QImage img(16,16,QImage::Format_ARGB32);
- img.fill(0);
- QPainter p(&img);
- p.setBrush(QBrush(Qt::white, style));
- p.setPen(Qt::NoPen);
- p.drawRect(0,0,16,16);
- p.end();
- QPixmap pattern(QPixmap::fromImage(img));
- QDirect3DPaintEnginePrivate *ct = const_cast<QDirect3DPaintEnginePrivate *>(this);
- ct->verifyTexture(pattern);
- ct->m_patterns.insert(style, pattern);
- }
-
- return m_patterns.value(style);
-}
-
-bool QDirect3DPaintEnginePrivate::testCaps()
-{
- D3DCAPS9 caps;
- if (FAILED(m_d3d_object->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
- return false;
-
- if ((caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
- && (caps.DevCaps & D3DDEVCAPS_PUREDEVICE)
- && (caps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST)
- && (caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
- return true;
-#if 0
- qDebug() << "Direct3D caps:";
- qDebug() << "D3DPRESENT_INTERVAL_IMMEDIATE:" << ((caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) != 0);
- qDebug() << "D3DDEVCAPS_PUREDEVICE:" << ((caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0);
- qDebug() << "D3DPRASTERCAPS_SCISSORTEST:" << ((caps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST) != 0);
- qDebug() << "D3DSTENCILCAPS_TWOSIDED:" << ((caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
-#endif
- return false;
-}
-
-void QDirect3DPaintEnginePrivate::initDevice()
-{
- m_statemanager->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- m_statemanager->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
- m_statemanager->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- m_statemanager->SetRenderState(D3DRS_LIGHTING, FALSE);
- m_statemanager->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
- m_statemanager->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
- m_statemanager->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
-}
-
-void QDirect3DPaintEnginePrivate::updatePen(const QPen &pen)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::updatePen";
-#endif
- m_pen = pen;
- m_has_cosmetic_pen = false;
- m_has_pen = (m_pen.style() != Qt::NoPen);
- if (m_has_pen) {
- m_pen_brush_style = m_pen.brush().style();
-
- if (m_pen_brush_style >= Qt::SolidPattern && m_pen_brush_style <= Qt::DiagCrossPattern) {
- int a, r, g, b;
- m_pen.color().getRgb(&r, &g, &b, &a);
- m_pen_color = D3DCOLOR_ARGB((int)(a * m_opacity),r,g,b);
- } else {
- m_pen_color = m_opacity_color;
- }
-
- m_has_cosmetic_pen = m_pen.isCosmetic();
-
- if (m_pen_brush_style != Qt::NoBrush &&
- m_pen_brush_style != Qt::SolidPattern) {
- bool ok;
- m_inv_pen_matrix = m_pen.brush().transform().inverted(&ok);
- if (!ok)
- qWarning() << "QDirect3DPaintEngine: No inverse matix for pen brush matrix.";
- }
-
- m_pen_width = m_pen.widthF();
- if (m_pen_width == 0.0f)
- m_pen_width = 1.0f;
- }
-}
-
-void QDirect3DPaintEnginePrivate::updateBrush(const QBrush &brush)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::updateBrush";
-#endif
- m_brush = brush;
- m_brush_style = m_brush.style();
- m_has_brush = (m_brush_style != Qt::NoBrush);
- if (m_has_brush) {
- if (m_brush_style >= Qt::SolidPattern && m_brush_style <= Qt::DiagCrossPattern) {
- int a, r, g, b;
- m_brush.color().getRgb(&r, &g, &b, &a);
- m_brush_color = D3DCOLOR_ARGB((int)(a * m_opacity),r,g,b);
- } else {
- m_brush_color = m_opacity_color;
- }
-
- if (m_brush_style != Qt::SolidPattern) {
- bool ok;
- m_inv_brush_matrix = (m_brush.transform() * m_brush_origin).inverted(&ok);
- if (!ok)
- qWarning() << "QDirect3DPaintEngine: No inverse matix for brush matrix.";
-
- // make sure the texture is loaded as a texture
- if (m_brush_style == Qt::TexturePattern)
- verifyTexture(m_brush.texture());
-
-
- }
- }
-}
-
-void QDirect3DPaintEnginePrivate::updateTransform(const QTransform &matrix)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::updateTransform";
-#endif
- m_matrix = matrix;
- m_inv_scale = qMax(1 / qMax( qMax(qAbs(m_matrix.m11()), qAbs(m_matrix.m22())),
- qMax(qAbs(m_matrix.m12()), qAbs(m_matrix.m21())) ), 0.0001);
- m_txop = matrix.type();
-}
-
-int QDirect3DPaintEnginePrivate::flushAntialiased(int offset)
-{
- // fills the mask (returns number of items added to the mask)
- int newoffset = m_draw_helper->drawAntialiasedMask(offset, m_batch.m_item_index);
-
- // set the render target to the current output surface
- if (FAILED(m_d3d_device->SetRenderTarget(0, m_current_surface)))
- qWarning() << "QDirect3DPaintEngine: SetRenderTarget failed!";
-
- // draw the bounding boxes (using the mask generated by drawAntialiasedMask)
- for (int i=offset; i<newoffset; ++i) {
- QD3DBatchItem *item = &(m_batch.items[i]);
- int pass = (item->m_info & QD3DBatchItem::BI_COMPLEXBRUSH) ? PASS_AA_DRAW : PASS_AA_DRAW_DIRECT;
- m_statemanager->beginPass(pass);
- prepareItem(item);
- if (item->m_info & QD3DBatchItem::BI_BRECT)
- m_draw_helper->drawAntialiasedBoundingRect(item);
- cleanupItem(item);
- }
-
- m_statemanager->endPass();
-
- return newoffset;
-}
-
-bool QDirect3DPaintEnginePrivate::prepareBatch(QD3DBatchItem *item, int offset)
-{
- if (item->m_info & QD3DBatchItem::BI_CLIP) {
- setRenderTechnique(RT_Aliased);
- if (item->m_info & QD3DBatchItem::BI_CLEARCLIP) {
- m_d3d_device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
- return true;
- }
-
- m_draw_helper->drawAliasedMask(offset);
- m_d3d_device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
- if (item->m_info & QD3DBatchItem::BI_BRECT) {
- m_statemanager->beginPass(PASS_STENCIL_CLIP);
- m_draw_helper->drawAliasedBoundingRect(item);
- m_statemanager->endPass();
- }
-
- return true;
- }
-
- if (item->m_info & QD3DBatchItem::BI_AA) {
- setRenderTechnique(RT_Antialiased);
- } else {
- setRenderTechnique(RT_Aliased);
- }
-
- return false;
-}
-
-void QDirect3DPaintEnginePrivate::prepareItem(QD3DBatchItem *item) {
- // pixmap
- int brushmode = 0;
- m_statemanager->startStateBlock();
- if ((item->m_info & QD3DBatchItem::BI_PIXMAP) || (item->m_info & QD3DBatchItem::BI_IMAGE)) {
- QRasterPixmapData *data = static_cast<QRasterPixmapData*>(item->m_pixmap.data);
- IDirect3DTexture9 *tex = (item->m_info & QD3DBatchItem::BI_PIXMAP) ?
- data->texture : item->m_texture;
- m_statemanager->setTexture(tex);
- brushmode = 5;
- }
-
- if (item->m_info & QD3DBatchItem::BI_AA) {
- m_statemanager->setMaskChannel(item->m_maskpos.channel);
- m_statemanager->setMaskOffset(item->m_xoffset, item->m_yoffset);
- }
-
- if (item->m_info & QD3DBatchItem::BI_COMPLEXBRUSH) {
- const QBrush brush = item->m_brush;
- switch (brush.style()) {
- case Qt::TexturePattern: {
- QRasterPixmapData *data = static_cast<QRasterPixmapData*>(brush.texture().data);
- m_statemanager->setTexture(data->texture, QGradient::RepeatSpread);
- brushmode = 1;
- break;
- }
- case Qt::LinearGradientPattern:
- m_statemanager->setTexture(m_gradient_cache->
- getBuffer(brush.gradient()->stops(), item->m_opacity),
- brush.gradient()->spread());
- brushmode = 2;
- break;
- case Qt::ConicalGradientPattern:
- m_statemanager->setTexture(m_gradient_cache->
- getBuffer(brush.gradient()->stops(), item->m_opacity),
- brush.gradient()->spread());
- brushmode = 3;
- break;
- case Qt::RadialGradientPattern:
- m_statemanager->setTexture(m_gradient_cache->
- getBuffer(brush.gradient()->stops(), item->m_opacity),
- brush.gradient()->spread());
- m_statemanager->setFocalDistance(item->m_distance);
- brushmode = 4;
- break;
- default: {
- QRasterPixmapData *data = static_cast<QRasterPixmapData*>(getPattern(brush.style()).data);
- m_statemanager->setTexture(data->texture, QGradient::RepeatSpread);
- brushmode = 5;
- }
- };
- }
-
- if (item->m_info & QD3DBatchItem::BI_TRANSFORM) {
- m_statemanager->setTransformation(&item->m_matrix);
- } else {
- m_statemanager->setTransformation();
- }
-
- m_statemanager->setBrushMode(brushmode);
- setCompositionMode(item->m_cmode);
- m_statemanager->endStateBlock();
-}
-
-
-void QDirect3DPaintEnginePrivate::releaseDC()
-{
- if (m_dc) {
- m_dcsurface->ReleaseDC(m_dc);
- m_dcsurface = 0;
- m_dc = 0;
- }
-}
-
-
-void QDirect3DPaintEnginePrivate::cleanupItem(QD3DBatchItem *item)
-{
- if (item->m_info & QD3DBatchItem::BI_PIXMAP)
- item->m_pixmap = QPixmap();
- item->m_brush = QBrush();
-}
-
-void QDirect3DPaintEnginePrivate::verifyTexture(const QPixmap &pm)
-{
- QRasterPixmapData *pmData = static_cast<QRasterPixmapData*>(pm.data);
- if (!pmData->texture) {
- QImage im = pmData->image;
- // bitmaps are drawn with the current pen color
- if (im.depth() == 1) {
- QVector<QRgb> colors(2);
- colors[0] = 0;
- colors[1] = m_pen.color().rgba();
- im.setColorTable(colors);
- }
- im = im.convertToFormat(QImage::Format_ARGB32);
- if (FAILED(m_d3d_device->CreateTexture(im.width(), im.height(), 1, 0,
- D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pmData->texture, 0)))
- {
- qWarning("QDirect3DPaintEngine: unable to create Direct3D texture from pixmap.");
- return;
- }
- D3DLOCKED_RECT rect;
- if (FAILED(pmData->texture->LockRect(0, &rect, 0, 0))) {
- qDebug() << "QDirect3DPaintEngine: unable to lock texture rect.";
- return;
- }
- DWORD *dst = (DWORD *) rect.pBits;
- DWORD *src = (DWORD *) im.scanLine(0);
-
- Q_ASSERT((rect.Pitch/4) == (im.bytesPerLine()/4));
- memcpy(dst, src, rect.Pitch*im.height());
- pmData->texture->UnlockRect(0);
- }
-}
-
-bool QDirect3DPaintEnginePrivate::isFastRect(const QRectF &rect)
-{
- if (m_matrix.type() < QTransform::TxRotate) {
- QRectF r = m_matrix.mapRect(rect);
- return r.topLeft().toPoint() == r.topLeft()
- && r.bottomRight().toPoint() == r.bottomRight();
- }
-
- return false;
-}
-
-void QDirect3DPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode)
-{
- switch(mode) {
- case QPainter::CompositionMode_SourceOver:
- default:
- m_statemanager->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
- m_statemanager->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
- };
-}
-
-void QDirect3DPaintEnginePrivate::cleanup()
-{
- // clean batch
- for(int i=0; i<QD3D_BATCH_SIZE; ++i) {
- m_batch.items[i].m_brush = QBrush();
- m_batch.items[i].m_pixmap = QPixmap();
- }
-
- m_surface_manager.cleanup();
- m_patterns.clear();
-
- delete m_gradient_cache;
- delete m_draw_helper;
-
- if (m_effect)
- m_effect->Release();
-
- if (m_d3d_object)
- m_d3d_object->Release();
-
- m_effect = 0;
- m_d3d_object = 0;
- m_gradient_cache = 0;
- m_draw_helper = 0;
-}
-
-void QDirect3DPaintEnginePrivate::flushAliased(QD3DBatchItem *item, int offset)
-{
- m_draw_helper->drawAliasedMask(offset);
-
- if (item->m_info & QD3DBatchItem::BI_BRECT) {
- int pass = (item->m_info & QD3DBatchItem::BI_MASK) ? PASS_STENCIL_DRAW_DIRECT : PASS_STENCIL_NOSTENCILCHECK_DIRECT;
- if (item->m_info & (QD3DBatchItem::BI_COMPLEXBRUSH|QD3DBatchItem::BI_IMAGE|QD3DBatchItem::BI_PIXMAP) )
- pass = (item->m_info & QD3DBatchItem::BI_MASK) ? PASS_STENCIL_DRAW : PASS_STENCIL_NOSTENCILCHECK;
- m_statemanager->beginPass(pass);
- prepareItem(item);
- m_draw_helper->drawAliasedBoundingRect(item);
- cleanupItem(item);
- m_statemanager->endPass();
- }
-}
-
-void QDirect3DPaintEnginePrivate::flushText(QD3DBatchItem *item, int)
-{
- prepareItem(item);
- m_statemanager->setTexture(item->m_texture);
- m_statemanager->setBrushMode(1);
-// m_statemanager->SetRenderState(D3DRS_BLENDFACTOR, item->m_brush.color().rgba());
- m_statemanager->beginPass(m_cleartype_text ? PASS_CLEARTYPE_TEXT : PASS_TEXT);
- m_draw_helper->drawTextItem(item);
- m_statemanager->endPass();
- cleanupItem(item);
-}
-
-void QDirect3DPaintEnginePrivate::flushLines(QD3DBatchItem *item, int)
-{
- m_draw_helper->drawAliasedLines(item);
-
- if (item->m_info & QD3DBatchItem::BI_BRECT) {
- int pass = (item->m_info & QD3DBatchItem::BI_COMPLEXBRUSH) ? PASS_STENCIL_DRAW : PASS_STENCIL_DRAW_DIRECT;
- m_statemanager->beginPass(pass);
- prepareItem(item);
- m_draw_helper->drawAliasedBoundingRect(item);
- cleanupItem(item);
- m_statemanager->endPass();
- }
-}
-
-void QDirect3DPaintEnginePrivate::flushBatch()
-{
-// static int dbgcounter = 0;
-// ++dbgcounter;
-// qDebug() << " -> flush" << dbgcounter;
-
- int offset = 0;
- m_draw_helper->unlockVertexBuffer();
- releaseDC();
-
- // iterate over all items in the batch
- while (offset != m_batch.m_item_index) {
- QD3DBatchItem *item = &(m_batch.items[offset]);
-
- if (prepareBatch(item, offset)) {
- ++offset;
- continue;
- }
-
- if (item->m_info & QD3DBatchItem::BI_FASTLINE) {
- flushLines(item, offset++);
- } else if (item->m_info & QD3DBatchItem::BI_AA) {
- offset = flushAntialiased(offset);
- } else if (item->m_info & QD3DBatchItem::BI_TEXT) {
- flushText(item, offset++);
- } else {
- flushAliased(item, offset++);
- }
- }
-
- // reset batch
- m_batch.m_item_index = 0;
-
- // release doomed textures
- for (int i=0; i<qd3d_release_list.size(); ++i)
- qd3d_release_list.at(i)->Release();
- qd3d_release_list.clear();
-}
-
-QDirect3DPaintEngine::QDirect3DPaintEngine()
- : QPaintEngine(*(new QDirect3DPaintEnginePrivate),
- PaintEngineFeatures(AllFeatures & ~ObjectBoundingModeGradients))
-{ }
-
-QDirect3DPaintEngine::~QDirect3DPaintEngine()
-{
-}
-
-bool QDirect3DPaintEngine::begin(QPaintDevice *device)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::begin";
-#endif
- Q_D(QDirect3DPaintEngine);
- setActive(true);
-
- QSize old_size = d->m_surface_size;
- d->m_surface_size = QRect(0, 0, device->width(), device->height()).size();
-
- d->m_current_state = 0;
- d->m_inv_scale = 1;
- d->m_opacity = 1.0f;
- d->m_opacity_color = D3DCOLOR_ARGB(255,255,255,255);
- d->m_matrix = QTransform();
- d->m_brush_origin = QTransform();
- d->m_txop = QTransform::TxNone;
- d->m_cmode = QPainter::CompositionMode_SourceOver;
-
- Q_ASSERT(device && device->devType() == QInternal::Widget);
- if (d->m_d3d_device == 0) {
- qWarning() << "QDirect3DPaintEngine: No Device!";
- return false;
- }
-
- d->m_cleartype_text = false;
-// QT_WA({
-// UINT result;
-// BOOL ok;
-// ok = SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0);
-// if (ok)
-// d->m_cleartype_text = (result == FE_FONTSMOOTHINGCLEARTYPE);
-// }, {
-// UINT result;
-// BOOL ok;
-// ok = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0);
-// if (ok)
-// d->m_cleartype_text = (result == FE_FONTSMOOTHINGCLEARTYPE);
-// });
-
- d->m_surface_manager.setPaintDevice(device);
- int status = d->m_surface_manager.status();
- if (status & QD3DSurfaceManager::NeedsResetting) {
- d->m_effect->OnLostDevice();
- d->m_draw_helper->beforeReset();
- d->m_statemanager->reset();
- d->m_surface_manager.reset();
- d->m_draw_helper->afterReset();
- d->m_effect->OnResetDevice();
- d->initDevice();
- }
-
- LPDIRECT3DSURFACE9 newsurface = d->m_surface_manager.renderTarget();
- if (d->m_current_surface != newsurface) {
- d->m_current_surface = newsurface;
- if (FAILED(d->m_d3d_device->SetRenderTarget(0, newsurface)))
- qWarning() << "QDirect3DPaintEngine: SetRenderTarget failed!";
- }
-
- status = d->m_surface_manager.status();
- if (status & QD3DSurfaceManager::MaxSizeChanged) {
- QSize maxsize = d->m_surface_manager.maxSize();
- d->m_draw_helper->setMaskSize(maxsize);
- int masksize[2] = {maxsize.width(), maxsize.height()};
- d->m_effect->SetIntArray("g_mMaskSize", masksize, 2);
- }
-
- if (old_size != d->m_surface_size) {
- D3DXMATRIX projMatrix;
- pD3DXMatrixOrthoOffCenterLH(&projMatrix, 0, d->m_surface_size.width(), d->m_surface_size.height(), 0, 0.0f, 1.0f);
- d->m_statemanager->setProjection(&projMatrix);
- }
-
- if (!d->m_in_scene) {
- if (FAILED(d->m_d3d_device->BeginScene())) {
- qWarning() << "QDirect3DPaintEngine: BeginScene() failed.";
- return false;
- }
- QWidget *widget = static_cast<QWidget *>(device);
- if (widget->autoFillBackground() == true) {
- QColor color = widget->palette().brush(widget->backgroundRole()).color();
- RECT rect = {0, 0, widget->width(), widget->height()};
- d->m_d3d_device->ColorFill(d->m_current_surface, &rect,
- D3DCOLOR_ARGB(color.alpha(), color.red(), color.green(), color.blue()));
- }
- d->m_in_scene = true;
- }
-
- // set system clip
- d->m_clipping_enabled = false;
- d->m_has_complex_clipping = false;
-
- d->m_sysclip_region = systemClip();
- QVector<QRect> rects = d->m_sysclip_region.rects();
- if (rects.count() == 1 && rects.at(0).size() == d->m_surface_size)
- d->m_sysclip_region = QRegion();
-
- d->updateClipRegion(QRegion(), Qt::NoClip);
-
- return true;
-}
-
-void QDirect3DPaintEngine::drawEllipse(const QRectF &rect)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawEllipse (float)";
-#endif
- QPaintEngine::drawEllipse(rect);
-}
-
-void QDirect3DPaintEngine::drawEllipse(const QRect &rect)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawEllipse";
-#endif
- QPaintEngine::drawEllipse(rect);
-}
-
-void QDirect3DPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawImage";
-#endif
-
- Q_D(QDirect3DPaintEngine);
- int width = image.width();
- int height = image.height();
-
- // transform rectangle
- QPolygonF txrect(QRectF(sr.left() / width, sr.top() / height,
- sr.width() / width, sr.height() / height));
-
- QD3DBatchItem *item = d->nextBatchItem();
- item->m_info = QD3DBatchItem::BI_IMAGE | QD3DBatchItem::BI_TRANSFORM;
- item->m_texture = qd3d_image_cache()->lookup(d->m_d3d_device, image);
- item->m_matrix = d->m_matrix;
- d->m_draw_helper->queueRect(r.adjusted(-0.5f,-0.5f,-0.5f,-0.5f), item, d->m_opacity_color, txrect);
-}
-
-void QDirect3DPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawLines (float)";
-#endif
- Q_D(QDirect3DPaintEngine);
-
- if (!d->m_has_pen)
- return;
-
- if (d->m_has_fast_pen && (d->m_pen_brush_style == Qt::SolidPattern)) {
- QD3DBatchItem *item = d->nextBatchItem();
- if (d->m_pen.isCosmetic())
- item->m_info |= QD3DBatchItem::BI_COSMETICPEN;
- item->m_info |= QD3DBatchItem::BI_TRANSFORM;
- item->m_matrix = d->m_matrix;
- d->m_draw_helper->queueAliasedLines(lines, lineCount, &item);
- } else {
- QRectF brect;
- QPainterPath path;
-
- // creates a path with the lines
- path.moveTo(lines[0].x1(), lines[0].y1());
- qreal lastx = lines[0].x2();
- qreal lasty = lines[0].y2();
- path.lineTo(lastx, lasty);
-
- for (int i=1; i<lineCount; ++i) {
- qreal x = lines[i].x1();
- qreal y = lines[i].y1();
- if (lastx != x || lasty != y) {
- path.moveTo(x, y);
- }
- path.lineTo(lines[i].x2(), lines[i].y2());
- }
-
- if (d->m_has_cosmetic_pen) {
- brect = path.controlPointRect();
- path = d->m_matrix.map(path);
- }
-
- d->strokePath(path, brect, true);
- }
-}
-
-void QDirect3DPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawLines";
-#endif
- QPaintEngine::drawLines(lines, lineCount);
-}
-
-void QDirect3DPaintEngine::drawPath(const QPainterPath &path)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPath";
-#endif
- Q_D(QDirect3DPaintEngine);
-
- if (path.isEmpty())
- return;
-
- QRectF brect;
- QPainterPath tpath;
-
- if (d->m_has_cosmetic_pen) {
- brect = path.controlPointRect();
- tpath = d->m_matrix.map(path);
- } else {
- tpath = path;
- }
-
- if (d->m_has_brush)
- d->fillPath(tpath, brect);
-
- if (d->m_has_pen)
- d->strokePath(tpath, brect);
-}
-
-
-QPointF QDirect3DPaintEnginePrivate::transformPoint(const QPointF &p, qreal *w) const
-{
- (*w) = 1.0f;
- qreal fx = p.x();
- qreal fy = p.y();
- qreal nx = m_matrix.m11()*fx + m_matrix.m21()*fy + m_matrix.m31();
- qreal ny = m_matrix.m12()*fx + m_matrix.m22()*fy + m_matrix.m32();
- if (!m_matrix.isAffine()) {
- *w = m_matrix.m13()*fx + m_matrix.m23()*fy + m_matrix.m33();
- //*w = 1/(*w);
- nx = nx/(*w);
- ny = ny/(*w);
- }
- return QPointF(nx, ny);
-}
-
-void QDirect3DPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPixmap";
-#endif
- Q_D(QDirect3DPaintEngine);
-
- if (d->m_draw_helper->needsFlushing())
- d->flushBatch();
-
- int width = pm.width();
- int height = pm.height();
-
- // transform rectangle
- QPolygonF txrect(QRectF(sr.left() / width, sr.top() / height,
- sr.width() / width, sr.height() / height));
-
- QD3DBatchItem *item = d->nextBatchItem();
- item->m_info = QD3DBatchItem::BI_PIXMAP|QD3DBatchItem::BI_TRANSFORM;
-
- item->m_pixmap = pm;
- d->verifyTexture(item->m_pixmap);
-
- item->m_matrix = d->m_matrix;
- d->m_draw_helper->queueRect(r.adjusted(-0.5f,-0.5f,-0.5f,-0.5f), item, d->m_opacity_color, txrect);
-}
-
-void QDirect3DPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPoints (float)";
-#endif
- QPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirect3DPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPoints";
-#endif
- QPaintEngine::drawPoints(points, pointCount);
-}
-
-void QDirect3DPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPolygon";
-#endif
- Q_D(QDirect3DPaintEngine);
-
- if (d->m_has_brush && mode != PolylineMode) {
- QPainterPath path;
- path.setFillRule(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);
- path.moveTo(points[0]);
- for (int i=1; i<pointCount; ++i)
- path.lineTo(points[i]);
- if (path.isEmpty())
- return;
- d->fillPath(path, QRectF());
- }
-
- if (d->m_has_pen) {
- QPainterPath path(points[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(points[i]);
- if (mode != PolylineMode)
- path.lineTo(points[0]);
-
- if (path.isEmpty())
- return;
- QRectF brect;
- if (d->m_has_cosmetic_pen) {
- brect = path.controlPointRect();
- path = d->m_matrix.map(path);
- }
-
- d->strokePath(path, brect);
- }
-}
-
-void QDirect3DPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawPolygon";
-#endif
- QPaintEngine::drawPolygon(points, pointCount, mode);
-}
-
-void QDirect3DPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QDirect3DPaintEngine);
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawRects (float)";
-#endif
- for (int i=0; i<rectCount; ++i) {
- if ((d->m_brush_style == Qt::SolidPattern) &&
- (!(d->m_current_state & QD3DBatchItem::BI_AA) || d->isFastRect(rects[i]))) {
- QD3DBatchItem *item = d->nextBatchItem();
- item->m_info |= QD3DBatchItem::BI_TRANSFORM;
- item->m_info &= ~QD3DBatchItem::BI_AA;
- item->m_matrix = d->m_matrix;
- const QRectF rect = rects[i];
- d->m_draw_helper->queueRect(rect, item, d->m_brush_color);
-
- if (d->m_has_pen) {
- if (d->m_has_fast_pen && (d->m_pen_brush_style == Qt::SolidPattern)) {
- QLineF lines[4];
- qreal x1 = rect.x();
- qreal y1 = rect.y();
- qreal x2 = rect.width() + x1;
- qreal y2 = rect.height() + y1;
- lines[0] = QLineF(x1, y1, x2, y1);
- lines[1] = QLineF(x2, y1, x2, y2);
- lines[2] = QLineF(x2, y2, x1, y2);
- lines[3] = QLineF(x1, y2, x1, y1);
- QD3DBatchItem *item = d->nextBatchItem();
- if (d->m_pen.isCosmetic())
- item->m_info |= QD3DBatchItem::BI_COSMETICPEN;
- item->m_info |= QD3DBatchItem::BI_TRANSFORM;
- item->m_matrix = d->m_matrix;
- d->m_draw_helper->queueAliasedLines(lines, 4, &item);
- } else {
- QPainterPath path;
- QRectF brect;
-
- path.addRect(rects[i]);
- if (d->m_has_cosmetic_pen) {
- brect = path.controlPointRect();
- path = d->m_matrix.map(path);
- }
-
- d->strokePath(path, brect, true);
- }
- }
- } else {
- QPainterPath path;
- QRectF brect;
-
- path.addRect(rects[i]);
- if (d->m_has_cosmetic_pen) {
- brect = path.controlPointRect();
- path = d->m_matrix.map(path);
- }
-
- if (d->m_has_brush)
- d->fillPath(path, brect);
-
- if (d->m_has_pen)
- d->strokePath(path, brect, true);
- }
- }
-}
-
-void QDirect3DPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawRects";
-#endif
- QPaintEngine::drawRects(rects, rectCount);
-}
-
-
-void QDirect3DPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- Q_D(QDirect3DPaintEngine);
-
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawTextItem";
-#endif
-// if (d->m_matrix.isScaling() || (d->m_pen_brush_style >= Qt::LinearGradientPattern
-// && d->m_pen_brush_style <= Qt::ConicalGradientPattern)) {
-// QPaintEngine::drawTextItem(p, textItem);
-// return;
-// }
-
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
- matrix.translate(p.x(), p.y());
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
- qd3d_glyph_cache()->cacheGlyphs(this, ti, glyphs, d->m_cleartype_text);
- QD3DFontTexture *font_tex = qd3d_glyph_cache()->fontTexture(ti.fontEngine);
-
- QD3DBatchItem *item = d->nextBatchItem();
- d->m_draw_helper->lockVertexBuffer();
-
- item->m_info = QD3DBatchItem::BI_TEXT
- | (d->m_current_state & ~QD3DBatchItem::BI_AA) | QD3DBatchItem::BI_TRANSFORM;
- item->m_texture = font_tex->texture;
- item->m_offset = d->m_draw_helper->index();
- item->m_matrix = d->m_matrix;
- item->m_count = 0;
- item->m_brush = d->m_pen.brush();
-
- for (int i=0; i< glyphs.size(); ++i) {
- QD3DGlyphCoord *g = qd3d_glyph_cache()->lookup(ti.fontEngine, glyphs[i]);
-
- // we don't cache glyphs with no width/height
- if (!g)
- continue;
-
- // texture coords
- qreal tex_coords[] = { g->x, g->y, g->x + g->width, g->y + g->height };
- QPointF logical_pos(qRound((positions[i].x - g->x_offset).toReal()) - 0.5f,
- qRound((positions[i].y + g->y_offset).toReal()) - 0.5f);
-
- QRectF glyph_rect(logical_pos, QSizeF(g->log_width, g->log_height));
- d->m_draw_helper->queueTextGlyph(glyph_rect, tex_coords, item, d->m_pen_color);
- }
-}
-
-void QDirect3DPaintEngine::drawTiledPixmap(const QRectF &rect, const QPixmap &pixmap, const QPointF &p)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::drawTiledPixmap";
-#endif
- QPaintEngine::drawTiledPixmap(rect, pixmap, p);
-}
-
-bool QDirect3DPaintEngine::end()
-{
- Q_D(QDirect3DPaintEngine);
-
- d->flushBatch();
-
- if (d->m_flush_on_end) {
- QPaintDevice *pdev = paintDevice();
- LPDIRECT3DSWAPCHAIN9 swapchain = swapChain(pdev);
-
-
- QWidget *w = 0;
- if (pdev->devType() == QInternal::Widget) {
- w = static_cast<QWidget *>(pdev);
- }
-
- if (w && swapchain) {
- QRect br = w->rect();
- QRect wbr = br;//.translated(-w->pos());
-
- RECT destrect;
- destrect.left = wbr.x();
- destrect.top = wbr.y();
- destrect.right = destrect.left + wbr.width();
- destrect.bottom = destrect.top + wbr.height();
-
- RECT srcrect;
- srcrect.left = br.x();// + w->x();
- srcrect.top = br.y();// + w->y();
- srcrect.right = wbr.width() + srcrect.left;
- srcrect.bottom = wbr.height() + srcrect.top;
- int devwidth = w->width();
- int devheight = w->height();
-
- if (devwidth <= srcrect.right) {
- int diff = srcrect.right - devwidth;
- srcrect.right -= diff;
- destrect.right -= diff;
- if (srcrect.right <= srcrect.left)
- return false;
- }
- if (devheight <= srcrect.bottom) {
- int diff = srcrect.bottom - devheight;
- srcrect.bottom -= diff;
- destrect.bottom -= diff;
- if (srcrect.bottom <= srcrect.top)
- return false;
- }
-
- if (FAILED(swapchain->Present(&srcrect, &destrect, w->winId(), 0, 0)))
- qWarning("QDirect3DPaintEngine: failed to present back buffer.");
- }
- }
-
-
- return true;
-}
-
-void QDirect3DPaintEngine::updateState(const QPaintEngineState &state)
-{
-#ifdef QT_DEBUG_D3D_CALLS
- qDebug() << "QDirect3DPaintEngine::updateState";
-#endif
- Q_D(QDirect3DPaintEngine);
-
- bool update_fast_pen = false;
- DirtyFlags flags = state.state();
-
- if (flags & DirtyOpacity) {
- d->m_opacity = state.opacity();
- if (d->m_opacity > 1.0f)
- d->m_opacity = 1.0f;
- if (d->m_opacity < 0.f)
- d->m_opacity = 0.f;
- uint c = (d->m_opacity * 255);
- d->m_opacity_color = D3DCOLOR_ARGB(c,c,c,c);
- flags |= (DirtyPen | DirtyBrush);
- }
-
- if (flags & DirtyCompositionMode) {
- d->m_cmode = state.compositionMode();
- }
-
- if (flags & DirtyTransform) {
- d->updateTransform(state.transform());
- update_fast_pen = true;
- }
-
- if (flags & DirtyHints) {
- if (state.renderHints() & QPainter::Antialiasing)
- d->m_current_state |= QD3DBatchItem::BI_AA;
- else
- d->m_current_state &= ~QD3DBatchItem::BI_AA;
- update_fast_pen = true;
- }
-
- if (flags & DirtyFont) {
- d->updateFont(state.font());
- }
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled() && !d->m_clipping_enabled) {
- d->m_clipping_enabled = true;
- if (d->m_has_complex_clipping)
- d->updateClipPath(painter()->clipPath(), Qt::ReplaceClip);
- else
- d->updateClipRegion(painter()->clipRegion(), Qt::ReplaceClip);
- } else if (!state.isClipEnabled() && d->m_clipping_enabled) {
- d->m_clipping_enabled = false;
- if (d->m_has_complex_clipping)
- d->updateClipPath(QPainterPath(), Qt::NoClip);
- else
- d->updateClipRegion(QRegion(), Qt::NoClip);
- }
- }
-
- if (flags & DirtyClipRegion) {
- d->updateClipRegion(state.clipRegion(), state.clipOperation());
- }
-
- if (flags & DirtyClipPath) {
- d->updateClipPath(state.clipPath(), state.clipOperation());
- }
-
- if (flags & DirtyBrushOrigin) {
- d->m_brush_origin = QTransform();
- d->m_brush_origin.translate(-state.brushOrigin().x(),
- -state.brushOrigin().y());
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyPen) {
- d->updatePen(state.pen());
- update_fast_pen = true;
- }
-
- if (flags & DirtyBrush)
- d->updateBrush(state.brush());
-
- if (update_fast_pen && d->m_has_pen) {
- if (d->m_current_state & QD3DBatchItem::BI_AA) {
- d->m_has_fast_pen = false;
- d->m_has_aa_fast_pen = ((d->m_txop <= QTransform::TxTranslate) || d->m_has_cosmetic_pen)
- && (d->m_pen_width <= 1.0f)
- && (d->m_pen.style() == Qt::SolidLine);
- } else {
- d->m_has_aa_fast_pen = false;
- d->m_has_fast_pen = ((d->m_txop <= QTransform::TxTranslate) || d->m_has_cosmetic_pen)
- && (d->m_pen.style() == Qt::SolidLine)
- && (d->m_pen.capStyle() == Qt::SquareCap);
- }
- }
-}
-
-void QDirect3DPaintEngine::cleanup()
-{
- Q_D(QDirect3DPaintEngine);
- d->cleanup();
-}
-
-void QDirect3DPaintEngine::scroll(QPaintDevice *pd, const RECT &srcrect, const RECT &destrect)
-{
- Q_D(QDirect3DPaintEngine);
- LPDIRECT3DSURFACE9 srcsurf = d->m_surface_manager.surface(pd);
- LPDIRECT3DSURFACE9 masksurf = d->m_draw_helper->freeMaskSurface();
- if (FAILED(d->m_d3d_device->StretchRect(srcsurf, &srcrect, masksurf, &srcrect, D3DTEXF_NONE)))
- qWarning("QDirect3DPaintEngine: StretchRect failed.");
- if (FAILED(d->m_d3d_device->StretchRect(masksurf, &srcrect, srcsurf, &destrect, D3DTEXF_NONE)))
- qWarning("QDirect3DPaintEngine: StretchRect failed.");
-}
-
-LPDIRECT3DSWAPCHAIN9 QDirect3DPaintEngine::swapChain(QPaintDevice *pd)
-{
- Q_D(QDirect3DPaintEngine);
-
- if (d->m_in_scene) {
- if (d->m_d3d_device == 0) {
- qWarning("QDirect3DPaintEngine: No device!");
- return false;
- }
-
- d->setRenderTechnique(QDirect3DPaintEnginePrivate::RT_NoTechnique);
- if (FAILED(d->m_d3d_device->EndScene()))
- qWarning("QDirect3DPaintEngine: failed to end scene.");
-
- d->m_in_scene = false;
- }
-
- return d->m_surface_manager.swapChain(pd);
-}
-
-void QDirect3DPaintEngine::releaseSwapChain(QPaintDevice *pd)
-{
- Q_D(QDirect3DPaintEngine);
- d->m_surface_manager.releasePaintDevice(pd);
-}
-
-HDC QDirect3DPaintEngine::getDC() const
-{
- QDirect3DPaintEnginePrivate *d = const_cast<QDirect3DPaintEnginePrivate *>(d_func());
-
- if (!d->m_dc && d->m_current_surface) {
- d->m_dcsurface = d->m_current_surface;
- if (FAILED(d->m_current_surface->GetDC(&d->m_dc)))
- qWarning() << "QDirect3DPaintEngine::getDC() failed!";
- }
-
- return d->m_dc;
-}
-
-void QDirect3DPaintEngine::setFlushOnEnd(bool flushOnEnd)
-{
- Q_D(QDirect3DPaintEngine);
-
- d->m_flush_on_end = flushOnEnd;
-}
-
-bool QDirect3DPaintEngine::hasDirect3DSupport()
-{
- Q_D(QDirect3DPaintEngine);
- return d->m_supports_d3d;
-}
-
-QT_END_NAMESPACE
-
-#include "qpaintengine_d3d.moc"
diff --git a/src/gui/painting/qpaintengine_d3d.fx b/src/gui/painting/qpaintengine_d3d.fx
deleted file mode 100644
index 1148b2a..0000000
--- a/src/gui/painting/qpaintengine_d3d.fx
+++ /dev/null
@@ -1,608 +0,0 @@
-bool g_mCosmeticPen;
-int4 g_mChannel;
-float2 g_mMaskOffset;
-int2 g_mMaskSize;
-float4x4 g_mMaskProjection;
-float4x4 g_mViewProjection;
-float4x4 g_mTransformation;
-texture g_mAAMask;
-texture g_mTexture;
-int g_mBrushMode;
-float g_mFocalDist;
-
-#define M_PI 3.14159265358979323846
-
-sampler PixmapSampler = sampler_state
-{
- texture = <g_mTexture>;
- MIPFILTER = NONE;
- MINFILTER = LINEAR;
- MAGFILTER = LINEAR;
-};
-
-sampler TextSampler = sampler_state
-{
- texture = <g_mTexture>;
- MIPFILTER = NONE;
- MINFILTER = POINT;
- MAGFILTER = POINT;
-};
-
-sampler AAMaskSampler = sampler_state
-{
- texture = <g_mAAMask>;
- AddressU = WRAP;
- AddressV = WRAP;
- AddressW = WRAP;
- MIPFILTER = NONE;
- MINFILTER = POINT;
- MAGFILTER = POINT;
-};
-
-struct VS_FULL
-{
- float4 Position : POSITION;
- float4 Diffuse : COLOR0;
- float4 TexCoords0 : TEXCOORD0;
- float4 TexCoords1 : TEXCOORD1;
-};
-
-VS_FULL TrapezoidVS( float4 Position : POSITION,
- float4 Diffuse : COLOR0,
- float4 TexCoords0 : TEXCOORD0,
- float4 TexCoords1 : TEXCOORD1)
-{
- VS_FULL Output;
-
- float a = (TexCoords1.x * Position.x) + (TexCoords1.z * (1.0 - Position.x) ); // left or right a
- float b = (TexCoords1.y * Position.x) + (TexCoords1.w * (1.0 - Position.x) ); // left or right b
- float d = 1.0 - (Position.x * 2);
-
- Position.x = (a * Position.y + b) + ( sqrt( abs(a * a) ) * d );
- //Position.x += step(abs(a), 0) * d;
- Position.x += (0.5 * d);
-
- Output.Position = mul(Position, g_mMaskProjection);
- Output.Diffuse = Diffuse;
- Output.TexCoords0 = TexCoords0;
- Output.TexCoords1 = TexCoords1;
-
- return Output;
-}
-
-struct PS_OUTPUT
-{
- float4 Color : COLOR0;
-};
-
-PS_OUTPUT TrapezoidPS(VS_FULL In, float2 pixelPos : VPOS)
-{
- PS_OUTPUT Out;
-
- float top = max(pixelPos.y - 0.5, In.TexCoords0.x);
- float bottom = min(pixelPos.y + 0.5, In.TexCoords0.y);
-
- float area = bottom - top;
-
- float left = pixelPos.x - 0.5;
- float right = pixelPos.x + 0.5;
-
- // use line equations to compute intersections of left/right edges with top/bottom of truncated pixel
- // vecX: x = (left, top), y = (left, bottom), z = (right, top), w = (right, bottom)
- float4 vecX = In.TexCoords1.xxzz * float2(top, bottom).xyxy + In.TexCoords1.yyww;
-
- float2 invA = In.TexCoords0.zw;
-
- // transform right line to left to be able to use same calculations for both
- vecX.zw = 2 * pixelPos.x - vecX.zw;
-
- float2 topX = float2(vecX.x, vecX.z);
- float2 bottomX = float2(vecX.y, vecX.w);
-
- // transform lines such that top intersection is to the right of bottom intersection
- float2 topXTemp = max(topX, bottomX);
- float2 bottomXTemp = min(topX, bottomX);
-
- // make sure line slope reflects mirrored lines
- invA = lerp(invA, -invA, step(topX, bottomX));
-
- float2 vecLeftRight = float2(left, right);
-
- // compute the intersections of the lines with the left and right edges of the pixel
- // intersectY: x = (left_line, left), y = (left_line, right), z = (right_line, left), w = (right_line, right)
- float4 intersectY = top + (vecLeftRight.xyxy - topXTemp.xxyy) * invA.xxyy;
-
- float2 temp = lerp(area - 0.5 * (right - bottomXTemp) * (bottom - intersectY.yw), // left < bottom < right < top
- (0.5 * (topXTemp + bottomXTemp) - left) * area, // left < bottom < top < right
- step(topXTemp, right));
-
- float2 excluded = 0.5 * (intersectY.xz - top) * (topXTemp - left); // bottom < left < top < right
-
- excluded = lerp(0.5 * (intersectY.yw + intersectY.xz) - top, // bottom < left < right < top
- excluded, step(topXTemp, right));
-
- excluded = lerp(temp, // left < bottom < right (see calculation of temp)
- excluded, step(bottomXTemp, left));
-
- excluded = lerp(float2(area, area), // right < bottom < top
- excluded, step(bottomXTemp, right));
-
- excluded *= step(left, topXTemp);
-
- float result = (area - excluded.x - excluded.y) * step(top, bottom);
- Out.Color.r = result * g_mChannel[0];
- Out.Color.g = result * g_mChannel[1];
- Out.Color.b = result * g_mChannel[2];
- Out.Color.a = result * g_mChannel[3];
-
- return Out;
-}
-
-VS_FULL ViewProjectionVS( float4 Position : POSITION,
- float4 Diffuse : COLOR0,
- float4 TexCoords0 : TEXCOORD0,
- float4 TexCoords1 : TEXCOORD1)
-{
- VS_FULL Output;
-
- Output.Position = mul(Position, g_mTransformation);
- Output.Position = mul(Output.Position, g_mViewProjection);
- Output.Diffuse = Diffuse;
- Output.TexCoords0 = TexCoords0;
- Output.TexCoords1 = TexCoords1;
-
- return Output;
-}
-
-PS_OUTPUT DirectMaskPS(VS_FULL In, float2 pixelPos : VPOS)
-{
- PS_OUTPUT Out;
- Out.Color = In.Diffuse;
-
- float2 maskcoords = ( (pixelPos + g_mMaskOffset) - 0.5 ) / g_mMaskSize;
- float2 clipcoords = (pixelPos - 0.5) / g_mMaskSize;
-
- float4 c = tex2D(AAMaskSampler, maskcoords.xy) * Out.Color.a;
- Out.Color.a = c.r * g_mChannel[0];
- Out.Color.a += c.g * g_mChannel[1];
- Out.Color.a += c.b * g_mChannel[2];
- Out.Color.a += c.a * g_mChannel[3];
-
- return Out;
-}
-
-PS_OUTPUT MaskPS(VS_FULL In, float2 pixelPos : VPOS)
-{
- PS_OUTPUT Out;
-
- if (g_mBrushMode == 1) {
- float x = In.TexCoords0.x;
- float y = In.TexCoords0.y;
- x = x - int(x);
- y = y - int(y);
- Out.Color = tex2D(PixmapSampler, float2(x, y));
- Out.Color.a = Out.Color.a * In.Diffuse.a;
- } else if (g_mBrushMode == 2) {
- Out.Color = tex1D(PixmapSampler, In.TexCoords0.x);
- } else if (g_mBrushMode == 3) {
- float t = atan2(In.TexCoords0.y, -In.TexCoords0.x) / (2 * M_PI);
- Out.Color = tex1D(PixmapSampler, t + 0.5);
- } else if (g_mBrushMode == 4) {
- float2 tc = float2(In.TexCoords0.x, abs(In.TexCoords0.y));
- float a = (tc.x - g_mFocalDist) / tc.y;
- float b = g_mFocalDist;
-
- float A = 1 + (a * a);
- float B = 2.0 * a * b;
- float C = (b * b) - 1;
-
- float y = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A);
- Out.Color = tex1D(PixmapSampler, (tc.y / y) );
- } else if (g_mBrushMode == 5) {
- Out.Color = tex2D(PixmapSampler, In.TexCoords0.xy);
- Out.Color = Out.Color * In.Diffuse;
- } else {
- Out.Color = In.Diffuse;
- }
-
- float2 maskcoords = ( (pixelPos + g_mMaskOffset) - 0.5 ) / g_mMaskSize;
-
- float4 c = tex2D(AAMaskSampler, maskcoords.xy) * Out.Color.a;
- Out.Color.a = c.r * g_mChannel[0];
- Out.Color.a += c.g * g_mChannel[1];
- Out.Color.a += c.b * g_mChannel[2];
- Out.Color.a += c.a * g_mChannel[3];
-
- return Out;
-}
-
-struct VS_NORMAL
-{
- float4 Position : POSITION;
- float4 Diffuse : COLOR0;
- float4 TexCoords : TEXCOORD0;
-};
-
-VS_NORMAL MaskProjectionVS(VS_NORMAL In)
-{
- VS_NORMAL Output;
-
- Output.Position = mul(In.Position, g_mMaskProjection);
- Output.Diffuse = In.Diffuse;
- Output.TexCoords = In.TexCoords;
-
- return Output;
-}
-
-float4 DirectSimplePS(float4 Color : COLOR0) : COLOR0
-{
- return Color;
-}
-
-float4 SimplePS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0
-{
- if (g_mBrushMode == 1) {
- float opacity = Color.a;
- float x = TexCoords.x;
- float y = TexCoords.y;
- x = x - int(x);
- y = y - int(y);
- Color = tex2D(PixmapSampler, float2(x, y));
- Color.a = Color.a * opacity;
- } else if (g_mBrushMode == 2) {
- Color = tex1D(PixmapSampler, TexCoords.x);
- } else if (g_mBrushMode == 3) {
- float t = atan2(TexCoords.y, -TexCoords.x) / (2 * M_PI);
- Color = tex1D(PixmapSampler, t + 0.5);
- } else if (g_mBrushMode == 4) {
- float2 tc = float2(TexCoords.x, abs(TexCoords.y));
- float a = (tc.x - g_mFocalDist) / tc.y;
- float b = g_mFocalDist;
-
- float A = 1 + (a * a);
- float B = 2.0 * a * b;
- float C = (b * b) - 1;
-
- float y = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A);
- Color = tex1D(PixmapSampler, (tc.y / y) );
- } else if (g_mBrushMode == 5) {
- Color = tex2D(PixmapSampler, TexCoords.xy) * Color;
- }
-
- return Color;
-}
-
-float4 TextPS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0
-{
- Color.a *= tex2D(TextSampler, TexCoords.xy).a;
- return Color;
-}
-
-float4 ClearTypePS(float4 Color : COLOR0, float4 TexCoords : TEXCOORD0) : COLOR0
-{
-// if (g_mUsePixmap) {
-// float4 MaskColor = tex2D(PixmapSampler, TexCoords.xy);
-// Color = float4(1.0, 0.0, 0.0, 1.0);
-// Color.a = (1 - MaskColor.a) + MaskColor.a * Color.a;
-// Color.r = (1.0 - MaskColor.r) + (MaskColor.r * Color.r);
-// Color.g = (1.0 - MaskColor.g) + (MaskColor.g * Color.g);
-// Color.b = (1.0 - MaskColor.b) + (MaskColor.b * Color.b);
-// Color = MaskColor;
- return tex2D(PixmapSampler, TexCoords.xy);
-}
-
-VS_NORMAL NoTxAliasedVS(VS_NORMAL In)
-{
- VS_NORMAL Output;
-
- Output.Position = mul(In.Position, g_mViewProjection);
- Output.Diffuse = In.Diffuse;
- Output.TexCoords = In.TexCoords;
-
- return Output;
-}
-
-VS_NORMAL AliasedVS(VS_NORMAL In)
-{
- VS_NORMAL Output;
-
- Output.Position = mul(In.Position, g_mTransformation);
- Output.Position = mul(Output.Position, g_mViewProjection);
- Output.Diffuse = In.Diffuse;
- Output.TexCoords = In.TexCoords;
-
- return Output;
-}
-
-VS_NORMAL AliasedLinesVS(VS_NORMAL In)
-{
- VS_NORMAL Output;
-
- float4 start = float4(In.Position.x, In.Position.y, 0.5, In.Position.w);
- float4 end = float4(In.TexCoords.z, In.TexCoords.w, 0.5, In.Position.w);
- if (g_mCosmeticPen) {
- start = mul(start, g_mTransformation);
- end = mul(end, g_mTransformation);
- }
-
- float2 line_vec = end - start;
- float2 vec = normalize(line_vec);
- float2 norm = float2(-vec.y, vec.x);
-
- float pen_width = In.Position.z;
- norm = norm * pen_width * 0.5;
- vec = vec * pen_width * 0.5;
-
- Output.Position.w = In.Position.w;
- Output.Position.x = start.x + (vec.x * In.TexCoords.x);
- Output.Position.x = Output.Position.x + (norm.x * In.TexCoords.y);
- Output.Position.x = Output.Position.x + (line_vec.x * step(0, In.TexCoords.x));
- Output.Position.y = start.y + (vec.y * In.TexCoords.x);
- Output.Position.y = Output.Position.y + (norm.y * In.TexCoords.y);
- Output.Position.y = Output.Position.y + (line_vec.y * step(0, In.TexCoords.x));
- Output.Position.z = 0.5;
-
- if (!g_mCosmeticPen) {
- Output.Position = mul(Output.Position, g_mTransformation);
- }
- Output.Position = mul(Output.Position, g_mViewProjection);
-
- Output.Diffuse = In.Diffuse;
- Output.TexCoords = In.TexCoords;
-
- return Output;
-}
-
-
-technique Antialiased
-{
- pass PASS_AA_CREATEMASK
- {
- StencilEnable = False;
- ZWriteEnable = False;
- ColorWriteEnable = 0x0f;
- ZEnable = False;
-
- SrcBlend = One;
- DestBlend = One;
-
- VertexShader = compile vs_3_0 TrapezoidVS();
- PixelShader = compile ps_3_0 TrapezoidPS();
- }
-
- pass PASS_AA_DRAW
- {
- StencilEnable = False;
- ZFunc = Greater;
- ZWriteEnable = False;
- ZEnable = True;
- ColorWriteEnable = 0x0f;
-
- VertexShader = compile vs_3_0 ViewProjectionVS();
- PixelShader = compile ps_3_0 MaskPS();
- }
-
- pass PASS_AA_DRAW_DIRECT
- {
- StencilEnable = False;
- ZFunc = Greater;
- ZEnable = True;
- ZWriteEnable = False;
- ColorWriteEnable = 0x0f;
-
- VertexShader = compile vs_3_0 ViewProjectionVS();
- PixelShader = compile ps_3_0 DirectMaskPS();
- }
-}
-
-technique Aliased
-{
- pass PASS_STENCIL_ODDEVEN
- {
- TwoSidedStencilMode = False;
- StencilEnable = True;
- StencilPass = Invert;
- StencilFunc = Always;
- ColorWriteEnable = 0;
-
- ZEnable = False;
- ZWriteEnable = False;
-
- VertexShader = compile vs_1_1 NoTxAliasedVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_STENCIL_WINDING
- {
- TwoSidedStencilMode = True;
- StencilEnable = True;
- StencilRef = 0;
- StencilMask = 0xFFFFFFFF;
-
- CCW_StencilPass = Incr;
- CCW_StencilFunc = Always;
-
- StencilPass = Decr;
- StencilFunc = Always;
-
- ColorWriteEnable = 0;
-
- ZEnable = False;
- ZWriteEnable = False;
-
- VertexShader = compile vs_1_1 NoTxAliasedVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_STENCIL_DRAW
- {
- TwoSidedStencilMode = False;
- StencilEnable = True;
- StencilFunc = NotEqual;
- StencilMask = 0xFFFFFFFF;
- StencilRef = 0;
- StencilPass = Zero;
- StencilFail = Zero;
- StencilZFail = Zero;
-
- ColorWriteEnable = 0x0f;
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- VertexShader = compile vs_1_1 AliasedVS();
- PixelShader = compile ps_2_0 SimplePS();
- }
-
- pass PASS_STENCIL_DRAW_DIRECT
- {
- TwoSidedStencilMode = False;
- StencilEnable = True;
- StencilFunc = NotEqual;
- StencilMask = 0xFFFFFFFF;
- StencilRef = 0;
- StencilPass = Zero;
- StencilFail = Zero;
- StencilZFail = Zero;
-
- ColorWriteEnable = 0x0f;
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- VertexShader = compile vs_1_1 AliasedVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_STENCIL_CLIP
- {
- TwoSidedStencilMode = False;
- StencilEnable = True;
- StencilFunc = NotEqual;
- StencilMask = 0xFFFFFFFF;
- StencilRef = 0;
- StencilPass = Zero;
- StencilFail = Zero;
- StencilZFail = Zero;
-
- ColorWriteEnable = 0;
- ZEnable = True;
- ZWriteEnable = True;
- ZFunc = Always;
-
- VertexShader = compile vs_1_1 NoTxAliasedVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_STENCIL_NOSTENCILCHECK
- {
- StencilEnable = False;
-
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- ColorWriteEnable = 0x0f;
-
- SrcBlend = SrcAlpha;
- DestBlend = InvSrcAlpha;
-
- VertexShader = compile vs_1_1 AliasedVS();
- PixelShader = compile ps_2_0 SimplePS();
- }
-
- pass PASS_STENCIL_NOSTENCILCHECK_DIRECT
- {
- StencilEnable = False;
-
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- ColorWriteEnable = 0x0f;
-
- SrcBlend = SrcAlpha;
- DestBlend = InvSrcAlpha;
-
- VertexShader = compile vs_1_1 AliasedVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_TEXT
- {
- StencilEnable = False;
-
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- ColorWriteEnable = 0x0f;
-
- SrcBlend = SrcAlpha;
- DestBlend = InvSrcAlpha;
-
- VertexShader = compile vs_1_1 AliasedVS();
- PixelShader = compile ps_2_0 TextPS();
- }
-
- pass PASS_CLEARTYPE_TEXT
- {
- StencilEnable = False;
-
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- ColorWriteEnable = 0x0f;
-
-// SrcBlend = SrcAlpha;
-// DestBlend = InvSrcAlpha;
-
-// SrcBlend = DestColor;
-// DestBlend = Zero;
- SrcBlend = BlendFactor;
- DestBlend = InvSrcColor;
-
-// SrcBlend = Zero;
-// DestBlend = SrcColor;
-
-// SrcBlend = One;
-// DestBlend = Zero;
-
- VertexShader = compile vs_3_0 AliasedVS();
- PixelShader = compile ps_3_0 ClearTypePS();
- }
-
- pass PASS_ALIASED_LINES
- {
- TwoSidedStencilMode = False;
- StencilEnable = True;
- StencilPass = Invert;
- StencilFunc = Always;
- ColorWriteEnable = 0;
-
- ZEnable = False;
- ZWriteEnable = False;
-
- VertexShader = compile vs_1_1 AliasedLinesVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-
- pass PASS_ALIASED_LINES_DIRECT
- {
- StencilEnable = False;
-
- ZEnable = True;
- ZWriteEnable = False;
- ZFunc = Greater;
-
- ColorWriteEnable = 0x0f;
-
- SrcBlend = SrcAlpha;
- DestBlend = InvSrcAlpha;
-
- VertexShader = compile vs_1_1 AliasedLinesVS();
- PixelShader = compile ps_2_0 DirectSimplePS();
- }
-}
-
diff --git a/src/gui/painting/qpaintengine_d3d.qrc b/src/gui/painting/qpaintengine_d3d.qrc
deleted file mode 100644
index c106f2b..0000000
--- a/src/gui/painting/qpaintengine_d3d.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>qpaintengine_d3d.fx</file>
-</qresource>
-</RCC>
diff --git a/src/gui/painting/qpaintengine_d3d_p.h b/src/gui/painting/qpaintengine_d3d_p.h
deleted file mode 100644
index 8fa5cf6..0000000
--- a/src/gui/painting/qpaintengine_d3d_p.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_D3D_P_H
-#define QPAINTENGINE_D3D_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "QtGui/qpaintengine.h"
-#include <d3d9.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDirect3DPaintEnginePrivate;
-class QDirect3DPaintEngine : public QPaintEngine
-{
- Q_DECLARE_PRIVATE(QDirect3DPaintEngine)
-public:
- QDirect3DPaintEngine();
- ~QDirect3DPaintEngine();
- bool begin(QPaintDevice *device);
-
- void drawEllipse(const QRectF &rect);
- void drawEllipse(const QRect &rect);
-
- void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
-
- void drawLines(const QLineF *lines, int lineCount);
- void drawLines(const QLine *lines, int lineCount);
-
- void drawPath(const QPainterPath &path);
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
-
- void drawPoints(const QPointF *points, int pointCount);
- void drawPoints(const QPoint *points, int pointCount);
-
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
-
- void drawRects(const QRectF *rects, int rectCount);
- void drawRects(const QRect * rects, int rectCount);
-
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
-
- void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
-
- bool end();
-
- Type type() const { return Direct3D; }
- void updateState(const QPaintEngineState &state);
-
- void cleanup();
-
- HDC getDC() const;
- void setFlushOnEnd(bool flushOnEnd);
- bool hasDirect3DSupport();
-
-public:
- void scroll(QPaintDevice *pd, const RECT &srcrect, const RECT &destrect);
- LPDIRECT3DSWAPCHAIN9 swapChain(QPaintDevice *pd);
- void releaseSwapChain(QPaintDevice *pd);
-
-private:
- Q_DISABLE_COPY(QDirect3DPaintEngine)
- friend class QPixmap;
- friend class QD3DGlyphCache;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h
index eeba7ec..0b5e175 100644
--- a/src/gui/painting/qpaintengine_p.h
+++ b/src/gui/painting/qpaintengine_p.h
@@ -83,10 +83,12 @@ public:
if (systemClip.isEmpty())
return;
- if (systemTransform.type() <= QTransform::TxTranslate)
- systemClip.translate(qRound(systemTransform.dx()), qRound(systemTransform.dy()));
- else
- systemClip = systemTransform.map(systemClip);
+ if (hasSystemTransform) {
+ if (systemTransform.type() <= QTransform::TxTranslate)
+ systemClip.translate(qRound(systemTransform.dx()), qRound(systemTransform.dy()));
+ else
+ systemClip = systemTransform.map(systemClip);
+ }
// Make sure we're inside the viewport.
if (hasSystemViewport) {
@@ -101,7 +103,7 @@ public:
inline void setSystemTransform(const QTransform &xform)
{
systemTransform = xform;
- if ((hasSystemTransform = !xform.isIdentity()))
+ if ((hasSystemTransform = !xform.isIdentity()) || hasSystemViewport)
transformSystemClip();
systemStateChanged();
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index d2b1ed7..295abc5 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -4409,6 +4409,9 @@ void QClipData::fixup()
*/
void QClipData::setClipRect(const QRect &rect)
{
+ if (rect == clipRect)
+ return;
+
// qDebug() << "setClipRect" << clipSpanHeight << count << allocated << rect;
hasRectClip = true;
clipRect = rect;
@@ -4418,6 +4421,11 @@ void QClipData::setClipRect(const QRect &rect)
ymin = qMin(rect.y(), clipSpanHeight);
ymax = qMin(rect.y() + rect.height(), clipSpanHeight);
+ if (m_spans) {
+ delete m_spans;
+ m_spans = 0;
+ }
+
// qDebug() << xmin << xmax << ymin << ymax;
}
@@ -4441,6 +4449,12 @@ void QClipData::setClipRegion(const QRegion &region)
ymin = rect.y();
ymax = rect.y() + rect.height();
}
+
+ if (m_spans) {
+ delete m_spans;
+ m_spans = 0;
+ }
+
}
/*!
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index caed293..d9c7937 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5167,6 +5167,9 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
Q_D(QPainter);
+ if (!d->engine)
+ return;
+
#ifndef QT_NO_DEBUG
qt_painter_thread_test(d->device->devType(), "drawPixmap()");
#endif
@@ -5176,9 +5179,6 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
}
- if (!d->engine)
- return;
-
qreal x = p.x();
qreal y = p.y();
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index c8674b7..7601beb 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -1532,7 +1532,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
value = rect;
} else {
value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0)
- .mapRect(d->fullPage ? d->devPaperRect : d->devPageRect);
+ .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect);
}
break;
diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp
index 4f3e71c..5161e32 100644
--- a/src/gui/painting/qprinter.cpp
+++ b/src/gui/painting/qprinter.cpp
@@ -834,11 +834,15 @@ void QPrinter::setPrinterName(const QString &name)
#endif
QList<QPrinterInfo> prnList = QPrinterInfo::availablePrinters();
- d->validPrinter = false;
- for (int i = 0; i < prnList.size(); ++i) {
- if (prnList[i].printerName() == name) {
- d->validPrinter = true;
- break;
+ if (name.isEmpty()) {
+ d->validPrinter = d->outputFormat == QPrinter::PdfFormat || d->outputFormat == QPrinter::PostScriptFormat;
+ } else {
+ d->validPrinter = false;
+ for (int i = 0; i < prnList.size(); ++i) {
+ if (prnList[i].printerName() == name) {
+ d->validPrinter = true;
+ break;
+ }
}
}
diff --git a/src/gui/painting/qwindowsurface_d3d.cpp b/src/gui/painting/qwindowsurface_d3d.cpp
deleted file mode 100644
index 2b7f633..0000000
--- a/src/gui/painting/qwindowsurface_d3d.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//#define D3D_DEBUG_BACKBUFFER
-
-#include <QtGui/QPaintDevice>
-#include <QtGui/QWidget>
-#include "qdebug.h"
-
-#include "qpaintengine_d3d_p.h"
-#include "qwindowsurface_d3d_p.h"
-#include "private/qwidget_p.h"
-#include "private/qbackingstore_p.h"
-
-#include <d3d9.h>
-
-QT_BEGIN_NAMESPACE
-
-extern QDirect3DPaintEngine *qt_d3dEngine();
-
-struct QD3DWindowSurfacePrivate
-{
- QSize m_lastSize;
- QWidget *m_widget;
-};
-
-QD3DWindowSurface::QD3DWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new QD3DWindowSurfacePrivate)
-{
- Q_ASSERT(window->isTopLevel());
- d_ptr->m_widget = window;
-}
-
-
-QD3DWindowSurface::~QD3DWindowSurface()
-{
- delete d_ptr;
-}
-
-QPaintDevice *QD3DWindowSurface::paintDevice()
-{
- return d_ptr->m_widget;
-}
-
-
-void QD3DWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
-
- QDirect3DPaintEngine *engine = qt_d3dEngine();
- LPDIRECT3DSWAPCHAIN9 swapchain = engine->swapChain(d_ptr->m_widget);
-
- if (swapchain) {
- QRect br = rgn.boundingRect();
- QRect wbr = br.translated(-wOffset);
-
- RECT destrect;
- destrect.left = wbr.x();
- destrect.top = wbr.y();
- destrect.right = destrect.left + wbr.width();
- destrect.bottom = destrect.top + wbr.height();
-
- RECT srcrect;
- srcrect.left = br.x() + offset.x();
- srcrect.top = br.y() + offset.y();
- srcrect.right = wbr.width() + srcrect.left;
- srcrect.bottom = wbr.height() + srcrect.top;
- int devwidth = d_ptr->m_lastSize.width();
- int devheight = d_ptr->m_lastSize.height();
-
- if (devwidth <= srcrect.right) {
- int diff = srcrect.right - devwidth;
- srcrect.right -= diff;
- destrect.right -= diff;
- if (srcrect.right <= srcrect.left)
- return;
- }
- if (devheight <= srcrect.bottom) {
- int diff = srcrect.bottom - devheight;
- srcrect.bottom -= diff;
- destrect.bottom -= diff;
- if (srcrect.bottom <= srcrect.top)
- return;
- }
-
- if (FAILED(swapchain->Present(&srcrect, &destrect, widget->winId(), 0, 0)))
- qWarning("QDirect3DPaintEngine: failed to present back buffer.");
-
-#ifdef D3D_DEBUG_BACKBUFFER
- qDebug() << widget << srcrect.left << srcrect.top << wbr.width() << wbr.height() << "Dest: " << destrect.left << destrect.top;
- IDirect3DSurface9 *surface;
- swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &surface);
- QString filename("C:\\test.bmp");
- D3DXSaveSurfaceToFile(filename.utf16(), D3DXIFF_BMP, surface, 0, 0);
- surface->Release();
-#endif
- }
-}
-
-void QD3DWindowSurface::setGeometry(const QRect &rect)
-{
- if (rect.isEmpty())
- qt_d3dEngine()->releaseSwapChain(d_ptr->m_widget);
-
- d_ptr->m_lastSize = rect.size();
- QWindowSurface::setGeometry(rect);
-}
-
-
-bool QD3DWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- QDirect3DPaintEngine *engine = qt_d3dEngine();
- QRect rect = area.boundingRect();
-
- RECT destrect;
- destrect.left = rect.x()+dx;
- destrect.top = rect.y()+dy;
- destrect.right = rect.width() + destrect.left;
- destrect.bottom = rect.height() + destrect.top;
-
- RECT srcrect;
- srcrect.left = rect.x();
- srcrect.top = rect.y();
- srcrect.right = rect.width() + srcrect.left;
- srcrect.bottom = rect.height() + srcrect.top;
-
- engine->scroll(d_ptr->m_widget, srcrect, destrect);
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qwindowsurface_d3d_p.h b/src/gui/painting/qwindowsurface_d3d_p.h
deleted file mode 100644
index 9cdfe29..0000000
--- a/src/gui/painting/qwindowsurface_d3d_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** 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.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_D3D_P_H
-#define QWINDOWSURFACE_D3D_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include "private/qwindowsurface_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QWidget;
-struct QD3DWindowSurfacePrivate;
-
-class QD3DWindowSurface : public QWindowSurface
-{
-public:
- QD3DWindowSurface(QWidget *widget);
- ~QD3DWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
-
-private:
- QD3DWindowSurfacePrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_D3D_P_H
diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp
index acb8437..0842ec7 100644
--- a/src/gui/styles/gtksymbols.cpp
+++ b/src/gui/styles/gtksymbols.cpp
@@ -746,9 +746,9 @@ static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
foreach (const QString &rawfilter, filters) {
GtkFileFilter *gtkFilter = QGtk::gtk_file_filter_new ();
QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
- QGtk::gtk_file_filter_set_name(gtkFilter, qPrintable(name));
-
QStringList extensions = extract_filter(rawfilter);
+ QGtk::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name));
+
foreach (const QString &fileExtension, extensions) {
QGtk::gtk_file_filter_add_pattern (gtkFilter, qPrintable(fileExtension));
}
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index be80d37..f8ae1a6 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -2019,7 +2019,9 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
: QIcon::Disabled);
QPixmap tabIcon = tabV2.icon.pixmap(iconSize,
(tabV2.state & State_Enabled) ? QIcon::Normal
- : QIcon::Disabled);
+ : QIcon::Disabled,
+ (tabV2.state & State_Selected) ? QIcon::On
+ : QIcon::Off);
int offset = 6;
int left = opt->rect.left();
diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp
index b7fa575..ca71da2 100644
--- a/src/gui/styles/qgtkstyle.cpp
+++ b/src/gui/styles/qgtkstyle.cpp
@@ -951,14 +951,15 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element,
"interior-focus", &interior_focus,
"focus-line-width", &focus_line_width, NULL);
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=405421 for info about this hack
+ g_object_set_data(G_OBJECT(gtkEntry), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
+
if (!interior_focus && option->state & State_HasFocus)
rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width);
-
gtkPainter.paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ?
GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
GTK_SHADOW_IN, gtkEntry->style,
option->state & State_HasFocus ? QLS("focus") : QString());
-
if (!interior_focus && option->state & State_HasFocus)
gtkPainter.paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ?
GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE,
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 5d08c58..e32c5e2 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -2649,6 +2649,9 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
case PM_MenuHMargin:
ret = 0;
break;
+ case PM_ToolBarFrameWidth:
+ ret = 0;
+ break;
default:
ret = QWindowsStyle::pixelMetric(metric, opt, widget);
break;
@@ -3679,8 +3682,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
needText = true;
if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
- pr.setHeight(pixmap.size().height() + 6);
- cr.adjust(0, pr.bottom(), 0, -3);
+ pr.setHeight(pixmap.size().height());
+ cr.adjust(0, pr.bottom() + 1, 0, 1);
alignment |= Qt::AlignCenter;
} else {
pr.setWidth(pixmap.width() + 8);
@@ -3688,7 +3691,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
alignment |= Qt::AlignLeft | Qt::AlignVCenter;
}
}
- if (down) {
+ if (opt->state & State_Sunken) {
pr.translate(shiftX, shiftY);
pixmap = darkenPixmap(pixmap);
}
@@ -3718,7 +3721,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
}
drawItemText(p, cr, alignment, pal,
tb->state & State_Enabled, tb->text, role);
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 && down) {
+ if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 &&
+ (tb->state & State_Sunken)) {
// Draw a "drop shadow" in earlier versions.
drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment,
tb->palette, tb->state & State_Enabled, tb->text);
@@ -4544,9 +4548,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
case CE_ToolBar: {
// For unified tool bars, draw nothing.
if (w) {
- if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window()))
+ if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
if (mainWindow->unifiedTitleAndToolBarOnMac())
break;
+ }
}
// draw background gradient
@@ -5270,6 +5275,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
if (const QStyleOptionToolButton *tb
= qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
+// p->fillRect(tb->rect, QColor(155, 0, 155, 155));
if (tb->subControls & SC_ToolButtonMenu) {
QStyleOption arrowOpt(0);
arrowOpt.rect = subControlRect(cc, tb, SC_ToolButtonMenu, widget);
@@ -5282,16 +5288,22 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
drawToolbarButtonArrow(tb->rect, tds, cg);
}
if (tb->state & State_On) {
- QPen oldPen = p->pen();
- p->setPen(QColor(0, 0, 0, 0x3a));
- p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
- p->drawLine(tb->rect.left() + 1, tb->rect.top(),
- tb->rect.right() - 1, tb->rect.top());
- p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
- tb->rect.right() - 1, tb->rect.bottom());
- p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
- p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
- p->setPen(oldPen);
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ static QPixmap pm(QLatin1String(":/trolltech/mac/style/images/leopard-unified-toolbar-on.png"));
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ QStyleHelper::drawBorderPixmap(pm, p, tb->rect, 2, 2, 2, 2);
+ } else {
+ QPen oldPen = p->pen();
+ p->setPen(QColor(0, 0, 0, 0x3a));
+ p->fillRect(tb->rect.adjusted(1, 1, -1, -1), QColor(0, 0, 0, 0x12));
+ p->drawLine(tb->rect.left() + 1, tb->rect.top(),
+ tb->rect.right() - 1, tb->rect.top());
+ p->drawLine(tb->rect.left() + 1, tb->rect.bottom(),
+ tb->rect.right() - 1, tb->rect.bottom());
+ p->drawLine(tb->rect.topLeft(), tb->rect.bottomLeft());
+ p->drawLine(tb->rect.topRight(), tb->rect.bottomRight());
+ p->setPen(oldPen);
+ }
}
drawControl(CE_ToolButtonLabel, opt, p, widget);
} else {
@@ -6009,6 +6021,14 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
}
break;
case CT_ToolButton:
+ if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) {
+ sz.rwidth() += 4;
+ if (sz.height() <= 32) {
+ // Workaround strange HIToolBar bug when getting constraints.
+ sz.rheight() += 1;
+ }
+ return sz;
+ }
sz.rwidth() += 10;
sz.rheight() += 10;
return sz;
diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp
index 3320970..69f8cd2 100644
--- a/src/gui/styles/qstylehelper.cpp
+++ b/src/gui/styles/qstylehelper.cpp
@@ -50,9 +50,10 @@
QT_BEGIN_NAMESPACE
-const bool QStyleHelper::UsePixmapCache = true;
+namespace QStyleHelper {
+const bool UsePixmapCache = true;
-QString QStyleHelper::uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
+QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size)
{
QString tmp;
const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option);
@@ -74,7 +75,7 @@ QString QStyleHelper::uniqueName(const QString &key, const QStyleOption *option,
#ifndef QT_NO_DIAL
-int QStyleHelper::calcBigLineSize(int radius)
+int calcBigLineSize(int radius)
{
int bigLineSize = radius / 6;
if (bigLineSize < 4)
@@ -107,7 +108,7 @@ static QPointF calcRadialPos(const QStyleOptionSlider *dial, qreal offset)
return pos;
}
-qreal QStyleHelper::angle(const QPointF &p1, const QPointF &p2)
+qreal angle(const QPointF &p1, const QPointF &p2)
{
static const qreal rad_factor = 180 / Q_PI;
qreal _angle = 0;
@@ -139,7 +140,7 @@ qreal QStyleHelper::angle(const QPointF &p1, const QPointF &p2)
return _angle;
}
-QPolygonF QStyleHelper::calcLines(const QStyleOptionSlider *dial)
+QPolygonF calcLines(const QStyleOptionSlider *dial)
{
QPolygonF poly;
int width = dial->rect.width();
@@ -182,7 +183,7 @@ QPolygonF QStyleHelper::calcLines(const QStyleOptionSlider *dial)
// This will draw a nice and shiny QDial for us. We don't want
// all the shinyness in QWindowsStyle, hence we place it here
-void QStyleHelper::drawDial(const QStyleOptionSlider *option, QPainter *painter)
+void drawDial(const QStyleOptionSlider *option, QPainter *painter)
{
QPalette pal = option->palette;
QColor buttonColor = pal.button().color();
@@ -292,4 +293,61 @@ void QStyleHelper::drawDial(const QStyleOptionSlider *option, QPainter *painter)
}
#endif //QT_NO_DIAL
+void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
+ int left, int top, int right,
+ int bottom)
+{
+ QSize size = pixmap.size();
+ //painter->setRenderHint(QPainter::SmoothPixmapTransform);
+
+ //top
+ if (top > 0) {
+ painter->drawPixmap(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), pixmap,
+ QRect(left, 0, size.width() -right - left, top));
+
+ //top-left
+ if(left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top(), left, top), pixmap,
+ QRect(0, 0, left, top));
+
+ //top-right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top(), right, top), pixmap,
+ QRect(size.width() - right, 0, right, top));
+ }
+
+ //left
+ if (left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), pixmap,
+ QRect(0, top, left, size.height() - bottom - top));
+
+ //center
+ painter->drawPixmap(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left,
+ rect.height() - bottom - top), pixmap,
+ QRect(left, top, size.width() -right -left,
+ size.height() - bottom - top));
+ //right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), pixmap,
+ QRect(size.width() - right, top, right, size.height() - bottom - top));
+
+ //bottom
+ if (bottom > 0) {
+ painter->drawPixmap(QRect(rect.left() +left, rect.top() + rect.height() - bottom,
+ rect.width() - right - left, bottom), pixmap,
+ QRect(left, size.height() - bottom,
+ size.width() - right - left, bottom));
+ //bottom-left
+ if (left > 0)
+ painter->drawPixmap(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), pixmap,
+ QRect(0, size.height() - bottom, left, bottom));
+
+ //bottom-right
+ if (right > 0)
+ painter->drawPixmap(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), pixmap,
+ QRect(size.width() - right, size.height() - bottom, right, bottom));
+
+ }
+}
+}
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstylehelper_p.h b/src/gui/styles/qstylehelper_p.h
index d9b2e28..711bd2d 100644
--- a/src/gui/styles/qstylehelper_p.h
+++ b/src/gui/styles/qstylehelper_p.h
@@ -19,6 +19,7 @@
QT_BEGIN_NAMESPACE
class QPainter;
+class QPixmap;
class QStyleOptionSlider;
class QStyleOption;
@@ -32,6 +33,9 @@ namespace QStyleHelper
int calcBigLineSize(int radius);
void drawDial(const QStyleOptionSlider *dial, QPainter *painter);
#endif //QT_NO_DIAL
+ void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rect,
+ int left = 0, int top = 0, int right = 0,
+ int bottom = 0);
}
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 49ac57a..f480008 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -2876,12 +2876,6 @@ void QStyleSheetStyle::polish(QWidget *w)
QRenderRule rule = renderRule(w, PseudoElement_None, PseudoClass_Any);
if (rule.hasDrawable() || rule.hasBox()) {
if (w->metaObject() == &QWidget::staticMetaObject
-#ifndef QT_NO_MENUBAR
- || qobject_cast<QMenuBar *>(w)
-#endif
-#ifndef QT_NO_MENU
- || qobject_cast<QMenu *>(w)
-#endif
#ifndef QT_NO_ITEMVIEWS
|| qobject_cast<QHeaderView *>(w)
#endif
@@ -4164,9 +4158,8 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
rule.configurePalette(&frmOpt.palette, QPalette::Text, QPalette::Base);
frmOpt.rect = rule.borderRect(frmOpt.rect);
baseStyle()->drawControl(ce, &frmOpt, p, w);
- } else {
- rule.drawBorder(p, rule.borderRect(opt->rect));
}
+ // else, borders are already drawn in PE_Widget
}
return;
@@ -4220,12 +4213,6 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
QRect rect = opt->rect;
switch (pe) {
- case PE_PanelStatusBar:
- if (rule.hasDrawable()) {
- rule.drawRule(p, opt->rect);
- return;
- }
- break;
case PE_FrameStatusBar: {
QRenderRule subRule = renderRule(w->parentWidget(), opt, PseudoElement_Item);
@@ -4337,36 +4324,34 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
return;
case PE_Widget:
- if (!rule.hasBackground()) {
+ if (!rule.hasDrawable()) {
QWidget *container = containerWidget(w);
if (autoFillDisabledWidgets->contains(container)
- && (container == w || !renderRule(container, opt).hasBackground())) {
+ && (container == w || !renderRule(container, opt).hasDrawable())) {
//we do not have a background, but we disabled the autofillbackground anyway. so fill the background now.
// (this may happen if we have rules like :focus)
p->fillRect(opt->rect, opt->palette.brush(w->backgroundRole()));
}
break;
}
-
#ifndef QT_NO_SCROLLAREA
if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w)) {
const QAbstractScrollAreaPrivate *sap = sa->d_func();
rule.drawBackground(p, opt->rect, sap->contentsOffset());
- } else
-#endif
- {
- rule.drawBackground(p, opt->rect);
+ if (rule.hasBorder())
+ rule.drawBorder(p, rule.borderRect(opt->rect));
+ break;
}
-
- return;
-
- case PE_FrameMenu:
+#endif
+ //fall tghought
+ case PE_PanelMenu:
case PE_PanelMenuBar:
- if (!rule.hasNativeBorder()) {
- rule.drawBorder(p, rule.borderRect(opt->rect));
+ case PE_PanelStatusBar:
+ if(rule.hasDrawable()) {
+ rule.drawRule(p, opt->rect);
return;
}
- break;
+ break;
case PE_IndicatorToolBarSeparator:
case PE_IndicatorToolBarHandle: {
@@ -5887,13 +5872,11 @@ void QStyleSheetStyle::clearWidgetFont(QWidget* w) const
w->setProperty("_q_styleSheetWidgetFont", QVariant(QVariant::Invalid));
}
-// Returns the palette that should be used when the particular widget is focused.
-// This needs to be called by some widgets that do drawing themselves instead
-// of through the style.
-// ### This should be removed ideally by Qt 4.5, and at least by Qt 5, and fixed
-// for good by letting the style draw everything.
+// Polish palette that should be used for a particular widget, with particular states
+// (eg. :focus, :hover, ...)
+// this is called by widgets that paint themself in their paint event
// Returns true if there is a new palette in pal.
-bool QStyleSheetStyle::focusPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal)
+bool QStyleSheetStyle::styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal)
{
if (!w || !opt || !pal)
return false;
diff --git a/src/gui/styles/qstylesheetstyle_p.h b/src/gui/styles/qstylesheetstyle_p.h
index 1f61445..e057274 100644
--- a/src/gui/styles/qstylesheetstyle_p.h
+++ b/src/gui/styles/qstylesheetstyle_p.h
@@ -131,7 +131,7 @@ public:
void saveWidgetFont(QWidget* w, const QFont& font) const;
void clearWidgetFont(QWidget* w) const;
- bool focusPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal);
+ bool styleSheetPalette(const QWidget* w, const QStyleOption* opt, QPalette* pal);
protected Q_SLOTS:
QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *opt = 0,
diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp
index 63c1315..016b7c1 100644
--- a/src/gui/widgets/qlabel.cpp
+++ b/src/gui/widgets/qlabel.cpp
@@ -971,6 +971,13 @@ void QLabel::paintEvent(QPaintEvent *)
#endif
if (d->isTextLabel) {
QRectF lr = d->layoutRect();
+ QStyleOption opt;
+ opt.initFrom(this);
+#ifndef QT_NO_STYLE_STYLESHEET
+ if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
+ cssStyle->styleSheetPalette(this, &opt, &opt.palette);
+ }
+#endif
if (d->control) {
#ifndef QT_NO_SHORTCUT
const bool underline = (bool)style->styleHint(QStyle::SH_UnderlineShortcut, 0, this, 0);
@@ -984,11 +991,9 @@ void QLabel::paintEvent(QPaintEvent *)
d->ensureTextLayouted();
QAbstractTextDocumentLayout::PaintContext context;
- QStyleOption opt(0);
- opt.init(this);
if (!isEnabled() && style->styleHint(QStyle::SH_EtchDisabledText, &opt, this)) {
- context.palette = palette();
+ context.palette = opt.palette;
context.palette.setColor(QPalette::Text, context.palette.light().color());
painter.save();
painter.translate(lr.x() + 1, lr.y() + 1);
@@ -999,12 +1004,7 @@ void QLabel::paintEvent(QPaintEvent *)
}
// Adjust the palette
- context.palette = palette();
-#ifndef QT_NO_STYLE_STYLESHEET
- if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style)) {
- cssStyle->focusPalette(this, &opt, &context.palette);
- }
-#endif
+ context.palette = opt.palette;
if (foregroundRole() != QPalette::Text && isEnabled())
context.palette.setColor(QPalette::Text, context.palette.color(foregroundRole()));
@@ -1019,12 +1019,10 @@ void QLabel::paintEvent(QPaintEvent *)
int flags = align;
if (d->hasShortcut) {
flags |= Qt::TextShowMnemonic;
- QStyleOption opt;
- opt.initFrom(this);
if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
flags |= Qt::TextHideMnemonic;
}
- style->drawItemText(&painter, lr.toRect(), flags, palette(), isEnabled(), d->text, foregroundRole());
+ style->drawItemText(&painter, lr.toRect(), flags, opt.palette, isEnabled(), d->text, foregroundRole());
}
} else
#ifndef QT_NO_PICTURE
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index e243ad0..d16ed10 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -2518,7 +2518,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
// draw text, selections and cursors
#ifndef QT_NO_STYLE_STYLESHEET
if (QStyleSheetStyle* cssStyle = qobject_cast<QStyleSheetStyle*>(style())) {
- cssStyle->focusPalette(this, &panel, &pal);
+ cssStyle->styleSheetPalette(this, &panel, &pal);
}
#endif
p.setPen(pal.text().color());
diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm
index c807afb..53e1ad5 100644
--- a/src/gui/widgets/qmainwindowlayout_mac.mm
+++ b/src/gui/widgets/qmainwindowlayout_mac.mm
@@ -502,11 +502,11 @@ void QMainWindowLayout::fixSizeInUnifiedToolbar(QToolBar *tb) const
QMacCocoaAutoReleasePool pool;
QWidgetItem layoutItem(tb);
QSize size = layoutItem.maximumSize();
- NSSize nssize = NSMakeSize(size.width(), size.height());
+ NSSize nssize = NSMakeSize(size.width(), size.height() - 2);
[item setMaxSize:nssize];
size = layoutItem.minimumSize();
nssize.width = size.width();
- nssize.height = size.height();
+ nssize.height = size.height() - 2;
[item setMinSize:nssize];
}
}
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index b562b1f..49de8c1 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -1941,8 +1941,10 @@ void QTabBar::changeEvent(QEvent *event)
if (event->type() == QEvent::StyleChange) {
d->elideMode = Qt::TextElideMode(style()->styleHint(QStyle::SH_TabBar_ElideMode, 0, this));
d->useScrollButtons = !style()->styleHint(QStyle::SH_TabBar_PreferNoArrows, 0, this);
+ d->refresh();
+ } else if (event->type() == QEvent::FontChange) {
+ d->refresh();
}
- d->refresh();
QWidget::changeEvent(event);
}