diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qhighdpiscaling.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qhighdpiscaling_p.h | 44 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 289 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.h | 1 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture_p.h | 2 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexturehelper_p.h | 37 | ||||
-rw-r--r-- | src/gui/painting/qpdf.cpp | 28 | ||||
-rw-r--r-- | src/gui/painting/qpdf_p.h | 2 |
8 files changed, 347 insertions, 58 deletions
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 19e3045fc9..de586ac46c 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcScaling, "qt.scaling"); +#ifndef QT_NO_HIGHDPISCALING static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO"; static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR"; static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR"; @@ -317,4 +318,5 @@ QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen) return platformScreen->geometry().topLeft(); } +#endif //QT_NO_HIGHDPISCALING QT_END_NAMESPACE diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index c79540d9e4..9e33787f53 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -62,6 +62,7 @@ class QScreen; class QPlatformScreen; typedef QPair<qreal, qreal> QDpi; +#ifndef QT_NO_HIGHDPISCALING class Q_GUI_EXPORT QHighDpiScaling { public: static void initHighDpiScaling(); @@ -464,7 +465,50 @@ QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window) } } // namespace QHighDpi +#else // QT_NO_HIGHDPISCALING +class Q_GUI_EXPORT QHighDpiScaling { +public: + static inline void initHighDpiScaling() {} + static inline void updateHighDpiScaling() {} + static inline void setGlobalFactor(qreal) {} + static inline void setScreenFactor(QScreen *, qreal) {} + + static inline bool isActive() { return false; } + static inline qreal factor(const QWindow *) { return 1.0; } + static inline qreal factor(const QScreen *) { return 1.0; } + static inline qreal factor(const QPlatformScreen *) { return 1.0; } + static inline QPoint origin(const QScreen *) { return QPoint(); } + static inline QPoint origin(const QPlatformScreen *) { return QPoint(); } + static inline QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *) { return pos; } + static inline QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *) { return pos; } + static inline QDpi logicalDpi() { return QDpi(-1,-1); } +}; +namespace QHighDpi { + template <typename T> inline + T toNative(const T &value, ...) { return value; } + template <typename T> inline + T fromNative(const T &value, ...) { return value; } + + template <typename T> inline + T fromNativeLocalPosition(const T &value, ...) { return value; } + template <typename T> inline + T toNativeLocalPosition(const T &value, ...) { return value; } + + template <typename T> inline + T fromNativeLocalRegion(const T &value, ...) { return value; } + template <typename T> inline + T toNativeLocalRegion(const T &value, ...) { return value; } + + template <typename T> inline + T fromNativeScreenGeometry(const T &value, ...) { return value; } + + template <typename T, typename U> inline + T toNativePixels(const T &value, const U*) {return value;} + template <typename T, typename U> inline + T fromNativePixels(const T &value, const U*) {return value;} +} +#endif // QT_NO_HIGHDPISCALING QT_END_NAMESPACE #endif // QHIGHDPISCALING_P_H diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5271826015..301b2ad13d 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -401,6 +401,9 @@ static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat) case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: return true; + case QOpenGLTexture::RGB8_ETC1: + return false; + case QOpenGLTexture::DepthFormat: case QOpenGLTexture::AlphaFormat: @@ -442,20 +445,23 @@ static bool isTextureTargetMultisample(QOpenGLTexture::Target target) return false; } -void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) +bool QOpenGLTexturePrivate::isUsingImmutableStorage() const { - // Resolve the actual number of mipmap levels we can use - mipLevels = evaluateMipLevels(); - // Use immutable storage whenever possible, falling back to mutable // Note that if multisample textures are not supported at all, we'll still fail into // the mutable storage allocation - const bool useImmutableStorage = isSizedTextureFormat(format) + return isSizedTextureFormat(format) && (isTextureTargetMultisample(target) ? features.testFlag(QOpenGLTexture::ImmutableMultisampleStorage) : features.testFlag(QOpenGLTexture::ImmutableStorage)); +} + +void QOpenGLTexturePrivate::allocateStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) +{ + // Resolve the actual number of mipmap levels we can use + mipLevels = evaluateMipLevels(); - if (useImmutableStorage) + if (isUsingImmutableStorage()) allocateImmutableStorage(); else allocateMutableStorage(pixelFormat, pixelType); @@ -663,6 +669,7 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen case QOpenGLTexture::SRGB_Alpha_DXT3: case QOpenGLTexture::SRGB_Alpha_DXT5: case QOpenGLTexture::SRGB_BP_UNorm: + case QOpenGLTexture::RGB8_ETC1: return QOpenGLTexture::RGBA; case QOpenGLTexture::R11_EAC_UNorm: @@ -840,6 +847,7 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: case QOpenGLTexture::RGBA8_ETC2_EAC: case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: return QOpenGLTexture::UInt8; case QOpenGLTexture::DepthFormat: @@ -857,8 +865,133 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe return QOpenGLTexture::NoPixelType; } +static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat) +{ + switch (internalFormat) { + case QOpenGLTexture::NoFormat: + + case QOpenGLTexture::R8_UNorm: + case QOpenGLTexture::RG8_UNorm: + case QOpenGLTexture::RGB8_UNorm: + case QOpenGLTexture::RGBA8_UNorm: + case QOpenGLTexture::R16_UNorm: + case QOpenGLTexture::RG16_UNorm: + case QOpenGLTexture::RGB16_UNorm: + case QOpenGLTexture::RGBA16_UNorm: + case QOpenGLTexture::R8_SNorm: + case QOpenGLTexture::RG8_SNorm: + case QOpenGLTexture::RGB8_SNorm: + case QOpenGLTexture::RGBA8_SNorm: + case QOpenGLTexture::R16_SNorm: + case QOpenGLTexture::RG16_SNorm: + case QOpenGLTexture::RGB16_SNorm: + case QOpenGLTexture::RGBA16_SNorm: + case QOpenGLTexture::R8U: + case QOpenGLTexture::RG8U: + case QOpenGLTexture::RGB8U: + case QOpenGLTexture::RGBA8U: + case QOpenGLTexture::R16U: + case QOpenGLTexture::RG16U: + case QOpenGLTexture::RGB16U: + case QOpenGLTexture::RGBA16U: + case QOpenGLTexture::R32U: + case QOpenGLTexture::RG32U: + case QOpenGLTexture::RGB32U: + case QOpenGLTexture::RGBA32U: + case QOpenGLTexture::R8I: + case QOpenGLTexture::RG8I: + case QOpenGLTexture::RGB8I: + case QOpenGLTexture::RGBA8I: + case QOpenGLTexture::R16I: + case QOpenGLTexture::RG16I: + case QOpenGLTexture::RGB16I: + case QOpenGLTexture::RGBA16I: + case QOpenGLTexture::R32I: + case QOpenGLTexture::RG32I: + case QOpenGLTexture::RGB32I: + case QOpenGLTexture::RGBA32I: + case QOpenGLTexture::R16F: + case QOpenGLTexture::RG16F: + case QOpenGLTexture::RGB16F: + case QOpenGLTexture::RGBA16F: + case QOpenGLTexture::R32F: + case QOpenGLTexture::RG32F: + case QOpenGLTexture::RGB32F: + case QOpenGLTexture::RGBA32F: + case QOpenGLTexture::RGB9E5: + case QOpenGLTexture::RG11B10F: + case QOpenGLTexture::RG3B2: + case QOpenGLTexture::R5G6B5: + case QOpenGLTexture::RGB5A1: + case QOpenGLTexture::RGBA4: + case QOpenGLTexture::RGB10A2: + + case QOpenGLTexture::D16: + case QOpenGLTexture::D24: + case QOpenGLTexture::D32: + case QOpenGLTexture::D32F: + + case QOpenGLTexture::D24S8: + case QOpenGLTexture::D32FS8X24: + + case QOpenGLTexture::S8: + return false; + + case QOpenGLTexture::RGB_DXT1: + case QOpenGLTexture::RGBA_DXT1: + case QOpenGLTexture::RGBA_DXT3: + case QOpenGLTexture::RGBA_DXT5: + case QOpenGLTexture::R_ATI1N_UNorm: + case QOpenGLTexture::R_ATI1N_SNorm: + case QOpenGLTexture::RG_ATI2N_UNorm: + case QOpenGLTexture::RG_ATI2N_SNorm: + case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT: + case QOpenGLTexture::RGB_BP_SIGNED_FLOAT: + case QOpenGLTexture::RGB_BP_UNorm: + case QOpenGLTexture::SRGB8: + case QOpenGLTexture::SRGB8_Alpha8: + case QOpenGLTexture::SRGB_DXT1: + case QOpenGLTexture::SRGB_Alpha_DXT1: + case QOpenGLTexture::SRGB_Alpha_DXT3: + case QOpenGLTexture::SRGB_Alpha_DXT5: + case QOpenGLTexture::SRGB_BP_UNorm: + case QOpenGLTexture::R11_EAC_UNorm: + case QOpenGLTexture::R11_EAC_SNorm: + case QOpenGLTexture::RG11_EAC_UNorm: + case QOpenGLTexture::RG11_EAC_SNorm: + case QOpenGLTexture::RGB8_ETC2: + case QOpenGLTexture::SRGB8_ETC2: + case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: + case QOpenGLTexture::RGBA8_ETC2_EAC: + case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: + return true; + + case QOpenGLTexture::DepthFormat: + case QOpenGLTexture::AlphaFormat: + case QOpenGLTexture::RGBFormat: + case QOpenGLTexture::RGBAFormat: + case QOpenGLTexture::LuminanceFormat: + case QOpenGLTexture::LuminanceAlphaFormat: + return false; + } + + Q_UNREACHABLE(); + return false; +} + void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) { + // There is no way to allocate mutable storage for compressed textures in in + // versions older than OpenGL 3.1 and OpenGL ES 3.0, because the older specs + // do not mandate accepting null data pointers for glCompressedTexImage*D, + // unlike glTexImage*D (which in turn does not accept compressed formats). + if (isCompressedFormat(format)) { + storageAllocated = true; + return; + } + switch (target) { case QOpenGLTexture::TargetBuffer: // Buffer textures get their storage from an external OpenGL buffer @@ -1196,86 +1329,121 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options) { + if (!isCompressedFormat(format)) { + qWarning("Cannot set compressed data for non-compressed format 0x%x", format); + return; + } + + const bool needsFullSpec = !isUsingImmutableStorage(); // was allocateStorage() a no-op? + switch (target) { case QOpenGLTexture::Target1D: Q_UNUSED(layer); Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel, - 0, mipLevelSize( mipLevel, dimensions[0] ), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage1D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel, + 0, mipLevelSize( mipLevel, dimensions[0] ), + format, dataSize, data, options); + } break; case QOpenGLTexture::Target1DArray: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, - 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + 1, + format, dataSize, data, options); + } break; case QOpenGLTexture::Target2D: Q_UNUSED(layer); Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, - 0, 0, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage2D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + 0, 0, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + format, dataSize, data, options); + } break; case QOpenGLTexture::Target2DArray: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 1, + format, dataSize, data, options); + } break; case QOpenGLTexture::Target3D: Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layer, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - mipLevelSize(mipLevel, dimensions[2]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage3D(textureId, target, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + mipLevelSize(mipLevel, dimensions[2]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layer, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + mipLevelSize(mipLevel, dimensions[2]), + format, dataSize, data, options); + } break; case QOpenGLTexture::TargetCubeMap: Q_UNUSED(layer); - texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, - 0, 0, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - format, dataSize, data, options); + if (needsFullSpec) { + texFuncs->glCompressedTextureImage2D(textureId, cubeFace, bindingTarget, mipLevel, + format, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 0, dataSize, data, options); + } else { + texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, + 0, 0, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + format, dataSize, data, options); + } break; case QOpenGLTexture::TargetCubeMapArray: { int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; int layerFace = 6 * layer + faceIndex; - texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, - 0, 0, layerFace, - mipLevelSize(mipLevel, dimensions[0]), - mipLevelSize(mipLevel, dimensions[1]), - 1, - format, dataSize, data, options); + if (!needsFullSpec) { + texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + 0, 0, layerFace, + mipLevelSize(mipLevel, dimensions[0]), + mipLevelSize(mipLevel, dimensions[1]), + 1, + format, dataSize, data, options); + } break; } case QOpenGLTexture::TargetRectangle: - Q_UNUSED(mipLevel); - Q_UNUSED(layer); - Q_UNUSED(cubeFace); - texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, 0, - 0, 0, - dimensions[0], - dimensions[1], - format, dataSize, data, options); - break; - case QOpenGLTexture::Target2DMultisample: case QOpenGLTexture::Target2DMultisampleArray: case QOpenGLTexture::TargetBuffer: @@ -1857,6 +2025,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target \value SRGB8_PunchThrough_Alpha1_ETC2 Equivalent to GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 \value RGBA8_ETC2_EAC Equivalent to GL_COMPRESSED_RGBA8_ETC2_EAC \value SRGB8_Alpha8_ETC2_EAC Equivalent to GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC + \value RGB8_ETC1 Equivalent to GL_ETC1_RGB8_OES \value SRGB8 Equivalent to GL_SRGB8 \value SRGB8_Alpha8 Equivalent to GL_SRGB8_ALPHA8 @@ -2394,6 +2563,7 @@ void QOpenGLTexture::setFormat(TextureFormat format) case QOpenGLTexture::SRGB8_PunchThrough_Alpha1_ETC2: case QOpenGLTexture::RGBA8_ETC2_EAC: case QOpenGLTexture::SRGB8_Alpha8_ETC2_EAC: + case QOpenGLTexture::RGB8_ETC1: case RG3B2: case R5G6B5: case RGB5A1: @@ -3458,6 +3628,8 @@ QPair<int, int> QOpenGLTexture::mipLevelRange() const The automatic mipmap generation is enabled by default. + \note Mipmap generation is not supported for compressed textures with OpenGL ES 2.0. + \sa isAutoMipMapGenerationEnabled(), generateMipMaps() */ void QOpenGLTexture::setAutoMipMapGenerationEnabled(bool enabled) @@ -3483,6 +3655,9 @@ bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const have disabled automatic mipmap generation then you need to call this function or the overload to create the mipmap chain. + \note Mipmap generation is not supported for compressed textures with OpenGL + ES 2.0. + \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels() */ void QOpenGLTexture::generateMipMaps() @@ -3490,6 +3665,11 @@ void QOpenGLTexture::generateMipMaps() Q_D(QOpenGLTexture); Q_ASSERT(d->texFuncs); Q_ASSERT(d->textureId); + if (isCompressedFormat(d->format)) { + if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) + if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + return; + } d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget); } @@ -3510,6 +3690,11 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) Q_D(QOpenGLTexture); Q_ASSERT(d->texFuncs); Q_ASSERT(d->textureId); + if (isCompressedFormat(d->format)) { + if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) + if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + return; + } int oldBaseLevel; if (resetBaseLevel) oldBaseLevel = mipBaseLevel(); diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index baab2d634f..ec52a192fa 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -196,6 +196,7 @@ public: SRGB8_PunchThrough_Alpha1_ETC2 = 0x9277, // GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 RGBA8_ETC2_EAC = 0x9278, // GL_COMPRESSED_RGBA8_ETC2_EAC SRGB8_Alpha8_ETC2_EAC = 0x9279, // GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC + RGB8_ETC1 = 0x8D64, // GL_ETC1_RGB8_OES // sRGB formats SRGB8 = 0x8C41, // GL_SRGB8 diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h index be4bf0e93c..ac9d44db42 100644 --- a/src/gui/opengl/qopengltexture_p.h +++ b/src/gui/opengl/qopengltexture_p.h @@ -117,6 +117,8 @@ public: return std::floor(double(qMax(1, baseLevelSize >> mipLevel))); } + bool isUsingImmutableStorage() const; + QOpenGLTexture *q_ptr; QOpenGLContext *context; QOpenGLTexture::Target target; diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h index 5a56516b49..d659fcedfb 100644 --- a/src/gui/opengl/qopengltexturehelper_p.h +++ b/src/gui/opengl/qopengltexturehelper_p.h @@ -253,23 +253,48 @@ public: inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) { - (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits); + } } inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) + { - (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits); + } } inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLsizei imageSize, const GLvoid *bits) + GLint border, GLsizei imageSize, const GLvoid *bits, + const QOpenGLPixelTransferOptions * const options = 0) { - (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + if (options) { + QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions(); + setPixelUploadOptions(*options); + (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + setPixelUploadOptions(oldOptions); + } else { + (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits); + } } private: diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 846c513f01..0814e0494d 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -996,6 +996,34 @@ void QPdfEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) *d->currentPage << "Q\n"; } +void QPdfEngine::drawHyperlink(const QRectF &r, const QUrl &url) +{ + Q_D(QPdfEngine); + + const uint annot = d->addXrefEntry(-1); + const QByteArray urlascii = url.toEncoded(); + int len = urlascii.size(); + QVarLengthArray<char> url_esc(0); + for (int j = 0; j < len; j++) { + if (urlascii[j] == '(' || urlascii[j] == ')' || urlascii[j] == '\\') + url_esc.append('\\'); + url_esc.append(urlascii[j]); + } + url_esc.append('\0'); + + char buf[256]; + const QRectF rr = d->pageMatrix().mapRect(r); + d->xprintf("<<\n/Type /Annot\n/Subtype /Link\n/Rect ["); + d->xprintf("%s ", qt_real_to_string(rr.left(), buf)); + d->xprintf("%s ", qt_real_to_string(rr.top(), buf)); + d->xprintf("%s ", qt_real_to_string(rr.right(), buf)); + d->xprintf("%s", qt_real_to_string(rr.bottom(), buf)); + d->xprintf("]\n/Border [0 0 0]\n/A <<\n"); + d->xprintf("/Type /Action\n/S /URI\n/URI (%s)\n", url_esc.constData()); + d->xprintf(">>\n>>\n"); + d->xprintf("endobj\n"); + d->currentPage->annotations.append(annot); +} void QPdfEngine::updateState(const QPaintEngineState &state) { diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 2b50cdc6f7..de30744ca2 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -188,6 +188,8 @@ public: Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE; void drawTiledPixmap (const QRectF & rectangle, const QPixmap & pixmap, const QPointF & point) Q_DECL_OVERRIDE; + void drawHyperlink(const QRectF &r, const QUrl &url); + void updateState(const QPaintEngineState &state) Q_DECL_OVERRIDE; int metric(QPaintDevice::PaintDeviceMetric metricType) const; |