Make Rectangle border be inner instead of centered on the outline.
authorSamuel Rødal <samuel.rodal@digia.com>
Tue, 16 Oct 2012 15:55:46 +0000 (17:55 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 22 Oct 2012 16:23:12 +0000 (18:23 +0200)
This avoids awkward situations such as when clipping to a parent item of
the same size and makes it easier to reason about the bounding rectangle
of the item.

Task-number: QTBUG-21341
Change-Id: If015cfbc5792429f4a407fc0547ea71eca779eda
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Reviewed-by: Laszlo Papp <lpapp@kde.org>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
src/quick/doc/images/rect-border-width.png [deleted file]
src/quick/doc/snippets/qml/rectangle/rect-border-width.qml [deleted file]
src/quick/items/qquickrectangle.cpp
src/quick/items/qquickrectangle_p.h
src/quick/items/qquickrectangle_p_p.h
src/quick/scenegraph/qsgdefaultrectanglenode.cpp

diff --git a/src/quick/doc/images/rect-border-width.png b/src/quick/doc/images/rect-border-width.png
deleted file mode 100644 (file)
index e232cf3..0000000
Binary files a/src/quick/doc/images/rect-border-width.png and /dev/null differ
diff --git a/src/quick/doc/snippets/qml/rectangle/rect-border-width.qml b/src/quick/doc/snippets/qml/rectangle/rect-border-width.qml
deleted file mode 100644 (file)
index 9616ca8..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**   * Redistributions of source code must retain the above copyright
-**     notice, this list of conditions and the following disclaimer.
-**   * Redistributions in binary form must reproduce the above copyright
-**     notice, this list of conditions and the following disclaimer in
-**     the documentation and/or other materials provided with the
-**     distribution.
-**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-**     of its contributors may be used to endorse or promote products derived
-**     from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-
-//![0]
-Rectangle {
-    width: 100; height: 100
-    color: "lightblue"
-
-    Rectangle {
-        anchors.fill: parent
-        anchors.margins: 10
-        clip: true
-
-        Rectangle {
-            anchors.fill: parent
-            border.width: 1
-        }
-    }
-}
-//![0]
index 3339464..46d4868 100644 (file)
@@ -317,23 +317,6 @@ QQuickRectangle::QQuickRectangle(QQuickItem *parent)
 
 void QQuickRectangle::doUpdate()
 {
-    Q_D(QQuickRectangle);
-    qreal penMargin = 0;
-    qreal penOffset = 0;
-    if (d->pen && d->pen->isValid()) {
-        if (d->pen->pixelAligned()) {
-            const int pw = qRound(d->pen->width());
-            penMargin = qreal(0.5) * pw;
-            penOffset = (pw & 1) * qreal(0.5);
-        } else {
-            penMargin = qreal(0.5) * d->pen->width();
-        }
-    }
-    if (penMargin != d->penMargin || penOffset != d->penOffset) {
-        d->penMargin = penMargin;
-        d->penOffset = penOffset;
-        d->dirty(QQuickItemPrivate::Size); // update clip
-    }
     update();
 }
 
@@ -348,21 +331,7 @@ void QQuickRectangle::doUpdate()
     \note The width of the rectangle's border does not affect the geometry of the
     rectangle itself or its position relative to other items if anchors are used.
 
-    If \c border.width is an odd number, the rectangle is painted at a half-pixel offset to retain
-    border smoothness. Also, the border is rendered evenly on either side of the
-    rectangle's boundaries, and the spare pixel is rendered to the right and below the
-    rectangle (as documented for QRect rendering). This can cause unintended effects if
-    \c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item:
-
-    \div {class="float-right"}
-    \inlineimage rect-border-width.png
-    \enddiv
-
-    \snippet qml/rectangle/rect-border-width.qml 0
-
-    \clearfloat
-    Here, the innermost rectangle's border is clipped on the bottom and right edges by its
-    parent. To avoid this, the border width can be set to two instead of one.
+    The border is rendered within the rectangle's boundaries.
 */
 QQuickPen *QQuickRectangle::border()
 {
@@ -525,16 +494,4 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
     return rectangle;
 }
 
-QRectF QQuickRectangle::boundingRect() const
-{
-    Q_D(const QQuickRectangle);
-    return QRectF(d->penOffset - d->penMargin, d->penOffset - d->penMargin,
-                  d->width + 2 * d->penMargin, d->height + 2 * d->penMargin);
-}
-
-QRectF QQuickRectangle::clipRect() const
-{
-    return QQuickRectangle::boundingRect();
-}
-
 QT_END_NAMESPACE
index 102506a..481033a 100644 (file)
@@ -156,9 +156,6 @@ public:
     qreal radius() const;
     void setRadius(qreal radius);
 
-    virtual QRectF boundingRect() const;
-    virtual QRectF clipRect() const;
-
 Q_SIGNALS:
     void colorChanged();
     void radiusChanged();
index d8f3d66..3d4d019 100644 (file)
@@ -66,7 +66,7 @@ class QQuickRectanglePrivate : public QQuickItemPrivate
 
 public:
     QQuickRectanglePrivate() :
-    color(Qt::white), gradient(0), pen(0), radius(0), penMargin(0), penOffset(0)
+    color(Qt::white), gradient(0), pen(0), radius(0)
     {
     }
 
@@ -79,8 +79,6 @@ public:
     QQuickGradient *gradient;
     QQuickPen *pen;
     qreal radius;
-    qreal penMargin;
-    qreal penOffset;
     static int doUpdateSlotIdx;
 
     QQuickPen *getPen() {
index dab8550..4d5094d 100644 (file)
@@ -342,9 +342,12 @@ void QSGDefaultRectangleNode::update()
 
 void QSGDefaultRectangleNode::updateGeometry()
 {
-    float penWidth = m_aligned ? float(qRound(m_pen_width)) : float(m_pen_width);
     float width = float(m_rect.width());
     float height = float(m_rect.height());
+    float penWidth = qMin(qMin(width, height) * 0.5f, float(m_pen_width));
+
+    if (m_aligned)
+        penWidth = qRound(penWidth);
 
     QSGGeometry *g = geometry();
     g->setDrawingMode(GL_TRIANGLE_STRIP);
@@ -377,14 +380,9 @@ void QSGDefaultRectangleNode::updateGeometry()
         float radius = qMin(qMin(width, height) * 0.5f, float(m_radius));
         QRectF innerRect = m_rect;
         innerRect.adjust(radius, radius, -radius, -radius);
-        if (m_aligned && (int(penWidth) & 1)) {
-            // Pen width is odd, so add the offset as documented.
-            innerRect.moveLeft(innerRect.left() + qreal(0.5));
-            innerRect.moveTop(innerRect.top() + qreal(0.5));
-        }
 
-        float innerRadius = radius - penWidth * 0.5f;
-        float outerRadius = radius + penWidth * 0.5f;
+        float innerRadius = radius - penWidth * 1.0f;
+        float outerRadius = radius;
         float delta = qMin(width, height) * 0.5f;
 
         // Number of segments per corner, approximately one per 3 pixels.
@@ -630,16 +628,8 @@ void QSGDefaultRectangleNode::updateGeometry()
         QRectF innerRect = m_rect;
         QRectF outerRect = m_rect;
 
-        if (penWidth) {
-            if (m_aligned && (int(penWidth) & 1)) {
-                // Pen width is odd, so add the offset as documented.
-                innerRect.moveLeft(innerRect.left() + qreal(0.5));
-                innerRect.moveTop(innerRect.top() + qreal(0.5));
-                outerRect = innerRect;
-            }
-            innerRect.adjust(0.5f * penWidth, 0.5f * penWidth, -0.5f * penWidth, -0.5f * penWidth);
-            outerRect.adjust(-0.5f * penWidth, -0.5f * penWidth, 0.5f * penWidth, 0.5f * penWidth);
-        }
+        if (penWidth)
+            innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth);
 
         float delta = qMin(width, height) * 0.5f;
         int innerVertexCount = 4 + gradientIntersections * 2;