summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/dialogs/qdialog.cpp14
-rw-r--r--src/gui/dialogs/qdialog.h2
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp13
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp11
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp12
-rw-r--r--src/gui/image/qicon.cpp19
-rw-r--r--src/gui/image/qicon.h2
-rw-r--r--src/gui/image/qiconengine.cpp20
-rw-r--r--src/gui/image/qiconengine.h5
-rw-r--r--src/gui/image/qiconloader.cpp6
-rw-r--r--src/gui/kernel/qapplication_win.cpp25
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm7
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h11
-rw-r--r--src/gui/kernel/qwidget.cpp8
-rw-r--r--src/gui/painting/qbezier.cpp305
-rw-r--r--src/gui/painting/qbezier_p.h9
-rw-r--r--src/gui/painting/qdrawhelper.cpp21
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qpaintengineex.cpp3
-rw-r--r--src/gui/painting/qpainterpath.cpp11
-rw-r--r--src/gui/painting/qpathclipper.cpp509
-rw-r--r--src/gui/painting/qpathclipper_p.h30
-rw-r--r--src/gui/painting/qwindowsurface_p.h8
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm16
-rw-r--r--src/gui/text/qtextodfwriter.cpp12
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp1
-rw-r--r--src/gui/widgets/qlinecontrol.cpp2
-rw-r--r--src/gui/widgets/qmenu.cpp2
-rw-r--r--src/gui/widgets/qmenu_mac.mm19
31 files changed, 287 insertions, 821 deletions
diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp
index a6bd78a..e4f45ba 100644
--- a/src/gui/dialogs/qdialog.cpp
+++ b/src/gui/dialogs/qdialog.cpp
@@ -393,7 +393,6 @@ void QDialogPrivate::resetModalitySetByOpen()
resetModalityTo = -1;
}
-#if defined(Q_WS_WINCE) || defined(Q_WS_S60)
#ifdef Q_WS_WINCE_WM
void QDialogPrivate::_q_doneAction()
{
@@ -408,12 +407,12 @@ void QDialogPrivate::_q_doneAction()
bool QDialog::event(QEvent *e)
{
bool result = QWidget::event(e);
-#ifdef Q_WS_WINCE
+#if defined(Q_WS_WINCE)
if (e->type() == QEvent::OkRequest) {
accept();
result = true;
- }
-#else
+ } else
+#elif defined(Q_WS_S60)
if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize )) {
if (!testAttribute(Qt::WA_Moved)) {
Qt::WindowStates state = windowState();
@@ -422,11 +421,14 @@ bool QDialog::event(QEvent *e)
if (state != windowState())
setWindowState(state);
}
- }
+ } else
#endif
+ if (e->type() == QEvent::Move) {
+ setAttribute(Qt::WA_Moved, true); // as explicit as the user wants it to be
+ }
+
return result;
}
-#endif
/*!
Returns the modal dialog's result code, \c Accepted or \c Rejected.
diff --git a/src/gui/dialogs/qdialog.h b/src/gui/dialogs/qdialog.h
index 777256a..7ab0cb6 100644
--- a/src/gui/dialogs/qdialog.h
+++ b/src/gui/dialogs/qdialog.h
@@ -107,9 +107,7 @@ public Q_SLOTS:
protected:
QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = 0);
-#if defined(Q_WS_WINCE) || defined(Q_WS_S60)
bool event(QEvent *e);
-#endif
void keyPressEvent(QKeyEvent *);
void closeEvent(QCloseEvent *);
void showEvent(QShowEvent *);
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 9759b39..6cc3f7d 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1237,6 +1237,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
}
dirtySceneTransform = 1;
+ if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
+ transformChanged();
// Restore the sub focus chain.
if (subFocusItem) {
@@ -3622,6 +3624,7 @@ void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
q_ptr->prepareGeometryChange();
transformData->transform = transform;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -3812,6 +3815,8 @@ void QGraphicsItem::setRotation(qreal angle)
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->rotationChanged();
+
+ d_ptr->transformChanged();
}
/*!
@@ -3876,6 +3881,8 @@ void QGraphicsItem::setScale(qreal factor)
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->scaleChanged();
+
+ d_ptr->transformChanged();
}
@@ -3931,6 +3938,7 @@ void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transf
transformations.at(i)->d_func()->setItem(this);
d_ptr->transformData->onlyTransform = false;
d_ptr->dirtySceneTransform = 1;
+ d_ptr->transformChanged();
}
/*!
@@ -3947,6 +3955,7 @@ void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
t->d_func()->setItem(q);
transformData->onlyTransform = false;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -3963,6 +3972,7 @@ void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
t->d_func()->setItem(q);
transformData->onlyTransform = false;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -10086,6 +10096,9 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event)
#endif //QT_NO_IM
}
break;
+ case QEvent::ShortcutOverride:
+ dd->sendControlEvent(event);
+ return true;
default:
break;
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index f922842..8c7fbb4 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -284,6 +284,7 @@ public:
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
bool discardUpdateRequest(bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
+ virtual void transformChanged() {}
int depth() const;
#ifndef QT_NO_GRAPHICSEFFECT
enum InvalidateReason {
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
index ad7cf5d..1f89714 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp
@@ -1024,9 +1024,18 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even
// Map event position from us to the receiver
pos = d->mapToReceiver(pos, receiver);
+ QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
+ //If the receiver by-pass the proxy its popups
+ //will be top level QWidgets therefore they need
+ //the screen position. mapToGlobal expect the widget to
+ //have proper coordinates in regards of the windowing system
+ //but it's not true because the widget is embedded.
+ if (bypassGraphicsProxyWidget(receiver))
+ globalPos = event->screenPos();
+
// Send mouse event. ### Doesn't propagate the event.
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
- pos.toPoint(), receiver->mapToGlobal(pos.toPoint()), event->modifiers());
+ pos.toPoint(), globalPos, event->modifiers());
QApplication::sendEvent(receiver, &contextMenuEvent);
event->setAccepted(contextMenuEvent.isAccepted());
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index a767987..114de85 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -733,11 +733,13 @@ void QGraphicsViewPrivate::_q_unsetViewportCursor()
}
// Restore the original viewport cursor.
- hasStoredOriginalCursor = false;
- if (dragMode == QGraphicsView::ScrollHandDrag)
- viewport->setCursor(Qt::OpenHandCursor);
- else
- viewport->setCursor(originalCursor);
+ if (hasStoredOriginalCursor) {
+ hasStoredOriginalCursor = false;
+ if (dragMode == QGraphicsView::ScrollHandDrag)
+ viewport->setCursor(Qt::OpenHandCursor);
+ else
+ viewport->setCursor(originalCursor);
+ }
}
#endif
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index fad51f4..bc52e99 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -879,6 +879,25 @@ QList<QSize> QIcon::availableSizes(Mode mode, State state) const
}
/*!
+ \since 4.7
+
+ Returns the name used to create the icon, if available.
+
+ Depending on the way the icon was created, it may have an associated
+ name. This is the case for icons created with fromTheme() or icons
+ using a QIconEngine which supports the QIconEngineV2::IconNameHook.
+
+ \sa fromTheme(), QIconEngine
+*/
+QString QIcon::name() const
+{
+ if (!d || !d->engine || d->engine_version < 2)
+ return QString();
+ QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
+ return engine->iconName();
+}
+
+/*!
\since 4.6
Sets the search paths for icon themes to \a paths.
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 2812703..faef07b 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -81,6 +81,8 @@ public:
QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const;
+ QString name() const;
+
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const;
inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const
{ paint(painter, QRect(x, y, w, h), alignment, mode, state); }
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index 4c7c728..050d48d 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -183,6 +183,10 @@ void QIconEngine::addFile(const QString &/*fileName*/, const QSize &/*size*/, QI
that should be filled with icon sizes. Engines that work in terms
of a scalable, vectorial format normally return an empty list.
+ \value IconNameHook Allows to query the name used to create the
+ icon, for example when instantiating an icon using
+ QIcon::fromTheme().
+
\sa virtual_hook()
*/
@@ -301,4 +305,20 @@ QList<QSize> QIconEngineV2::availableSizes(QIcon::Mode mode, QIcon::State state)
return arg.sizes;
}
+/*!
+ \since 4.7
+
+ Returns the name used to create the engine, if available.
+
+ \note This is a helper method and the actual work is done by
+ virtual_hook() method, hence this method depends on icon engine support
+ and may not work with all icon engines.
+ */
+QString QIconEngineV2::iconName()
+{
+ QString name;
+ virtual_hook(QIconEngineV2::IconNameHook, reinterpret_cast<void*>(&name));
+ return name;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index 1f9266b..6d8b6ad 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -80,7 +80,7 @@ public:
virtual void virtual_hook(int id, void *data);
public:
- enum IconEngineHook { AvailableSizesHook = 1 };
+ enum IconEngineHook { AvailableSizesHook = 1, IconNameHook };
struct AvailableSizesArgument
{
@@ -92,6 +92,9 @@ public:
// ### Qt 5: make this function const and virtual.
QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal,
QIcon::State state = QIcon::Off);
+
+ // ### Qt 5: make this function const and virtual.
+ QString iconName();
};
QT_END_NAMESPACE
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 72ec2e8..a515ef8 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -554,6 +554,12 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
}
}
break;
+ case QIconEngineV2::IconNameHook:
+ {
+ QString &name = *reinterpret_cast<QString*>(data);
+ name = m_iconName;
+ }
+ break;
default:
QIconEngineV2::virtual_hook(id, data);
}
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 1d8eb4c..fb2837e 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -79,6 +79,7 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c
#include "qlayout.h"
#include "qtooltip.h"
#include "qt_windows.h"
+#include "qscrollbar.h"
#if defined(QT_NON_COMMERCIAL)
#include "qnc_win.h"
#endif
@@ -701,6 +702,21 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
QApplication::setPalette(menu, "QMenuBar");
}
+static void qt_set_windows_updateScrollBar(QWidget *widget)
+{
+ QList<QObject*> children = widget->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *o = children.at(i);
+ if(!o->isWidgetType())
+ continue;
+ if (QWidget *w = static_cast<QWidget *>(o))
+ qt_set_windows_updateScrollBar(w);
+ }
+ if (qobject_cast<QScrollBar*>(widget))
+ widget->updateGeometry();
+}
+
+
/*****************************************************************************
qt_init() - initializes Qt for Windows
*****************************************************************************/
@@ -1930,6 +1946,15 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
}
}
}
+ else if (msg.wParam == SPI_SETNONCLIENTMETRICS) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget && !widget->parentWidget()) {
+ qt_set_windows_updateScrollBar(widget);
+ QEvent e(QEvent::LayoutRequest);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
+
break;
case WM_PAINT: // paint event
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
index b58fd7c..8d65aa1 100644
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ b/src/gui/kernel/qcocoamenuloader_mac.mm
@@ -53,6 +53,12 @@
QT_FORWARD_DECLARE_CLASS(QCFString)
QT_FORWARD_DECLARE_CLASS(QString)
+#ifndef QT_NO_TRANSLATION
+ QT_BEGIN_NAMESPACE
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_END_NAMESPACE
+#endif
+
QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
@@ -226,7 +232,6 @@ QT_USE_NAMESPACE
- (void)qtTranslateApplicationMenu
{
#ifndef QT_NO_TRANSLATION
- extern QString qt_mac_applicationmenu_string(int type);
[servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
[hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))];
[hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index ec00915..e94d247 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -101,6 +101,17 @@ QT_END_NAMESPACE
return !(isPopup || isToolTip || isTool);
}
+- (void)becomeMainWindow
+{
+ [super becomeMainWindow];
+ // Cocoa sometimes tell a hidden window to become the
+ // main window (and as such, show it). This can e.g
+ // happend when the application gets activated. If
+ // this is the case, we tell it to hide again:
+ if (![self isVisible])
+ [self orderOut:self];
+}
+
- (void)toggleToolbarShown:(id)sender
{
macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 10fa4b9..441e823 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -7307,9 +7307,9 @@ void QWidgetPrivate::show_helper()
setVisible(false).
- \note If you are working with QDialog or its subclasses and you invoke
- the show() function after this function, the dialog will be displayed in
- its original position.
+ \note Since Qt 4.7, when calling hide() and then show() on QDialog
+ derived widgets will show on the previous (as in "Where the user moved it to")
+ position.
\sa hideEvent(), isHidden(), show(), setVisible(), isVisible(), close()
*/
@@ -7322,7 +7322,7 @@ void QWidgetPrivate::hide_helper()
bool isEmbedded = false;
#if !defined QT_NO_GRAPHICSVIEW
- isEmbedded = q->isWindow() && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
+ isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
#else
Q_UNUSED(isEmbedded);
#endif
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index a08c79e..7ff2a37 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -612,88 +612,6 @@ give_up:
return o - curveSegments;
}
-#if 0
-static inline bool IntersectBB(const QBezier &a, const QBezier &b)
-{
- return a.bounds().intersects(b.bounds());
-}
-#else
-static int IntersectBB(const QBezier &a, const QBezier &b)
-{
- // Compute bounding box for a
- qreal minax, maxax, minay, maxay;
- if (a.x1 > a.x4) // These are the most likely to be extremal
- minax = a.x4, maxax = a.x1;
- else
- minax = a.x1, maxax = a.x4;
-
- if (a.x3 < minax)
- minax = a.x3;
- else if (a.x3 > maxax)
- maxax = a.x3;
-
- if (a.x2 < minax)
- minax = a.x2;
- else if (a.x2 > maxax)
- maxax = a.x2;
-
- if (a.y1 > a.y4)
- minay = a.y4, maxay = a.y1;
- else
- minay = a.y1, maxay = a.y4;
-
- if (a.y3 < minay)
- minay = a.y3;
- else if (a.y3 > maxay)
- maxay = a.y3;
-
- if (a.y2 < minay)
- minay = a.y2;
- else if (a.y2 > maxay)
- maxay = a.y2;
-
- // Compute bounding box for b
- qreal minbx, maxbx, minby, maxby;
- if (b.x1 > b.x4)
- minbx = b.x4, maxbx = b.x1;
- else
- minbx = b.x1, maxbx = b.x4;
-
- if (b.x3 < minbx)
- minbx = b.x3;
- else if (b.x3 > maxbx)
- maxbx = b.x3;
-
- if (b.x2 < minbx)
- minbx = b.x2;
- else if (b.x2 > maxbx)
- maxbx = b.x2;
-
- if (b.y1 > b.y4)
- minby = b.y4, maxby = b.y1;
- else
- minby = b.y1, maxby = b.y4;
-
- if (b.y3 < minby)
- minby = b.y3;
- else if (b.y3 > maxby)
- maxby = b.y3;
-
- if (b.y2 < minby)
- minby = b.y2;
- else if (b.y2 > maxby)
- maxby = b.y2;
-
- // Test bounding box of b against bounding box of a
- if ((minax > maxbx) || (minay > maxby) // Not >= : need boundary case
- || (minbx > maxax) || (minby > maxay))
- return 0; // they don't intersect
- else
- return 1; // they intersect
-}
-#endif
-
-
#ifdef QDEBUG_BEZIER
static QDebug operator<<(QDebug dbg, const QBezier &bz)
{
@@ -705,193 +623,6 @@ static QDebug operator<<(QDebug dbg, const QBezier &bz)
}
#endif
-static bool RecursivelyIntersect(const QBezier &a, qreal t0, qreal t1, int deptha,
- const QBezier &b, qreal u0, qreal u1, int depthb,
- QVector<QPair<qreal, qreal> > *t)
-{
-#ifdef QDEBUG_BEZIER
- static int I = 0;
- int currentD = I;
- fprintf(stderr, "%d) t0 = %lf, t1 = %lf, deptha = %d\n"
- "u0 = %lf, u1 = %lf, depthb = %d\n", I++, t0, t1, deptha,
- u0, u1, depthb);
-#endif
- if (deptha > 0) {
- QBezier A[2];
- a.split(&A[0], &A[1]);
- qreal tmid = (t0+t1)*0.5;
- //qDebug()<<"\t1)"<<A[0];
- //qDebug()<<"\t2)"<<A[1];
- deptha--;
- if (depthb > 0) {
- QBezier B[2];
- b.split(&B[0], &B[1]);
- //qDebug()<<"\t3)"<<B[0];
- //qDebug()<<"\t4)"<<B[1];
- qreal umid = (u0+u1)*0.5;
- depthb--;
- if (IntersectBB(A[0], B[0])) {
- //fprintf(stderr, "\t 1 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], B[0])) {
- //fprintf(stderr, "\t 2 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[0], B[1])) {
- //fprintf(stderr, "\t 3 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], B[1])) {
- //fprintf(stderr, "\t 4 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- } else {
- if (IntersectBB(A[0], b)) {
- //fprintf(stderr, "\t 5 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- b, u0, u1, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], b)) {
- //fprintf(stderr, "\t 6 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- b, u0, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- }
- } else {
- if (depthb > 0) {
- QBezier B[2];
- b.split(&B[0], &B[1]);
- qreal umid = (u0 + u1)*0.5;
- depthb--;
- if (IntersectBB(a, B[0])) {
- //fprintf(stderr, "\t 7 from %d\n", currentD);
- if (RecursivelyIntersect(a, t0, t1, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(a, B[1])) {
- //fprintf(stderr, "\t 8 from %d\n", currentD);
- if (RecursivelyIntersect(a, t0, t1, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- }
- else {
- // Both segments are fully subdivided; now do line segments
- qreal xlk = a.x4 - a.x1;
- qreal ylk = a.y4 - a.y1;
- qreal xnm = b.x4 - b.x1;
- qreal ynm = b.y4 - b.y1;
- qreal xmk = b.x1 - a.x1;
- qreal ymk = b.y1 - a.y1;
- qreal det = xnm * ylk - ynm * xlk;
- if (1.0 + det == 1.0) {
- return false;
- } else {
- qreal detinv = 1.0 / det;
- qreal rs = (xnm * ymk - ynm *xmk) * detinv;
- qreal rt = (xlk * ymk - ylk * xmk) * detinv;
- if ((rs < 0.0) || (rs > 1.0) || (rt < 0.0) || (rt > 1.0))
- return false;
-
- if (t) {
- const qreal alpha_a = t0 + rs * (t1 - t0);
- const qreal alpha_b = u0 + rt * (u1 - u0);
-
- *t << qMakePair(alpha_a, alpha_b);
- }
-
- return true;
- }
- }
- }
-}
-
-QVector< QPair<qreal, qreal> > QBezier::findIntersections(const QBezier &a, const QBezier &b)
-{
- QVector< QPair<qreal, qreal> > v(2);
- findIntersections(a, b, &v);
- return v;
-}
-
-bool QBezier::findIntersections(const QBezier &a, const QBezier &b,
- QVector<QPair<qreal, qreal> > *t)
-{
- if (IntersectBB(a, b)) {
- QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)),
- qFabs((a.y3 - a.y2) - (a.y2 - a.y1)));
- QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)),
- qFabs((a.y4 - a.y3) - (a.y3 - a.y2)));
- QPointF la;
- if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x());
- if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y());
- QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)),
- qFabs((b.y3 - b.y2) - (b.y2 - b.y1)));
- QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)),
- qFabs((b.y4 - b.y3) - (b.y3 - b.y2)));
- QPointF lb;
- if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x());
- if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y());
- qreal l0;
- if (la.x() > la.y())
- l0 = la.x();
- else
- l0 = la.y();
- int ra;
- if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)
- ra = 0;
- else
- ra = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));
- if (lb.x() > lb.y())
- l0 = lb.x();
- else
- l0 = lb.y();
- int rb;
- if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)
- rb = 0;
- else
- rb = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));
-
- // if qreal is float then halve the number of subdivisions
- if (sizeof(qreal) == 4) {
- ra /= 2;
- rb /= 2;
- }
-
- return RecursivelyIntersect(a, 0., 1., ra, b, 0., 1., rb, t);
- }
-
- //Don't sort here because it breaks the orders of corresponding
- // intersections points. this way t's at the same locations correspond
- // to the same intersection point.
- //qSort(parameters[0].begin(), parameters[0].end(), qLess<qreal>());
- //qSort(parameters[1].begin(), parameters[1].end(), qLess<qreal>());
-
- return false;
-}
-
static inline void splitBezierAt(const QBezier &bez, qreal t,
QBezier *left, QBezier *right)
{
@@ -920,42 +651,6 @@ static inline void splitBezierAt(const QBezier &bez, qreal t,
right->y4 = bez.y4;
}
-QVector< QList<QBezier> > QBezier::splitAtIntersections(QBezier &b)
-{
- QVector< QList<QBezier> > curves(2);
-
- QVector< QPair<qreal, qreal> > allInters = findIntersections(*this, b);
-
- QList<qreal> inters1;
- QList<qreal> inters2;
-
- for (int i = 0; i < allInters.size(); ++i) {
- inters1 << allInters[i].first;
- inters2 << allInters[i].second;
- }
-
- qSort(inters1.begin(), inters1.end(), qLess<qreal>());
- qSort(inters2.begin(), inters2.end(), qLess<qreal>());
-
- Q_ASSERT(inters1.count() == inters2.count());
-
- int i;
- for (i = 0; i < inters1.count(); ++i) {
- qreal t1 = inters1.at(i);
- qreal t2 = inters2.at(i);
-
- QBezier curve1, curve2;
- parameterSplitLeft(t1, &curve1);
- b.parameterSplitLeft(t2, &curve2);
- curves[0].append(curve1);
- curves[0].append(curve2);
- }
- curves[0].append(*this);
- curves[1].append(b);
-
- return curves;
-}
-
qreal QBezier::length(qreal error) const
{
qreal length = 0.0;
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index f015ea8..846635f 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -111,16 +111,7 @@ public:
int shifted(QBezier *curveSegments, int maxSegmets,
qreal offset, float threshold) const;
- QVector< QList<QBezier> > splitAtIntersections(QBezier &a);
-
QBezier bezierOnInterval(qreal t0, qreal t1) const;
-
- static QVector< QPair<qreal, qreal> > findIntersections(const QBezier &a,
- const QBezier &b);
-
- static bool findIntersections(const QBezier &a, const QBezier &b,
- QVector<QPair<qreal, qreal> > *t);
-
QBezier getSubRange(qreal t0, qreal t1) const;
qreal x1, y1, x2, y2, x3, y3, x4, y4;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index b440fce..bfa1136 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -674,6 +674,11 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int image_width = data->texture.width;
int image_height = data->texture.height;
+ int image_x1 = data->texture.x1;
+ int image_y1 = data->texture.y1;
+ int image_x2 = data->texture.x2;
+ int image_y2 = data->texture.y2;
+
const qreal cx = x + 0.5;
const qreal cy = y + 0.5;
@@ -708,17 +713,17 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
y2 = y1 + 1;
y2 %= image_height;
} else {
- if (x1 < 0) {
- x2 = x1 = 0;
- } else if (x1 >= image_width - 1) {
- x2 = x1 = image_width - 1;
+ if (x1 < image_x1) {
+ x2 = x1 = image_x1;
+ } else if (x1 >= image_x2 - 1) {
+ x2 = x1 = image_x2 - 1;
} else {
x2 = x1 + 1;
}
- if (y1 < 0) {
- y2 = y1 = 0;
- } else if (y1 >= image_height - 1) {
- y2 = y1 = image_height - 1;
+ if (y1 < image_y1) {
+ y2 = y1 = image_y1;
+ } else if (y1 >= image_y2 - 1) {
+ y2 = y1 = image_y2 - 1;
} else {
y2 = y1 + 1;
}
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 8f14583..9148ac2 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2552,7 +2552,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
int sr_t = qFloor(sr.top());
int sr_b = qCeil(sr.bottom()) - 1;
- if (!s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
+ if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
// as fillRect will apply the aliased coordinate delta we need to
// subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 9366513..a78cafb 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -974,6 +974,9 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount,
const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/)
{
+ if (pixmap.isNull())
+ return;
+
qreal oldOpacity = state()->opacity;
QTransform oldTransform = state()->matrix;
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index f78de34..f5a698e 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1914,7 +1914,7 @@ static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF
case QPainterPath::MoveToElement:
if (i > 0
- && qFuzzyCompare(last_pt.x(), last_start.y())
+ && qFuzzyCompare(last_pt.x(), last_start.x())
&& qFuzzyCompare(last_pt.y(), last_start.y())
&& qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),
last_start.x(), last_start.y(), rect))
@@ -3167,6 +3167,8 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
Set operations on paths will treat the paths as areas. Non-closed
paths will be treated as implicitly closed.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
\sa intersected(), subtracted()
*/
@@ -3182,6 +3184,8 @@ QPainterPath QPainterPath::united(const QPainterPath &p) const
\since 4.3
Returns a path which is the intersection of this path's fill area and \a p's fill area.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::intersected(const QPainterPath &p) const
{
@@ -3198,7 +3202,8 @@ QPainterPath QPainterPath::intersected(const QPainterPath &p) const
Set operations on paths will treat the paths as areas. Non-closed
paths will be treated as implicitly closed.
-
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::subtracted(const QPainterPath &p) const
{
@@ -3227,6 +3232,8 @@ QPainterPath QPainterPath::subtractedInverted(const QPainterPath &p) const
Returns a simplified version of this path. This implies merging all subpaths that intersect,
and returning a path containing no intersecting edges. Consecutive parallel lines will also
be merged. The simplified path will always use the default fill rule, Qt::OddEvenFill.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::simplified() const
{
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 00e74ba..9dedf3a 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -105,22 +105,10 @@ public:
bool hasIntersections(const QPathSegments &a, const QPathSegments &b) const;
private:
- void intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections);
void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections);
-
- bool beziersIntersect(const QBezier &one, const QBezier &two) const;
bool linesIntersect(const QLineF &a, const QLineF &b) const;
};
-bool QIntersectionFinder::beziersIntersect(const QBezier &one, const QBezier &two) const
-{
- return (comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2())
- && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4()))
- || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3())
- && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))
- || QBezier::findIntersections(one, two, 0);
-}
-
bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
{
const QPointF p1 = a.p1();
@@ -174,11 +162,6 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
return false;
}
- // if the lines are not parallel and share a common end point, then they
- // don't intersect
- if (p1_equals_q1 || p1_equals_q2 || p2_equals_q1 || p2_equals_q2)
- return false;
-
const qreal invPar = 1 / par;
const qreal tp = (qDelta.y() * (q1.x() - p1.x()) -
@@ -193,48 +176,6 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
return tq >= 0 && tq <= 1;
}
-void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections)
-{
- if ((comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2())
- && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4()))
- || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3())
- && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))) {
-
- return;
- }
-
- t.clear();
-
- if (!QBezier::findIntersections(one, two, &t))
- return;
-
- int count = t.size();
-
- for (int i = 0; i < count; ++i) {
- qreal alpha_p = t.at(i).first;
- qreal alpha_q = t.at(i).second;
-
- QPointF pt;
- if (qFuzzyIsNull(alpha_p)) {
- pt = one.pt1();
- } else if (qFuzzyIsNull(alpha_p - 1)) {
- pt = one.pt4();
- } else if (qFuzzyIsNull(alpha_q)) {
- pt = two.pt1();
- } else if (qFuzzyIsNull(alpha_q - 1)) {
- pt = two.pt4();
- } else {
- pt = one.pointAt(alpha_p);
- }
-
- QIntersection intersection;
- intersection.alphaA = alpha_p;
- intersection.alphaB = alpha_q;
- intersection.pos = pt;
- intersections.add(intersection);
- }
-}
-
void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections)
{
const QPointF p1 = a.p1();
@@ -357,19 +298,8 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData
intersections.add(intersection);
}
-static const QBezier bezierFromLine(const QLineF &line)
-{
- const QPointF p1 = line.p1();
- const QPointF p2 = line.p2();
- const QPointF delta = (p2 - p1) / 3;
- return QBezier::fromPoints(p1, p1 + delta, p1 + 2 * delta, p2);
-}
-
bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const
{
- QBezier tempA;
- QBezier tempB;
-
if (a.segments() == 0 || b.segments() == 0)
return false;
@@ -391,9 +321,6 @@ bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSe
QRectF rb(minX, minY, maxX - minX, maxY - minY);
for (int i = 0; i < a.segments(); ++i) {
- const QBezier *bezierA = a.bezierAt(i);
- bool isBezierA = bezierA != 0;
-
const QRectF &r1 = a.elementBounds(i);
if (r1.left() > rb.right() || rb.left() > r1.right())
@@ -409,28 +336,8 @@ bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSe
if (r1.top() > r2.bottom() || r2.top() > r1.bottom())
continue;
- bool isBezierB = b.bezierAt(j) != 0;
-
- if (isBezierA || isBezierB) {
- const QBezier *bezierB;
- if (isBezierB) {
- bezierB = b.bezierAt(j);
- } else {
- tempB = bezierFromLine(b.lineAt(j));
- bezierB = &tempB;
- }
-
- if (!bezierA) {
- tempA = bezierFromLine(a.lineAt(i));
- bezierA = &tempA;
- }
-
- if (beziersIntersect(*bezierA, *bezierB))
- return true;
- } else {
- if (linesIntersect(a.lineAt(i), b.lineAt(j)))
- return true;
- }
+ if (linesIntersect(a.lineAt(i), b.lineAt(j)))
+ return true;
}
}
@@ -439,16 +346,10 @@ bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSe
void QIntersectionFinder::produceIntersections(QPathSegments &segments)
{
- QBezier tempA;
- QBezier tempB;
-
QVector<QPair<qreal, qreal> > t;
QDataBuffer<QIntersection> intersections;
for (int i = 0; i < segments.segments(); ++i) {
- const QBezier *bezierA = segments.bezierAt(i);
- bool isBezierA = bezierA != 0;
-
const QRectF &r1 = segments.elementBounds(i);
for (int j = 0; j < i; ++j) {
@@ -461,29 +362,10 @@ void QIntersectionFinder::produceIntersections(QPathSegments &segments)
intersections.reset();
- bool isBezierB = segments.bezierAt(j) != 0;
+ const QLineF lineA = segments.lineAt(i);
+ const QLineF lineB = segments.lineAt(j);
- if (isBezierA || isBezierB) {
- const QBezier *bezierB;
- if (isBezierB) {
- bezierB = segments.bezierAt(j);
- } else {
- tempB = bezierFromLine(segments.lineAt(j));
- bezierB = &tempB;
- }
-
- if (!bezierA) {
- tempA = bezierFromLine(segments.lineAt(i));
- bezierA = &tempA;
- }
-
- intersectBeziers(*bezierA, *bezierB, t, intersections);
- } else {
- const QLineF lineA = segments.lineAt(i);
- const QLineF lineB = segments.lineAt(j);
-
- intersectLines(lineA, lineB, intersections);
- }
+ intersectLines(lineA, lineB, intersections);
for (int k = 0; k < intersections.size(); ++k) {
QPathSegments::Intersection i_isect, j_isect;
@@ -731,53 +613,34 @@ void QWingedEdge::intersectAndAdd()
qSort(intersections.data(), intersections.data() + intersections.size());
- const QBezier *bezier = m_segments.bezierAt(i);
- if (bezier) {
- int first = m_segments.segmentAt(i).va;
- int second = m_segments.segmentAt(i).vb;
-
- qreal alpha = 0.0;
- int last = first;
- for (int j = 0; j < intersections.size(); ++j) {
- const QPathSegments::Intersection &isect = intersections.at(j);
+ int first = m_segments.segmentAt(i).va;
+ int second = m_segments.segmentAt(i).vb;
- addBezierEdge(bezier, last, isect.vertex, alpha, isect.t, pathId);
+ int last = first;
+ for (int j = 0; j < intersections.size(); ++j) {
+ const QPathSegments::Intersection &isect = intersections.at(j);
- alpha = isect.t;
- last = isect.vertex;
- }
-
- addBezierEdge(bezier, last, second, alpha, 1.0, pathId);
- } else {
- int first = m_segments.segmentAt(i).va;
- int second = m_segments.segmentAt(i).vb;
-
- int last = first;
- for (int j = 0; j < intersections.size(); ++j) {
- const QPathSegments::Intersection &isect = intersections.at(j);
-
- QPathEdge *ep = edge(addEdge(last, isect.vertex));
-
- if (ep) {
- const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1;
- if (pathId == 0)
- ep->windingA += dir;
- else
- ep->windingB += dir;
- }
-
- last = isect.vertex;
- }
-
- QPathEdge *ep = edge(addEdge(last, second));
+ QPathEdge *ep = edge(addEdge(last, isect.vertex));
if (ep) {
- const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y() ? 1 : -1;
+ const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1;
if (pathId == 0)
ep->windingA += dir;
else
ep->windingB += dir;
}
+
+ last = isect.vertex;
+ }
+
+ QPathEdge *ep = edge(addEdge(last, second));
+
+ if (ep) {
+ const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y() ? 1 : -1;
+ if (pathId == 0)
+ ep->windingA += dir;
+ else
+ ep->windingB += dir;
}
}
}
@@ -832,7 +695,6 @@ static bool isLine(const QBezier &bezier)
void QPathSegments::setPath(const QPainterPath &path)
{
m_points.reset();
- m_beziers.reset();
m_intersections.reset();
m_segments.reset();
@@ -845,6 +707,9 @@ void QPathSegments::addPath(const QPainterPath &path)
{
int firstSegment = m_segments.size();
+ QRectF pathBounds = path.boundingRect();
+ qreal invPathScale = 1 / qMax(pathBounds.width(), pathBounds.height());
+
bool hasMoveTo = false;
int lastMoveTo = 0;
int last = 0;
@@ -879,8 +744,26 @@ void QPathSegments::addPath(const QPainterPath &path)
if (isLine(bezier)) {
m_segments << Segment(m_pathId, last, current);
} else {
- m_segments << Segment(m_pathId, last, current, m_beziers.size());
- m_beziers << bezier;
+ QRectF bounds = bezier.bounds();
+
+ qreal segmentScale = qMax(bounds.width(), bounds.height());
+
+ // threshold based on same algorithm as in qtriangulatingstroker.cpp
+ int threshold = qMin<float>(64, segmentScale * invPathScale * (512 * 3.14f / 6));
+ if (threshold < 3) threshold = 3;
+ qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1);
+
+ for (int t = 1; t < threshold - 1; ++t) {
+ currentPoint = bezier.pointAt(t * one_over_threshold_minus_1);
+
+ int index = m_points.size();
+ m_segments << Segment(m_pathId, last, index);
+ last = index;
+
+ m_points << currentPoint;
+ }
+
+ m_segments << Segment(m_pathId, last, current);
}
}
last = current;
@@ -896,24 +779,19 @@ void QPathSegments::addPath(const QPainterPath &path)
m_segments << Segment(m_pathId, last, lastMoveTo);
for (int i = firstSegment; i < m_segments.size(); ++i) {
- const QBezier *bezier = bezierAt(i);
- if (bezier) {
- m_segments.at(i).bounds = bezier->bounds();
- } else {
- const QLineF line = lineAt(i);
+ const QLineF line = lineAt(i);
- qreal x1 = line.p1().x();
- qreal y1 = line.p1().y();
- qreal x2 = line.p2().x();
- qreal y2 = line.p2().y();
+ qreal x1 = line.p1().x();
+ qreal y1 = line.p1().y();
+ qreal x2 = line.p2().x();
+ qreal y2 = line.p2().y();
- if (x2 < x1)
- qSwap(x1, x2);
- if (y2 < y1)
- qSwap(y1, y2);
+ if (x2 < x1)
+ qSwap(x1, x2);
+ if (y2 < y1)
+ qSwap(y1, y2);
- m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1);
- }
+ m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1);
}
++m_pathId;
@@ -948,28 +826,17 @@ static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei)
const QPathEdge *ep = list.edge(ei);
Q_ASSERT(ep);
- qreal t;
qreal sign;
if (ep->first == vi) {
- t = ep->t0;
sign = 1;
} else {
- t = ep->t1;
sign = -1;
}
- QPointF normal;
- if (ep->bezier) {
- normal = ep->bezier->derivedAt(t);
-
- if (qFuzzyIsNull(normal.x()) && qFuzzyIsNull(normal.y()))
- normal = ep->bezier->secondDerivedAt(t);
- } else {
- const QPointF a = *list.vertex(ep->first);
- const QPointF b = *list.vertex(ep->second);
- normal = b - a;
- }
+ const QPointF a = *list.vertex(ep->first);
+ const QPointF b = *list.vertex(ep->second);
+ QPointF normal = b - a;
return normalize(sign * normal);
}
@@ -979,83 +846,9 @@ static inline QPointF midPoint(const QWingedEdge &list, int ei)
const QPathEdge *ep = list.edge(ei);
Q_ASSERT(ep);
- if (ep->bezier) {
- return ep->bezier->pointAt(0.5 * (ep->t0 + ep->t1));
- } else {
- const QPointF a = *list.vertex(ep->first);
- const QPointF b = *list.vertex(ep->second);
- return a + 0.5 * (b - a);
- }
-}
-
-static QBezier transform(const QBezier &bezier, const QPointF &xAxis, const QPointF &yAxis, const QPointF &origin)
-{
- QPointF points[4] = {
- bezier.pt1(),
- bezier.pt2(),
- bezier.pt3(),
- bezier.pt4()
- };
-
- for (int i = 0; i < 4; ++i) {
- const QPointF p = points[i] - origin;
-
- points[i].rx() = dot(xAxis, p);
- points[i].ry() = dot(yAxis, p);
- }
-
- return QBezier::fromPoints(points[0], points[1], points[2], points[3]);
-}
-
-static bool isLeftOf(const QWingedEdge &list, int vi, int ai, int bi)
-{
- const QPathEdge *ap = list.edge(ai);
- const QPathEdge *bp = list.edge(bi);
-
- Q_ASSERT(ap);
- Q_ASSERT(bp);
-
- if (!(ap->bezier || bp->bezier))
- return false;
-
- const QPointF tangent = tangentAt(list, vi, ai);
- const QPointF normal(tangent.y(), -tangent.x());
-
- const QPointF origin = *list.vertex(vi);
-
- const QPointF dpA = midPoint(list, ai) - origin;
- const QPointF dpB = midPoint(list, bi) - origin;
-
- qreal xA = dot(normal, dpA);
- qreal xB = dot(normal, dpB);
-
- if (xA <= 0 && xB >= 0)
- return true;
-
- if (xA >= 0 && xB <= 0)
- return false;
-
- if (!ap->bezier)
- return xB > 0;
-
- if (!bp->bezier)
- return xA < 0;
-
- // both are beziers on the same side of the tangent
-
- // transform the beziers into the local coordinate system
- // such that positive y is along the tangent, and positive x is along the normal
-
- QBezier bezierA = transform(*ap->bezier, normal, tangent, origin);
- QBezier bezierB = transform(*bp->bezier, normal, tangent, origin);
-
- qreal y = qMin(bezierA.pointAt(0.5 * (ap->t0 + ap->t1)).y(),
- bezierB.pointAt(0.5 * (bp->t0 + bp->t1)).y());
-
- xA = bezierA.pointAt(bezierA.tForY(ap->t0, ap->t1, y)).x();
- xB = bezierB.pointAt(bezierB.tForY(bp->t0, bp->t1, y)).x();
-
- return xA < xB;
+ const QPointF a = *list.vertex(ep->first);
+ const QPointF b = *list.vertex(ep->second);
+ return a + 0.5 * (b - a);
}
QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
@@ -1084,7 +877,6 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
status.flip();
Q_ASSERT(edge(status.edge)->vertex(status.direction) == vi);
-
qreal d2 = delta(vi, ei, status.edge);
#ifdef QDEBUG_CLIPPER
@@ -1092,8 +884,7 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
qDebug() << "Delta to edge" << status.edge << d2 << ", angles: " << op->angle << op->invAngle;
#endif
- if (!(qFuzzyIsNull(d2) && isLeftOf(*this, vi, status.edge, ei))
- && (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) {
+ if (d2 < d) {
position = status.edge;
d = d2;
}
@@ -1210,15 +1001,15 @@ static qreal computeAngle(const QPointF &v)
#endif
}
-int QWingedEdge::addEdge(const QPointF &a, const QPointF &b, const QBezier *bezier, qreal t0, qreal t1)
+int QWingedEdge::addEdge(const QPointF &a, const QPointF &b)
{
int fi = insert(a);
int si = insert(b);
- return addEdge(fi, si, bezier, t0, t1);
+ return addEdge(fi, si);
}
-int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal t1)
+int QWingedEdge::addEdge(int fi, int si)
{
if (fi == si)
return -1;
@@ -1236,29 +1027,11 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal
QPathEdge *ep = edge(ei);
- ep->bezier = bezier;
- ep->t0 = t0;
- ep->t1 = t1;
-
- if (bezier) {
- QPointF aTangent = bezier->derivedAt(t0);
- QPointF bTangent = -bezier->derivedAt(t1);
-
- if (qFuzzyIsNull(aTangent.x()) && qFuzzyIsNull(aTangent.y()))
- aTangent = bezier->secondDerivedAt(t0);
-
- if (qFuzzyIsNull(bTangent.x()) && qFuzzyIsNull(bTangent.y()))
- bTangent = bezier->secondDerivedAt(t1);
-
- ep->angle = computeAngle(aTangent);
- ep->invAngle = computeAngle(bTangent);
- } else {
- const QPointF tangent = QPointF(*sp) - QPointF(*fp);
- ep->angle = computeAngle(tangent);
- ep->invAngle = ep->angle + 64;
- if (ep->invAngle >= 128)
- ep->invAngle -= 128;
- }
+ const QPointF tangent = QPointF(*sp) - QPointF(*fp);
+ ep->angle = computeAngle(tangent);
+ ep->invAngle = ep->angle + 64;
+ if (ep->invAngle >= 128)
+ ep->invAngle -= 128;
QPathVertex *vertices[2] = { fp, sp };
QPathEdge::Direction dirs[2] = { QPathEdge::Backward, QPathEdge::Forward };
@@ -1313,74 +1086,6 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal
return ei;
}
-void QWingedEdge::addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path)
-{
- if (qFuzzyCompare(alphaA, alphaB))
- return;
-
- qreal alphaMid = (alphaA + alphaB) * 0.5;
-
- qreal s0 = 0;
- qreal s1 = 1;
- int count = bezier->stationaryYPoints(s0, s1);
-
- m_splitPoints.clear();
- m_splitPoints << alphaA;
- m_splitPoints << alphaMid;
- m_splitPoints << alphaB;
-
- if (count > 0 && !qFuzzyCompare(s0, alphaA) && !qFuzzyCompare(s0, alphaMid) && !qFuzzyCompare(s0, alphaB) && s0 > alphaA && s0 < alphaB)
- m_splitPoints << s0;
-
- if (count > 1 && !qFuzzyCompare(s1, alphaA) && !qFuzzyCompare(s1, alphaMid) && !qFuzzyCompare(s1, alphaB) && s1 > alphaA && s1 < alphaB)
- m_splitPoints << s1;
-
- if (count > 0)
- qSort(m_splitPoints.begin(), m_splitPoints.end());
-
- int last = vertexA;
- for (int i = 0; i < m_splitPoints.size() - 1; ++i) {
- const qreal t0 = m_splitPoints[i];
- const qreal t1 = m_splitPoints[i+1];
-
- int current;
- if ((i + 1) == (m_splitPoints.size() - 1)) {
- current = vertexB;
- } else {
- current = insert(bezier->pointAt(t1));
- }
-
- QPathEdge *ep = edge(addEdge(last, current, bezier, t0, t1));
-
- if (ep) {
- const int dir = m_vertices.at(last).y < m_vertices.at(current).y ? 1 : -1;
- if (path == 0)
- ep->windingA += dir;
- else
- ep->windingB += dir;
- }
-
- last = current;
- }
-}
-
-void QWingedEdge::addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path)
-{
- if (qFuzzyCompare(alphaA, alphaB))
- return;
-
- if (comparePoints(a, b)) {
- int v = insert(a);
-
- addBezierEdge(bezier, v, v, alphaA, alphaB, path);
- } else {
- int va = insert(a);
- int vb = insert(b);
-
- addBezierEdge(bezier, va, vb, alphaA, alphaB, path);
- }
-}
-
int QWingedEdge::insert(const QPathVertex &vertex)
{
if (!m_vertices.isEmpty()) {
@@ -1429,37 +1134,12 @@ static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge
status.traversal = traversal;
status.direction = QPathEdge::Forward;
- const QBezier *bezier = 0;
- qreal t0 = 1;
- qreal t1 = 0;
- bool forward = true;
-
path.moveTo(*list.vertex(list.edge(edge)->first));
do {
const QPathEdge *ep = list.edge(status.edge);
- if (ep->bezier != bezier || (bezier && t0 != ep->t1 && t1 != ep->t0)) {
- if (bezier) {
- QBezier sub = bezier->bezierOnInterval(t0, t1);
-
- if (forward)
- path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4());
- else
- path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1());
- }
-
- bezier = ep->bezier;
- t0 = 1;
- t1 = 0;
- forward = status.direction == QPathEdge::Forward;
- }
-
- if (ep->bezier) {
- t0 = qMin(t0, ep->t0);
- t1 = qMax(t1, ep->t1);
- } else
- addLineTo(path, *list.vertex(ep->vertex(status.direction)));
+ addLineTo(path, *list.vertex(ep->vertex(status.direction)));
if (status.traversal == QPathEdge::LeftTraversal)
ep->flag &= ~16;
@@ -1468,14 +1148,6 @@ static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge
status = list.next(status);
} while (status.edge != edge);
-
- if (bezier) {
- QBezier sub = bezier->bezierOnInterval(t0, t1);
- if (forward)
- path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4());
- else
- path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1());
- }
}
void QWingedEdge::simplify()
@@ -1937,25 +1609,10 @@ bool QWingedEdge::isInside(qreal x, qreal y) const
QPointF b = *vertex(ep->second);
if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) {
- if (ep->bezier) {
- qreal maxX = qMax(a.x(), qMax(b.x(), qMax(ep->bezier->x2, ep->bezier->x3)));
- qreal minX = qMin(a.x(), qMin(b.x(), qMin(ep->bezier->x2, ep->bezier->x3)));
-
- if (minX > x) {
- winding += w;
- } else if (maxX > x) {
- const qreal t = ep->bezier->tForY(ep->t0, ep->t1, y);
- const qreal intersection = ep->bezier->pointAt(t).x();
-
- if (intersection > x)
- winding += w;
- }
- } else {
- qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
+ qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
- if (intersectionX > x)
- winding += w;
- }
+ if (intersectionX > x)
+ winding += w;
}
}
@@ -1971,17 +1628,9 @@ static QVector<QCrossingEdge> findCrossings(const QWingedEdge &list, qreal y)
QPointF b = *list.vertex(edge->second);
if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) {
- if (edge->bezier) {
- const qreal t = edge->bezier->tForY(edge->t0, edge->t1, y);
- const qreal intersection = edge->bezier->pointAt(t).x();
-
- const QCrossingEdge edge = { i, intersection };
- crossings << edge;
- } else {
- const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
- const QCrossingEdge edge = { i, intersection };
- crossings << edge;
- }
+ const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
+ const QCrossingEdge edge = { i, intersection };
+ crossings << edge;
}
}
return crossings;
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index b42dc1d..7962400 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -151,10 +151,6 @@ public:
qreal angle;
qreal invAngle;
- const QBezier *bezier;
- qreal t0;
- qreal t1;
-
int next(Traversal traversal, Direction direction) const;
void setNext(Traversal traversal, Direction direction, int next);
@@ -182,9 +178,8 @@ public:
};
struct Segment {
- Segment(int pathId, int vertexA, int vertexB, int bezierIndex = -1)
+ Segment(int pathId, int vertexA, int vertexB)
: path(pathId)
- , bezier(bezierIndex)
, va(vertexA)
, vb(vertexB)
, intersection(-1)
@@ -192,7 +187,6 @@ public:
}
int path;
- int bezier;
// vertices
int va;
@@ -216,7 +210,6 @@ public:
const Segment &segmentAt(int index) const;
const QLineF lineAt(int index) const;
- const QBezier *bezierAt(int index) const;
const QRectF &elementBounds(int index) const;
int pathId(int index) const;
@@ -231,7 +224,6 @@ public:
private:
QDataBuffer<QPointF> m_points;
QDataBuffer<Segment> m_segments;
- QDataBuffer<QBezier> m_beziers;
QDataBuffer<Intersection> m_intersections;
int m_pathId;
@@ -272,8 +264,8 @@ public:
TraversalStatus next(const TraversalStatus &status) const;
- int addEdge(const QPointF &a, const QPointF &b, const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);
- int addEdge(int vertexA, int vertexB, const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);
+ int addEdge(const QPointF &a, const QPointF &b);
+ int addEdge(int vertexA, int vertexB);
bool isInside(qreal x, qreal y) const;
@@ -285,11 +277,7 @@ private:
void printNode(int i, FILE *handle);
- QBezier bezierFromIndex(int index) const;
-
void removeEdge(int ei);
- void addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path);
- void addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path);
int insert(const QPathVertex &vertex);
TraversalStatus findInsertStatus(int vertex, int edge) const;
@@ -312,9 +300,6 @@ inline QPathEdge::QPathEdge(int a, int b)
, second(b)
, angle(0)
, invAngle(0)
- , bezier(0)
- , t0(0)
- , t1(0)
{
m_next[0][0] = -1;
m_next[1][0] = -1;
@@ -396,15 +381,6 @@ inline const QLineF QPathSegments::lineAt(int index) const
return QLineF(m_points.at(segment.va), m_points.at(segment.vb));
}
-inline const QBezier *QPathSegments::bezierAt(int index) const
-{
- const Segment &segment = m_segments.at(index);
- if (segment.bezier >= 0)
- return &m_beziers.at(segment.bezier);
- else
- return 0;
-}
-
inline const QRectF &QPathSegments::elementBounds(int index) const
{
return m_segments.at(index).bounds;
diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
index e6ee5f6..6171ae8 100644
--- a/src/gui/painting/qwindowsurface_p.h
+++ b/src/gui/painting/qwindowsurface_p.h
@@ -73,8 +73,12 @@ public:
QWidget *window() const;
virtual QPaintDevice *paintDevice() = 0;
- virtual void flush(QWidget *widget, const QRegion &region,
- const QPoint &offset) = 0;
+
+ // 'widget' can be a child widget, in which case 'region' is in child widget coordinates and
+ // offset is the (child) widget's offset in relation to the window surface. On QWS, 'offset'
+ // can be larger than just the offset from the top-level widget as there may also be window
+ // decorations which are painted into the window surface.
+ virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset) = 0;
virtual void setGeometry(const QRect &rect);
QRect geometry() const;
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index b0e2d37..8036728 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -981,7 +981,7 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
qreal y = position.y() + line.y() + line.ascent();
p->save();
p->setFont(option->font);
- p->drawText(int(x), int(y), elidedText);
+ p->drawText(QPointF(x, y), elidedText);
p->restore();
break;
}
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 074dd89..f5b0b0c 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -2143,7 +2143,7 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
ret = 0;
else
- ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ ret = 1;
break;
case PM_MaximumDragDistance:
ret = -1;
@@ -3099,14 +3099,16 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
HIRect hirect = qt_hirectForQRect(opt->rect);
HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
break; }
+
case PE_Frame: {
QPen oldPen = p->pen();
- QPen newPen;
- newPen.setBrush(opt->palette.dark());
- p->setPen(newPen);
+ p->setPen(opt->palette.base().color().darker(140));
p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(opt->palette.base().color().darker(180));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
p->setPen(oldPen);
break; }
+
case PE_FrameLineEdit:
if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
if (frame->state & State_Sunken) {
@@ -3279,10 +3281,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (header->orientation == Qt::Horizontal){
switch (header->position) {
case QStyleOptionHeader::Beginning:
+ ir.adjust(-1, -1, 0, 0);
break;
case QStyleOptionHeader::Middle:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::OnlyOneSection:
case QStyleOptionHeader::End:
- ir.adjust(-1, 0, 0, 0);
+ ir.adjust(-1, -1, 1, 0);
break;
default:
break;
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index d369bff0..7992de5 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -493,10 +493,10 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
format.nonBreakableLines() ? QString::fromLatin1("true") : QString::fromLatin1("false"));
if (format.hasProperty(QTextFormat::TabPositions)) {
QList<QTextOption::Tab> tabs = format.tabPositions();
- writer.writeStartElement(styleNS, QString::fromLatin1("style-tab-stops"));
+ writer.writeStartElement(styleNS, QString::fromLatin1("tab-stops"));
QList<QTextOption::Tab>::Iterator iterator = tabs.begin();
while(iterator != tabs.end()) {
- writer.writeEmptyElement(styleNS, QString::fromLatin1("style-tab-stop"));
+ writer.writeEmptyElement(styleNS, QString::fromLatin1("tab-stop"));
writer.writeAttribute(styleNS, QString::fromLatin1("position"), pixelToPoint(iterator->position) );
QString type;
switch(iterator->type) {
@@ -511,7 +511,7 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
++iterator;
}
- writer.writeEndElement(); // style-tab-stops
+ writer.writeEndElement(); // tab-stops
}
writer.writeEndElement(); // paragraph-properties
@@ -698,11 +698,11 @@ void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCe
if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding));
if (format.bottomPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.bottomPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"), pixelToPoint(format.bottomPadding()));
if (format.leftPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.leftPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-left"), pixelToPoint(format.leftPadding()));
if (format.rightPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.rightPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-right"), pixelToPoint(format.rightPadding()));
}
if (format.hasProperty(QTextFormat::TextVerticalAlignment)) {
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 73ec53e..8cffebd 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -983,6 +983,7 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
case QEvent::ApplicationLayoutDirectionChange:
+ case QEvent::LayoutRequest:
d->layoutChildren();
// fall through
default:
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index 42df800..d027b91 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -1350,6 +1350,7 @@ bool QLineControl::processEvent(QEvent* ev)
#endif
switch(ev->type()){
#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMousePress:{
@@ -1439,6 +1440,7 @@ void QLineControl::processMouseEvent(QMouseEvent* ev)
moveCursor(cursor, mark);
break;
}
+ case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::MouseButtonDblClick:
if (ev->button() == Qt::LeftButton) {
selectWordAtPos(xToPos(ev->pos().x()));
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index f9b132e..907dd14 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -1834,7 +1834,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
QSize size = sizeHint();
QRect screen;
#ifndef QT_NO_GRAPHICSVIEW
- bool isEmbedded = d->nearestGraphicsProxyWidget(this);
+ bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
if (isEmbedded)
screen = d->popupGeometry(this);
else
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 6a0eb53..7645c23 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -665,6 +665,7 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
}
}
#else
+ bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
for (NSMenuItem *item in [menu itemArray]) {
OSMenuRef submenu = [item submenu];
if (submenu != merge) {
@@ -674,10 +675,20 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
// The item should follow what the QAction has.
if ([item tag]) {
QAction *action = reinterpret_cast<QAction *>([item tag]);
- syncNSMenuItemEnabled(item, action->isEnabled());
- } else {
- syncNSMenuItemEnabled(item, YES);
- }
+ syncNSMenuItemEnabled(item, action->isEnabled());
+ } else {
+ syncNSMenuItemEnabled(item, YES);
+ }
+ // We sneak in some extra code here to handle a menu problem:
+ // If there is no window on screen, we cannot set 'nil' as
+ // menu item target, because then cocoa will disable the item
+ // (guess it assumes that there will be no first responder to
+ // catch the trigger anyway?) OTOH, If we have a modal window,
+ // then setting the menu loader as target will make cocoa not
+ // deliver the trigger because the loader is then seen as modally
+ // shaddowed). So either way there are shortcomings. Instead, we
+ // decide the target as late as possible:
+ [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
} else {
syncNSMenuItemEnabled(item, NO);
}