Skip to content

Commit

Permalink
Ensure consistent cursor width under fractional scaling
Browse files Browse the repository at this point in the history
Under fractional scaling, an N units wide rectangle can in general
cover either M or M+1 pixels, depending on placement. For a tall thin
recangle like the cursor, this difference becomes very visible as the
cursor moves from position to position. Avoid by instead painting the
cursor as a cosmetic line in such cases, since that keeps its width
independently of the current transformation.

Fixes: QTBUG-95319
Pick-to: 6.4 6.3 6.2 5.15
Change-Id: I31a31f89fe7eac3037694946aa452a9f2bd6e5be
Reviewed-by: Morten Johan Sørvig <[email protected]>
  • Loading branch information
aavit committed Jun 28, 2022
1 parent 40ddf2c commit 3709bc3
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/gui/text/qtextlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,20 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
QPainter::CompositionMode origCompositionMode = p->compositionMode();
if (p->paintEngine()->hasFeature(QPaintEngine::RasterOpModes))
p->setCompositionMode(QPainter::RasterOp_NotDestination);
p->fillRect(QRectF(x, y, qreal(width), (base + cursorDescent).toReal()), p->pen().brush());
const QTransform &deviceTransform = p->deviceTransform();
const qreal xScale = deviceTransform.m11();
if (deviceTransform.type() != QTransform::TxScale || std::trunc(xScale) == xScale) {
p->fillRect(QRectF(x, y, qreal(width), (base + cursorDescent).toReal()), p->pen().brush());
} else {
// Ensure consistently rendered cursor width under fractional scaling
const QPen origPen = p->pen();
QPen pen(origPen.brush(), qRound(width * xScale), Qt::SolidLine, Qt::FlatCap);
pen.setCosmetic(true);
const qreal center = x + qreal(width) / 2;
p->setPen(pen);
p->drawLine(QPointF(center, y), QPointF(center, y + (base + cursorDescent).toReal()));
p->setPen(origPen);
}
p->setCompositionMode(origCompositionMode);
if (toggleAntialiasing)
p->setRenderHint(QPainter::Antialiasing, false);
Expand Down

0 comments on commit 3709bc3

Please sign in to comment.