📄 context2d.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the example classes of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "context2d.h"#include "qcontext2dcanvas.h"#include <QVariant>#include <math.h>static const double Q_PI = 3.14159265358979323846; // pi#define DEGREES(t) ((t) * 180.0 / Q_PI)#define qClamp(val, min, max) qMin(qMax(val, min), max)static QList<qreal> parseNumbersList(QString::const_iterator &itr){ QList<qreal> points; QString temp; while ((*itr).isSpace()) ++itr; while ((*itr).isNumber() || (*itr) == '-' || (*itr) == '+' || (*itr) == '.') { temp = QString(); if ((*itr) == '-') temp += *itr++; else if ((*itr) == '+') temp += *itr++; while ((*itr).isDigit()) temp += *itr++; if ((*itr) == '.') temp += *itr++; while ((*itr).isDigit()) temp += *itr++; while ((*itr).isSpace()) ++itr; if ((*itr) == ',') ++itr; points.append(temp.toDouble()); //eat spaces while ((*itr).isSpace()) ++itr; } return points;}static QColor colorFromString(const QString &name){ QString::const_iterator itr = name.constBegin(); QList<qreal> compo; if (name.startsWith("rgba(")) { ++itr; ++itr; ++itr; ++itr; ++itr; compo = parseNumbersList(itr); if (compo.size() != 4) { return QColor(); } //alpha seems to be always between 0-1 compo[3] *= 255; return QColor((int)compo[0], (int)compo[1], (int)compo[2], (int)compo[3]); } else if (name.startsWith("rgb(")) { ++itr; ++itr; ++itr; ++itr; compo = parseNumbersList(itr); if (compo.size() != 3) { return QColor(); } return QColor((int)qClamp(compo[0], qreal(0), qreal(255)), (int)qClamp(compo[1], qreal(0), qreal(255)), (int)qClamp(compo[2], qreal(0), qreal(255))); } else { //QRgb color; //CSSParser::parseColor(name, color); return QColor(name); }}static QPainter::CompositionMode compositeOperatorFromString(const QString &compositeOperator){ if ( compositeOperator == "source-over" ) { return QPainter::CompositionMode_SourceOver; } else if ( compositeOperator == "source-out" ) { return QPainter::CompositionMode_SourceOut; } else if ( compositeOperator == "source-in" ) { return QPainter::CompositionMode_SourceIn; } else if ( compositeOperator == "source-atop" ) { return QPainter::CompositionMode_SourceAtop; } else if ( compositeOperator == "destination-atop" ) { return QPainter::CompositionMode_DestinationAtop; } else if ( compositeOperator == "destination-in" ) { return QPainter::CompositionMode_DestinationIn; } else if ( compositeOperator == "destination-out" ) { return QPainter::CompositionMode_DestinationOut; } else if ( compositeOperator == "destination-over" ) { return QPainter::CompositionMode_DestinationOver; } else if ( compositeOperator == "darker" ) { return QPainter::CompositionMode_SourceOver; } else if ( compositeOperator == "lighter" ) { return QPainter::CompositionMode_SourceOver; } else if ( compositeOperator == "copy" ) { return QPainter::CompositionMode_Source; } else if ( compositeOperator == "xor" ) { return QPainter::CompositionMode_Xor; } return QPainter::CompositionMode_SourceOver;}void CanvasGradientData::setup(QScriptEngine *e){ QScriptValue proto = e->newObject(); proto.setProperty("addColorStop", e->newFunction(&CanvasGradientData::addColorStop, /*length=*/ 2)); e->setDefaultPrototype(qRegisterMetaType<CanvasGradient>(), proto);}QScriptValue CanvasGradientData::addColorStop(QScriptContext *ctx, QScriptEngine *e){ QVariant self = ctx->thisObject().toVariant(); if (qVariantCanConvert<CanvasGradient>(self)) { CanvasGradient g = qvariant_cast<CanvasGradient>(self); qsreal pos = ctx->argument(0).toNumber(); QColor color = colorFromString(ctx->argument(1).toString()); g->gradient.setColorAt(pos, color); } return e->undefinedValue();}void Context2D::save(){ m_stateStack.push(m_state); m_painter.save();}void Context2D::restore(){ if (!m_stateStack.isEmpty()) m_state = m_stateStack.pop(); m_painter.restore();}void Context2D::scale(qreal x, qreal y){ if (m_state.creatingShape) m_state.matrix.scale(x, y); m_painter.scale(x, y);}void Context2D::rotate(qreal angle){ if (m_state.creatingShape) m_state.matrix.rotate(DEGREES(angle)); m_painter.rotate(DEGREES(angle));}void Context2D::translate(qreal x, qreal y){ if (m_state.creatingShape) m_state.matrix.translate(x, y); m_painter.translate(x, y);}void Context2D::transform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy){ QMatrix mat(m11, m12, m21, m22, dx, dy); if (m_state.creatingShape) m_state.matrix *= mat; m_painter.setMatrix(mat, true);}void Context2D::setTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy){ QMatrix mat(m11, m12, m21, m22, dx, dy); if (m_state.creatingShape) m_state.matrix = mat; m_painter.setMatrix(mat, false);}void Context2D::setGlobalAlpha(qreal alpha){ m_painter.setOpacity(alpha);}void Context2D::setGlobalCompositeOperation(const QString &op){ QPainter::CompositionMode mode = compositeOperatorFromString(op); m_painter.setCompositionMode(mode);}void Context2D::setStrokeStyle(const QVariant &style){ QPen pen = m_painter.pen(); if (qVariantCanConvert<CanvasGradient>(style)) { CanvasGradient cg = qvariant_cast<CanvasGradient>(style); pen.setBrush(cg->qgradient()); } else { QColor clr = colorFromString(style.toString()); pen.setColor(clr); } if (pen.style() == Qt::NoPen) pen.setStyle(Qt::SolidLine); m_painter.setPen(pen);}void Context2D::setFillStyle(const QVariant &style){ if (qVariantCanConvert<CanvasGradient>(style)) { CanvasGradient cg = qvariant_cast<CanvasGradient>(style); m_painter.setBrush(cg->qgradient()); } else { QColor clr = colorFromString(style.toString()); m_painter.setBrush(clr); }}qreal Context2D::globalAlpha() const{ return m_painter.opacity();}QString Context2D::globalCompositeOperation() const{ return 0;}QVariant Context2D::strokeStyle() const{ return m_painter.pen().color().name();}QVariant Context2D::fillStyle() const{ return m_painter.brush().color().name();}CanvasGradient Context2D::createLinearGradient(qreal x0, qreal y0, qreal x1, qreal y1){ QLinearGradient g(x0, y0, x1, y1); return CanvasGradient(new CanvasGradientData(g));}CanvasGradient Context2D::createRadialGradient(qreal x0, qreal y0, qreal r0, qreal x1, qreal y1, qreal r1){ QRadialGradient g(QPointF(x1, y1), r0+r1, QPointF(x0, y0)); return CanvasGradient(new CanvasGradientData(g));}void Context2D::setLineWidth(qreal w){ QPen p = m_painter.pen(); p.setWidthF(w); m_painter.setPen(p);}void Context2D::setLineCap(const QString &capString){ QPen pen = m_painter.pen(); if (capString == "round") pen.setCapStyle(Qt::RoundCap); else if (capString == "square") pen.setCapStyle(Qt::SquareCap); else pen.setCapStyle(Qt::FlatCap); m_painter.setPen(pen);}void Context2D::setLineJoin(const QString &joinString){ QPen pen = m_painter.pen(); if (joinString == "round") pen.setJoinStyle(Qt::RoundJoin); else if (joinString == "bevel") pen.setJoinStyle(Qt::BevelJoin); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -