Fix crash in font distancefield computation
If setting a larger-than-default distance field base font size (renderTypeQuality in qml), an exceptionally large glyph could cause integer overflows in the distance filed computation, causing asserts or crashes. Change the computation types to avoid the overflow. This improves on b6f962c87f5084eaf962bfb033b1398f80475120. Fixes: QTBUG-124310 Pick-to: 6.7 6.5 6.2 5.15 Change-Id: I48b7dc3c0a0f35859d45c40d03498ac057e9fa70 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> (cherry picked from commit 30a753944300c13e96f9239a9891cbc8e2e378c1) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
65a1e71700
commit
940ba11f8c
@ -130,11 +130,15 @@ QPoint IntersectionPoint::round() const
|
||||
|
||||
// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
|
||||
// line and zero if exactly on the line.
|
||||
// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
|
||||
// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
|
||||
inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
|
||||
// The returned value is the sign of the cross product between 'v2-v1' and 'p-v1'.
|
||||
inline int pointSideOfLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
|
||||
{
|
||||
return cross(v2 - v1, p - v1);
|
||||
qint64 ux = qint64(v2.x()) - v1.x();
|
||||
qint64 uy = qint64(v2.y()) - v1.y();
|
||||
qint64 vx = qint64(p.x()) - v1.x();
|
||||
qint64 vy = qint64(p.y()) - v1.y();
|
||||
qint64 c = (ux * vy) - (uy * vx);
|
||||
return (c > 0) ? 1 : (c < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2,
|
||||
@ -1399,19 +1403,19 @@ bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right)
|
||||
return true;
|
||||
if (leftU.x() > qMax(rightL.x(), rightU.x()))
|
||||
return false;
|
||||
int d = pointDistanceFromLine(leftU, rightL, rightU);
|
||||
int d = pointSideOfLine(leftU, rightL, rightU);
|
||||
// d < 0: left, d > 0: right, d == 0: on top
|
||||
if (d == 0) {
|
||||
d = pointDistanceFromLine(leftL, rightL, rightU);
|
||||
d = pointSideOfLine(leftL, rightL, rightU);
|
||||
if (d == 0) {
|
||||
if (right->degree > Element::Line) {
|
||||
d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1]));
|
||||
d = pointSideOfLine(leftL, rightL, m_points->at(right->indices[1]));
|
||||
if (d == 0)
|
||||
d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2]));
|
||||
d = pointSideOfLine(leftL, rightL, m_points->at(right->indices[2]));
|
||||
} else if (left->degree > Element::Line) {
|
||||
d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU);
|
||||
d = pointSideOfLine(m_points->at(left->indices[1]), rightL, rightU);
|
||||
if (d == 0)
|
||||
d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU);
|
||||
d = pointSideOfLine(m_points->at(left->indices[2]), rightL, rightU);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1431,13 +1435,13 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
|
||||
Q_ASSERT(point >= v2 && point <= v1);
|
||||
if (point == v1 || point == v2)
|
||||
break;
|
||||
int d = pointDistanceFromLine(point, v1, v2);
|
||||
int d = pointSideOfLine(point, v1, v2);
|
||||
if (d == 0) {
|
||||
if (element->degree == Element::Line)
|
||||
break;
|
||||
d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1]));
|
||||
d = pointSideOfLine(point, v1, m_points->at(element->indices[1]));
|
||||
if (d == 0)
|
||||
d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2]));
|
||||
d = pointSideOfLine(point, v1, m_points->at(element->indices[2]));
|
||||
Q_ASSERT(d != 0);
|
||||
}
|
||||
if (d < 0) {
|
||||
@ -1463,7 +1467,7 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
|
||||
Q_ASSERT(point >= v2 && point <= v1);
|
||||
bool equal = (point == v1 || point == v2);
|
||||
if (!equal) {
|
||||
int d = pointDistanceFromLine(point, v1, v2);
|
||||
int d = pointSideOfLine(point, v1, v2);
|
||||
Q_ASSERT(d >= 0);
|
||||
equal = (d == 0 && element->degree == Element::Line);
|
||||
}
|
||||
@ -1484,7 +1488,7 @@ QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerB
|
||||
Q_ASSERT(point >= v2 && point <= v1);
|
||||
bool equal = (point == v1 || point == v2);
|
||||
if (!equal) {
|
||||
int d = pointDistanceFromLine(point, v1, v2);
|
||||
int d = pointSideOfLine(point, v1, v2);
|
||||
Q_ASSERT(d <= 0);
|
||||
equal = (d == 0 && element->degree == Element::Line);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user