aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/scenegraph/softwarecontext/rectanglenode.cpp
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@digia.com>2014-09-01 16:49:58 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-09-02 13:45:44 +0300
commitba0d8e93d8525bb459e9b6cb384f2fe0701d5a02 (patch)
tree8239423e74a36f24e00c9624d289c143b6824489 /src/plugins/scenegraph/softwarecontext/rectanglenode.cpp
parentf013631527b3cc569527e9541c11b0f12c420473 (diff)
Reformat project to be a Qt Module
Change-Id: I2fe8df530a687247a9cd7ea12c1d8de79fef506e Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/plugins/scenegraph/softwarecontext/rectanglenode.cpp')
-rw-r--r--src/plugins/scenegraph/softwarecontext/rectanglenode.cpp219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/softwarecontext/rectanglenode.cpp b/src/plugins/scenegraph/softwarecontext/rectanglenode.cpp
new file mode 100644
index 0000000000..054ffd3ecf
--- /dev/null
+++ b/src/plugins/scenegraph/softwarecontext/rectanglenode.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt SceneGraph Raster Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "rectanglenode.h"
+#include <qmath.h>
+
+#include <QtGui/QPainter>
+
+
+RectangleNode::RectangleNode()
+ : m_penWidth(0)
+ , m_radius(0)
+ , m_cornerPixmapIsDirty(true)
+{
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+void RectangleNode::setRect(const QRectF &rect)
+{
+ if (m_rect != rect) {
+ m_rect = rect;
+ }
+}
+
+void RectangleNode::setColor(const QColor &color)
+{
+ if (m_color != color) {
+ m_color = color;
+ m_cornerPixmapIsDirty = true;
+ }
+}
+
+void RectangleNode::setPenColor(const QColor &color)
+{
+ if (m_penColor != color) {
+ m_penColor = color;
+ m_cornerPixmapIsDirty = true;
+ }
+}
+
+void RectangleNode::setPenWidth(qreal width)
+{
+ if (m_penWidth != width) {
+ m_penWidth = width;
+ m_cornerPixmapIsDirty = true;
+ }
+}
+
+void RectangleNode::setGradientStops(const QGradientStops &stops)
+{
+ m_stops = stops;
+ m_cornerPixmapIsDirty = true;
+}
+
+void RectangleNode::setRadius(qreal radius)
+{
+ if (m_radius != radius) {
+ m_radius = radius;
+ m_cornerPixmapIsDirty = true;
+ }
+}
+
+void RectangleNode::setAligned(bool /*aligned*/)
+{
+}
+
+void RectangleNode::update()
+{
+ if (!m_penWidth || m_penColor == Qt::transparent) {
+ m_pen = Qt::NoPen;
+ } else {
+ m_pen = QPen(m_penColor);
+ m_pen.setWidthF(m_penWidth);
+ }
+
+ if (!m_stops.isEmpty()) {
+ QLinearGradient gradient(QPoint(0,0), QPoint(0,1));
+ gradient.setStops(m_stops);
+ gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
+ m_brush = QBrush(gradient);
+ } else {
+ m_brush = QBrush(m_color);
+ }
+
+ if (m_cornerPixmapIsDirty) {
+ //Generate new corner Pixmap
+ int radius = qRound(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5f, m_radius));
+
+ m_cornerPixmap = QPixmap(radius * 2, radius * 2);
+ m_cornerPixmap.fill(Qt::transparent);
+
+ if (radius > 0) {
+ QPainter cornerPainter(&m_cornerPixmap);
+ cornerPainter.setRenderHint(QPainter::Antialiasing);
+ cornerPainter.setCompositionMode(QPainter::CompositionMode_Source);
+
+ //Paint outer cicle
+ if (m_penWidth > 0) {
+ cornerPainter.setPen(Qt::NoPen);
+ cornerPainter.setBrush(m_penColor);
+ cornerPainter.drawRoundedRect(QRectF(0, 0, radius * 2, radius *2), radius, radius);
+ }
+
+ //Paint inner circle
+ if (radius > m_penWidth) {
+ cornerPainter.setPen(Qt::NoPen);
+ if (m_stops.isEmpty())
+ cornerPainter.setBrush(m_brush);
+ else
+ cornerPainter.setBrush(Qt::transparent);
+
+ QMarginsF adjustmentMargins(m_penWidth, m_penWidth, m_penWidth, m_penWidth);
+ QRectF cornerCircleRect = QRectF(0, 0, radius * 2, radius * 2).marginsRemoved(adjustmentMargins);
+ cornerPainter.drawRoundedRect(cornerCircleRect, radius, radius);
+ }
+ cornerPainter.end();
+ }
+ m_cornerPixmapIsDirty = false;
+ }
+}
+
+void RectangleNode::paint(QPainter *painter)
+{
+ //Radius should never exceeds half of the width or half of the height
+ int radius = qRound(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius));
+
+ QPainter::RenderHints previousRenderHints = painter->renderHints();
+ painter->setRenderHint(QPainter::Antialiasing, false);
+
+ if (m_penWidth > 0) {
+ //Borders can not be more than half the height/width of a rect
+ double borderWidth = qMin(m_penWidth, m_rect.width() * 0.5);
+ double borderHeight = qMin(m_penWidth, m_rect.height() * 0.5);
+
+ //Fill 4 border Rects
+ QRectF borderTop(QPointF(m_rect.x() + radius, m_rect.y()),
+ QPointF(m_rect.x() + m_rect.width() - radius, m_rect.y() + borderHeight));
+ painter->fillRect(borderTop, m_penColor);
+ QRectF borderBottom(QPointF(m_rect.x() + radius, m_rect.y() + m_rect.height() - borderHeight),
+ QPointF(m_rect.x() + m_rect.width() - radius, m_rect.y() + m_rect.height()));
+ painter->fillRect(borderBottom, m_penColor);
+ QRectF borderLeft(QPointF(m_rect.x(), m_rect.y() + radius),
+ QPointF(m_rect.x() + borderWidth, m_rect.y() + m_rect.height() - radius));
+ painter->fillRect(borderLeft, m_penColor);
+ QRectF borderRight(QPointF(m_rect.x() + m_rect.width() - borderWidth, m_rect.y() + radius),
+ QPointF(m_rect.x() + m_rect.width(), m_rect.y() + m_rect.height() - radius));
+ painter->fillRect(borderRight, m_penColor);
+ }
+
+ if (radius > 0) {
+ //blit 4 corners to border
+ QRectF topLeftCorner(QPointF(m_rect.x(), m_rect.y()),
+ QPointF(m_rect.x() + radius, m_rect.y() + radius));
+ painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, radius, radius));
+ QRectF topRightCorner(QPointF(m_rect.x() + m_rect.width() - radius, m_rect.y()),
+ QPointF(m_rect.x() + m_rect.width(), m_rect.y() + radius));
+ painter->drawPixmap(topRightCorner, m_cornerPixmap, QRectF(radius, 0, radius, radius));
+ QRectF bottomLeftCorner(QPointF(m_rect.x(), m_rect.y() + m_rect.height() - radius),
+ QPointF(m_rect.x() + radius, m_rect.y() + m_rect.height()));
+ painter->drawPixmap(bottomLeftCorner, m_cornerPixmap, QRectF(0, radius, radius, radius));
+ QRectF bottomRightCorner(QPointF(m_rect.x() + m_rect.width() - radius, m_rect.y() + m_rect.height() - radius),
+ QPointF(m_rect.x() + m_rect.width(), m_rect.y() + m_rect.height()));
+ painter->drawPixmap(bottomRightCorner, m_cornerPixmap, QRectF(radius, radius, radius, radius));
+
+ }
+
+ QRectF brushRect = m_rect.marginsRemoved(QMarginsF(m_penWidth, m_penWidth, m_penWidth, m_penWidth));
+ if (brushRect.width() < 0)
+ brushRect.setWidth(0);
+ if (brushRect.height() < 0)
+ brushRect.setHeight(0);
+ double innerRectRadius = qMax(0.0, radius - m_penWidth);
+
+ //If not completely transparent or has a gradient
+ if (m_color.alpha() > 0 || !m_stops.empty()) {
+ if (innerRectRadius > 0) {
+ //Rounded Rect
+ if (m_stops.empty()) {
+ //Rounded Rects without gradient need 3 blits
+ QRectF centerRect(QPointF(brushRect.x() + innerRectRadius, brushRect.y()),
+ QPointF(brushRect.x() + brushRect.width() - innerRectRadius, brushRect.y() + brushRect.height()));
+ painter->fillRect(centerRect, m_color);
+ QRectF leftRect(QPointF(brushRect.x(), brushRect.y() + innerRectRadius),
+ QPointF(brushRect.x() + innerRectRadius, brushRect.y() + brushRect.height() - innerRectRadius));
+ painter->fillRect(leftRect, m_color);
+ QRectF rightRect(QPointF(brushRect.x() + brushRect.width() - innerRectRadius, brushRect.y() + innerRectRadius),
+ QPointF(brushRect.x() + brushRect.width(), brushRect.y() + brushRect.height() - innerRectRadius));
+ painter->fillRect(rightRect, m_color);
+ } else {
+ //Rounded Rect with gradient (slow)
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(m_brush);
+ painter->drawRoundedRect(brushRect, innerRectRadius, innerRectRadius);
+ }
+ } else {
+ //non-rounded rects only need 1 blit
+ painter->fillRect(brushRect, m_brush);
+ }
+ }
+
+ painter->setRenderHints(previousRenderHints);
+}