Skip to content

Commit

Permalink
Use floating point types for position offsets and cursorRectangle.
Browse files Browse the repository at this point in the history
Rounding to align painting to pixel boundaries is no longer necessary
are largely removed.  Correct the few instances remaining in TextEdit
and TextInput.

Change-Id: Ic6ec57092d74ec43b23d85cd8868e0190acc3e09
Reviewed-by: Yann Bodson <yann.bodson@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Feb 24, 2012
1 parent 8efc0ba commit 5fee1e7
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 108 deletions.
22 changes: 11 additions & 11 deletions src/quick/items/qquicktextedit.cpp
Expand Up @@ -732,10 +732,10 @@ QRectF QQuickTextEdit::positionToRectangle(int pos) const
Position 0 is before the first character, position 1 is after the first character
but before the second, and so on until position \l {text}.length, which is after all characters.
*/
int QQuickTextEdit::positionAt(int x, int y) const
int QQuickTextEdit::positionAt(qreal x, qreal y) const
{
Q_D(const QQuickTextEdit);
int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
int r = d->document->documentLayout()->hitTest(QPointF(x,y-d->yoff), Qt::FuzzyHit);
QTextCursor cursor = d->control->textCursor();
if (r > cursor.position()) {
// The cursor position includes positions within the preedit text, but only positions in the
Expand Down Expand Up @@ -1290,10 +1290,10 @@ Qt::TextInteractionFlags QQuickTextEdit::textInteractionFlags() const
automatically when it changes. The width of the delegate is unaffected by changes in the
cursor rectangle.
*/
QRect QQuickTextEdit::cursorRectangle() const
QRectF QQuickTextEdit::cursorRectangle() const
{
Q_D(const QQuickTextEdit);
return d->control->cursorRect().toRect().translated(0,d->yoff);
return d->control->cursorRect().translated(0, d->yoff);
}

bool QQuickTextEdit::event(QEvent *event)
Expand Down Expand Up @@ -1863,11 +1863,11 @@ void QQuickTextEdit::updateSize()
} else {
d->document->setTextWidth(-1);
}
QFontMetrics fm = QFontMetrics(d->font);
int dy = height();
dy -= (int)d->document->size().height();
QFontMetricsF fm(d->font);
qreal dy = height();
dy -= d->document->size().height();

int nyoff;
qreal nyoff;
if (heightValid()) {
if (d->vAlign == AlignBottom)
nyoff = dy;
Expand All @@ -1883,7 +1883,7 @@ void QQuickTextEdit::updateSize()
setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);

//### need to comfirm cost of always setting these
int newWidth = qCeil(d->document->idealWidth());
qreal newWidth = d->document->idealWidth();
if (!widthValid() && d->document->textWidth() != newWidth)
d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
// ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
Expand All @@ -1892,13 +1892,13 @@ void QQuickTextEdit::updateSize()
iWidth = newWidth;
else if (d->requireImplicitWidth)
iWidth = naturalWidth;
qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height();
if (iWidth > -1)
setImplicitSize(iWidth, newHeight);
else
setImplicitHeight(newHeight);

QSize size(newWidth, newHeight);
QSizeF size(newWidth, newHeight);
if (d->contentSize != size) {
d->contentSize = size;
emit contentSizeChanged();
Expand Down
6 changes: 3 additions & 3 deletions src/quick/items/qquicktextedit_p.h
Expand Up @@ -79,7 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QDeclarativeComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
Expand Down Expand Up @@ -212,7 +212,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
void setTextInteractionFlags(Qt::TextInteractionFlags flags);
Qt::TextInteractionFlags textInteractionFlags() const;

QRect cursorRectangle() const;
QRectF cursorRectangle() const;

QVariant inputMethodQuery(Qt::InputMethodQuery property) const;

Expand All @@ -224,7 +224,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
void resetBaseUrl();

Q_INVOKABLE QRectF positionToRectangle(int) const;
Q_INVOKABLE int positionAt(int x, int y) const;
Q_INVOKABLE int positionAt(qreal x, qreal y) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);

Expand Down
8 changes: 4 additions & 4 deletions src/quick/items/qquicktextedit_p_p.h
Expand Up @@ -69,8 +69,8 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
public:
QQuickTextEditPrivate()
: color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
, textMargin(0.0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0)
, lastSelectionStart(0), lastSelectionEnd(0), lineCount(0), yoff(0)
, textMargin(0.0), yoff(0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0)
, lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
, mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone)
Expand Down Expand Up @@ -98,9 +98,10 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
QColor selectionColor;
QColor selectedTextColor;

