Merge remote-tracking branch 'origin/5.12' into 5.13

Change-Id: Ia5d893e57deb78bc32e2053a5a79543ff847fe32
This commit is contained in:
Qt Forward Merge Bot 2019-04-02 01:00:25 +02:00
commit ffe9c395dc
16 changed files with 212 additions and 64 deletions

View File

@ -23,4 +23,8 @@ QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_LINK = $${CROSS_COMPILE}g++ QMAKE_LINK = $${CROSS_COMPILE}g++
QMAKE_LINK_C = $${CROSS_COMPILE}gcc QMAKE_LINK_C = $${CROSS_COMPILE}gcc
QMAKE_CFLAGS_LTCG = -flto
QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG
load(qt_config) load(qt_config)

View File

@ -95,7 +95,9 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t)
if (project->isActiveConfig("debug_info")) { if (project->isActiveConfig("debug_info")) {
if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) {
QString pdb_target = project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb"; const QFileInfo targetFileInfo = project->first("DESTDIR") + project->first("TARGET")
+ project->first("TARGET_EXT");
const QString pdb_target = targetFileInfo.completeBaseName() + ".pdb";
QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target; QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target;
QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute)); QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute));
if(!ret.isEmpty()) if(!ret.isEmpty())
@ -252,15 +254,16 @@ void NmakeMakefileGenerator::init()
project->values("PRECOMPILED_PCH_C") = ProStringList(precompPchC); project->values("PRECOMPILED_PCH_C") = ProStringList(precompPchC);
} }
ProString tgt = project->first("DESTDIR") const QFileInfo targetFileInfo = project->first("DESTDIR") + project->first("TARGET")
+ project->first("TARGET") + project->first("TARGET_VERSION_EXT"); + project->first("TARGET_EXT");
const ProString targetBase = targetFileInfo.path() + '/' + targetFileInfo.completeBaseName();
if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("shared")) { if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("shared")) {
project->values("QMAKE_CLEAN").append(tgt + ".exp"); project->values("QMAKE_CLEAN").append(targetBase + ".exp");
project->values("QMAKE_DISTCLEAN").append(tgt + ".lib"); project->values("QMAKE_DISTCLEAN").append(targetBase + ".lib");
} }
if (project->isActiveConfig("debug_info")) { if (project->isActiveConfig("debug_info")) {
QString pdbfile; QString pdbfile;
QString distPdbFile = tgt + ".pdb"; QString distPdbFile = targetBase + ".pdb";
if (project->isActiveConfig("staticlib")) { if (project->isActiveConfig("staticlib")) {
// For static libraries, the compiler's pdb file and the dist pdb file are the same. // For static libraries, the compiler's pdb file and the dist pdb file are the same.
pdbfile = distPdbFile; pdbfile = distPdbFile;
@ -276,8 +279,8 @@ void NmakeMakefileGenerator::init()
project->values("QMAKE_DISTCLEAN").append(distPdbFile); project->values("QMAKE_DISTCLEAN").append(distPdbFile);
} }
if (project->isActiveConfig("debug")) { if (project->isActiveConfig("debug")) {
project->values("QMAKE_CLEAN").append(tgt + ".ilk"); project->values("QMAKE_CLEAN").append(targetBase + ".ilk");
project->values("QMAKE_CLEAN").append(tgt + ".idb"); project->values("QMAKE_CLEAN").append(targetBase + ".idb");
} else { } else {
ProStringList &defines = project->values("DEFINES"); ProStringList &defines = project->values("DEFINES");
if (!defines.contains("NDEBUG")) if (!defines.contains("NDEBUG"))

View File

@ -260,31 +260,25 @@ static int installFile(const QString &source, const QString &target, bool exe =
return 3; return 3;
} }
QFileDevice::Permissions targetPermissions = QFileDevice::ReadOwner | QFileDevice::WriteOwner
| QFileDevice::ReadUser | QFileDevice::WriteUser
| QFileDevice::ReadGroup | QFileDevice::ReadOther;
if (exe) { if (exe) {
if (!targetFile.setPermissions(sourceFile.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeUser | targetPermissions |= QFileDevice::ExeOwner | QFileDevice::ExeUser |
QFileDevice::ExeGroup | QFileDevice::ExeOther)) { QFileDevice::ExeGroup | QFileDevice::ExeOther;
fprintf(stderr, "Error setting execute permissions on %s: %s\n", }
qPrintable(target), qPrintable(targetFile.errorString())); if (!targetFile.setPermissions(targetPermissions)) {
return 3; fprintf(stderr, "Error setting permissions on %s: %s\n",
} qPrintable(target), qPrintable(targetFile.errorString()));
return 3;
} }
// Copy file times // Copy file times
QString error; QString error;
#ifdef Q_OS_WIN
const QFile::Permissions permissions = targetFile.permissions();
const bool readOnly = !(permissions & QFile::WriteUser);
if (readOnly)
targetFile.setPermissions(permissions | QFile::WriteUser);
#endif
if (!IoUtils::touchFile(target, sourceFile.fileName(), &error)) { if (!IoUtils::touchFile(target, sourceFile.fileName(), &error)) {
fprintf(stderr, "%s", qPrintable(error)); fprintf(stderr, "%s", qPrintable(error));
return 3; return 3;
} }
#ifdef Q_OS_WIN
if (readOnly)
targetFile.setPermissions(permissions);
#endif
return 0; return 0;
} }

View File

@ -254,10 +254,8 @@ public:
const float huge = std::numeric_limits<float>::infinity(); const float huge = std::numeric_limits<float>::infinity();
return d < 0 ? -huge : huge; return d < 0 ? -huge : huge;
} }
if (std::fabs(d) >= std::numeric_limits<double>::min() // i.e. d != 0 if (d != 0 && float(d) == 0) {
&& std::fabs(d) < std::numeric_limits<float>::min()) { // Values that underflow double already failed. Match them:
// Values smaller than std::numeric_limits<double>::min() have
// failed already; match them.
if (ok != 0) if (ok != 0)
*ok = false; *ok = false;
return 0; return 0;

View File

@ -1091,15 +1091,31 @@ void QImage::detach()
} }
static void copyMetadata(QImageData *dst, const QImageData *src) static void copyPhysicalMetadata(QImageData *dst, const QImageData *src)
{ {
// Doesn't copy colortable and alpha_clut, or offset.
dst->dpmx = src->dpmx; dst->dpmx = src->dpmx;
dst->dpmy = src->dpmy; dst->dpmy = src->dpmy;
dst->devicePixelRatio = src->devicePixelRatio; dst->devicePixelRatio = src->devicePixelRatio;
}
static void copyMetadata(QImageData *dst, const QImageData *src)
{
// Doesn't copy colortable and alpha_clut, or offset.
copyPhysicalMetadata(dst, src);
dst->text = src->text; dst->text = src->text;
} }
static void copyMetadata(QImage *dst, const QImage &src)
{
dst->setDotsPerMeterX(src.dotsPerMeterX());
dst->setDotsPerMeterY(src.dotsPerMeterY());
dst->setDevicePixelRatio(src.devicePixelRatio());
const auto textKeys = src.textKeys();
for (const auto &key: textKeys)
dst->setText(key, src.text(key));
}
/*! /*!
\fn QImage QImage::copy(int x, int y, int width, int height) const \fn QImage QImage::copy(int x, int y, int width, int height) const
\overload \overload
@ -2951,8 +2967,10 @@ QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
} }
QImage mask(d->width, d->height, Format_MonoLSB); QImage mask(d->width, d->height, Format_MonoLSB);
if (!mask.isNull()) if (!mask.isNull()) {
dither_to_Mono(mask.d, d, flags, true); dither_to_Mono(mask.d, d, flags, true);
copyPhysicalMetadata(mask.d, d);
}
return mask; return mask;
} }
@ -3070,6 +3088,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const
#undef PIX #undef PIX
copyPhysicalMetadata(m.d, d);
return m; return m;
} }
#endif //QT_NO_IMAGE_HEURISTIC_MASK #endif //QT_NO_IMAGE_HEURISTIC_MASK
@ -3113,6 +3132,8 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
} }
if (mode == Qt::MaskOutColor) if (mode == Qt::MaskOutColor)
maskImage.invertPixels(); maskImage.invertPixels();
copyPhysicalMetadata(maskImage.d, d);
return maskImage; return maskImage;
} }
@ -4684,8 +4705,7 @@ QImage QImage::smoothScaled(int w, int h) const {
static QImage rotated90(const QImage &image) static QImage rotated90(const QImage &image)
{ {
QImage out(image.height(), image.width(), image.format()); QImage out(image.height(), image.width(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY()); copyMetadata(&out, image);
out.setDotsPerMeterY(image.dotsPerMeterX());
if (image.colorCount() > 0) if (image.colorCount() > 0)
out.setColorTable(image.colorTable()); out.setColorTable(image.colorTable());
int w = image.width(); int w = image.width();
@ -4713,8 +4733,7 @@ static QImage rotated180(const QImage &image)
return image.mirrored(true, true); return image.mirrored(true, true);
QImage out(image.width(), image.height(), image.format()); QImage out(image.width(), image.height(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY()); copyMetadata(&out, image);
out.setDotsPerMeterY(image.dotsPerMeterX());
if (image.colorCount() > 0) if (image.colorCount() > 0)
out.setColorTable(image.colorTable()); out.setColorTable(image.colorTable());
int w = image.width(); int w = image.width();
@ -4726,8 +4745,7 @@ static QImage rotated180(const QImage &image)
static QImage rotated270(const QImage &image) static QImage rotated270(const QImage &image)
{ {
QImage out(image.height(), image.width(), image.format()); QImage out(image.height(), image.width(), image.format());
out.setDotsPerMeterX(image.dotsPerMeterY()); copyMetadata(&out, image);
out.setDotsPerMeterY(image.dotsPerMeterX());
if (image.colorCount() > 0) if (image.colorCount() > 0)
out.setColorTable(image.colorTable()); out.setColorTable(image.colorTable());
int w = image.width(); int w = image.width();

View File

@ -178,6 +178,7 @@ QBitmap QPlatformPixmap::mask() const
if (mask.isNull()) // allocation failed if (mask.isNull()) // allocation failed
return QBitmap(); return QBitmap();
mask.setDevicePixelRatio(devicePixelRatio());
mask.setColorCount(2); mask.setColorCount(2);
mask.setColor(0, QColor(Qt::color0).rgba()); mask.setColor(0, QColor(Qt::color0).rgba());
mask.setColor(1, QColor(Qt::color1).rgba()); mask.setColor(1, QColor(Qt::color1).rgba());

View File

@ -545,9 +545,11 @@ QBrush::QBrush(const QBrush &other)
*/ */
QBrush::QBrush(const QGradient &gradient) QBrush::QBrush(const QGradient &gradient)
{ {
Q_ASSERT_X(gradient.type() != QGradient::NoGradient, "QBrush::QBrush", if (Q_UNLIKELY(gradient.type() == QGradient::NoGradient)) {
"QGradient should not be used directly, use the linear, radial\n" d.reset(nullBrushInstance());
"or conical gradients instead"); d->ref.ref();
return;
}
const Qt::BrushStyle enum_table[] = { const Qt::BrushStyle enum_table[] = {
Qt::LinearGradientPattern, Qt::LinearGradientPattern,
@ -1376,8 +1378,10 @@ QGradient::QGradient(Preset preset)
}(); }();
const QJsonValue presetData = jsonPresets[preset - 1]; const QJsonValue presetData = jsonPresets[preset - 1];
if (!presetData.isObject()) if (!presetData.isObject()) {
qWarning("QGradient: Undefined preset %i", preset);
return; return;
}
m_type = LinearGradient; m_type = LinearGradient;
setCoordinateMode(ObjectMode); setCoordinateMode(ObjectMode);

View File

@ -446,6 +446,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->setRedBlueSwizzle(false); d_ptr->blitter->setRedBlueSwizzle(false);
} }
// There is no way to tell if the OpenGL-rendered content is premultiplied or not.
// For compatibility, assume that it is not, and use normal alpha blend always.
if (d_ptr->premultiplied)
funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
for (int i = 0; i < textures->count(); ++i) { for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))

