summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/linux/qspimatchrulematcher.cpp9
-rw-r--r--src/gui/configure.cmake33
-rw-r--r--src/gui/image/qpaintengine_pic.cpp17
-rw-r--r--src/gui/image/qpicture.cpp6
-rw-r--r--src/gui/image/qpicture_p.h1
-rw-r--r--src/gui/image/qppmhandler.cpp69
-rw-r--r--src/gui/painting/qcolorspace.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp4
-rw-r--r--src/gui/text/qfont.cpp4
9 files changed, 115 insertions, 30 deletions
diff --git a/src/gui/accessible/linux/qspimatchrulematcher.cpp b/src/gui/accessible/linux/qspimatchrulematcher.cpp
index d7047ad3e0e..48357f7ae63 100644
--- a/src/gui/accessible/linux/qspimatchrulematcher.cpp
+++ b/src/gui/accessible/linux/qspimatchrulematcher.cpp
@@ -23,11 +23,11 @@ QSpiMatchRuleMatcher::QSpiMatchRuleMatcher(const QSpiMatchRule &matchRule)
m_interfaceMatchType(matchRule.interfaceMatchType)
{
// extract roles encoded in bitset stored in multiple 32 bit integers
- std::unordered_set<AtspiRole> atSpiRoles;
- for (int i = 0; i < matchRule.roles.size(); ++i) {
+ for (qsizetype i = 0; i < matchRule.roles.size(); ++i) {
+ const auto role = matchRule.roles.at(i);
for (int j = 0; j < 32; j++) {
- if (matchRule.roles.at(i) & (1 << j)) {
- const int atspiRole = i * 32 + j;
+ if (role & (1 << j)) {
+ const auto atspiRole = i * 32 + j;
if (atspiRole < ATSPI_ROLE_LAST_DEFINED)
m_roles.insert(AtspiRole(atspiRole));
else
@@ -38,6 +38,7 @@ QSpiMatchRuleMatcher::QSpiMatchRuleMatcher(const QSpiMatchRule &matchRule)
}
// use qualified interface names to match what accessibleInterfaces() returns
+ m_interfaces.reserve(matchRule.interfaces.size());
for (const QString &ifaceName : matchRule.interfaces)
m_interfaces.push_back("org.a11y.atspi."_L1 + ifaceName);
}
diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
index dac2d072e42..b14f7e74ad2 100644
--- a/src/gui/configure.cmake
+++ b/src/gui/configure.cmake
@@ -30,6 +30,7 @@ set_property(CACHE INPUT_libpng PROPERTY STRINGS undefined no qt system)
#### Libraries
qt_set01(X11_SUPPORTED LINUX OR HPUX OR FREEBSD OR NETBSD OR OPENBSD OR SOLARIS OR
HURD)
+qt_feature_vcpkg_scope(gui)
qt_find_package(ATSPI2 MODULE PROVIDED_TARGETS PkgConfig::ATSPI2 MODULE_NAME gui QMAKE_LIB atspi)
qt_find_package(DirectFB PROVIDED_TARGETS PkgConfig::DirectFB MODULE_NAME gui QMAKE_LIB directfb)
qt_find_package(Libdrm MODULE PROVIDED_TARGETS Libdrm::Libdrm MODULE_NAME gui QMAKE_LIB drm)
@@ -39,15 +40,26 @@ qt_find_package(PlatformGraphics
qt_find_package(EGL MODULE PROVIDED_TARGETS EGL::EGL MODULE_NAME gui QMAKE_LIB egl)
qt_find_package(WrapSystemFreetype 2.2.0 MODULE
- PROVIDED_TARGETS WrapSystemFreetype::WrapSystemFreetype MODULE_NAME gui QMAKE_LIB freetype)
+ PROVIDED_TARGETS WrapSystemFreetype::WrapSystemFreetype MODULE_NAME gui QMAKE_LIB freetype
+ VCPKG_PORT freetype
+ VCPKG_ADD_TO_FEATURE freetype
+)
if(QT_FEATURE_system_zlib)
qt_add_qmake_lib_dependency(freetype zlib)
endif()
-qt_find_package(Fontconfig PROVIDED_TARGETS Fontconfig::Fontconfig MODULE_NAME gui QMAKE_LIB fontconfig)
+qt_find_package(Fontconfig PROVIDED_TARGETS Fontconfig::Fontconfig MODULE_NAME gui
+ QMAKE_LIB fontconfig
+ VCPKG_PORT fontconfig
+ VCPKG_ADD_TO_FEATURE fontconfig
+ VCPKG_PLATFORM "linux"
+)
qt_add_qmake_lib_dependency(fontconfig freetype)
qt_find_package(gbm MODULE PROVIDED_TARGETS gbm::gbm MODULE_NAME gui QMAKE_LIB gbm)
qt_find_package(WrapSystemHarfbuzz 2.6.0 MODULE
- PROVIDED_TARGETS WrapSystemHarfbuzz::WrapSystemHarfbuzz MODULE_NAME gui QMAKE_LIB harfbuzz)
+ PROVIDED_TARGETS WrapSystemHarfbuzz::WrapSystemHarfbuzz MODULE_NAME gui QMAKE_LIB harfbuzz
+ VCPKG_PORT harfbuzz
+ VCPKG_ADD_TO_FEATURE harfbuzz
+)
qt_find_package(Libinput MODULE
PROVIDED_TARGETS Libinput::Libinput MODULE_NAME gui QMAKE_LIB libinput)
qt_find_package_extend_sbom(TARGETS Libinput::Libinput
@@ -61,11 +73,20 @@ qt_find_package_extend_sbom(TARGETS Libinput::Libinput
"Copyright © 2013-2015 Red Hat, Inc."
)
qt_find_package(WrapSystemJpeg MODULE
- PROVIDED_TARGETS WrapSystemJpeg::WrapSystemJpeg MODULE_NAME gui QMAKE_LIB libjpeg)
+ PROVIDED_TARGETS WrapSystemJpeg::WrapSystemJpeg MODULE_NAME gui QMAKE_LIB libjpeg
+ VCPKG_PORT libjpeg-turbo
+ VCPKG_ADD_TO_FEATURE jpeg
+)
qt_find_package(WrapSystemMd4c MODULE
- PROVIDED_TARGETS WrapSystemMd4c::WrapSystemMd4c MODULE_NAME gui QMAKE_LIB libmd4c)
+ PROVIDED_TARGETS WrapSystemMd4c::WrapSystemMd4c MODULE_NAME gui QMAKE_LIB libmd4c
+ VCPKG_PORT md4c
+ VCPKG_ADD_TO_FEATURE textmarkdownreader
+)
qt_find_package(WrapSystemPNG MODULE
- PROVIDED_TARGETS WrapSystemPNG::WrapSystemPNG MODULE_NAME gui QMAKE_LIB libpng)
+ PROVIDED_TARGETS WrapSystemPNG::WrapSystemPNG MODULE_NAME gui QMAKE_LIB libpng
+ VCPKG_PORT libpng
+ VCPKG_ADD_TO_FEATURE png
+)
if(QT_FEATURE_system_zlib)
qt_add_qmake_lib_dependency(libpng zlib)
endif()
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index ba4888cef75..b151c3b2d18 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -31,6 +31,7 @@ public:
QDataStream s;
QPainter *pt;
QPicturePrivate *pic_d;
+ bool sizeLimitExceeded = false;
};
QPicturePaintEngine::QPicturePaintEngine()
@@ -68,6 +69,7 @@ bool QPicturePaintEngine::begin(QPaintDevice *pd)
d->s.setVersion(d->pic_d->formatMajor);
d->pic_d->pictb.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ d->sizeLimitExceeded = false;
d->s.writeRawData(qt_mfhdr_tag, 4);
d->s << (quint16) 0 << (quint16) d->pic_d->formatMajor << (quint16) d->pic_d->formatMinor;
d->s << (quint8) QPicturePrivate::PdcBegin << (quint8) sizeof(qint32);
@@ -109,7 +111,7 @@ bool QPicturePaintEngine::end()
d->s << cs; // write checksum
d->pic_d->pictb.close();
setActive(false);
- return true;
+ return !d->sizeLimitExceeded;
}
#define SERIALIZE_CMD(c) \
@@ -286,6 +288,19 @@ void QPicturePaintEngine::updateRenderHints(QPainter::RenderHints hints)
void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr)
{
Q_D(QPicturePaintEngine);
+
+ constexpr int sizeLimit = std::numeric_limits<int>::max() - 8; // Leave room for ending bytes
+ if (d->sizeLimitExceeded || d->pic_d->pictb.pos() > sizeLimit) {
+ d->pic_d->trecs--; // Remove last command added, started by SERIALIZE_CMD
+ d->pic_d->pictb.seek(pos - 2);
+ d->pic_d->pictbData.resize(pos - 2);
+ if (!d->sizeLimitExceeded) {
+ d->sizeLimitExceeded = true;
+ qWarning("QPicture: size limit exceeded, will be truncated");
+ }
+ return;
+ }
+
int newpos = d->pic_d->pictb.pos(); // new position
int length = newpos - pos;
QRectF br(r);
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index ac0525d7abf..db2a5fd9ba9 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -970,7 +970,8 @@ QPicture& QPicture::operator=(const QPicture &p)
Constructs a QPicturePrivate
*/
QPicturePrivate::QPicturePrivate()
- : in_memory_only(false)
+ : pictb(&pictbData),
+ in_memory_only(false)
{
}
@@ -980,7 +981,8 @@ QPicturePrivate::QPicturePrivate()
Copy-Constructs a QPicturePrivate. Needed when detaching.
*/
QPicturePrivate::QPicturePrivate(const QPicturePrivate &other)
- : trecs(other.trecs),
+ : pictb(&pictbData),
+ trecs(other.trecs),
formatOk(other.formatOk),
formatMinor(other.formatMinor),
brect(other.brect),
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index c512f49320b..1d8142f44b7 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -113,6 +113,7 @@ public:
bool checkFormat();
void resetFormat();
+ QByteArray pictbData;
QBuffer pictb;
int trecs;
bool formatOk;
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index a0a1dcdaca9..8a413ded95e 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -123,8 +123,8 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
break;
case '2': // ascii PGM
case '5': // raw PGM
- nbits = 8;
- format = QImage::Format_Grayscale8;
+ nbits = mcc <= std::numeric_limits<uint8_t>::max() ? 8 : 16;
+ format = mcc <= std::numeric_limits<uint8_t>::max() ? QImage::Format_Grayscale8 : QImage::Format_Grayscale16;
break;
case '3': // ascii PPM
case '6': // raw PPM
@@ -175,20 +175,20 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
}
delete[] buf24;
- } else if (nbits == 8 && mcc > 255) { // type 5 16bit
- pbm_bpl = 2*w;
+ } else if (nbits == 16) { // type 5 16bit
+ pbm_bpl = sizeof(uint16_t)*w;
uchar *buf16 = new uchar[pbm_bpl];
for (y=0; y<h; y++) {
if (device->read((char *)buf16, pbm_bpl) != pbm_bpl) {
delete[] buf16;
return false;
}
- uchar *p = outImage->scanLine(y);
- uchar *end = p + w;
- uchar *b = buf16;
+ uint16_t *p = reinterpret_cast<uint16_t *>(outImage->scanLine(y));
+ uint16_t *end = p + w;
+ uint16_t *b = reinterpret_cast<uint16_t *>(buf16);
while (p < end) {
- *p++ = (b[0] << 8 | b[1]) * 255 / mcc;
- b += 2;
+ *p++ = qFromBigEndian(*b) * std::numeric_limits<uint16_t>::max() / mcc;
+ b++;
}
}
delete[] buf16;
@@ -225,13 +225,25 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
*p++ = b;
}
} else if (nbits == 8) {
- if (mcc == 255) {
+ if (mcc == std::numeric_limits<uint8_t>::max()) {
while (n-- && ok) {
*p++ = read_pbm_int(device, &ok);
}
} else {
while (n-- && ok) {
- *p++ = (read_pbm_int(device, &ok) & 0xffff) * 255 / mcc;
+ *p++ = (read_pbm_int(device, &ok) & 0xffff) * std::numeric_limits<uint8_t>::max() / mcc;
+ }
+ }
+ } else if (nbits == 16) {
+ uint16_t* data = reinterpret_cast<uint16_t*>(p);
+ qsizetype numPixel = n/2;
+ if (mcc == std::numeric_limits<uint16_t>::max()) {
+ while (numPixel-- && ok) {
+ *data++ = read_pbm_int(device, &ok);
+ }
+ } else {
+ while (numPixel-- && ok) {
+ *data++ = (read_pbm_int(device, &ok) & 0xffff) * std::numeric_limits<uint16_t>::max() / mcc;
}
}
} else { // 32 bits
@@ -280,7 +292,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, QByteArra
if (format == "pbm") {
image = image.convertToFormat(QImage::Format_Mono);
} else if (gray) {
- image = image.convertToFormat(QImage::Format_Grayscale8);
+ image = image.depth() <= 8 ? image.convertToFormat(QImage::Format_Grayscale8) : image.convertToFormat(QImage::Format_Grayscale16);
} else {
switch (image.format()) {
case QImage::Format_Mono:
@@ -388,6 +400,34 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, QByteArra
delete [] buf;
break;
}
+ case 16: {
+ str.insert(1, gray ? '5' : '6');
+ str.append("65535\n");
+ if (out->write(str, str.size()) != str.size())
+ return false;
+ qsizetype bpl = sizeof(uint16_t) * qsizetype(w) * (gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ for (uint y=0; y<h; y++) {
+ const uint16_t *b = reinterpret_cast<const uint16_t *>(image.constScanLine(y));
+ uint16_t *p = reinterpret_cast<uint16_t *>(buf);
+ uint16_t *end = reinterpret_cast<uint16_t *>(buf + bpl);
+ if (gray) {
+ while (p < end)
+ *p++ = qToBigEndian(*b++);
+ } else {
+ while (p < end) {
+ uchar color = qToBigEndian(*b++);
+ *p++ = color;
+ *p++ = color;
+ *p++ = color;
+ }
+ }
+ if (bpl != (qsizetype)out->write((char*)buf, bpl))
+ return false;
+ }
+ delete [] buf;
+ break;
+ }
case 32: {
str.insert(1, '6');
@@ -530,7 +570,10 @@ QVariant QPpmHandler::option(ImageOption option) const
break;
case '2': // ascii PGM
case '5': // raw PGM
- format = QImage::Format_Grayscale8;
+ if (mcc <= std::numeric_limits<uint8_t>::max())
+ format = QImage::Format_Grayscale8;
+ else
+ format = QImage::Format_Grayscale16;
break;
case '3': // ascii PPM
case '6': // raw PPM
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index 9149971b999..680bdef3ac9 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -1205,9 +1205,9 @@ QByteArray QColorSpace::iccProfile() const
*/
QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
{
+ QColorSpace colorSpace;
// Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else
QByteArray ownedIccProfile = iccProfile.nullTerminated();
- QColorSpace colorSpace;
if (QIcc::fromIccProfile(ownedIccProfile, &colorSpace))
return colorSpace;
colorSpace.detach();
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 4c5414f177e..2b6a8a858f9 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6498,8 +6498,8 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()");
#endif
- qreal sw = pixmap.width();
- qreal sh = pixmap.height();
+ const qreal sw = pixmap.width() / pixmap.devicePixelRatio();
+ const qreal sh = pixmap.height() / pixmap.devicePixelRatio();
qreal sx = sp.x();
qreal sy = sp.y();
if (sx < 0)
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 7ffb688c035..2b2f2a27fcd 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -1829,6 +1829,8 @@ bool QFont::operator==(const QFont &f) const
*/
bool QFont::operator<(const QFont &f) const
{
+ // NB: This operator actually implements greater-than, because it consistently
+ // swaps LHS (should be *this, but is `f`) and RHS (should be `f`, but is *this)
if (f.d == d) return false;
// the < operator for fontdefs ignores point sizes.
const QFontDef &r1 = f.d->request;
@@ -2199,7 +2201,7 @@ QString QFont::toString() const
fontDescription += comma + QString::number(sortedFeatures.size());
for (const auto &[tag, value] : std::as_const(sortedFeatures).asKeyValueRange())
- fontDescription += comma + tag.toString() + u'=' + QString::number(value);
+ fontDescription += comma + QLatin1StringView{tag.toString()} + u'=' + QString::number(value);
return fontDescription;
}