summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/image/qpixmap_blitter.cpp4
-rw-r--r--src/gui/kernel/qguiapplication.cpp18
-rw-r--r--src/gui/kernel/qopenglcontext.cpp3
-rw-r--r--src/gui/kernel/qopenglcontext_p.h7
-rw-r--r--src/gui/kernel/qplatformmenu.h5
-rw-r--r--src/gui/kernel/qwindow.cpp4
-rw-r--r--src/gui/opengl/qopengl.h10
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp3
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp48
-rw-r--r--src/gui/opengl/qopengltexture.cpp4
-rw-r--r--src/gui/painting/qblittable_p.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp157
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp2
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp33
-rw-r--r--src/gui/painting/qpainter.cpp18
-rw-r--r--src/gui/painting/qvectorpath_p.h28
-rw-r--r--src/gui/text/qfontdatabase.cpp6
-rw-r--r--src/gui/text/qfontengine.cpp9
-rw-r--r--src/gui/text/qfontengine_ft.cpp36
-rw-r--r--src/gui/text/qfontengine_p.h2
-rw-r--r--src/gui/text/qtextlayout.cpp1
21 files changed, 335 insertions, 65 deletions
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index 839a7a709f..2915cdda2d 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -59,6 +59,7 @@ static int global_ser_no = 0;
QBlittablePlatformPixmap::QBlittablePlatformPixmap()
: QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
, m_alpha(false)
+ , m_devicePixelRatio(1.0)
#ifdef QT_BLITTER_RASTEROVERLAY
,m_rasterOverlay(0), m_unmergedCopy(0)
#endif //QT_BLITTER_RASTEROVERLAY
@@ -121,7 +122,7 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
case QPaintDevice::PdmPhysicalDpiY:
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
- return 1;
+ return devicePixelRatio();
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
@@ -178,6 +179,7 @@ void QBlittablePlatformPixmap::fromImage(const QImage &image,
Qt::ImageConversionFlags flags)
{
m_alpha = image.hasAlphaChannel();
+ m_devicePixelRatio = image.devicePixelRatio();
resize(image.width(),image.height());
markRasterOverlay(QRect(0,0,w,h));
QImage *thisImg = buffer();
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index ab71fe9081..8ccff4321d 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -466,7 +466,14 @@ static QWindowGeometrySpecification windowGeometrySpecification;
\section1 Supported Command Line Options
- All Qt programs automatically support the following command line options:
+ All Qt programs automatically support a set of command-line options that
+ allow modifying the way Qt will interact with the windowing system. Some of
+ the options are also accessible via environment variables, which are the
+ preferred form if the application can launch GUI sub-processes or other
+ applications (environment variables will be inherited by child processes).
+ When in doubt, use the environment variables.
+
+ The options currently supported are the following:
\list
\li \c{-platform} \e {platformName[:options]}, specifies the
@@ -489,18 +496,21 @@ 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 {-qwindowtitle}, sets the title of the first window
\li \c{-reverse}, sets the application's layout direction to
- Qt::RightToLeft
+ Qt::RightToLeft. This option is intended to aid debugging and should
+ not be used in production. The default value is automatically detected
+ from the user's locale (see also QLocale::textDirection()).
\li \c{-session} \e session, restores the application from an earlier
\l{Session Management}{session}.
- \li -qwindowgeometry, sets the geometry of the first window
- \li -qwindowtitle, sets the title of the first window
\endlist
The following standard command line options are available for X11:
\list
\li \c {-display} \e {hostname:screen_number}, switches displays on X11.
+
+ Overrides the \c DISPLAY environment variable.
\li \c {-geometry} \e geometry, same as \c {-qwindowgeometry}.
\endlist
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 1af5c09fd2..be592153d2 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -1345,7 +1345,8 @@ void QOpenGLSharedResourceGuard::freeResource(QOpenGLContext *context)
QOpenGLMultiGroupSharedResource instance.
*/
QOpenGLMultiGroupSharedResource::QOpenGLMultiGroupSharedResource()
- : active(0)
+ : active(0),
+ m_mutex(QMutex::Recursive)
{
#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
qDebug("Creating context group resource object %p.", this);
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index b21ff67068..711a3b1b2f 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -127,7 +127,7 @@ private:
class Q_GUI_EXPORT QOpenGLContextGroupPrivate : public QObjectPrivate
{
- Q_DECLARE_PUBLIC(QOpenGLContextGroup);
+ Q_DECLARE_PUBLIC(QOpenGLContextGroup)
public:
QOpenGLContextGroupPrivate()
: m_context(0)
@@ -171,7 +171,9 @@ public:
template <typename T>
T *value(QOpenGLContext *context) {
QOpenGLContextGroup *group = context->shareGroup();
- QMutexLocker locker(&group->d_func()->m_mutex);
+ // Have to use our own mutex here, not the group's, since
+ // m_groups has to be protected too against any concurrent access.
+ QMutexLocker locker(&m_mutex);
T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0));
if (!resource) {
resource = new T(context);
@@ -183,6 +185,7 @@ public:
private:
QAtomicInt active;
QList<QOpenGLContextGroup *> m_groups;
+ QMutex m_mutex;
};
class QPaintEngineEx;
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 19e2d9bccf..b88f2a7e84 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -86,6 +86,9 @@ public:
virtual void setChecked(bool isChecked) = 0;
virtual void setShortcut(const QKeySequence& shortcut) = 0;
virtual void setEnabled(bool enabled) = 0;
+
+ virtual void setNativeContents(WId item) { Q_UNUSED(item); }
+
Q_SIGNALS:
void activated();
void hovered();
@@ -118,6 +121,8 @@ public:
setVisible(true);
}
+ virtual void dismiss() { } // Closes this and all its related menu popups
+
virtual QPlatformMenuItem *menuItemAt(int position) const = 0;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 6dcc3df166..40e9b9723a 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -455,7 +455,7 @@ void QWindow::setVisible(bool visible)
}
#ifndef QT_NO_CURSOR
- if (visible && d->hasCursor)
+ if (visible && (d->hasCursor || QGuiApplication::overrideCursor()))
d->applyCursor();
#endif
d->platformWindow->setVisible(visible);
@@ -743,7 +743,7 @@ void QWindow::setTitle(const QString &title)
d->windowTitle = title;
changed = true;
}
- if (d->platformWindow)
+ if (d->platformWindow && type() != Qt::Desktop)
d->platformWindow->setWindowTitle(title);
if (changed)
emit windowTitleChanged(title);
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index 190c05ba26..ef5ab9aa65 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -112,17 +112,19 @@ typedef GLfloat GLdouble;
# endif // Q_OS_MAC
#endif // QT_OPENGL_ES_2
-// Desktops, apart from Mac OS X prior to 10.7 can support OpenGL 3
-// and desktops apart from Mac can support OpenGL 4
+// Desktops, apart from Mac OS X prior to 10.7 can support OpenGL 3.
+// Desktops, apart from Mac OS X prior to 10.9 can support OpenGL 4.
#if !defined(QT_OPENGL_ES_2)
# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
# define QT_OPENGL_3
# define QT_OPENGL_3_2
# endif
-#if !defined(Q_OS_MAC)
+# if !defined(Q_OS_MAC) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
# define QT_OPENGL_4
+# endif
+# if !defined(Q_OS_MAC)
# define QT_OPENGL_4_3
-#endif
+# endif
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index cc829df950..7fb6815120 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -1112,6 +1112,9 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
\fn QImage QOpenGLFramebufferObject::toImage() const
Returns the contents of this framebuffer object as a QImage.
+
+ Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
+ a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported.
*/
QImage QOpenGLFramebufferObject::toImage() const
{
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index c4862945bb..6e85e5eb4b 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -2236,6 +2236,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& v
Sets the uniform variable at \a location in the current context
to a 2x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
@@ -2251,6 +2255,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value
Sets the uniform variable called \a name in the current context
to a 2x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
@@ -2262,6 +2270,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& v
Sets the uniform variable at \a location in the current context
to a 2x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
@@ -2277,6 +2289,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value
Sets the uniform variable called \a name in the current context
to a 2x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat2x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
@@ -2288,6 +2304,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& v
Sets the uniform variable at \a location in the current context
to a 3x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
@@ -2303,6 +2323,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value
Sets the uniform variable called \a name in the current context
to a 3x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
@@ -2340,6 +2364,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& v
Sets the uniform variable at \a location in the current context
to a 3x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
@@ -2355,6 +2383,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value
Sets the uniform variable called \a name in the current context
to a 3x4 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat3x4, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec4.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
@@ -2366,6 +2398,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& v
Sets the uniform variable at \a location in the current context
to a 4x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
@@ -2381,6 +2417,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value
Sets the uniform variable called \a name in the current context
to a 4x2 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x2, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec2.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
@@ -2392,6 +2432,10 @@ void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& v
Sets the uniform variable at \a location in the current context
to a 4x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
@@ -2407,6 +2451,10 @@ void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value
Sets the uniform variable called \a name in the current context
to a 4x3 matrix \a value.
+ \note This function is not aware of non square matrix support,
+ that is, GLSL types like mat4x3, that is present in modern OpenGL
+ versions. Instead, it treats the uniform as an array of vec3.
+
\sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 445e3ed64e..e3444332a0 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -180,6 +180,10 @@ bool QOpenGLTexturePrivate::create()
void QOpenGLTexturePrivate::destroy()
{
+ if (!context) {
+ // not created or already destroyed
+ return;
+ }
if (QOpenGLContext::currentContext() != context) {
qWarning("Requires a valid current OpenGL context.\n"
"Texture has not been destroyed");
diff --git a/src/gui/painting/qblittable_p.h b/src/gui/painting/qblittable_p.h
index 159e60079f..f65549d63c 100644
--- a/src/gui/painting/qblittable_p.h
+++ b/src/gui/painting/qblittable_p.h
@@ -68,7 +68,7 @@ public:
// Internal ones
OutlineCapability = 0x0001000
};
- Q_DECLARE_FLAGS (Capabilities, Capability);
+ Q_DECLARE_FLAGS (Capabilities, Capability)
QBlittable(const QSize &size, Capabilities caps);
virtual ~QBlittable();
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 7a5c5dc660..b5ccafdf9a 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1709,6 +1709,163 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
}
} else {
//we are zooming less than 8x, use 4bit precision
+
+ if (blendType != BlendTransformedBilinearTiled) {
+#define BILINEAR_ROTATE_BOUNDS_PROLOG \
+ while (b < end) { \
+ int x1 = (fx >> 16); \
+ int x2; \
+ int y1 = (fy >> 16); \
+ int y2; \
+ fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2); \
+ fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); \
+ if (x1 != x2 && y1 != y2) \
+ break; \
+ const uint *s1 = (const uint *)data->texture.scanLine(y1); \
+ const uint *s2 = (const uint *)data->texture.scanLine(y2); \
+ uint tl = s1[x1]; \
+ uint tr = s1[x2]; \
+ uint bl = s2[x1]; \
+ uint br = s2[x2]; \
+ int distx = (fx & 0x0000ffff) >> 12; \
+ int disty = (fy & 0x0000ffff) >> 12; \
+ *b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty); \
+ fx += fdx; \
+ fy += fdy; \
+ ++b; \
+ } \
+ uint *boundedEnd = end - 3; \
+ boundedEnd -= 3;
+
+#if defined(__SSE2__)
+ BILINEAR_ROTATE_BOUNDS_PROLOG
+
+ const __m128i colorMask = _mm_set1_epi32(0x00ff00ff);
+ const __m128i v_256 = _mm_set1_epi16(256);
+ __m128i v_fdx = _mm_set1_epi32(fdx*4);
+ __m128i v_fdy = _mm_set1_epi32(fdy*4);
+
+ const uchar *textureData = data->texture.imageData;
+ const int bytesPerLine = data->texture.bytesPerLine;
+
+ union Vect_buffer { __m128i vect; qint32 i[4]; };
+ Vect_buffer v_fx, v_fy;
+
+ for (int i = 0; i < 4; i++) {
+ v_fx.i[i] = fx;
+ v_fy.i[i] = fy;
+ fx += fdx;
+ fy += fdy;
+ }
+
+ while (b < boundedEnd) {
+ if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
+ break;
+ if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
+ break;
+ if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
+ break;
+ if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
+ break;
+
+ Vect_buffer tl, tr, bl, br;
+ Vect_buffer v_fx_shifted, v_fy_shifted;
+ v_fx_shifted.vect = _mm_srli_epi32(v_fx.vect, 16);
+ v_fy_shifted.vect = _mm_srli_epi32(v_fy.vect, 16);
+
+ for (int i = 0; i < 4; i++) {
+ const int x1 = v_fx_shifted.i[i];
+ const int y1 = v_fy_shifted.i[i];
+ const uchar *sl = textureData + bytesPerLine * y1;
+ const uint *s1 = (const uint *)sl;
+ const uint *s2 = (const uint *)(sl + bytesPerLine);
+ tl.i[i] = s1[x1];
+ tr.i[i] = s1[x1+1];
+ bl.i[i] = s2[x1];
+ br.i[i] = s2[x1+1];
+ }
+ __m128i v_distx = _mm_srli_epi16(v_fx.vect, 12);
+ __m128i v_disty = _mm_srli_epi16(v_fy.vect, 12);
+ v_distx = _mm_shufflehi_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
+ v_distx = _mm_shufflelo_epi16(v_distx, _MM_SHUFFLE(2,2,0,0));
+ v_disty = _mm_shufflehi_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
+ v_disty = _mm_shufflelo_epi16(v_disty, _MM_SHUFFLE(2,2,0,0));
+
+ interpolate_4_pixels_16_sse2(tl.vect, tr.vect, bl.vect, br.vect, v_distx, v_disty, colorMask, v_256, b);
+ b+=4;
+ v_fx.vect = _mm_add_epi32(v_fx.vect, v_fdx);
+ v_fy.vect = _mm_add_epi32(v_fy.vect, v_fdy);
+ }
+ fx = v_fx.i[0];
+ fy = v_fy.i[0];
+#elif defined(__ARM_NEON__)
+ BILINEAR_ROTATE_BOUNDS_PROLOG
+
+ const int16x8_t colorMask = vdupq_n_s16(0x00ff);
+ const int16x8_t invColorMask = vmvnq_s16(colorMask);
+ const int16x8_t v_256 = vdupq_n_s16(256);
+ int32x4_t v_fdx = vdupq_n_s32(fdx*4);
+ int32x4_t v_fdy = vdupq_n_s32(fdy*4);
+
+ const uchar *textureData = data->texture.imageData;
+ const int bytesPerLine = data->texture.bytesPerLine;
+
+ union Vect_buffer { int32x4_t vect; quint32 i[4]; };
+ Vect_buffer v_fx, v_fy;
+
+ for (int i = 0; i < 4; i++) {
+ v_fx.i[i] = fx;
+ v_fy.i[i] = fy;
+ fx += fdx;
+ fy += fdy;
+ }
+
+ const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
+
+ while (b < boundedEnd) {
+ if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
+ break;
+ if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
+ break;
+ if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
+ break;
+ if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
+ break;
+
+ Vect_buffer tl, tr, bl, br;
+
+ Vect_buffer v_fx_shifted, v_fy_shifted;
+ v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
+ v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16);
+
+ for (int i = 0; i < 4; i++) {
+ const int x1 = v_fx_shifted.i[i];
+ const int y1 = v_fy_shifted.i[i];
+ const uchar *sl = textureData + bytesPerLine * y1;
+ const uint *s1 = (const uint *)sl;
+ const uint *s2 = (const uint *)(sl + bytesPerLine);
+ tl.i[i] = s1[x1];
+ tr.i[i] = s1[x1+1];
+ bl.i[i] = s2[x1];
+ br.i[i] = s2[x1+1];
+ }
+
+ int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
+ int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12);
+ v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
+ v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
+ int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
+
+ interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
+ b+=4;
+ v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
+ v_fy.vect = vaddq_s32(v_fy.vect, v_fdy);
+ }
+ fx = v_fx.i[0];
+ fy = v_fy.i[0];
+#endif
+ }
+
while (b < end) {
int x1 = (fx >> 16);
int x2;
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index 26eacacd49..67a692e2db 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -238,7 +238,7 @@ private:
class QBlitterPaintEnginePrivate : public QRasterPaintEnginePrivate
{
- Q_DECLARE_PUBLIC(QBlitterPaintEngine);
+ Q_DECLARE_PUBLIC(QBlitterPaintEngine)
public:
QBlitterPaintEnginePrivate(QBlittablePlatformPixmap *p)
: QRasterPaintEnginePrivate()
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bfcb24ae3a..ce8c1d1ca7 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -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.
@@ -235,21 +235,6 @@ static const QRectF boundingRect(const QPointF *points, int pointCount)
}
#endif
-template <typename T> static inline bool isRect(const T *pts, int elementCount) {
- return (elementCount == 5 // 5-point polygon, check for closed rect
- && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- && pts[0] < pts[4] && pts[1] < pts[5]
- ) ||
- (elementCount == 4 // 4-point polygon, check for unclosed rect
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- && pts[0] < pts[4] && pts[1] < pts[5]
- );
-}
-
-
static void qt_ft_outline_move_to(qfixed x, qfixed y, void *data)
{
((QOutlineMapper *) data)->moveTo(QPointF(qt_fixed_to_real(x), qt_fixed_to_real(y)));
@@ -1193,22 +1178,14 @@ void QRasterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
-
// There are some cases that are not supported by clip(QRect)
if (op != Qt::IntersectClip || !s->clip || s->clip->hasRectClip || s->clip->hasRegionClip) {
if (s->matrix.type() <= QTransform::TxScale
- && ((path.shape() == QVectorPath::RectangleHint)
- || (isRect(points, path.elementCount())
- && (!types || (types[0] == QPainterPath::MoveToElement
- && types[1] == QPainterPath::LineToElement
- && types[2] == QPainterPath::LineToElement
- && types[3] == QPainterPath::LineToElement))))) {
+ && path.isRect()) {
#ifdef QT_DEBUG_DRAW
qDebug() << " --- optimizing vector clip to rect clip...";
#endif
-
+ const qreal *points = path.points();
QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op))
return;
@@ -1939,7 +1916,7 @@ void QRasterPaintEngine::drawPolygon(const QPointF *points, int pointCount, Poly
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && isRect((qreal *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((qreal *) points, pointCount)) {
QRectF r(points[0], points[2]);
drawRects(&r, 1);
return;
@@ -1980,7 +1957,7 @@ void QRasterPaintEngine::drawPolygon(const QPoint *points, int pointCount, Polyg
qDebug() << " - " << points[i];
#endif
Q_ASSERT(pointCount >= 2);
- if (mode != PolylineMode && isRect((int *) points, pointCount)) {
+ if (mode != PolylineMode && QVectorPath::isRect((int *) points, pointCount)) {
QRect r(points[0].x(),
points[0].y(),
points[2].x() - points[0].x(),
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index fe5fc051df..3f387d575b 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -147,8 +147,9 @@ static inline uint line_emulation(uint emulation)
}
#ifndef QT_NO_DEBUG
-static bool qt_painter_thread_test(int devType, const char *what)
+static bool qt_painter_thread_test(int devType, int engineType, const char *what)
{
+ const QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
switch (devType) {
case QInternal::Image:
case QInternal::Printer:
@@ -157,8 +158,13 @@ static bool qt_painter_thread_test(int devType, const char *what)
break;
default:
if (QThread::currentThread() != qApp->thread()
- && (devType!=QInternal::Pixmap || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps))
- && (devType!=QInternal::OpenGL || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL))) {
+ // pixmaps cannot be targets unless threaded pixmaps are supported
+ && (devType != QInternal::Pixmap || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedPixmaps))
+ // framebuffer objects and such cannot be targets unless threaded GL is supported
+ && (devType != QInternal::OpenGL || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL))
+ // widgets cannot be targets except for QGLWidget
+ && (devType != QInternal::Widget || !platformIntegration->hasCapability(QPlatformIntegration::ThreadedOpenGL)
+ || (engineType != QPaintEngine::OpenGL && engineType != QPaintEngine::OpenGL2))) {
qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
return false;
}
@@ -5054,7 +5060,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
#endif
if (d->extended) {
@@ -5125,7 +5131,7 @@ void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
if (!d->engine || pm.isNull())
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawPixmap()");
#endif
qreal x = r.x();
@@ -6610,7 +6616,7 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
return;
#ifndef QT_NO_DEBUG
- qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
+ qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()");
#endif
qreal sw = pixmap.width();
diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h
index e97d6e1dce..ca95c32597 100644
--- a/src/gui/painting/qvectorpath_p.h
+++ b/src/gui/painting/qvectorpath_p.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.
@@ -167,6 +167,32 @@ public:
return 0;
}
+ template <typename T> static inline bool isRect(const T *pts, int elementCount) {
+ return (elementCount == 5 // 5-point polygon, check for closed rect
+ && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
+ && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
+ && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
+ && pts[0] < pts[4] && pts[1] < pts[5]
+ ) ||
+ (elementCount == 4 // 4-point polygon, check for unclosed rect
+ && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
+ && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
+ && pts[0] < pts[4] && pts[1] < pts[5]
+ );
+ }
+
+ inline bool isRect() const
+ {
+ const QPainterPath::ElementType * const types = elements();
+
+ return (shape() == QVectorPath::RectangleHint)
+ || (isRect(points(), elementCount())
+ && (!types || (types[0] == QPainterPath::MoveToElement
+ && types[1] == QPainterPath::LineToElement
+ && types[2] == QPainterPath::LineToElement
+ && types[3] == QPainterPath::LineToElement)));
+ }
+
private:
Q_DISABLE_COPY(QVectorPath)
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 558258c30e..06438103ad 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2501,10 +2501,14 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
if (!engine) {
if (!request.family.isEmpty()) {
+ QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
+ if (styleHint == QFont::AnyStyle && request.fixedPitch)
+ styleHint = QFont::TypeWriter;
+
QStringList fallbacks = request.fallBackFamilies
+ fallbackFamilies(request.family,
QFont::Style(request.style),
- QFont::StyleHint(request.styleHint),
+ styleHint,
QChar::Script(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index b2254c4826..078e16574f 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1335,6 +1335,15 @@ QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &fami
return f;
}
+/**
+ * Some font engines like the windows font engine
+ * can not reliable create outline paths
+ */
+bool QFontEngine::hasUnreliableGlyphOutline() const
+{
+ return false;
+}
+
QFixed QFontEngine::lastRightBearing(const QGlyphLayout &glyphs, bool round)
{
if (glyphs.numGlyphs >= 1) {
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index fe38755ffd..f5ca559d62 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -450,6 +450,7 @@ static void scaleOutline(FT_Face face, FT_GlyphSlot g, FT_Fixed x_scale, FT_Fixe
}
}
+#define GLYPH2PATH_DEBUG QT_NO_QDEBUG_MACRO // qDebug
void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale)
{
const qreal factor = 1/64.;
@@ -461,22 +462,32 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
int i = 0;
for (int j = 0; j < g->outline.n_contours; ++j) {
int last_point = g->outline.contours[j];
- QPointF start = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
- if(!(g->outline.tags[i] & 1)) {
- start += cp + QPointF(g->outline.points[last_point].x*factor, -g->outline.points[last_point].y*factor);
- start /= 2;
+ GLYPH2PATH_DEBUG() << "contour:" << i << "to" << last_point;
+ QPointF start = QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
+ if (!(g->outline.tags[i] & 1)) { // start point is not on curve:
+ if (!(g->outline.tags[last_point] & 1)) { // end point is not on curve:
+ GLYPH2PATH_DEBUG() << " start and end point are not on curve";
+ start = (QPointF(g->outline.points[last_point].x*factor,
+ -g->outline.points[last_point].y*factor) + start) / 2.0;
+ } else {
+ GLYPH2PATH_DEBUG() << " end point is on curve, start is not";
+ start = QPointF(g->outline.points[last_point].x*factor,
+ -g->outline.points[last_point].y*factor);
+ }
+ --i; // to use original start point as control point below
}
-// qDebug("contour: %d -- %d", i, g->outline.contours[j]);
-// qDebug("first point at %f %f", start.x(), start.y());
- path->moveTo(start);
+ start += cp;
+ GLYPH2PATH_DEBUG() << " start at" << start;
+ path->moveTo(start);
QPointF c[4];
c[0] = start;
int n = 1;
while (i < last_point) {
++i;
c[n] = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
-// qDebug() << " i=" << i << " flag=" << (int)g->outline.tags[i] << "point=" << c[n];
+ GLYPH2PATH_DEBUG() << " " << i << c[n] << "tag =" << (int)g->outline.tags[i]
+ << ": on curve =" << (bool)(g->outline.tags[i] & 1);
++n;
switch (g->outline.tags[i] & 3) {
case 2:
@@ -498,7 +509,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
case 1:
case 3:
if (n == 2) {
-// qDebug() << "lineTo" << c[1];
+ GLYPH2PATH_DEBUG() << " lineTo" << c[1];
path->lineTo(c[1]);
c[0] = c[1];
n = 1;
@@ -510,13 +521,14 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
}
break;
}
-// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
+ GLYPH2PATH_DEBUG() << " cubicTo" << c[1] << c[2] << c[3];
path->cubicTo(c[1], c[2], c[3]);
c[0] = c[3];
n = 1;
}
+
if (n == 1) {
-// qDebug() << "closeSubpath";
+ GLYPH2PATH_DEBUG() << " closeSubpath";
path->closeSubpath();
} else {
c[3] = start;
@@ -524,7 +536,7 @@ void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoi
c[2] = (2*c[1] + c[3])/3;
c[1] = (2*c[1] + c[0])/3;
}
-// qDebug() << "cubicTo" << c[1] << c[2] << c[3];
+ GLYPH2PATH_DEBUG() << " close cubicTo" << c[1] << c[2] << c[3];
path->cubicTo(c[1], c[2], c[3]);
}
++i;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 5e40abbda6..fc849d788f 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -251,6 +251,8 @@ public:
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
+ virtual bool hasUnreliableGlyphOutline() const;
+
enum HintStyle {
HintNone,
HintLight,
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index c3cf2e56bb..84ad9038d5 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2810,7 +2810,6 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
break;
glyph_pos = gs;
edge = pos;
- break;
}
pos -= glyphs.effectiveAdvance(gs);
++gs;