View File

@ -1208,6 +1208,11 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
return handled; return handled;
} }
inline qreal scaleOneValuator(qreal normValue, qreal screenMin, qreal screenSize)
{
return screenMin + normValue * screenSize;
}
void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData) void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletData)
{ {
auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event); auto *ev = reinterpret_cast<const qt_xcb_input_device_event_t *>(event);
@ -1220,6 +1225,17 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
QPointF global(fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y)); QPointF global(fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y));
double pressure = 0, rotation = 0, tangentialPressure = 0; double pressure = 0, rotation = 0, tangentialPressure = 0;
int xTilt = 0, yTilt = 0; int xTilt = 0, yTilt = 0;
static const bool useValuators = !qEnvironmentVariableIsSet("QT_XCB_TABLET_LEGACY_COORDINATES");
// Valuators' values are relative to the physical size of the current virtual
// screen. Therefore we cannot use QScreen/QWindow geometry and should use
// QPlatformWindow/QPlatformScreen instead.
QRect physicalScreenArea;
if (Q_LIKELY(useValuators)) {
const QList<QPlatformScreen *> siblings = window->screen()->handle()->virtualSiblings();
for (const QPlatformScreen *screen : siblings)
physicalScreenArea |= screen->geometry();
}
for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData->valuatorInfo.begin(), for (QHash<int, TabletData::ValuatorClassInfo>::iterator it = tabletData->valuatorInfo.begin(),
ite = tabletData->valuatorInfo.end(); it != ite; ++it) { ite = tabletData->valuatorInfo.end(); it != ite; ++it) {
@ -1228,6 +1244,20 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal); xi2GetValuatorValueIfSet(event, classInfo.number, &classInfo.curVal);
double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal); double normalizedValue = (classInfo.curVal - classInfo.minVal) / (classInfo.maxVal - classInfo.minVal);
switch (valuator) { switch (valuator) {
case QXcbAtom::AbsX:
if (Q_LIKELY(useValuators)) {
const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width());
global.setX(value);
local.setX(value - window->handle()->geometry().x());
}
break;
case QXcbAtom::AbsY:
if (Q_LIKELY(useValuators)) {
qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height());
global.setY(value);
local.setY(value - window->handle()->geometry().y());
}
break;
case QXcbAtom::AbsPressure: case QXcbAtom::AbsPressure:
pressure = normalizedValue; pressure = normalizedValue;
break; break;

