summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-06-15 22:39:25 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-15 22:39:25 +0200
commite5bcf68d3055d6738b56cbbafb407bad4363e63c (patch)
treed70319316c926697e136527ce9a6628d34f0ebc4 /src/gui
parentd57d184b6d18deab172ac400b9db973e6aacab21 (diff)
parentbe4b80af8235d5f5664f03589258eec0e43da78b (diff)
Merge "Merge remote-tracking branch 'origin/release' into stable" into refs/staging/stable
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/Qt5GuiConfigExtras.cmake.in18
-rw-r--r--src/gui/gui.pro6
-rw-r--r--src/gui/opengl/qopenglfunctions_4_1_core.cpp1
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp42
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h2
-rw-r--r--src/gui/painting/qrasterizer.cpp61
6 files changed, 90 insertions, 40 deletions
diff --git a/src/gui/Qt5GuiConfigExtras.cmake.in b/src/gui/Qt5GuiConfigExtras.cmake.in
index f1bc441009..83e77280d5 100644
--- a/src/gui/Qt5GuiConfigExtras.cmake.in
+++ b/src/gui/Qt5GuiConfigExtras.cmake.in
@@ -2,13 +2,15 @@
!!IF !isEmpty(CMAKE_ANGLE_EGL_DLL_RELEASE)
!!IF isEmpty(CMAKE_INCLUDE_DIR_IS_ABSOLUTE)
-set(Qt5Gui_EGL_INCLUDE_DIRS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$$CMAKE_INCLUDE_DIR\")
+set(Qt5Gui_EGL_INCLUDE_DIRS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$$CMAKE_INCLUDE_DIR/QtANGLE\")
!!ELSE
-set(Qt5Gui_EGL_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR\")
+set(Qt5Gui_EGL_INCLUDE_DIRS \"$$CMAKE_INCLUDE_DIR/QtANGLE\")
!!ENDIF
_qt5_Gui_check_file_exists(${Qt5Gui_EGL_INCLUDE_DIRS})
+list(APPEND Qt5Gui_INCLUDE_DIRS ${Qt5Gui_EGL_INCLUDE_DIRS})
+set_property(TARGET Qt5::Gui APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Qt5Gui_EGL_INCLUDE_DIRS})
set(Qt5Gui_OPENGL_INCLUDE_DIRS ${Qt5Gui_EGL_INCLUDE_DIRS})
macro(_populate_qt5gui_gl_target_properties TargetName Configuration LIB_LOCATION IMPLIB_LOCATION)
@@ -55,7 +57,7 @@ find_path(_qt5gui_OPENGL_INCLUDE_DIR $$CMAKE_GL_HEADER_NAME
PATHS $$CMAKE_GL_INCDIRS
NO_DEFAULT_PATH)
if (NOT _qt5gui_OPENGL_INCLUDE_DIR)
- message(FATAL_ERROR \"Failed to find \\\"$$CMAKE_GL_HEADER_NAME\\\" in \\\"$$CMAKE_GL_INCDIRS\\\", using the CMAKE_FIND_ROOT_PATH \\\"${CMAKE_FIND_ROOT_PATH}\\\".\")
+ message(FATAL_ERROR \"Failed to find \\\"$$CMAKE_GL_HEADER_NAME\\\" in \\\"$$CMAKE_GL_INCDIRS\\\".\")
endif()
_qt5_Gui_check_file_exists(${_qt5gui_OPENGL_INCLUDE_DIR})
@@ -85,7 +87,7 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs)
if (\"${ARGN}\" STREQUAL \"OPTIONAL\")
break()
else()
- message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\", using the CMAKE_FIND_ROOT_PATH \\\"${CMAKE_FIND_ROOT_PATH}\\\".\")
+ message(FATAL_ERROR \"Failed to find \\\"${_lib}\\\" in \\\"${LibDir}\\\".\")
endif()
endif()
add_library(Qt5::Gui_${_cmake_lib_name} SHARED IMPORTED)
@@ -114,9 +116,11 @@ macro(_qt5gui_find_extra_libs Name Libs LibDir IncDirs)
endif()
list(APPEND Qt5Gui_${Name}_LIBRARIES Qt5::Gui_${_cmake_lib_name})
endforeach()
- foreach(_dir ${IncDirs})
- _qt5_Gui_check_file_exists(${_dir})
- endforeach()
+ if (NOT CMAKE_CROSSCOMPILING)
+ foreach(_dir ${IncDirs})
+ _qt5_Gui_check_file_exists(${_dir})
+ endforeach()
+ endif()
endmacro()
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index e2dd5efcde..3203b41362 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -12,6 +12,12 @@ MODULE_PLUGIN_TYPES = \
platforms \
imageformats
+# This is here only because the platform plugin is no module, obviously.
+win32:contains(QT_CONFIG, angle) {
+ MODULE_AUX_INCLUDES = \
+ \$\$QT_MODULE_INCLUDE_BASE/QtANGLE
+}
+
load(qt_module)
# Code coverage with TestCocoon
diff --git a/src/gui/opengl/qopenglfunctions_4_1_core.cpp b/src/gui/opengl/qopenglfunctions_4_1_core.cpp
index b36cb0de94..474397bb1f 100644
--- a/src/gui/opengl/qopenglfunctions_4_1_core.cpp
+++ b/src/gui/opengl/qopenglfunctions_4_1_core.cpp
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
\class QOpenGLFunctions_4_1_Core
\inmodule QtGui
\since 5.1
+ \wrapper
\brief The QOpenGLFunctions_4_1_Core class provides all functions for this version and profile of OpenGL.
\sa QAbstractOpenGLFunctions
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 0f3cde3efd..39f64224f0 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -133,10 +133,15 @@ struct NoDasher {
};
+/*
+ * The return value is the result of the clipLine() call performed at the start
+ * of each of the two functions, aka "false" means completely outside the devices
+ * rect.
+ */
template<DrawPixel drawPixel, class Dasher>
-static void drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+static bool drawLine(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
template<DrawPixel drawPixel, class Dasher>
-static void drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+static bool drawLineAA(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
inline void drawPixel(QCosmeticStroker *stroker, int x, int y, int coverage)
{
@@ -602,17 +607,20 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
caps |= CapEnd;
QCosmeticStroker::Point last = this->lastPixel;
- stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
+ bool unclipped = stroke(this, p.x(), p.y(), p2.x(), p2.y(), caps);
/* fix for gaps in polylines with fastpen and aliased in a sequence
of points with small distances: if current point p2 has been dropped
- out, keep last non dropped point p. */
- if (fastPenAliased) {
- if (last.x != lastPixel.x || last.y != lastPixel.y ||
- points == begin + 2 || points == end - 2 ) {
- {
- p = p2;
- }
+ out, keep last non dropped point p.
+
+ However, if the line was completely outside the devicerect, we
+ still need to update p to avoid drawing the line after this one from
+ a bad starting position.
+ */
+ if (fastPenAliased && unclipped) {
+ if (last.x != lastPixel.x || last.y != lastPixel.y
+ || points == begin + 2 || points == end - 2) {
+ p = p2;
}
} else {
p = p2;
@@ -720,10 +728,10 @@ static inline void capAdjust(int caps, int &x1, int &x2, int &y, int yinc)
the drawing shifts from horizontal to vertical or back.
*/
template<DrawPixel drawPixel, class Dasher>
-static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
+static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
{
if (stroker->clipLine(rx1, ry1, rx2, ry2))
- return;
+ return false;
const int half = stroker->legacyRounding ? 31 : 0;
int x1 = toF26Dot6(rx1) + half;
@@ -813,7 +821,7 @@ static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
} else {
// horizontal
if (!dx)
- return;
+ return true;
QCosmeticStroker::Direction dir = QCosmeticStroker::LeftToRight;
@@ -886,14 +894,15 @@ static void drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
}
}
stroker->lastPixel = last;
+ return true;
}
template<DrawPixel drawPixel, class Dasher>
-static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
+static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2, qreal ry2, int caps)
{
if (stroker->clipLine(rx1, ry1, rx2, ry2))
- return;
+ return false;
int x1 = toF26Dot6(rx1);
int y1 = toF26Dot6(ry1);
@@ -967,7 +976,7 @@ static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
} else {
// horizontal
if (!dx)
- return;
+ return true;
int yinc = F16Dot16FixedDiv(dy, dx);
@@ -1029,6 +1038,7 @@ static void drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
drawPixel(stroker, x, (y>>16) + 1, alpha * alphaEnd >> 6);
}
}
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
index 05c8a2b0cf..5fc3559da4 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
class QCosmeticStroker;
-typedef void (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
+typedef bool (*StrokeLine)(QCosmeticStroker *stroker, qreal x1, qreal y1, qreal x2, qreal y2, int caps);
class QCosmeticStroker
{
diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp
index a6be7c6c78..197d49369e 100644
--- a/src/gui/painting/qrasterizer.cpp
+++ b/src/gui/painting/qrasterizer.cpp
@@ -734,6 +734,35 @@ static inline QPointF snapTo26Dot6Grid(const QPointF &p)
qFloorF(p.y() * 64) * (1 / qreal(64)));
}
+/*
+ The rasterize line function relies on some div by zero which should
+ result in +/-inf values. However, when floating point exceptions are
+ enabled, this will cause crashes, so we return high numbers instead.
+ As the returned value is used in further arithmetic, returning
+ FLT_MAX/DBL_MAX will also cause values, so instead return a value
+ that is well outside the int-range.
+ */
+static inline qreal qSafeDivide(qreal x, qreal y)
+{
+ if (y == 0)
+ return x > 0 ? 1e20 : -1e20;
+ return x / y;
+}
+
+/* Conversion to int fails if the value is too large to fit into INT_MAX or
+ too small to fit into INT_MIN, so we need this slightly safer conversion
+ when floating point exceptions are enabled
+ */
+static inline int qSafeFloatToQ16Dot16(qreal x)
+{
+ qreal tmp = x * 65536.;
+ if (tmp > qreal(INT_MAX))
+ return INT_MAX;
+ else if (tmp < qreal(INT_MIN))
+ return -INT_MAX;
+ return int(tmp);
+}
+
void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap)
{
if (a == b || width == 0 || d->clipRect.isEmpty())
@@ -946,23 +975,23 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
const QPointF bottomLeftEdge = bottom - left;
const QPointF bottomRightEdge = bottom - right;
- const qreal topLeftSlope = topLeftEdge.x() / topLeftEdge.y();
- const qreal bottomLeftSlope = bottomLeftEdge.x() / bottomLeftEdge.y();
+ const qreal topLeftSlope = qSafeDivide(topLeftEdge.x(), topLeftEdge.y());
+ const qreal bottomLeftSlope = qSafeDivide(bottomLeftEdge.x(), bottomLeftEdge.y());
- const qreal topRightSlope = topRightEdge.x() / topRightEdge.y();
- const qreal bottomRightSlope = bottomRightEdge.x() / bottomRightEdge.y();
+ const qreal topRightSlope = qSafeDivide(topRightEdge.x(), topRightEdge.y());
+ const qreal bottomRightSlope = qSafeDivide(bottomRightEdge.x(), bottomRightEdge.y());
- const Q16Dot16 topLeftSlopeFP = FloatToQ16Dot16(topLeftSlope);
- const Q16Dot16 topRightSlopeFP = FloatToQ16Dot16(topRightSlope);
+ const Q16Dot16 topLeftSlopeFP = qSafeFloatToQ16Dot16(topLeftSlope);
+ const Q16Dot16 topRightSlopeFP = qSafeFloatToQ16Dot16(topRightSlope);
- const Q16Dot16 bottomLeftSlopeFP = FloatToQ16Dot16(bottomLeftSlope);
- const Q16Dot16 bottomRightSlopeFP = FloatToQ16Dot16(bottomRightSlope);
+ const Q16Dot16 bottomLeftSlopeFP = qSafeFloatToQ16Dot16(bottomLeftSlope);
+ const Q16Dot16 bottomRightSlopeFP = qSafeFloatToQ16Dot16(bottomRightSlope);
- const Q16Dot16 invTopLeftSlopeFP = FloatToQ16Dot16(1 / topLeftSlope);
- const Q16Dot16 invTopRightSlopeFP = FloatToQ16Dot16(1 / topRightSlope);
+ const Q16Dot16 invTopLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topLeftSlope));
+ const Q16Dot16 invTopRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, topRightSlope));
- const Q16Dot16 invBottomLeftSlopeFP = FloatToQ16Dot16(1 / bottomLeftSlope);
- const Q16Dot16 invBottomRightSlopeFP = FloatToQ16Dot16(1 / bottomRightSlope);
+ const Q16Dot16 invBottomLeftSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomLeftSlope));
+ const Q16Dot16 invBottomRightSlopeFP = qSafeFloatToQ16Dot16(qSafeDivide(1, bottomRightSlope));
if (d->antialiased) {
const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound));
@@ -1137,10 +1166,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f);
int iMiddle = qMin(iLeft, iRight);
- Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);
- Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);
- Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);
- Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);
+ Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope);
+ Q16Dot16 leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope);
+ Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope);
+ Q16Dot16 rightIntersectBf = qSafeFloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope);
int ny;
int y = iTop;