diff options
author | Liang Qi <liang.qi@qt.io> | 2017-05-29 10:06:10 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-05-29 10:54:41 +0200 |
commit | 6a772fd201ac738dc86e71bd82e98f65158e6335 (patch) | |
tree | 674007720f41d27b251bbcffd7a368a93f88eb96 /src/gui/painting | |
parent | 40206a9f6d7635bb19305d1c8d74908808e3529e (diff) | |
parent | 4c346b6e2bfab976bc9b16275b8382aee38aefa4 (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.cpp | 66 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 33 |
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 |