View File

@ -3411,18 +3411,20 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
case PE_IndicatorTabClose: { case PE_IndicatorTabClose: {
// Make close button visible only on the hovered tab. // Make close button visible only on the hovered tab.
QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget()); QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget());
const QWidget *closeBtn = w;
if (!tabBar) { if (!tabBar) {
// QStyleSheetStyle instead of CloseButton (which has // QStyleSheetStyle instead of CloseButton (which has
// a QTabBar as a parent widget) uses the QTabBar itself: // a QTabBar as a parent widget) uses the QTabBar itself:
tabBar = qobject_cast<QTabBar *>(const_cast<QWidget*>(w)); tabBar = qobject_cast<QTabBar *>(const_cast<QWidget*>(w));
closeBtn = decltype(closeBtn)(property("_q_styleSheetRealCloseButton").value<void *>());
} }
if (tabBar) { if (tabBar) {
const bool documentMode = tabBar->documentMode(); const bool documentMode = tabBar->documentMode();
const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar)); const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar));
const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex(); const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex();
if (!documentMode || if (!documentMode ||
(hoveredTabIndex != -1 && ((w == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) || (hoveredTabIndex != -1 && ((closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) ||
(w == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) { (closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) {
const bool hover = (opt->state & State_MouseOver); const bool hover = (opt->state & State_MouseOver);
const bool selected = (opt->state & State_Selected); const bool selected = (opt->state & State_Selected);
const bool pressed = (opt->state & State_Sunken); const bool pressed = (opt->state & State_Sunken);
@ -4323,7 +4325,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
d->setupNSGraphicsContext(cgCtx, YES); d->setupNSGraphicsContext(cgCtx, YES);
[s.toNSString() drawInRect:textRect [s.toNSString() drawInRect:textRect
withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c }]; withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c,
NSObliquenessAttributeName: [NSNumber numberWithDouble: myFont.italic() ? 0.3 : 0.0]}];
d->restoreNSGraphicsContext(cgCtx); d->restoreNSGraphicsContext(cgCtx);
} else { } else {

View File

@ -4593,8 +4593,12 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
break; break;
#if QT_CONFIG(tabbar) #if QT_CONFIG(tabbar)
case PE_IndicatorTabClose: case PE_IndicatorTabClose:
if (w) if (w) {
// QMacStyle needs a real widget, not its parent - to implement
// 'document mode' properly, drawing nothing if a tab is not hovered.
baseStyle()->setProperty("_q_styleSheetRealCloseButton", QVariant::fromValue((void *)w));
w = w->parentWidget(); //match on the QTabBar instead of the CloseButton w = w->parentWidget(); //match on the QTabBar instead of the CloseButton
}
pseudoElement = PseudoElement_TabBarTabCloseButton; pseudoElement = PseudoElement_TabBarTabCloseButton;
#endif #endif
@ -4612,6 +4616,9 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
} else { } else {
baseStyle()->drawPrimitive(pe, opt, p, w); baseStyle()->drawPrimitive(pe, opt, p, w);
} }
if (baseStyle()->property("_q_styleSheetRealCloseButton").toBool())
baseStyle()->setProperty("_q_styleSheetRealCloseButton", QVariant(QVariant::Invalid));
} }
QPixmap QStyleSheetStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap, QPixmap QStyleSheetStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap& pixmap,

View File

@ -952,29 +952,42 @@ void tst_QLocale::stringToDouble()
void tst_QLocale::stringToFloat_data() void tst_QLocale::stringToFloat_data()
{ {
using Bounds = std::numeric_limits<float>;
toReal_data(); toReal_data();
if (std::numeric_limits<float>::has_infinity) { const QString C(QStringLiteral("C"));
double huge = std::numeric_limits<float>::infinity(); if (Bounds::has_infinity) {
QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge; double huge = Bounds::infinity();
QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge; QTest::newRow("C inf") << C << QString("inf") << true << huge;
QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge; QTest::newRow("C +inf") << C << QString("+inf") << true << +huge;
QTest::newRow("C -inf") << C << QString("-inf") << true << -huge;
// Overflow float, but not double: // Overflow float, but not double:
QTest::newRow("C big") << QString("C") << QString("3.5e38") << false << huge; QTest::newRow("C big") << C << QString("3.5e38") << false << huge;
QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << false << -huge; QTest::newRow("C -big") << C << QString("-3.5e38") << false << -huge;
// Overflow double, too: // Overflow double, too:
QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge; QTest::newRow("C huge") << C << QString("2e308") << false << huge;
QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge; QTest::newRow("C -huge") << C << QString("-2e308") << false << -huge;
} }
if (std::numeric_limits<float>::has_quiet_NaN) if (Bounds::has_quiet_NaN)
QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << double(std::numeric_limits<float>::quiet_NaN()); QTest::newRow("C qnan") << C << QString("NaN") << true << double(Bounds::quiet_NaN());
// Minimal float: shouldn't underflow
QTest::newRow("C float min")
<< C << QLocale::c().toString(Bounds::denorm_min()) << true << double(Bounds::denorm_min());
QTest::newRow("C float -min")
<< C << QLocale::c().toString(-Bounds::denorm_min()) << true << -double(Bounds::denorm_min());
// Underflow float, but not double: // Underflow float, but not double:
QTest::newRow("C small") << QString("C") << QString("1e-45") << false << 0.; QTest::newRow("C small") << C << QString("7e-46") << false << 0.;
QTest::newRow("C -small") << QString("C") << QString("-1e-45") << false << 0.; QTest::newRow("C -small") << C << QString("-7e-46") << false << 0.;
using Double = std::numeric_limits<double>;
QTest::newRow("C double min")
<< C << QLocale::c().toString(Double::denorm_min()) << false << 0.0;
QTest::newRow("C double -min")
<< C << QLocale::c().toString(-Double::denorm_min()) << false << 0.0;
// Underflow double, too: // Underflow double, too:
QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.; QTest::newRow("C tiny") << C << QString("2e-324") << false << 0.;
QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.; QTest::newRow("C -tiny") << C << QString("-2e-324") << false << 0.;
} }
void tst_QLocale::stringToFloat() void tst_QLocale::stringToFloat()

View File

@ -3284,11 +3284,46 @@ void tst_QImage::metadataPassthrough()
QCOMPARE(mirrored.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(mirrored.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(mirrored.devicePixelRatio(), a.devicePixelRatio()); QCOMPARE(mirrored.devicePixelRatio(), a.devicePixelRatio());
QTransform t;
t.rotate(90);
QImage rotated = a.transformed(t);
QCOMPARE(rotated.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
QCOMPARE(rotated.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(rotated.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(rotated.devicePixelRatio(), a.devicePixelRatio());
QImage swapped = a.rgbSwapped(); QImage swapped = a.rgbSwapped();
QCOMPARE(swapped.text(QStringLiteral("Test")), a.text(QStringLiteral("Test"))); QCOMPARE(swapped.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
QCOMPARE(swapped.dotsPerMeterX(), a.dotsPerMeterX()); QCOMPARE(swapped.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(swapped.dotsPerMeterY(), a.dotsPerMeterY()); QCOMPARE(swapped.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio()); QCOMPARE(swapped.devicePixelRatio(), a.devicePixelRatio());
QImage converted = a.convertToFormat(QImage::Format_RGB32);
QCOMPARE(converted.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
QCOMPARE(converted.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(converted.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(converted.devicePixelRatio(), a.devicePixelRatio());
QImage copied = a.copy(0, 0, a.width() / 2, a.height() / 2);
QCOMPARE(copied.text(QStringLiteral("Test")), a.text(QStringLiteral("Test")));
QCOMPARE(copied.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(copied.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(copied.devicePixelRatio(), a.devicePixelRatio());
QImage alphaMask = a.createAlphaMask();
QCOMPARE(alphaMask.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(alphaMask.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(alphaMask.devicePixelRatio(), a.devicePixelRatio());
QImage heuristicMask = a.createHeuristicMask();
QCOMPARE(heuristicMask.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(heuristicMask.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(heuristicMask.devicePixelRatio(), a.devicePixelRatio());
QImage maskFromColor = a.createMaskFromColor(qRgb(0, 0, 0));
QCOMPARE(maskFromColor.dotsPerMeterX(), a.dotsPerMeterX());
QCOMPARE(maskFromColor.dotsPerMeterY(), a.dotsPerMeterY());
QCOMPARE(maskFromColor.devicePixelRatio(), a.devicePixelRatio());
} }
void tst_QImage::pixelColor() void tst_QImage::pixelColor()

View File

@ -121,6 +121,7 @@ private slots:
void copy(); void copy();
void deepCopyPreservesDpr(); void deepCopyPreservesDpr();
void dprPassthrough();
void depthOfNullObjects(); void depthOfNullObjects();
void transformed(); void transformed();
@ -1169,6 +1170,39 @@ void tst_QPixmap::deepCopyPreservesDpr()
QCOMPARE(dest.devicePixelRatio(), dpr); QCOMPARE(dest.devicePixelRatio(), dpr);
} }
void tst_QPixmap::dprPassthrough()
{
const qreal dpr = 2;
QPixmap src(32, 32);
src.setDevicePixelRatio(dpr);
src.fill(Qt::transparent);
QCOMPARE(src.devicePixelRatio(), dpr);
QImage img = src.toImage();
QCOMPARE(img.devicePixelRatio(), dpr);
QPixmap pm(1, 1);
pm.convertFromImage(img);
QCOMPARE(pm.devicePixelRatio(), dpr);
QBitmap heuristicMask = src.createHeuristicMask();
QCOMPARE(heuristicMask.devicePixelRatio(), dpr);
QBitmap maskFromColor = src.createMaskFromColor(Qt::white);
QCOMPARE(maskFromColor.devicePixelRatio(), dpr);
QBitmap mask = src.mask();
QCOMPARE(mask.devicePixelRatio(), dpr);
QPixmap scaled = src.scaled(16, 16);
QCOMPARE(scaled.devicePixelRatio(), dpr);
QTransform t;
t.rotate(90);
QPixmap transformed = src.transformed(t);
QCOMPARE(transformed.devicePixelRatio(), dpr);
}
void tst_QPixmap::depthOfNullObjects() void tst_QPixmap::depthOfNullObjects()
{ {
QBitmap b1; QBitmap b1;

View File

@ -345,6 +345,8 @@ void tst_QBrush::gradientPresets()
QGradient invalidPreset(QGradient::Preset(-1)); QGradient invalidPreset(QGradient::Preset(-1));
QCOMPARE(invalidPreset.type(), QGradient::NoGradient); QCOMPARE(invalidPreset.type(), QGradient::NoGradient);
QBrush brush(invalidPreset);
QCOMPARE(brush.style(), Qt::NoBrush);
} }
void fill(QPaintDevice *pd) { void fill(QPaintDevice *pd) {

View File

@ -244,7 +244,6 @@ void tst_qmake::simple_app_versioned()
QVERIFY2(QFile::exists(pdbFilePath), qPrintable(pdbFilePath)); QVERIFY2(QFile::exists(pdbFilePath), qPrintable(pdbFilePath));
QVERIFY(test_compiler.make(buildDir, "install")); QVERIFY(test_compiler.make(buildDir, "install"));
QString installedPdbFilePath = installDir + '/' + targetBase + ".pdb"; QString installedPdbFilePath = installDir + '/' + targetBase + ".pdb";
QEXPECT_FAIL("", "QTBUG-74265", Continue);
QVERIFY2(QFile::exists(installedPdbFilePath), qPrintable(installedPdbFilePath)); QVERIFY2(QFile::exists(installedPdbFilePath), qPrintable(installedPdbFilePath));
} }
@ -252,10 +251,8 @@ void tst_qmake::simple_app_versioned()
QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version)); QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version));
QVERIFY(test_compiler.makeDistClean(buildDir)); QVERIFY(test_compiler.makeDistClean(buildDir));
QVERIFY(!test_compiler.exists(destDir, "simple app", Exe, version)); QVERIFY(!test_compiler.exists(destDir, "simple app", Exe, version));
if (checkPdb) { if (checkPdb)
QEXPECT_FAIL("", "QTBUG-74265", Continue);
QVERIFY(!QFile::exists(pdbFilePath)); QVERIFY(!QFile::exists(pdbFilePath));
}
QVERIFY(test_compiler.removeMakefile(buildDir)); QVERIFY(test_compiler.removeMakefile(buildDir));
} }