summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qblendfunctions.cpp4
-rw-r--r--src/gui/painting/qdrawhelper.cpp10
-rw-r--r--src/gui/painting/qdrawhelper_p.h17
-rw-r--r--src/gui/painting/qdrawhelper_sse4.cpp16
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h38
-rw-r--r--src/gui/painting/qpaintengine.cpp6
-rw-r--r--src/gui/painting/qpainter.cpp45
-rw-r--r--src/gui/painting/qpainterpath.cpp2
-rw-r--r--src/gui/painting/qregion.cpp2
-rw-r--r--src/gui/painting/qstroker_p.h2
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); }