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.8 6.7 6.5 6.2 5.15 Change-Id: I48b7dc3c0a0f35859d45c40d03498ac057e9fa70 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
parent
7c218d20ae
commit
30a7539443
@ -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