summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/configure.cmake11
-rw-r--r--src/gui/doc/src/richtext.qdoc6
-rw-r--r--src/gui/image/qimage.cpp5
-rw-r--r--src/gui/image/qplatformpixmap.h7
-rw-r--r--src/gui/itemmodels/qfilesystemmodel.cpp9
-rw-r--r--src/gui/kernel/qevent.cpp75
-rw-r--r--src/gui/kernel/qinputdevice.cpp5
-rw-r--r--src/gui/kernel/qpointingdevice.cpp23
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp2
-rw-r--r--src/gui/rhi/qrhi.cpp20
-rw-r--r--src/gui/rhi/qrhi.h4
-rw-r--r--src/gui/rhi/qrhid3d11.cpp2
-rw-r--r--src/gui/rhi/qrhid3d12.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp22
-rw-r--r--src/gui/rhi/qrhigles2_p.h3
-rw-r--r--src/gui/rhi/qrhimetal.mm8
-rw-r--r--src/gui/rhi/qrhimetal_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp4
-rw-r--r--src/gui/rhi/qrhivulkan_p.h1
-rw-r--r--src/gui/text/qfont_p.h4
-rw-r--r--src/gui/text/qfontvariableaxis.cpp38
-rw-r--r--src/gui/text/qtextengine.cpp61
-rw-r--r--src/gui/text/qtextengine_p.h4
23 files changed, 263 insertions, 54 deletions
diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
index ad76bb095a0..5001f2deeec 100644
--- a/src/gui/configure.cmake
+++ b/src/gui/configure.cmake
@@ -1217,17 +1217,6 @@ qt_feature("xcb-egl-plugin" PRIVATE
CONDITION QT_FEATURE_egl AND QT_FEATURE_opengl
EMIT_IF QT_FEATURE_xcb
)
-qt_feature("xcb-native-painting" PRIVATE
- LABEL "Native painting (experimental)"
- AUTODETECT OFF
- CONDITION QT_FEATURE_xcb_xlib AND QT_FEATURE_fontconfig AND XRender_FOUND
- EMIT_IF QT_FEATURE_xcb
-)
-qt_feature("xrender" PRIVATE
- LABEL "XRender for native painting"
- CONDITION QT_FEATURE_xcb_native_painting
- EMIT_IF QT_FEATURE_xcb AND QT_FEATURE_xcb_native_painting
-)
qt_feature("xcb-xlib" PRIVATE
LABEL "XCB Xlib"
CONDITION QT_FEATURE_xlib AND X11_XCB_FOUND
diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc
index 2fa49a31e03..f94c436bd80 100644
--- a/src/gui/doc/src/richtext.qdoc
+++ b/src/gui/doc/src/richtext.qdoc
@@ -1047,6 +1047,12 @@
\li \c type (\c 1, \c a, \c A, \c square, \c disc, \c circle)
\endlist
+ Additionally, the following attribute is supported by the \c ol tag:
+
+ \list
+ \li \c start
+ \endlist
+
\section1 Table Cell Attributes
The following attributes are supported by the \c td and \c th
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 6ba113ef8fb..4a8b409379c 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -47,6 +47,9 @@
#include <memory>
+#define QT_XFORM_TYPE_MSBFIRST 0
+#define QT_XFORM_TYPE_LSBFIRST 1
+
QT_BEGIN_NAMESPACE
class QCmyk32;
@@ -4447,6 +4450,8 @@ int QImage::metric(PaintDeviceMetric metric) const
trigx += m11; \
trigy += m12;
// END OF MACRO
+
+static
bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth,
uchar *dptr, qsizetype dbpl, int p_inc, int dHeight,
const uchar *sptr, qsizetype sbpl, int sWidth, int sHeight)
diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h
index 5621afa4da5..3346ca85375 100644
--- a/src/gui/image/qplatformpixmap.h
+++ b/src/gui/image/qplatformpixmap.h
@@ -33,7 +33,7 @@ public:
enum ClassId { RasterClass, DirectFBClass,
BlitterClass, Direct2DClass,
- X11Class, CustomClass = 1024 };
+ CustomClass = 1024 };
QPlatformPixmap(PixelType pixelType, int classId);
virtual ~QPlatformPixmap();
@@ -111,7 +111,6 @@ protected:
private:
friend class QPixmap;
- friend class QX11PlatformPixmap;
friend class QImagePixmapCleanupHooks; // Needs to set is_cached
int detach_no;
@@ -122,10 +121,6 @@ private:
uint is_cached;
};
-# define QT_XFORM_TYPE_MSBFIRST 0
-# define QT_XFORM_TYPE_LSBFIRST 1
-Q_GUI_EXPORT bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, qsizetype, int, int, const uchar*, qsizetype, int, int);
-
QT_END_NAMESPACE
#endif // QPLATFORMPIXMAP_H
diff --git a/src/gui/itemmodels/qfilesystemmodel.cpp b/src/gui/itemmodels/qfilesystemmodel.cpp
index 622c2e5bc92..9eb31f1b6d4 100644
--- a/src/gui/itemmodels/qfilesystemmodel.cpp
+++ b/src/gui/itemmodels/qfilesystemmodel.cpp
@@ -1787,14 +1787,17 @@ bool QFileSystemModel::event(QEvent *event)
bool QFileSystemModel::rmdir(const QModelIndex &aindex)
{
+ Q_D(QFileSystemModel);
+
QString path = filePath(aindex);
const bool success = QDir().rmdir(path);
-#if QT_CONFIG(filesystemwatcher)
if (success) {
- QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+#if QT_CONFIG(filesystemwatcher)
d->fileInfoGatherer->removePath(path);
- }
#endif
+ QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(aindex.parent());
+ d->removeNode(parentNode, fileName(aindex));
+ }
return success;
}
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index ae730a9b3af..7b1e76cc78f 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -1146,6 +1146,33 @@ Q_IMPL_POINTER_EVENT(QHoverEvent)
*/
/*!
+ \property QWheelEvent::device
+ \brief the device from which the wheel event originated
+
+ \sa pointingDevice()
+*/
+
+/*!
+ \property QWheelEvent::inverted
+ \since 5.7
+ \brief whether the delta values delivered with the event are inverted
+
+ Normally, a vertical wheel will produce a QWheelEvent with positive delta
+ values if the top of the wheel is rotating away from the hand operating it.
+ Similarly, a horizontal wheel movement will produce a QWheelEvent with
+ positive delta values if the top of the wheel is moved to the left.
+
+ However, on some platforms this is configurable, so that the same
+ operations described above will produce negative delta values (but with the
+ same magnitude). With the inverted property a wheel event consumer can
+ choose to always follow the direction of the wheel, regardless of the
+ system settings, but only for specific widgets.
+
+ \note Many platforms provide no such information. On such platforms
+ \l inverted always returns false.
+*/
+
+/*!
\fn bool QWheelEvent::inverted() const
\since 5.7
@@ -1236,6 +1263,24 @@ bool QWheelEvent::isEndEvent() const
#endif // QT_CONFIG(wheelevent)
/*!
+ \property QWheelEvent::pixelDelta
+ \brief the scrolling distance in pixels on screen
+
+ This value is provided on platforms that support high-resolution
+ pixel-based delta values, such as \macos. The value should be used
+ directly to scroll content on screen.
+
+ \note On platforms that support scrolling \l{phase()}{phases}, the delta
+ may be null when scrolling is about to begin (Qt::ScrollBegin) or has
+ ended (Qt::ScrollEnd).
+
+ \note On X11 this value is driver-specific and unreliable, use
+ angleDelta() instead.
+
+ \sa angleDelta()
+*/
+
+/*!
\fn QPoint QWheelEvent::pixelDelta() const
Returns the scrolling distance in pixels on screen. This value is
@@ -1256,6 +1301,27 @@ bool QWheelEvent::isEndEvent() const
*/
/*!
+ \property QWheelEvent::angleDelta
+ \brief the relative amount that the wheel was rotated, in eighths of a degree
+
+ A positive value indicates that the wheel was rotated forwards away from the
+ user; a negative value indicates that the wheel was rotated backwards toward
+ the user. \c angleDelta().y() provides the angle through which the common
+ vertical mouse wheel was rotated since the previous event. \c angleDelta().x()
+ provides the angle through which the horizontal mouse wheel was rotated, if
+ the mouse has a horizontal wheel; otherwise it stays at zero.
+
+ Most mouse types work in steps of 15 degrees, in which case the delta value
+ is a multiple of 120; i.e., 120 units * 1/8 = 15 degrees.
+
+ \note On platforms that support scrolling \l{phase()}{phases}, the delta
+ may be null when scrolling is about to begin (Qt::ScrollBegin) or has
+ ended (Qt::ScrollEnd).
+
+ \sa pixelDelta()
+*/
+
+/*!
\fn QPoint QWheelEvent::angleDelta() const
Returns the relative amount that the wheel was rotated, in eighths of a
@@ -1294,6 +1360,15 @@ bool QWheelEvent::isEndEvent() const
*/
/*!
+ \property QWheelEvent::phase
+ \since 5.2
+ \brief the scrolling phase of this wheel event
+
+ \note The Qt::ScrollBegin and Qt::ScrollEnd phases are currently
+ supported only on \macos.
+*/
+
+/*!
\fn Qt::ScrollPhase QWheelEvent::phase() const
\since 5.2
diff --git a/src/gui/kernel/qinputdevice.cpp b/src/gui/kernel/qinputdevice.cpp
index 8e5c38922e0..caed0fc6135 100644
--- a/src/gui/kernel/qinputdevice.cpp
+++ b/src/gui/kernel/qinputdevice.cpp
@@ -187,6 +187,11 @@ QString QInputDevice::name() const
}
/*!
+ \property QInputDevice::type
+ \brief the device type
+*/
+
+/*!
Returns the device type.
*/
QInputDevice::DeviceType QInputDevice::type() const
diff --git a/src/gui/kernel/qpointingdevice.cpp b/src/gui/kernel/qpointingdevice.cpp
index dcce354688a..7062340b287 100644
--- a/src/gui/kernel/qpointingdevice.cpp
+++ b/src/gui/kernel/qpointingdevice.cpp
@@ -241,6 +241,11 @@ void QPointingDevice::setMaximumTouchPoints(int c)
#endif // QT_DEPRECATED_SINCE(6, 0)
/*!
+ \property QPointingDevice::pointerType
+ \brief the pointer type
+*/
+
+/*!
Returns the pointer type.
*/
QPointingDevice::PointerType QPointingDevice::pointerType() const
@@ -250,6 +255,12 @@ QPointingDevice::PointerType QPointingDevice::pointerType() const
}
/*!
+ \property QPointingDevice::maximumPoints
+ \brief the maximum number of simultaneous touch points (fingers) that
+ can be detected
+*/
+
+/*!
Returns the maximum number of simultaneous touch points (fingers) that
can be detected.
*/
@@ -260,6 +271,11 @@ int QPointingDevice::maximumPoints() const
}
/*!
+ \property QPointingDevice::buttonCount
+ \brief the maximum number of on-device buttons that can be detected
+*/
+
+/*!
Returns the maximum number of on-device buttons that can be detected.
*/
int QPointingDevice::buttonCount() const
@@ -269,6 +285,13 @@ int QPointingDevice::buttonCount() const
}
/*!
+ \property QPointingDevice::uniqueId
+ \brief a unique ID (of dubious utility) for the device
+
+ You probably should rather be concerned with QPointerEventPoint::uniqueId().
+*/
+
+/*!
Returns a unique ID (of dubious utility) for the device.
You probably should rather be concerned with QPointerEventPoint::uniqueId().
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index d27539b2419..c9df5d28a45 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -301,6 +301,8 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c,
const QFixedPoint &subPixelPosition)
{
QImage mask = textureMapForGlyph(g, subPixelPosition);
+ if (mask.isNull())
+ return;
#ifdef CACHE_DEBUG
printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 62b7ab6efb0..5590f2fb431 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -7186,6 +7186,26 @@ QRhiResource::Type QRhiGraphicsPipeline::resourceType() const
*/
/*!
+ \fn bool QRhiGraphicsPipeline::hasDepthClamp() const
+ \return true if depth clamp is enabled.
+
+ \since 6.11
+ */
+
+/*!
+ \fn void QRhiGraphicsPipeline::setDepthClamp(bool enable)
+
+ Enables depth clamping when \a enable is true. When depth clamping is
+ enabled, primitives that would otherwise be clipped by the near or far
+ clip plane are rasterized and their depth values are clamped to the
+ depth range. When disabled (the default), such primitives are clipped.
+
+ \note This setting is ignored on OpenGL ES.
+
+ \since 6.11
+ */
+
+/*!
\fn QRhiGraphicsPipeline::CompareOp QRhiGraphicsPipeline::depthOp() const
\return the depth comparison function.
*/
diff --git a/src/gui/rhi/qrhi.h b/src/gui/rhi/qrhi.h
index b5a3f7b43be..5ee2a9acd13 100644
--- a/src/gui/rhi/qrhi.h
+++ b/src/gui/rhi/qrhi.h
@@ -1453,6 +1453,9 @@ public:
bool hasDepthWrite() const { return m_depthWrite; }
void setDepthWrite(bool enable) { m_depthWrite = enable; }
+ bool hasDepthClamp() const { return m_depthClamp; }
+ void setDepthClamp(bool enable) { m_depthClamp = enable; }
+
CompareOp depthOp() const { return m_depthOp; }
void setDepthOp(CompareOp op) { m_depthOp = op; }
@@ -1524,6 +1527,7 @@ protected:
QVarLengthArray<TargetBlend, 8> m_targetBlends;
bool m_depthTest = false;
bool m_depthWrite = false;
+ bool m_depthClamp = false;
CompareOp m_depthOp = Less;
bool m_stencilTest = false;
StencilOpState m_stencilFront;
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index a5f860e7724..1441be24043 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -4673,7 +4673,7 @@ bool QD3D11GraphicsPipeline::create()
rastDesc.FrontCounterClockwise = m_frontFace == CCW;
rastDesc.DepthBias = m_depthBias;
rastDesc.SlopeScaledDepthBias = m_slopeScaledDepthBias;
- rastDesc.DepthClipEnable = true;
+ rastDesc.DepthClipEnable = m_depthClamp ? FALSE : TRUE;
rastDesc.ScissorEnable = m_flags.testFlag(UsesScissor);
rastDesc.MultisampleEnable = rhiD->effectiveSampleDesc(m_sampleCount).Count > 1;
HRESULT hr = rhiD->dev->CreateRasterizerState(&rastDesc, &rastState);
diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp
index 4f09b3c136b..b68b65b1063 100644
--- a/src/gui/rhi/qrhid3d12.cpp
+++ b/src/gui/rhi/qrhid3d12.cpp
@@ -6263,7 +6263,7 @@ bool QD3D12GraphicsPipeline::create()
stream.rasterizerState.object.FrontCounterClockwise = m_frontFace == CCW;
stream.rasterizerState.object.DepthBias = m_depthBias;
stream.rasterizerState.object.SlopeScaledDepthBias = m_slopeScaledDepthBias;
- stream.rasterizerState.object.DepthClipEnable = TRUE;
+ stream.rasterizerState.object.DepthClipEnable = m_depthClamp ? FALSE : TRUE;
stream.rasterizerState.object.MultisampleEnable = sampleDesc.Count > 1;
stream.depthStencilState.object.DepthEnable = m_depthTest;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 15f5cd8f7e8..1308d4362e5 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -585,6 +585,10 @@ QT_BEGIN_NAMESPACE
#define GL_PROGRAM 0x82E2
#endif
+#ifndef GL_DEPTH_CLAMP
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
/*!
Constructs a new QRhiGles2InitParams.
@@ -998,6 +1002,13 @@ bool QRhiGles2::create(QRhi::Flags flags)
}
if (caps.gles)
+ caps.depthClamp = false;
+ else
+ caps.depthClamp = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2); // Desktop 3.2
+ if (!caps.depthClamp)
+ caps.depthClamp = ctx->hasExtension("GL_EXT_depth_clamp") || ctx->hasExtension("GL_ARB_depth_clamp");
+
+ if (caps.gles)
caps.textureCompareMode = caps.ctxMajor >= 3; // ES 3.0
else
caps.textureCompareMode = true;
@@ -3959,6 +3970,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break;
case QGles2CommandBuffer::Command::InvalidateFramebuffer:
if (caps.gles && caps.ctxMajor >= 3) {
+ f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.invalidateFramebuffer.fbo);
f->glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER,
cmd.args.invalidateFramebuffer.attCount,
cmd.args.invalidateFramebuffer.att);
@@ -4095,6 +4107,15 @@ void QRhiGles2::executeBindGraphicsPipeline(QGles2CommandBuffer *cbD, QGles2Grap
f->glDepthMask(depthWrite);
}
+ const bool depthClamp = psD->m_depthClamp;
+ if (caps.depthClamp && (forceUpdate || depthClamp != state.depthClamp)) {
+ state.depthClamp = depthClamp;
+ if (depthClamp)
+ f->glEnable(GL_DEPTH_CLAMP);
+ else
+ f->glDisable(GL_DEPTH_CLAMP);
+ }
+
const GLenum depthFunc = toGlCompareOp(psD->m_depthOp);
if (forceUpdate || depthFunc != state.depthFunc) {
state.depthFunc = depthFunc;
@@ -4881,6 +4902,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (mayDiscardDepthStencil) {
QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::InvalidateFramebuffer;
+ cmd.args.invalidateFramebuffer.fbo = rtTex->framebuffer;
if (caps.needsDepthStencilCombinedAttach) {
cmd.args.invalidateFramebuffer.attCount = 1;
cmd.args.invalidateFramebuffer.att[0] = GL_DEPTH_STENCIL_ATTACHMENT;
diff --git a/src/gui/rhi/qrhigles2_p.h b/src/gui/rhi/qrhigles2_p.h
index 725e71a3665..70dd96a8dc7 100644
--- a/src/gui/rhi/qrhigles2_p.h
+++ b/src/gui/rhi/qrhigles2_p.h
@@ -547,6 +547,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
GLbitfield barriers;
} barrier;
struct {
+ GLuint fbo;
int attCount;
GLenum att[3];
} invalidateFramebuffer;
@@ -592,6 +593,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
} blend[16];
bool depthTest;
bool depthWrite;
+ bool depthClamp;
GLenum depthFunc;
bool stencilTest;
GLuint stencilReadMask;
@@ -1074,6 +1076,7 @@ public:
uint baseVertex : 1;
uint compute : 1;
uint textureCompareMode : 1;
+ uint depthClamp : 1;
uint properMapBuffer : 1;
uint nonBaseLevelFramebufferTexture : 1;
uint texelFetch : 1;
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index c3f1031b44b..7fa05f69232 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -403,6 +403,7 @@ struct QMetalGraphicsPipelineData
MTLWinding winding;
MTLCullMode cullMode;
MTLTriangleFillMode triangleFillMode;
+ MTLDepthClipMode depthClipMode;
float depthBias;
float slopeScaledDepthBias;
QMetalShader vs;
@@ -1477,7 +1478,6 @@ void QMetalGraphicsPipeline::makeActiveForCurrentRenderPassEncoder(QMetalCommand
[cbD->d->currentRenderPassEncoder setDepthStencilState: d->ds];
cbD->d->currentDepthStencilState = d->ds;
}
-
if (cbD->currentCullMode == -1 || d->cullMode != uint(cbD->currentCullMode)) {
[cbD->d->currentRenderPassEncoder setCullMode: d->cullMode];
cbD->currentCullMode = int(d->cullMode);
@@ -1486,6 +1486,10 @@ void QMetalGraphicsPipeline::makeActiveForCurrentRenderPassEncoder(QMetalCommand
[cbD->d->currentRenderPassEncoder setTriangleFillMode: d->triangleFillMode];
cbD->currentTriangleFillMode = int(d->triangleFillMode);
}
+ if (cbD->currentDepthClipMode == -1 || d->depthClipMode != uint(cbD->currentDepthClipMode)) {
+ [cbD->d->currentRenderPassEncoder setDepthClipMode: d->depthClipMode];
+ cbD->currentDepthClipMode = int(d->depthClipMode);
+ }
if (cbD->currentFrontFaceWinding == -1 || d->winding != uint(cbD->currentFrontFaceWinding)) {
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: d->winding];
cbD->currentFrontFaceWinding = int(d->winding);
@@ -5035,6 +5039,7 @@ void QMetalGraphicsPipeline::mapStates()
d->winding = m_frontFace == CCW ? MTLWindingCounterClockwise : MTLWindingClockwise;
d->cullMode = toMetalCullMode(m_cullMode);
d->triangleFillMode = toMetalTriangleFillMode(m_polygonMode);
+ d->depthClipMode = m_depthClamp ? MTLDepthClipModeClamp : MTLDepthClipModeClip;
d->depthBias = float(m_depthBias);
d->slopeScaledDepthBias = m_slopeScaledDepthBias;
}
@@ -6257,6 +6262,7 @@ void QMetalCommandBuffer::resetPerPassCachedState()
currentIndexFormat = QRhiCommandBuffer::IndexUInt16;
currentCullMode = -1;
currentTriangleFillMode = -1;
+ currentDepthClipMode = -1;
currentFrontFaceWinding = -1;
currentDepthBiasValues = { 0.0f, 0.0f };
diff --git a/src/gui/rhi/qrhimetal_p.h b/src/gui/rhi/qrhimetal_p.h
index 7c19ae9e767..6649a6cd304 100644
--- a/src/gui/rhi/qrhimetal_p.h
+++ b/src/gui/rhi/qrhimetal_p.h
@@ -299,6 +299,7 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
QRhiCommandBuffer::IndexFormat currentIndexFormat;
int currentCullMode;
int currentTriangleFillMode;
+ int currentDepthClipMode;
int currentFrontFaceWinding;
std::pair<float, float> currentDepthBiasValues;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index c5167a6e7de..481ffd57b5d 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -949,6 +949,8 @@ bool QRhiVulkan::create(QRhi::Flags flags)
// elsewhere states that the minimum bufferOffset is 4...
texbufAlign = qMax<VkDeviceSize>(4, physDevProperties.limits.optimalBufferCopyOffsetAlignment);
+ caps.depthClamp = physDevFeatures.depthClamp;
+
caps.wideLines = physDevFeatures.wideLines;
caps.texture3DSliceAs2D = caps.apiVersion >= QVersionNumber(1, 1);
@@ -8402,6 +8404,8 @@ bool QVkGraphicsPipeline::create()
VkPipelineRasterizationStateCreateInfo rastInfo = {};
rastInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ if (m_depthClamp && rhiD->caps.depthClamp)
+ rastInfo.depthClampEnable = m_depthClamp;
rastInfo.cullMode = toVkCullMode(m_cullMode);
rastInfo.frontFace = toVkFrontFace(m_frontFace);
if (m_depthBias != 0 || !qFuzzyIsNull(m_slopeScaledDepthBias)) {
diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h
index d141a84c5fb..1e9318513fd 100644
--- a/src/gui/rhi/qrhivulkan_p.h
+++ b/src/gui/rhi/qrhivulkan_p.h
@@ -936,6 +936,7 @@ public:
struct {
bool compute = false;
+ bool depthClamp = false;
bool wideLines = false;
bool debugUtils = false;
bool vertexAttribDivisor = false;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d1509e4a251..75550439521 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -166,6 +166,7 @@ public:
QFontPrivate();
QFontPrivate(const QFontPrivate &other);
+ QFontPrivate &operator=(const QFontPrivate &) = delete;
~QFontPrivate();
QFontEngine *engineForScript(int script) const;
@@ -206,9 +207,6 @@ public:
void setVariableAxis(QFont::Tag tag, float value);
void unsetVariableAxis(QFont::Tag tag);
bool hasVariableAxis(QFont::Tag tag, float value) const;
-
-private:
- QFontPrivate &operator=(const QFontPrivate &) { return *this; }
};
diff --git a/src/gui/text/qfontvariableaxis.cpp b/src/gui/text/qfontvariableaxis.cpp
index be83a3e02ce..bbc14f4cd11 100644
--- a/src/gui/text/qfontvariableaxis.cpp
+++ b/src/gui/text/qfontvariableaxis.cpp
@@ -60,6 +60,18 @@ QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QFontVariableAxisPrivate)
QFontVariableAxis::QFontVariableAxis(const QFontVariableAxis &axis) = default;
/*!
+ \property QFontVariableAxis::tag
+ \brief the tag of the axis
+
+ This is a four-character sequence which identifies the axis. Certain tags
+ have standardized meanings, such as "wght" (weight) and "wdth" (width),
+ but any sequence of four latin-1 characters is a valid tag. By convention,
+ non-standard/custom axes are denoted by tags in all uppercase.
+
+ \sa QFont::setVariableAxis(), name()
+*/
+
+/*!
Returns the tag of the axis. This is a four-character sequence which identifies the axis.
Certain tags have standardized meanings, such as "wght" (weight) and "wdth" (width), but any
sequence of four latin-1 characters is a valid tag. By convention, non-standard/custom axes
@@ -91,6 +103,13 @@ void QFontVariableAxis::setTag(QFont::Tag tag)
}
/*!
+ \property QFontVariableAxis::name
+ \brief the name of the axis, if provided by the font
+
+ \sa tag()
+*/
+
+/*!
Returns the name of the axis, if provided by the font.
\sa tag()
@@ -153,6 +172,15 @@ void QFontVariableAxis::setMinimumValue(qreal minimumValue)
}
/*!
+ \property QFontVariableAxis::maximumValue
+ \brief the maximum value of the axis
+
+ Setting the axis to a value which is higher than this is not supported.
+
+ \sa minimumValue(), defaultValue()
+*/
+
+/*!
Returns the maximum value of the axis. Setting the axis to a value which is higher than this
is not supported.
@@ -182,6 +210,16 @@ void QFontVariableAxis::setMaximumValue(qreal maximumValue)
}
/*!
+ \property QFontVariableAxis::defaultValue
+ \brief the default value of the axis
+
+ This is the value the axis will have if none has been provided in the
+ QFont query.
+
+ \sa minimumValue(), maximumValue()
+*/
+
+/*!
Returns the default value of the axis. This is the value the axis will have if none has been
provided in the QFont query.
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 11c79f23d25..29fda652ef6 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
+#include <QtCore/private/qflatmap_p.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "qdebug.h"
#include "qtextformat.h"
@@ -1613,11 +1614,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
{
uint glyphs_shaped = 0;
- hb_buffer_t *buffer = hb_buffer_create();
- hb_buffer_set_unicode_funcs(buffer, hb_qt_get_unicode_funcs());
+ if (!buffer) {
+ buffer = hb_buffer_create();
+ hb_buffer_set_unicode_funcs(buffer, hb_qt_get_unicode_funcs());
+ }
+
hb_buffer_pre_allocate(buffer, itemLength);
if (Q_UNLIKELY(!hb_buffer_allocation_successful(buffer))) {
hb_buffer_destroy(buffer);
+ buffer = nullptr;
return 0;
}
@@ -1671,26 +1676,26 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
bool dontLigate = hasLetterSpacing && !scriptRequiresOpenType;
- QHash<QFont::Tag, quint32> features;
- features.insert(QFont::Tag("kern"), !!kerningEnabled);
+ QVarLengthFlatMap<QFont::Tag, hb_feature_t, 16> features;
+ auto insertFeature = [&features](QFont::Tag tag, quint32 value) {
+ features.insert(tag, { tag.value(),
+ value,
+ HB_FEATURE_GLOBAL_START,
+ HB_FEATURE_GLOBAL_END });
+ };
+ // fontFeatures have precedence
+ for (const auto &[tag, value]: fontFeatures.asKeyValueRange())
+ insertFeature(tag, value);
+ insertFeature(QFont::Tag("kern"), !!kerningEnabled);
if (dontLigate) {
- features.insert(QFont::Tag("liga"), false);
- features.insert(QFont::Tag("clig"), false);
- features.insert(QFont::Tag("dlig"), false);
- features.insert(QFont::Tag("hlig"), false);
- }
- features.insert(fontFeatures);
-
- QVarLengthArray<hb_feature_t, 16> featureArray;
- for (auto it = features.constBegin(); it != features.constEnd(); ++it) {
- featureArray.append({ it.key().value(),
- it.value(),
- HB_FEATURE_GLOBAL_START,
- HB_FEATURE_GLOBAL_END });
+ insertFeature(QFont::Tag("liga"), false);
+ insertFeature(QFont::Tag("clig"), false);
+ insertFeature(QFont::Tag("dlig"), false);
+ insertFeature(QFont::Tag("hlig"), false);
}
// whitelist cross-platforms shapers only
- static const char *shaper_list[] = {
+ constexpr const char *shaper_list[] = {
"graphite2",
"ot",
"fallback",
@@ -1699,13 +1704,11 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
bool shapedOk = hb_shape_full(hb_font,
buffer,
- featureArray.constData(),
- features.size(),
+ features.values().constData(),
+ features.values().size(),
shaper_list);
- if (Q_UNLIKELY(!shapedOk)) {
- hb_buffer_destroy(buffer);
+ if (Q_UNLIKELY(!shapedOk))
return 0;
- }
if (Q_UNLIKELY(HB_DIRECTION_IS_BACKWARD(props.direction)))
hb_buffer_reverse(buffer);
@@ -1718,10 +1721,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
num_glyphs = 1;
// ensure we have enough space for shaped glyphs and metrics
- if (Q_UNLIKELY(!ensureSpace(glyphs_shaped + num_glyphs))) {
- hb_buffer_destroy(buffer);
+ if (Q_UNLIKELY(!ensureSpace(glyphs_shaped + num_glyphs)))
return 0;
- }
// fetch the shaped glyphs and metrics
QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs);
@@ -1781,8 +1782,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
glyphs_shaped += num_glyphs;
}
- hb_buffer_destroy(buffer);
-
return glyphs_shaped;
}
@@ -1826,6 +1825,12 @@ QTextEngine::~QTextEngine()
delete layoutData;
delete specialData;
resetFontEngineCache();
+#if QT_CONFIG(harfbuzz)
+ if (buffer) {
+ hb_buffer_destroy(buffer);
+ buffer = nullptr;
+ }
+#endif
}
const QCharAttributes *QTextEngine::attributes() const
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index dffbc129b3a..e513fd598ba 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -40,6 +40,8 @@
#include <stdlib.h>
#include <vector>
+struct hb_buffer_t;
+
QT_BEGIN_NAMESPACE
class QFontPrivate;
@@ -583,6 +585,8 @@ private:
void indexFormats();
void resolveFormats() const;
+ mutable hb_buffer_t *buffer = nullptr;
+
public:
bool atWordSeparator(int position) const;