summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-05-29 10:06:10 +0200
committerLiang Qi <liang.qi@qt.io>2017-05-29 10:54:41 +0200
commit6a772fd201ac738dc86e71bd82e98f65158e6335 (patch)
tree674007720f41d27b251bbcffd7a368a93f88eb96 /src/gui/painting
parent40206a9f6d7635bb19305d1c8d74908808e3529e (diff)
parent4c346b6e2bfab976bc9b16275b8382aee38aefa4 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: .qmake.conf mkspecs/common/msvc-desktop.conf mkspecs/win32-g++/qmake.conf mkspecs/win32-icc/qmake.conf src/platformsupport/fontdatabases/mac/coretext.pri src/plugins/platforms/cocoa/qcocoawindow.h src/plugins/platforms/cocoa/qcocoawindow.mm Change-Id: I74a6f7705c9547ed8bbac7260eb4645543e32655
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/qdrawhelper.cpp66
-rw-r--r--src/gui/painting/qpainterpath.cpp33
2 files changed, 62 insertions, 37 deletions
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 3aa7accef6..b329f2c915 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -5643,17 +5643,11 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, co
static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorProfile *colorProfile)
{
// Do a gammacorrected gray alphablend...
- QRgba64 dstLinear = QRgba64::fromArgb32(*dst);
+ const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
- if (colorProfile && !dstLinear.isTransparent())
- dstLinear = colorProfile->fromLinear(dstLinear.unpremultiplied()).premultiplied();
+ QRgba64 blend = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
- dstLinear = interpolate255(srcLinear, coverage, dstLinear, 255 - coverage);
-
- if (colorProfile && !dstLinear.isTransparent())
- dstLinear = colorProfile->fromLinear(dstLinear.unpremultiplied()).premultiplied();
-
- *dst = toArgb32(dstLinear);
+ *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile)
@@ -5663,7 +5657,12 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL
} else if (coverage == 255) {
*dst = src;
} else {
- grayBlendPixel(dst, coverage, srcLinear, colorProfile);
+ if (*dst >= 0xff000000) {
+ grayBlendPixel(dst, coverage, srcLinear, colorProfile);
+ } else {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
+ *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage);
+ }
}
}
@@ -5751,14 +5750,25 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co
dstColor = colorProfile->fromLinear(dstColor);
dest[x] = dstColor;
} else {
- // Give up and do a gray alphablend.
- if (colorProfile && !dstColor.isTransparent())
- dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied();
+ // Do a gray alphablend.
+ alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile);
+ }
+ }
+}
+
+static inline void alphargbblend_argb32(quint32 *dst, uint coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile)
+{
+ if (coverage == 0xff000000) {
+ // nothing
+ } else if (coverage == 0xffffffff) {
+ *dst = src;
+ } else {
+ if (*dst >= 0xff000000) {
+ rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
+ } else {
+ // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
const int a = qRgbAvg(coverage);
- dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - a);
- if (colorProfile && !dstColor.isTransparent())
- dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied();
- dest[x] = dstColor;
+ *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a);
}
}
}
@@ -5863,16 +5873,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
while (mapHeight--) {
for (int i = 0; i < mapWidth; ++i) {
const uint coverage = src[i];
- if (coverage == 0xffffffff) {
- dst[i] = c;
- } else if (coverage != 0xff000000) {
- if (dst[i] >= 0xff000000) {
- rgbBlendPixel(dst + i, coverage, srcColor, colorProfile);
- } else {
- // Give up and do a gray blend.
- grayBlendPixel(dst + i, qRgbAvg(coverage), srcColor, colorProfile);
- }
- }
+ alphargbblend_argb32(dst + i, coverage, srcColor, c, colorProfile);
}
dst += destStride;
@@ -5898,16 +5899,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
for (int xp=start; xp<end; ++xp) {
const uint coverage = src[xp - x];
- if (coverage == 0xffffffff) {
- dst[xp] = c;
- } else if (coverage != 0xff000000) {
- if (dst[xp] >= 0xff000000) {
- rgbBlendPixel(dst + xp, coverage, srcColor, colorProfile);
- } else {
- // Give up and do a gray blend.
- grayBlendPixel(dst + xp, qRgbAvg(coverage), srcColor, colorProfile);
- }
- }
+ alphargbblend_argb32(dst + xp, coverage, srcColor, c, colorProfile);
}
} // for (i -> line.count)
src += srcStride;
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 7dbc83b338..27bd2e59e6 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1981,6 +1981,17 @@ static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qr
return false;
}
+static bool pointOnEdge(const QRectF &rect, const QPointF &point)
+{
+ if ((point.x() == rect.left() || point.x() == rect.right()) &&
+ (point.y() >= rect.top() && point.y() <= rect.bottom()))
+ return true;
+ if ((point.y() == rect.top() || point.y() == rect.bottom()) &&
+ (point.x() >= rect.left() && point.x() <= rect.right()))
+ return true;
+ return false;
+}
+
/*
Returns \c true if any lines or curves cross the four edges in of rect
*/
@@ -1988,6 +1999,7 @@ static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF
{
QPointF last_pt;
QPointF last_start;
+ enum { OnRect, InsideRect, OutsideRect} edgeStatus = OnRect;
for (int i=0; i<path->elementCount(); ++i) {
const QPainterPath::Element &e = path->elementAt(i);
@@ -2026,6 +2038,27 @@ static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF
default:
break;
}
+ // Handle crossing the edges of the rect at the end-points of individual sub-paths.
+ // A point on on the edge itself is considered neither inside nor outside for this purpose.
+ if (!pointOnEdge(rect, last_pt)) {
+ bool contained = rect.contains(last_pt);
+ switch (edgeStatus) {
+ case OutsideRect:
+ if (contained)
+ return true;
+ break;
+ case InsideRect:
+ if (!contained)
+ return true;
+ break;
+ case OnRect:
+ edgeStatus = contained ? InsideRect : OutsideRect;
+ break;
+ }
+ } else {
+ if (last_pt == last_start)
+ edgeStatus = OnRect;
+ }
}
// implicitly close last subpath