Merge "Merge remote-tracking branch 'origin/release' into stable" into refs/staging/stable

bb10
Stephen Kelly 2013-03-13 23:35:18 +01:00 committed by The Qt Project
commit 2a388e503f
22 changed files with 182 additions and 53 deletions

View File

@ -1,2 +1,5 @@
load(qt_build_config)
CONFIG += qt_example_installs
# In qtbase, all modules follow qglobal.h
MODULE_VERSION = $$QT_VERSION

View File

@ -25,11 +25,13 @@ QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR
!build_online_docs: \
QDOC += -installdir $$[QT_INSTALL_DOCS]
qtver.name = QT_VERSION
qtver.value = $$QT_VERSION
qtver.value = $$VERSION
isEmpty(qtver.value): qtver.value = $$MODULE_VERSION
isEmpty(qtver.value): error("No version for documentation specified.")
qtmver.name = QT_VER
qtmver.value = $${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}
qtmver.value = $$replace(qtver.value, ^(\\d+\\.\\d+).*$, \\1)
qtvertag.name = QT_VERSION_TAG
qtvertag.value = $$replace(QT_VERSION, \.,)
qtvertag.value = $$replace(qtver.value, \.,)
qtAddToolEnv(QDOC, qtver qtmver qtvertag)
doc_command = $$QDOC $$QMAKE_DOCS
prepare_docs {

View File

@ -20,7 +20,8 @@
load(qt_build_config) # loads qmodule.pri if hasn't been loaded already
isEmpty(MODULE):MODULE = $$section($$list($$basename(_PRO_FILE_)), ., 0, 0)
isEmpty(VERSION):VERSION = $$QT_VERSION
isEmpty(VERSION): VERSION = $$MODULE_VERSION
isEmpty(VERSION): error("Module does not define version.")
# Compile as shared/DLL or static according to the option given to configure
# unless overridden. Host builds are always static

View File

@ -79,7 +79,7 @@ public:
virtual bool init();
virtual int type() const { return BUILDSMETATYPE; }
virtual bool write(const QString &);
virtual bool write();
};
void
@ -149,7 +149,7 @@ BuildsMetaMakefileGenerator::init()
}
bool
BuildsMetaMakefileGenerator::write(const QString &oldpwd)
BuildsMetaMakefileGenerator::write()
{
Build *glue = 0;
if(!makefiles.isEmpty() && !makefiles.first()->build.isNull()) {
@ -181,7 +181,6 @@ BuildsMetaMakefileGenerator::write(const QString &oldpwd)
if(Option::output.fileName().isEmpty() &&
Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE)
Option::output.setFileName(project->first("QMAKE_MAKEFILE").toQString());
Option::output_dir = oldpwd;
QString build_name = build->name;
if(!build->build.isEmpty()) {
if(!build_name.isEmpty())
@ -268,7 +267,7 @@ public:
virtual bool init();
virtual int type() const { return SUBDIRSMETATYPE; }
virtual bool write(const QString &);
virtual bool write();
};
bool
@ -349,7 +348,7 @@ SubdirsMetaMakefileGenerator::init()
} else {
const QString output_name = Option::output.fileName();
Option::output.setFileName(sub->output_file);
hasError |= !sub->makefile->write(sub->output_dir);
hasError |= !sub->makefile->write();
delete sub;
qmakeClearCaches();
sub = 0;
@ -378,7 +377,7 @@ SubdirsMetaMakefileGenerator::init()
}
bool
SubdirsMetaMakefileGenerator::write(const QString &oldpwd)
SubdirsMetaMakefileGenerator::write()
{
bool ret = true;
const QString &pwd = qmake_getpwd();
@ -397,10 +396,7 @@ SubdirsMetaMakefileGenerator::write(const QString &oldpwd)
printf("Writing %s\n", QDir::cleanPath(Option::output_dir+"/"+
Option::output.fileName()).toLatin1().constData());
}
QString writepwd = Option::fixPathToLocalOS(qmake_getpwd());
if(!writepwd.startsWith(Option::fixPathToLocalOS(oldpwd)))
writepwd = oldpwd;
if(!(ret = subs.at(i)->makefile->write(writepwd)))
if (!(ret = subs.at(i)->makefile->write()))
break;
//restore because I'm paranoid
qmake_setpwd(pwd);

View File

@ -69,7 +69,7 @@ public:
virtual bool init() = 0;
virtual int type() const { return -1; }
virtual bool write(const QString &oldpwd) = 0;
virtual bool write() = 0;
};
QT_END_NAMESPACE

