diff options
author | Warwick Allison <warwick.allison@nokia.com> | 2009-05-18 06:46:12 (GMT) |
---|---|---|
committer | Warwick Allison <warwick.allison@nokia.com> | 2009-05-19 01:20:46 (GMT) |
commit | 692782c4d11cf7352a7923633cb015c3580e2704 (patch) | |
tree | 9fe49f61456d379244b796eb3bc2a2c1b46fce4b /src/declarative/fx/qfxrect.cpp | |
parent | 86cc7c0d6dffc5cabe215606cb6fadf98e8214cc (diff) | |
download | Qt-692782c4d11cf7352a7923633cb015c3580e2704.zip Qt-692782c4d11cf7352a7923633cb015c3580e2704.tar.gz Qt-692782c4d11cf7352a7923633cb015c3580e2704.tar.bz2 |
Fix pens.
Now corresponds to standard Qt painting; in particular, penwidth extends
outside rectangle.
Task-number: 249318
Diffstat (limited to 'src/declarative/fx/qfxrect.cpp')
-rw-r--r-- | src/declarative/fx/qfxrect.cpp | 157 |
1 files changed, 95 insertions, 62 deletions
diff --git a/src/declarative/fx/qfxrect.cpp b/src/declarative/fx/qfxrect.cpp index dafd8a2..cd5a4c3 100644 --- a/src/declarative/fx/qfxrect.cpp +++ b/src/declarative/fx/qfxrect.cpp @@ -86,8 +86,26 @@ QML_DEFINE_TYPE(QFxPen,Pen); void QFxPen::setColor(const QColor &c) { _color = c; - emit updated(); _valid = _color.alpha() ? true : false; + emit updated(); +} + +/*! + \property QFxPen::width + \brief the width of the pen. + + \qml + // rect with green border using hexidecimal notation + Rect { pen.width: 4 } + \endqml + + Odd pen widths generally lead to half-pixel painting. +*/ +void QFxPen::setWidth(int w) +{ + _width = w; + _valid = (_width < 1) ? false : true; + emit updated(); } @@ -167,6 +185,8 @@ void QFxRect::doUpdate() Q_D(QFxRect); d->_rectTexture.clear(); #endif + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + setPaintMargin((pw+1)/2); update(); } @@ -372,14 +392,19 @@ void QFxRect::generateRoundedRect() { Q_D(QFxRect); if (d->_rectImage.isNull()) { - d->_rectImage = QImage(d->_radius*2 + 1, d->_radius*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + d->_rectImage = QImage(d->_radius*2 + 1 + pw*2, d->_radius*2 + 1 + pw*2, QImage::Format_ARGB32_Premultiplied); d->_rectImage.fill(0); QPainter p(&(d->_rectImage)); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); - p.drawRoundedRect(0, 0, d->_rectImage.width(), d->_rectImage.height(), d->_radius, d->_radius); + p.drawRoundedRect((pw+1)/2, (pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2, d->_radius, d->_radius); } } @@ -387,14 +412,19 @@ void QFxRect::generateBorderedRect() { Q_D(QFxRect); if (d->_rectImage.isNull()) { - d->_rectImage = QImage(d->pen()->width()*2 + 1, d->pen()->width()*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + d->_rectImage = QImage(d->pen()->width()*2 + 1 + pw*2, d->pen()->width()*2 + 1 + pw*2, QImage::Format_ARGB32_Premultiplied); d->_rectImage.fill(0); QPainter p(&(d->_rectImage)); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } p.setBrush(d->_color); - p.drawRect(0, 0, d->_rectImage.width(), d->_rectImage.height()); + p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, d->_rectImage.width()-(pw+1)/2*2, d->_rectImage.height()-(pw+1)/2*2); } } #elif defined(QFX_RENDER_OPENGL) @@ -402,14 +432,15 @@ void QFxRect::generateRoundedRect() { Q_D(QFxRect); if (d->_rectTexture.isNull()) { - QImage roundRect(int(d->_radius*2 + 1), int(d->_radius*2 + 1), QImage::Format_ARGB32); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + QImage roundRect(d->_radius*2 + 4 + pw*2, d->_radius*2 + 4 + pw*2, QImage::Format_ARGB32_Premultiplied); roundRect.fill(0); QPainter p(&roundRect); QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); p.setPen(pn); p.setBrush(d->_color); - p.drawRoundedRect(0, 0, roundRect.width(), roundRect.height(), d->_radius, d->_radius); + p.drawRoundedRect((pw+1)/2, (pw+1)/2, roundRect.width()-(pw+1)/2*2, roundRect.height()-(pw+1)/2*2, d->_radius, d->_radius); d->_rectTexture.setImage(roundRect); } } @@ -418,14 +449,15 @@ void QFxRect::generateBorderedRect() { Q_D(QFxRect); if (d->_rectTexture.isNull()) { - QImage borderedRect(d->pen()->width()*2 + 1, d->pen()->width()*2 + 1, QImage::Format_ARGB32_Premultiplied); + const int pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0; + QImage borderedRect(pw*2 + 4, pw*2 + 4, QImage::Format_ARGB32_Premultiplied); borderedRect.fill(0); QPainter p(&(borderedRect)); QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); p.setPen(pn); p.setBrush(d->_color); - p.drawRect(0, 0, borderedRect.width(), borderedRect.height()); + p.drawRect(qreal(pw+1)/2, qreal(pw+1)/2, borderedRect.width()-(pw+1)/2*2, borderedRect.height()-(pw+1)/2*2); d->_rectTexture.setImage(borderedRect); } } @@ -458,9 +490,13 @@ void QFxRect::drawRect(QPainter &p) // XXX This path is still slower than the image path // Image path won't work for gradients though p.save(); - QPen pn(QColor(pen()->color()), pen()->width()); p.setRenderHint(QPainter::Antialiasing); - p.setPen(pn); + if (d->_pen && d->_pen->isValid()) { + QPen pn(QColor(pen()->color()), pen()->width()); + p.setPen(pn); + } else { + p.setPen(Qt::NoPen); + } if (d->_gradcolor.isValid()){ QLinearGradient grad(0, 0, 0, height()); grad.setColorAt(0, d->_color); @@ -476,13 +512,15 @@ void QFxRect::drawRect(QPainter &p) p.restore(); } else { int offset = 0; + const int pw = d->_pen && d->_pen->isValid() ? (d->_pen->width()+1)/2*2 : 0; + if (d->_radius > 0) { generateRoundedRect(); //### implicit conversion to int - offset = d->_radius; + offset = int(d->_radius+0.5+pw); } else { generateBorderedRect(); - offset = d->pen()->width(); + offset = pw; } //basically same code as QFxImage uses to paint sci images @@ -490,40 +528,42 @@ void QFxRect::drawRect(QPainter &p) int ySide = qMin(offset * 2, int(height()));; // Upper left - p.drawImage(QRect(0, 0, offset, offset), d->_rectImage, QRect(0, 0, offset, offset)); + p.drawImage(QRect(-pw/2, -pw/2, offset, offset), d->_rectImage, QRect(0, 0, offset, offset)); // Upper middle if (d->_rectImage.width() - xSide) - p.drawImage(QRect(offset, 0, width() - xSide, offset), d->_rectImage, - QRect(offset, 0, d->_rectImage.width() - xSide, offset)); + p.drawImage(QRect(offset-pw/2, -pw/2, width() - xSide + pw, offset), d->_rectImage, + QRect(d->_rectImage.width()/2, 0, 1, offset)); // Upper right if (d->_rectImage.width() - offset) { - p.drawImage(QPoint(width()-offset, 0), d->_rectImage, + p.drawImage(QPoint(width()-offset+pw/2, -pw/2), d->_rectImage, QRect(d->_rectImage.width()-offset, 0, offset, offset)); } // Middle left if (d->_rectImage.height() - ySide) - p.drawImage(QRect(0, offset, offset, height() - ySide), d->_rectImage, - QRect(0, offset, offset, d->_rectImage.height() - ySide)); + p.drawImage(QRect(-pw/2, offset-pw/2, offset, height() - ySide + pw), d->_rectImage, + QRect(0, d->_rectImage.height()/2, offset, 1)); // Middle if (d->_rectImage.width() - xSide && d->_rectImage.height() - ySide) - p.drawImage(QRect(offset, offset, width() - xSide, height() - ySide), d->_rectImage, - QRect(offset, offset, d->_rectImage.width() - xSide, d->_rectImage.height() - ySide)); - // Midlle right + // XXX paint errors in animation example + //p.fillRect(offset-pw/2, offset-pw/2, width() - xSide + pw, height() - ySide + pw, d->getColor()); + p.drawImage(QRect(offset-pw/2, offset-pw/2, width() - xSide + pw, height() - ySide + pw), d->_rectImage, + QRect(d->_rectImage.width()/2, d->_rectImage.height()/2, 1, 1)); + // Middle right if (d->_rectImage.height() - ySide) - p.drawImage(QRect(width()-offset, offset, offset, height() - ySide), d->_rectImage, - QRect(d->_rectImage.width()-offset, offset, offset, d->_rectImage.height() - ySide)); + p.drawImage(QRect(width()-offset+pw/2, offset-pw/2, offset, height() - ySide + pw), d->_rectImage, + QRect(d->_rectImage.width()-offset, d->_rectImage.height()/2, offset, 1)); // Lower left - p.drawImage(QPoint(0, height() - offset), d->_rectImage, QRect(0, d->_rectImage.height() - offset, offset, offset)); + p.drawImage(QPoint(-pw/2, height() - offset + pw/2), d->_rectImage, QRect(0, d->_rectImage.height() - offset, offset, offset)); // Lower Middle if (d->_rectImage.width() - xSide) - p.drawImage(QRect(offset, height() - offset, width() - xSide, offset), d->_rectImage, - QRect(offset, d->_rectImage.height() - offset, d->_rectImage.width() - xSide, offset)); + p.drawImage(QRect(offset-pw/2, height() - offset +pw/2, width() - xSide + pw, offset), d->_rectImage, + QRect(d->_rectImage.width()/2, d->_rectImage.height() - offset, 1, offset)); // Lower Right if (d->_rectImage.width() - offset) - p.drawImage(QPoint(width()-offset, height() - offset), d->_rectImage, + p.drawImage(QPoint(width()-offset+pw/2, height() - offset+pw/2), d->_rectImage, QRect(d->_rectImage.width()-offset, d->_rectImage.height() - offset, offset, offset)); } } @@ -586,12 +626,14 @@ void QFxRect::paintGLContents(GLPainter &p) } } else { qreal offset = 0; + qreal pw = d->_pen && d->_pen->isValid() ? d->_pen->width() : 0.0; + if (d->_radius > 0) { generateRoundedRect(); - offset = d->_radius; + offset = d->_radius + pw+1.5; } else { generateBorderedRect(); - offset = d->pen()->width(); + offset = pw+1.5; } QGLShaderProgram *shader = p.useTextureShader(); @@ -601,38 +643,29 @@ void QFxRect::paintGLContents(GLPainter &p) if (!imgWidth || !imgHeight) return; - float widthV = width(); - float heightV = height(); + float widthV = qreal(width())+pw/2; + float heightV = qreal(height())+pw/2; - float texleft = 0; - float texright = 1; - float textop = 1; - float texbottom = 0; - float imgleft = 0; - float imgright = widthV; - float imgtop = 0; - float imgbottom = heightV; - - texleft = float(offset) / imgWidth; - imgleft = offset; - texright = 1. - float(offset) / imgWidth; - imgright = widthV - offset; - textop = 1. - float(offset) / imgHeight; - imgtop = offset; - texbottom = float(offset) / imgHeight; - imgbottom = heightV - offset; + float texleft = float(offset) / imgWidth; + float imgleft = offset-pw/2; + float texright = float(imgWidth-offset) / imgWidth; + float imgright = widthV - offset; + float textop = float(imgHeight-offset) / imgHeight; + float imgtop = offset-pw/2; + float texbottom = float(offset) / imgHeight; + float imgbottom = heightV - offset; //Bug 231768: Inappropriate interpolation was occuring on 3x3 textures if (offset==1) texleft=texright=textop=texbottom=0.5; - float vert1[] = { 0, 0, - 0, imgtop, - imgleft, 0, + float vert1[] = { -pw/2, -pw/2, + -pw/2, imgtop, + imgleft, -pw/2, imgleft, imgtop, - imgright, 0, + imgright, -pw/2, imgright, imgtop, - widthV, 0, + widthV, -pw/2, widthV, imgtop }; float tex1[] = { 0, 0, 0, textop, @@ -642,8 +675,8 @@ void QFxRect::paintGLContents(GLPainter &p) texright, textop, 1, 0, 1, textop }; - float vert2[] = { 0, imgtop, - 0, imgbottom, + float vert2[] = { -pw/2, imgtop, + -pw/2, imgbottom, imgleft, imgtop, imgleft, imgbottom, imgright, imgtop, @@ -658,8 +691,8 @@ void QFxRect::paintGLContents(GLPainter &p) texright, texbottom, 1, textop, 1, texbottom }; - float vert3[] = { 0, imgbottom, - 0, heightV, + float vert3[] = { -pw/2, imgbottom, + -pw/2, heightV, imgleft, imgbottom, imgleft, heightV, imgright, imgbottom, |