diff options
Diffstat (limited to 'src/gui')
76 files changed, 2615 insertions, 1090 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 776320a517..f7a4a53716 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -97,6 +97,15 @@ QT_BEGIN_NAMESPACE Accessibility, and the Unix/X11 AT-SPI standard. Other backends can be supported using QAccessibleBridge. + In the Unix/X11 AT-SPI implementation, applications become accessible + when two conditions are met: + \list + \li org.a11y.Status.IsEnabled DBus property is true + \li org.a11y.Status.ScreenReaderEnabled DBus property is true + \endlist + An alternative to setting the DBus AT-SPI properties is to set + the QT_LINUX_ACCESSIBILITY_ALWAYS_ON environment variable. + In addition to QAccessible's static functions, Qt offers one generic interface, QAccessibleInterface, that can be used to wrap all widgets and objects (e.g., QPushButton). This single diff --git a/src/gui/doc/images/qpixelformat-argb32buffer.png b/src/gui/doc/images/qpixelformat-argb32buffer.png Binary files differnew file mode 100644 index 0000000000..5888f0b03d --- /dev/null +++ b/src/gui/doc/images/qpixelformat-argb32buffer.png diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3998bbf3ff..dda8894722 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4508,4 +4508,273 @@ QDebug operator<<(QDebug dbg, const QImage &i) \sa textKeys() */ +static const QPixelFormat pixelformats[] = { + //QImage::Format_Invalid: + QPixelFormat(), + //QImage::Format_Mono: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_MonoLSB: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_Indexed8: + QPixelFormat(QPixelFormat::Indexed, + /*RED*/ 8, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB16: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8565_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB666: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB6666_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 6, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB555: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8555_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB444: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB4444_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 4, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBX8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), +}; +Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats); + +/*! + Returns the QImage::Format as a QPixelFormat +*/ +QPixelFormat QImage::pixelFormat() const Q_DECL_NOTHROW +{ + return toPixelFormat(format()); +} + +/*! + Converts \a format into a QPixelFormat +*/ +QPixelFormat QImage::toPixelFormat(QImage::Format format) Q_DECL_NOTHROW +{ + Q_ASSERT(static_cast<int>(format) < NImageFormats); + return pixelformats[format]; +} + +/*! + Converts \a format into a QImage::Format +*/ +QImage::Format QImage::toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW +{ + for (int i = 0; i < NImageFormats; i++) { + if (format == pixelformats[i]) + return Format(i); + } + return Format_Invalid; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4326d5dbbc..365a7873a4 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -45,6 +45,7 @@ #include <QtGui/qtransform.h> #include <QtGui/qpaintdevice.h> #include <QtGui/qrgb.h> +#include <QtGui/qpixelformat.h> #include <QtCore/qbytearray.h> #include <QtCore/qrect.h> #include <QtCore/qstring.h> @@ -305,6 +306,10 @@ public: QString text(const QString &key = QString()) const; void setText(const QString &key, const QString &value); + QPixelFormat pixelFormat() const Q_DECL_NOTHROW; + static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW; + static QImage::Format toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW; + #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED inline QString text(const char* key, const char* lang=0) const; QT_DEPRECATED inline QList<QImageTextKeyLang> textList() const; diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 629a7c9b69..cf61d2d84b 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -2176,7 +2176,11 @@ void qInitImageConversions() #ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2 extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags); inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2; - return; + + extern void convert_RGB888_to_RGB32_mips_dspr2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + qimage_converter_map[QImage::Format::RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_mips_dspr2; + qimage_converter_map[QImage::Format::RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_mips_dspr2; + qimage_converter_map[QImage::Format::RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_mips_dspr2; #endif } diff --git a/src/gui/image/qimage_mips_dspr2.cpp b/src/gui/image/qimage_mips_dspr2.cpp index a1c40a16df..f61a2262d2 100644 --- a/src/gui/image/qimage_mips_dspr2.cpp +++ b/src/gui/image/qimage_mips_dspr2.cpp @@ -66,4 +66,24 @@ bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConve return true; } +extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(uint *dst, const uchar *src, int len); + +void convert_RGB888_to_RGB32_mips_dspr2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB888); + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uchar *src_data = (const uchar*) src->data; + quint32 *dest_data = (quint32*) dest->data; + + for (int i = 0; i < src->height; ++i) { + qt_convert_rgb888_to_rgb32_mips_dspr2_asm(dest_data, src_data, src->width); + src_data += src->bytes_per_line; + dest_data = (quint32*) ((uchar*) dest_data + dest->bytes_per_line); + } +} + QT_END_NAMESPACE + diff --git a/src/gui/image/qimage_mips_dspr2_asm.S b/src/gui/image/qimage_mips_dspr2_asm.S index 1f03b72dd4..df626586dc 100644 --- a/src/gui/image/qimage_mips_dspr2_asm.S +++ b/src/gui/image/qimage_mips_dspr2_asm.S @@ -205,3 +205,95 @@ LEAF_MIPS_DSPR2(premultiply_argb_inplace_mips_asm) END(premultiply_argb_inplace_mips_asm) + +LEAF_MIPS_DSPR2(qt_convert_rgb888_to_rgb32_mips_dspr2_asm) +/* + * Parameters: + * a0 - dst *a8r8g8b8 + * a1 - src *r8g8b8 + * a2 - len + * + * R G B r g b R G B r g b R G B r g b . . . -- input + * ------- ------- ------- ------- ------- + * _ R G B _ r g b _ R G B _ r g b _ R G . . -- output + * + * Register usage: + * a2 - tail (len % 4) == (len & 0x3) + * t0 - batches (len / 4) == (len >> 2) + * t1-t7, s1-s3 - temporary + */ + + srl t0, a2, 2 /* batches = len / 4 */ + andi a2, a2, 0x3 /* tail = len % 4 */ + + beqz t0, 5f /* if !batches: tail */ + lui t7, 0xff00 /* [FF 00 00 00] */ + SAVE_REGS_ON_STACK 8, s1, s2, s3, s0, v0, v1 + +1: pref 4, 0 (a1) /* hint: read-streamed */ + pref 5, 0 (a0) /* hint: prepare-write */ + addiu t0, t0, -1 /* batches-- */ + + lbu t1, 0 (a1) /* [__ __ __ R1] */ + lbu t2, 1 (a1) /* [__ __ __ G1] */ + lbu t3, 2 (a1) /* [__ __ __ B1] */ + + lbu t4, 3 (a1) /* [__ __ __ r2] */ + lbu t5, 4 (a1) /* [__ __ __ g2] */ + lbu t6, 5 (a1) /* [__ __ __ b2] */ + + lbu s1, 6 (a1) /* [__ __ __ R3] */ + lbu s2, 7 (a1) /* [__ __ __ G3] */ + lbu s3, 8 (a1) /* [__ __ __ B3] */ + + lbu s0, 9 (a1) /* [__ __ __ r4] */ + lbu v0, 10 (a1) /* [__ __ __ g4] */ + lbu v1, 11 (a1) /* [__ __ __ b4] */ + + append t1, t2, 8 /* [__ __ R1 G1] */ + append t4, t5, 8 /* [__ __ r2 g2] */ + append s1, s2, 8 /* [__ __ R3 G3] */ + append s0, v0, 8 /* [__ __ r4 g4] */ + append t1, t3, 8 /* [__ R1 G1 B1] */ + append t4, t6, 8 /* [__ r2 g2 b2] */ + append s1, s3, 8 /* [__ R3 G4 B3] */ + append s0, v1, 8 /* [__ r4 g4 b4] */ + or t1, t1, t7 /* [FF R1 G1 B1] */ + or t4, t4, t7 /* [FF r2 g2 b2] */ + or s1, s1, t7 /* [FF R3 G3 B3] */ + or s0, s0, t7 /* [FF r4 g4 b4] */ + + sw t1, 0 (a0) + sw t4, 4 (a0) + sw s1, 8 (a0) + sw s0, 12 (a0) + + addiu a1, a1, 12 /* src += 4*3 */ + bnez t0, 1b /* if batches: loop */ + addiu a0, a0, 16 /* dst += 4 */ + + RESTORE_REGS_FROM_STACK 8, s1, s2, s3, s0, v0, v1 + + /* handle remaining "tail" (a2) items */ +5: beqz a2, 0f + lui t0, 0xff00 /* [FF __ __ __] */ + +1: lbu t1, 0 (a1) /* [__ __ __ RR] */ + lbu t2, 1 (a1) /* [__ __ __ GG] */ + lbu t3, 2 (a1) /* [__ __ __ BB] */ + sll t1, t1, 16 /* [__ RR __ __] */ + sll t2, t2, 8 /* [__ __ GG __] */ + or t0, t0, t1 /* [FF RR __ __] */ + or t2, t2, t3 /* [__ __ GG BB] */ + addi a2, a2, -1 /* len-- */ + or t0, t0, t2 /* [FF RR GG BB] */ + addiu a1, a1, 3 /* src += 3 */ + sw t0, 0 (a0) + addiu a0, a0, 4 /* dst++ */ + bnez a2, 1b /* if tail: loop */ + lui t0, 0xff00 /* [FF __ __ __] */ + +0: jr ra + nop + +END(qt_convert_rgb888_to_rgb32_mips_dspr2_asm) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 091837b8b4..a291df29b6 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -125,7 +125,6 @@ #include <qimageiohandler.h> #include <qlist.h> #include <qrect.h> -#include <qset.h> #include <qsize.h> #include <qcolor.h> #include <qvariant.h> @@ -568,7 +567,7 @@ bool QImageReaderPrivate::initHandler() // check some preconditions if (!device || (!deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly))) { imageReaderError = QImageReader::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Invalid device")); + errorString = QImageReader::tr("Invalid device"); return false; } @@ -595,7 +594,7 @@ bool QImageReaderPrivate::initHandler() if (!device->isOpen()) { imageReaderError = QImageReader::FileNotFoundError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "File not found")); + errorString = QImageReader::tr("File not found"); file->setFileName(fileName); // restore the old file name return false; } @@ -604,7 +603,7 @@ bool QImageReaderPrivate::initHandler() // assign a handler if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat, ignoresFormatAndExtension)) == 0) { imageReaderError = QImageReader::UnsupportedFormatError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unsupported image format")); + errorString = QImageReader::tr("Unsupported image format"); return false; } return true; @@ -1191,7 +1190,7 @@ bool QImageReader::read(QImage *image) // read the image if (!d->handler->read(image)) { d->imageReaderError = InvalidDataError; - d->errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unable to read image data")); + d->errorString = QImageReader::tr("Unable to read image data"); return false; } @@ -1383,7 +1382,7 @@ QImageReader::ImageReaderError QImageReader::error() const QString QImageReader::errorString() const { if (d->errorString.isEmpty()) - return QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error")); + return QImageReader::tr("Unknown error"); return d->errorString; } @@ -1444,11 +1443,11 @@ QByteArray QImageReader::imageFormat(QIODevice *device) #ifndef QT_NO_IMAGEFORMATPLUGIN void supportedImageHandlerFormats(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result); + QList<QByteArray> *result); void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result); + QList<QByteArray> *result); #endif /*! @@ -1481,7 +1480,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QList<QByteArray> QImageReader::supportedImageFormats() { - QSet<QByteArray> formats; + QList<QByteArray> formats; for (int i = 0; i < _qt_NumFormats; ++i) formats << _qt_BuiltInFormats[i].extension; @@ -1489,12 +1488,9 @@ QList<QByteArray> QImageReader::supportedImageFormats() supportedImageHandlerFormats(loader(), QImageIOPlugin::CanRead, &formats); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedFormats; - for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it) - sortedFormats << *it; - - std::sort(sortedFormats.begin(), sortedFormats.end()); - return sortedFormats; + std::sort(formats.begin(), formats.end()); + formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); + return formats; } /*! @@ -1508,7 +1504,7 @@ QList<QByteArray> QImageReader::supportedImageFormats() QList<QByteArray> QImageReader::supportedMimeTypes() { - QSet<QByteArray> mimeTypes; + QList<QByteArray> mimeTypes; for (int i = 0; i < _qt_NumFormats; ++i) mimeTypes << _qt_BuiltInFormats[i].mimeType; @@ -1516,12 +1512,9 @@ QList<QByteArray> QImageReader::supportedMimeTypes() supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedMimeTypes; - for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) - sortedMimeTypes << *it; - - std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end()); - return sortedMimeTypes; + std::sort(mimeTypes.begin(), mimeTypes.end()); + mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); + return mimeTypes; } QT_END_NAMESPACE diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 4f3c93af7d..8409545079 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -43,6 +43,7 @@ #define QIMAGEREADER_H #include <QtCore/qbytearray.h> +#include <QtCore/qcoreapplication.h> #include <QtGui/qimage.h> #include <QtGui/qimageiohandler.h> @@ -58,6 +59,7 @@ class QStringList; class QImageReaderPrivate; class Q_GUI_EXPORT QImageReader { + Q_DECLARE_TR_FUNCTIONS(QImageReader) public: enum ImageReaderError { UnknownError, diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index c12dbb6544..c003e56573 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -279,7 +279,7 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq) compression = 0; gamma = 0.0; imageWriterError = QImageWriter::UnknownError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unknown error")); + errorString = QImageWriter::tr("Unknown error"); q = qq; } @@ -288,19 +288,19 @@ bool QImageWriterPrivate::canWriteHelper() { if (!device) { imageWriterError = QImageWriter::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device is not set")); + errorString = QImageWriter::tr("Device is not set"); return false; } if (!device->isOpen()) device->open(QIODevice::WriteOnly); if (!device->isWritable()) { imageWriterError = QImageWriter::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device not writable")); + errorString = QImageWriter::tr("Device not writable"); return false; } if (!handler && (handler = createWriteHandlerHelper(device, format)) == 0) { imageWriterError = QImageWriter::UnsupportedFormatError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format")); + errorString = QImageWriter::tr("Unsupported image format"); return false; } return true; @@ -667,7 +667,7 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const { if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == 0) { d->imageWriterError = QImageWriter::UnsupportedFormatError; - d->errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format")); + d->errorString = QImageWriter::tr("Unsupported image format"); return false; } @@ -678,7 +678,7 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const #ifndef QT_NO_IMAGEFORMATPLUGIN void supportedImageHandlerFormats(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result) + QList<QByteArray> *result) { typedef QMultiMap<int, QString> PluginKeyMap; typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; @@ -687,6 +687,7 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, const PluginKeyMapConstIterator cend = keyMap.constEnd(); int i = -1; QImageIOPlugin *plugin = 0; + result->reserve(result->size() + keyMap.size()); for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) { if (it.key() != i) { i = it.key(); @@ -694,13 +695,13 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, } const QByteArray key = it.value().toLatin1(); if (plugin && (plugin->capabilities(0, key) & cap) != 0) - result->insert(key); + result->append(key); } } void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result) + QList<QByteArray> *result) { QList<QJsonObject> metaDataList = loader->metaData(); @@ -713,7 +714,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, const int keyCount = keys.size(); for (int k = 0; k < keyCount; ++k) { if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0) - result->insert(mimeTypes.at(k).toString().toLatin1()); + result->append(mimeTypes.at(k).toString().toLatin1()); } } } @@ -746,7 +747,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, */ QList<QByteArray> QImageWriter::supportedImageFormats() { - QSet<QByteArray> formats; + QList<QByteArray> formats; #ifndef QT_NO_IMAGEFORMAT_BMP formats << "bmp"; #endif @@ -770,12 +771,9 @@ QList<QByteArray> QImageWriter::supportedImageFormats() supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedFormats; - for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it) - sortedFormats << *it; - - std::sort(sortedFormats.begin(), sortedFormats.end()); - return sortedFormats; + std::sort(formats.begin(), formats.end()); + formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); + return formats; } /*! @@ -788,7 +786,7 @@ QList<QByteArray> QImageWriter::supportedImageFormats() */ QList<QByteArray> QImageWriter::supportedMimeTypes() { - QSet<QByteArray> mimeTypes; + QList<QByteArray> mimeTypes; #ifndef QT_NO_IMAGEFORMAT_BMP mimeTypes << "image/bmp"; #endif @@ -814,12 +812,9 @@ QList<QByteArray> QImageWriter::supportedMimeTypes() supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedMimeTypes; - for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) - sortedMimeTypes << *it; - - std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end()); - return sortedMimeTypes; + std::sort(mimeTypes.begin(), mimeTypes.end()); + mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); + return mimeTypes; } QT_END_NAMESPACE diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index 3f5cf9c454..024ad3aa5a 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -43,6 +43,7 @@ #define QIMAGEWRITER_H #include <QtCore/qbytearray.h> +#include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> #include <QtGui/qimageiohandler.h> @@ -55,6 +56,7 @@ class QImage; class QImageWriterPrivate; class Q_GUI_EXPORT QImageWriter { + Q_DECLARE_TR_FUNCTIONS(QImageWriter) public: enum ImageWriterError { UnknownError, diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 5008b1982b..dfacf34097 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -856,6 +856,7 @@ bool QJpegHandlerPrivate::read(QImage *image) Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); +extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uchar *src, int len); QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) @@ -874,6 +875,9 @@ QJpegHandler::QJpegHandler() rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3; } #endif // QT_COMPILER_SUPPORTS_SSSE3 +#if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2) + rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_mips_dspr2_asm; +#endif // QT_COMPILER_SUPPORTS_DSPR2 } QJpegHandler::~QJpegHandler() diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index ec89b405b5..807746a26e 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -118,7 +118,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, */ const char *qt_mfhdr_tag = "QPIC"; // header tag -static const quint16 mfhdr_maj = 11; // major version # +static const quint16 mfhdr_maj = QDataStream::Qt_DefaultCompiledVersion; // major version # static const quint16 mfhdr_min = 0; // minor version # /*! diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index e9e4a1d818..2aeea6288b 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -68,11 +68,10 @@ HEADERS += \ kernel/qplatformservices.h \ kernel/qplatformscreenpageflipper.h \ kernel/qplatformsystemtrayicon.h \ - kernel/qplatformsessionmanager.h + kernel/qplatformsessionmanager.h \ + kernel/qpixelformat.h SOURCES += \ - kernel/qclipboard_qpa.cpp \ - kernel/qcursor_qpa.cpp \ kernel/qgenericpluginfactory.cpp \ kernel/qgenericplugin.cpp \ kernel/qwindowsysteminterface.cpp \ @@ -109,7 +108,6 @@ SOURCES += \ kernel/qinputmethod.cpp \ kernel/qkeysequence.cpp \ kernel/qkeymapper.cpp \ - kernel/qkeymapper_qpa.cpp \ kernel/qpalette.cpp \ kernel/qguivariant.cpp \ kernel/qscreen.cpp \ @@ -120,9 +118,10 @@ SOURCES += \ kernel/qplatformdialoghelper.cpp \ kernel/qplatformservices.cpp \ kernel/qplatformscreenpageflipper.cpp \ - kernel/qplatformsystemtrayicon_qpa.cpp \ + kernel/qplatformsystemtrayicon.cpp \ kernel/qplatformsessionmanager.cpp \ - kernel/qplatformmenu.cpp + kernel/qplatformmenu.cpp \ + kernel/qpixelformat.cpp contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { HEADERS += \ diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 3c2d36ce86..672eb9eb65 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -50,6 +50,10 @@ #include "qimage.h" #include "qtextcodec.h" +#include "private/qguiapplication_p.h" +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformclipboard.h> + QT_BEGIN_NAMESPACE /*! @@ -438,6 +442,12 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa setMimeData() */ +const QMimeData* QClipboard::mimeData(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + if (!clipboard->supportsMode(mode)) return 0; + return clipboard->mimeData(mode); +} /*! \fn void QClipboard::setMimeData(QMimeData *src, Mode mode) @@ -458,6 +468,13 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa mimeData() */ +void QClipboard::setMimeData(QMimeData* src, Mode mode) +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + if (!clipboard->supportsMode(mode)) return; + + clipboard->setMimeData(src,mode); +} /*! \fn void QClipboard::clear(Mode mode) @@ -472,7 +489,10 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \sa QClipboard::Mode, supportsSelection() */ - +void QClipboard::clear(Mode mode) +{ + setMimeData(0, mode); +} /*! Returns \c true if the clipboard supports mouse selection; otherwise @@ -527,6 +547,11 @@ bool QClipboard::ownsFindBuffer() const Returns \c true if the clipboard supports the clipboard mode speacified by \a mode; otherwise returns \c false. */ +bool QClipboard::supportsMode(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + return clipboard->supportsMode(mode); +} /*! \internal @@ -534,6 +559,11 @@ bool QClipboard::ownsFindBuffer() const Returns \c true if the clipboard supports the clipboard data speacified by \a mode; otherwise returns \c false. */ +bool QClipboard::ownsMode(Mode mode) const +{ + QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); + return clipboard->ownsMode(mode); +} /*! \internal diff --git a/src/gui/kernel/qclipboard_qpa.cpp b/src/gui/kernel/qclipboard_qpa.cpp deleted file mode 100644 index ff8a210cba..0000000000 --- a/src/gui/kernel/qclipboard_qpa.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qclipboard.h" - -#ifndef QT_NO_CLIPBOARD - -#include "qmimedata.h" -#include "private/qguiapplication_p.h" -#include <qpa/qplatformclipboard.h> -#include <qpa/qplatformintegration.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -void QClipboard::clear(Mode mode) -{ - setMimeData(0, mode); -} - -const QMimeData* QClipboard::mimeData(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - if (!clipboard->supportsMode(mode)) return 0; - return clipboard->mimeData(mode); -} - -void QClipboard::setMimeData(QMimeData* src, Mode mode) -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - if (!clipboard->supportsMode(mode)) return; - - clipboard->setMimeData(src,mode); -} - -bool QClipboard::supportsMode(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - return clipboard->supportsMode(mode); -} - -bool QClipboard::ownsMode(Mode mode) const -{ - QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - return clipboard->ownsMode(mode); -} - -#endif // QT_NO_CLIPBOARD - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index a33b264704..87774b2056 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -51,6 +51,9 @@ #include <private/qcursor_p.h> #include <qdebug.h> +#include <qpa/qplatformcursor.h> +#include <private/qguiapplication_p.h> + QT_BEGIN_NAMESPACE /*! @@ -172,6 +175,13 @@ QT_BEGIN_NAMESPACE \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal() */ +QPoint QCursor::pos(const QScreen *screen) +{ + if (screen) + if (const QPlatformCursor *cursor = screen->handle()->cursor()) + return cursor->pos(); + return QGuiApplicationPrivate::lastCursorPosition.toPoint(); +} /*! \fn QPoint QCursor::pos() @@ -191,7 +201,10 @@ QT_BEGIN_NAMESPACE \sa setPos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen() */ - +QPoint QCursor::pos() +{ + return QCursor::pos(QGuiApplication::primaryScreen()); +} /*! \fn void QCursor::setPos(QScreen *screen, int x, int y) @@ -214,6 +227,19 @@ QT_BEGIN_NAMESPACE \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal() */ +void QCursor::setPos(QScreen *screen, int x, int y) +{ + if (screen) { + if (QPlatformCursor *cursor = screen->handle()->cursor()) { + const QPoint pos = QPoint(x, y); + // Need to check, since some X servers generate null mouse move + // events, causing looping in applications which call setPos() on + // every mouse move event. + if (pos != cursor->pos()) + cursor->setPos(pos); + } + } +} /*! \fn void QCursor::setPos(int x, int y) @@ -226,6 +252,10 @@ QT_BEGIN_NAMESPACE \sa pos(), QWidget::mapFromGlobal(), QWidget::mapToGlobal(), QGuiApplication::primaryScreen() */ +void QCursor::setPos(int x, int y) +{ + QCursor::setPos(QGuiApplication::primaryScreen(), x, y); +} /*! \fn void QCursor::setPos (const QPoint &p) @@ -401,34 +431,6 @@ QCursor::QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) d = QCursorData::setBitmap(bitmap, mask, hotX, hotY); } -QCursorData *qt_cursorTable[Qt::LastCursor + 1]; -bool QCursorData::initialized = false; - -/*! \internal */ -void QCursorData::cleanup() -{ - if(!QCursorData::initialized) - return; - - for (int shape = 0; shape <= Qt::LastCursor; ++shape) { - // In case someone has a static QCursor defined with this shape - if (!qt_cursorTable[shape]->ref.deref()) - delete qt_cursorTable[shape]; - qt_cursorTable[shape] = 0; - } - QCursorData::initialized = false; -} - -/*! \internal */ -void QCursorData::initialize() -{ - if (QCursorData::initialized) - return; - for (int shape = 0; shape <= Qt::LastCursor; ++shape) - qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape); - QCursorData::initialized = true; -} - /*! Constructs a cursor with the default arrow shape. */ @@ -602,6 +604,73 @@ QDebug operator<<(QDebug dbg, const QCursor &c) } #endif +/***************************************************************************** + Internal QCursorData class + *****************************************************************************/ + +QCursorData *qt_cursorTable[Qt::LastCursor + 1]; +bool QCursorData::initialized = false; + +QCursorData::QCursorData(Qt::CursorShape s) + : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0) +{ +} + +QCursorData::~QCursorData() +{ + delete bm; + delete bmm; +} + +/*! \internal */ +void QCursorData::cleanup() +{ + if(!QCursorData::initialized) + return; + + for (int shape = 0; shape <= Qt::LastCursor; ++shape) { + // In case someone has a static QCursor defined with this shape + if (!qt_cursorTable[shape]->ref.deref()) + delete qt_cursorTable[shape]; + qt_cursorTable[shape] = 0; + } + QCursorData::initialized = false; +} + +/*! \internal */ +void QCursorData::initialize() +{ + if (QCursorData::initialized) + return; + for (int shape = 0; shape <= Qt::LastCursor; ++shape) + qt_cursorTable[shape] = new QCursorData((Qt::CursorShape)shape); + QCursorData::initialized = true; +} + +QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) +{ + if (!QCursorData::initialized) + QCursorData::initialize(); + if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { + qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); + QCursorData *c = qt_cursorTable[0]; + c->ref.ref(); + return c; + } + QCursorData *d = new QCursorData; + d->bm = new QBitmap(bitmap); + d->bmm = new QBitmap(mask); + d->cshape = Qt::BitmapCursor; + d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; + d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; + + return d; +} + +void QCursorData::update() +{ +} + QT_END_NAMESPACE #endif // QT_NO_CURSOR diff --git a/src/gui/kernel/qcursor_qpa.cpp b/src/gui/kernel/qcursor_qpa.cpp deleted file mode 100644 index 0b19a47c69..0000000000 --- a/src/gui/kernel/qcursor_qpa.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qcursor.h> -#include <qscreen.h> -#include <private/qcursor_p.h> -#include <qpa/qplatformcursor.h> -#include <private/qguiapplication_p.h> -#include <qbitmap.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -#ifndef QT_NO_CURSOR - -/***************************************************************************** - Internal QCursorData class - *****************************************************************************/ - -QCursorData::QCursorData(Qt::CursorShape s) - : ref(1), cshape(s), bm(0), bmm(0), hx(0), hy(0) -{ -} - -QCursorData::~QCursorData() -{ - delete bm; - delete bmm; -} - - -/***************************************************************************** - Global cursors - *****************************************************************************/ - -extern QCursorData *qt_cursorTable[Qt::LastCursor + 1]; // qcursor.cpp - -QCursorData *QCursorData::setBitmap(const QBitmap &bitmap, const QBitmap &mask, int hotX, int hotY) -{ - if (!QCursorData::initialized) - QCursorData::initialize(); - if (bitmap.depth() != 1 || mask.depth() != 1 || bitmap.size() != mask.size()) { - qWarning("QCursor: Cannot create bitmap cursor; invalid bitmap(s)"); - QCursorData *c = qt_cursorTable[0]; - c->ref.ref(); - return c; - } - QCursorData *d = new QCursorData; - d->bm = new QBitmap(bitmap); - d->bmm = new QBitmap(mask); - d->cshape = Qt::BitmapCursor; - d->hx = hotX >= 0 ? hotX : bitmap.width() / 2; - d->hy = hotY >= 0 ? hotY : bitmap.height() / 2; - - return d; -} - -void QCursorData::update() -{ -} - -#endif //QT_NO_CURSOR - -QPoint QCursor::pos() -{ - return QCursor::pos(QGuiApplication::primaryScreen()); -} - -QPoint QCursor::pos(const QScreen *screen) -{ - if (screen) - if (const QPlatformCursor *cursor = screen->handle()->cursor()) - return cursor->pos(); - return QGuiApplicationPrivate::lastCursorPosition.toPoint(); -} - -void QCursor::setPos(QScreen *screen, int x, int y) -{ - if (screen) { - if (QPlatformCursor *cursor = screen->handle()->cursor()) { - const QPoint pos = QPoint(x, y); - // Need to check, since some X servers generate null mouse move - // events, causing looping in applications which call setPos() on - // every mouse move event. - if (pos != cursor->pos()) - cursor->setPos(pos); - } - } -} - -void QCursor::setPos(int x, int y) -{ - QCursor::setPos(QGuiApplication::primaryScreen(), x, y); -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 0a826284c9..df143103ad 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -377,8 +377,6 @@ public: inline const QRegion ®ion() const { return m_region; } protected: - friend class QApplication; - friend class QCoreApplication; QRect m_rect; QRegion m_region; bool m_erased; @@ -395,7 +393,6 @@ public: protected: QPoint p, oldp; friend class QApplication; - friend class QCoreApplication; }; class Q_GUI_EXPORT QExposeEvent : public QEvent @@ -421,7 +418,6 @@ public: protected: QSize s, olds; friend class QApplication; - friend class QCoreApplication; }; @@ -601,7 +597,6 @@ public: inline void ignore(const QRect & r) { ignore(); rect = r; } protected: - friend class QApplication; QRect rect; }; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 8ccff4321d..b49f5f00ce 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -496,6 +496,7 @@ static QWindowGeometrySpecification windowGeometrySpecification; \li \c {-qwindowgeometry} \e geometry, specifies window geometry for the main window using the X11-syntax. For example: \c {-qwindowgeometry 100x100+50+50} + \li \c {-qwindowicon}, sets the default window icon \li \c {-qwindowtitle}, sets the title of the first window \li \c{-reverse}, sets the application's layout direction to Qt::RightToLeft. This option is intended to aid debugging and should @@ -1107,6 +1108,7 @@ void QGuiApplicationPrivate::createPlatformIntegration() argv[j++] = argv[i]; continue; } + const bool isXcb = platformName == "xcb"; QByteArray arg = argv[i]; if (arg.startsWith("--")) arg.remove(0, 1); @@ -1119,12 +1121,17 @@ void QGuiApplicationPrivate::createPlatformIntegration() } else if (arg == "-platformtheme") { if (++i < argc) platformThemeName = QString::fromLocal8Bit(argv[i]); - } else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) { + } else if (arg == "-qwindowgeometry" || (isXcb && arg == "-geometry")) { if (++i < argc) windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]); - } else if (arg == "-qwindowtitle" || (platformName == "xcb" && arg == "-title")) { + } else if (arg == "-qwindowtitle" || (isXcb && arg == "-title")) { if (++i < argc) firstWindowTitle = QString::fromLocal8Bit(argv[i]); + } else if (arg == "-qwindowicon" || (isXcb && arg == "-icon")) { + if (++i < argc) { + const QString icon = QString::fromLocal8Bit(argv[i]); + forcedWindowIcon = QDir::isAbsolutePath(icon) ? QIcon(icon) : QIcon::fromTheme(icon); + } } else { argv[j++] = argv[i]; } @@ -1416,6 +1423,20 @@ QPlatformNativeInterface *QGuiApplication::platformNativeInterface() } /*! + Returns a function pointer from the platformplugin matching \a function +*/ +QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function) +{ + QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); + if (!pi) { + qWarning() << "QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function"; + return Q_NULLPTR; + } + + return pi->nativeInterface() ? pi->nativeInterface()->platformFunction(function) : Q_NULLPTR; +} + +/*! Enters the main event loop and waits until exit() is called, and then returns the value that was set to exit() (which is 0 if exit() is called via quit()). @@ -1538,8 +1559,9 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv case QWindowSystemInterfacePrivate::WindowScreenChanged: QGuiApplicationPrivate::processWindowScreenChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowScreenChangedEvent *>(e)); break; - case QWindowSystemInterfacePrivate::ApplicationStateChanged: - QGuiApplicationPrivate::setApplicationState(static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e)->newState); + case QWindowSystemInterfacePrivate::ApplicationStateChanged: { + QWindowSystemInterfacePrivate::ApplicationStateChangedEvent * changeEvent = static_cast<QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *>(e); + QGuiApplicationPrivate::setApplicationState(changeEvent->newState, changeEvent->forcePropagate); } break; case QWindowSystemInterfacePrivate::FlushEvents: QWindowSystemInterface::deferredFlushWindowSystemEvents(); @@ -2852,9 +2874,9 @@ Qt::ApplicationState QGuiApplication::applicationState() \sa applicationState() */ -void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state) +void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, bool forcePropagate) { - if (applicationState == state) + if ((applicationState == state) && !forcePropagate) return; applicationState = state; diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 6d9a4b2376..50aefaadb5 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -143,6 +143,8 @@ public: static QPlatformNativeInterface *platformNativeInterface(); + static QFunctionPointer platformFunction(const QByteArray &function); + static void setQuitOnLastWindowClosed(bool quit); static bool quitOnLastWindowClosed(); diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 1ec808ec27..782a4b34b3 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -234,6 +234,7 @@ public: QInputMethod *inputMethod; QString firstWindowTitle; + QIcon forcedWindowIcon; static QList<QObject *> generic_plugin_list; #ifndef QT_NO_SHORTCUT @@ -288,7 +289,7 @@ public: static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window); - static void setApplicationState(Qt::ApplicationState state); + static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false); protected: virtual void notifyThemeChanged(); diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index 0e150a9c1e..2ec72fd2d0 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -45,6 +45,9 @@ #include <private/qobject_p.h> #include "qkeymapper_p.h" +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> + QT_BEGIN_NAMESPACE /*! @@ -117,4 +120,32 @@ QKeyMapperPrivate *qt_keymapper_private() return QKeyMapper::instance()->d_func(); } +QKeyMapperPrivate::QKeyMapperPrivate() +{ + keyboardInputLocale = QLocale::system(); + keyboardInputDirection = keyboardInputLocale.textDirection(); +} + +QKeyMapperPrivate::~QKeyMapperPrivate() +{ + // clearMappings(); +} + +void QKeyMapperPrivate::clearMappings() +{ +} + +QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e) +{ + QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e); + if (!result.isEmpty()) + return result; + + if (e->key() && (e->key() != Qt::Key_unknown)) + result << int(e->key() + e->modifiers()); + else if (!e->text().isEmpty()) + result << int(e->text().at(0).unicode() + e->modifiers()); + return result; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeymapper_qpa.cpp b/src/gui/kernel/qkeymapper_qpa.cpp deleted file mode 100644 index 3966909db1..0000000000 --- a/src/gui/kernel/qkeymapper_qpa.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkeymapper_p.h" -#include <qdebug.h> -#include <private/qevent_p.h> -#include <private/qlocale_p.h> -#include <private/qguiapplication_p.h> -#include <qpa/qplatformintegration.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - - -QKeyMapperPrivate::QKeyMapperPrivate() -{ - keyboardInputLocale = QLocale::system(); - keyboardInputDirection = keyboardInputLocale.textDirection(); -} - -QKeyMapperPrivate::~QKeyMapperPrivate() -{ - // clearMappings(); -} - -void QKeyMapperPrivate::clearMappings() -{ -} - -QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *e) -{ - QList<int> result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e); - if (!result.isEmpty()) - return result; - - if (e->key() && (e->key() != Qt::Key_unknown)) - result << int(e->key() + e->modifiers()); - else if (!e->text().isEmpty()) - result << int(e->text().at(0).unicode() + e->modifiers()); - return result; -} - -QT_END_NAMESPACE diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index be592153d2..012e384d72 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -486,6 +486,64 @@ void QOpenGLContext::setScreen(QScreen *screen) } /*! + Set the native handles for this context. When create() is called and a + native handle is set, configuration settings, like format(), are ignored + since this QOpenGLContext will wrap an already created native context + instead of creating a new one from scratch. + + On some platforms the native context handle is not sufficient and other + related handles (for example, for a window or display) have to be provided + in addition. Therefore \a handle is variant containing a platform-specific + value type. These classes can be found in the QtPlatformHeaders module. + + When create() is called with native handles set, the handles' ownership are + not taken, meaning that destroy() will not destroy the native context. + + \note Some frameworks track the current context and surfaces internally. + Making the adopted QOpenGLContext current via Qt will have no effect on such + other frameworks' internal state. Therefore a subsequent makeCurrent done + via the other framework may have no effect. It is therefore advisable to + make explicit calls to make no context and surface current to reset the + other frameworks' internal state after performing OpenGL operations via Qt. + + \note Using foreign contexts with Qt windows and Qt contexts with windows + and surfaces created by other frameworks may give unexpected results, + depending on the platform, due to potential mismatches in context and window + pixel formats. To make sure this does not happen, avoid making contexts and + surfaces from different frameworks current together. Instead, prefer + approaches based on context sharing where OpenGL resources like textures are + accessible both from Qt's and the foreign framework's contexts. + + \since 5.4 + \sa nativeHandle() +*/ +void QOpenGLContext::setNativeHandle(const QVariant &handle) +{ + Q_D(QOpenGLContext); + d->nativeHandle = handle; +} + +/*! + Returns the native handle for the context. + + This function provides access to the QOpenGLContext's underlying native + context. The returned variant contains a platform-specific value type. These + classes can be found in the module QtPlatformHeaders. + + On platforms where retrieving the native handle is not supported, or if + neither create() nor setNativeHandle() was called, a null variant is + returned. + + \since 5.4 + \sa setNativeHandle() + */ +QVariant QOpenGLContext::nativeHandle() const +{ + Q_D(const QOpenGLContext); + return d->nativeHandle; +} + +/*! Attempts to create the OpenGL context with the current configuration. The current configuration includes the format, the share context, and the @@ -506,7 +564,8 @@ void QOpenGLContext::setScreen(QScreen *screen) */ bool QOpenGLContext::create() { - destroy(); + if (isValid()) + destroy(); Q_D(QOpenGLContext); d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); @@ -556,6 +615,7 @@ void QOpenGLContext::destroy() d->versionFunctionsBackend.clear(); delete d->textureFunctions; d->textureFunctions = 0; + d->nativeHandle = QVariant(); } /*! diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h index 19aecee75a..99f2fece51 100644 --- a/src/gui/kernel/qopenglcontext.h +++ b/src/gui/kernel/qopenglcontext.h @@ -64,6 +64,7 @@ #include <QtCore/qhash.h> #include <QtCore/qpair.h> +#include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -153,6 +154,7 @@ public: void setFormat(const QSurfaceFormat &format); void setShareContext(QOpenGLContext *shareContext); void setScreen(QScreen *screen); + void setNativeHandle(const QVariant &handle); bool create(); bool isValid() const; @@ -161,6 +163,7 @@ public: QOpenGLContext *shareContext() const; QOpenGLContextGroup *shareGroup() const; QScreen *screen() const; + QVariant nativeHandle() const; GLuint defaultFramebufferObject() const; @@ -242,4 +245,4 @@ QT_END_NAMESPACE #endif // QT_NO_OPENGL -#endif // QGUIGLCONTEXT_H +#endif // QOPENGLCONTEXT_H diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 711a3b1b2f..a7525c0e54 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -245,6 +245,8 @@ public: QPaintEngineEx *active_engine; + QVariant nativeHandle; + static QOpenGLContext *setCurrentContext(QOpenGLContext *context); static void setGlobalShareContext(QOpenGLContext *context); diff --git a/src/gui/kernel/qpixelformat.cpp b/src/gui/kernel/qpixelformat.cpp new file mode 100644 index 0000000000..436694915f --- /dev/null +++ b/src/gui/kernel/qpixelformat.cpp @@ -0,0 +1,630 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpixelformat.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QPixelFormat + \inmodule QtGui + \since 5.4 + \brief QPixelFormat is a class for describing different pixel + layouts in graphics buffers + + In Qt there is a often a need to represent the layout of the pixels in a + graphics buffer. Internally QPixelFormat stores everything in a 64 bit + datastructure. This gives performance but also some limitations. + + QPixelFormat can describe 5 color channels and 1 alpha channel, each can use + 6 bits to describe the size of the color channel. + + The position of the alpha channel is described with a separate enum. This is + to make it possible to describe QImage formats like ARGB32, and also + describe typical OpenGL formats like RBGA8888. + + How pixels are suppose to be read is determined by the TypeInterpretation + enum. It describes if color values are suppose to be read byte per byte, + or if a pixel is suppose to be read as a complete int and then masked. + \sa TypeInterpretation + + There is no support for describing YUV's macro pixels. Instead a list of YUV + formats has been made. When a QPixelFormat is describing a YUV format, the + bitsPerPixel value has been deduced by the YUV Layout enum. Also, the color + channels should all be set to zero except the fifth color channel that + should store the bitsPerPixel value. +*/ + +/*! + \enum QPixelFormat::ColorModel + + This enum type is used to describe the color model of the pixelformat. + + \value RGB The color model is RGB. + + \value BGR This is logically the opposite endian version of RGB. However, + for ease of use it has its own model. + + \value Indexed The color model uses a color palette. + + \value GrayScale The color model is GrayScale. + + \value CMYK The color model is CMYK. + + \value HSL The color model is HSL. + + \value HSV The color model is HSV. + + \value YUV The color model is YUV. +*/ + +/*! + \enum QPixelFormat::AlphaUsage + + This enum describes if the alpha channel is used or not. Sometimes the + pixelformat will have a size for the alpha channel, but the pixel format + does actually not use the alpha channel. For example RGB32 is such a + format. The RGB channels are 8 bits each, and there is no alpha channel. + But the complete size for each pixel is 32. Therefore the alpha channel size + is 8, but the alpha channel is ignored. Its important to note that in such + situations the position of the alpha channel is significant. + + \value IgnoresAlpha The alpha channel is not used. + + \value UsesAlpha The alpha channel is used. +*/ + +/*! + \enum QPixelFormat::AlphaPosition + + This enum type is used to describe the alpha channels position relative to the + color channels. + + \value AtBeginning The alpha channel will be put in front of the color + channels . E.g. ARGB. + + \value AtEnd The alpha channel will be put in the back of the color + channels. E.g. RGBA. +*/ + +/*! + \enum QPixelFormat::AlphaPremultiplied + + This enum type describes the boolean state if the alpha channel is multiplied + into the color channels or not. + + \value NotPremultiplied The alpha channel is not multiplied into the color channels. + + \value Premultiplied The alpha channel is multiplied into the color channels. +*/ + +/*! + \enum QPixelFormat::TypeInterpretation + + This enum describes how each pixel is interpreted. If a pixel is read as a + full 32 bit unsigned integer and then each channel is masked out, or if + each byte is read as unsigned char values. Typically QImage formats + interpret one pixel as an unsigned integer and then the color channels are + masked out. OpenGL on the other hand typically interpreted pixels "one byte + after the other", Ie. unsigned byte. + + QImage also have the format Format_RGBA8888 (and its derivatives), where + the pixels are interpreted as unsigned bytes. OpenGL has extensions that makes it + possible to upload pixel buffers in an unsigned integer format. + + \image qpixelformat-argb32buffer.png An unsigned integer ARGB32 pixel. + + The image above shows a ARGB pixel in memory read as an unsigned integer. + However, if this pixel was read byte for byte on a little endian system the + first byte would be the byte containing the B-channel. The next byte would + be the G-channel, then the R-channel and finally the A-channel. This shows + that on little endian systems, how each pixel is interpreted is significant + for integer formats. This is not the case on big endian systems. + + \value UnsignedInteger + \value UnsignedShort + \value UnsignedByte + \value FloatingPoint +*/ + +/*! + \enum QPixelFormat::ByteOrder + + This enum describes the ByteOrder of the pixel format. This enum is mostly + ignored but have some use cases for YUV formats. BGR formats have their own + color model, and should not be described by using the opposite endianness + on an RGB format. + + \value LittleEndian The byte order is little endian. + \value BigEndian The byte order is big endian. + \value CurrentSystemEndian This enum will not be stored, but is converted in + the constructor to the endian enum that matches + the enum of the current system. + +*/ + +/*! + \enum QPixelFormat::YUVLayout + + YUV is not represented by describing the size of the color channels. This is + because YUV often use macro pixels, making the concept of sperate color channels + invalid. Instead the different YUV layouts are described with this enum. + + \value YUV444 + \value YUV422 + \value YUV411 + \value YUV420P + \value YUV420SP + \value YV12 + \value UYVY + \value YUYV + \value NV12 + \value NV21 + \value IMC1 + \value IMC2 + \value IMC3 + \value IMC4 + \value Y8 + \value Y16 +*/ + +/*! + \fn QPixelFormat::QPixelFormat() + + Creates a null pixelformat. This format maps to QImage::Format_Invalid. +*/ + +/*! + \fn QPixelFormat::QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) + + Creates a QPixelFormat which assigns its data to the attributes. + \a colorModel will be put into a buffer which is 4 bits long. + + \a firstSize \a secondSize \a thirdSize \a fourthSize \a fifthSize \a + alphaSize are all meant to represent the size of a channel. The channels will + be used for different uses dependent on the \a colorModel. For RGB the + firstSize will represent the Red channel. On CMYK it will represent the + value of the Cyan channel. + + \a alphaUsage represents if the alpha channel is used or not. + + \a alphaPosition is the position of the alpha channel. + + \a premultiplied represents if the alpha channel is already multiplied with + the color channels. + + \a typeInterpretation is how the pixel is interpreted. + + \a byteOrder represents the endianness of the pixelformat. This defaults to + CurrentSystemEndian. + + \a subEnum is used for colorModels that have to store some extra + information with supplying an extra enum. This is used by YUV to store the + YUV type The default value is 0. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatRgb) == sizeof(QPixelFormat)); + +/*! + \class QPixelFormatRgb + \inmodule QtGui + \since 5.4 + \brief QPixelFormatRgb is a helper class for creating pixel formats with + the rgb color model + + The size of QPixelFormatRgb is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatRgb::QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor making an RGB pixelformat. \a redSize \a greenSize \a + blueSize represent the size of each color channel. \a alphaSize describes + the alpha channel size and its position is described with \a alphaPosition. + \a alphaUsage is used to determine if the alpha channel is used or not. + Setting the alpha channel size to 8 and alphaUsage to IgnoresAlpha is how + it is possible to create a 32 bit format where the rgb channels only use 24 + bits combined. \a premultiplied \a typeInterpretation are + accessible with accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatGrayScale) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatGrayScale + \inmodule QtGui + \since 5.4 + \brief QPixelFormatGrayScale is a helper class for creating pixel formats with + the gray scale color model. + + The size of QPixelFormatGrayScale is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating a GrayScale format. Monochrome formats can be + described by passing 1 to \a channelSize. Its also possible to define very + accurate greyscale formats using doubles to describe each pixel by passing 8 + as \a channelSize and FloatingPoint as \a typeInterpretation. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatCmyk) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatCmyk + \inmodule QtGui + \since 5.4 + \brief QPixelFormatCmyk is a helper class for creating pixel formats with + the CMYK color model + + The size of QPixelFormatCmyk is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) + + Constructor for creating CMYK formats. The channel count will be 4 or + 5 depending on if \a alphaSize is bigger than zero or not. The CMYK color + channels will all be set to the value of \a channelSize. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. + + \sa TypeInterpretation +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsl) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsl + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsl is a helper class for creating pixel formats with + the HSL color model. + + The size of QPixelFormatHsl is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSL formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and lightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatHsv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatHsv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatHsv is a helper class for creating pixel formats with + the HSV color model. + + The size of QPixelFormatHsv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) + + Constructor for creating HSV formats. The channel count will be 3 or 4 + depending on if \a alphaSize is bigger than 0. + + \a channelSize will set the hueSize saturationSize and brightnessSize to the same value. + + \a alphaUsage \a alphaPosition and \a typeInterpretation are all accessible with + the accessors with the same name. +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormatYuv) == sizeof(QPixelFormat)); +/*! + \class QPixelFormatYuv + \inmodule QtGui + \since 5.4 + \brief QPixelFormatYuv is a helper class for creating pixel formats with + the YUV color model. + + The size of QPixelFormatYuv is guaranteed to be the size of QPixelFormat. +*/ + +/*! + \fn QPixelFormatYuv::QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian) + + Constructor for creating a QPixelFormat describing a YUV format with + \a yuvLayout. \a alphaSize describes the size of a potential alpha channel + and is position is described with \a alphaPosition. The "first" "second" .. + "fifth" channels are all set to 0. \a alphaUsage \a premultiplied \a + typeInterpretation and \a byteOrder will work as with other formats. +*/ + +/*! + \fn ColorModel QPixelFormat::colorModel() const + + Accessor function for getting the colorModel. +*/ + +/*! + \fn uchar QPixelFormat::channelCount() const + + Accessor function for getting the channelCount. Channel Count is deduced + by color channels with a size > 0 and if the size of the alpha channel is > 0. +*/ + +/*! + \fn uchar QPixelFormat::redSize() const + + Accessor function for the size of the red color channel. +*/ + +/*! + \fn uchar QPixelFormat::greenSize() const + + Accessor function for the size of the green color channel. +*/ + +/*! + \fn uchar QPixelFormat::blueSize() const + + Accessor function for the size of the blue color channel. +*/ + +/*! + \fn uchar QPixelFormat::cyanSize() const + + Accessor function for the cyan color channel. +*/ + +/*! + \fn uchar QPixelFormat::magentaSize() const + + Accessor function for the megenta color channel. +*/ + +/*! + \fn uchar QPixelFormat::yellowSize() const + + Accessor function for the yellow color channel. +*/ + +/*! + \fn uchar QPixelFormat::blackSize() const + + Accessor function for the black/key color channel. +*/ + +/*! + \fn uchar QPixelFormat::hueSize() const + + Accessor function for the hue channel size. +*/ + +/*! + \fn uchar QPixelFormat::saturationSize() const + + Accessor function for the saturation channel size. +*/ + +/*! + \fn uchar QPixelFormat::lightnessSize() const + + Accessor function for the lightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::brightnessSize() const + + Accessor function for the brightness channel size. +*/ + +/*! + \fn uchar QPixelFormat::alphaSize() const + + Accessor function for the alpha channel size. +*/ + +/*! + \fn uchar QPixelFormat::bitsPerPixel() const + + Accessor function for the bits used per pixel. This function returns the + sum of the color channels + the size of the alpha channel. +*/ + +/*! + \fn AlphaPremultiplied QPixelFormat::premultiplied() const + + Accessor function for the AlphaPremultiplied enum. This indicates if the + alpha channel is multiplied in to the color channels. + +*/ + +/*! + \fn TypeInterpretation QPixelFormat::typeInterpretation() const + + Accessor function for the type representation of a color channel or a pixel. + + \sa TypeInterpretation +*/ + +/*! + \fn ByteOrder QPixelFormat::byteOrder() const + + The byte order is almost always set the the byte order of the current + system. However, it can be useful to describe some YUV formats. This + function should never return QPixelFormat::CurrentSystemEndian as this + value is translated to a endian value in the constructor. +*/ + +/*! + \fn AlphaUsage QPixelFormat::alphaUsage() const + + Accessor function for alphaUsage. +*/ + +/*! + \fn AlphaPosition QPixelFormat::alphaPosition() const + + Accessor function for alphaPosition. +*/ + +/*! + \fn YUVLayout QPixelFormat::yuvLayout() const + + Accessor function for the YUVLayout. It is difficult to describe the color + channels of a YUV pixel format since YUV color model uses macro pixels. + Instead the layout of the pixels are stored as an enum. +*/ + +/*! + \fn uchar QPixelFormat::subEnum() const + + Accessor for the datapart which contains subEnums + This is the same as the yuvLayout() function. + + \sa yuvLayout() + \internal +*/ + +Q_STATIC_ASSERT(sizeof(QPixelFormat) == sizeof(quint64)); + + +namespace QtPrivate { + QPixelFormat QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder) + { + uchar bits_per_pixel = 0; + switch (yuvLayout) { + case QPixelFormat::YUV444: + bits_per_pixel = 24; + break; + case QPixelFormat::YUV422: + bits_per_pixel = 16; + break; + case QPixelFormat::YUV411: + case QPixelFormat::YUV420P: + case QPixelFormat::YUV420SP: + case QPixelFormat::YV12: + bits_per_pixel = 12; + break; + case QPixelFormat::UYVY: + case QPixelFormat::YUYV: + bits_per_pixel = 16; + break; + case QPixelFormat::NV12: + case QPixelFormat::NV21: + bits_per_pixel = 12; + break; + case QPixelFormat::IMC1: + case QPixelFormat::IMC2: + case QPixelFormat::IMC3: + case QPixelFormat::IMC4: + bits_per_pixel = 12; + break; + case QPixelFormat::Y8: + bits_per_pixel = 8; + break; + case QPixelFormat::Y16: + bits_per_pixel = 16; + break; + } + + return QPixelFormat(QPixelFormat::YUV, + 0, 0, 0, 0, + bits_per_pixel, + alphaSize, + alphaUsage, + alphaPosition, + premultiplied, + typeInterpretation, + byteOrder, + yuvLayout); + } +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qpixelformat.h b/src/gui/kernel/qpixelformat.h new file mode 100644 index 0000000000..b020a53e6d --- /dev/null +++ b/src/gui/kernel/qpixelformat.h @@ -0,0 +1,452 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPIXELFORMAT_H +#define QPIXELFORMAT_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + +class QPixelFormat +{ +public: + enum ColorModel { + RGB, + BGR, + Indexed, + GrayScale, + CMYK, + HSL, + HSV, + YUV + }; + + enum AlphaUsage { + UsesAlpha, + IgnoresAlpha + }; + + enum AlphaPosition { + AtBeginning, + AtEnd + }; + + enum AlphaPremultiplied { + NotPremultiplied, + Premultiplied + }; + + enum TypeInterpretation { + UnsignedInteger, + UnsignedShort, + UnsignedByte, + FloatingPoint + }; + + enum YUVLayout { + YUV444, + YUV422, + YUV411, + YUV420P, + YUV420SP, + YV12, + UYVY, + YUYV, + NV12, + NV21, + IMC1, + IMC2, + IMC3, + IMC4, + Y8, + Y16 + }; + + enum ByteOrder { + LittleEndian, + BigEndian, + CurrentSystemEndian + }; + + Q_DECL_CONSTEXPR inline QPixelFormat() Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QPixelFormat(ColorModel colorModel, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied, + TypeInterpretation typeInterpretation, + ByteOrder byteOrder = CurrentSystemEndian, + uchar subEnum = 0) Q_DECL_NOTHROW; + + Q_DECL_CONSTEXPR inline ColorModel colorModel() const Q_DECL_NOTHROW { return ColorModel(model); } + Q_DECL_CONSTEXPR inline uchar channelCount() const Q_DECL_NOTHROW { return (first > 0) + + (second > 0) + + (third > 0) + + (fourth > 0) + + (fifth > 0) + + (alpha > 0); } + + Q_DECL_CONSTEXPR inline uchar redSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar greenSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar blueSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar cyanSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar magentaSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar yellowSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar blackSize() const Q_DECL_NOTHROW { return fourth; } + + Q_DECL_CONSTEXPR inline uchar hueSize() const Q_DECL_NOTHROW { return first; } + Q_DECL_CONSTEXPR inline uchar saturationSize() const Q_DECL_NOTHROW { return second; } + Q_DECL_CONSTEXPR inline uchar lightnessSize() const Q_DECL_NOTHROW { return third; } + Q_DECL_CONSTEXPR inline uchar brightnessSize() const Q_DECL_NOTHROW { return third; } + + Q_DECL_CONSTEXPR inline uchar alphaSize() const Q_DECL_NOTHROW { return alpha; } + + Q_DECL_CONSTEXPR inline uchar bitsPerPixel() const Q_DECL_NOTHROW { return first + + second + + third + + fourth + + fifth + + alpha; } + + Q_DECL_CONSTEXPR inline AlphaUsage alphaUsage() const Q_DECL_NOTHROW { return AlphaUsage(alpha_usage); } + Q_DECL_CONSTEXPR inline AlphaPosition alphaPosition() const Q_DECL_NOTHROW { return AlphaPosition(alpha_position); } + Q_DECL_CONSTEXPR inline AlphaPremultiplied premultiplied() const Q_DECL_NOTHROW { return AlphaPremultiplied(premul); } + Q_DECL_CONSTEXPR inline TypeInterpretation typeInterpretation() const Q_DECL_NOTHROW { return TypeInterpretation(type_interpretation); } + Q_DECL_CONSTEXPR inline ByteOrder byteOrder() const Q_DECL_NOTHROW { return ByteOrder(byte_order); } + + Q_DECL_CONSTEXPR inline YUVLayout yuvLayout() const Q_DECL_NOTHROW { return YUVLayout(sub_enum); } + Q_DECL_CONSTEXPR inline uchar subEnum() const Q_DECL_NOTHROW { return sub_enum; } + +protected: + quint64 model : 4; + quint64 first : 6; + quint64 second : 6; + quint64 third : 6; + quint64 fourth : 6; + quint64 fifth : 6; + quint64 alpha : 6; + quint64 alpha_usage : 1; + quint64 alpha_position : 1; + quint64 premul: 1; + quint64 type_interpretation : 4; + quint64 byte_order : 2; + quint64 sub_enum : 6; + quint64 unused : 8; + + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2); + friend Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2); +}; +Q_DECLARE_TYPEINFO(QPixelFormat, Q_PRIMITIVE_TYPE); + +class QPixelFormatRgb : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatRgb(uchar redSize, + uchar greenSize, + uchar blueSize, + uchar alphaSize, + AlphaUsage alphaUsage, + AlphaPosition alphaPosition, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatGrayScale : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatGrayScale(uchar bufferSize, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatCmyk : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatCmyk(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = UnsignedInteger) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsl : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsl(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +class QPixelFormatHsv : public QPixelFormat +{ +public: + Q_DECL_CONSTEXPR + inline QPixelFormatHsv(uchar channelSize, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + TypeInterpretation typeInterpretation = FloatingPoint) Q_DECL_NOTHROW; +}; + +namespace QtPrivate { + QPixelFormat Q_GUI_EXPORT QPixelFormat_createYUV(QPixelFormat::YUVLayout yuvLayout, + uchar alphaSize, + QPixelFormat::AlphaUsage alphaUsage, + QPixelFormat::AlphaPosition alphaPosition, + QPixelFormat::AlphaPremultiplied premultiplied, + QPixelFormat::TypeInterpretation typeInterpretation, + QPixelFormat::ByteOrder byteOrder); +} + +class QPixelFormatYuv : public QPixelFormat +{ +public: + inline QPixelFormatYuv(YUVLayout yuvLayout, + uchar alphaSize = 0, + AlphaUsage alphaUsage = IgnoresAlpha, + AlphaPosition alphaPosition = AtBeginning, + AlphaPremultiplied premultiplied = NotPremultiplied, + TypeInterpretation typeInterpretation = UnsignedByte, + ByteOrder byteOrder = LittleEndian); +}; + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat() Q_DECL_NOTHROW + : model(0) + , first(0) + , second(0) + , third(0) + , fourth(0) + , fifth(0) + , alpha(0) + , alpha_usage(0) + , alpha_position(0) + , premul(0) + , type_interpretation(0) + , byte_order(0) + , sub_enum(0) + , unused(0) +{ +} + +Q_DECL_CONSTEXPR +QPixelFormat::QPixelFormat(ColorModel mdl, + uchar firstSize, + uchar secondSize, + uchar thirdSize, + uchar fourthSize, + uchar fifthSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied premult, + TypeInterpretation typeInterp, + ByteOrder b_order, + uchar s_enum) Q_DECL_NOTHROW + : model(mdl) + , first(firstSize) + , second(secondSize) + , third(thirdSize) + , fourth(fourthSize) + , fifth(fifthSize) + , alpha(alfa) + , alpha_usage(usage) + , alpha_position(position) + , premul(premult) + , type_interpretation(typeInterp) +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + , byte_order(b_order == CurrentSystemEndian ? LittleEndian : b_order) +#else + , byte_order(b_order == CurrentSystemEndian ? BigEndian : b_order) +#endif + , sub_enum(s_enum) + , unused(0) +{ +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator==(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ + return fmt1.model == fmt2.model + && fmt1.first == fmt2.first + && fmt1.second == fmt2.second + && fmt1.third == fmt2.third + && fmt1.fourth == fmt2.fourth + && fmt1.fifth == fmt2.fifth + && fmt1.alpha == fmt2.alpha + && fmt1.alpha_usage == fmt2.alpha_usage + && fmt1.alpha_position == fmt2.alpha_position + && fmt1.premul == fmt2.premul + && fmt1.type_interpretation == fmt2.type_interpretation + && fmt1.byte_order == fmt2.byte_order + && fmt1.sub_enum == fmt2.sub_enum + && fmt1.unused == fmt2.unused; +} + +Q_DECL_CONST_FUNCTION Q_DECL_CONSTEXPR inline bool operator!=(const QPixelFormat &fmt1, const QPixelFormat &fmt2) +{ return !(fmt1 == fmt2); } + +Q_DECL_CONSTEXPR +QPixelFormatRgb::QPixelFormatRgb(uchar red, + uchar green, + uchar blue, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied pmul, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(RGB, + red, + green, + blue, + 0, + 0, + alfa, + usage, + position, + pmul, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatGrayScale::QPixelFormatGrayScale(uchar channelSize, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(GrayScale, + channelSize, + 0, + 0, + 0, + 0, + 0, + IgnoresAlpha, + AtBeginning, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatCmyk::QPixelFormatCmyk(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(CMYK, + channelSize, + channelSize, + channelSize, + channelSize, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsl::QPixelFormatHsl(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSL, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +Q_DECL_CONSTEXPR +QPixelFormatHsv::QPixelFormatHsv(uchar channelSize, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + TypeInterpretation typeInt) Q_DECL_NOTHROW + : QPixelFormat(HSV, + channelSize, + channelSize, + channelSize, + 0, + 0, + alfa, + usage, + position, + NotPremultiplied, + typeInt) +{ } + +QPixelFormatYuv::QPixelFormatYuv(YUVLayout layout, + uchar alfa, + AlphaUsage usage, + AlphaPosition position, + AlphaPremultiplied p_mul, + TypeInterpretation typeInt, + ByteOrder b_order) + : QPixelFormat(QtPrivate::QPixelFormat_createYUV(layout, + alfa, + usage, + position, + p_mul, + typeInt, + b_order)) + +{ } + +QT_END_NAMESPACE + +#endif //QPIXELFORMAT_H diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index da192a8e25..f20482a859 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -271,13 +271,32 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix } #ifndef QT_NO_OPENGL +/*! + Factory function for QPlatformOpenGLContext. The \a context parameter is a pointer to + the context for which a platform-specific context backend needs to be + created. Configuration settings like the format, share context and screen have to be + taken from this QOpenGLContext and the resulting platform context is expected to be + backed by a native context that fulfills these criteria. + + If the context has native handles set, no new native context is expected to be created. + Instead, the provided handles have to be used. In this case the ownership of the handle + must not be taken and the platform implementation is not allowed to destroy the native + context. Configuration parameters like the format are also to be ignored. Instead, the + platform implementation is responsible for querying the configuriation from the provided + native context. + + Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could + not be created. + + \sa QOpenGLContext +*/ QPlatformOpenGLContext *QPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { Q_UNUSED(context); qWarning("This plugin does not support createPlatformOpenGLContext!"); return 0; } -#endif +#endif // QT_NO_OPENGL /*! Factory function for QPlatformSharedGraphicsCache. This function will return 0 if the platform diff --git a/src/gui/kernel/qplatformnativeinterface.cpp b/src/gui/kernel/qplatformnativeinterface.cpp index 6571a47849..2e5485f1c2 100644 --- a/src/gui/kernel/qplatformnativeinterface.cpp +++ b/src/gui/kernel/qplatformnativeinterface.cpp @@ -118,6 +118,12 @@ QPlatformNativeInterface::NativeResourceForBackingStoreFunction QPlatformNativeI return 0; } +QFunctionPointer QPlatformNativeInterface::platformFunction(const QByteArray &function) const +{ + Q_UNUSED(function); + return Q_NULLPTR; +} + /*! Contains generic window properties that the platform may utilize. */ diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h index eaa24a9e55..58d13c4320 100644 --- a/src/gui/kernel/qplatformnativeinterface.h +++ b/src/gui/kernel/qplatformnativeinterface.h @@ -85,6 +85,8 @@ public: virtual NativeResourceForWindowFunction nativeResourceFunctionForWindow(const QByteArray &resource); virtual NativeResourceForBackingStoreFunction nativeResourceFunctionForBackingStore(const QByteArray &resource); + virtual QFunctionPointer platformFunction(const QByteArray &function) const; + virtual QVariantMap windowProperties(QPlatformWindow *window) const; virtual QVariant windowProperty(QPlatformWindow *window, const QString &name) const; virtual QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const; diff --git a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp b/src/gui/kernel/qplatformsystemtrayicon.cpp index bc37f99210..bc37f99210 100644 --- a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp +++ b/src/gui/kernel/qplatformsystemtrayicon.cpp diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 40e9b9723a..bebf3ab6c4 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -436,11 +436,14 @@ void QWindow::setVisible(bool visible) QCoreApplication::removePostedEvents(qApp, QEvent::Quit); if (type() == Qt::Window) { - QString &firstWindowTitle = QGuiApplicationPrivate::instance()->firstWindowTitle; + QGuiApplicationPrivate *app_priv = QGuiApplicationPrivate::instance(); + QString &firstWindowTitle = app_priv->firstWindowTitle; if (!firstWindowTitle.isEmpty()) { setTitle(firstWindowTitle); firstWindowTitle = QString(); } + if (!app_priv->forcedWindowIcon.isNull()) + setIcon(app_priv->forcedWindowIcon); } QShowEvent showEvent; @@ -1519,6 +1522,9 @@ void QWindow::resize(const QSize &newSize) void QWindow::destroy() { Q_D(QWindow); + if (!d->platformWindow) + return; + QObjectList childrenWindows = children(); for (int i = 0; i < childrenWindows.size(); i++) { QObject *object = childrenWindows.at(i); @@ -1788,6 +1794,9 @@ bool QWindow::close() if (parent()) return false; + if (!d->platformWindow) + return true; + if (QGuiApplicationPrivate::focus_window == this) QGuiApplicationPrivate::focus_window = 0; if (QGuiApplicationPrivate::currentMouseWindow == this) @@ -1942,15 +1951,10 @@ bool QWindow::event(QEvent *ev) break; #endif - case QEvent::Close: { - Q_D(QWindow); - bool wasVisible = isVisible(); - if (ev->isAccepted()) { - destroy(); - if (wasVisible) - d->maybeQuitOnLastWindowClosed(); - } - break; } + case QEvent::Close: + if (ev->isAccepted()) + close(); + break; case QEvent::Expose: exposeEvent(static_cast<QExposeEvent *>(ev)); diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h index fea995a0f5..0dd027e585 100644 --- a/src/gui/kernel/qwindowdefs_win.h +++ b/src/gui/kernel/qwindowdefs_win.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -107,7 +107,7 @@ Q_DECLARE_HANDLE(HRGN); #ifndef HMONITOR Q_DECLARE_HANDLE(HMONITOR); #endif -#ifndef HRESULT +#ifndef _HRESULT_DEFINED typedef long HRESULT; #endif diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 49ff8bcb0d..c9990b0f4f 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -133,11 +133,11 @@ void QWindowSystemInterface::handleWindowScreenChanged(QWindow *tlw, QScreen *sc QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } -void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState) +void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate) { Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)); QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e = - new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState); + new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 71feb1bcb7..eb18245f7b 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -148,7 +148,7 @@ public: static void handleWindowStateChanged(QWindow *w, Qt::WindowState newState); static void handleWindowScreenChanged(QWindow *w, QScreen *newScreen); - static void handleApplicationStateChanged(Qt::ApplicationState newState); + static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false); static void handleExposeEvent(QWindow *tlw, const QRegion ®ion); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 8e503bbf3d..752b3f16cc 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -176,11 +176,12 @@ public: class ApplicationStateChangedEvent : public WindowSystemEvent { public: - ApplicationStateChangedEvent(Qt::ApplicationState newState) - : WindowSystemEvent(ApplicationStateChanged), newState(newState) + ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false) + : WindowSystemEvent(ApplicationStateChanged), newState(newState), forcePropagate(forcePropagate) { } Qt::ApplicationState newState; + bool forcePropagate; }; class FlushEventsEvent : public WindowSystemEvent { diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 0b3c5b4cb9..5d7a176fe5 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1542,6 +1542,52 @@ void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVe #endif /*! + \fn void QMatrix4x4::viewport(const QRectF &rect) + \overload + + Sets up viewport transform for viewport bounded by \a rect and with near and far set + to 0 and 1 respectively. +*/ + +/*! + Multiplies this matrix by another that performs the scale and bias + transformation used by OpenGL to transform from normalized device + coordinates (NDC) to viewport (window) coordinates. That is it maps + points from the cube ranging over [-1, 1] in each dimension to the + viewport with it's near-lower-left corner at (\a left, \a bottom, \a nearPlane) + and with size (\a width, \a height, \a farPlane - \a nearPlane). + + This matches the transform used by the fixed function OpenGL viewport + transform controlled by the functions glViewport() and glDepthRange(). + */ +void QMatrix4x4::viewport(float left, float bottom, float width, float height, float nearPlane, float farPlane) +{ + const float w2 = width / 2.0f; + const float h2 = height / 2.0f; + + QMatrix4x4 m(1); + m.m[0][0] = w2; + m.m[1][0] = 0.0f; + m.m[2][0] = 0.0f; + m.m[3][0] = left + w2; + m.m[0][1] = 0.0f; + m.m[1][1] = h2; + m.m[2][1] = 0.0f; + m.m[3][1] = bottom + h2; + m.m[0][2] = 0.0f; + m.m[1][2] = 0.0f; + m.m[2][2] = (farPlane - nearPlane) / 2.0f; + m.m[3][2] = (nearPlane + farPlane) / 2.0f; + m.m[0][3] = 0.0f; + m.m[1][3] = 0.0f; + m.m[2][3] = 0.0f; + m.m[3][3] = 1.0f; + m.flagBits = General; + + *this *= m; +} + +/*! \deprecated Flips between right-handed and left-handed coordinate systems diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index d4ba7d64d8..c42ccc2dc5 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -148,6 +148,8 @@ public: #ifndef QT_NO_VECTOR3D void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up); #endif + void viewport(const QRectF &rect); + void viewport(float left, float bottom, float width, float height, float nearPlane = 0.0f, float farPlane = 1.0f); void flipCoordinates(); void copyDataTo(float *values) const; @@ -1077,6 +1079,11 @@ inline float *QMatrix4x4::data() return *m; } +inline void QMatrix4x4::viewport(const QRectF &rect) +{ + viewport(rect.x(), rect.y(), rect.width(), rect.height()); +} + #ifndef QT_NO_DEBUG_STREAM Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m); #endif diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index cadba26797..f82401c973 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -2,7 +2,6 @@ contains(QT_CONFIG, opengl):CONFIG += opengl contains(QT_CONFIG, opengles2):CONFIG += opengles2 -contains(QT_CONFIG, egl):CONFIG += egl contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index ef5ab9aa65..09bb6adf9a 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -79,7 +79,28 @@ typedef void* GLeglImageOES; # else // "uncontrolled" ES2 platforms -# include <GLES2/gl2.h> + +// In "es2" builds (QT_OPENGL_ES_2) additional defines indicate if ES +// 3.0 or higher is available. In this case include the corresponding +// header. These are backwards compatible and it should be safe to +// include headers on top of each other, meaning that applications can +// include gl2.h even if gl31.h gets included here. + +// This compile time differentation is important inside Qt because, +// unlike desktop GL, GLES is different when it comes to versioning +// and extensions: Standard functions that are new in a given version +// are always available in a version-specific header and are not +// guaranteed to be dynamically resolvable via eglGetProcAddress (and +// are typically not available as extensions even if they were part of +// an extension for a previous version). + +# if defined(QT_OPENGL_ES_3_1) +# include <GLES3/gl31.h> +# elif defined(QT_OPENGL_ES_3) +# include <GLES3/gl3.h> +# else +# include <GLES2/gl2.h> +#endif /* Some GLES2 implementations (like the one on Harmattan) are missing the diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 265771ce1b..065cbb0e57 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -106,8 +106,6 @@ public: OpenGLExtensions openGLExtensions(); bool hasOpenGLExtension(QOpenGLExtensions::OpenGLExtension extension) const; - void initializeGLExtensions(); - GLvoid *glMapBuffer(GLenum target, GLenum access); GLboolean glUnmapBuffer(GLenum target); diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index e3444332a0..8fefd43977 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -67,7 +67,7 @@ QOpenGLTexturePrivate::QOpenGLTexturePrivate(QOpenGLTexture::Target textureTarge mipLevels(-1), layers(1), faces(1), - samples(1), + samples(0), fixedSamplePositions(true), baseLevel(0), maxLevel(1000), @@ -200,7 +200,7 @@ void QOpenGLTexturePrivate::destroy() mipLevels = -1; layers = 1; faces = 1; - samples = 1; + samples = 0; fixedSamplePositions = true, baseLevel = 0; maxLevel = 1000; @@ -2063,6 +2063,125 @@ int QOpenGLTexture::faces() const } /*! + Sets the number of \a samples to allocate storage for when rendering to + a multisample capable texture target. This function should + be called before storage is allocated for the texture. + + For targets that do not support multisampling this function has + no effect. + + \sa samples(), isStorageAllocated() +*/ +void QOpenGLTexture::setSamples(int samples) +{ + Q_D(QOpenGLTexture); + d->create(); + if (isStorageAllocated()) { + qWarning("Cannot set sample count on a texture that already has storage allocated.\n" + "To do so, destroy() the texture and then create() and setSamples()"); + return; + } + + switch (d->target) { + case QOpenGLTexture::Target2DMultisample: + case QOpenGLTexture::Target2DMultisampleArray: + d->samples = samples; + break; + + case QOpenGLTexture::Target1D: + case QOpenGLTexture::Target2D: + case QOpenGLTexture::Target3D: + case QOpenGLTexture::Target1DArray: + case QOpenGLTexture::Target2DArray: + case QOpenGLTexture::TargetCubeMap: + case QOpenGLTexture::TargetCubeMapArray: + case QOpenGLTexture::TargetBuffer: + case QOpenGLTexture::TargetRectangle: + + qWarning("Texture target does not support multisampling"); + break; + } +} + +/*! + Returns the number of multisample sample points for this texture. + If storage has not yet been allocated for this texture then + this function returns the requested number of samples. + + For texture targets that do not support multisampling this + will return 0. + + \sa setSamples(), isStorageAllocated() +*/ +int QOpenGLTexture::samples() const +{ + Q_D(const QOpenGLTexture); + return d->samples; +} + +/*! + Sets whether the sample positions and number of samples used with + a multisample capable texture target to \a fixed. If set to \c true + the sample positions and number of samples used are the same for + all texels in the image and will not depend upon the image size or + internal format. This function should be called before storage is allocated + for the texture. + + For targets that do not support multisampling this function has + no effect. + + The default value is \c true. + + \sa isFixedSamplePositions(), isStorageAllocated() +*/ +void QOpenGLTexture::setFixedSamplePositions(bool fixed) +{ + Q_D(QOpenGLTexture); + d->create(); + if (isStorageAllocated()) { + qWarning("Cannot set sample positions on a texture that already has storage allocated.\n" + "To do so, destroy() the texture and then create() and setFixedSamplePositions()"); + return; + } + + switch (d->target) { + case QOpenGLTexture::Target2DMultisample: + case QOpenGLTexture::Target2DMultisampleArray: + d->fixedSamplePositions = fixed; + break; + + case QOpenGLTexture::Target1D: + case QOpenGLTexture::Target2D: + case QOpenGLTexture::Target3D: + case QOpenGLTexture::Target1DArray: + case QOpenGLTexture::Target2DArray: + case QOpenGLTexture::TargetCubeMap: + case QOpenGLTexture::TargetCubeMapArray: + case QOpenGLTexture::TargetBuffer: + case QOpenGLTexture::TargetRectangle: + + qWarning("Texture target does not support multisampling"); + break; + } +} + +/*! + Returns whether this texture uses a fixed pattern of multisample + samples. If storage has not yet been allocated for this texture then + this function returns the requested fixed sample position setting. + + For texture targets that do not support multisampling this + will return \c true. + + \sa setFixedSamplePositions(), isStorageAllocated() +*/ +bool QOpenGLTexture::isFixedSamplePositions() const +{ + Q_D(const QOpenGLTexture); + return d->fixedSamplePositions; +} + +/*! Allocates server-side storage for this texture object taking into account, the format, dimensions, mipmap levels, array layers and cubemap faces. diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index 0c272456f6..4587dd2f76 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -272,6 +272,10 @@ public: void setLayers(int layers); int layers() const; int faces() const; + void setSamples(int samples); + int samples() const; + void setFixedSamplePositions(bool fixed); + bool isFixedSamplePositions() const; void allocateStorage(); bool isStorageAllocated() const; diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index 1ede5a3682..e5de2678a4 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -173,7 +173,7 @@ public: QColor toCmyk() const; QColor toHsl() const; - QColor convertTo(Spec colorSpec) const; + QColor convertTo(Spec colorSpec) const Q_REQUIRED_RESULT; static QColor fromRgb(QRgb rgb); static QColor fromRgba(QRgb rgba); @@ -190,10 +190,10 @@ public: static QColor fromHsl(int h, int s, int l, int a = 255); static QColor fromHslF(qreal h, qreal s, qreal l, qreal a = 1.0); - QColor light(int f = 150) const; - QColor lighter(int f = 150) const; - QColor dark(int f = 200) const; - QColor darker(int f = 200) const; + QColor light(int f = 150) const Q_REQUIRED_RESULT; + QColor lighter(int f = 150) const Q_REQUIRED_RESULT; + QColor dark(int f = 200) const Q_REQUIRED_RESULT; + QColor darker(int f = 200) const Q_REQUIRED_RESULT; QColor &operator=(const QColor &); QColor &operator=(Qt::GlobalColor color); diff --git a/src/gui/painting/qcolor_p.cpp b/src/gui/painting/qcolor_p.cpp index 72b6279b2f..adc81582e2 100644 --- a/src/gui/painting/qcolor_p.cpp +++ b/src/gui/painting/qcolor_p.cpp @@ -301,9 +301,8 @@ inline bool operator<(const RGBData &data, const char *name) static bool get_named_rgb(const char *name_no_space, QRgb *rgb) { - QByteArray name = QByteArray(name_no_space).toLower(); - const RGBData *r = std::lower_bound(rgbTbl, rgbTbl + rgbTblSize, name.constData()); - if ((r != rgbTbl + rgbTblSize) && !(name.constData() < *r)) { + const RGBData *r = std::lower_bound(rgbTbl, rgbTbl + rgbTblSize, name_no_space); + if ((r != rgbTbl + rgbTblSize) && !(name_no_space < *r)) { *rgb = r->value; return true; } @@ -319,7 +318,7 @@ bool qt_get_named_rgb(const char *name, QRgb* rgb) int pos = 0; for(int i = 0; i < len; i++) { if(name[i] != '\t' && name[i] != ' ') - name_no_space[pos++] = name[i]; + name_no_space[pos++] = QChar::toLower(name[i]); } name_no_space[pos] = 0; @@ -334,7 +333,7 @@ bool qt_get_named_rgb(const QChar *name, int len, QRgb *rgb) int pos = 0; for(int i = 0; i < len; i++) { if(name[i] != QLatin1Char('\t') && name[i] != QLatin1Char(' ')) - name_no_space[pos++] = name[i].toLatin1(); + name_no_space[pos++] = name[i].toLower().toLatin1(); } name_no_space[pos] = 0; return get_named_rgb(name_no_space, rgb); @@ -352,6 +351,7 @@ QStringList qt_get_colornames() { int i = 0; QStringList lst; + lst.reserve(rgbTblSize); for (i = 0; i < rgbTblSize; i++) lst << QLatin1String(rgbTbl[i].name); return lst; diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index d2c1ae3a3c..93062899d3 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -100,7 +100,7 @@ public: bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); } qreal determinant() const { return _m11*_m22 - _m12*_m21; } - QMatrix inverted(bool *invertible = 0) const; + QMatrix inverted(bool *invertible = 0) const Q_REQUIRED_RESULT; bool operator==(const QMatrix &) const; bool operator!=(const QMatrix &) const; diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h index 7b928ba5f6..2a17a13517 100644 --- a/src/gui/painting/qpaintengine.h +++ b/src/gui/painting/qpaintengine.h @@ -250,7 +250,7 @@ private: friend class QFontEngineWin; friend class QMacPrintEngine; friend class QMacPrintEnginePrivate; - friend class QFontEngineQPA; + friend class QFontEngineQPF2; friend class QPainter; friend class QPainterPrivate; friend class QWidget; diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 4bfdbd91e0..c4703b3712 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -250,7 +250,7 @@ private: QRect toNormalizedFillRect(const QRectF &rect); inline void ensureBrush(const QBrush &brush) { - if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags)) + if (!qbrush_fast_equals(state()->lastBrush, brush) || state()->fillFlags) updateBrush(brush); } inline void ensureBrush() { ensureBrush(state()->brush); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 3f387d575b..7c691c9670 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6422,6 +6422,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText continue; + multi->ensureEngineAt(which); QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start); ti2.width = 0; // set the high byte to zero and calc the width @@ -6449,6 +6450,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText which = e; } + multi->ensureEngineAt(which); QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start); ti2.width = 0; // set the high byte to zero and calc the width diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index aa2b9bea54..7a29bb87b4 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1644,7 +1644,8 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QTransform &matrix) const if (count == 0) return polys; - QList<QRectF> bounds; + QVector<QRectF> bounds; + bounds.reserve(count); for (int i=0; i<count; ++i) bounds += subpaths.at(i).boundingRect(); diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index c0b3769c2d..b661057f64 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -327,17 +327,29 @@ QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, QPen::QPen(const QPen &p) { d = p.d; - d->ref.ref(); + if (d) + d->ref.ref(); } /*! + \fn QPen::QPen(QPen &&pen) + \since 5.4 + + Constructs a pen that is moved from the given \a pen. + + The moved-from pen can only be assigned to, copied, or + destroyed. Any other operation (prior to assignment) leads to + undefined behavior. +*/ + +/*! Destroys the pen. */ QPen::~QPen() { - if (!d->ref.deref()) + if (d && !d->ref.deref()) delete d; } @@ -373,7 +385,7 @@ void QPen::detach() QPen &QPen::operator=(const QPen &p) { - qAtomicAssign(d, p.d); + QPen(p).swap(*this); return *this; } diff --git a/src/gui/painting/qpen.h b/src/gui/painting/qpen.h index c5144f784f..486f699476 100644 --- a/src/gui/painting/qpen.h +++ b/src/gui/painting/qpen.h @@ -72,6 +72,8 @@ public: QPen &operator=(const QPen &pen); #ifdef Q_COMPILER_RVALUE_REFS + inline QPen(QPen &&other) + : d(other.d) { other.d = 0; } inline QPen &operator=(QPen &&other) { qSwap(d, other.d); return *this; } #endif diff --git a/src/gui/painting/qpolygon.h b/src/gui/painting/qpolygon.h index 1039e842ab..b696fe279a 100644 --- a/src/gui/painting/qpolygon.h +++ b/src/gui/painting/qpolygon.h @@ -71,8 +71,8 @@ public: void translate(int dx, int dy); void translate(const QPoint &offset); - QPolygon translated(int dx, int dy) const; - inline QPolygon translated(const QPoint &offset) const; + QPolygon translated(int dx, int dy) const Q_REQUIRED_RESULT; + inline QPolygon translated(const QPoint &offset) const Q_REQUIRED_RESULT; QRect boundingRect() const; @@ -88,9 +88,9 @@ public: bool containsPoint(const QPoint &pt, Qt::FillRule fillRule) const; - QPolygon united(const QPolygon &r) const; - QPolygon intersected(const QPolygon &r) const; - QPolygon subtracted(const QPolygon &r) const; + QPolygon united(const QPolygon &r) const Q_REQUIRED_RESULT; + QPolygon intersected(const QPolygon &r) const Q_REQUIRED_RESULT; + QPolygon subtracted(const QPolygon &r) const Q_REQUIRED_RESULT; }; inline QPolygon::QPolygon(int asize) : QVector<QPoint>(asize) {} diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h index 0e436e3fb4..323a1858fa 100644 --- a/src/gui/painting/qregion.h +++ b/src/gui/painting/qregion.h @@ -86,23 +86,23 @@ public: void translate(int dx, int dy); inline void translate(const QPoint &p) { translate(p.x(), p.y()); } - QRegion translated(int dx, int dy) const; - inline QRegion translated(const QPoint &p) const { return translated(p.x(), p.y()); } + QRegion translated(int dx, int dy) const Q_REQUIRED_RESULT; + inline QRegion translated(const QPoint &p) const Q_REQUIRED_RESULT { return translated(p.x(), p.y()); } - QRegion united(const QRegion &r) const; - QRegion united(const QRect &r) const; - QRegion intersected(const QRegion &r) const; - QRegion intersected(const QRect &r) const; - QRegion subtracted(const QRegion &r) const; - QRegion xored(const QRegion &r) const; + QRegion united(const QRegion &r) const Q_REQUIRED_RESULT; + QRegion united(const QRect &r) const Q_REQUIRED_RESULT; + QRegion intersected(const QRegion &r) const Q_REQUIRED_RESULT; + QRegion intersected(const QRect &r) const Q_REQUIRED_RESULT; + QRegion subtracted(const QRegion &r) const Q_REQUIRED_RESULT; + QRegion xored(const QRegion &r) const Q_REQUIRED_RESULT; #if QT_DEPRECATED_SINCE(5, 0) - inline QT_DEPRECATED QRegion unite(const QRegion &r) const { return united(r); } - inline QT_DEPRECATED QRegion unite(const QRect &r) const { return united(r); } - inline QT_DEPRECATED QRegion intersect(const QRegion &r) const { return intersected(r); } - inline QT_DEPRECATED QRegion intersect(const QRect &r) const { return intersected(r); } - inline QT_DEPRECATED QRegion subtract(const QRegion &r) const { return subtracted(r); } - inline QT_DEPRECATED QRegion eor(const QRegion &r) const { return xored(r); } + inline QT_DEPRECATED QRegion unite(const QRegion &r) const Q_REQUIRED_RESULT { return united(r); } + inline QT_DEPRECATED QRegion unite(const QRect &r) const Q_REQUIRED_RESULT { return united(r); } + inline QT_DEPRECATED QRegion intersect(const QRegion &r) const Q_REQUIRED_RESULT { return intersected(r); } + inline QT_DEPRECATED QRegion intersect(const QRect &r) const Q_REQUIRED_RESULT { return intersected(r); } + inline QT_DEPRECATED QRegion subtract(const QRegion &r) const Q_REQUIRED_RESULT { return subtracted(r); } + inline QT_DEPRECATED QRegion eor(const QRegion &r) const Q_REQUIRED_RESULT { return xored(r); } #endif bool intersects(const QRegion &r) const; diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 060362f63e..e6acbe0490 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -104,9 +104,9 @@ public: qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33); - QTransform inverted(bool *invertible = 0) const; - QTransform adjoint() const; - QTransform transposed() const; + QTransform inverted(bool *invertible = 0) const Q_REQUIRED_RESULT; + QTransform adjoint() const Q_REQUIRED_RESULT; + QTransform transposed() const Q_REQUIRED_RESULT; QTransform &translate(qreal dx, qreal dy); QTransform &scale(qreal sx, qreal sy); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index cf40dd028d..31fd9929f9 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -62,6 +62,8 @@ #include <limits.h> #include <qpa/qplatformscreen.h> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformfontdatabase.h> #include <QtGui/private/qguiapplication_p.h> #include <QtCore/QMutexLocker> @@ -545,79 +547,6 @@ QFontEngineData::~QFontEngineData() */ /*! - \fn QString QFont::rawName() const - \deprecated - - Returns the name of the font within the underlying window system. - - On X11, this function will return an empty string. - - Using the return value of this function is usually \e not \e - portable. - - \sa setRawName() -*/ - -/*! - \fn void QFont::setRawName(const QString &name) - \deprecated - - Sets a font by its system specific name. - - A font set with setRawName() is still a full-featured QFont. It can - be queried (for example with italic()) or modified (for example with - setItalic()) and is therefore also suitable for rendering rich text. - - If Qt's internal font database cannot resolve the raw name, the - font becomes a raw font with \a name as its family. - - \sa rawName(), setRawMode(), setFamily() -*/ - -/*! - \fn QString QFont::lastResortFamily() const - - Returns the "last resort" font family name. - - The current implementation tries a wide variety of common fonts, - returning the first one it finds. Is is possible that no family is - found in which case an empty string is returned. - - \sa lastResortFont() -*/ - -/*! - \fn QString QFont::defaultFamily() const - - Returns the family name that corresponds to the current style - hint. - - \sa StyleHint, styleHint(), setStyleHint() -*/ - -/*! - \fn QString QFont::lastResortFont() const - - Returns a "last resort" font name for the font matching algorithm. - This is used if the last resort family is not available. It will - always return a name, if necessary returning something like - "fixed" or "system". - - The current implementation tries a wide variety of common fonts, - returning the first one it finds. The implementation may change - at any time, but this function will always return a string - containing something. - - It is theoretically possible that there really isn't a - lastResortFont() in which case Qt will abort with an error - message. We have not been able to identify a case where this - happens. Please \l{bughowto.html}{report it as a bug} if - it does, preferably with a list of the fonts you have installed. - - \sa lastResortFamily(), rawName() -*/ - -/*! Constructs a font from \a font for use on the paint device \a pd. */ QFont::QFont(const QFont &font, QPaintDevice *pd) @@ -1913,20 +1842,6 @@ void QFont::insertSubstitutions(const QString &familyName, } } -/*! \fn void QFont::initialize() - \internal - - Internal function that initializes the font system. The font cache - and font dict do not alloc the keys. The key is a QString which is - shared between QFontPrivate and QXFontName. -*/ - -/*! \fn void QFont::cleanup() - \internal - - Internal function that cleans up the font system. -*/ - /*! Removes all the substitutions for \a familyName. @@ -2041,6 +1956,42 @@ static void set_extended_font_bits(quint8 bits, QFontPrivate *f) } #endif +/*! + \fn QString QFont::rawName() const + \deprecated + + Returns the name of the font within the underlying window system. + + On X11, this function will return an empty string. + + Using the return value of this function is usually \e not \e + portable. + + \sa setRawName() +*/ +QString QFont::rawName() const +{ + return QLatin1String("unknown"); +} + +/*! + \fn void QFont::setRawName(const QString &name) + \deprecated + + Sets a font by its system specific name. + + A font set with setRawName() is still a full-featured QFont. It can + be queried (for example with italic()) or modified (for example with + setItalic()) and is therefore also suitable for rendering rich text. + + If Qt's internal font database cannot resolve the raw name, the + font becomes a raw font with \a name as its family. + + \sa rawName(), setRawMode(), setFamily() +*/ +void QFont::setRawName(const QString &) +{ +} /*! Returns the font's key, a textual representation of a font. It is @@ -2134,17 +2085,96 @@ bool QFont::fromString(const QString &descrip) return true; } +/*! \fn void QFont::initialize() + \internal + + Internal function that initializes the font system. The font cache + and font dict do not alloc the keys. The key is a QString which is + shared between QFontPrivate and QXFontName. +*/ +void QFont::initialize() +{ +} + +/*! \fn void QFont::cleanup() + \internal + + Internal function that cleans up the font system. +*/ +void QFont::cleanup() +{ + QFontCache::cleanup(); +} + /*! \internal Internal function that dumps font cache statistics. */ void QFont::cacheStatistics() { +} + +/*! + \fn QString QFont::lastResortFamily() const + + Returns the "last resort" font family name. + + The current implementation tries a wide variety of common fonts, + returning the first one it finds. Is is possible that no family is + found in which case an empty string is returned. + + \sa lastResortFont() +*/ +QString QFont::lastResortFamily() const +{ + return QString::fromLatin1("helvetica"); +} +/*! + \fn QString QFont::defaultFamily() const + + Returns the family name that corresponds to the current style + hint. + \sa StyleHint, styleHint(), setStyleHint() +*/ +QString QFont::defaultFamily() const +{ + QPlatformFontDatabase *fontDB = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + const QStringList fallbacks = fontDB->fallbacksForFamily(QString(), QFont::StyleNormal + , QFont::StyleHint(d->request.styleHint), QChar::Script_Common); + if (!fallbacks.isEmpty()) + return fallbacks.first(); + return QString(); } +/*! + \fn QString QFont::lastResortFont() const + Returns a "last resort" font name for the font matching algorithm. + This is used if the last resort family is not available. It will + always return a name, if necessary returning something like + "fixed" or "system". + + The current implementation tries a wide variety of common fonts, + returning the first one it finds. The implementation may change + at any time, but this function will always return a string + containing something. + + It is theoretically possible that there really isn't a + lastResortFont() in which case Qt will abort with an error + message. We have not been able to identify a case where this + happens. Please \l{bughowto.html}{report it as a bug} if + it does, preferably with a list of the fonts you have installed. + + \sa lastResortFamily(), rawName() +*/ +QString QFont::lastResortFont() const +{ + qFatal("QFont::lastResortFont: Cannot find any reasonable font"); + // Shut compiler up + return QString(); +} /***************************************************************************** QFont stream functions @@ -2165,6 +2195,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) s << font.d->request.family.toLatin1(); } else { s << font.d->request.family; + if (s.version() >= QDataStream::Qt_5_4) + s << font.d->request.styleName; } if (s.version() >= QDataStream::Qt_4_0) { @@ -2185,8 +2217,14 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) } s << (quint8) font.d->request.styleHint; - if (s.version() >= QDataStream::Qt_3_1) - s << (quint8) font.d->request.styleStrategy; + if (s.version() >= QDataStream::Qt_3_1) { + // Continue writing 8 bits for versions < 5.4 so that we don't write too much, + // even though we need 16 to store styleStrategy, so there is some data loss. + if (s.version() >= QDataStream::Qt_5_4) + s << (quint16) font.d->request.styleStrategy; + else + s << (quint8) font.d->request.styleStrategy; + } s << (quint8) 0 << (quint8) font.d->request.weight << get_font_bits(s.version(), font.d.data()); @@ -2198,6 +2236,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) s << font.d->letterSpacing.value(); s << font.d->wordSpacing.value(); } + if (s.version() >= QDataStream::Qt_5_4) + s << (quint8)font.d->request.hintingPreference; return s; } @@ -2215,7 +2255,8 @@ QDataStream &operator>>(QDataStream &s, QFont &font) font.d = new QFontPrivate; font.resolve_mask = QFont::AllPropertiesResolved; - quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits; + quint8 styleHint, charSet, weight, bits; + quint16 styleStrategy = QFont::PreferDefault; if (s.version() == 1) { QByteArray fam; @@ -2223,6 +2264,8 @@ QDataStream &operator>>(QDataStream &s, QFont &font) font.d->request.family = QString::fromLatin1(fam); } else { s >> font.d->request.family; + if (s.version() >= QDataStream::Qt_5_4) + s >> font.d->request.styleName; } if (s.version() >= QDataStream::Qt_4_0) { @@ -2242,8 +2285,15 @@ QDataStream &operator>>(QDataStream &s, QFont &font) font.d->request.pixelSize = pixelSize; } s >> styleHint; - if (s.version() >= QDataStream::Qt_3_1) - s >> styleStrategy; + if (s.version() >= QDataStream::Qt_3_1) { + if (s.version() >= QDataStream::Qt_5_4) { + s >> styleStrategy; + } else { + quint8 tempStyleStrategy; + s >> tempStyleStrategy; + styleStrategy = tempStyleStrategy; + } + } s >> charSet; s >> weight; @@ -2273,6 +2323,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font) s >> value; font.d->wordSpacing.setValue(value); } + if (s.version() >= QDataStream::Qt_5_4) { + quint8 value; + s >> value; + font.d->request.hintingPreference = QFont::HintingPreference(value); + } return s; } diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 4d8712e76e..be0402b95a 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -92,7 +92,7 @@ struct QFontDef uint weight : 7; // 0-99 uint fixedPitch : 1; uint style : 2; - uint stretch : 12; // 0-400 + uint stretch : 12; // 0-4000 uint hintingPreference : 2; uint ignorePitch : 1; diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp deleted file mode 100644 index be432dc52f..0000000000 --- a/src/gui/text/qfont_qpa.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qplatformintegration.h> -#include <qpa/qplatformfontdatabase.h> - -QT_BEGIN_NAMESPACE - -void QFont::initialize() -{ -} - -void QFont::cleanup() -{ - QFontCache::cleanup(); -} - - -/***************************************************************************** - QFont member functions - *****************************************************************************/ - -QString QFont::rawName() const -{ - return QLatin1String("unknown"); -} - -void QFont::setRawName(const QString &) -{ -} - -QString QFont::defaultFamily() const -{ - QPlatformFontDatabase *fontDB = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); - const QStringList fallbacks = fontDB->fallbacksForFamily(QString(), QFont::StyleNormal - , QFont::StyleHint(d->request.styleHint), QChar::Script_Common); - if (!fallbacks.isEmpty()) - return fallbacks.first(); - return QString(); -} - -QString QFont::lastResortFamily() const -{ - return QString::fromLatin1("helvetica"); -} - -QString QFont::lastResortFont() const -{ - qFatal("QFont::lastResortFont: Cannot find any reasonable font"); - // Shut compiler up - return QString(); -} - - -QT_END_NAMESPACE - diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index 9986ef6c60..5be24dc3fe 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -167,7 +167,7 @@ private: friend class QFontPrivate; friend class QFontDialog; friend class QFontDialogPrivate; - friend class QFontEngineMultiQPA; + friend class QFontEngineMultiBasicImpl; QFontDatabasePrivate *d; }; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 078e16574f..a165330913 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -42,6 +42,10 @@ #include <qdebug.h> #include <private/qfontengine_p.h> #include <private/qfontengineglyphcache_p.h> +#include <private/qguiapplication_p.h> + +#include <qpa/qplatformfontdatabase.h> +#include <qpa/qplatformintegration.h> #include "qbitmap.h" #include "qpainter.h" @@ -1985,4 +1989,115 @@ QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosit return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t); } +/* + Creates a new multi engine. + + This function takes ownership of the QFontEngine, increasing it's refcount. +*/ +QFontEngineMultiBasicImpl::QFontEngineMultiBasicImpl(QFontEngine *fe, int _script, const QStringList &fallbacks) + : QFontEngineMulti(fallbacks.size() + 1), + fallbackFamilies(fallbacks), script(_script) + , fallbacksQueried(true) +{ + init(fe); +} + +QFontEngineMultiBasicImpl::QFontEngineMultiBasicImpl(QFontEngine *fe, int _script) + : QFontEngineMulti(2) + , script(_script) + , fallbacksQueried(false) +{ + fallbackFamilies << QString(); + init(fe); +} + +void QFontEngineMultiBasicImpl::init(QFontEngine *fe) +{ + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + engines[0] = fe; + fe->ref.ref(); + fontDef = engines[0]->fontDef; + cache_cost = fe->cache_cost; +} + +void QFontEngineMultiBasicImpl::loadEngine(int at) +{ + ensureFallbackFamiliesQueried(); + Q_ASSERT(at < engines.size()); + Q_ASSERT(engines.at(at) == 0); + QFontDef request = fontDef; + request.styleStrategy |= QFont::NoFontMerging; + request.family = fallbackFamilies.at(at-1); + engines[at] = QFontDatabase::findFont(script, + /*fontprivate = */0, + request, /*multi = */false); + Q_ASSERT(engines[at]); + engines[at]->ref.ref(); + engines[at]->fontDef = request; +} +void QFontEngineMultiBasicImpl::ensureFallbackFamiliesQueried() +{ + if (fallbacksQueried) + return; + QStringList fallbacks = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(engine(0)->fontDef.family, QFont::Style(engine(0)->fontDef.style) + , QFont::AnyStyle, QChar::Script(script)); + setFallbackFamiliesList(fallbacks); +} + +void QFontEngineMultiBasicImpl::setFallbackFamiliesList(const QStringList &fallbacks) +{ + // Original FontEngine to restore after the fill. + QFontEngine *fe = engines[0]; + fallbackFamilies = fallbacks; + if (!fallbackFamilies.isEmpty()) { + engines.fill(0, fallbackFamilies.size() + 1); + engines[0] = fe; + } else { + // Turns out we lied about having any fallback at all. + fallbackFamilies << fe->fontDef.family; + engines[1] = fe; + fe->ref.ref(); + } + fallbacksQueried = true; +} + +/* + This is used indirectly by Qt WebKit when using QTextLayout::setRawFont + + The purpose of this is to provide the necessary font fallbacks when drawing complex + text. Since Qt WebKit ends up repeatedly creating QTextLayout instances and passing them + the same raw font over and over again, we want to cache the corresponding multi font engine + as it may contain fallback font engines already. +*/ +QFontEngine* QFontEngineMultiBasicImpl::createMultiFontEngine(QFontEngine *fe, int script) +{ + QFontEngine *engine = 0; + QFontCache::Key key(fe->fontDef, script, /*multi = */true); + QFontCache *fc = QFontCache::instance(); + // We can't rely on the fontDef (and hence the cache Key) + // alone to distinguish webfonts, since these should not be + // accidentally shared, even if the resulting fontcache key + // is strictly identical. See: + // http://www.w3.org/TR/css3-fonts/#font-face-rule + const bool faceIsLocal = !fe->faceId().filename.isEmpty(); + QFontCache::EngineCache::Iterator it = fc->engineCache.find(key), + end = fc->engineCache.end(); + while (it != end && it.key() == key) { + Q_ASSERT(it.value().data->type() == QFontEngine::Multi); + QFontEngineMulti *cachedEngine = static_cast<QFontEngineMulti *>(it.value().data); + if (fe == cachedEngine->engine(0) || (faceIsLocal && fe->faceId().filename == cachedEngine->engine(0)->faceId().filename)) { + engine = cachedEngine; + fc->updateHitCountAndTimeStamp(it.value()); + break; + } + it++; + } + if (!engine) { + engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); + QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); + } + Q_ASSERT(engine); + return engine; +} + QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index fc849d788f..5040424c6f 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -433,6 +433,29 @@ protected: QVector<QFontEngine *> engines; }; +class Q_GUI_EXPORT QFontEngineMultiBasicImpl : public QFontEngineMulti +{ +public: + QFontEngineMultiBasicImpl(QFontEngine *fe, int script, const QStringList &fallbacks); + QFontEngineMultiBasicImpl(QFontEngine *fe, int script); + + void loadEngine(int at); + static QFontEngine* createMultiFontEngine(QFontEngine *fe, int script); + + int fallbackFamilyCount() const { return fallbackFamilies.size(); } + QString fallbackFamilyAt(int at) const { return fallbackFamilies.at(at); } + + virtual void ensureFallbackFamiliesQueried(); + virtual void setFallbackFamiliesList(const QStringList &fallbacks); + +private: + void init(QFontEngine *fe); + + mutable QStringList fallbackFamilies; + int script; + mutable bool fallbacksQueried; +}; + class QTestFontEngine : public QFontEngineBox { public: diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpf2.cpp index f9ed3c38c1..bcb128baac 100644 --- a/src/gui/text/qfontengine_qpa.cpp +++ b/src/gui/text/qfontengine_qpf2.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qfontengine_qpa_p.h" +#include "qfontengine_qpf2_p.h" #include <QtCore/QFile> #include <QtCore/QFileInfo> @@ -57,28 +57,28 @@ QT_BEGIN_NAMESPACE //#define DEBUG_HEADER //#define DEBUG_FONTENGINE -static QFontEngineQPA::TagType tagTypes[QFontEngineQPA::NumTags] = { - QFontEngineQPA::StringType, // FontName - QFontEngineQPA::StringType, // FileName - QFontEngineQPA::UInt32Type, // FileIndex - QFontEngineQPA::UInt32Type, // FontRevision - QFontEngineQPA::StringType, // FreeText - QFontEngineQPA::FixedType, // Ascent - QFontEngineQPA::FixedType, // Descent - QFontEngineQPA::FixedType, // Leading - QFontEngineQPA::FixedType, // XHeight - QFontEngineQPA::FixedType, // AverageCharWidth - QFontEngineQPA::FixedType, // MaxCharWidth - QFontEngineQPA::FixedType, // LineThickness - QFontEngineQPA::FixedType, // MinLeftBearing - QFontEngineQPA::FixedType, // MinRightBearing - QFontEngineQPA::FixedType, // UnderlinePosition - QFontEngineQPA::UInt8Type, // GlyphFormat - QFontEngineQPA::UInt8Type, // PixelSize - QFontEngineQPA::UInt8Type, // Weight - QFontEngineQPA::UInt8Type, // Style - QFontEngineQPA::StringType, // EndOfHeader - QFontEngineQPA::BitFieldType// WritingSystems +static QFontEngineQPF2::TagType tagTypes[QFontEngineQPF2::NumTags] = { + QFontEngineQPF2::StringType, // FontName + QFontEngineQPF2::StringType, // FileName + QFontEngineQPF2::UInt32Type, // FileIndex + QFontEngineQPF2::UInt32Type, // FontRevision + QFontEngineQPF2::StringType, // FreeText + QFontEngineQPF2::FixedType, // Ascent + QFontEngineQPF2::FixedType, // Descent + QFontEngineQPF2::FixedType, // Leading + QFontEngineQPF2::FixedType, // XHeight + QFontEngineQPF2::FixedType, // AverageCharWidth + QFontEngineQPF2::FixedType, // MaxCharWidth + QFontEngineQPF2::FixedType, // LineThickness + QFontEngineQPF2::FixedType, // MinLeftBearing + QFontEngineQPF2::FixedType, // MinRightBearing + QFontEngineQPF2::FixedType, // UnderlinePosition + QFontEngineQPF2::UInt8Type, // GlyphFormat + QFontEngineQPF2::UInt8Type, // PixelSize + QFontEngineQPF2::UInt8Type, // Weight + QFontEngineQPF2::UInt8Type, // Style + QFontEngineQPF2::StringType, // EndOfHeader + QFontEngineQPF2::BitFieldType// WritingSystems }; @@ -122,21 +122,21 @@ static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr) quint16 tag, length; READ_VERIFY(quint16, tag); READ_VERIFY(quint16, length); - if (tag == QFontEngineQPA::Tag_EndOfHeader) + if (tag == QFontEngineQPF2::Tag_EndOfHeader) return endPtr; - if (tag < QFontEngineQPA::NumTags) { + if (tag < QFontEngineQPF2::NumTags) { switch (tagTypes[tag]) { - case QFontEngineQPA::BitFieldType: - case QFontEngineQPA::StringType: + case QFontEngineQPF2::BitFieldType: + case QFontEngineQPF2::StringType: // can't do anything... break; - case QFontEngineQPA::UInt32Type: + case QFontEngineQPF2::UInt32Type: VERIFY_TAG(length == sizeof(quint32)); break; - case QFontEngineQPA::FixedType: + case QFontEngineQPF2::FixedType: VERIFY_TAG(length == sizeof(quint32)); break; - case QFontEngineQPA::UInt8Type: + case QFontEngineQPF2::UInt8Type: VERIFY_TAG(length == sizeof(quint8)); break; } @@ -150,7 +150,7 @@ static inline const uchar *verifyTag(const uchar *tagPtr, const uchar *endPtr) return tagPtr + length; } -const QFontEngineQPA::Glyph *QFontEngineQPA::findGlyph(glyph_t g) const +const QFontEngineQPF2::Glyph *QFontEngineQPF2::findGlyph(glyph_t g) const { if (!g || g >= glyphMapEntries) return 0; @@ -168,7 +168,7 @@ const QFontEngineQPA::Glyph *QFontEngineQPA::findGlyph(glyph_t g) const return reinterpret_cast<const Glyph *>(fontData + glyphDataOffset + glyphPos); } -bool QFontEngineQPA::verifyHeader(const uchar *data, int size) +bool QFontEngineQPF2::verifyHeader(const uchar *data, int size) { VERIFY(quintptr(data) % Q_ALIGNOF(Header) == 0); VERIFY(size >= int(sizeof(Header))); @@ -194,7 +194,7 @@ bool QFontEngineQPA::verifyHeader(const uchar *data, int size) return true; } -QVariant QFontEngineQPA::extractHeaderField(const uchar *data, HeaderTag requestedTag) +QVariant QFontEngineQPF2::extractHeaderField(const uchar *data, HeaderTag requestedTag) { const Header *header = reinterpret_cast<const Header *>(data); const uchar *tagPtr = data + sizeof(Header); @@ -226,7 +226,7 @@ QVariant QFontEngineQPA::extractHeaderField(const uchar *data, HeaderTag request } -QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data) +QFontEngineQPF2::QFontEngineQPF2(const QFontDef &def, const QByteArray &data) : QFontEngine(QPF2), fontData(reinterpret_cast<const uchar *>(data.constData())), dataSize(data.size()) { @@ -243,7 +243,7 @@ QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data) readOnly = true; #if defined(DEBUG_FONTENGINE) - qDebug() << "QFontEngineQPA::QFontEngineQPA( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')'; + qDebug() << "QFontEngineQPF2::QFontEngineQPF2( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')'; #endif if (!verifyHeader(fontData, dataSize)) { @@ -312,11 +312,11 @@ QFontEngineQPA::QFontEngineQPA(const QFontDef &def, const QByteArray &data) #endif } -QFontEngineQPA::~QFontEngineQPA() +QFontEngineQPF2::~QFontEngineQPF2() { } -bool QFontEngineQPA::getSfntTableData(uint tag, uchar *buffer, uint *length) const +bool QFontEngineQPF2::getSfntTableData(uint tag, uchar *buffer, uint *length) const { if (tag != MAKE_TAG('c', 'm', 'a', 'p') || !cmap) return false; @@ -328,7 +328,7 @@ bool QFontEngineQPA::getSfntTableData(uint tag, uchar *buffer, uint *length) con return true; } -glyph_t QFontEngineQPA::glyphIndex(uint ucs4) const +glyph_t QFontEngineQPF2::glyphIndex(uint ucs4) const { glyph_t glyph = getTrueTypeGlyphIndex(cmap, ucs4); if (glyph == 0 && symbol && ucs4 < 0x100) @@ -339,7 +339,7 @@ glyph_t QFontEngineQPA::glyphIndex(uint ucs4) const return glyph; } -bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const +bool QFontEngineQPF2::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { Q_ASSERT(glyphs->numGlyphs >= *nglyphs); if (*nglyphs < len) { @@ -386,7 +386,7 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph return true; } -void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const +void QFontEngineQPF2::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const { for (int i = 0; i < glyphs->numGlyphs; ++i) { const Glyph *g = findGlyph(glyphs->glyphs[i]); @@ -396,7 +396,7 @@ void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFla } } -QImage QFontEngineQPA::alphaMapForGlyph(glyph_t g) +QImage QFontEngineQPF2::alphaMapForGlyph(glyph_t g) { const Glyph *glyph = findGlyph(g); if (!glyph) @@ -409,12 +409,12 @@ QImage QFontEngineQPA::alphaMapForGlyph(glyph_t g) return image; } -void QFontEngineQPA::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) +void QFontEngineQPF2::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) { addBitmapFontToPath(x, y, glyphs, path, flags); } -glyph_metrics_t QFontEngineQPA::boundingBox(const QGlyphLayout &glyphs) +glyph_metrics_t QFontEngineQPF2::boundingBox(const QGlyphLayout &glyphs) { glyph_metrics_t overall; // initialize with line height, we get the same behaviour on all platforms @@ -442,7 +442,7 @@ glyph_metrics_t QFontEngineQPA::boundingBox(const QGlyphLayout &glyphs) return overall; } -glyph_metrics_t QFontEngineQPA::boundingBox(glyph_t glyph) +glyph_metrics_t QFontEngineQPF2::boundingBox(glyph_t glyph) { glyph_metrics_t overall; const Glyph *g = findGlyph(glyph); @@ -456,107 +456,107 @@ glyph_metrics_t QFontEngineQPA::boundingBox(glyph_t glyph) return overall; } -QFixed QFontEngineQPA::ascent() const +QFixed QFontEngineQPF2::ascent() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>()); } -QFixed QFontEngineQPA::descent() const +QFixed QFontEngineQPF2::descent() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>()); } -QFixed QFontEngineQPA::leading() const +QFixed QFontEngineQPF2::leading() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_Leading).value<qreal>()); } -qreal QFontEngineQPA::maxCharWidth() const +qreal QFontEngineQPF2::maxCharWidth() const { return extractHeaderField(fontData, Tag_MaxCharWidth).value<qreal>(); } -qreal QFontEngineQPA::minLeftBearing() const +qreal QFontEngineQPF2::minLeftBearing() const { return extractHeaderField(fontData, Tag_MinLeftBearing).value<qreal>(); } -qreal QFontEngineQPA::minRightBearing() const +qreal QFontEngineQPF2::minRightBearing() const { return extractHeaderField(fontData, Tag_MinRightBearing).value<qreal>(); } -QFixed QFontEngineQPA::underlinePosition() const +QFixed QFontEngineQPF2::underlinePosition() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_UnderlinePosition).value<qreal>()); } -QFixed QFontEngineQPA::lineThickness() const +QFixed QFontEngineQPF2::lineThickness() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_LineThickness).value<qreal>()); } -bool QFontEngineQPA::isValid() const +bool QFontEngineQPF2::isValid() const { return fontData && dataSize && cmapOffset && glyphMapOffset && glyphDataOffset && glyphDataSize > 0; } -void QPAGenerator::generate() +void QPF2Generator::generate() { writeHeader(); writeGMap(); - writeBlock(QFontEngineQPA::GlyphBlock, QByteArray()); + writeBlock(QFontEngineQPF2::GlyphBlock, QByteArray()); dev->seek(4); // position of header.lock writeUInt32(0); } -void QPAGenerator::writeHeader() +void QPF2Generator::writeHeader() { - QFontEngineQPA::Header header; + QFontEngineQPF2::Header header; header.magic[0] = 'Q'; header.magic[1] = 'P'; header.magic[2] = 'F'; header.magic[3] = '2'; header.lock = 1; - header.majorVersion = QFontEngineQPA::CurrentMajorVersion; - header.minorVersion = QFontEngineQPA::CurrentMinorVersion; + header.majorVersion = QFontEngineQPF2::CurrentMajorVersion; + header.minorVersion = QFontEngineQPF2::CurrentMinorVersion; header.dataSize = 0; dev->write((const char *)&header, sizeof(header)); - writeTaggedString(QFontEngineQPA::Tag_FontName, fe->fontDef.family.toUtf8()); + writeTaggedString(QFontEngineQPF2::Tag_FontName, fe->fontDef.family.toUtf8()); QFontEngine::FaceId face = fe->faceId(); - writeTaggedString(QFontEngineQPA::Tag_FileName, face.filename); - writeTaggedUInt32(QFontEngineQPA::Tag_FileIndex, face.index); + writeTaggedString(QFontEngineQPF2::Tag_FileName, face.filename); + writeTaggedUInt32(QFontEngineQPF2::Tag_FileIndex, face.index); { const QByteArray head = fe->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')); if (head.size() >= 4) { const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData())); - writeTaggedUInt32(QFontEngineQPA::Tag_FontRevision, revision); + writeTaggedUInt32(QFontEngineQPF2::Tag_FontRevision, revision); } } - writeTaggedQFixed(QFontEngineQPA::Tag_Ascent, fe->ascent()); - writeTaggedQFixed(QFontEngineQPA::Tag_Descent, fe->descent()); - writeTaggedQFixed(QFontEngineQPA::Tag_Leading, fe->leading()); - writeTaggedQFixed(QFontEngineQPA::Tag_XHeight, fe->xHeight()); - writeTaggedQFixed(QFontEngineQPA::Tag_AverageCharWidth, fe->averageCharWidth()); - writeTaggedQFixed(QFontEngineQPA::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth())); - writeTaggedQFixed(QFontEngineQPA::Tag_LineThickness, fe->lineThickness()); - writeTaggedQFixed(QFontEngineQPA::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing())); - writeTaggedQFixed(QFontEngineQPA::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing())); - writeTaggedQFixed(QFontEngineQPA::Tag_UnderlinePosition, fe->underlinePosition()); - writeTaggedUInt8(QFontEngineQPA::Tag_PixelSize, fe->fontDef.pixelSize); - writeTaggedUInt8(QFontEngineQPA::Tag_Weight, fe->fontDef.weight); - writeTaggedUInt8(QFontEngineQPA::Tag_Style, fe->fontDef.style); - - writeTaggedUInt8(QFontEngineQPA::Tag_GlyphFormat, QFontEngineQPA::AlphamapGlyphs); - - writeTaggedString(QFontEngineQPA::Tag_EndOfHeader, QByteArray()); + writeTaggedQFixed(QFontEngineQPF2::Tag_Ascent, fe->ascent()); + writeTaggedQFixed(QFontEngineQPF2::Tag_Descent, fe->descent()); + writeTaggedQFixed(QFontEngineQPF2::Tag_Leading, fe->leading()); + writeTaggedQFixed(QFontEngineQPF2::Tag_XHeight, fe->xHeight()); + writeTaggedQFixed(QFontEngineQPF2::Tag_AverageCharWidth, fe->averageCharWidth()); + writeTaggedQFixed(QFontEngineQPF2::Tag_MaxCharWidth, QFixed::fromReal(fe->maxCharWidth())); + writeTaggedQFixed(QFontEngineQPF2::Tag_LineThickness, fe->lineThickness()); + writeTaggedQFixed(QFontEngineQPF2::Tag_MinLeftBearing, QFixed::fromReal(fe->minLeftBearing())); + writeTaggedQFixed(QFontEngineQPF2::Tag_MinRightBearing, QFixed::fromReal(fe->minRightBearing())); + writeTaggedQFixed(QFontEngineQPF2::Tag_UnderlinePosition, fe->underlinePosition()); + writeTaggedUInt8(QFontEngineQPF2::Tag_PixelSize, fe->fontDef.pixelSize); + writeTaggedUInt8(QFontEngineQPF2::Tag_Weight, fe->fontDef.weight); + writeTaggedUInt8(QFontEngineQPF2::Tag_Style, fe->fontDef.style); + + writeTaggedUInt8(QFontEngineQPF2::Tag_GlyphFormat, QFontEngineQPF2::AlphamapGlyphs); + + writeTaggedString(QFontEngineQPF2::Tag_EndOfHeader, QByteArray()); align4(); const quint64 size = dev->pos(); @@ -566,11 +566,11 @@ void QPAGenerator::writeHeader() dev->seek(size); } -void QPAGenerator::writeGMap() +void QPF2Generator::writeGMap() { const quint16 glyphCount = fe->glyphCount(); - writeUInt16(QFontEngineQPA::GMapBlock); + writeUInt16(QFontEngineQPF2::GMapBlock); writeUInt16(0); // padding writeUInt32(glyphCount * 4); @@ -582,7 +582,7 @@ void QPAGenerator::writeGMap() dev->seek(pos + numBytes); } -void QPAGenerator::writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &data) +void QPF2Generator::writeBlock(QFontEngineQPF2::BlockTag tag, const QByteArray &data) { writeUInt16(tag); writeUInt16(0); // padding @@ -593,144 +593,32 @@ void QPAGenerator::writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &da writeUInt8(0); } -void QPAGenerator::writeTaggedString(QFontEngineQPA::HeaderTag tag, const QByteArray &string) +void QPF2Generator::writeTaggedString(QFontEngineQPF2::HeaderTag tag, const QByteArray &string) { writeUInt16(tag); writeUInt16(string.length()); dev->write(string); } -void QPAGenerator::writeTaggedUInt32(QFontEngineQPA::HeaderTag tag, quint32 value) +void QPF2Generator::writeTaggedUInt32(QFontEngineQPF2::HeaderTag tag, quint32 value) { writeUInt16(tag); writeUInt16(sizeof(value)); writeUInt32(value); } -void QPAGenerator::writeTaggedUInt8(QFontEngineQPA::HeaderTag tag, quint8 value) +void QPF2Generator::writeTaggedUInt8(QFontEngineQPF2::HeaderTag tag, quint8 value) { writeUInt16(tag); writeUInt16(sizeof(value)); writeUInt8(value); } -void QPAGenerator::writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value) +void QPF2Generator::writeTaggedQFixed(QFontEngineQPF2::HeaderTag tag, QFixed value) { writeUInt16(tag); writeUInt16(sizeof(quint32)); writeUInt32(value.value()); } - -/* - Creates a new multi QPA engine. - - This function takes ownership of the QFontEngine, increasing it's refcount. -*/ -QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script, const QStringList &fallbacks) - : QFontEngineMulti(fallbacks.size() + 1), - fallbackFamilies(fallbacks), script(_script) - , fallbacksQueried(true) -{ - init(fe); -} - -QFontEngineMultiQPA::QFontEngineMultiQPA(QFontEngine *fe, int _script) - : QFontEngineMulti(2) - , script(_script) - , fallbacksQueried(false) -{ - fallbackFamilies << QString(); - init(fe); -} - -void QFontEngineMultiQPA::init(QFontEngine *fe) -{ - Q_ASSERT(fe && fe->type() != QFontEngine::Multi); - engines[0] = fe; - fe->ref.ref(); - fontDef = engines[0]->fontDef; - cache_cost = fe->cache_cost; -} - -void QFontEngineMultiQPA::loadEngine(int at) -{ - ensureFallbackFamiliesQueried(); - Q_ASSERT(at < engines.size()); - Q_ASSERT(engines.at(at) == 0); - QFontDef request = fontDef; - request.styleStrategy |= QFont::NoFontMerging; - request.family = fallbackFamilies.at(at-1); - engines[at] = QFontDatabase::findFont(script, - /*fontprivate = */0, - request, /*multi = */false); - Q_ASSERT(engines[at]); - engines[at]->ref.ref(); - engines[at]->fontDef = request; -} -void QFontEngineMultiQPA::ensureFallbackFamiliesQueried() -{ - if (fallbacksQueried) - return; - QStringList fallbacks = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(engine(0)->fontDef.family, QFont::Style(engine(0)->fontDef.style) - , QFont::AnyStyle, QChar::Script(script)); - setFallbackFamiliesList(fallbacks); -} - -void QFontEngineMultiQPA::setFallbackFamiliesList(const QStringList &fallbacks) -{ - // Original FontEngine to restore after the fill. - QFontEngine *fe = engines[0]; - fallbackFamilies = fallbacks; - if (!fallbackFamilies.isEmpty()) { - engines.fill(0, fallbackFamilies.size() + 1); - engines[0] = fe; - } else { - // Turns out we lied about having any fallback at all. - fallbackFamilies << fe->fontDef.family; - engines[1] = fe; - fe->ref.ref(); - } - fallbacksQueried = true; -} - -/* - This is used indirectly by Qt WebKit when using QTextLayout::setRawFont - - The purpose of this is to provide the necessary font fallbacks when drawing complex - text. Since Qt WebKit ends up repeatedly creating QTextLayout instances and passing them - the same raw font over and over again, we want to cache the corresponding multi font engine - as it may contain fallback font engines already. -*/ -QFontEngine* QFontEngineMultiQPA::createMultiFontEngine(QFontEngine *fe, int script) -{ - QFontEngine *engine = 0; - QFontCache::Key key(fe->fontDef, script, /*multi = */true); - QFontCache *fc = QFontCache::instance(); - // We can't rely on the fontDef (and hence the cache Key) - // alone to distinguish webfonts, since these should not be - // accidentally shared, even if the resulting fontcache key - // is strictly identical. See: - // http://www.w3.org/TR/css3-fonts/#font-face-rule - const bool faceIsLocal = !fe->faceId().filename.isEmpty(); - QFontCache::EngineCache::Iterator it = fc->engineCache.find(key), - end = fc->engineCache.end(); - while (it != end && it.key() == key) { - Q_ASSERT(it.value().data->type() == QFontEngine::Multi); - QFontEngineMulti *cachedEngine = static_cast<QFontEngineMulti *>(it.value().data); - if (faceIsLocal || fe == cachedEngine->engine(0)) { - engine = cachedEngine; - fc->updateHitCountAndTimeStamp(it.value()); - break; - } - it++; - } - if (!engine) { - engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); - QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); - } - Q_ASSERT(engine); - return engine; -} - QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_qpa_p.h b/src/gui/text/qfontengine_qpf2_p.h index e84b067c68..a616cc3300 100644 --- a/src/gui/text/qfontengine_qpa_p.h +++ b/src/gui/text/qfontengine_qpf2_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QFONTENGINE_QPA_P_H -#define QFONTENGINE_QPA_P_H +#ifndef QFONTENGINE_QPF2_P_H +#define QFONTENGINE_QPF2_P_H // // W A R N I N G @@ -67,7 +67,7 @@ class QFontEngine; class QFreetypeFace; class QBuffer; -class Q_GUI_EXPORT QFontEngineQPA : public QFontEngine +class Q_GUI_EXPORT QFontEngineQPF2 : public QFontEngine { public: // if you add new tags please make sure to update the tables in @@ -157,8 +157,8 @@ public: qint8 advance; }; - QFontEngineQPA(const QFontDef &def, const QByteArray &data); - ~QFontEngineQPA(); + QFontEngineQPF2(const QFontDef &def, const QByteArray &data); + ~QFontEngineQPF2(); FaceId faceId() const { return face_id; } bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; @@ -211,20 +211,20 @@ private: mutable bool kerning_pairs_loaded; }; -struct QPAGenerator +struct QPF2Generator { - QPAGenerator(QBuffer *device, QFontEngine *engine) + QPF2Generator(QBuffer *device, QFontEngine *engine) : dev(device), fe(engine) {} void generate(); void writeHeader(); void writeGMap(); - void writeBlock(QFontEngineQPA::BlockTag tag, const QByteArray &data); + void writeBlock(QFontEngineQPF2::BlockTag tag, const QByteArray &data); - void writeTaggedString(QFontEngineQPA::HeaderTag tag, const QByteArray &string); - void writeTaggedUInt32(QFontEngineQPA::HeaderTag tag, quint32 value); - void writeTaggedUInt8(QFontEngineQPA::HeaderTag tag, quint8 value); - void writeTaggedQFixed(QFontEngineQPA::HeaderTag tag, QFixed value); + void writeTaggedString(QFontEngineQPF2::HeaderTag tag, const QByteArray &string); + void writeTaggedUInt32(QFontEngineQPF2::HeaderTag tag, quint32 value); + void writeTaggedUInt8(QFontEngineQPF2::HeaderTag tag, quint8 value); + void writeTaggedQFixed(QFontEngineQPF2::HeaderTag tag, QFixed value); void writeUInt16(quint16 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); } void writeUInt32(quint32 value) { value = qToBigEndian(value); dev->write((const char *)&value, sizeof(value)); } @@ -237,29 +237,6 @@ struct QPAGenerator QFontEngine *fe; }; -class Q_GUI_EXPORT QFontEngineMultiQPA : public QFontEngineMulti -{ -public: - QFontEngineMultiQPA(QFontEngine *fe, int script, const QStringList &fallbacks); - QFontEngineMultiQPA(QFontEngine *fe, int script); - - void loadEngine(int at); - static QFontEngine* createMultiFontEngine(QFontEngine *fe, int script); - - int fallbackFamilyCount() const { return fallbackFamilies.size(); } - QString fallbackFamilyAt(int at) const { return fallbackFamilies.at(at); } - - virtual void ensureFallbackFamiliesQueried(); - virtual void setFallbackFamiliesList(const QStringList &fallbacks); - -private: - void init(QFontEngine *fe); - - mutable QStringList fallbackFamilies; - int script; - mutable bool fallbacksQueried; -}; - QT_END_NAMESPACE -#endif // QFONTENGINE_QPA_P_H +#endif // QFONTENGINE_QPF2_P_H diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp index 33301005c6..e9ffa68591 100644 --- a/src/gui/text/qplatformfontdatabase.cpp +++ b/src/gui/text/qplatformfontdatabase.cpp @@ -41,7 +41,7 @@ #include "qplatformfontdatabase.h" #include <QtGui/private/qfontengine_p.h> -#include <QtGui/private/qfontengine_qpa_p.h> +#include <QtGui/private/qfontengine_qpf2_p.h> #include <QtCore/QLibraryInfo> #include <QtCore/QDir> @@ -69,12 +69,12 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * return; const uchar *data = reinterpret_cast<const uchar *>(dataArray.constData()); - if (QFontEngineQPA::verifyHeader(data, dataArray.size())) { - QString fontName = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_FontName).toString(); - int pixelSize = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_PixelSize).toInt(); - QVariant weight = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Weight); - QVariant style = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_Style); - QByteArray writingSystemBits = QFontEngineQPA::extractHeaderField(data, QFontEngineQPA::Tag_WritingSystems).toByteArray(); + if (QFontEngineQPF2::verifyHeader(data, dataArray.size())) { + QString fontName = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_FontName).toString(); + int pixelSize = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_PixelSize).toInt(); + QVariant weight = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_Weight); + QVariant style = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_Style); + QByteArray writingSystemBits = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_WritingSystems).toByteArray(); if (!fontName.isEmpty() && pixelSize) { QFont::Weight fontWeight = QFont::Normal; @@ -322,7 +322,7 @@ void QPlatformFontDatabase::invalidate() */ QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) { - return new QFontEngineMultiQPA(fontEngine, script); + return new QFontEngineMultiBasicImpl(fontEngine, script); } /*! @@ -332,7 +332,7 @@ QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) { QByteArray *fileDataPtr = static_cast<QByteArray *>(handle); - QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr); + QFontEngineQPF2 *engine = new QFontEngineQPF2(fontDef,*fileDataPtr); //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family; return engine; } diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index f789ec596b..9b24742823 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -47,6 +47,10 @@ #include "qrawfont_p.h" #include "qplatformfontdatabase.h" +#include <private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformfontdatabase.h> + #include <QtCore/qendian.h> QT_BEGIN_NAMESPACE @@ -252,7 +256,7 @@ void QRawFont::loadFromData(const QByteArray &fontData, d->cleanUp(); d->hintingPreference = hintingPreference; d->thread = QThread::currentThread(); - d->platformLoadFromData(fontData, pixelSize, hintingPreference); + d->loadFromData(fontData, pixelSize, hintingPreference); } /*! @@ -735,7 +739,6 @@ void QRawFont::setPixelSize(qreal pixelSize) */ void QRawFontPrivate::cleanUp() { - platformCleanUp(); if (fontEngine != 0) { if (!fontEngine->ref.deref()) delete fontEngine; @@ -744,6 +747,17 @@ void QRawFontPrivate::cleanUp() hintingPreference = QFont::PreferDefaultHinting; } +void QRawFontPrivate::loadFromData(const QByteArray &fontData, qreal pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_ASSERT(fontEngine == 0); + + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); + if (fontEngine != 0) + fontEngine->ref.ref(); +} + /*! Returns the smallest rectangle containing the glyph with the given \a glyphIndex. diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index c9c15717cc..b13454c391 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -95,8 +95,7 @@ public: } void cleanUp(); - void platformCleanUp(); - void platformLoadFromData(const QByteArray &fontData, + void loadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp deleted file mode 100644 index 7de6ef0e8b..0000000000 --- a/src/gui/text/qrawfont_qpa.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qglobal.h> - -#if !defined(QT_NO_RAWFONT) - -#include "qrawfont_p.h" -#include <qpa/qplatformintegration.h> -#include <qpa/qplatformfontdatabase.h> -#include <private/qguiapplication_p.h> - -QT_BEGIN_NAMESPACE - -void QRawFontPrivate::platformCleanUp() -{ -} - -void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize, - QFont::HintingPreference hintingPreference) -{ - Q_ASSERT(fontEngine == 0); - - QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); - fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); - if (fontEngine != 0) - fontEngine->ref.ref(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 67dedca760..0928a22352 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -59,10 +59,6 @@ #include <algorithm> #include <stdlib.h> -#ifndef QT_NO_RAWFONT -#include "qfontengine_qpa_p.h" -#endif - QT_BEGIN_NAMESPACE static const float smallCapsFraction = 0.7f; @@ -88,7 +84,7 @@ public: /// The caps parameter is used to choose the algoritm of splitting text and assiging roles to the textitems void generate(int start, int length, QFont::Capitalization caps) { - if ((int)caps == (int)QFont::SmallCaps) + if (caps == QFont::SmallCaps) generateScriptItemsSmallCaps(reinterpret_cast<const ushort *>(m_string.unicode()), start, length); else if(caps == QFont::Capitalize) generateScriptItemsCapitalize(start, length); @@ -122,9 +118,7 @@ private: return; const int end = start + length; for (int i = start + 1; i < end; ++i) { - if (m_analysis[i].bidiLevel == m_analysis[start].bidiLevel - && m_analysis[i].flags == m_analysis[start].flags - && m_analysis[i].script == m_analysis[start].script + if (m_analysis[i] == m_analysis[start] && m_analysis[i].flags < QScriptAnalysis::SpaceTabOrObject && i - start < MaxItemLength) continue; @@ -1420,8 +1414,6 @@ void QTextEngine::invalidate() freeMemory(); minWidth = 0; maxWidth = 0; - if (specialData) - specialData->resolvedFormats.clear(); resetFontEngineCache(); } @@ -1582,9 +1574,9 @@ void QTextEngine::itemize() const } Q_ASSERT(position <= length); QFont::Capitalization capitalization = - formats()->charFormat(format).hasProperty(QTextFormat::FontCapitalization) - ? formats()->charFormat(format).fontCapitalization() - : formats()->defaultFont().capitalization(); + formatCollection()->charFormat(format).hasProperty(QTextFormat::FontCapitalization) + ? formatCollection()->charFormat(format).fontCapitalization() + : formatCollection()->defaultFont().capitalization(); itemizer.generate(prevPosition, position - prevPosition, capitalization); if (it == end) { if (position < length) @@ -1601,8 +1593,8 @@ void QTextEngine::itemize() const #ifndef QT_NO_RAWFONT if (useRawFont && specialData) { int lastIndex = 0; - for (int i = 0; i < specialData->addFormats.size(); ++i) { - const QTextLayout::FormatRange &range = specialData->addFormats.at(i); + for (int i = 0; i < specialData->formats.size(); ++i) { + const QTextLayout::FormatRange &range = specialData->formats.at(i); const QTextCharFormat &format = range.format; if (format.hasProperty(QTextFormat::FontCapitalization)) { itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase); @@ -1617,7 +1609,7 @@ void QTextEngine::itemize() const } addRequiredBoundaries(); - resolveAdditionalFormats(); + resolveFormats(); } bool QTextEngine::isRightToLeft() const @@ -1880,7 +1872,7 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix if (feCache.prevFontEngine && feCache.prevFontEngine->type() == QFontEngine::Multi && feCache.prevScript == script) { engine = feCache.prevFontEngine; } else { - engine = QFontEngineMultiQPA::createMultiFontEngine(rawFont.d->fontEngine, script); + engine = QFontEngineMultiBasicImpl::createMultiFontEngine(rawFont.d->fontEngine, script); feCache.prevFontEngine = engine; feCache.prevScript = script; engine->ref.ref(); @@ -1889,13 +1881,13 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix feCache.prevScaledFontEngine = 0; } } - if (si.analysis.flags & QFont::SmallCaps) { + if (si.analysis.flags == QScriptAnalysis::SmallCaps) { if (feCache.prevScaledFontEngine) { scaledEngine = feCache.prevScaledFontEngine; } else { QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize()); scEngine->ref.ref(); - scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script); + scaledEngine = QFontEngineMultiBasicImpl::createMultiFontEngine(scEngine, script); scaledEngine->ref.ref(); feCache.prevScaledFontEngine = scaledEngine; // If scEngine is not ref'ed by scaledEngine, make sure it is deallocated and not leaked. @@ -2363,6 +2355,8 @@ void QTextEngine::freeMemory() layoutData->haveCharAttributes = false; layoutData->items.clear(); } + if (specialData) + specialData->resolvedFormats.clear(); for (int i = 0; i < lines.size(); ++i) { lines[i].justified = 0; lines[i].gridfitted = 0; @@ -2372,7 +2366,7 @@ void QTextEngine::freeMemory() int QTextEngine::formatIndex(const QScriptItem *si) const { if (specialData && !specialData->resolvedFormats.isEmpty()) { - QTextFormatCollection *collection = formats(); + QTextFormatCollection *collection = formatCollection(); Q_ASSERT(collection); return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0])); } @@ -2394,16 +2388,16 @@ int QTextEngine::formatIndex(const QScriptItem *si) const QTextCharFormat QTextEngine::format(const QScriptItem *si) const { - if (const QTextFormatCollection *formats = this->formats()) - return formats->charFormat(formatIndex(si)); + if (const QTextFormatCollection *collection = formatCollection()) + return collection->charFormat(formatIndex(si)); return QTextCharFormat(); } void QTextEngine::addRequiredBoundaries() const { if (specialData) { - for (int i = 0; i < specialData->addFormats.size(); ++i) { - const QTextLayout::FormatRange &r = specialData->addFormats.at(i); + for (int i = 0; i < specialData->formats.size(); ++i) { + const QTextLayout::FormatRange &r = specialData->formats.at(i); setBoundary(r.start); setBoundary(r.start + r.length); //qDebug("adding boundaries %d %d", r.start, r.start+r.length); @@ -2472,7 +2466,7 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText) if (preeditText.isEmpty()) { if (!specialData) return; - if (specialData->addFormats.isEmpty()) { + if (specialData->formats.isEmpty()) { delete specialData; specialData = 0; } else { @@ -2489,41 +2483,41 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText) clearLineData(); } -void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList) +void QTextEngine::setFormats(const QList<QTextLayout::FormatRange> &formats) { - if (formatList.isEmpty()) { + if (formats.isEmpty()) { if (!specialData) return; if (specialData->preeditText.isEmpty()) { delete specialData; specialData = 0; } else { - specialData->addFormats.clear(); + specialData->formats.clear(); } } else { if (!specialData) { specialData = new SpecialData; specialData->preeditPosition = -1; } - specialData->addFormats = formatList; - indexAdditionalFormats(); + specialData->formats = formats; + indexFormats(); } invalidate(); clearLineData(); } -void QTextEngine::indexAdditionalFormats() +void QTextEngine::indexFormats() { - QTextFormatCollection *collection = formats(); + QTextFormatCollection *collection = formatCollection(); if (!collection) { Q_ASSERT(!block.docHandle()); - specialData->formats.reset(new QTextFormatCollection); - collection = specialData->formats.data(); + specialData->formatCollection.reset(new QTextFormatCollection); + collection = specialData->formatCollection.data(); } // replace with shared copies - for (int i = 0; i < specialData->addFormats.count(); ++i) { - QTextCharFormat &format = specialData->addFormats[i].format; + for (int i = 0; i < specialData->formats.size(); ++i) { + QTextCharFormat &format = specialData->formats[i].format; format = collection->charFormat(collection->indexForFormat(format)); } } @@ -2928,45 +2922,44 @@ public: }; } -void QTextEngine::resolveAdditionalFormats() const +void QTextEngine::resolveFormats() const { - if (!specialData || specialData->addFormats.isEmpty() - || !specialData->resolvedFormats.isEmpty()) + if (!specialData || specialData->formats.isEmpty()) return; + Q_ASSERT(specialData->resolvedFormats.isEmpty()); - QTextFormatCollection *collection = formats(); + QTextFormatCollection *collection = formatCollection(); - specialData->resolvedFormats.clear(); QVector<QTextCharFormat> resolvedFormats(layoutData->items.count()); - QVarLengthArray<int, 64> addFormatSortedByStart; - addFormatSortedByStart.reserve(specialData->addFormats.count()); - for (int i = 0; i < specialData->addFormats.count(); ++i) { - if (specialData->addFormats.at(i).length >= 0) - addFormatSortedByStart.append(i); + QVarLengthArray<int, 64> formatsSortedByStart; + formatsSortedByStart.reserve(specialData->formats.size()); + for (int i = 0; i < specialData->formats.size(); ++i) { + if (specialData->formats.at(i).length >= 0) + formatsSortedByStart.append(i); } - QVarLengthArray<int, 64> addFormatSortedByEnd = addFormatSortedByStart; - std::sort(addFormatSortedByStart.begin(), addFormatSortedByStart.end(), - FormatRangeComparatorByStart(specialData->addFormats)); - std::sort(addFormatSortedByEnd.begin(), addFormatSortedByEnd.end(), - FormatRangeComparatorByEnd(specialData->addFormats)); + QVarLengthArray<int, 64> formatsSortedByEnd = formatsSortedByStart; + std::sort(formatsSortedByStart.begin(), formatsSortedByStart.end(), + FormatRangeComparatorByStart(specialData->formats)); + std::sort(formatsSortedByEnd.begin(), formatsSortedByEnd.end(), + FormatRangeComparatorByEnd(specialData->formats)); QVarLengthArray<int, 16> currentFormats; - const int *startIt = addFormatSortedByStart.constBegin(); - const int *endIt = addFormatSortedByEnd.constBegin(); + const int *startIt = formatsSortedByStart.constBegin(); + const int *endIt = formatsSortedByEnd.constBegin(); for (int i = 0; i < layoutData->items.count(); ++i) { const QScriptItem *si = &layoutData->items.at(i); int end = si->position + length(si); - while (startIt != addFormatSortedByStart.constEnd() && - specialData->addFormats.at(*startIt).start <= si->position) { + while (startIt != formatsSortedByStart.constEnd() && + specialData->formats.at(*startIt).start <= si->position) { currentFormats.insert(std::upper_bound(currentFormats.begin(), currentFormats.end(), *startIt), *startIt); ++startIt; } - while (endIt != addFormatSortedByEnd.constEnd() && - specialData->addFormats.at(*endIt).start + specialData->addFormats.at(*endIt).length < end) { + while (endIt != formatsSortedByEnd.constEnd() && + specialData->formats.at(*endIt).start + specialData->formats.at(*endIt).length < end) { int *currentFormatIterator = std::lower_bound(currentFormats.begin(), currentFormats.end(), *endIt); if (*endIt < *currentFormatIterator) currentFormatIterator = currentFormats.end(); @@ -2982,7 +2975,7 @@ void QTextEngine::resolveAdditionalFormats() const } if (!currentFormats.isEmpty()) { foreach (int cur, currentFormats) { - const QTextLayout::FormatRange &range = specialData->addFormats.at(cur); + const QTextLayout::FormatRange &range = specialData->formats.at(cur); Q_ASSERT(range.start <= si->position && range.start + range.length >= end); format.merge(range.format); } @@ -3482,15 +3475,15 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co logicalItem(-1), item(-1), visualOrder(nItems), - levels(nItems), selection(_selection) { - pos_x = x = QFixed::fromReal(pos.x()); + x = QFixed::fromReal(pos.x()); x += line.x; x += eng->alignLine(line); + QVarLengthArray<uchar> levels(nItems); for (int i = 0; i < nItems; ++i) levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); @@ -3561,7 +3554,7 @@ bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selec return false; int start_glyph = logClusters[from]; - int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to]; + int end_glyph = (to == itemLength) ? si->num_glyphs : logClusters[to]; QFixed soff; QFixed swidth; if (si->analysis.bidiLevel %2) { @@ -3586,7 +3579,7 @@ bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selec // If the ending character is also part of a ligature, swidth does // not contain that part yet, we also need to find out the width of // that left part - *selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph); + *selectionWidth += eng->offsetInLigature(si, to, itemLength, end_glyph); } return true; } diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 342a94de66..29aa9597db 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -505,10 +505,10 @@ public: void freeMemory(); int findItem(int strPos) const; - inline QTextFormatCollection *formats() const { + inline QTextFormatCollection *formatCollection() const { if (block.docHandle()) return block.docHandle()->formatCollection(); - return specialData ? specialData->formats.data() : 0; + return specialData ? specialData->formatCollection.data() : 0; } QTextCharFormat format(const QScriptItem *si) const; inline QAbstractTextDocumentLayout *docLayout() const { @@ -572,19 +572,17 @@ public: ItemDecorationList overlineList; inline bool visualCursorMovement() const - { - return (visualMovement || - (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle : false)); - } + { return visualMovement || (block.docHandle() && block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle); } inline int preeditAreaPosition() const { return specialData ? specialData->preeditPosition : -1; } inline QString preeditAreaText() const { return specialData ? specialData->preeditText : QString(); } void setPreeditArea(int position, const QString &text); - inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); } - inline QList<QTextLayout::FormatRange> additionalFormats() const - { return specialData ? specialData->addFormats : QList<QTextLayout::FormatRange>(); } - void setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList); + inline bool hasFormats() const + { return block.docHandle() || (specialData && !specialData->formats.isEmpty()); } + inline QList<QTextLayout::FormatRange> formats() const + { return specialData ? specialData->formats : QList<QTextLayout::FormatRange>(); } + void setFormats(const QList<QTextLayout::FormatRange> &formats); private: static void init(QTextEngine *e); @@ -592,15 +590,15 @@ private: struct SpecialData { int preeditPosition; QString preeditText; - QList<QTextLayout::FormatRange> addFormats; + QList<QTextLayout::FormatRange> formats; QVector<QTextCharFormat> resolvedFormats; // only used when no docHandle is available - QScopedPointer<QTextFormatCollection> formats; + QScopedPointer<QTextFormatCollection> formatCollection; }; SpecialData *specialData; - void indexAdditionalFormats(); - void resolveAdditionalFormats() const; + void indexFormats(); + void resolveFormats() const; public: bool atWordSeparator(int position) const; @@ -676,15 +674,14 @@ struct QTextLineItemIterator QTextEngine *eng; QFixed x; - QFixed pos_x; const QScriptLine &line; QScriptItem *si; - int lineNum; - int lineEnd; - int firstItem; - int lastItem; - int nItems; + const int lineNum; + const int lineEnd; + const int firstItem; + const int lastItem; + const int nItems; int logicalItem; int item; int itemLength; @@ -697,7 +694,6 @@ struct QTextLineItemIterator QFixed itemWidth; QVarLengthArray<int> visualOrder; - QVarLengthArray<uchar> levels; const QTextLayout::FormatRange *selection; }; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 84ad9038d5..912ab05a59 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -500,7 +500,7 @@ QString QTextLayout::preeditAreaText() const */ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList) { - d->setAdditionalFormats(formatList); + d->setFormats(formatList); if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); @@ -513,7 +513,7 @@ void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList) */ QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const { - return d->additionalFormats(); + return d->formats(); } /*! @@ -562,7 +562,7 @@ bool QTextLayout::cacheEnabled() const */ void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style) { - d->visualMovement = style == Qt::VisualMoveStyle ? true : false; + d->visualMovement = style == Qt::VisualMoveStyle; } /*! @@ -2198,14 +2198,10 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const if (si.analysis.flags >= QScriptAnalysis::TabOrObject) continue; - QPointF pos(iterator.x.toReal(), y); - if (from >= 0 && length >= 0 && - (from >= si.position + eng->length(&si) - || from + length <= si.position - || from + length <= iterator.itemStart - || from >= iterator.itemEnd)) { + if (from >= 0 && length >= 0 && (from >= iterator.itemEnd || from + length <= iterator.itemStart)) continue; - } + + QPointF pos(iterator.x.toReal(), y); QFont font; QGlyphRun::GlyphRunFlags flags; @@ -2226,15 +2222,13 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const } int relativeFrom = qMax(iterator.itemStart, from) - si.position; - int relativeTo = qMin(iterator.itemEnd - 1, from + length - 1) - si.position; + int relativeTo = qMin(iterator.itemEnd, from + length) - 1 - si.position; unsigned short *logClusters = eng->logClusters(&si); int glyphsStart = logClusters[relativeFrom]; - int glyphsEnd = (relativeTo == eng->length(&si)) - ? si.num_glyphs - 1 - : logClusters[relativeTo]; + int glyphsEnd = (relativeTo == iterator.itemLength) ? si.num_glyphs - 1 : logClusters[relativeTo]; // the glyph index right next to the requested range - int nextGlyphIndex = relativeTo < eng->length(&si) - 1 ? logClusters[relativeTo + 1] : si.num_glyphs; + int nextGlyphIndex = (relativeTo < iterator.itemLength - 1) ? logClusters[relativeTo + 1] : si.num_glyphs; if (nextGlyphIndex - 1 > glyphsEnd) glyphsEnd = nextGlyphIndex - 1; bool startsInsideLigature = relativeFrom > 0 && logClusters[relativeFrom - 1] == glyphsStart; diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index c67769ad48..091129f5be 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -77,10 +77,8 @@ SOURCES += \ text/qdistancefield.cpp SOURCES += \ - text/qfont_qpa.cpp \ - text/qfontengine_qpa.cpp \ - text/qplatformfontdatabase.cpp \ - text/qrawfont_qpa.cpp + text/qfontengine_qpf2.cpp \ + text/qplatformfontdatabase.cpp HEADERS += \ text/qplatformfontdatabase.h diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 87146118db..460646324f 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -314,7 +314,7 @@ extern Q_CORE_EXPORT QString qt_applicationName_noFallback(); QString QDesktopServices::storageLocationImpl(QStandardPaths::StandardLocation type) { - if (type == QStandardPaths::DataLocation) { + if (type == QStandardPaths::AppLocalDataLocation) { // Preserve Qt 4 compatibility: // * QCoreApplication::applicationName() must default to empty // * Unix data location is under the "data/" subdirectory diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp index 10b4a2ee35..7170477e84 100644 --- a/src/gui/util/qgridlayoutengine.cpp +++ b/src/gui/util/qgridlayoutengine.cpp @@ -983,9 +983,10 @@ void QGridLayoutEngine::invalidate() q_cachedEffectiveFirstRows[Ver] = -1; q_cachedEffectiveLastRows[Hor] = -1; q_cachedEffectiveLastRows[Ver] = -1; - q_totalBoxesValid = false; - q_sizeHintValid[Hor] = false; - q_sizeHintValid[Ver] = false; + + q_totalBoxCachedConstraints[Hor] = NotCached; + q_totalBoxCachedConstraints[Ver] = NotCached; + q_cachedSize = QSizeF(); q_cachedConstraintOrientation = UnknownConstraint; } @@ -1530,7 +1531,11 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri const QAbstractLayoutStyleInfo *styleInfo) const { const int o = (orientation == Qt::Vertical ? Ver : Hor); - if (q_sizeHintValid[o] && !colPositions && !colSizes) { + const int cc = columnCount(orientation); + + const qreal constraint = (colPositions && colSizes && hasDynamicConstraint()) ? (colPositions[cc - 1] + colSizes[cc - 1]) : qreal(CachedWithNoConstraint); + qreal &cachedConstraint = q_totalBoxCachedConstraints[o]; + if (cachedConstraint == constraint) { if (totalBox != &q_totalBoxes[o]) *totalBox = q_totalBoxes[o]; return; @@ -1541,10 +1546,10 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri rowData->distributeMultiCells(rowInfo); *totalBox = rowData->totalBox(0, rowCount(orientation)); - if (!colPositions && !colSizes) { + if (totalBox != &q_totalBoxes[o]) q_totalBoxes[o] = *totalBox; - q_sizeHintValid[o] = true; - } + + cachedConstraint = constraint; } /** @@ -1593,10 +1598,9 @@ Qt::Orientation QGridLayoutEngine::constraintOrientation() const void QGridLayoutEngine::ensureGeometries(const QSizeF &size, const QAbstractLayoutStyleInfo *styleInfo) const { - if (!styleInfo->hasChanged() && q_totalBoxesValid && q_cachedSize == size) + if (!styleInfo->hasChanged() && q_cachedSize == size) return; - q_totalBoxesValid = true; q_cachedSize = size; q_xx.resize(columnCount()); @@ -1606,7 +1610,7 @@ void QGridLayoutEngine::ensureGeometries(const QSizeF &size, q_descents.resize(rowCount()); if (constraintOrientation() != Qt::Horizontal) { - //We might have items whose width depends on their height + //We might have items whose height depends on their width (HFW) ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo); //Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as //constraints to find the row heights @@ -1617,7 +1621,7 @@ void QGridLayoutEngine::ensureGeometries(const QSizeF &size, q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]); } else { - //We have items whose height depends on their width + //We have items whose width depends on their height (WFH) ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo); //Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as //constraints to find the column widths diff --git a/src/gui/util/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h index 9650e7fffe..bbc94bd51f 100644 --- a/src/gui/util/qgridlayoutengine_p.h +++ b/src/gui/util/qgridlayoutengine_p.h @@ -450,15 +450,21 @@ private: mutable int q_cachedEffectiveLastRows[NOrientations]; mutable quint8 q_cachedConstraintOrientation : 3; + // this is useful to cache + mutable QGridLayoutBox q_totalBoxes[NOrientations]; + enum { + NotCached = -2, // Cache is empty. Happens when the engine is invalidated. + CachedWithNoConstraint = -1 // cache has a totalBox without any HFW/WFH constraints. + // >= 0 // cache has a totalBox with this specific constraint. + }; + mutable qreal q_totalBoxCachedConstraints[NOrientations]; // holds the constraint used for the cached totalBox + // Layout item input mutable QGridLayoutRowData q_columnData; mutable QGridLayoutRowData q_rowData; - mutable QGridLayoutBox q_totalBoxes[NOrientations]; // Output mutable QSizeF q_cachedSize; - mutable bool q_totalBoxesValid; - mutable bool q_sizeHintValid[NOrientations]; mutable QVector<qreal> q_xx; mutable QVector<qreal> q_yy; mutable QVector<qreal> q_widths; |