Skip to content

Commit

Permalink
Enable text layout drawing on coordinates outside QFIXED_MAX
Browse files Browse the repository at this point in the history
In an earlier commit, painting on such coordinates was rejected, since
it would overflow the internal calculations using QFixed. Instead,
avoid the overflow by translating the painter to avoid the huge
coordinate values.
Also reduce the max value somewhat, so that pos stays well away from
QFIXED_MAX, to avoid overflows in the other QFixed variables that have
values offset from pos.

Fixes: QTBUG-103745
Pick-to: 6.3 6.2
Change-Id: Iebdec32bed57fe8e65551c7d278da9fd6c041b37
Reviewed-by: Eskil Abrahamsen Blomfeldt <[email protected]>
  • Loading branch information
aavit committed May 24, 2022
1 parent 718d680 commit cc42d90
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/gui/text/qtextlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2468,7 +2468,7 @@ void QTextLine::draw(QPainter *painter, const QPointF &position) const
draw_internal(painter, position, nullptr);
}

void QTextLine::draw_internal(QPainter *p, const QPointF &pos,
void QTextLine::draw_internal(QPainter *p, const QPointF &origPos,
const QTextLayout::FormatRange *selection) const
{
#ifndef QT_NO_RAWFONT
Expand All @@ -2486,17 +2486,21 @@ void QTextLine::draw_internal(QPainter *p, const QPointF &pos,
&& selection->start + selection->length > line.from) {

const qreal lineHeight = line.height().toReal();
QRectF r(pos.x() + line.x.toReal(), pos.y() + line.y.toReal(),
QRectF r(origPos.x() + line.x.toReal(), origPos.y() + line.y.toReal(),
lineHeight / 2, QFontMetrics(eng->font()).horizontalAdvance(u' '));
setPenAndDrawBackground(p, QPen(), selection->format, r);
p->setPen(pen);
}
return;
}

static QRectF maxFixedRect(QPointF(-QFIXED_MAX, -QFIXED_MAX), QPointF(QFIXED_MAX, QFIXED_MAX));
if (!maxFixedRect.contains(pos))
return;
static QRectF maxFixedRect(-QFIXED_MAX / 2, -QFIXED_MAX / 2, QFIXED_MAX, QFIXED_MAX);
const bool xlateToFixedRange = !maxFixedRect.contains(origPos);
QPointF pos;
if (Q_LIKELY(!xlateToFixedRange))
pos = origPos;
else
p->translate(origPos);

QTextLineItemIterator iterator(eng, index, pos, selection);
QFixed lineBase = line.base();
Expand Down Expand Up @@ -2689,6 +2693,9 @@ void QTextLine::draw_internal(QPainter *p, const QPointF &pos,
}
eng->drawDecorations(p);

if (xlateToFixedRange)
p->translate(-origPos);

if (eng->hasFormats())
p->setPen(pen);
}
Expand Down

0 comments on commit cc42d90

Please sign in to comment.