Avoid crash in font distancefield computation
A very particular glyph in one particular font would hit an assert in the glyph path simplification code. It is not clear why this happens, but at least it should not crash. So instead, this patch makes the code bail out cleanly, just leaving that glyph empty (invisible). Task-number: QTBUG-124310 Change-Id: Id3b9c0b03fb82800f029fc718000ee6ca81408f7 Pick-to: 6.7 6.5 6.2 5.15 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> (cherry picked from commit b6f962c87f5084eaf962bfb033b1398f80475120) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
84971028ea
commit
985bc72f22
@ -312,7 +312,7 @@ private:
|
||||
|
||||
void initElements(const QVectorPath &path, const QTransform &matrix);
|
||||
void removeIntersections();
|
||||
void connectElements();
|
||||
bool connectElements();
|
||||
void fillIndices();
|
||||
BVHNode *buildTree(Element **elements, int elementCount);
|
||||
bool intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode, BVHNode *treeNode);
|
||||
@ -461,11 +461,17 @@ PathSimplifier::PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &ver
|
||||
{
|
||||
m_points->reset();
|
||||
m_indices->reset();
|
||||
bool ok = true;
|
||||
initElements(path, matrix);
|
||||
if (!m_elements.isEmpty()) {
|
||||
removeIntersections();
|
||||
connectElements();
|
||||
fillIndices();
|
||||
ok = connectElements();
|
||||
if (ok)
|
||||
fillIndices();
|
||||
}
|
||||
if (!ok) {
|
||||
m_points->reset();
|
||||
m_indices->reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,7 +656,7 @@ void PathSimplifier::removeIntersections()
|
||||
m_bvh.free(); // The bounding volume hierarchy is not needed anymore.
|
||||
}
|
||||
|
||||
void PathSimplifier::connectElements()
|
||||
bool PathSimplifier::connectElements()
|
||||
{
|
||||
Q_ASSERT(!m_elements.isEmpty());
|
||||
QDataBuffer<Event> events(m_elements.size() * 2);
|
||||
@ -830,7 +836,8 @@ void PathSimplifier::connectElements()
|
||||
}
|
||||
|
||||
if (!orderedElements.isEmpty()) {
|
||||
Q_ASSERT((orderedElements.size() & 1) == 0);
|
||||
if (orderedElements.size() & 1) // Unexpected path structure
|
||||
return false;
|
||||
int i = 0;
|
||||
Element *firstElement = orderedElements.at(0);
|
||||
if (m_points->at(firstElement->indices[0]) != eventPoint) {
|
||||
@ -856,6 +863,7 @@ void PathSimplifier::connectElements()
|
||||
Q_ASSERT((element->next == nullptr) == (element->previous == nullptr));
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void PathSimplifier::fillIndices()
|
||||
|
@ -474,6 +474,11 @@ static void makeDistanceField(QDistanceFieldData *data, const QPainterPath &path
|
||||
QDataBuffer<quint32> pathIndices(0);
|
||||
QDataBuffer<QPoint> pathVertices(0);
|
||||
qSimplifyPath(path, pathVertices, pathIndices, transform);
|
||||
if (pathVertices.isEmpty()) {
|
||||
qCWarning(lcDistanceField) << "Unexpected glyph path structure, bailing out";
|
||||
memset(data->data, 0, data->nbytes);
|
||||
return;
|
||||
}
|
||||
|
||||
const qint32 interiorColor = -0x7f80; // 8:8 signed format, -127.5
|
||||
const qint32 exteriorColor = 0x7f80; // 8:8 signed format, 127.5
|
||||
|
Loading…
x
Reference in New Issue
Block a user