diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/image/qpixmap_blitter.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 18 | ||||
-rw-r--r-- | src/gui/kernel/qopenglcontext.cpp | 3 | ||||
-rw-r--r-- | src/gui/kernel/qopenglcontext_p.h | 7 | ||||
-rw-r--r-- | src/gui/kernel/qplatformmenu.h | 5 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 4 | ||||
-rw-r--r-- | src/gui/opengl/qopengl.h | 10 | ||||
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 3 | ||||
-rw-r--r-- | src/gui/opengl/qopenglshaderprogram.cpp | 48 | ||||
-rw-r--r-- | src/gui/opengl/qopengltexture.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qblittable_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 157 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_blitter.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 33 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 18 | ||||
-rw-r--r-- | src/gui/painting/qvectorpath_p.h | 28 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qfontengine.cpp | 9 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 36 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 1 |
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; |