View File

@ -187,7 +187,7 @@ int runQMake(int argc, char **argv)
if (!success)
exit_val = 3;
if(mkfile && !mkfile->write(oldpwd)) {
if (mkfile && !mkfile->write()) {
if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT)
fprintf(stderr, "Unable to generate project file.\n");
else

View File

@ -736,13 +736,13 @@ QLocale::QLocale(QLocalePrivate &dd)
The separator can be either underscore or a minus sign.
If the string violates the locale format, or language is not
a valid ISO 369 code, the "C" locale is used instead. If country
a valid ISO 639 code, the "C" locale is used instead. If country
is not present, or is not a valid ISO 3166 code, the most
appropriate country is chosen for the specified language.
The language, script and country codes are converted to their respective
\c Language, \c Script and \c Country enums. After this conversion is
performed the constructor behaves exactly like QLocale(Country, Script,
performed, the constructor behaves exactly like QLocale(Country, Script,
Language).
This constructor is much slower than QLocale(Country, Script, Language).

View File

@ -239,8 +239,9 @@ QImage QRasterPlatformPixmap::toImage(const QRect &rect) const
return image;
QRect clipped = rect.intersected(QRect(0, 0, w, h));
if (d % 8 == 0)
return QImage(image.scanLine(clipped.y()) + clipped.x() * (d / 8),
const uint du = uint(d);
if ((du % 8 == 0) && (((uint(clipped.x()) * du)) % 32 == 0))
return QImage(image.scanLine(clipped.y()) + clipped.x() * (du / 8),
clipped.width(), clipped.height(),
image.bytesPerLine(), image.format());
else

View File

@ -290,11 +290,14 @@ void QCosmeticStroker::setup()
ppl = buffer->bytesPerLine()>>2;
}
// dashes are sensitive to clips, so we need to clip consistently when painting to the same device
QRect clipRect = strokeSelection & Dashed ? deviceRect : clip;
// setup FP clip bounds
xmin = clip.left() - 1;
xmax = clip.right() + 2;
ymin = clip.top() - 1;
ymax = clip.bottom() + 2;
xmin = clipRect.left() - 1;
xmax = clipRect.right() + 2;
ymin = clipRect.top() - 1;
ymax = clipRect.bottom() + 2;
lastPixel.x = -1;
}

View File

@ -85,8 +85,9 @@ public:
HorizontalMask = 0xc
};
QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr)
QCosmeticStroker(QRasterPaintEngineState *s, const QRect &dr, const QRect &dr_unclipped)
: state(s),
deviceRect(dr_unclipped),
clip(dr),
pattern(0),
reversePattern(0),
@ -110,6 +111,7 @@ public:
QRasterPaintEngineState *state;
QRect deviceRect;
QRect clip;
// clip bounds in real
qreal xmin, xmax;

View File