QSize contentSize;
QSizeF contentSize;

qreal textMargin;
qreal yoff;

QString text;
QUrl baseUrl;
Expand All @@ -115,7 +116,6 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
int lastSelectionStart;
int lastSelectionEnd;
int lineCount;
int yoff;

enum UpdateType {
UpdateNone,
Expand Down
42 changes: 19 additions & 23 deletions src/quick/items/qquicktextinput.cpp
Expand Up @@ -677,7 +677,7 @@ void QQuickTextInput::setCursorPosition(int cp)
cursor rectangle.
*/

QRect QQuickTextInput::cursorRectangle() const
QRectF QQuickTextInput::cursorRectangle() const
{
Q_D(const QQuickTextInput);

Expand All @@ -688,12 +688,8 @@ QRect QQuickTextInput::cursorRectangle() const
c = 0;
QTextLine l = d->m_textLayout.lineForTextPosition(c);
if (!l.isValid())
return QRect();
return QRect(
qRound(l.cursorToX(c) - d->hscroll),
qRound(l.y() - d->vscroll),
1,
qCeil(l.height()));
return QRectF();
return QRectF(l.cursorToX(c) - d->hscroll, l.y() - d->vscroll, 1, l.height());
}

/*!
Expand Down Expand Up @@ -1368,7 +1364,7 @@ void QQuickTextInput::positionAt(QDeclarativeV8Function *args) const
args->returnValue(v8::Int32::New(pos));
}

int QQuickTextInputPrivate::positionAt(int x, int y, QTextLine::CursorPosition position) const
int QQuickTextInputPrivate::positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const
{
x += hscroll;
y += vscroll;
Expand Down Expand Up @@ -1432,7 +1428,7 @@ void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event)
d->selectWordAtPos(cursor);
event->setAccepted(true);
if (!d->hasPendingTripleClick()) {
d->tripleClickStartPoint = event->localPos().toPoint();
d->tripleClickStartPoint = event->localPos();
d->tripleClickTimer.start();
}
} else {
Expand Down Expand Up @@ -1617,15 +1613,15 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
Q_Q(QQuickTextInput);
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor);
const int preeditLength = m_textLayout.preeditAreaText().length();
const int width = qMax(0, qFloor(q->width()));
int widthUsed = currentLine.isValid() ? qRound(currentLine.naturalTextWidth()) : 0;
const qreal width = qMax<qreal>(0, q->width());
qreal widthUsed = currentLine.isValid() ? currentLine.naturalTextWidth() : 0;
int previousScroll = hscroll;

if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) {
hscroll = 0;
} else {
Q_ASSERT(currentLine.isValid());
int cix = qRound(currentLine.cursorToX(m_cursor + preeditLength));
qreal cix = currentLine.cursorToX(m_cursor + preeditLength);
if (cix - hscroll >= width) {
// text doesn't fit, cursor is to the right of br (scroll right)
hscroll = cix - width;
Expand All @@ -1640,7 +1636,7 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
if (preeditLength > 0) {
// check to ensure long pre-edit text doesn't push the cursor
// off to the left
cix = qRound(currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1)));
cix = currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1));
if (cix < hscroll)
hscroll = cix;
}
Expand All @@ -1653,9 +1649,9 @@ void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
const int preeditLength = m_textLayout.preeditAreaText().length();
const int height = qMax(0, qFloor(q->height()));
int heightUsed = boundingRect.height();
int previousScroll = vscroll;
const qreal height = qMax<qreal>(0, q->height());
qreal heightUsed = boundingRect.height();
qreal previousScroll = vscroll;

if (!autoScroll || heightUsed <= height) {
// text fits in br; use vscroll for alignment
Expand All @@ -1674,8 +1670,8 @@ void QQuickTextInputPrivate::updateVerticalScroll()
} else {
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength);
QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF();
int top = qFloor(r.top());
int bottom = qCeil(r.bottom());
qreal top = r.top();
int bottom = r.bottom();

if (bottom - vscroll >= height) {
// text doesn't fit, cursor is to the below the br (scroll down)
Expand All @@ -1692,7 +1688,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
// check to ensure long pre-edit text doesn't push the cursor
// off the top
currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1));
top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0;
top = currentLine.isValid() ? currentLine.rect().top() : 0;
if (top < vscroll)
vscroll = top;
}
Expand Down Expand Up @@ -1742,11 +1738,11 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->deleteContent();
node->setMatrix(QMatrix4x4());

QPoint offset = QPoint(0,0);
QPointF offset(0, 0);
if (d->autoScroll && d->m_textLayout.lineCount() > 0) {
QFontMetrics fm = QFontMetrics(d->font);
QFontMetricsF fm(d->font);
// the y offset is there to keep the baseline constant in case we have script changes in the text.
offset = -QPoint(d->hscroll, d->vscroll + qRound(d->m_textLayout.lineAt(0).ascent()) - fm.ascent());
offset = -QPoint(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
} else {
offset = -QPoint(d->hscroll, d->vscroll);
}
Expand Down Expand Up @@ -2732,7 +2728,7 @@ void QQuickTextInputPrivate::updateLayout()

updateType = UpdatePaintNode;
q->update();
q->setImplicitSize(qCeil(boundingRect.width()), qCeil(boundingRect.height()));
q->setImplicitSize(boundingRect.width(), boundingRect.height());

if (previousRect != boundingRect)
emit q->contentSizeChanged();
Expand Down
4 changes: 2 additions & 2 deletions src/quick/items/qquicktextinput_p.h
Expand Up @@ -76,7 +76,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
Expand Down Expand Up @@ -195,7 +195,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
int cursorPosition() const;
void setCursorPosition(int cp);

QRect cursorRectangle() const;
QRectF cursorRectangle() const;

int selectionStart() const;
int selectionEnd() const;
Expand Down
13 changes: 7 additions & 6 deletions src/quick/items/qquicktextinput_p_p.h
Expand Up @@ -77,14 +77,14 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
Q_DECLARE_PUBLIC(QQuickTextInput)
public:
QQuickTextInputPrivate()
: cursorItem(0)
: hscroll(0)
, vscroll(0)
, cursorItem(0)
, textNode(0)
, m_maskData(0)
, color(QRgb(0xFF000000))
, selectionColor(QRgb(0xFF000080))
, selectedTextColor(QRgb(0xFFFFFFFF))
, hscroll(0)
, vscroll(0)
, m_cursor(0)
, m_preeditCursor(0)
, m_blinkPeriod(0)
Expand Down Expand Up @@ -179,6 +179,9 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
QDeclarativeGuard<QValidator> m_validator;
#endif

qreal hscroll;
qreal vscroll;

QTextLayout m_textLayout;
QString m_text;
QString m_inputMask;
Expand All @@ -203,8 +206,6 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
#endif
int lastSelectionStart;
int lastSelectionEnd;
int hscroll;
int vscroll;
int m_cursor;
int m_preeditCursor;
int m_blinkPeriod; // 0 for non-blinking cursor
Expand Down Expand Up @@ -295,7 +296,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }

int positionAt(int x, int y, QTextLine::CursorPosition position) const;
int positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const;
int positionAt(const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters) const {
return positionAt(point.x(), point.y(), position);
}
Expand Down

0 comments on commit 5fee1e7

Please sign in to comment.