diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qblendfunctions.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 10 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 17 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper_sse4.cpp | 16 | ||||
-rw-r--r-- | src/gui/painting/qdrawingprimitive_sse2_p.h | 38 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine.cpp | 6 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 45 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qregion.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qstroker_p.h | 2 |
10 files changed, 124 insertions, 18 deletions
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index b3710411c9..dbdd82e432 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -422,8 +422,8 @@ static void qt_blend_argb32pm_on_a2rgb30pm(uchar *destPixels, int dbpl, const_alpha = (const_alpha * 255) >> 8; for (int y=0; y<h; ++y) { for (int x=0; x<w; ++x) { - uint s = BYTE_MUL(src[x], const_alpha); - dst[x] = qConvertArgb32ToA2rgb30<PixelOrder>(s) + BYTE_MUL_RGB30(dst[x], 255 - qAlpha(s)); + uint s = src[x]; + dst[x] = BYTE_MUL_RGB30(qConvertArgb32ToA2rgb30<PixelOrder>(s), const_alpha) + BYTE_MUL_RGB30(dst[x], 255 - qt_div_255(qAlpha(s) * const_alpha)); } dst = (quint32 *)(((uchar *) dst) + dbpl); src = (const quint32 *)(((const uchar *) src) + sbpl); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 7b03cc00ff..07e5a3d19b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6291,6 +6291,10 @@ void qt_memfill32(quint32 *dest, quint32 color, int count) } #endif +#ifdef QT_COMPILER_SUPPORTS_SSE4_1 +template<QtPixelOrder> const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); +#endif + void qInitDrawhelperAsm() { const uint features = qCpuFeatures(); @@ -6352,7 +6356,7 @@ void qInitDrawhelperAsm() } #endif // SSSE3 -#if QT_COMPILER_SUPPORTS_SSE4_1 +#if defined(QT_COMPILER_SUPPORTS_SSE4_1) if (qCpuHasFeature(SSE4_1)) { #if !defined(__SSE4_1__) extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); @@ -6366,10 +6370,12 @@ void qInitDrawhelperAsm() qPixelLayouts[QImage::Format_ARGB32].convertFromARGB32PM = convertARGB32FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertFromARGB32PM = convertRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertFromARGB32PM = convertRGBXFromARGB32PM_sse4; + qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>; + qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].convertFromARGB32PM = convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>; } #endif -#if QT_COMPILER_SUPPORTS_AVX2 && !defined(__AVX2__) +#if defined(QT_COMPILER_SUPPORTS_AVX2) && !defined(__AVX2__) if (qCpuHasFeature(AVX2)) { extern const uint *QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); extern const uint *QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 179900ddd2..2c222b97c2 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -882,9 +882,25 @@ template<enum QtPixelOrder> inline uint qConvertRgb32ToRgb30(QRgb); template<enum QtPixelOrder> inline QRgb qConvertA2rgb30ToArgb32(uint c); +// A combined unpremultiply and premultiply with new simplified alpha. +// Needed when alpha loses precision relative to other colors during conversion (ARGB32 -> A2RGB30). +template<unsigned int Shift> +inline QRgb qRepremultiply(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255 || alpha == 0) + return p; + p = qUnpremultiply(p); + Q_CONSTEXPR uint mult = 255 / (255 >> Shift); + const uint newAlpha = mult * (alpha >> Shift); + p = (p & ~0xff000000) | (newAlpha<<24); + return qPremultiply(p); +} + template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 22) & 0x3fc00000) | ((c << 14) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) @@ -894,6 +910,7 @@ inline uint qConvertArgb32ToA2rgb30<PixelOrderBGR>(QRgb c) template<> inline uint qConvertArgb32ToA2rgb30<PixelOrderRGB>(QRgb c) { + c = qRepremultiply<6>(c); return (c & 0xc0000000) | (((c << 6) & 0x3fc00000) | ((c >> 2) & 0x00300000)) | (((c << 4) & 0x000ff000) | ((c >> 4) & 0x00000c00)) diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 43a3958997..7cc498eefc 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -74,6 +74,22 @@ const uint *QT_FASTCALL convertRGBXFromARGB32PM_sse4(uint *buffer, const uint *s return buffer; } +template<QtPixelOrder PixelOrder> +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = qConvertArgb32ToA2rgb30_sse4<PixelOrder>(src[i]); + return buffer; +} + +template +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderBGR>(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *); +template +const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM_sse4<PixelOrderRGB>(uint *buffer, const uint *src, int count, + const QPixelLayout *, const QRgb *); + QT_END_NAMESPACE #endif diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index 1a7dddf0d5..c74055e440 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -35,6 +35,7 @@ #define QDRAWINGPRIMITIVE_SSE2_P_H #include <private/qsimd_p.h> +#include "qdrawhelper_p.h" #ifdef __SSE2__ @@ -256,6 +257,43 @@ inline QRgb qUnpremultiply_sse4(QRgb p) vl = _mm_packus_epi16(vl, vl); return _mm_cvtsi128_si32(vl); } + +template<enum QtPixelOrder PixelOrder> +QT_FUNCTION_TARGET(SSE4_1) +inline uint qConvertArgb32ToA2rgb30_sse4(QRgb p) +{ + const uint alpha = qAlpha(p); + if (alpha == 255) + return qConvertRgb32ToRgb30<PixelOrder>(p); + if (alpha == 0) + return 0; + Q_CONSTEXPR uint mult = 255 / (255 >> 6); + const uint invAlpha = qt_inv_premul_factor[alpha]; + const uint newalpha = (alpha >> 6); + const __m128i via = _mm_set1_epi32(invAlpha); + const __m128i vna = _mm_set1_epi32(mult * newalpha); + const __m128i vr1 = _mm_set1_epi32(0x1000); + const __m128i vr2 = _mm_set1_epi32(0x80); + __m128i vl = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(p)); + vl = _mm_mullo_epi32(vl, via); + vl = _mm_add_epi32(vl, vr1); + vl = _mm_srli_epi32(vl, 14); + vl = _mm_mullo_epi32(vl, vna); + vl = _mm_add_epi32(vl, _mm_srli_epi32(vl, 8)); + vl = _mm_add_epi32(vl, vr2); + vl = _mm_srli_epi32(vl, 8); + vl = _mm_packus_epi32(vl, vl); + uint rgb30 = (newalpha << 30); + rgb30 |= ((uint)_mm_extract_epi16(vl, 1)) << 10; + if (PixelOrder == PixelOrderRGB) { + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)); + } else { + rgb30 |= ((uint)_mm_extract_epi16(vl, 0)) << 20; + rgb30 |= ((uint)_mm_extract_epi16(vl, 2)); + } + return rgb30; +} #endif QT_END_NAMESPACE diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index bf1f31a85b..ef93094387 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -149,7 +149,7 @@ QFont QTextItem::font() const provided is the raster paint engine, which contains a software rasterizer which supports the full feature set on all supported platforms. This is the default for painting on QWidget-based classes in e.g. on Windows, - X11 and Mac OS X, it is the backend for painting on QImage and it is + X11 and OS X, it is the backend for painting on QImage and it is used as a fallback for paint engines that do not support a certain capability. In addition we provide QPaintEngine implementations for OpenGL (accessible through QGLWidget) and printing (which allows using @@ -363,8 +363,8 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw \value X11 \value Windows \value MacPrinter - \value CoreGraphics Mac OS X's Quartz2D (CoreGraphics) - \value QuickDraw Mac OS X's QuickDraw + \value CoreGraphics OS X's Quartz2D (CoreGraphics) + \value QuickDraw OS X's QuickDraw \value QWindowSystem Qt for Embedded Linux \value PostScript (No longer supported) \value OpenGL diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index f9cabe840d..1726bbe71f 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5966,8 +5966,17 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br \endtable The \a boundingRect (if not null) is set to the what the bounding rectangle - should be in order to enclose the whole text. The \a flags argument is a bitwise - OR of the following flags: + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents \a rectangle: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable + + The \a flags argument is a bitwise OR of the following flags: \list \li Qt::AlignLeft @@ -6016,8 +6025,18 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * \overload Draws the given \a text within the provided \a rectangle according - to the specified \a flags. The \a boundingRect (if not null) is set to - the what the bounding rectangle should be in order to enclose the whole text. + to the specified \a flags. + + The \a boundingRect (if not null) is set to the what the bounding rectangle + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents \a rectangle: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable By default, QPainter draws text anti-aliased. @@ -6050,9 +6069,19 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * Draws the given \a text within the rectangle with origin (\a{x}, \a{y}), \a width and \a height. - The \a boundingRect (if not null) is set to the actual bounding - rectangle of the output. The \a flags argument is a bitwise OR of - the following flags: + The \a boundingRect (if not null) is set to the what the bounding rectangle + should be in order to enclose the whole text. For example, in the following + image, the dotted line represents \a boundingRect as calculated by the + function, and the dashed line represents the rectangle defined by + \a x, \a y, \a width and \a height: + + \table 100% + \row + \li \inlineimage qpainter-text-bounds.png + \li \snippet code/src_gui_painting_qpainter.cpp drawText + \endtable + + The \a flags argument is a bitwise OR of the following flags: \list \li Qt::AlignLeft @@ -6177,7 +6206,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) QPen wavePen = pen; wavePen.setCapStyle(Qt::SquareCap); - // This is to protect against making the line too fat, as happens on Mac OS X + // This is to protect against making the line too fat, as happens on OS X // due to it having a rather thick width for the regular underline. const qreal maxPenWidth = .8 * radius; if (wavePen.widthF() > maxPenWidth) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index e2f267d7ee..48010c0a71 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -218,7 +218,7 @@ static void qt_debug_path(const QPainterPath &path) Below is a code snippet that shows how a QPainterPath object can be used: - \table 100% + \table 70% \row \li \inlineimage qpainterpath-construction.png \li diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 19314ef84f..e6b777a30e 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -906,7 +906,7 @@ QRegion QRegion::intersect(const QRect &r) const sort key and X as the minor sort key. \endlist \omit - Only some platforms have these restrictions (Qt for Embedded Linux, X11 and Mac OS X). + Only some platforms have these restrictions (Qt for Embedded Linux, X11 and OS X). \endomit */ diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index f967c091df..d3765bbd29 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -201,7 +201,7 @@ public: QStroker(); ~QStroker(); - void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = width >= 1 ? 1.0/width : 0.5;} + void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = qt_real_to_fixed(width > 4 ? 1.0/width : 0.25); } qfixed strokeWidth() const { return m_strokeWidth; } void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); } |