@ -1054,20 +1054,20 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt,
void QRasterPaintEnginePrivate::systemStateChanged()
{
QRect clipRect(0, 0,
deviceRectUnclipped = QRect(0, 0,
qMin(QT_RASTER_COORD_LIMIT, device->width()),
qMin(QT_RASTER_COORD_LIMIT, device->height()));
if (!systemClip.isEmpty()) {
QRegion clippedDeviceRgn = systemClip & clipRect;
QRegion clippedDeviceRgn = systemClip & deviceRectUnclipped;
deviceRect = clippedDeviceRgn.boundingRect();
baseClip->setClipRegion(clippedDeviceRgn);
} else {
deviceRect = clipRect;
deviceRect = deviceRectUnclipped;
baseClip->setClipRect(deviceRect);
}
#ifdef QT_DEBUG_DRAW
qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << clipRect << systemClip;
qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << deviceRectUnclipped << systemClip;
#endif
exDeviceRect = deviceRect;
@ -1529,7 +1529,7 @@ void QRasterPaintEngine::drawRects(const QRect *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@ -1576,7 +1576,7 @@ void QRasterPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (s->penData.blend) {
QRectVectorPath path;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i = 0; i < rectCount; ++i) {
path.set(rects[i]);
@ -1610,7 +1610,7 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
return;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(path);
} else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) {
@ -1953,7 +1953,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
if (s->penData.blend) {
QVectorPath vp((qreal *) points, pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@ -2018,7 +2018,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
QVectorPath vp((qreal *) fpoints.data(), pointCount, 0, QVectorPath::polygonFlags(mode));
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPath(vp);
} else {
@ -3112,7 +3112,7 @@ void QRasterPaintEngine::drawPoints(const QPointF *points, int pointCount)
return;
}
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@ -3132,7 +3132,7 @@ void QRasterPaintEngine::drawPoints(const QPoint *points, int pointCount)
return;
}
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
stroker.drawPoints(points, pointCount);
}
@ -3153,7 +3153,7 @@ void QRasterPaintEngine::drawLines(const QLine *lines, int lineCount)
return;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
const QLine &l = lines[i];
@ -3225,7 +3225,7 @@ void QRasterPaintEngine::drawLines(const QLineF *lines, int lineCount)
if (!s->penData.blend)
return;
if (s->flags.fast_pen) {
QCosmeticStroker stroker(s, d->deviceRect);
QCosmeticStroker stroker(s, d->deviceRect, d->deviceRectUnclipped);
stroker.setLegacyRoundingEnabled(s->flags.legacy_rounding);
for (int i=0; i<lineCount; ++i) {
QLineF line = lines[i];

View File

@ -323,6 +323,7 @@ public:
#endif
QRect deviceRect;
QRect deviceRectUnclipped;
QStroker basicStroker;
QScopedPointer<QDashStroker> dashStroker;

View File

@ -706,7 +706,7 @@ quint16 QNetworkProxy::port() const
If a QAbstractSocket or QTcpSocket has the
QNetworkProxy::DefaultProxy type, then the QNetworkProxy set with
this function is used. If you want more flexibility in determining
which the proxy, use the QNetworkProxyFactory class.
which proxy is used, use the QNetworkProxyFactory class.
Setting a default proxy value with this function will override the
application proxy factory set with

View File

@ -202,6 +202,14 @@ static void cleanupCocoaApplicationDelegate()
if ([self canQuit]) {
if (!startedQuit) {
startedQuit = true;
// Close open windows. This is done in order to deliver de-expose
// events while the event loop is still running.
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
QWindow *window = topLevels.at(i);
topLevels.at(i)->close();
}
QGuiApplication::exit(0);
startedQuit = false;
}

View File

@ -108,6 +108,7 @@ public:
void setWindowIcon(const QIcon &icon);
void raise();
void lower();
bool isExposed() const;
void propagateSizeHints();
void setOpacity(qreal level);
void setMask(const QRegion &region);
@ -144,6 +145,8 @@ public:
QCocoaMenuBar *menubar() const;
qreal devicePixelRatio() const;
void exposeWindow();
void obscureWindow();
protected:
// NSWindow handling. The QCocoaWindow/QNSView can either be displayed
// in an existing NSWindow or in one created by Qt.
@ -178,6 +181,7 @@ public: // for QNSView
bool m_hasModalSession;
bool m_frameStrutEventsEnabled;
bool m_isExposed;
};
QT_END_NAMESPACE

View File

@ -200,6 +200,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_menubar(0)
, m_hasModalSession(false)
, m_frameStrutEventsEnabled(false)
, m_isExposed(false)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@ -284,9 +285,12 @@ void QCocoaWindow::setVisible(bool visible)
}
// Make sure the QWindow has a frame ready before we show the NSWindow.
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
QWindowSystemInterface::flushWindowSystemEvents();
// This call is here to handle initial window show correctly:
// - top-level windows need to have backing store content ready when the
// window is shown, sendin the expose event here makes that more likely.
// - QNSViews for child windows are initialy not hidden and won't get the
// viewDidUnhide message.
exposeWindow();
if (m_nsWindow) {
// setWindowState might have been called while the window was hidden and
@ -338,8 +342,6 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
if (!QCoreApplication::closingDown())
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
}
}
@ -489,6 +491,11 @@ void QCocoaWindow::lower()
[m_nsWindow orderBack: m_nsWindow];
}
bool QCocoaWindow::isExposed() const
{
return m_isExposed;
}
void QCocoaWindow::propagateSizeHints()
{
QCocoaAutoReleasePool pool;
@ -873,6 +880,22 @@ qreal QCocoaWindow::devicePixelRatio() const
}
}
void QCocoaWindow::exposeWindow()
{
if (!m_isExposed) {
m_isExposed = true;
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
}
void QCocoaWindow::obscureWindow()
{
if (m_isExposed) {
m_isExposed = false;
QWindowSystemInterface::handleExposeEvent(window(), QRegion());
}
}
QMargins QCocoaWindow::frameMargins() const
{
NSRect frameW = [m_nsWindow frame];

View File

@ -59,6 +59,7 @@ QT_END_NAMESPACE
QPoint m_backingStoreOffset;
CGImageRef m_maskImage;
uchar *m_maskData;
bool m_shouldInvalidateWindowShadow;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
@ -76,9 +77,12 @@ QT_END_NAMESPACE
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
- (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset;
- (void)setMaskRegion:(const QRegion *)region;
- (void)invalidateWindowShadowIfNeeded;
- (void)drawRect:(NSRect)dirtyRect;
- (void)updateGeometry;
- (void)windowNotification : (NSNotification *) windowNotification;
- (void)viewDidHide;
- (void)viewDidUnhide;
- (BOOL)isFlipped;
- (BOOL)acceptsFirstResponder;

View File

@ -80,6 +80,7 @@ static QTouchDevice *touchDevice = 0;
m_backingStore = 0;
m_maskImage = 0;
m_maskData = 0;
m_shouldInvalidateWindowShadow = false;
m_window = 0;
m_buttons = Qt::NoButton;
m_sendKeyEvent = false;
@ -266,10 +267,10 @@ static QTouchDevice *touchDevice = 0;
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowMinimized);
} else if (notificationName == NSWindowDidDeminiaturizeNotification) {
QWindowSystemInterface::handleWindowStateChanged(m_window, Qt::WindowNoState);
// Qt expects an expose event after restore/deminiaturize. This also needs
// to be a non-synchronous event to make sure it gets processed after
// the state change event sent above.
QWindowSystemInterface::handleExposeEvent(m_window, QRegion(m_window->geometry()));
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
m_platformWindow->exposeWindow();
} else {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@ -285,6 +286,16 @@ static QTouchDevice *touchDevice = 0;
}
}
- (void)viewDidHide
{
m_platformWindow->obscureWindow();
}
- (void)viewDidUnhide
{
m_platformWindow->exposeWindow();
}
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
{
m_backingStore = backingStore;
@ -295,13 +306,14 @@ static QTouchDevice *touchDevice = 0;
- (void) setMaskRegion:(const QRegion *)region
{
m_shouldInvalidateWindowShadow = true;
if (m_maskImage)
CGImageRelease(m_maskImage);
if (region->isEmpty()) {
m_maskImage = 0;
}
const QRect &rect = qt_mac_toQRect([self frame]);
const QRect &rect = region->boundingRect();
QImage maskImage(rect.size(), QImage::Format_RGB888);
maskImage.fill(Qt::white);
QPainter p(&maskImage);
@ -314,6 +326,14 @@ static QTouchDevice *touchDevice = 0;
m_maskImage = qt_mac_toCGImage(maskImage, true, &m_maskData);
}
- (void)invalidateWindowShadowIfNeeded
{
if (m_shouldInvalidateWindowShadow && m_platformWindow->m_nsWindow) {
[m_platformWindow->m_nsWindow invalidateShadow];
m_shouldInvalidateWindowShadow = false;
}
}
- (void) drawRect:(NSRect)dirtyRect
{
if (!m_backingStore)
@ -368,6 +388,8 @@ static QTouchDevice *touchDevice = 0;
CGContextRestoreGState(cgContext);
CGImageRelease(cleanImg);
CGImageRelease(subMask);
[self invalidateWindowShadowIfNeeded];
}
- (BOOL) isFlipped

View File

@ -167,6 +167,8 @@ private slots:
void scaled_QTBUG19157();
void detachOnLoad_QTBUG29639();
void copyOnNonAlignedBoundary();
};
static bool lenientCompare(const QPixmap &actual, const QPixmap &expected)
@ -1503,5 +1505,13 @@ void tst_QPixmap::detachOnLoad_QTBUG29639()
QVERIFY(a.toImage() != b.toImage());
}
void tst_QPixmap::copyOnNonAlignedBoundary()
{
QImage img(8, 2, QImage::Format_RGB16);
QPixmap pm1 = QPixmap::fromImage(img, Qt::NoFormatConversion);
QPixmap pm2 = pm1.copy(QRect(5, 0, 3, 2)); // When copying second line: 2 bytes too many are read which might cause an access violation.
}
QTEST_MAIN(tst_QPixmap)
#include "tst_qpixmap.moc"

