diff options
Diffstat (limited to 'src/gui')
| -rw-r--r-- | src/gui/accessible/linux/qspimatchrulematcher.cpp | 9 | ||||
| -rw-r--r-- | src/gui/configure.cmake | 33 | ||||
| -rw-r--r-- | src/gui/image/qpaintengine_pic.cpp | 17 | ||||
| -rw-r--r-- | src/gui/image/qpicture.cpp | 6 | ||||
| -rw-r--r-- | src/gui/image/qpicture_p.h | 1 | ||||
| -rw-r--r-- | src/gui/image/qppmhandler.cpp | 69 | ||||
| -rw-r--r-- | src/gui/painting/qcolorspace.cpp | 6 | ||||
| -rw-r--r-- | src/gui/painting/qpainter.cpp | 17 |
8 files changed, 123 insertions, 35 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 c43d133dd1e..680bdef3ac9 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -1205,13 +1205,13 @@ QByteArray QColorSpace::iccProfile() const */ QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile) { - // Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else - const QByteArray ownedIccProfile(iccProfile.nullTerminated()); QColorSpace colorSpace; + // Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else + QByteArray ownedIccProfile = iccProfile.nullTerminated(); if (QIcc::fromIccProfile(ownedIccProfile, &colorSpace)) return colorSpace; colorSpace.detach(); - colorSpace.d_ptr->iccProfile = ownedIccProfile; + colorSpace.d_ptr->iccProfile = std::move(ownedIccProfile); return colorSpace; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index a3f9f069b69..2b6a8a858f9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6474,8 +6474,9 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO and height (on both 1x and 2x displays), and produces high-resolution output on 2x displays. - The \a position offset is always in the painter coordinate system, - indepentent of display devicePixelRatio. + The \a position offset is provided in the device independent pixels + relative to the top-left corner of the \a rectangle. The \a position + can be used to align the repeating pattern inside the \a rectangle. \sa drawPixmap() */ @@ -6497,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) @@ -6579,8 +6580,12 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo (\a{x}, \a{y}) specifies the top-left point in the paint device that is to be drawn onto; with the given \a width and \a - height. (\a{sx}, \a{sy}) specifies the top-left point in the \a - pixmap that is to be drawn; this defaults to (0, 0). + height. + + (\a{sx}, \a{sy}) specifies the origin inside the specified rectangle + where the pixmap will be drawn. The origin position is specified in + the device independent pixels relative to (\a{x}, \a{y}). This defaults + to (0, 0). */ #ifndef QT_NO_PICTURE |