View File

@ -280,6 +280,7 @@ private slots:
void drawTextWithComplexBrush();
void QTBUG26013_squareCapStroke();
void QTBUG25153_drawLine();
void dashing_systemClip();
private:
void fillData();
@ -4461,6 +4462,43 @@ void tst_QPainter::QTBUG25153_drawLine()
}
}
static void dashing_systemClip_paint(QPainter *p)
{
p->setPen(QPen(Qt::black, 1, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin));
p->drawLine(8, 8, 42, 8);
p->drawLine(42, 8, 42, 42);
p->drawLine(42, 42, 8, 42);
p->drawLine(8, 42, 8, 8);
}
void tst_QPainter::dashing_systemClip()
{
QImage image(50, 50, QImage::Format_RGB32);
image.fill(Qt::white);
QPainter p(&image);
dashing_systemClip_paint(&p);
p.end();
QImage old = image.copy();
image.paintEngine()->setSystemClip(QRect(10, 0, image.width() - 10, image.height()));
p.begin(&image);
dashing_systemClip_paint(&p);
// doing same paint operation again with different system clip should not change the image
QCOMPARE(old, image);
old = image;
p.setClipRect(QRect(20, 20, 30, 30));
dashing_systemClip_paint(&p);
// ditto for regular clips
QCOMPARE(old, image);
}
QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc"

View File

@ -832,10 +832,19 @@ static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceI
class UnclippedWidget : public QWidget
{
public:
bool painted;
UnclippedWidget()
: painted(false)
{
}
void paintEvent(QPaintEvent *)
{
QPainter p(this);
p.fillRect(rect().adjusted(-1000, -1000, 1000, 1000), Qt::black);
painted = true;
}
};
@ -866,10 +875,8 @@ void tst_QGL::graphicsViewClipping()
scene.setSceneRect(view.viewport()->rect());
QVERIFY(QTest::qWaitForWindowExposed(&view));
#ifdef Q_OS_MAC
// The black rectangle jumps from the center to the upper left for some reason.
QTest::qWait(100);
#endif
QTRY_VERIFY(widget->painted);
QImage image = viewport->grabFrameBuffer();
QImage expected = image;

View File

@ -103,6 +103,10 @@ void tst_QToolTip::task183679()
QFETCH(Qt::Key, key);
QFETCH(bool, visible);
#ifdef Q_OS_MAC
QSKIP("This test fails in the CI system, QTBUG-30040");
#endif
Widget_task183679 widget;
widget.show();
QApplication::setActiveWindow(&widget);